Add parameterized callable functions from CSharp
This commit is contained in:
parent
e5ea4d0fde
commit
f74992e47b
|
@ -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.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<LuaType> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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
|
||||
|
@ -49,9 +58,17 @@ namespace Upsilon.Evaluator
|
|||
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()
|
||||
|
|
|
@ -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<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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue