Made indexable also work with full stop index

This commit is contained in:
Deukhoofd 2018-11-20 14:05:34 +01:00
parent 066af47b5b
commit df8c7b99c9
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
10 changed files with 130 additions and 15 deletions

View File

@ -4,6 +4,7 @@ using System.Collections.Immutable;
using Upsilon.BaseTypes;
using Upsilon.BaseTypes.Number;
using Upsilon.Parser;
using Upsilon.Text;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder
@ -83,6 +84,8 @@ namespace Upsilon.Binder
return BindTableExpression((TableExpressionSyntax) e);
case SyntaxKind.IndexExpression:
return BindIndexExpression((IndexExpressionSyntax) e);
case SyntaxKind.FullStopIndexExpression:
return BindFullStopIndexExpression((FullStopIndexExpressionSyntax) e);
case SyntaxKind.FunctionExpression:
return BindFunctionExpression((FunctionExpressionSyntax) e);
case SyntaxKind.BadExpression:
@ -452,11 +455,34 @@ namespace Upsilon.Binder
}
}
private BoundExpression BindFullStopIndexExpression(FullStopIndexExpressionSyntax e)
{
var expression = BindExpression(e.Expression);
var index = e.Index.Name;
switch (expression.Type)
{
case Type.Table:
case Type.UserData:
case Type.Unknown:
return new BoundFullStopIndexExpression(expression, index);
case Type.String:
return new BoundFullStopIndexExpression(expression, index);
default:
_diagnostics.LogInvalidIndexExpression(expression.Type, Type.String, e.Span);
return new BoundLiteralExpression(new LuaNull());
}
}
private BoundStatement BindTableAssignmentStatement(TableAssigmentStatementSyntax e)
{
var tableIndexExpression = (BoundIndexExpression)BindExpression(e.TableExpression);
BoundExpression indexableExpression;
if (e.TableExpression.Kind == SyntaxKind.IndexExpression)
indexableExpression = (BoundIndexExpression)BindExpression(e.TableExpression);
else
indexableExpression = (BoundFullStopIndexExpression)BindExpression(e.TableExpression);
var value = BindExpression(e.Expression);
return new BoundTableAssigmentStatement(tableIndexExpression, value);
return new BoundTableAssigmentStatement(indexableExpression, value);
}
}
}

View File

@ -18,4 +18,19 @@ namespace Upsilon.Binder
public override BoundKind Kind => BoundKind.BoundIndexExpression;
public override Type Type { get; }
}
public class BoundFullStopIndexExpression : BoundExpression
{
public BoundExpression Expression { get; }
public string Index { get; }
public BoundFullStopIndexExpression(BoundExpression expression, string index)
{
Expression = expression;
Index = index;
}
public override BoundKind Kind => BoundKind.BoundFullstopIndexExpression;
public override Type Type => Type.Unknown;
}
}

View File

@ -22,6 +22,7 @@ namespace Upsilon.Binder
BoundPromise,
BoundReturnStatement,
BoundFunctionAssignmentStatement,
BoundTableAssigmentStatement
BoundTableAssigmentStatement,
BoundFullstopIndexExpression
}
}

View File

@ -2,10 +2,10 @@ namespace Upsilon.Binder
{
public class BoundTableAssigmentStatement : BoundStatement
{
public BoundIndexExpression TableIndexExpression { get; }
public BoundExpression TableIndexExpression { get; }
public BoundExpression Value { get; }
public BoundTableAssigmentStatement(BoundIndexExpression tableIndexExpression, BoundExpression value)
public BoundTableAssigmentStatement(BoundExpression tableIndexExpression, BoundExpression value)
{
TableIndexExpression = tableIndexExpression;
Value = value;

View File

@ -71,6 +71,7 @@ namespace Upsilon.Evaluator
case BoundKind.BoundFunctionExpression:
case BoundKind.BoundTableExpression:
case BoundKind.BoundIndexExpression:
case BoundKind.BoundFullstopIndexExpression:
_lastValue = EvaluateExpression((BoundExpression) b);
break;
case BoundKind.BoundAssignmentStatement:
@ -148,6 +149,8 @@ namespace Upsilon.Evaluator
return EvaluateBoundFunctionStatement((BoundFunctionExpression) e);
case BoundKind.BoundPromise:
return EvaluateUnboundFunctionStatement((UnboundFunctionExpression) e);
case BoundKind.BoundFullstopIndexExpression:
return EvaluateFullStopIndexExpression((BoundFullStopIndexExpression) e);
default:
throw new NotImplementedException();
}
@ -343,16 +346,41 @@ namespace Upsilon.Evaluator
{
scope = scopeOwner.EvaluationScope;
}
var evaluator = new Evaluator(_diagnostics, scope);
var indexer = evaluator.EvaluateExpression(e.Index);
var indexer = EvaluateExpression(e.Index);
return indexable.Get(indexer.ToString(), scope);
}
private LuaType EvaluateFullStopIndexExpression(BoundFullStopIndexExpression e)
{
var variable = EvaluateExpression(e.Expression);
if (!(variable is IIndexable indexable))
{
throw new Exception("Variable is not indexable.");
}
var scope = Scope;
if (variable is IScopeOwner scopeOwner)
{
scope = scopeOwner.EvaluationScope;
}
return indexable.Get(e.Index, scope);
}
private void EvaluateTableAssignmentStatement(BoundTableAssigmentStatement e)
{
var table = EvaluateExpression(e.TableIndexExpression.Identifier);
var index = EvaluateExpression(e.TableIndexExpression.Index);
LuaType table;
LuaType index;
if (e.TableIndexExpression.Kind == BoundKind.BoundIndexExpression)
{
table = EvaluateExpression(((BoundIndexExpression)e.TableIndexExpression).Identifier);
index = EvaluateExpression(((BoundIndexExpression)e.TableIndexExpression).Index);
}
else
{
table = EvaluateExpression(((BoundFullStopIndexExpression)e.TableIndexExpression).Expression);
index = ((BoundFullStopIndexExpression) e.TableIndexExpression).Index.ToLuaType();
}
var value = EvaluateExpression(e.Value);
if (!(table is IIndexable indexable))
{

View File

@ -27,4 +27,26 @@ namespace Upsilon.Parser
yield return CloseBracket;
}
}
public class FullStopIndexExpressionSyntax : ExpressionSyntax
{
public ExpressionSyntax Expression { get; }
public SyntaxToken FullStop { get; }
public IdentifierToken Index { get; }
public FullStopIndexExpressionSyntax(ExpressionSyntax expression, SyntaxToken fullStop, IdentifierToken index)
{
Expression = expression;
FullStop = fullStop;
Index = index;
}
public override SyntaxKind Kind => SyntaxKind.FullStopIndexExpression;
public override IEnumerable<SyntaxNode> ChildNodes()
{
yield return Expression;
yield return FullStop;
yield return Index;
}
}
}

