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 Type Type => Type.Function;
public override object ToCSharpObject() public override object ToCSharpObject()
{ {
return Block; return this;
} }
public ImmutableArray<VariableSymbol> Parameters { get; } public ImmutableArray<VariableSymbol> Parameters { get; }

View File

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

View File

@ -6,11 +6,13 @@ namespace Upsilon.Binder
{ {
public class BoundTableExpression : BoundExpression 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; KeyType = keyType;
ValueType = valueType; ValueType = valueType;
Expressions = expressions; Expressions = expressions;
Statements = statements;
} }
public override BoundKind Kind => BoundKind.BoundTableExpression; public override BoundKind Kind => BoundKind.BoundTableExpression;
@ -19,6 +21,7 @@ namespace Upsilon.Binder
public Type KeyType { get; } public Type KeyType { get; }
public Type ValueType { 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); Scope.Set(boundFunctionStatement.Identifier, func);
else else
Scope.SetGlobal(boundFunctionStatement.Identifier, func); Scope.SetGlobal(boundFunctionStatement.Identifier, func);
_lastValue = func;
} }
private void EvaluateUnboundFunctionStatement(UnboundFunctionStatement unboundFunctionStatement) private void EvaluateUnboundFunctionStatement(UnboundFunctionStatement unboundFunctionStatement)
@ -293,10 +294,23 @@ namespace Upsilon.Evaluator
private LuaType EvaluateTableExpression(BoundTableExpression e) private LuaType EvaluateTableExpression(BoundTableExpression e)
{ {
var dic = new Dictionary<string, LuaType>(); 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); if (boundStatement.Kind == BoundKind.BoundAssignmentStatement)
dic.Add(boundExpression.Key, evaluated); {
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); return new LuaTable(dic);
} }

View File

@ -297,16 +297,7 @@ namespace Upsilon.Parser
if (!lastCommaFound) if (!lastCommaFound)
break; break;
var parsed = ParseStatement(); var parsed = ParseStatement();
SyntaxNode node; SyntaxNode node = parsed;
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();
}
arrBuilder.Add(node); arrBuilder.Add(node);
lastCommaFound = Current.Kind == SyntaxKind.Comma; lastCommaFound = Current.Kind == SyntaxKind.Comma;
if (lastCommaFound) NextToken(); if (lastCommaFound) NextToken();