diff --git a/Upsilon/Binder/Binder.cs b/Upsilon/Binder/Binder.cs index 5bdd611..7c30107 100644 --- a/Upsilon/Binder/Binder.cs +++ b/Upsilon/Binder/Binder.cs @@ -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(); var statements = ImmutableArray.CreateBuilder(); 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); diff --git a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs index 99792bb..cd781eb 100644 --- a/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs +++ b/Upsilon/Binder/BoundExpressions/BoundIndexExpression.cs @@ -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; } } } \ No newline at end of file diff --git a/Upsilon/Binder/VariableSymbol.cs b/Upsilon/Binder/VariableSymbol.cs index c50f81f..c527588 100644 --- a/Upsilon/Binder/VariableSymbol.cs +++ b/Upsilon/Binder/VariableSymbol.cs @@ -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 Variables { get; } - public TableVariableSymbol(string name, Type outType, bool local, VariableSymbol[] variables) + public TableVariableSymbol(string name, Type outType, bool local, Dictionary variables) :base (name, Type.Table, local) { OutType = outType;