Made indexable also work with full stop index
This commit is contained in:
parent
066af47b5b
commit
df8c7b99c9
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ namespace Upsilon.Binder
|
|||
BoundPromise,
|
||||
BoundReturnStatement,
|
||||
BoundFunctionAssignmentStatement,
|
||||
BoundTableAssigmentStatement
|
||||
BoundTableAssigmentStatement,
|
||||
BoundFullstopIndexExpression
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 '"':
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -323,6 +330,18 @@ namespace Upsilon.Parser
|
|||
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);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue