Fixes for binding userdata method types

This commit is contained in:
Deukhoofd 2018-12-07 18:15:17 +01:00
parent 99ac02924b
commit bbab802f2d
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
6 changed files with 41 additions and 18 deletions

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.Evaluator; using Upsilon.Evaluator;
using Upsilon.Text; using Upsilon.Text;
@ -55,5 +56,10 @@ namespace Upsilon.BaseTypes
{ {
return _objects.GetType(); return _objects.GetType();
} }
public override string ToString()
{
return $"{{{string.Join(", ", _objects.Select(x => x.ToString()))}}}";
}
} }
} }

View File

@ -122,10 +122,15 @@ namespace Upsilon.BaseTypes
return Type.Table; return Type.Table;
if (t == typeof(IIterable)) if (t == typeof(IIterable))
return Type.Nil; return Type.Nil;
if (t == typeof(ScriptType)) if (t == typeof(SimpleScriptTable))
return Type.Unknown; return Type.Table;
if (typeof(IEnumerable).IsAssignableFrom(t)) if (typeof(IEnumerable).IsAssignableFrom(t))
return Type.Table; return Type.Table;
if (typeof(IIndexable).IsAssignableFrom(t))
return Type.Table;
if (t == typeof(ScriptType))
return Type.Unknown;
return Type.UserData; return Type.UserData;
} }

View File

