Initial work on the concept of statements

This commit is contained in:
Deukhoofd 2018-11-12 16:21:59 +01:00
parent 3d811ff801
commit ec7a32240f
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
16 changed files with 155 additions and 34 deletions

View File

@ -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)

View File

@ -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; }
}
}*/
}

View File

@ -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;
}
}
}

View File

@ -7,7 +7,10 @@ namespace Upsilon.Binder
BoundLiteralExpression,
BoundBinaryExpression,
BoundUnaryExpression,
BoundAssignmentExpression,
VariableExpression
VariableExpression,
// Statements
BoundAssignmentStatement,
BoundExpressionStatement
}
}

View File

@ -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; }
}
}

View File

@ -0,0 +1,6 @@
namespace Upsilon.Binder
{
public abstract class BoundStatement : BoundNode
{
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -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()

View File

@ -0,0 +1,7 @@
namespace Upsilon.Parser
{
public abstract class StatementSyntax : SyntaxNode
{
}
}

View File

@ -18,6 +18,8 @@ namespace Upsilon.Parser
return SyntaxKind.OrKeyword;
case "local":
return SyntaxKind.LocalKeyword;
case "end":
return SyntaxKind.EndKeyword;
default:
return SyntaxKind.Identifier;
}

View File

@ -27,6 +27,7 @@ namespace Upsilon.Parser
AndKeyword,
OrKeyword,
LocalKeyword,
EndKeyword,
Identifier,
@ -41,5 +42,8 @@ namespace Upsilon.Parser
// script unit
ScriptUnit,
// statements
ExpressionStatement
}
}

View File

@ -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>