Fixes script --> C# function calls not working

This commit is contained in:
Deukhoofd 2018-11-28 21:23:08 +01:00
parent babbf2875f
commit af0ff235e1
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
9 changed files with 106 additions and 53 deletions

View File

@ -25,13 +25,13 @@ namespace Upsilon.BaseTypes
public abstract ScriptType Run(Diagnostics diagnostics, ScriptType[] variables);
}
internal class ScriptInternalFunction : ScriptFunction, IScopeOwner
internal class ScriptRuntimeFunction : ScriptFunction, IScopeOwner
{
public BoundBlockStatement Block { get; }
public ImmutableArray<BoundVariableSymbol> Parameters { get; }
public EvaluationScope EvaluationScope { get; }
public ScriptInternalFunction(ImmutableArray<BoundVariableSymbol> parameters, BoundBlockStatement block,
public ScriptRuntimeFunction(ImmutableArray<BoundVariableSymbol> parameters, BoundBlockStatement block,
EvaluationScope evaluationScope)
{
Parameters = parameters;
@ -59,11 +59,13 @@ namespace Upsilon.BaseTypes
_method = method;
_object = o;
_directTypeManipulation = directTypeManipulation;
ReturnType = _method.ReturnType;
}
private readonly UserDataMethod _method;
private readonly object _object;
private readonly bool _directTypeManipulation;
public System.Type ReturnType { get; }
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables)
{

View File

@ -1,5 +1,7 @@
using System;
using System.Collections;
using Upsilon.BaseTypes.Number;
using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.BaseTypes.UserData;
namespace Upsilon.BaseTypes
@ -43,7 +45,7 @@ namespace Upsilon.BaseTypes
return new GenericUserData(o);
}
public static Type GetLuaType(object o)
public static Type GetScriptType(object o)
{
if (o is ScriptType t)
{
@ -70,5 +72,38 @@ namespace Upsilon.BaseTypes
return Type.UserData;
}
}
public static Type GetScriptType(this System.Type t)
{
if (t == typeof(bool))
return Type.Boolean;
if (t == typeof(string))
return Type.String;
if (t == typeof(int))
return Type.Number;
if (t == typeof(long))
return Type.Number;
if (t == typeof(float))
return Type.Number;
if (t == typeof(double))
return Type.Number;
if (t == typeof(void))
return Type.Nil;
if (t == typeof(ScriptString))
return Type.String;
if (typeof(ScriptNumber).IsAssignableFrom(t))
return Type.Number;
if (typeof(ScriptFunction).IsAssignableFrom(t))
return Type.Function;
if (typeof(ScriptTable).IsAssignableFrom(t))
return Type.Table;
if (t == typeof(IIterable))
return Type.Nil;
throw new ArgumentException(t.ToString());
}
}
}

View File

@ -32,6 +32,7 @@ namespace Upsilon.BaseTypes.UserData
public string Name { get; }
private List<UserDataMethodPart> MethodParts { get; }
public System.Type ReturnType { get; }
public UserDataMethod(MethodInfo method)
{
@ -41,6 +42,7 @@ namespace Upsilon.BaseTypes.UserData
{
part
};
ReturnType = part.Method.ReturnType;
}
public void LoadMethodPart(MethodInfo method)

View File

@ -232,6 +232,10 @@ namespace Upsilon.Binder
returnType = function.ResultType;
var pars = function.Parameters;
if (!function.IsInternal)
{
if (pars.Length != parameters.Count)
{
_diagnostics.LogError(
@ -258,6 +262,7 @@ namespace Upsilon.Binder
}
}
}
}
return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType);
}
@ -508,7 +513,7 @@ namespace Upsilon.Binder
if (!Scope.TryGetVariable(name, !isLocal, out var variable))
{
var functionVariable = new FunctionVariableSymbol(name, isLocal, parameters.ToImmutable(), func.ReturnType)
var functionVariable = new FunctionVariableSymbol(name, isLocal, parameters.ToImmutable(), func.ReturnType, false)
{
CommentValue = commentData.ToArray()
};

View File

@ -26,12 +26,14 @@ namespace Upsilon.Binder
public ImmutableArray<VariableSymbol> Parameters { get; }
public Type ResultType { get; internal set; }
public bool IsBound { get; set; }
public bool IsInternal { get; }
public FunctionVariableSymbol(string name, bool local, ImmutableArray<VariableSymbol> parameters, Type resultType)
public FunctionVariableSymbol(string name, bool local, ImmutableArray<VariableSymbol> parameters, Type resultType, bool isInternal)
: base(name, Type.Function, local)
{
Parameters = parameters;
ResultType = resultType;
IsInternal = isInternal;
}
}

