Better evaluating of tables, allows things like functions to be added to tables as well

This commit is contained in:
Deukhoofd 2018-11-17 19:45:24 +01:00
parent b897adccf8
commit 44a2048153
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
5 changed files with 36 additions and 51 deletions

View File

@ -14,7 +14,7 @@ namespace Upsilon.BaseTypes
public override Type Type => Type.Function;
public override object ToCSharpObject()
{
return Block;
return this;
}
public ImmutableArray<VariableSymbol> Parameters { get; }

View File

@ -358,44 +358,21 @@ namespace Upsilon.Binder
{
var keyType = Type.Unknown;
var valueType = Type.Unknown;
var currentKey = 0;
var dictionary = new Dictionary<string, BoundExpression>();
var dictionary = new Dictionary<string, bool>();
var statements = ImmutableArray.CreateBuilder<BoundStatement>();
Scope = new BoundScope(Scope);
foreach (var expressionSyntax in e.Expressions)
{
if (expressionSyntax.Kind == SyntaxKind.AssignmentStatement)
{
var assignment = (AssignmentExpressionSyntax) expressionSyntax;
var key = assignment.Identifier.Name;
if (keyType == Type.Unknown)
keyType = Type.String;
if (dictionary.ContainsKey(key))
{
// TODO: Log
continue;
}
var bound = BindExpression(assignment.Expression);
if (valueType == Type.Unknown)
valueType = bound.Type;
dictionary.Add(key, bound);
}
else
{
var expression = (ExpressionSyntax) expressionSyntax;
currentKey++;
if (dictionary.ContainsKey(currentKey.ToString()))
{
// TODO: Log
continue;
}
if (keyType == Type.Unknown)
keyType = Type.Number;
var bound = BindExpression(expression);
if (valueType == Type.Unknown)
valueType = bound.Type;
dictionary.Add(currentKey.ToString(), bound);
}
var bound = BindStatement((StatementSyntax) expressionSyntax);
statements.Add(bound);
}
return new BoundTableExpression(keyType, valueType, dictionary);
foreach (var variable in Scope.Variables)
{
dictionary.Add(variable.Key, true);
}
Scope = Scope.ParentScope;
return new BoundTableExpression(keyType, valueType, dictionary, statements);
}
}

View File

@ -6,11 +6,13 @@ namespace Upsilon.Binder
{
public class BoundTableExpression : BoundExpression
{
public BoundTableExpression(Type keyType, Type valueType, Dictionary<string, BoundExpression> expressions)
public BoundTableExpression(Type keyType, Type valueType, Dictionary<string, bool> expressions,
ImmutableArray<BoundStatement>.Builder statements)
{
KeyType = keyType;
ValueType = valueType;
Expressions = expressions;
Statements = statements;
}
public override BoundKind Kind => BoundKind.BoundTableExpression;
@ -19,6 +21,7 @@ namespace Upsilon.Binder
public Type KeyType { get; }
public Type ValueType { get; }
public Dictionary<string, BoundExpression> Expressions { get; }
public Dictionary<string, bool> Expressions { get; }
public ImmutableArray<BoundStatement>.Builder Statements { get; }
}
}

View File

@ -250,6 +250,7 @@ namespace Upsilon.Evaluator
Scope.Set(boundFunctionStatement.Identifier, func);
else
Scope.SetGlobal(boundFunctionStatement.Identifier, func);
_lastValue = func;
}
private void EvaluateUnboundFunctionStatement(UnboundFunctionStatement unboundFunctionStatement)
@ -293,10 +294,23 @@ namespace Upsilon.Evaluator
private LuaType EvaluateTableExpression(BoundTableExpression e)
{
var dic = new Dictionary<string, LuaType>();
foreach (var boundExpression in e.Expressions)
var innerEvaluator = new Evaluator(_diagnostics, Scope);
var currentPos = 1;
foreach (var boundStatement in e.Statements)
{
var evaluated = EvaluateExpression(boundExpression.Value);
dic.Add(boundExpression.Key, evaluated);
if (boundStatement.Kind == BoundKind.BoundAssignmentStatement)
{
var assignment = (BoundVariableAssignment)boundStatement;
var key = assignment.Variable.Name;
var value = EvaluateExpression(assignment.BoundExpression);
dic.Add(key, value);
}
else
{
innerEvaluator.EvaluateStatement(boundStatement);
dic.Add(currentPos.ToString(), innerEvaluator._lastValue);
}
currentPos++;
}
return new LuaTable(dic);
}

View File

@ -297,16 +297,7 @@ namespace Upsilon.Parser
if (!lastCommaFound)
break;
var parsed = ParseStatement();
SyntaxNode node;
if (parsed.Kind == SyntaxKind.ExpressionStatement)
node = ((ExpressionStatementSyntax) parsed).Expression;
else if (parsed.Kind == SyntaxKind.AssignmentStatement)
node = parsed;
else
{
//TODO Better error handling
throw new Exception();
}
SyntaxNode node = parsed;
arrBuilder.Add(node);
lastCommaFound = Current.Kind == SyntaxKind.Comma;
if (lastCommaFound) NextToken();