Add parameterized callable functions from CSharp

This commit is contained in:
Deukhoofd 2018-11-16 14:58:15 +01:00
parent e5ea4d0fde
commit f74992e47b
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
4 changed files with 101 additions and 6 deletions

View 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();
}
}
}
}

View File

@ -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;
} }

View File

@ -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()

View File

@ -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);
}
} }
} }