diff --git a/Upsilon/BaseTypes/TypeConversion.cs b/Upsilon/BaseTypes/TypeConversion.cs new file mode 100644 index 0000000..2514d80 --- /dev/null +++ b/Upsilon/BaseTypes/TypeConversion.cs @@ -0,0 +1,30 @@ +using System; +using Upsilon.BaseTypes.Number; + +namespace Upsilon.BaseTypes +{ + public static class TypeConversion + { + public static LuaType ToLuaType(this object o) + { + switch (o) + { + case bool b: + return new LuaBoolean(b); + case int i: + return new NumberLong(i); + case long i: + return new NumberLong(i); + case float f: + return new NumberDouble(f); + case double f: + return new NumberDouble(f); + + + default: + throw new Exception(); + } + + } + } +} \ No newline at end of file diff --git a/Upsilon/Evaluator/Evaluator.cs b/Upsilon/Evaluator/Evaluator.cs index c233640..d0a3f7b 100644 --- a/Upsilon/Evaluator/Evaluator.cs +++ b/Upsilon/Evaluator/Evaluator.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using Upsilon.BaseTypes; using Upsilon.BaseTypes.Number; using Upsilon.Binder; @@ -35,15 +36,23 @@ namespace Upsilon.Evaluator return _returnValue; } - public LuaType Evaluate(BoundScript e, string functionName) + public LuaType Evaluate(BoundScript e, string functionName, ImmutableArray parameters) { Evaluate(e.Statement); if (!Scope.TryGet(functionName, out var statement) || statement.Type != Type.Function) { throw new ArgumentException(($"Function '{functionName}' could not be found")); } + var function = (LuaFunction) statement; var innerEvaluator = new Evaluator(_diagnostics, Scope); - var result = innerEvaluator.Evaluate(((LuaFunction)statement).Block); + for (var index = 0; index < parameters.Length; index++) + { + var parameter = parameters[index]; + var parameterName = function.Parameters[index]; + innerEvaluator.Scope.Set(parameterName, parameter); + } + + var result = innerEvaluator.Evaluate(function.Block); return result; } diff --git a/Upsilon/Evaluator/Script.cs b/Upsilon/Evaluator/Script.cs index b3b0afb..583b7e8 100644 --- a/Upsilon/Evaluator/Script.cs +++ b/Upsilon/Evaluator/Script.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Collections.Immutable; using Upsilon.BaseTypes; using Upsilon.Binder; using Upsilon.Parser; @@ -39,9 +40,17 @@ namespace Upsilon.Evaluator return Evaluator.Evaluate(Bind()); } - public object EvaluateFunction(string functionName) + public object EvaluateFunction(string functionName, object[] parameters = null) { - return Evaluator.Evaluate(Bind(), functionName); + var luaParameters = ImmutableArray.CreateBuilder(); + if (parameters != null) + { + foreach (var parameter in parameters) + { + luaParameters.Add(parameter.ToLuaType()); + } + } + return Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); } public T Evaluate() where T : LuaType @@ -49,9 +58,17 @@ namespace Upsilon.Evaluator return (T)Evaluator.Evaluate(Bind()); } - public T EvaluateFunction(string functionName) where T : LuaType + public T EvaluateFunction(string functionName, object[] parameters = null) where T : LuaType { - return (T)Evaluator.Evaluate(Bind(), functionName); + var luaParameters = ImmutableArray.CreateBuilder(); + if (parameters != null) + { + foreach (var parameter in parameters) + { + luaParameters.Add(parameter.ToLuaType()); + } + } + return (T)Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); } public string PrettyPrintSyntaxTree() diff --git a/UpsilonTests/FunctionTests.cs b/UpsilonTests/FunctionTests.cs index 55a1bb0..7123178 100644 --- a/UpsilonTests/FunctionTests.cs +++ b/UpsilonTests/FunctionTests.cs @@ -166,5 +166,44 @@ end Assert.Equal(100, (long)result); } + [Fact] + public void ReturnFromCSharpCallWithParameter() + { + const string input = @" +function testFunc (b) + if b then + return 100 + else + return 50 + end +end +"; + var script = new Script(input); + Assert.Empty(script.Diagnostics.Messages); + var result = script.EvaluateFunction("testFunc", new object[] {true}); + Assert.Empty(script.Diagnostics.Messages); + Assert.Equal(100, (long)result); + var result2 = script.EvaluateFunction("testFunc", new object[] {false}); + Assert.Empty(script.Diagnostics.Messages); + Assert.Equal(50, (long)result2); + + } + + [Fact] + public void ReturnFromCSharpCallWithParameters() + { + const string input = @" +function add (a, b) + return a + b +end +"; + var script = new Script(input); + Assert.Empty(script.Diagnostics.Messages); + var result = script.EvaluateFunction("add", new object[] {400, 128}); + Assert.Empty(script.Diagnostics.Messages); + Assert.Equal(528, (long)result); + + } + } } \ No newline at end of file