View File

@ -61,8 +61,10 @@ namespace Upsilon.Evaluator
{
throw new ArgumentException(($"Function '{functionName}' could not be found"));
}
var function = (ScriptInternalFunction) statement;
var function = (ScriptRuntimeFunction) statement;
var innerEvaluator = new Evaluator(_diagnostics, Scope);
if (parameters != null)
{
for (var index = 0; index < parameters.Length; index++)
{
var parameter = parameters[index];
@ -89,6 +91,7 @@ namespace Upsilon.Evaluator
innerEvaluator.Scope.CreateLocal(parameterSymbol, parameter.ToScriptType());
}
}
var result = innerEvaluator.EvaluateNode(function.Block);
return result;
@ -414,13 +417,13 @@ namespace Upsilon.Evaluator
private ScriptType EvaluateBoundFunctionStatement(BoundFunctionExpression boundFunctionExpression)
{
var func = new ScriptInternalFunction(boundFunctionExpression.Parameters, boundFunctionExpression.Block, Scope);
var func = new ScriptRuntimeFunction(boundFunctionExpression.Parameters, boundFunctionExpression.Block, Scope);
return func;
}
private ScriptType EvaluateUnboundFunctionStatement(UnboundFunctionExpression unboundFunctionExpression)
{
var func = new ScriptInternalFunction(unboundFunctionExpression.Parameters, unboundFunctionExpression.Block, Scope);
var func = new ScriptRuntimeFunction(unboundFunctionExpression.Parameters, unboundFunctionExpression.Block, Scope);
return func;
}

View File

@ -8,7 +8,7 @@ using Upsilon.BaseTypes.ScriptTypeInterfaces;
namespace Upsilon.StandardLibraries
{
internal class BasicFunctions : LuaLibrary
internal class BasicFunctions : ScriptLibrary
{
[StandardLibraryScriptFunction("assert")]
public void Assert(ScriptBoolean boolean, ScriptString message = null)

View File

@ -5,11 +5,11 @@ using Upsilon.BaseTypes.UserData;
namespace Upsilon.StandardLibraries
{
internal abstract class LuaLibrary
internal abstract class ScriptLibrary
{
public Dictionary<string, ScriptFunction> LoadMethods()
public Dictionary<string, ScriptMethodInfoFunction> LoadMethods()
{
var dictionary = new Dictionary<string, ScriptFunction>();
var dictionary = new Dictionary<string, ScriptMethodInfoFunction>();
var methods = GetType().GetMethods();
foreach (var methodInfo in methods)
{

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Upsilon.BaseTypes;
@ -42,13 +43,16 @@ namespace Upsilon.StandardLibraries
public static (EvaluationScope, BoundScope) CreateStandardLibrary()
{
var basicFunctions = new BasicFunctions().LoadMethods();
var scope = new EvaluationScope(basicFunctions.ToDictionary(x => x.Key, x => (ScriptType)x.Value));
var boundScope =
new BoundScope(
scope.Variables.ToDictionary(x => x.Key,
x => (VariableSymbol) new FunctionVariableSymbol(x.Key, false,
ImmutableArray<VariableSymbol>.Empty, x.Value.Type) {IsBound = true}),
null);
var funcs = new Dictionary<string, ScriptType>();
var boundFuncs = new Dictionary<string, VariableSymbol>();
foreach (var func in basicFunctions)
{
funcs.Add(func.Key, func.Value);
boundFuncs.Add(func.Key, new FunctionVariableSymbol(func.Key, true, ImmutableArray<VariableSymbol>.Empty,
func.Value.ReturnType.GetScriptType(), true){IsBound = true});
}
var scope = new EvaluationScope(funcs);
var boundScope = new BoundScope(boundFuncs, null);
return (scope, boundScope);
}