From bbab802f2d4c068a629eef7fc4dcdff166fbbadc Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 7 Dec 2018 18:15:17 +0100 Subject: [PATCH] Fixes for binding userdata method types --- Upsilon/BaseTypes/SimpleScriptTable.cs | 6 ++++ Upsilon/BaseTypes/TypeConversion.cs | 9 ++++-- Upsilon/Binder/Binder.cs | 29 ++++++++++++------- ...terSymbol.cs => UserDataVariableSymbol.cs} | 9 ++++-- Upsilon/Evaluator/Evaluator.cs | 2 +- Upsilon/StandardLibraries/StaticScope.cs | 4 +-- 6 files changed, 41 insertions(+), 18 deletions(-) rename Upsilon/Binder/VariableSymbols/{FunctionParameterSymbol.cs => UserDataVariableSymbol.cs} (53%) diff --git a/Upsilon/BaseTypes/SimpleScriptTable.cs b/Upsilon/BaseTypes/SimpleScriptTable.cs index e2faac7..14bef88 100644 --- a/Upsilon/BaseTypes/SimpleScriptTable.cs +++ b/Upsilon/BaseTypes/SimpleScriptTable.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.Evaluator; using Upsilon.Text; @@ -55,5 +56,10 @@ namespace Upsilon.BaseTypes { return _objects.GetType(); } + + public override string ToString() + { + return $"{{{string.Join(", ", _objects.Select(x => x.ToString()))}}}"; + } } } \ No newline at end of file diff --git a/Upsilon/BaseTypes/TypeConversion.cs b/Upsilon/BaseTypes/TypeConversion.cs index f5ac9ca..8a5c738 100644 --- a/Upsilon/BaseTypes/TypeConversion.cs +++ b/Upsilon/BaseTypes/TypeConversion.cs @@ -122,10 +122,15 @@ namespace Upsilon.BaseTypes return Type.Table; if (t == typeof(IIterable)) return Type.Nil; - if (t == typeof(ScriptType)) - return Type.Unknown; + if (t == typeof(SimpleScriptTable)) + return Type.Table; if (typeof(IEnumerable).IsAssignableFrom(t)) return Type.Table; + if (typeof(IIndexable).IsAssignableFrom(t)) + return Type.Table; + + if (t == typeof(ScriptType)) + return Type.Unknown; return Type.UserData; } diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 043600d..98bfbef 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -214,7 +214,8 @@ namespace Upsilon.Binder } var returnType = Type.Unknown; - if (ResolveVariable(expression) is FunctionVariableSymbol function) + var resolved = ResolveVariable(expression); + if (resolved is FunctionVariableSymbol function) { if (function is ScriptFunctionVariableSymbol scriptFunction) { @@ -278,6 +279,13 @@ namespace Upsilon.Binder _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); } @@ -299,22 +307,23 @@ namespace Upsilon.Binder } if (indexerVariable.Type == Type.UserData) { - var bDefProperty = ((UserDataBoundTypeDefinition) ((FunctionParameterSymbol) indexerVariable) - .BoundTypeDefinition).Properties[fullStopIndexExpression.Index.ToLowerInvariant()]; + var parent = + (UserDataBoundTypeDefinition) ((UserDataVariableSymbol) indexerVariable).BoundTypeDefinition; + var bDefProperty = parent.Properties[fullStopIndexExpression.Index.ToLowerInvariant()]; 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 is FunctionParameterSymbol funcSymbol) + if (indexerVariable is UserDataVariableSymbol funcSymbol) { var boundProp = funcSymbol.BoundTypeDefinition; if (boundProp is UserDataBoundTypeDefinition bProp) { var property = bProp.Properties[fullStopIndexExpression.Index.ToLowerInvariant()]; 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) { _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 { - variableSymbol = new FunctionParameterSymbol(variable.IdentifierName.Name, type); + variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, type); } } 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)); innerScope.DefineLocalVariable(variableSymbol); @@ -746,7 +755,7 @@ namespace Upsilon.Binder var variableSymbol = ResolveVariable(expression); if (variableSymbol != null) { - var functionParameter = (FunctionParameterSymbol) variableSymbol; + var functionParameter = (UserDataVariableSymbol) variableSymbol; var udBoundDef = (UserDataBoundTypeDefinition)functionParameter.BoundTypeDefinition; if (udBoundDef.Properties.TryGetValue(index.ToLowerInvariant(), out var property)) { diff --git a/Upsilon/Binder/VariableSymbols/FunctionParameterSymbol.cs b/Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs similarity index 53% rename from Upsilon/Binder/VariableSymbols/FunctionParameterSymbol.cs rename to Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs index 0af5d9f..ad71603 100644 --- a/Upsilon/Binder/VariableSymbols/FunctionParameterSymbol.cs +++ b/Upsilon/Binder/VariableSymbols/UserDataVariableSymbol.cs @@ -3,18 +3,21 @@ using Upsilon.BoundTypes; namespace Upsilon.Binder.VariableSymbols { - public class FunctionParameterSymbol : VariableSymbol + public class UserDataVariableSymbol : VariableSymbol { 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; } - 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; + Parent = parent; } private Type _type; diff --git a/Upsilon/Evaluator/Evaluator.cs b/Upsilon/Evaluator/Evaluator.cs index d919cf3..57d66b5 100644 --- a/Upsilon/Evaluator/Evaluator.cs +++ b/Upsilon/Evaluator/Evaluator.cs @@ -76,7 +76,7 @@ namespace Upsilon.Evaluator for (var index = 0; index < parameters.Length; index++) { var parameter = parameters[index]; - var parameterSymbol = (FunctionParameterSymbol)function.Parameters[index].VariableSymbol; + var parameterSymbol = (UserDataVariableSymbol)function.Parameters[index].VariableSymbol; if (parameterSymbol.BoundTypeDefinition != null) { bool isCompatible = false; diff --git a/Upsilon/StandardLibraries/StaticScope.cs b/Upsilon/StandardLibraries/StaticScope.cs index 239edd9..e0e8b63 100644 --- a/Upsilon/StandardLibraries/StaticScope.cs +++ b/Upsilon/StandardLibraries/StaticScope.cs @@ -73,7 +73,7 @@ namespace Upsilon.StandardLibraries UserDataTypeHandler.LoadType(); funcs.Add("math", new MathLibrary().ToScriptType()); boundFuncs.Add("math", - new FunctionParameterSymbol("math", BoundTypeHandler.GetTypeDefinition(typeof(MathLibrary)))); + new UserDataVariableSymbol("math", BoundTypeHandler.GetTypeDefinition(typeof(MathLibrary)))); var scope = new EvaluationScope(funcs); var boundScope = new BoundScope(boundFuncs, null); @@ -87,7 +87,7 @@ namespace Upsilon.StandardLibraries VariableSymbol varSymbol = null; if (ubDef != null) { - varSymbol = new FunctionParameterSymbol(name, ubDef); + varSymbol = new UserDataVariableSymbol(name, ubDef); } else {