View File

@ -74,6 +74,8 @@ namespace Upsilon.Parser
return new SyntaxToken(SyntaxKind.OpenBracket, _position, "[", null);
case ']':
return new SyntaxToken(SyntaxKind.CloseBracket, _position, "]", null);
case '.':
return new SyntaxToken(SyntaxKind.FullStop, _position, ".", null);
case ',':
return new SyntaxToken(SyntaxKind.Comma, _position, ",", null);
case '"':

View File

@ -178,6 +178,10 @@ namespace Upsilon.Parser
{
return ParseTableAssignmentExpression(expression);
}
if (expression.Kind == SyntaxKind.FullStopIndexExpression && Current.Kind == SyntaxKind.Equals)
{
return ParseTableAssignmentExpression(expression);
}
return new ExpressionStatementSyntax(expression);
}
@ -199,12 +203,15 @@ namespace Upsilon.Parser
{
expression = ParseBinaryExpression();
}
while (Current.Kind == SyntaxKind.OpenBracket || Current.Kind == SyntaxKind.OpenParenthesis)
while (Current.Kind == SyntaxKind.OpenBracket || Current.Kind == SyntaxKind.OpenParenthesis ||
Current.Kind == SyntaxKind.FullStop)
{
if (Current.Kind == SyntaxKind.OpenBracket)
expression = ParseIndexExpression(expression);
else if (Current.Kind == SyntaxKind.OpenParenthesis)
expression = ParseFunctionCallExpression(expression);
else if (Current.Kind == SyntaxKind.FullStop)
expression = ParseFullStopIndexExpression(expression);
}
return expression;
}
@ -317,12 +324,24 @@ namespace Upsilon.Parser
private ExpressionSyntax ParseIndexExpression(ExpressionSyntax expression)
{
var openBracket = MatchToken(SyntaxKind.OpenBracket);
var index = ParseExpression();
var openBracket = MatchToken(SyntaxKind.OpenBracket);
var index = ParseExpression();
var closeBracket = MatchToken(SyntaxKind.CloseBracket);
return new IndexExpressionSyntax(expression, openBracket, index, closeBracket);
}
private ExpressionSyntax ParseFullStopIndexExpression(ExpressionSyntax expression)
{
var fullStop = MatchToken(SyntaxKind.FullStop);
var index = MatchToken(SyntaxKind.Identifier);
if (index is IdentifierToken identifier)
{
return new FullStopIndexExpressionSyntax(expression, fullStop, identifier);
}
_diagnostics.LogBadCharacter(expression.Span, SyntaxKind.Identifier);
return new BadExpressionSyntax();
}
private ExpressionSyntax ParseParenthesizedExpression()
{
var l = MatchToken(SyntaxKind.OpenParenthesis);

View File

@ -21,6 +21,7 @@ namespace Upsilon.Parser
Tilde,
TildeEquals,
Comma,
FullStop,
String,
OpenBrace,
CloseBrace,
@ -56,6 +57,7 @@ namespace Upsilon.Parser
BadExpression,
TableExpression,
IndexExpression,
FullStopIndexExpression,
// script unit
ScriptUnit,
@ -69,6 +71,6 @@ namespace Upsilon.Parser
FunctionExpression,
ReturnStatement,
FunctionAssignmentStatement,
TableAssignmentStatement
TableAssignmentStatement,
}
}

View File

@ -32,7 +32,7 @@ namespace Ycicle
continue;
}
//Console.WriteLine(script.PrettyPrintSyntaxTree());
var evaluate = script.Evaluate<double>();
var evaluate = script.Evaluate();
if (script.Diagnostics.Messages.Count > 0)
{