Initial work on the concept of statements
This commit is contained in:
parent
3d811ff801
commit
ec7a32240f
|
@ -18,10 +18,23 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
public BoundScript BindScript(ScriptSyntax e)
|
public BoundScript BindScript(ScriptSyntax e)
|
||||||
{
|
{
|
||||||
var bound = BindExpression(e.Statement);
|
var bound = BindStatement(e.Statement);
|
||||||
return new BoundScript(bound);
|
return new BoundScript(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BoundStatement BindStatement(StatementSyntax s)
|
||||||
|
{
|
||||||
|
switch (s.Kind)
|
||||||
|
{
|
||||||
|
case SyntaxKind.ExpressionStatement:
|
||||||
|
return BindExpressionStatement((ExpressionStatementSyntax) s);
|
||||||
|
case SyntaxKind.AssignmentExpression:
|
||||||
|
return BindAssignmentStatement((AssignmentExpressionSyntax) s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public BoundExpression BindExpression(ExpressionSyntax e)
|
public BoundExpression BindExpression(ExpressionSyntax e)
|
||||||
{
|
{
|
||||||
switch (e.Kind)
|
switch (e.Kind)
|
||||||
|
@ -34,8 +47,6 @@ namespace Upsilon.Binder
|
||||||
return BindLiteralExpression((LiteralExpressionSyntax) e);
|
return BindLiteralExpression((LiteralExpressionSyntax) e);
|
||||||
case SyntaxKind.ParenthesizedExpression:
|
case SyntaxKind.ParenthesizedExpression:
|
||||||
return BindParenthesizedExpression((ParenthesizedExpressionSyntax) e);
|
return BindParenthesizedExpression((ParenthesizedExpressionSyntax) e);
|
||||||
case SyntaxKind.AssignmentExpression:
|
|
||||||
return BindAssignmentExpression((AssignmentExpressionSyntax) e);
|
|
||||||
case SyntaxKind.VariableExpression:
|
case SyntaxKind.VariableExpression:
|
||||||
return BindVariableExpression((VariableExpressionSyntax) e);
|
return BindVariableExpression((VariableExpressionSyntax) e);
|
||||||
case SyntaxKind.BadExpression:
|
case SyntaxKind.BadExpression:
|
||||||
|
@ -105,7 +116,13 @@ namespace Upsilon.Binder
|
||||||
return BindExpression(e.Expression);
|
return BindExpression(e.Expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundExpression BindAssignmentExpression(AssignmentExpressionSyntax e)
|
private BoundStatement BindExpressionStatement(ExpressionStatementSyntax s)
|
||||||
|
{
|
||||||
|
var exp = BindExpression(s.Expression);
|
||||||
|
return new BoundExpressionStatement(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BoundStatement BindAssignmentStatement(AssignmentExpressionSyntax e)
|
||||||
{
|
{
|
||||||
var name = e.Identifier.Name;
|
var name = e.Identifier.Name;
|
||||||
var boundExpression = BindExpression(e.Expression);
|
var boundExpression = BindExpression(e.Expression);
|
||||||
|
@ -123,11 +140,12 @@ namespace Upsilon.Binder
|
||||||
if (boundExpression.Type != variable.Type)
|
if (boundExpression.Type != variable.Type)
|
||||||
{
|
{
|
||||||
_diagnostics.LogCannotConvert(boundExpression.Type, variable.Type, e.Span);
|
_diagnostics.LogCannotConvert(boundExpression.Type, variable.Type, e.Span);
|
||||||
return boundExpression;
|
throw new NotImplementedException();
|
||||||
|
//return boundExpression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BoundAssignmenExpression(variable, boundExpression);
|
return new BoundVariableAssignment(variable, boundExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BoundExpression BindVariableExpression(VariableExpressionSyntax e)
|
private BoundExpression BindVariableExpression(VariableExpressionSyntax e)
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Upsilon.BaseTypes;
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
public class BoundAssignmenExpression : BoundExpression
|
public class BoundAssignmenExpression : BoundExpression
|
||||||
{
|
{
|
||||||
public BoundAssignmenExpression(VariableSymbol variable, BoundExpression expression)
|
public BoundAssignmenExpression(VariableSymbol variable, BoundExpression expression)
|
||||||
|
@ -15,5 +16,5 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
public override BoundKind Kind => BoundKind.BoundAssignmentExpression;
|
public override BoundKind Kind => BoundKind.BoundAssignmentExpression;
|
||||||
public override Type Type { get; }
|
public override Type Type { get; }
|
||||||
}
|
}*/
|
||||||
}
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace Upsilon.Binder
|
||||||
|
{
|
||||||
|
public class BoundExpressionStatement : BoundStatement
|
||||||
|
{
|
||||||
|
public BoundExpression Expression { get; }
|
||||||
|
public override BoundKind Kind => BoundKind.BoundExpressionStatement;
|
||||||
|
|
||||||
|
public BoundExpressionStatement(BoundExpression expression)
|
||||||
|
{
|
||||||
|
Expression = expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,10 @@ namespace Upsilon.Binder
|
||||||
BoundLiteralExpression,
|
BoundLiteralExpression,
|
||||||
BoundBinaryExpression,
|
BoundBinaryExpression,
|
||||||
BoundUnaryExpression,
|
BoundUnaryExpression,
|
||||||
BoundAssignmentExpression,
|
VariableExpression,
|
||||||
VariableExpression
|
|
||||||
|
// Statements
|
||||||
|
BoundAssignmentStatement,
|
||||||
|
BoundExpressionStatement
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,14 +1,14 @@
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
public class BoundScript : BoundNode
|
public class BoundScript : BoundStatement
|
||||||
{
|
{
|
||||||
public BoundScript(BoundExpression statement)
|
public BoundScript(BoundStatement statement)
|
||||||
{
|
{
|
||||||
Statement = statement;
|
Statement = statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BoundKind Kind => BoundKind.BoundScript;
|
public override BoundKind Kind => BoundKind.BoundScript;
|
||||||
|
|
||||||
public BoundExpression Statement { get; }
|
public BoundStatement Statement { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Upsilon.Binder
|
||||||
|
{
|
||||||
|
public abstract class BoundStatement : BoundNode
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
namespace Upsilon.Binder
|
||||||
|
{
|
||||||
|
public class BoundVariableAssignment : BoundStatement
|
||||||
|
{
|
||||||
|
public VariableSymbol Variable { get; }
|
||||||
|
public BoundExpression BoundExpression { get; }
|
||||||
|
|
||||||
|
public BoundVariableAssignment(VariableSymbol variable, BoundExpression boundExpression)
|
||||||
|
{
|
||||||
|
Variable = variable;
|
||||||
|
BoundExpression = boundExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override BoundKind Kind => BoundKind.BoundAssignmentStatement;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ namespace Upsilon.Evaluator
|
||||||
public class Evaluator
|
public class Evaluator
|
||||||
{
|
{
|
||||||
private readonly Diagnostics _diagnostics;
|
private readonly Diagnostics _diagnostics;
|
||||||
|
private object _value;
|
||||||
public Script Script { get; }
|
public Script Script { get; }
|
||||||
private readonly Dictionary<VariableSymbol, object> _variables = new Dictionary<VariableSymbol, object>();
|
private readonly Dictionary<VariableSymbol, object> _variables = new Dictionary<VariableSymbol, object>();
|
||||||
|
|
||||||
|
@ -25,7 +26,26 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
public object Evaluate(BoundScript e)
|
public object Evaluate(BoundScript e)
|
||||||
{
|
{
|
||||||
return EvaluateExpression(e.Statement);
|
EvaluateStatement(e.Statement);
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EvaluateStatement(BoundStatement e)
|
||||||
|
{
|
||||||
|
switch (e.Kind)
|
||||||
|
{
|
||||||
|
case BoundKind.BoundAssignmentStatement:
|
||||||
|
EvaluateAssignmentStatement((BoundVariableAssignment) e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EvaluateExpressionStatement((BoundExpressionStatement) e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EvaluateExpressionStatement(BoundExpressionStatement e)
|
||||||
|
{
|
||||||
|
_value = EvaluateExpression(e.Expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private object EvaluateExpression(BoundExpression e)
|
private object EvaluateExpression(BoundExpression e)
|
||||||
|
@ -38,8 +58,6 @@ namespace Upsilon.Evaluator
|
||||||
return EvaluateBinaryExpression((BoundBinaryExpression) e);
|
return EvaluateBinaryExpression((BoundBinaryExpression) e);
|
||||||
case BoundKind.BoundUnaryExpression:
|
case BoundKind.BoundUnaryExpression:
|
||||||
return EvaluateUnaryExpression((BoundUnaryExpression) e);
|
return EvaluateUnaryExpression((BoundUnaryExpression) e);
|
||||||
case BoundKind.BoundAssignmentExpression:
|
|
||||||
return EvaluateAssignmentExpression((BoundAssignmenExpression) e);
|
|
||||||
case BoundKind.VariableExpression:
|
case BoundKind.VariableExpression:
|
||||||
return EvaluateVariableExpression((BoundVariableExpression) e);
|
return EvaluateVariableExpression((BoundVariableExpression) e);
|
||||||
default:
|
default:
|
||||||
|
@ -86,10 +104,11 @@ namespace Upsilon.Evaluator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private object EvaluateAssignmentExpression(BoundAssignmenExpression e)
|
private object EvaluateAssignmentStatement(BoundVariableAssignment e)
|
||||||
{
|
{
|
||||||
var val = EvaluateExpression(e.Expression);
|
var val = EvaluateExpression(e.BoundExpression);
|
||||||
_variables[e.Variable] = val;
|
_variables[e.Variable] = val;
|
||||||
|
_value = val;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Upsilon.Text;
|
using Upsilon.Text;
|
||||||
|
|
||||||
|
@ -50,25 +49,37 @@ namespace Upsilon.Parser
|
||||||
|
|
||||||
public ScriptSyntax ParseScriptSyntax()
|
public ScriptSyntax ParseScriptSyntax()
|
||||||
{
|
{
|
||||||
var expression = ParseExpression();
|
var statement = ParseStatement();
|
||||||
var eof = MatchToken(SyntaxKind.EndOfFile);
|
var eof = MatchToken(SyntaxKind.EndOfFile);
|
||||||
return new ScriptSyntax(expression, eof);
|
return new ScriptSyntax(statement, eof);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatementSyntax ParseStatement()
|
||||||
|
{
|
||||||
|
if (Current.Kind == SyntaxKind.Identifier && Next.Kind == SyntaxKind.Equals)
|
||||||
|
{
|
||||||
|
return ParseAssignmentExpression();
|
||||||
|
}
|
||||||
|
if (Current.Kind == SyntaxKind.LocalKeyword && Next.Kind == SyntaxKind.Identifier)
|
||||||
|
{
|
||||||
|
return ParseAssignmentExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseExpressionStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExpressionStatementSyntax ParseExpressionStatement()
|
||||||
|
{
|
||||||
|
var expression = ParseExpression();
|
||||||
|
return new ExpressionStatementSyntax(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExpressionSyntax ParseExpression()
|
public ExpressionSyntax ParseExpression()
|
||||||
{
|
{
|
||||||
if (Current.Kind == SyntaxKind.Identifier && Next.Kind == SyntaxKind.Equals)
|
|
||||||
{
|
|
||||||
return AssignmentExpression();
|
|
||||||
}
|
|
||||||
if (Current.Kind == SyntaxKind.LocalKeyword && Next.Kind == SyntaxKind.Identifier)
|
|
||||||
{
|
|
||||||
return AssignmentExpression();
|
|
||||||
}
|
|
||||||
return ParseBinaryExpression();
|
return ParseBinaryExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
private AssignmentExpressionSyntax AssignmentExpression()
|
private AssignmentExpressionSyntax ParseAssignmentExpression()
|
||||||
{
|
{
|
||||||
SyntaxToken localKeyword = null;
|
SyntaxToken localKeyword = null;
|
||||||
if (Current.Kind == SyntaxKind.LocalKeyword)
|
if (Current.Kind == SyntaxKind.LocalKeyword)
|
||||||
|
|
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Upsilon.Parser
|
namespace Upsilon.Parser
|
||||||
{
|
{
|
||||||
public class AssignmentExpressionSyntax : ExpressionSyntax
|
public class AssignmentExpressionSyntax : StatementSyntax
|
||||||
{
|
{
|
||||||
public AssignmentExpressionSyntax(SyntaxToken localToken, IdentifierToken identifier, SyntaxToken equalsToken,
|
public AssignmentExpressionSyntax(SyntaxToken localToken, IdentifierToken identifier, SyntaxToken equalsToken,
|
||||||
ExpressionSyntax expression)
|
ExpressionSyntax expression)
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Upsilon.Parser
|
||||||
|
{
|
||||||
|
public class ExpressionStatementSyntax : StatementSyntax
|
||||||
|
{
|
||||||
|
public ExpressionSyntax Expression { get; }
|
||||||
|
|
||||||
|
public ExpressionStatementSyntax(ExpressionSyntax expression)
|
||||||
|
{
|
||||||
|
Expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SyntaxKind Kind => SyntaxKind.ExpressionStatement;
|
||||||
|
public override IEnumerable<SyntaxNode> ChildNodes()
|
||||||
|
{
|
||||||
|
yield return Expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,9 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Upsilon.Parser
|
namespace Upsilon.Parser
|
||||||
{
|
{
|
||||||
public class ScriptSyntax : SyntaxNode
|
public class ScriptSyntax : StatementSyntax
|
||||||
{
|
{
|
||||||
public ScriptSyntax(ExpressionSyntax statement, SyntaxToken endOfFileToken)
|
public ScriptSyntax(StatementSyntax statement, SyntaxToken endOfFileToken)
|
||||||
{
|
{
|
||||||
Statement = statement;
|
Statement = statement;
|
||||||
EndOfFileToken = endOfFileToken;
|
EndOfFileToken = endOfFileToken;
|
||||||
|
@ -12,7 +12,7 @@ namespace Upsilon.Parser
|
||||||
|
|
||||||
public override SyntaxKind Kind => SyntaxKind.ScriptUnit;
|
public override SyntaxKind Kind => SyntaxKind.ScriptUnit;
|
||||||
|
|
||||||
public ExpressionSyntax Statement { get; }
|
public StatementSyntax Statement { get; }
|
||||||
public SyntaxToken EndOfFileToken { get; }
|
public SyntaxToken EndOfFileToken { get; }
|
||||||
|
|
||||||
public override IEnumerable<SyntaxNode> ChildNodes()
|
public override IEnumerable<SyntaxNode> ChildNodes()
|
|
@ -0,0 +1,7 @@
|
||||||
|
namespace Upsilon.Parser
|
||||||
|
{
|
||||||
|
public abstract class StatementSyntax : SyntaxNode
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,8 @@ namespace Upsilon.Parser
|
||||||
return SyntaxKind.OrKeyword;
|
return SyntaxKind.OrKeyword;
|
||||||
case "local":
|
case "local":
|
||||||
return SyntaxKind.LocalKeyword;
|
return SyntaxKind.LocalKeyword;
|
||||||
|
case "end":
|
||||||
|
return SyntaxKind.EndKeyword;
|
||||||
default:
|
default:
|
||||||
return SyntaxKind.Identifier;
|
return SyntaxKind.Identifier;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ namespace Upsilon.Parser
|
||||||
AndKeyword,
|
AndKeyword,
|
||||||
OrKeyword,
|
OrKeyword,
|
||||||
LocalKeyword,
|
LocalKeyword,
|
||||||
|
EndKeyword,
|
||||||
|
|
||||||
Identifier,
|
Identifier,
|
||||||
|
|
||||||
|
@ -41,5 +42,8 @@ namespace Upsilon.Parser
|
||||||
|
|
||||||
// script unit
|
// script unit
|
||||||
ScriptUnit,
|
ScriptUnit,
|
||||||
|
|
||||||
|
// statements
|
||||||
|
ExpressionStatement
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=parser_005Cexpressionsyntax/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=parser_005Cexpressionsyntax/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=parser_005Cstatementsyntax/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
Loading…
Reference in New Issue