@ -214,7 +214,8 @@ namespace Upsilon.Binder
} }
var returnType = Type.Unknown; var returnType = Type.Unknown;
if (ResolveVariable(expression) is FunctionVariableSymbol function) var resolved = ResolveVariable(expression);
if (resolved is FunctionVariableSymbol function)
{ {
if (function is ScriptFunctionVariableSymbol scriptFunction) if (function is ScriptFunctionVariableSymbol scriptFunction)
{ {
@ -278,6 +279,13 @@ namespace Upsilon.Binder
_diagnostics.LogError(error, span); _diagnostics.LogError(error, span);
} }
} }
else if (resolved is UserDataVariableSymbol udSymbol)
{
if (udSymbol.Parent != null && udSymbol.Parent.Properties[resolved.Name] is UserDataBoundMethod ubMethod)
{
returnType = ubMethod.ResultType;
}
}
return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType); return new BoundFunctionCallExpression(expression, parameters.ToImmutable(), e.Span, returnType);
} }
@ -299,22 +307,23 @@ namespace Upsilon.Binder
} }
if (indexerVariable.Type == Type.UserData) if (indexerVariable.Type == Type.UserData)
{ {
var bDefProperty = ((UserDataBoundTypeDefinition) ((FunctionParameterSymbol) indexerVariable) var parent =
.BoundTypeDefinition).Properties[fullStopIndexExpression.Index.ToLowerInvariant()]; (UserDataBoundTypeDefinition) ((UserDataVariableSymbol) indexerVariable).BoundTypeDefinition;
var bDefProperty = parent.Properties[fullStopIndexExpression.Index.ToLowerInvariant()];
var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType); var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType);
return new FunctionParameterSymbol(fullStopIndexExpression.Index, boundDef); return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, parent);
} }
if (indexerVariable.Type == Type.Unknown) if (indexerVariable.Type == Type.Unknown)
{ {
if (indexerVariable is FunctionParameterSymbol funcSymbol) if (indexerVariable is UserDataVariableSymbol funcSymbol)
{ {
var boundProp = funcSymbol.BoundTypeDefinition; var boundProp = funcSymbol.BoundTypeDefinition;
if (boundProp is UserDataBoundTypeDefinition bProp) if (boundProp is UserDataBoundTypeDefinition bProp)
{ {
var property = bProp.Properties[fullStopIndexExpression.Index.ToLowerInvariant()]; var property = bProp.Properties[fullStopIndexExpression.Index.ToLowerInvariant()];
var boundDef = BoundTypeHandler.GetTypeDefinition(property.ActualType); var boundDef = BoundTypeHandler.GetTypeDefinition(property.ActualType);
return new FunctionParameterSymbol(fullStopIndexExpression.Index, boundDef); return new UserDataVariableSymbol(fullStopIndexExpression.Index, boundDef, bProp);
} }
} }
@ -503,16 +512,16 @@ namespace Upsilon.Binder
if (type == null) if (type == null)
{ {
_diagnostics.LogError($"Unknown type name '{variable.TypeName.Name}'", variable.Span); _diagnostics.LogError($"Unknown type name '{variable.TypeName.Name}'", variable.Span);
variableSymbol = new FunctionParameterSymbol(variable.IdentifierName.Name, Type.Unknown); variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown);
} }
else else
{ {
variableSymbol = new FunctionParameterSymbol(variable.IdentifierName.Name, type); variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, type);
} }
} }
else else
{ {
variableSymbol = new FunctionParameterSymbol(variable.IdentifierName.Name, Type.Unknown); variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown);
} }
parameters.Add(new BoundVariableSymbol(variableSymbol, true, identifierToken.Span)); parameters.Add(new BoundVariableSymbol(variableSymbol, true, identifierToken.Span));
innerScope.DefineLocalVariable(variableSymbol); innerScope.DefineLocalVariable(variableSymbol);
@ -746,7 +755,7 @@ namespace Upsilon.Binder
var variableSymbol = ResolveVariable(expression); var variableSymbol = ResolveVariable(expression);
if (variableSymbol != null) if (variableSymbol != null)
{ {
var functionParameter = (FunctionParameterSymbol) variableSymbol; var functionParameter = (UserDataVariableSymbol) variableSymbol;
var udBoundDef = (UserDataBoundTypeDefinition)functionParameter.BoundTypeDefinition; var udBoundDef = (UserDataBoundTypeDefinition)functionParameter.BoundTypeDefinition;
if (udBoundDef.Properties.TryGetValue(index.ToLowerInvariant(), out var property)) if (udBoundDef.Properties.TryGetValue(index.ToLowerInvariant(), out var property))
{ {

View File

@ -3,18 +3,21 @@ using Upsilon.BoundTypes;
namespace Upsilon.Binder.VariableSymbols namespace Upsilon.Binder.VariableSymbols
{ {
public class FunctionParameterSymbol : VariableSymbol public class UserDataVariableSymbol : VariableSymbol
{ {
public BoundTypeDefinition BoundTypeDefinition { get; } public BoundTypeDefinition BoundTypeDefinition { get; }
public UserDataBoundTypeDefinition Parent { get; }
public FunctionParameterSymbol(string name, Type type) : base(name, type, true) public UserDataVariableSymbol(string name, Type type) : base(name, type, true)
{ {
_type = type; _type = type;
} }
public FunctionParameterSymbol(string name, BoundTypeDefinition type) : base(name, type.ScriptType, true) public UserDataVariableSymbol(string name, BoundTypeDefinition type, UserDataBoundTypeDefinition parent = null)
: base(name, type.ScriptType, true)
{ {
BoundTypeDefinition = type; BoundTypeDefinition = type;
Parent = parent;
} }
private Type _type; private Type _type;

View File

@ -76,7 +76,7 @@ namespace Upsilon.Evaluator
for (var index = 0; index < parameters.Length; index++) for (var index = 0; index < parameters.Length; index++)
{ {
var parameter = parameters[index]; var parameter = parameters[index];
var parameterSymbol = (FunctionParameterSymbol)function.Parameters[index].VariableSymbol; var parameterSymbol = (UserDataVariableSymbol)function.Parameters[index].VariableSymbol;
if (parameterSymbol.BoundTypeDefinition != null) if (parameterSymbol.BoundTypeDefinition != null)
{ {
bool isCompatible = false; bool isCompatible = false;

View File

@ -73,7 +73,7 @@ namespace Upsilon.StandardLibraries
UserDataTypeHandler.LoadType<MathLibrary>(); UserDataTypeHandler.LoadType<MathLibrary>();
funcs.Add("math", new MathLibrary().ToScriptType()); funcs.Add("math", new MathLibrary().ToScriptType());
boundFuncs.Add("math", boundFuncs.Add("math",
new FunctionParameterSymbol("math", BoundTypeHandler.GetTypeDefinition(typeof(MathLibrary)))); new UserDataVariableSymbol("math", BoundTypeHandler.GetTypeDefinition(typeof(MathLibrary))));
var scope = new EvaluationScope(funcs); var scope = new EvaluationScope(funcs);
var boundScope = new BoundScope(boundFuncs, null); var boundScope = new BoundScope(boundFuncs, null);
@ -87,7 +87,7 @@ namespace Upsilon.StandardLibraries
VariableSymbol varSymbol = null; VariableSymbol varSymbol = null;
if (ubDef != null) if (ubDef != null)
{ {
varSymbol = new FunctionParameterSymbol(name, ubDef); varSymbol = new UserDataVariableSymbol(name, ubDef);
} }
else else
{ {