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

View File

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

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, BoundLiteralExpression,
BoundBinaryExpression, BoundBinaryExpression,
BoundUnaryExpression, BoundUnaryExpression,
BoundAssignmentExpression, VariableExpression,
VariableExpression
// Statements
BoundAssignmentStatement,
BoundExpressionStatement
} }
} }

View File

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

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

View File

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

View File

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

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

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

View File

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

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