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.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
{

View File

@ -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;

View File

@ -504,10 +504,18 @@ namespace Upsilon.Binder
variable = new VariableSymbol(name, Type.Unknown, isLocal);
}
else
{
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:

View File

@ -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;