Initial support for generic funcs
This commit is contained in:
parent
587c8dfff3
commit
520cd1ffcc
|
@ -2,7 +2,7 @@ using Upsilon.Evaluator;
|
|||
|
||||
namespace Upsilon.BaseTypes.ScriptFunction
|
||||
{
|
||||
internal abstract class ScriptFunction : ScriptType
|
||||
public abstract class ScriptFunction : ScriptType
|
||||
{
|
||||
public override Type Type => Type.Function;
|
||||
public override object ToCSharpObject()
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Upsilon.Evaluator;
|
||||
|
||||
namespace Upsilon.BaseTypes.ScriptFunction
|
||||
{
|
||||
public class ScriptGenericFunction : ScriptFunction
|
||||
{
|
||||
public ScriptGenericFunction(Func<object, IEnumerable<object>> function)
|
||||
{
|
||||
Function = function;
|
||||
}
|
||||
|
||||
public ScriptGenericFunction(object o)
|
||||
{
|
||||
var type = o.GetType();
|
||||
var generics = type.GetGenericArguments();
|
||||
Function.GetMethodInfo();
|
||||
}
|
||||
|
||||
public Func<object, IEnumerable<object>> Function { get; }
|
||||
|
||||
public override ScriptType Run(Diagnostics diagnostics, ScriptType[] variables, Script script,
|
||||
EvaluationScope scope)
|
||||
{
|
||||
return Function.Invoke(variables.Select(x => x.ToCSharpObject())).ToScriptType();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
using Upsilon.BaseTypes.ScriptFunction;
|
||||
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
||||
using Upsilon.BaseTypes.UserData;
|
||||
|
||||
|
@ -42,6 +44,18 @@ namespace Upsilon.BaseTypes
|
|||
{
|
||||
return new DictionaryUserData(dic);
|
||||
}
|
||||
if (o.GetType().IsGenericType)
|
||||
{
|
||||
var generic = o.GetType().GetGenericTypeDefinition();
|
||||
if (generic.FullName != null && generic.FullName.Contains("System.Func"))
|
||||
{
|
||||
var function = (Delegate)o;
|
||||
var method = new UserDataMethod(function.GetMethodInfo());
|
||||
return new ScriptMethodInfoFunction(method, null, false,
|
||||
false, false);
|
||||
}
|
||||
}
|
||||
|
||||
return new GenericUserData(o);
|
||||
}
|
||||
|
||||
|
@ -102,7 +116,8 @@ namespace Upsilon.BaseTypes
|
|||
return Type.Nil;
|
||||
if (t == typeof(ScriptType))
|
||||
return Type.Unknown;
|
||||
|
||||
if (typeof(IEnumerable).IsAssignableFrom(t))
|
||||
return Type.Table | Type.Function;
|
||||
return Type.UserData;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Upsilon.BoundTypes;
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace Upsilon.Binder.VariableSymbols
|
|||
if (!functionParameter.ValidTypes.HasFlag(callingParameter.Type))
|
||||
{
|
||||
return (false,
|
||||
$"Unexpected variable passed to internal function '{functionParameter}'." +
|
||||
$"Unexpected variable passed to internal function at position {i + 1}. " +
|
||||
$"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'",
|
||||
callingParameter);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Upsilon.BaseTypes;
|
||||
using Upsilon.BaseTypes.Number;
|
||||
|
@ -75,11 +76,44 @@ namespace Upsilon.StandardLibraries
|
|||
{
|
||||
var luaVariable = value.ToScriptType();
|
||||
var ubDef = BoundTypeHandler.GetTypeDefinition(value.GetType());
|
||||
var varSymbol = new FunctionParameterSymbol(name, ubDef);
|
||||
VariableSymbol varSymbol = null;
|
||||
if (ubDef != null)
|
||||
{
|
||||
varSymbol = new FunctionParameterSymbol(name, ubDef);
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = value.GetType();
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
var generic = type.GetGenericTypeDefinition();
|
||||
if (generic.FullName != null && generic.FullName.Contains("System.Func"))
|
||||
{
|
||||
varSymbol = BuildFunctionVariableSymbol(name, type);
|
||||
}
|
||||
}
|
||||
if (varSymbol == null)
|
||||
throw new Exception("Unknown type: " + type);
|
||||
|
||||
}
|
||||
BoundScope.AssignToNearest(varSymbol);
|
||||
Scope.AssignToNearest(varSymbol, luaVariable);
|
||||
}
|
||||
|
||||
private static VariableSymbol BuildFunctionVariableSymbol(string name, System.Type type)
|
||||
{
|
||||
var genericParameters = type.GetGenericArguments();
|
||||
var parameters = new List<InternalFunctionVariableSymbol.InternalFunctionParameter>();
|
||||
for (var i = 0; i < genericParameters.Length - 1; i++)
|
||||
{
|
||||
var t = genericParameters[i].GetScriptType();
|
||||
parameters.Add(new InternalFunctionVariableSymbol.InternalFunctionParameter(t, false));
|
||||
}
|
||||
|
||||
var result = genericParameters[parameters.Count - 1].GetScriptType();
|
||||
return new InternalFunctionVariableSymbol(name, true, result, parameters.ToArray());
|
||||
}
|
||||
|
||||
private static Type DeriveValidTypes(System.Type type)
|
||||
{
|
||||
if (type == typeof(ScriptString))
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<HintPath>..\..\..\..\..\..\usr\share\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\Microsoft.CSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Collections.Immutable, Version=1.2.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<HintPath>..\..\..\..\..\usr\share\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Collections.Immutable.dll</HintPath>
|
||||
</Reference>
|
||||
|
|
Loading…
Reference in New Issue