Better binding for index expressions

This commit is contained in:
Deukhoofd 2019-01-26 13:23:12 +01:00
parent eeecd0225a
commit 65ae6f6f06
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
4 changed files with 44 additions and 8 deletions

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -8,8 +7,6 @@ using Upsilon.BaseTypes.Number;
using Upsilon.BaseTypes.ScriptFunction; using Upsilon.BaseTypes.ScriptFunction;
using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.BaseTypes.UserData; using Upsilon.BaseTypes.UserData;
using Upsilon.BoundTypes;
using Upsilon.Text;
namespace Upsilon.BaseTypes namespace Upsilon.BaseTypes
{ {

View File

@ -1,5 +1,6 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq; using System.Linq;
using Upsilon.BaseTypes.Number; using Upsilon.BaseTypes.Number;
using Upsilon.BaseTypes.ScriptTypeInterfaces; using Upsilon.BaseTypes.ScriptTypeInterfaces;
@ -17,7 +18,27 @@ namespace Upsilon.BaseTypes.UserData
public DictionaryUserData(IDictionary dictionary) public DictionaryUserData(IDictionary dictionary)
{ {
Dictionary = 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) 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() public override object ToCSharpObject()
{ {
return Dictionary; return Dictionary;

View File

@ -504,10 +504,18 @@ namespace Upsilon.Binder
variable = new VariableSymbol(name, Type.Unknown, isLocal); variable = new VariableSymbol(name, Type.Unknown, isLocal);
} }
else else
{
var boundType = BoundTypeHandler.GetTypeDefinition(ud);
if (boundType != null)
{ {
variable = new UserDataVariableSymbol(name, variable = new UserDataVariableSymbol(name,
BoundTypeHandler.GetTypeDefinition(ud), isLocal); BoundTypeHandler.GetTypeDefinition(ud), isLocal);
} }
else
{
variable = new VariableSymbol(name, assignment.Type, isLocal);
}
}
} }
else else
{ {
@ -652,6 +660,12 @@ namespace Upsilon.Binder
_diagnostics.LogError($"Unknown type name '{variable.TypeName.Name}'", variable.Span); _diagnostics.LogError($"Unknown type name '{variable.TypeName.Name}'", variable.Span);
variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, Type.Unknown, true); 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 else
{ {
variableSymbol = new UserDataVariableSymbol(variable.IdentifierName.Name, type, true); 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}'.", _diagnostics.LogError($"No variable '{realIndex.Value}' found in table '{realTable.VariableSymbol.Name}'.",
e.Span); 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); return new BoundIndexExpression(expression, index, Type.Unknown, e.Span);
case Type.UserData: case Type.UserData:
case Type.Unknown: case Type.Unknown:

View File

@ -7,7 +7,7 @@ namespace Upsilon.Binder
{ {
public class BoundIndexExpression : BoundExpression 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; Identifier = identifier;
Index = index; Index = index;