Initial support for generic funcs

This commit is contained in:
Deukhoofd 2018-12-05 17:20:28 +01:00
parent 587c8dfff3
commit 520cd1ffcc
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
7 changed files with 88 additions and 4 deletions

View File

@ -2,7 +2,7 @@ using Upsilon.Evaluator;
namespace Upsilon.BaseTypes.ScriptFunction namespace Upsilon.BaseTypes.ScriptFunction
{ {
internal abstract class ScriptFunction : ScriptType public abstract class ScriptFunction : ScriptType
{ {
public override Type Type => Type.Function; public override Type Type => Type.Function;
public override object ToCSharpObject() public override object ToCSharpObject()

View File

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

View File

@ -1,6 +1,8 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Reflection;
using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.Number;
using Upsilon.BaseTypes.ScriptFunction;
using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.BaseTypes.UserData; using Upsilon.BaseTypes.UserData;
@ -42,6 +44,18 @@ namespace Upsilon.BaseTypes
{ {
return new DictionaryUserData(dic); 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); return new GenericUserData(o);
} }
@ -102,7 +116,8 @@ namespace Upsilon.BaseTypes
return Type.Nil; return Type.Nil;
if (t == typeof(ScriptType)) if (t == typeof(ScriptType))
return Type.Unknown; return Type.Unknown;
if (typeof(IEnumerable).IsAssignableFrom(t))
return Type.Table | Type.Function;
return Type.UserData; return Type.UserData;
} }

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Upsilon.BoundTypes; using Upsilon.BoundTypes;

View File

@ -50,7 +50,7 @@ namespace Upsilon.Binder.VariableSymbols
if (!functionParameter.ValidTypes.HasFlag(callingParameter.Type)) if (!functionParameter.ValidTypes.HasFlag(callingParameter.Type))
{ {
return (false, 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}'", $"Expected one of the following: {functionParameter.ValidTypes.ToString()}, got: '{callingParameter.Type}'",
callingParameter); callingParameter);
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq; using System.Linq;
using Upsilon.BaseTypes; using Upsilon.BaseTypes;
using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.Number;
@ -75,11 +76,44 @@ namespace Upsilon.StandardLibraries
{ {
var luaVariable = value.ToScriptType(); var luaVariable = value.ToScriptType();
var ubDef = BoundTypeHandler.GetTypeDefinition(value.GetType()); 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); BoundScope.AssignToNearest(varSymbol);
Scope.AssignToNearest(varSymbol, luaVariable); 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) private static Type DeriveValidTypes(System.Type type)
{ {
if (type == typeof(ScriptString)) if (type == typeof(ScriptString))

View File

@ -5,6 +5,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <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"> <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> <HintPath>..\..\..\..\..\usr\share\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Collections.Immutable.dll</HintPath>
</Reference> </Reference>