Add parameterized callable functions from CSharp
This commit is contained in:
		
							
								
								
									
										30
									
								
								Upsilon/BaseTypes/TypeConversion.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Upsilon/BaseTypes/TypeConversion.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -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(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,5 +1,6 @@ | |||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.Collections.Immutable; | ||||||
| using Upsilon.BaseTypes; | using Upsilon.BaseTypes; | ||||||
| using Upsilon.BaseTypes.Number; | using Upsilon.BaseTypes.Number; | ||||||
| using Upsilon.Binder; | using Upsilon.Binder; | ||||||
| @@ -35,15 +36,23 @@ namespace Upsilon.Evaluator | |||||||
|             return _returnValue; |             return _returnValue; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public LuaType Evaluate(BoundScript e, string functionName) |         public LuaType Evaluate(BoundScript e, string functionName, ImmutableArray<LuaType> parameters) | ||||||
|         { |         { | ||||||
|             Evaluate(e.Statement); |             Evaluate(e.Statement); | ||||||
|             if (!Scope.TryGet(functionName, out var statement) || statement.Type != Type.Function) |             if (!Scope.TryGet(functionName, out var statement) || statement.Type != Type.Function) | ||||||
|             { |             { | ||||||
|                 throw new ArgumentException(($"Function '{functionName}' could not be found")); |                 throw new ArgumentException(($"Function '{functionName}' could not be found")); | ||||||
|             } |             } | ||||||
|  |             var function = (LuaFunction) statement; | ||||||
|             var innerEvaluator = new Evaluator(_diagnostics, Scope); |             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; |             return result; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.Collections.Immutable; | ||||||
| using Upsilon.BaseTypes; | using Upsilon.BaseTypes; | ||||||
| using Upsilon.Binder; | using Upsilon.Binder; | ||||||
| using Upsilon.Parser; | using Upsilon.Parser; | ||||||
| @@ -39,9 +40,17 @@ namespace Upsilon.Evaluator | |||||||
|             return Evaluator.Evaluate(Bind()); |             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<LuaType>(); | ||||||
|  |             if (parameters != null) | ||||||
|  |             { | ||||||
|  |                 foreach (var parameter in parameters) | ||||||
|  |                 { | ||||||
|  |                     luaParameters.Add(parameter.ToLuaType()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public T Evaluate<T>() where T : LuaType |         public T Evaluate<T>() where T : LuaType | ||||||
| @@ -49,9 +58,17 @@ namespace Upsilon.Evaluator | |||||||
|             return (T)Evaluator.Evaluate(Bind()); |             return (T)Evaluator.Evaluate(Bind()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public T EvaluateFunction<T>(string functionName) where T : LuaType |         public T EvaluateFunction<T>(string functionName, object[] parameters = null) where T : LuaType | ||||||
|         { |         { | ||||||
|             return (T)Evaluator.Evaluate(Bind(), functionName); |             var luaParameters = ImmutableArray.CreateBuilder<LuaType>(); | ||||||
|  |             if (parameters != null) | ||||||
|  |             { | ||||||
|  |                 foreach (var parameter in parameters) | ||||||
|  |                 { | ||||||
|  |                     luaParameters.Add(parameter.ToLuaType()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return (T)Evaluator.Evaluate(Bind(), functionName, luaParameters.ToImmutable()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public string PrettyPrintSyntaxTree() |         public string PrettyPrintSyntaxTree() | ||||||
|   | |||||||
| @@ -166,5 +166,44 @@ end | |||||||
|             Assert.Equal(100, (long)result); |             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<NumberLong>("testFunc", new object[] {true}); | ||||||
|  |             Assert.Empty(script.Diagnostics.Messages); | ||||||
|  |             Assert.Equal(100, (long)result); | ||||||
|  |             var result2 = script.EvaluateFunction<NumberLong>("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<NumberLong>("add", new object[] {400, 128}); | ||||||
|  |             Assert.Empty(script.Diagnostics.Messages); | ||||||
|  |             Assert.Equal(528, (long)result); | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user