From 65ae6f6f06e5bd0739fd6b8c908471d8b24659dd Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 26 Jan 2019 13:23:12 +0100 Subject: [PATCH] Better binding for index expressions --- Upsilon/BaseTypes/TypeConversion.cs | 3 --- .../BaseTypes/UserData/DictionaryUserData.cs | 25 +++++++++++++++++-- Upsilon/Binder/Binder.cs | 22 ++++++++++++++-- .../BoundExpressions/BoundIndexExpression.cs | 2 +- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Upsilon/BaseTypes/TypeConversion.cs b/Upsilon/BaseTypes/TypeConversion.cs index d49e6e3..a6bfde2 100644 --- a/Upsilon/BaseTypes/TypeConversion.cs +++ b/Upsilon/BaseTypes/TypeConversion.cs @@ -1,6 +1,5 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; @@ -8,8 +7,6 @@ using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.ScriptFunction; using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.BaseTypes.UserData; -using Upsilon.BoundTypes; -using Upsilon.Text; namespace Upsilon.BaseTypes { diff --git a/Upsilon/BaseTypes/UserData/DictionaryUserData.cs b/Upsilon/BaseTypes/UserData/DictionaryUserData.cs index 8b960f1..15ae61a 100644 --- a/Upsilon/BaseTypes/UserData/DictionaryUserData.cs +++ b/Upsilon/BaseTypes/UserData/DictionaryUserData.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.ScriptTypeInterfaces; @@ -17,7 +18,27 @@ namespace Upsilon.BaseTypes.UserData public DictionaryUserData(IDictionary dictionary) { Dictionary = dictionary; - BoundTypeName = BoundTypeHandler.GetTypeName(dictionary.GetType()); + var type = dictionary.GetType(); + var generics = type.GetGenericArguments(); + if (generics.Length == 2) + { + var keyType = generics[0]; + var valueType = generics[1]; + var boundKeyType = BoundTypeHandler.GetTypeName(keyType); + var boundValueType = BoundTypeHandler.GetTypeName(valueType); + var boundKey = boundKeyType == null + ? new UndefinedUserDataTypeContainer(keyType) + : new TypeContainer(boundKeyType); + var boundValue = boundValueType == null + ? new UndefinedUserDataTypeContainer(valueType) + : new TypeContainer(boundValueType); + Type = new CompositeTypeContainer(new[] {boundKey, boundValue}.ToImmutableArray()); + } + else + { + BoundTypeName = BoundTypeHandler.GetTypeName(type); + Type = BoundTypeName == null ? new UndefinedUserDataTypeContainer(type) : new TypeContainer(BoundTypeName); + } } public ScriptType Get(Diagnostics diagnostics, TextSpan span, ScriptType index, EvaluationScope scope) @@ -44,7 +65,7 @@ namespace Upsilon.BaseTypes.UserData } } - public override TypeContainer Type => new TypeContainer(BoundTypeName); + public override TypeContainer Type { get; } public override object ToCSharpObject() { return Dictionary; diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 9122efa..07a530a 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -505,8 +505,16 @@ namespace Upsilon.Binder } else { - variable = new UserDataVariableSymbol(name, - BoundTypeHandler.GetTypeDefinition(ud), isLocal); + var boundType = BoundTypeHandler.GetTypeDefinition(ud); + if (boundType != null) + { + variable = new UserDataVariableSymbol(name, + BoundTypeHandler.GetTypeDefinition(ud), isLocal); + } + else + { + variable = new VariableSymbol(name, assignment.Type, isLocal); + } } } else @@ -652,6 +660,12 @@ namespace Upsilon.Binder _diagnostics.LogError($"Unknown type name '{variable.TypeName.Name}'", variable.Span); variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown, true); } + else if (type.ScriptType == Type.Table) + { + variableSymbol = new TableVariableSymbol(variable.IdentifierName.Name, true, + new CompositeTypeContainer( + new TypeContainer[] {Type.Unknown, Type.Unknown}.ToImmutableArray())); + } else { variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, type, true); @@ -843,6 +857,10 @@ namespace Upsilon.Binder _diagnostics.LogError($"No variable '{realIndex.Value}' found in table '{realTable.VariableSymbol.Name}'.", e.Span); } + else if (expression.Type is CompositeTypeContainer compositeTypeContainer) + { + return new BoundIndexExpression(expression, index, compositeTypeContainer.Types[1], e.Span); + } return new BoundIndexExpression(expression, index, Type.Unknown, e.Span); case Type.UserData: case Type.Unknown: diff --git a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs index 56b2ece..1130a1b 100644 --- a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs @@ -7,7 +7,7 @@ namespace Upsilon.Binder { public class BoundIndexExpression : BoundExpression { - public BoundIndexExpression(BoundExpression identifier, BoundExpression index, Type type, TextSpan span) : base(span) + public BoundIndexExpression(BoundExpression identifier, BoundExpression index, TypeContainer type, TextSpan span) : base(span) { Identifier = identifier; Index = index;