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)
|
||||
{
|
||||
var bound = BindExpression(e.Statement);
|
||||
var bound = BindStatement(e.Statement);
|
||||
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)
|
||||
{
|
||||
switch (e.Kind)
|
||||
|
@ -34,8 +47,6 @@ namespace Upsilon.Binder
|
|||
return BindLiteralExpression((LiteralExpressionSyntax) e);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return BindParenthesizedExpression((ParenthesizedExpressionSyntax) e);
|
||||
case SyntaxKind.AssignmentExpression:
|
||||
return BindAssignmentExpression((AssignmentExpressionSyntax) e);
|
||||
case SyntaxKind.VariableExpression:
|
||||
return BindVariableExpression((VariableExpressionSyntax) e);
|
||||
case SyntaxKind.BadExpression:
|
||||
|
@ -105,7 +116,13 @@ namespace Upsilon.Binder
|
|||
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 boundExpression = BindExpression(e.Expression);
|
||||
|
@ -123,11 +140,12 @@ namespace Upsilon.Binder
|
|||
if (boundExpression.Type != variable.Type)
|
||||
{
|
||||
_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)
|
||||
|
|
|
@ -2,6 +2,7 @@ using Upsilon.BaseTypes;
|
|||
|
||||
namespace Upsilon.Binder
|
||||
{
|
||||
/*
|
||||
public class BoundAssignmenExpression : BoundExpression
|
||||
{
|
||||
public BoundAssignmenExpression(VariableSymbol variable, BoundExpression expression)
|
||||
|
@ -15,5 +16,5 @@ namespace Upsilon.Binder
|
|||
|
||||
public override BoundKind Kind => BoundKind.BoundAssignmentExpression;
|
||||
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,
|
||||
BoundBinaryExpression,
|
||||
BoundUnaryExpression,
|
||||
BoundAssignmentExpression,
|
||||
VariableExpression
|
||||
VariableExpression,
|
||||
|
||||
// Statements
|
||||
BoundAssignmentStatement,
|
||||
BoundExpressionStatement
|
||||
}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
namespace Upsilon.Binder
|
||||
{
|
||||
public class BoundScript : BoundNode
|
||||
public class BoundScript : BoundStatement
|
||||
{
|
||||
public BoundScript(BoundExpression statement)
|
||||
public BoundScript(BoundStatement statement)
|
||||
{
|
||||
Statement = statement;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
private readonly Diagnostics _diagnostics;
|
||||
private object _value;
|
||||
public Script Script { get; }
|
||||
private readonly Dictionary<VariableSymbol, object> _variables = new Dictionary<VariableSymbol, object>();
|
||||
|
||||
|
@ -25,7 +26,26 @@ namespace Upsilon.Evaluator
|
|||
|
||||
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)
|
||||
|
@ -38,8 +58,6 @@ namespace Upsilon.Evaluator
|
|||
return EvaluateBinaryExpression((BoundBinaryExpression) e);
|
||||
case BoundKind.BoundUnaryExpression:
|
||||
return EvaluateUnaryExpression((BoundUnaryExpression) e);
|
||||
case BoundKind.BoundAssignmentExpression:
|
||||
return EvaluateAssignmentExpression((BoundAssignmenExpression) e);
|
||||
case BoundKind.VariableExpression:
|
||||
return EvaluateVariableExpression((BoundVariableExpression) e);
|
||||
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;
|
||||
_value = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using Upsilon.Text;
|
||||
|
||||
|
@ -50,25 +49,37 @@ namespace Upsilon.Parser
|
|||
|
||||
public ScriptSyntax ParseScriptSyntax()
|
||||
{
|
||||
var expression = ParseExpression();
|
||||
var statement = ParseStatement();
|
||||
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()
|
||||
{
|
||||
if (Current.Kind == SyntaxKind.Identifier && Next.Kind == SyntaxKind.Equals)
|
||||
{
|
||||
return AssignmentExpression();
|
||||
}
|
||||
if (Current.Kind == SyntaxKind.LocalKeyword && Next.Kind == SyntaxKind.Identifier)
|
||||
{
|
||||
return AssignmentExpression();
|
||||
}
|
||||
return ParseBinaryExpression();
|
||||
}
|
||||
|
||||
private AssignmentExpressionSyntax AssignmentExpression()
|
||||
private AssignmentExpressionSyntax ParseAssignmentExpression()
|
||||
{
|
||||
SyntaxToken localKeyword = null;
|
||||
if (Current.Kind == SyntaxKind.LocalKeyword)
|
||||
|
|
|
@ -2,7 +2,7 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Upsilon.Parser
|
||||
{
|
||||
public class AssignmentExpressionSyntax : ExpressionSyntax
|
||||
public class AssignmentExpressionSyntax : StatementSyntax
|
||||
{
|
||||
public AssignmentExpressionSyntax(SyntaxToken localToken, IdentifierToken identifier, SyntaxToken equalsToken,
|
||||
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
|
||||
{
|
||||
public class ScriptSyntax : SyntaxNode
|
||||
public class ScriptSyntax : StatementSyntax
|
||||
{
|
||||
public ScriptSyntax(ExpressionSyntax statement, SyntaxToken endOfFileToken)
|
||||
public ScriptSyntax(StatementSyntax statement, SyntaxToken endOfFileToken)
|
||||
{
|
||||
Statement = statement;
|
||||
EndOfFileToken = endOfFileToken;
|
||||
|
@ -12,7 +12,7 @@ namespace Upsilon.Parser
|
|||
|
||||
public override SyntaxKind Kind => SyntaxKind.ScriptUnit;
|
||||
|
||||
public ExpressionSyntax Statement { get; }
|
||||
public StatementSyntax Statement { get; }
|
||||
public SyntaxToken EndOfFileToken { get; }
|
||||
|
||||
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;
|
||||
case "local":
|
||||
return SyntaxKind.LocalKeyword;
|
||||
case "end":
|
||||
return SyntaxKind.EndKeyword;
|
||||
default:
|
||||
return SyntaxKind.Identifier;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Upsilon.Parser
|
|||
AndKeyword,
|
||||
OrKeyword,
|
||||
LocalKeyword,
|
||||
EndKeyword,
|
||||
|
||||
Identifier,
|
||||
|
||||
|
@ -41,5 +42,8 @@ namespace Upsilon.Parser
|
|||
|
||||
// script unit
|
||||
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">
|
||||
<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