diff --git a/src/Runtime/Types/CSharpWrappers/Builtins/EzrBuiltinFunctions.cs b/src/Runtime/Types/CSharpWrappers/Builtins/EzrBuiltinFunctions.cs
index 8af0c6e..a7bef0a 100644
--- a/src/Runtime/Types/CSharpWrappers/Builtins/EzrBuiltinFunctions.cs
+++ b/src/Runtime/Types/CSharpWrappers/Builtins/EzrBuiltinFunctions.cs
@@ -4,6 +4,8 @@
using EzrSquared.Runtime.Types.Core.Text;
using EzrSquared.Runtime.WrapperAttributes;
using System;
+using System.Collections.Generic;
+using System.Text;
namespace EzrSquared.Runtime.Types.CSharpWrappers.Builtins;
@@ -19,12 +21,16 @@ public static class EzrBuiltinFunctions
/// ezr² parameters:
///
/// -
- /// message
- /// () The message to display on the console.
+ /// Extra Positional Arguments
+ /// ( of s) The message(s) to display on the console.
///
/// -
/// line_end
- /// (Optional, , , ) Line end character(s) to use instead of \n.
+ /// (Optional, ) Line end character(s) to use instead of \n.
+ ///
+ /// -
+ /// separator
+ /// (Optional, ) separator to separate each message to be printed.
///
///
///
@@ -32,29 +38,56 @@ public static class EzrBuiltinFunctions
///
///
/// ezr² errors:
- /// if "line_end" is not one of the specified types.
+ /// if no messages provided.
+ /// if "line_end" is not one of the specified types.
+ /// if "separator" is not one of the specified types.
///
/// The constructor arguments.
- [SharpMethodWrapper("show", RequiredParameters = ["message"], OptionalParameters = ["line_end"])]
+ [SharpMethodWrapper("show", HasExtraPositionalArguments = true, OptionalParameters = ["line_end", "separator"])]
public static void Show(SharpMethodParameters arguments)
{
RuntimeResult result = arguments.Result;
- Reference messageReference = arguments.ArgumentReferences["message"];
+ List messageReferences = arguments.ExtraPositionalArgumentReferences!;
- string message = messageReference.Object.ToPureString(result);
- if (result.ShouldReturn)
+ if (messageReferences.Count == 0)
+ {
+ result.Failure(new EzrMissingRequiredArgumentError("At least one message must be provided!", arguments.ExecutionContext, arguments.StartPosition, arguments.EndPosition));
return;
+ }
+
+ string separator = string.Empty;
+ if (arguments.ArgumentReferences.TryGetValue("separator", out Reference? separatorReference))
+ {
+ IEzrObject separatorObject = separatorReference.Object;
+ if (separatorObject is IEzrString separatorString)
+ separator = separatorString.StringValue;
+ else
+ {
+ result.Failure(new EzrUnexpectedTypeError($"Expected separator of type string, character or character list, but got object of type \"{separatorObject.TypeName}\"", arguments.ExecutionContext, separatorObject.StartPosition, separatorObject.EndPosition));
+ return;
+ }
+ }
+
+ StringBuilder messageBuilder = new();
+ int messagesCount = messageReferences.Count;
+
+ for (int i = 0; i < messagesCount; i++)
+ {
+ string messagePart = messageReferences[i].Object.ToPureString(result);
+ if (result.ShouldReturn)
+ return;
+
+ messageBuilder.Append(messagePart);
+ if (i < messagesCount - 1)
+ messageBuilder.Append(separator);
+ }
string lineEnd = Environment.NewLine;
if (arguments.ArgumentReferences.TryGetValue("line_end", out Reference? lineEndReference))
{
IEzrObject lineEndObject = lineEndReference.Object;
- if (lineEndObject is EzrString lineEndString)
- lineEnd = lineEndString.Value;
- else if (lineEndObject is EzrCharacter lineEndCharacter)
- lineEnd = lineEndCharacter.Value.ToString();
- else if (lineEndObject is EzrCharacterList lineEndCharacterList)
- lineEnd = lineEndCharacterList.StringValue;
+ if (lineEndObject is IEzrString lineEndString)
+ lineEnd = lineEndString.StringValue;
else
{
result.Failure(new EzrUnexpectedTypeError($"Expected line ending of type string, character or character list, but got object of type \"{lineEndObject.TypeName}\"", arguments.ExecutionContext, lineEndObject.StartPosition, lineEndObject.EndPosition));
@@ -62,7 +95,7 @@ public static void Show(SharpMethodParameters arguments)
}
}
- Console.Write($"{message}{lineEnd}");
+ Console.Write(messageBuilder.Append(lineEnd).ToString());
result.Success(ReferencePool.Get(EzrConstants.Nothing, AccessMod.PrivateConstant));
}
diff --git a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceExecutableWrapper.cs b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceExecutableWrapper.cs
index d38d43d..dffa865 100644
--- a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceExecutableWrapper.cs
+++ b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceExecutableWrapper.cs
@@ -1,4 +1,6 @@
-using EzrSquared.Runtime.Types.Core.Errors;
+global using WrapperArgumentPopulationResult = (System.Collections.Generic.Dictionary Arguments, System.Collections.Generic.List? ExtraPositionalArguments);
+
+using EzrSquared.Runtime.Types.Core.Errors;
using EzrSquared.Util;
using System;
using System.Collections.Generic;
@@ -28,7 +30,12 @@ public abstract class EzrSharpSourceExecutableWrapper(Context parentContext, Pos
///
/// Does the executable accept extra keyword arguments?
///
- public bool HasKeywordArguments;
+ public bool HasExtraKeywordArguments;
+
+ ///
+ /// Does the executable accept extra positional arguments?
+ ///
+ public bool HasExtraPositionalArguments;
///
/// Converts a string from PascalCase to lowecase plain text, seperated by spaces.
@@ -58,13 +65,21 @@ internal protected static string PascalCaseToLowerCasePlainText(string text)
/// The array of arguments.
/// Runtime result for carrying any errors.
/// The dictionary of all the arguments.
- protected internal Dictionary CheckAndPopulateArguments(Reference[] arguments, RuntimeResult result)
+ protected internal WrapperArgumentPopulationResult CheckAndPopulateArguments(Reference[] arguments, RuntimeResult result)
{
+ int totalRequiredArguments = 0;
+ foreach ((string Name, bool IsRequired) in Parameters)
+ {
+ if (IsRequired)
+ totalRequiredArguments++;
+ }
+
int calculatedParameterIndex = 0;
int requiredKeywordArguments = 0;
int flaggedRequiredArguments = -1;
Dictionary argumentReferences = new(arguments.Length);
+ List? extraPositionalArgumentReferences = HasExtraPositionalArguments ? new() : null;
for (int i = 0; i < arguments.Length; i++)
{
@@ -78,21 +93,16 @@ protected internal Dictionary CheckAndPopulateArguments(Refer
if (argumentReferences.ContainsKey(name))
{
result.Failure(new EzrIllegalOperationError($"Cannot override already defined argument \"{name}\"!", _executionContext, reference.Object.StartPosition, reference.Object.EndPosition));
- return argumentReferences;
+ return (argumentReferences, extraPositionalArgumentReferences);
}
- bool found = Array.Find(Parameters, (v) =>
- {
- parameterIndex++;
- return v.Name == name;
- }) != default;
-
- if (found)
+ parameterIndex = Array.FindIndex(Parameters, (param) => param.Name == name);
+ if (parameterIndex > -1)
{
argumentReferences.Add(name, reference);
requiredKeywordArguments++;
}
- else if (HasKeywordArguments)
+ else if (HasExtraKeywordArguments)
{
argumentReferences.Add(name, reference);
parameterIndex = -1;
@@ -100,13 +110,13 @@ protected internal Dictionary CheckAndPopulateArguments(Refer
else
{
result.Failure(new EzrUnexpectedArgumentError($"Did not expect argument \"{name}\"!", _executionContext, reference.Object.StartPosition, reference.Object.EndPosition));
- return argumentReferences;
+ return (argumentReferences, extraPositionalArgumentReferences);
}
}
else
{
IndexCheck:
- if (Parameters.Length <= calculatedParameterIndex)
+ if (Parameters.Length <= calculatedParameterIndex && !HasExtraPositionalArguments)
{
result.Failure(new EzrUnexpectedArgumentError(
requiredKeywordArguments > 0
@@ -115,6 +125,11 @@ protected internal Dictionary CheckAndPopulateArguments(Refer
_executionContext, StartPosition, EndPosition));
break;
}
+ else if (totalRequiredArguments <= calculatedParameterIndex && HasExtraPositionalArguments)
+ {
+ extraPositionalArgumentReferences!.Add(reference);
+ continue;
+ }
string argumentName = Parameters[calculatedParameterIndex].Name;
if (!argumentReferences.ContainsKey(argumentName))
@@ -145,11 +160,11 @@ protected internal Dictionary CheckAndPopulateArguments(Refer
if (Parameters[i].IsRequired && (flaggedRequiredArguments < 0 || (flaggedRequiredArguments & parameterFlag) != parameterFlag))
{
result.Failure(new EzrMissingRequiredArgumentError($"Expected required argument \"{Parameters[i].Name}\"!", _executionContext, StartPosition, EndPosition));
- return argumentReferences;
+ return (argumentReferences, extraPositionalArgumentReferences);
}
}
- return argumentReferences;
+ return (argumentReferences, extraPositionalArgumentReferences);
}
///
diff --git a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFieldWrapper.cs b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFieldWrapper.cs
index 6cf23f2..3b0deb7 100644
--- a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFieldWrapper.cs
+++ b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFieldWrapper.cs
@@ -79,7 +79,7 @@ public EzrSharpSourceFieldWrapper(FieldInfo fieldInfo, object? instance, Context
///
public override void Execute(Reference[] arguments, Interpreter interpreter, RuntimeResult result)
{
- Dictionary argumentReferences = CheckAndPopulateArguments(arguments, result);
+ Dictionary argumentReferences = CheckAndPopulateArguments(arguments, result).Arguments;
if (result.ShouldReturn)
return;
diff --git a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFunctionWrapper.cs b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFunctionWrapper.cs
index 01a7548..9da1406 100644
--- a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFunctionWrapper.cs
+++ b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceFunctionWrapper.cs
@@ -97,19 +97,21 @@ private void AddParameters(SharpMethodWrapperAttribute attribute)
for (int j = 0; j < attribute.OptionalParameters.Length; j++)
Parameters[j + requiredParameters] = new(attribute.OptionalParameters[j], false);
- HasKeywordArguments = attribute.HasKeywordArguments;
+ HasExtraKeywordArguments = attribute.HasExtraKeywordArguments;
+ HasExtraPositionalArguments = attribute.HasExtraPositionalArguments;
}
///
public override void Execute(Reference[] arguments, Interpreter interpreter, RuntimeResult result)
{
- Dictionary argumentReferences = CheckAndPopulateArguments(arguments, result);
+ WrapperArgumentPopulationResult argumentReferences = CheckAndPopulateArguments(arguments, result);
if (result.ShouldReturn)
return;
SharpFunction.Invoke(new SharpMethodParameters
(
- argumentReferences,
+ argumentReferences.Arguments,
+ argumentReferences.ExtraPositionalArguments,
_executionContext,
CreationContext,
Context,
diff --git a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourcePropertyWrapper.cs b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourcePropertyWrapper.cs
index 837429a..ae90a33 100644
--- a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourcePropertyWrapper.cs
+++ b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourcePropertyWrapper.cs
@@ -74,7 +74,7 @@ public EzrSharpSourcePropertyWrapper(PropertyInfo propertyInfo, object? instance
///
public override void Execute(Reference[] arguments, Interpreter interpreter, RuntimeResult result)
{
- Dictionary argumentReferences = CheckAndPopulateArguments(arguments, result);
+ Dictionary argumentReferences = CheckAndPopulateArguments(arguments, result).Arguments;
if (result.ShouldReturn)
return;
diff --git a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceTypeWrapper.cs b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceTypeWrapper.cs
index 1f0fd7d..af90862 100644
--- a/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceTypeWrapper.cs
+++ b/src/Runtime/Types/CSharpWrappers/SourceWrappers/EzrSharpSourceTypeWrapper.cs
@@ -100,7 +100,8 @@ public EzrSharpSourceTypeWrapper(
Parameters[j + requiredParameters] = new(constructor.Value.Attribute.OptionalParameters[j], false);
// Set variables.
- HasKeywordArguments = constructor.Value.Attribute.HasKeywordArguments;
+ HasExtraKeywordArguments = constructor.Value.Attribute.HasExtraKeywordArguments;
+ HasExtraPositionalArguments = constructor.Value.Attribute.HasExtraPositionalArguments;
Constructor = constructor.Value.Info;
// Get static methods to wrap.
@@ -238,7 +239,7 @@ public EzrSharpSourceTypeWrapper(
///
public override void Execute(Reference[] arguments, Interpreter interpreter, RuntimeResult result)
{
- Dictionary argumentReferences = CheckAndPopulateArguments(arguments, result);
+ WrapperArgumentPopulationResult argumentReferences = CheckAndPopulateArguments(arguments, result);
if (result.ShouldReturn)
return;
@@ -246,7 +247,8 @@ public override void Execute(Reference[] arguments, Interpreter interpreter, Run
[
new SharpMethodParameters
(
- argumentReferences,
+ argumentReferences.Arguments,
+ argumentReferences.ExtraPositionalArguments,
_executionContext,
CreationContext,
Context,
diff --git a/src/Runtime/WrapperAttributes/SharpMethodParameters.cs b/src/Runtime/WrapperAttributes/SharpMethodParameters.cs
index 0d2e28d..07e48be 100644
--- a/src/Runtime/WrapperAttributes/SharpMethodParameters.cs
+++ b/src/Runtime/WrapperAttributes/SharpMethodParameters.cs
@@ -6,6 +6,7 @@ namespace EzrSquared.Runtime.WrapperAttributes;
/// Class for the paramters of a wrapped C# method.
///
/// See .
+/// See .
/// See .
/// See .
/// See .
@@ -15,6 +16,7 @@ namespace EzrSquared.Runtime.WrapperAttributes;
/// See .
public class SharpMethodParameters(
Dictionary argumentReferences,
+ List? extraPositionalArgumentReferences,
Context executionContext,
Context creationContext,
Context methodContext,
@@ -28,6 +30,11 @@ public class SharpMethodParameters(
///
public Dictionary ArgumentReferences = argumentReferences;
+ ///
+ /// The references to optional extra positional ezr² arguments.
+ ///
+ public List? ExtraPositionalArgumentReferences = extraPositionalArgumentReferences;
+
///
/// The context under which the method is being executed.
///
diff --git a/src/Runtime/WrapperAttributes/SharpMethodWrapperAttribute.cs b/src/Runtime/WrapperAttributes/SharpMethodWrapperAttribute.cs
index 0d33e1a..79898ff 100644
--- a/src/Runtime/WrapperAttributes/SharpMethodWrapperAttribute.cs
+++ b/src/Runtime/WrapperAttributes/SharpMethodWrapperAttribute.cs
@@ -29,7 +29,12 @@ public class SharpMethodWrapperAttribute : Attribute
///
/// Does this method support additional keyword arguments (kwargs)?
///
- public bool HasKeywordArguments;
+ public bool HasExtraKeywordArguments;
+
+ ///
+ /// Does this method support additional positional arguments (args)?
+ ///
+ public bool HasExtraPositionalArguments;
///
/// Creates a new instance of with a name.