Work on type checking variables when getting them from tables

This commit is contained in:
Deukhoofd 2018-11-27 14:37:58 +01:00
parent dca8773e54
commit a0861e090f
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
3 changed files with 40 additions and 8 deletions

View File

@ -254,7 +254,7 @@ namespace Upsilon.Binder
{
var tableExpression = (BoundTableExpression) assignment;
variable = new TableVariableSymbol(name, tableExpression.ValueType, isLocal,
tableExpression.Expressions.Values.ToArray());
tableExpression.Expressions);
}
else
{
@ -472,7 +472,6 @@ namespace Upsilon.Binder
{
var keyType = Type.Unknown;
var valueType = Type.Unknown;
var dictionary = new Dictionary<string, bool>();
var statements = ImmutableArray.CreateBuilder<BoundStatement>();
var s = Scope;
Scope = BoundScope.WithReadOnlyScope(s);
@ -500,6 +499,14 @@ namespace Upsilon.Binder
switch (expression.Type)
{
case Type.Table:
if (expression.Kind == BoundKind.BoundTableExpression && index.Kind == BoundKind.BoundLiteralExpression)
{
var table = (BoundTableExpression)expression;
var realIndex = (BoundLiteralExpression) index;
var variable = table.Expressions[realIndex.Value.ToString()];
return new BoundIndexExpression(expression, index, variable.Type, e.Span);
}
return new BoundIndexExpression(expression, index, Type.Unknown, e.Span);
case Type.UserData:
case Type.Unknown:
return new BoundIndexExpression(expression, index, Type.Unknown, e.Span);
@ -518,11 +525,34 @@ namespace Upsilon.Binder
switch (expression.Type)
{
case Type.Table:
if (expression.Kind == BoundKind.BoundTableExpression)
{
var table = (BoundTableExpression)expression;
if (table.Expressions.TryGetValue(index, out var variable))
{
return new BoundFullStopIndexExpression(expression, index, variable.Type, e.Span);
}
_diagnostics.LogError($"No variable {index} found in table.", e.Span);
}
if (expression.Kind == BoundKind.VariableExpression)
{
var table = (BoundVariableExpression)expression;
var realTable = table.Variable;
var variableDic = ((TableVariableSymbol) realTable.VariableSymbol).Variables;
if (variableDic.TryGetValue(index, out var variable))
{
return new BoundFullStopIndexExpression(expression, index, variable.Type, e.Span);
}
_diagnostics.LogError($"No variable {index} found in table {realTable.VariableSymbol.Name}.",
e.Span);
}
return new BoundFullStopIndexExpression(expression, index, Type.Unknown, e.Span);
case Type.UserData:
case Type.Unknown:
return new BoundFullStopIndexExpression(expression, index, e.Span);
return new BoundFullStopIndexExpression(expression, index, Type.Unknown, e.Span);
case Type.String:
return new BoundFullStopIndexExpression(expression, index, e.Span);
return new BoundFullStopIndexExpression(expression, index, Type.String, e.Span);
default:
_diagnostics.LogInvalidIndexExpression(expression.Type, Type.String, e.Span);
return new BoundLiteralExpression(new ScriptNull(), e.Span);

View File

@ -35,10 +35,11 @@ namespace Upsilon.Binder
public BoundExpression Expression { get; }
public string Index { get; }
public BoundFullStopIndexExpression(BoundExpression expression, string index, TextSpan span) : base(span)
public BoundFullStopIndexExpression(BoundExpression expression, string index, Type type, TextSpan span) : base(span)
{
Expression = expression;
Index = index;
Type = type;
}
public override BoundKind Kind => BoundKind.BoundFullstopIndexExpression;
@ -49,6 +50,6 @@ namespace Upsilon.Binder
return this;
}
public override Type Type => Type.Unknown;
public override Type Type { get; }
}
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Upsilon.BaseTypes;
@ -34,9 +35,9 @@ namespace Upsilon.Binder
public class TableVariableSymbol : VariableSymbol
{
public Type OutType { get; }
public VariableSymbol[] Variables { get; }
public Dictionary<string, VariableSymbol> Variables { get; }
public TableVariableSymbol(string name, Type outType, bool local, VariableSymbol[] variables)
public TableVariableSymbol(string name, Type outType, bool local, Dictionary<string, VariableSymbol> variables)
:base (name, Type.Table, local)
{
OutType = outType;