Merge pull request #5 from mahalex/evaluate

Implement evaluation
This commit is contained in:
Alexander Luzgarev 2020-07-16 12:31:40 +02:00 committed by GitHub
commit b3c15aa1a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 3748 additions and 589 deletions

View File

@ -22,8 +22,8 @@ namespace ConsoleDemo
{
switch (lhs.Kind)
{
case TokenKind.IdentifierName:
var name = ((IdentifierNameSyntaxNode) lhs).Name.Text;
case TokenKind.IdentifierNameExpression:
var name = ((IdentifierNameExpressionSyntaxNode) lhs).Name.Text;
Console.WriteLine($"Adding variable assignment for {name}");
_variableAssignments.Add(name, new Variable());
break;
@ -66,8 +66,8 @@ namespace ConsoleDemo
{
switch (node.Kind)
{
case TokenKind.IdentifierName:
var name = (IdentifierNameSyntaxNode) node;
case TokenKind.IdentifierNameExpression:
var name = (IdentifierNameExpressionSyntaxNode) node;
if (_context.FindFunction(name.Name.Text))
{
return true;
@ -90,7 +90,7 @@ namespace ConsoleDemo
Variable assignment;
switch (node.Kind)
{
case TokenKind.IdentifierName:
case TokenKind.IdentifierNameExpression:
assignment = _variableAssignments.Find(node.Text);
if (assignment != null || node.Text == "end")
{
@ -98,12 +98,12 @@ namespace ConsoleDemo
}
break;
case TokenKind.FunctionCall:
case TokenKind.FunctionCallExpression:
var functionCall = (FunctionCallExpressionSyntaxNode)node;
return
(IsDefined(functionCall.FunctionName) && IsDefined(functionCall.Nodes)) ||
(IsDefinedFunctionName(functionCall.FunctionName) && IsDefined(functionCall.Nodes));
case TokenKind.CellArrayElementAccess:
case TokenKind.CellArrayElementAccessExpression:
var cellArrayElementAccess = (CellArrayElementAccessExpressionSyntaxNode) node;
return IsDefined(cellArrayElementAccess.Expression) && IsDefined(cellArrayElementAccess.Nodes);
case TokenKind.List:
@ -113,7 +113,7 @@ namespace ConsoleDemo
return true;
case TokenKind.StringLiteralExpression:
return true;
case TokenKind.BinaryOperation:
case TokenKind.BinaryOperationExpression:
var binaryOperation = (BinaryOperationExpressionSyntaxNode) node;
return IsDefined(binaryOperation.Lhs) && IsDefined(binaryOperation.Rhs);
case TokenKind.UnaryPrefixOperationExpression:
@ -139,7 +139,7 @@ namespace ConsoleDemo
{
var parameterAsNode = parameter.AsNode();
Console.WriteLine($"Parameter node: {parameterAsNode}");
if (parameterAsNode.Kind == TokenKind.IdentifierName)
if (parameterAsNode.Kind == TokenKind.IdentifierNameExpression)
{
Console.WriteLine($"Adding variable assignment for {parameterAsNode.Text}");
_variableAssignments.Add(parameterAsNode.Text, new Variable());
@ -159,17 +159,17 @@ namespace ConsoleDemo
_insideFunction = false;
}
public override void VisitMethodDefinition(MethodDefinitionSyntaxNode node)
public override void VisitConcreteMethodDeclaration(ConcreteMethodDeclarationSyntaxNode node)
{
_insideMethod = true;
base.VisitMethodDefinition(node);
base.VisitConcreteMethodDeclaration(node);
_insideMethod = false;
}
public override void VisitFile(FileSyntaxNode node)
{
_methodAssignments = new MethodAssignments();
foreach (var nodeOrToken in node.StatementList)
foreach (var nodeOrToken in node.Body.Statements)
{
if (nodeOrToken.IsToken)
{

View File

@ -8,7 +8,7 @@ namespace ProjectConsole
{
public override void VisitFile(FileSyntaxNode node)
{
Visit(node.StatementList);
Visit(node.Body.Statements);
OutputKeyword(node.EndOfFile);
}
@ -118,7 +118,7 @@ namespace ProjectConsole
OutputKeyword(node.ClassdefKeyword);
Visit(node.Attributes);
BoldOn();
Visit(node.ClassName);
OutputIdentifier(node.ClassName);
BoldOff();
Visit(node.BaseClassList);
Visit(node.Nodes);
@ -186,7 +186,7 @@ namespace ProjectConsole
OutputKeyword(node.EndKeyword);
}
public override void VisitMethodDefinition(MethodDefinitionSyntaxNode node)
public override void VisitConcreteMethodDeclaration(ConcreteMethodDeclarationSyntaxNode node)
{
OutputKeyword(node.FunctionKeyword);
Visit(node.OutputDescription);
@ -274,7 +274,7 @@ namespace ProjectConsole
OutputBracket(node.ClosingBrace);
}
public override void VisitIdentifierName(IdentifierNameSyntaxNode node)
public override void VisitIdentifierNameExpression(IdentifierNameExpressionSyntaxNode node)
{
OutputIdentifier(node.Name);
}
@ -306,12 +306,12 @@ namespace ProjectConsole
OutputControlKeyword(node.EndKeyword);
}
public override void VisitUnquotedStringLiteral(UnquotedStringLiteralSyntaxNode node)
public override void VisitUnquotedStringLiteralExpression(UnquotedStringLiteralExpressionSyntaxNode node)
{
OutputUnquotedStringLiteral(node.StringToken);
}
public override void VisitStringLiteral(StringLiteralSyntaxNode node)
public override void VisitStringLiteralExpression(StringLiteralExpressionSyntaxNode node)
{
OutputStringLiteral(node.StringToken);
}
@ -355,11 +355,11 @@ namespace ProjectConsole
public override void VisitCommandExpression(CommandExpressionSyntaxNode node)
{
Visit(node.CommandName);
OutputIdentifier(node.CommandName);
Visit(node.Arguments);
}
public override void VisitNumberLiteral(NumberLiteralSyntaxNode node)
public override void VisitNumberLiteralExpression(NumberLiteralExpressionSyntaxNode node)
{
OutputNumberLiteral(node.Number);
}
@ -370,13 +370,13 @@ namespace ProjectConsole
Visit(node.Operand);
}
public override void VisitUnaryPostixOperationExpression(UnaryPostixOperationExpressionSyntaxNode node)
public override void VisitUnaryPostfixOperationExpression(UnaryPostfixOperationExpressionSyntaxNode node)
{
Visit(node.Operand);
OutputOperator(node.Operation);
}
public override void VisitBaseClassInvokation(BaseClassInvokationSyntaxNode node)
public override void VisitClassInvokationExpression(ClassInvokationExpressionSyntaxNode node)
{
Visit(node.MethodName);
OutputOperator(node.AtSign);
@ -391,7 +391,7 @@ namespace ProjectConsole
public override void VisitAttribute(AttributeSyntaxNode node)
{
Visit(node.Name);
OutputIdentifier(node.Name);
Visit(node.Assignment);
}
@ -410,12 +410,12 @@ namespace ProjectConsole
OutputBracket(node.ClosingBrace);
}
public override void VisitCompoundName(CompoundNameSyntaxNode node)
public override void VisitCompoundNameExpression(CompoundNameExpressionSyntaxNode node)
{
Visit(node.Nodes);
}
public override void VisitDoubleQuotedStringLiteral(DoubleQuotedStringLiteralSyntaxNode node)
public override void VisitDoubleQuotedStringLiteralExpression(DoubleQuotedStringLiteralExpressionSyntaxNode node)
{
OutputStringLiteral(node.StringToken);
}
@ -454,7 +454,7 @@ namespace ProjectConsole
public override void VisitEnumerationItem(EnumerationItemSyntaxNode node)
{
Visit(node.Name);
OutputIdentifier(node.Name);
Visit(node.Values);
Visit(node.Commas);
}
@ -472,27 +472,27 @@ namespace ProjectConsole
OutputOperator(node.AssignmentSign);
}
public override void VisitIndirectMemberAccess(IndirectMemberAccessSyntaxNode node)
public override void VisitIndirectMemberAccessExpression(IndirectMemberAccessExpressionSyntaxNode node)
{
OutputBracket(node.OpeningBracket);
Visit(node.Expression);
OutputBracket(node.ClosingBracket);
}
public override void VisitLambda(LambdaSyntaxNode node)
public override void VisitLambdaExpression(LambdaExpressionSyntaxNode node)
{
OutputOperator(node.AtSign);
Visit(node.Input);
Visit(node.Body);
}
public override void VisitNamedFunctionHandle(NamedFunctionHandleSyntaxNode node)
public override void VisitNamedFunctionHandleExpression(NamedFunctionHandleExpressionSyntaxNode node)
{
OutputOperator(node.AtSign);
Visit(node.FunctionName);
}
public override void VisitMemberAccess(MemberAccessSyntaxNode node)
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntaxNode node)
{
Visit(node.LeftOperand);
OutputOperator(node.Dot);

View File

@ -1,5 +1,4 @@
using Parser;
using Semantics;
using System;
using System.IO;
using System.Linq;
@ -72,7 +71,7 @@ namespace ConsoleDemo
var childNodesAndTokens = root.GetChildNodesAndTokens();
var node = childNodesAndTokens[0].AsNode();
var classChildNodesAndTokens = node.GetChildNodesAndTokens();
var c = GetClass.FromTree(root, fileName);
var c = Semantics.GetClass.FromTree(root, fileName);
Console.WriteLine(c.Name);
foreach (var m in c.Methods)
{
@ -86,13 +85,13 @@ namespace ConsoleDemo
public static void ContextDemo()
{
var context = new Context();
var context = new Semantics.Context();
context.ScanPath(BaseDirectory);
}
public static void DumbPrinterDemo()
{
var context = new Context();
var context = new Semantics.Context();
context.ScanPath(BaseDirectory);
var fileName = Path.Combine(
BaseDirectory,
@ -105,7 +104,7 @@ namespace ConsoleDemo
public static void UsageDemo()
{
var context = new Context();
var context = new Semantics.Context();
context.ScanPath(BaseDirectory);
var fileName = Path.Combine(
BaseDirectory,
@ -130,7 +129,6 @@ namespace ConsoleDemo
//ContextDemo();
//DumbPrinterDemo();
//UsageDemo();
Console.ReadKey();
}
}
}

View File

@ -49,8 +49,8 @@ namespace ConsoleDemo
{
switch (lhs.Kind)
{
case TokenKind.IdentifierName:
var name = ((IdentifierNameSyntaxNode)lhs).Name.Text;
case TokenKind.IdentifierNameExpression:
var name = ((IdentifierNameExpressionSyntaxNode)lhs).Name.Text;
Console.WriteLine($"Adding variable assignment for {name}");
_variableAssignments.Add(name, new Variable());
break;
@ -72,7 +72,7 @@ namespace ConsoleDemo
public override void VisitFile(FileSyntaxNode node)
{
_methodAssignments = new MethodAssignments();
foreach (var nodeOrToken in node.StatementList)
foreach (var nodeOrToken in node.Body.Statements)
{
if (nodeOrToken.IsToken)
{
@ -100,7 +100,7 @@ namespace ConsoleDemo
{
var parameterAsNode = parameter.AsNode();
Console.WriteLine($"Parameter node: {parameterAsNode}");
if (parameterAsNode.Kind == TokenKind.IdentifierName)
if (parameterAsNode.Kind == TokenKind.IdentifierNameExpression)
{
Console.WriteLine($"Adding variable assignment for {parameterAsNode.Text}");
_variableAssignments.Add(parameterAsNode.Text, new Variable());
@ -120,7 +120,7 @@ namespace ConsoleDemo
_insideFunction = false;
}
public override void VisitMethodDefinition(MethodDefinitionSyntaxNode node)
public override void VisitConcreteMethodDeclaration(ConcreteMethodDeclarationSyntaxNode node)
{
_insideMethod = true;
_variableAssignments = new VariableAssignments();
@ -131,7 +131,7 @@ namespace ConsoleDemo
{
var parameterAsNode = parameter.AsNode();
Console.WriteLine($"Parameter node: {parameterAsNode}");
if (parameterAsNode.Kind == TokenKind.IdentifierName)
if (parameterAsNode.Kind == TokenKind.IdentifierNameExpression)
{
Console.WriteLine($"Adding variable assignment for {parameterAsNode.Text}");
_variableAssignments.Add(parameterAsNode.Text, new Variable());
@ -146,7 +146,7 @@ namespace ConsoleDemo
Console.WriteLine($"Parameter token: {parameter.AsToken()}");
}
}
base.VisitMethodDefinition(node);
base.VisitConcreteMethodDeclaration(node);
_variableAssignments = null;
_insideMethod = false;
}

View File

@ -75,7 +75,7 @@ namespace MApplication
public override void VisitFile(FileSyntaxNode node)
{
Visit(node.StatementList);
Visit(node.Body.Statements);
AddToken(node.EndOfFile, _scheme.Keyword);
}
@ -89,7 +89,7 @@ namespace MApplication
{
AddToken(node.ClassdefKeyword, _scheme.Keyword);
Visit(node.Attributes);
Visit(node.ClassName);
AddToken(node.ClassName, _scheme.Identifier);
Visit(node.BaseClassList);
Visit(node.Nodes);
AddToken(node.EndKeyword, _scheme.Keyword);
@ -138,7 +138,7 @@ namespace MApplication
AddToken(node.EndKeyword, _scheme.Keyword);
}
public override void VisitMethodDefinition(MethodDefinitionSyntaxNode node)
public override void VisitConcreteMethodDeclaration(ConcreteMethodDeclarationSyntaxNode node)
{
AddToken(node.FunctionKeyword, _scheme.Keyword);
Visit(node.OutputDescription);
@ -221,7 +221,7 @@ namespace MApplication
AddToken(node.ClosingBrace, _scheme.Bracket);
}
public override void VisitIdentifierName(IdentifierNameSyntaxNode node)
public override void VisitIdentifierNameExpression(IdentifierNameExpressionSyntaxNode node)
{
AddToken(node.Name, _scheme.Identifier);
}
@ -253,12 +253,12 @@ namespace MApplication
AddToken(node.EndKeyword, _scheme.ControlKeyword);
}
public override void VisitUnquotedStringLiteral(UnquotedStringLiteralSyntaxNode node)
public override void VisitUnquotedStringLiteralExpression(UnquotedStringLiteralExpressionSyntaxNode node)
{
AddToken(node.StringToken, _scheme.UnquotedStringLiteral);
}
public override void VisitStringLiteral(StringLiteralSyntaxNode node)
public override void VisitStringLiteralExpression(StringLiteralExpressionSyntaxNode node)
{
AddToken(node.StringToken, _scheme.StringLiteral);
}
@ -302,11 +302,11 @@ namespace MApplication
public override void VisitCommandExpression(CommandExpressionSyntaxNode node)
{
Visit(node.CommandName);
AddToken(node.CommandName, _scheme.Identifier);
Visit(node.Arguments);
}
public override void VisitNumberLiteral(NumberLiteralSyntaxNode node)
public override void VisitNumberLiteralExpression(NumberLiteralExpressionSyntaxNode node)
{
AddToken(node.Number, _scheme.NumberLiteral);
}
@ -317,13 +317,13 @@ namespace MApplication
Visit(node.Operand);
}
public override void VisitUnaryPostixOperationExpression(UnaryPostixOperationExpressionSyntaxNode node)
public override void VisitUnaryPostfixOperationExpression(UnaryPostfixOperationExpressionSyntaxNode node)
{
Visit(node.Operand);
AddToken(node.Operation, _scheme.Operator);
}
public override void VisitBaseClassInvokation(BaseClassInvokationSyntaxNode node)
public override void VisitClassInvokationExpression(ClassInvokationExpressionSyntaxNode node)
{
Visit(node.MethodName);
AddToken(node.AtSign, _scheme.Operator);
@ -338,7 +338,7 @@ namespace MApplication
public override void VisitAttribute(AttributeSyntaxNode node)
{
Visit(node.Name);
AddToken(node.Name, _scheme.Identifier);
Visit(node.Assignment);
}
@ -357,12 +357,12 @@ namespace MApplication
AddToken(node.ClosingBrace, _scheme.Bracket);
}
public override void VisitCompoundName(CompoundNameSyntaxNode node)
public override void VisitCompoundNameExpression(CompoundNameExpressionSyntaxNode node)
{
Visit(node.Nodes);
}
public override void VisitDoubleQuotedStringLiteral(DoubleQuotedStringLiteralSyntaxNode node)
public override void VisitDoubleQuotedStringLiteralExpression(DoubleQuotedStringLiteralExpressionSyntaxNode node)
{
AddToken(node.StringToken, _scheme.StringLiteral);
}
@ -401,7 +401,7 @@ namespace MApplication
public override void VisitEnumerationItem(EnumerationItemSyntaxNode node)
{
Visit(node.Name);
AddToken(node.Name, _scheme.Identifier);
Visit(node.Values);
Visit(node.Commas);
}
@ -419,27 +419,27 @@ namespace MApplication
AddToken(node.AssignmentSign, _scheme.Operator);
}
public override void VisitIndirectMemberAccess(IndirectMemberAccessSyntaxNode node)
public override void VisitIndirectMemberAccessExpression(IndirectMemberAccessExpressionSyntaxNode node)
{
AddToken(node.OpeningBracket, _scheme.Bracket);
Visit(node.Expression);
AddToken(node.ClosingBracket, _scheme.Bracket);
}
public override void VisitLambda(LambdaSyntaxNode node)
public override void VisitLambdaExpression(LambdaExpressionSyntaxNode node)
{
AddToken(node.AtSign, _scheme.Operator);
Visit(node.Input);
Visit(node.Body);
}
public override void VisitNamedFunctionHandle(NamedFunctionHandleSyntaxNode node)
public override void VisitNamedFunctionHandleExpression(NamedFunctionHandleExpressionSyntaxNode node)
{
AddToken(node.AtSign, _scheme.Operator);
Visit(node.FunctionName);
}
public override void VisitMemberAccess(MemberAccessSyntaxNode node)
public override void VisitMemberAccessExpression(MemberAccessExpressionSyntaxNode node)
{
Visit(node.LeftOperand);
AddToken(node.Dot, _scheme.Operator);

View File

@ -19,7 +19,7 @@ namespace Parser.Tests
var text = "a = b";
var sut = GetSut(text);
var actual = sut.Parse();
var assignment = actual.Root.StatementList[0].AsNode();
var assignment = actual.Root.Body.Statements[0].AsNode();
Assert.IsType<ExpressionStatementSyntaxNode>(assignment);
if (assignment is null)
{
@ -35,7 +35,7 @@ namespace Parser.Tests
var text = "2 + 3";
var sut = GetSut(text);
var actual = sut.Parse();
var statement = actual.Root.StatementList[0].AsNode();
var statement = actual.Root.Body.Statements[0].AsNode();
Assert.IsType<ExpressionStatementSyntaxNode>(statement);
if (statement is null)
{
@ -51,7 +51,7 @@ namespace Parser.Tests
var text = "a = ";
var sut = GetSut(text);
var actual = sut.Parse();
var assignment = actual.Root.StatementList[0].AsNode();
var assignment = actual.Root.Body.Statements[0].AsNode();
Assert.IsType<ExpressionStatementSyntaxNode>(assignment);
if (assignment is null)
{
@ -77,7 +77,7 @@ namespace Parser.Tests
var text = "2 + 3";
var sut = GetSut(text);
var actual = sut.Parse();
var statement = actual.Root.StatementList[0].AsNode() as ExpressionStatementSyntaxNode;
var statement = actual.Root.Body.Statements[0].AsNode() as ExpressionStatementSyntaxNode;
var expression = statement!.Expression as BinaryOperationExpressionSyntaxNode;
var lhs = expression!.Lhs;
var operation = expression.Operation;

456
Parser/Binding/Binder.cs Normal file
View File

@ -0,0 +1,456 @@
using Parser.Internal;
using Parser.Lowering;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using static Parser.Binding.BoundNodeFactory;
namespace Parser.Binding
{
public class Binder
{
private readonly DiagnosticsBag _diagnostics = new DiagnosticsBag();
public static BoundProgram BindProgram(SyntaxTree syntaxTree)
{
var binder = new Binder();
var boundRoot = binder.BindRoot(syntaxTree.NullRoot);
var statements = ((BoundBlockStatement)boundRoot.File.Body).Statements;
var functionsBuilder = ImmutableDictionary.CreateBuilder<FunctionSymbol, LoweredFunction>();
var globalStatements = statements.Where(s => s.Kind != BoundNodeKind.FunctionDeclaration).ToArray();
var mainFunction = (FunctionSymbol?)null;
var scriptFunction = (FunctionSymbol?)null;
if (globalStatements.Length > 0)
{
// we have to gather all bound expression statements into a "script" function.
scriptFunction = new FunctionSymbol("%script");
var body = Block(globalStatements[0].Syntax, globalStatements);
var loweredBody = Lowerer.Lower(body);
var declaration = new BoundFunctionDeclaration(
syntax: globalStatements[0].Syntax,
name: "%script",
inputDescription: ImmutableArray<ParameterSymbol>.Empty,
outputDescription: ImmutableArray<ParameterSymbol>.Empty,
body: body);
var loweredFunction = LowerFunction(declaration);
functionsBuilder.Add(scriptFunction, loweredFunction);
}
var functions = statements.OfType<BoundFunctionDeclaration>().ToArray();
var first = true;
foreach (var function in functions)
{
var functionSymbol = new FunctionSymbol(
name: function.Name);
var loweredFunction = LowerFunction(function);
functionsBuilder.Add(functionSymbol, loweredFunction);
if (first && globalStatements.Length == 0)
{
// the first function in a file will become "main".
first = false;
mainFunction = functionSymbol;
}
}
return new BoundProgram(
binder._diagnostics.ToImmutableArray(),
mainFunction,
scriptFunction,
functionsBuilder.ToImmutable());
}
private static LoweredFunction LowerFunction(BoundFunctionDeclaration declaration)
{
var loweredBody = Lowerer.Lower(declaration.Body);
return new LoweredFunction(
declaration: declaration,
name: declaration.Name,
inputDescription: declaration.InputDescription,
outputDescription: declaration.OutputDescription,
body: loweredBody);
}
private BoundRoot BindRoot(RootSyntaxNode node)
{
var boundFile = BindFile(node.File);
return Root(node, boundFile);
}
private BoundFile BindFile(FileSyntaxNode node)
{
var body = BindBlockStatement(node.Body);
return File(node, body);
}
private BoundStatement BindStatement(StatementSyntaxNode node)
{
return node.Kind switch
{
TokenKind.AbstractMethodDeclaration =>
BindAbstractMethodDeclaration((AbstractMethodDeclarationSyntaxNode)node),
TokenKind.BlockStatement =>
BindBlockStatement((BlockStatementSyntaxNode)node),
TokenKind.ClassDeclaration =>
BindClassDeclaration((ClassDeclarationSyntaxNode)node),
TokenKind.ConcreteMethodDeclaration =>
BindConcreteMethodDeclaration((ConcreteMethodDeclarationSyntaxNode)node),
TokenKind.EmptyStatement =>
BindEmptyStatement((EmptyStatementSyntaxNode)node),
TokenKind.ExpressionStatement =>
BindExpressionStatement((ExpressionStatementSyntaxNode)node),
TokenKind.ForStatement =>
BindForStatement((ForStatementSyntaxNode)node),
TokenKind.FunctionDeclaration =>
BindFunctionDeclaration((FunctionDeclarationSyntaxNode)node),
TokenKind.IfStatement =>
BindIfStatement((IfStatementSyntaxNode)node),
TokenKind.SwitchStatement =>
BindSwitchStatement((SwitchStatementSyntaxNode)node),
TokenKind.TryCatchStatement =>
BindTryCatchStatement((TryCatchStatementSyntaxNode)node),
TokenKind.WhileStatement =>
BindWhileStatement((WhileStatementSyntaxNode)node),
_ =>
throw new Exception($"Invalid statement node kind '{node.Kind}'."),
};
}
private BoundWhileStatement BindWhileStatement(WhileStatementSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundTryCatchStatement BindTryCatchStatement(TryCatchStatementSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundSwitchStatement BindSwitchStatement(SwitchStatementSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundIfStatement BindIfStatement(IfStatementSyntaxNode node)
{
var condition = BindExpression(node.Condition);
var body = BindStatement(node.Body);
var elseifClauses = node.ElseifClauses
.Where(n => n.IsNode)
.Select(n => (ElseifClause)n.AsNode()!);
var builder = ImmutableArray.CreateBuilder<BoundElseifClause>();
foreach (var elseifClause in elseifClauses)
{
var clause = BindElseifClause(elseifClause);
builder.Add(clause);
}
var maybeElseClause = node.ElseClause switch
{
{ } elseClause => BindElseClause(elseClause),
_ => null,
};
return IfStatement(node, condition, body, builder.ToImmutable(), maybeElseClause);
}
private BoundStatement BindElseClause(ElseClause node)
{
return BindStatement(node.Body);
}
private BoundBlockStatement BindBlockStatement(BlockStatementSyntaxNode node)
{
var boundStatements = BindStatementList(node.Statements);
return Block(node, boundStatements.ToArray());
}
private IEnumerable<BoundStatement> BindStatementList(SyntaxNodeOrTokenList list)
{
var statements = list.Where(s => s.IsNode).Select(s => (StatementSyntaxNode)s.AsNode()!);
foreach (var statement in statements)
{
yield return BindStatement(statement);
}
}
private ImmutableArray<BoundExpression> BindExpressionList(SyntaxNodeOrTokenList list)
{
var builder = ImmutableArray.CreateBuilder<BoundExpression>();
var expressions = list.Where(s => s.IsNode).Select(s => (ExpressionSyntaxNode)s.AsNode()!);
foreach (var expression in expressions)
{
var boundExpression = BindExpression(expression);
builder.Add(boundExpression);
}
return builder.ToImmutable();
}
private BoundElseifClause BindElseifClause(ElseifClause node)
{
var condition = BindExpression(node.Condition);
var body = BindStatement(node.Body);
return ElseifClause(node, condition, body);
}
private BoundFunctionDeclaration BindFunctionDeclaration(FunctionDeclarationSyntaxNode node)
{
var inputDescription = BindInputDescription(node.InputDescription);
var outputDescription = BindOutputDescription(node.OutputDescription);
var body = BindStatement(node.Body);
return new BoundFunctionDeclaration(node, node.Name.Text, inputDescription, outputDescription, body);
}
private ImmutableArray<ParameterSymbol> BindOutputDescription(FunctionOutputDescriptionSyntaxNode? node)
{
if (node is null)
{
return ImmutableArray<ParameterSymbol>.Empty;
}
var outputs = node.OutputList.Where(p => p.IsNode).Select(p => p.AsNode()!);
var builder = ImmutableArray.CreateBuilder<ParameterSymbol>();
foreach (var output in outputs)
{
if (output.Kind != TokenKind.IdentifierNameExpression)
{
throw new Exception($"Invalid function output kind {output.Kind}.");
}
builder.Add(BindParameterSymbol((IdentifierNameExpressionSyntaxNode)output));
}
return builder.ToImmutable();
}
private ImmutableArray<ParameterSymbol> BindInputDescription(FunctionInputDescriptionSyntaxNode? node)
{
if (node is null)
{
return ImmutableArray<ParameterSymbol>.Empty;
}
var parameters = node.ParameterList.Where(p => p.IsNode).Select(p => p.AsNode()!);
var builder = ImmutableArray.CreateBuilder<ParameterSymbol>();
foreach (var parameter in parameters)
{
if (parameter.Kind != TokenKind.IdentifierNameExpression)
{
throw new Exception($"Invalid function parameter kind {parameter.Kind}.");
}
builder.Add(BindParameterSymbol((IdentifierNameExpressionSyntaxNode)parameter));
}
return builder.ToImmutable();
}
private ParameterSymbol BindParameterSymbol(IdentifierNameExpressionSyntaxNode parameter)
{
return new ParameterSymbol(parameter.Text);
}
private BoundForStatement BindForStatement(ForStatementSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundExpressionStatement BindExpressionStatement(ExpressionStatementSyntaxNode node)
{
var expression = BindExpression(node.Expression);
return ExpressionStatement(node, expression);
}
private BoundExpression BindExpression(ExpressionSyntaxNode node)
{
return node.Kind switch
{
TokenKind.ArrayLiteralExpression =>
BindArrayLiteralExpression((ArrayLiteralExpressionSyntaxNode)node),
TokenKind.AssignmentExpression =>
BindAssignmentExpression((AssignmentExpressionSyntaxNode)node),
TokenKind.BinaryOperationExpression =>
BindBinaryOperationExpression((BinaryOperationExpressionSyntaxNode)node),
TokenKind.CellArrayElementAccessExpression =>
BindCellArrayElementAccessExpression((CellArrayElementAccessExpressionSyntaxNode)node),
TokenKind.CellArrayLiteralExpression =>
BindCellArrayLiteralExpression((CellArrayLiteralExpressionSyntaxNode)node),
TokenKind.ClassInvokationExpression =>
BindClassInvokationExpression((ClassInvokationExpressionSyntaxNode)node),
TokenKind.CommandExpression =>
BindCommandExpression((CommandExpressionSyntaxNode)node),
TokenKind.CompoundNameExpression =>
BindCompoundNameExpression((CompoundNameExpressionSyntaxNode)node),
TokenKind.DoubleQuotedStringLiteralExpression =>
BindDoubleQuotedStringLiteralExpression((DoubleQuotedStringLiteralExpressionSyntaxNode)node),
TokenKind.EmptyExpression =>
BindEmptyExpression((EmptyExpressionSyntaxNode)node),
TokenKind.FunctionCallExpression =>
BindFunctionCallExpression((FunctionCallExpressionSyntaxNode)node),
TokenKind.IdentifierNameExpression =>
BindIdentifierNameExpression((IdentifierNameExpressionSyntaxNode)node),
TokenKind.IndirectMemberAccessExpression =>
BindIndirectMemberAccessExpression((IndirectMemberAccessExpressionSyntaxNode)node),
TokenKind.LambdaExpression =>
BindLambdaExpression((LambdaExpressionSyntaxNode)node),
TokenKind.MemberAccessExpression =>
BindMemberAccessExpression((MemberAccessExpressionSyntaxNode)node),
TokenKind.NamedFunctionHandleExpression =>
BindNamedFunctionHandleExpression((NamedFunctionHandleExpressionSyntaxNode)node),
TokenKind.NumberLiteralExpression =>
BindNumberLiteralExpression((NumberLiteralExpressionSyntaxNode)node),
TokenKind.ParenthesizedExpression =>
BindParenthesizedExpression((ParenthesizedExpressionSyntaxNode)node),
TokenKind.StringLiteralExpression =>
BindStringLiteralExpression((StringLiteralExpressionSyntaxNode)node),
TokenKind.UnaryPrefixOperationExpression =>
BindUnaryPrefixOperationExpression((UnaryPrefixOperationExpressionSyntaxNode)node),
TokenKind.UnaryPostfixOperationExpression =>
BindUnaryPostfixOperationExpression((UnaryPostfixOperationExpressionSyntaxNode)node),
TokenKind.UnquotedStringLiteralExpression =>
BindUnquotedStringLiteralExpression((UnquotedStringLiteralExpressionSyntaxNode)node),
_ =>
throw new Exception($"Invalid statement node kind '{node.Kind}'."),
};
}
private BoundArrayLiteralExpression BindArrayLiteralExpression(ArrayLiteralExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundAssignmentExpression BindAssignmentExpression(AssignmentExpressionSyntaxNode node)
{
var left = BindExpression(node.Lhs);
var right = BindExpression(node.Rhs);
return Assignment(node, left, right);
}
private BoundBinaryOperationExpression BindBinaryOperationExpression(BinaryOperationExpressionSyntaxNode node)
{
var left = BindExpression(node.Lhs);
var right = BindExpression(node.Rhs);
return BinaryOperation(node, left, node.Operation.Kind, right);
}
private BoundCellArrayElementAccessExpression BindCellArrayElementAccessExpression(CellArrayElementAccessExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundCellArrayLiteralExpression BindCellArrayLiteralExpression(CellArrayLiteralExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundClassInvokationExpression BindClassInvokationExpression(ClassInvokationExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundCommandExpression BindCommandExpression(CommandExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundCompoundNameExpression BindCompoundNameExpression(CompoundNameExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundDoubleQuotedStringLiteralExpression BindDoubleQuotedStringLiteralExpression(DoubleQuotedStringLiteralExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundEmptyExpression BindEmptyExpression(EmptyExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundFunctionCallExpression BindFunctionCallExpression(FunctionCallExpressionSyntaxNode node)
{
var name = BindExpression(node.FunctionName);
var arguments = BindExpressionList(node.Nodes);
return FunctionCall(node, name, arguments);
}
private BoundIdentifierNameExpression BindIdentifierNameExpression(IdentifierNameExpressionSyntaxNode node)
{
return new BoundIdentifierNameExpression(node, node.Name.Text);
}
private BoundIndirectMemberAccessExpression BindIndirectMemberAccessExpression(IndirectMemberAccessExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundLambdaExpression BindLambdaExpression(LambdaExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundMemberAccessExpression BindMemberAccessExpression(MemberAccessExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundNamedFunctionHandleExpression BindNamedFunctionHandleExpression(NamedFunctionHandleExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundNumberLiteralExpression BindNumberLiteralExpression(NumberLiteralExpressionSyntaxNode node)
{
var value = (double)node.Number.Value!;
return NumberLiteral(node, value);
}
private BoundExpression BindParenthesizedExpression(ParenthesizedExpressionSyntaxNode node)
{
return BindExpression(node.Expression);
}
private BoundStringLiteralExpression BindStringLiteralExpression(StringLiteralExpressionSyntaxNode node)
{
var value = (string)node.StringToken.Value!;
return StringLiteral(node, value);
}
private BoundUnaryOperationExpression BindUnaryPrefixOperationExpression(UnaryPrefixOperationExpressionSyntaxNode node)
{
var operand = BindExpression(node.Operand);
return UnaryOperation(node, node.Operation.Kind, operand);
}
private BoundUnaryOperationExpression BindUnaryPostfixOperationExpression(UnaryPostfixOperationExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundUnquotedStringLiteralExpression BindUnquotedStringLiteralExpression(UnquotedStringLiteralExpressionSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundEmptyStatement BindEmptyStatement(EmptyStatementSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundConcreteMethodDeclaration BindConcreteMethodDeclaration(ConcreteMethodDeclarationSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundClassDeclaration BindClassDeclaration(ClassDeclarationSyntaxNode node)
{
throw new NotImplementedException();
}
private BoundAbstractMethodDeclaration BindAbstractMethodDeclaration(AbstractMethodDeclarationSyntaxNode node)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,48 @@
using System.Linq;
namespace Parser.Binding
{
public class BoundBinaryOperator
{
private static BoundBinaryOperator[] _operators =
{
new BoundBinaryOperator(TokenKind.EqualsToken, BoundBinaryOperatorKind.Equals),
new BoundBinaryOperator(TokenKind.PipePipeToken, BoundBinaryOperatorKind.PipePipe),
new BoundBinaryOperator(TokenKind.AmpersandAmpersandToken, BoundBinaryOperatorKind.AmpersandAmpersand),
new BoundBinaryOperator(TokenKind.PipeToken, BoundBinaryOperatorKind.Pipe),
new BoundBinaryOperator(TokenKind.AmpersandToken, BoundBinaryOperatorKind.Ampersand),
new BoundBinaryOperator(TokenKind.LessToken, BoundBinaryOperatorKind.Less),
new BoundBinaryOperator(TokenKind.LessOrEqualsToken, BoundBinaryOperatorKind.LessOrEquals),
new BoundBinaryOperator(TokenKind.GreaterToken, BoundBinaryOperatorKind.Greater),
new BoundBinaryOperator(TokenKind.GreaterOrEqualsToken, BoundBinaryOperatorKind.GreaterOrEquals),
new BoundBinaryOperator(TokenKind.EqualsEqualsToken, BoundBinaryOperatorKind.EqualsEquals),
new BoundBinaryOperator(TokenKind.TildeEqualsToken, BoundBinaryOperatorKind.TildeEquals),
new BoundBinaryOperator(TokenKind.ColonToken, BoundBinaryOperatorKind.Colon),
new BoundBinaryOperator(TokenKind.PlusToken, BoundBinaryOperatorKind.Plus),
new BoundBinaryOperator(TokenKind.MinusToken, BoundBinaryOperatorKind.Minus),
new BoundBinaryOperator(TokenKind.StarToken, BoundBinaryOperatorKind.Star),
new BoundBinaryOperator(TokenKind.DotStarToken, BoundBinaryOperatorKind.DotStar),
new BoundBinaryOperator(TokenKind.SlashToken, BoundBinaryOperatorKind.Slash),
new BoundBinaryOperator(TokenKind.DotSlashToken, BoundBinaryOperatorKind.DotSlash),
new BoundBinaryOperator(TokenKind.BackslashToken, BoundBinaryOperatorKind.Backslash),
new BoundBinaryOperator(TokenKind.DotBackslashToken, BoundBinaryOperatorKind.DotBackslash),
new BoundBinaryOperator(TokenKind.TildeToken, BoundBinaryOperatorKind.Tilde),
new BoundBinaryOperator(TokenKind.CaretToken, BoundBinaryOperatorKind.Caret),
new BoundBinaryOperator(TokenKind.DotCaretToken, BoundBinaryOperatorKind.DotCaret),
};
public BoundBinaryOperator(TokenKind syntaxKind, BoundBinaryOperatorKind kind)
{
SyntaxKind = syntaxKind;
Kind = kind;
}
public TokenKind SyntaxKind { get; }
public BoundBinaryOperatorKind Kind { get; }
internal static BoundBinaryOperator? GetOperator(TokenKind kind)
{
return _operators.FirstOrDefault(op => op.SyntaxKind == kind);
}
}
}

View File

@ -0,0 +1,29 @@
namespace Parser.Binding
{
public enum BoundBinaryOperatorKind
{
Equals,
PipePipe,
AmpersandAmpersand,
Pipe,
Ampersand,
Less,
LessOrEquals,
Greater,
GreaterOrEquals,
EqualsEquals,
TildeEquals,
Colon,
Plus,
Minus,
Star,
DotStar,
Slash,
DotSlash,
Backslash,
DotBackslash,
Tilde,
Caret,
DotCaret,
}
}

View File

@ -0,0 +1,17 @@
namespace Parser.Binding
{
public class BoundLabel
{
public string Name { get; }
public BoundLabel(string name)
{
Name = name;
}
public override string ToString()
{
return Name;
}
}
}

View File

@ -0,0 +1,13 @@
namespace Parser.Binding
{
public abstract class BoundNode
{
public BoundNode(SyntaxNode syntax)
{
Syntax = syntax;
}
public SyntaxNode Syntax { get; }
public abstract BoundNodeKind Kind { get; }
}
}

View File

@ -0,0 +1,170 @@
using System;
using System.Collections.Immutable;
namespace Parser.Binding
{
public static class BoundNodeFactory
{
public static BoundRoot Root(SyntaxNode syntax, BoundFile file)
{
return new BoundRoot(syntax, file);
}
public static BoundFile File(SyntaxNode syntax, BoundStatement body)
{
return new BoundFile(syntax, body);
}
public static BoundBlockStatement Block(SyntaxNode syntax, params BoundStatement[] statements)
{
return new BoundBlockStatement(syntax, statements.ToImmutableArray());
}
public static BoundBlockStatement Block(SyntaxNode syntax, ImmutableArray<BoundStatement> statements)
{
return new BoundBlockStatement(syntax, statements);
}
public static BoundExpressionStatement ExpressionStatement(SyntaxNode syntax, BoundExpression expression)
{
return new BoundExpressionStatement(syntax, expression);
}
public static BoundIfStatement IfStatement(
SyntaxNode syntax,
BoundExpression condition,
BoundStatement body,
ImmutableArray<BoundElseifClause> elseifClauses,
BoundStatement? elseClause)
{
return new BoundIfStatement(syntax, condition, body, elseifClauses, elseClause);
}
public static BoundLabelStatement LabelStatement(
SyntaxNode syntax,
BoundLabel label)
{
return new BoundLabelStatement(syntax, label);
}
public static BoundAssignmentExpression Assignment(
SyntaxNode syntax,
BoundExpression left,
BoundExpression right)
{
return new BoundAssignmentExpression(syntax, left, right);
}
public static BoundBinaryOperationExpression BinaryOperation(
SyntaxNode syntax,
BoundExpression left,
TokenKind kind,
BoundExpression right)
{
var op = BindBinaryOperator(kind);
return new BoundBinaryOperationExpression(syntax, left, op, right);
}
public static BoundConditionalGotoStatement ConditionalGoto(
SyntaxNode syntax,
BoundExpression condition,
BoundLabel label,
bool gotoIfTrue)
{
return new BoundConditionalGotoStatement(
syntax,
condition,
label,
gotoIfTrue);
}
public static BoundConditionalGotoStatement GotoIfTrue(
SyntaxNode syntax,
BoundExpression condition,
BoundLabel label)
{
return new BoundConditionalGotoStatement(
syntax,
condition,
label,
gotoIfTrue: true);
}
public static BoundConditionalGotoStatement GotoIfFalse(
SyntaxNode syntax,
BoundExpression condition,
BoundLabel label)
{
return new BoundConditionalGotoStatement(
syntax,
condition,
label,
gotoIfTrue: false);
}
public static BoundFunctionCallExpression FunctionCall(
SyntaxNode syntax,
BoundExpression name,
ImmutableArray<BoundExpression> arguments)
{
return new BoundFunctionCallExpression(syntax, name, arguments);
}
public static BoundGotoStatement Goto(
SyntaxNode syntax,
BoundLabel label)
{
return new BoundGotoStatement(syntax, label);
}
public static BoundIdentifierNameExpression Identifier(
SyntaxNode syntax,
string name)
{
return new BoundIdentifierNameExpression(syntax, name);
}
public static BoundNumberLiteralExpression NumberLiteral(
SyntaxNode syntax,
double value)
{
return new BoundNumberLiteralExpression(syntax, value);
}
public static BoundStringLiteralExpression StringLiteral(
SyntaxNode syntax,
string value)
{
return new BoundStringLiteralExpression(syntax, value);
}
public static BoundElseifClause ElseifClause(
SyntaxNode syntax,
BoundExpression condition,
BoundStatement body)
{
return new BoundElseifClause(syntax, condition, body);
}
public static BoundUnaryOperationExpression UnaryOperation(
SyntaxNode syntax,
TokenKind kind,
BoundExpression operand)
{
var op = BindUnaryOperator(kind);
return new BoundUnaryOperationExpression(syntax, op, operand);
}
private static BoundUnaryOperator BindUnaryOperator(TokenKind kind)
{
return BoundUnaryOperator.GetOperator(kind)
?? throw new Exception($"Unexpected unary operator kind {kind}.");
}
private static BoundBinaryOperator BindBinaryOperator(TokenKind kind)
{
return BoundBinaryOperator.GetOperator(kind)
?? throw new Exception($"Unexpected binary operator kind {kind}.");
}
}
}

View File

@ -0,0 +1,54 @@
namespace Parser.Binding
{
public enum BoundNodeKind
{
Root,
File,
// Statements
AbstractMethodDeclaration,
BlockStatement,
ClassDeclaration,
ConcreteMethodDeclaration,
ConditionalGotoStatement,
EmptyStatement,
ExpressionStatement,
ForStatement,
FunctionDeclaration,
GotoStatement,
IfStatement,
LabelStatement,
SwitchStatement,
TryCatchStatement,
WhileStatement,
// Expressions
ArrayLiteralExpression,
AssignmentExpression,
BinaryOperationExpression,
CellArrayElementAccessExpression,
CellArrayLiteralExpression,
ClassInvokationExpression,
CommandExpression,
CompoundNameExpression,
DoubleQuotedStringLiteralExpression,
EmptyExpression,
FunctionCallExpression,
IdentifierNameExpression,
IndirectMemberAccessExpression,
LambdaExpression,
MemberAccessExpression,
NamedFunctionHandleExpression,
NumberLiteralExpression,
ParenthesizedExpression,
StringLiteralExpression,
UnaryOperationExpression,
UnquotedStringLiteralExpression,
// Parts
ElseIfClause,
ElseClause
}
}

View File

@ -0,0 +1,37 @@
using Parser.Internal;
using System.Collections.Immutable;
namespace Parser.Binding
{
public class BoundProgram
{
public BoundProgram(
ImmutableArray<Diagnostic> diagnostics,
FunctionSymbol? mainFunction,
FunctionSymbol? scriptFunction,
ImmutableDictionary<FunctionSymbol, LoweredFunction> functions)
{
Diagnostics = diagnostics;
MainFunction = mainFunction;
ScriptFunction = scriptFunction;
Functions = functions;
}
public ImmutableArray<Diagnostic> Diagnostics { get; }
/// <summary>
/// A "main" function (first in a file without any global statements).
/// </summary>
public FunctionSymbol? MainFunction { get; }
/// <summary>
/// A "script" function (generated from all global statements in a file if there are any).
/// </summary>
public FunctionSymbol? ScriptFunction { get; }
/// <summary>
/// So-called "local" functions.
/// </summary>
public ImmutableDictionary<FunctionSymbol, LoweredFunction> Functions { get; }
}
}

499
Parser/Binding/BoundRoot.cs Normal file
View File

@ -0,0 +1,499 @@
using System.Collections.Immutable;
namespace Parser.Binding
{
public class BoundRoot : BoundNode
{
public BoundRoot(SyntaxNode syntax, BoundFile file)
: base(syntax)
{
File = file;
}
public BoundFile File { get; }
public override BoundNodeKind Kind => BoundNodeKind.Root;
}
public class BoundFile : BoundNode
{
public BoundFile(SyntaxNode syntax, BoundStatement body)
: base(syntax)
{
Body = body;
}
public BoundStatement Body { get; }
public override BoundNodeKind Kind => BoundNodeKind.File;
}
public abstract class BoundStatement : BoundNode
{
public BoundStatement(SyntaxNode syntax)
: base(syntax)
{
}
}
public abstract class BoundMethodDeclaration : BoundStatement
{
public BoundMethodDeclaration(SyntaxNode syntax)
: base(syntax)
{
}
}
public class BoundAbstractMethodDeclaration : BoundMethodDeclaration
{
public BoundAbstractMethodDeclaration(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.AbstractMethodDeclaration;
}
public class BoundBlockStatement : BoundStatement
{
public BoundBlockStatement(SyntaxNode syntax, ImmutableArray<BoundStatement> statements)
: base(syntax)
{
Statements = statements;
}
public override BoundNodeKind Kind => BoundNodeKind.BlockStatement;
public ImmutableArray<BoundStatement> Statements { get; }
}
public class BoundClassDeclaration : BoundStatement
{
public BoundClassDeclaration(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.ClassDeclaration;
}
public class BoundConcreteMethodDeclaration : BoundMethodDeclaration
{
public BoundConcreteMethodDeclaration(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.ConcreteMethodDeclaration;
}
public class BoundConditionalGotoStatement : BoundStatement
{
public BoundConditionalGotoStatement(SyntaxNode syntax, BoundExpression condition, BoundLabel label, bool gotoIfTrue = true)
: base(syntax)
{
Condition = condition;
Label = label;
GotoIfTrue = gotoIfTrue;
}
public BoundExpression Condition { get; }
public BoundLabel Label { get; }
public bool GotoIfTrue { get; }
public override BoundNodeKind Kind => BoundNodeKind.ConditionalGotoStatement;
}
public class BoundEmptyStatement : BoundStatement
{
public BoundEmptyStatement(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.EmptyStatement;
}
public class BoundExpressionStatement : BoundStatement
{
public BoundExpression Expression { get; }
public override BoundNodeKind Kind => BoundNodeKind.ExpressionStatement;
public BoundExpressionStatement(SyntaxNode syntax, BoundExpression expression)
: base(syntax)
{
Expression = expression;
}
}
public class BoundForStatement : BoundStatement
{
public BoundForStatement(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.ForStatement;
}
public class BoundFunctionDeclaration : BoundStatement
{
public BoundFunctionDeclaration(SyntaxNode syntax, string name, ImmutableArray<ParameterSymbol> inputDescription, ImmutableArray<ParameterSymbol> outputDescription, BoundStatement body)
: base(syntax)
{
Name = name;
InputDescription = inputDescription;
OutputDescription = outputDescription;
Body = body;
}
public override BoundNodeKind Kind => BoundNodeKind.FunctionDeclaration;
public string Name { get; }
public ImmutableArray<ParameterSymbol> InputDescription { get; }
public ImmutableArray<ParameterSymbol> OutputDescription { get; }
public BoundStatement Body { get; }
public BoundFunctionDeclaration WithBody(BoundStatement body)
{
if (body == Body)
{
return this;
}
return new BoundFunctionDeclaration(
Syntax,
Name,
InputDescription,
OutputDescription,
body);
}
}
public class BoundGotoStatement : BoundStatement
{
public BoundGotoStatement(SyntaxNode syntax, BoundLabel label)
: base(syntax)
{
Label = label;
}
public BoundLabel Label { get; }
public override BoundNodeKind Kind => BoundNodeKind.GotoStatement;
}
public class BoundIfStatement : BoundStatement
{
public BoundIfStatement(SyntaxNode syntax, BoundExpression condition, BoundStatement body, ImmutableArray<BoundElseifClause> elseifClauses, BoundStatement? elseClause)
: base(syntax)
{
Condition = condition;
Body = body;
ElseifClauses = elseifClauses;
ElseClause = elseClause;
}
public BoundExpression Condition { get; }
public BoundStatement Body { get; }
public ImmutableArray<BoundElseifClause> ElseifClauses { get; }
public BoundStatement? ElseClause { get; }
public override BoundNodeKind Kind => BoundNodeKind.IfStatement;
}
public class BoundLabelStatement : BoundStatement
{
public BoundLabelStatement(SyntaxNode syntax, BoundLabel label)
: base(syntax)
{
Label = label;
}
public BoundLabel Label { get; }
public override BoundNodeKind Kind => BoundNodeKind.LabelStatement;
}
public class BoundSwitchStatement : BoundStatement
{
public BoundSwitchStatement(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.SwitchStatement;
}
public class BoundTryCatchStatement : BoundStatement
{
public BoundTryCatchStatement(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.TryCatchStatement;
}
public class BoundWhileStatement : BoundStatement
{
public BoundWhileStatement(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.WhileStatement;
}
public abstract class BoundExpression : BoundNode
{
public BoundExpression(SyntaxNode syntax)
: base(syntax)
{
}
}
public class BoundArrayLiteralExpression : BoundExpression
{
public BoundArrayLiteralExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.ArrayLiteralExpression;
}
public class BoundAssignmentExpression : BoundExpression
{
public BoundAssignmentExpression(SyntaxNode syntax, BoundExpression left, BoundExpression right)
: base(syntax)
{
Left = left;
Right = right;
}
public BoundExpression Left { get; }
public BoundExpression Right { get; }
public override BoundNodeKind Kind => BoundNodeKind.AssignmentExpression;
}
public class BoundBinaryOperationExpression : BoundExpression
{
public BoundBinaryOperationExpression(SyntaxNode syntax, BoundExpression left, BoundBinaryOperator op, BoundExpression right)
: base(syntax)
{
Left = left;
Op = op;
Right = right;
}
public BoundExpression Left { get; }
public BoundBinaryOperator Op { get; }
public BoundExpression Right { get; }
public override BoundNodeKind Kind => BoundNodeKind.BinaryOperationExpression;
}
public class BoundCellArrayElementAccessExpression : BoundExpression
{
public BoundCellArrayElementAccessExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.CellArrayElementAccessExpression;
}
public class BoundCellArrayLiteralExpression : BoundExpression
{
public BoundCellArrayLiteralExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.CellArrayLiteralExpression;
}
public class BoundClassInvokationExpression : BoundExpression
{
public BoundClassInvokationExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.ClassInvokationExpression;
}
public class BoundCommandExpression : BoundExpression
{
public BoundCommandExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.CommandExpression;
}
public class BoundCompoundNameExpression : BoundExpression
{
public BoundCompoundNameExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.CompoundNameExpression;
}
public class BoundDoubleQuotedStringLiteralExpression : BoundExpression
{
public BoundDoubleQuotedStringLiteralExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.DoubleQuotedStringLiteralExpression;
}
public class BoundEmptyExpression : BoundExpression
{
public BoundEmptyExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.EmptyExpression;
}
public class BoundFunctionCallExpression : BoundExpression
{
public BoundFunctionCallExpression(SyntaxNode syntax, BoundExpression name, ImmutableArray<BoundExpression> arguments)
: base(syntax)
{
Name = name;
Arguments = arguments;
}
public BoundExpression Name { get; }
public ImmutableArray<BoundExpression> Arguments { get; }
public override BoundNodeKind Kind => BoundNodeKind.FunctionCallExpression;
}
public class BoundIdentifierNameExpression : BoundExpression
{
public BoundIdentifierNameExpression(SyntaxNode syntax, string name)
: base(syntax)
{
Name = name;
}
public string Name { get; }
public override BoundNodeKind Kind => BoundNodeKind.IdentifierNameExpression;
}
public class BoundIndirectMemberAccessExpression : BoundExpression
{
public BoundIndirectMemberAccessExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.IndirectMemberAccessExpression;
}
public class BoundLambdaExpression : BoundExpression
{
public BoundLambdaExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.LambdaExpression;
}
public class BoundMemberAccessExpression : BoundExpression
{
public BoundMemberAccessExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.MemberAccessExpression;
}
public class BoundNamedFunctionHandleExpression : BoundExpression
{
public BoundNamedFunctionHandleExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.NamedFunctionHandleExpression;
}
public class BoundNumberLiteralExpression : BoundExpression
{
public BoundNumberLiteralExpression(SyntaxNode syntax, double value)
: base(syntax)
{
Value = value;
}
public double Value { get; }
public override BoundNodeKind Kind => BoundNodeKind.NumberLiteralExpression;
}
public class BoundStringLiteralExpression : BoundExpression
{
public BoundStringLiteralExpression(SyntaxNode syntax, string value)
: base(syntax)
{
Value = value;
}
public string Value { get; }
public override BoundNodeKind Kind => BoundNodeKind.StringLiteralExpression;
}
public class BoundUnaryOperationExpression : BoundExpression
{
public BoundUnaryOperationExpression(SyntaxNode syntax, BoundUnaryOperator op, BoundExpression operand)
: base(syntax)
{
Op = op;
Operand = operand;
}
public override BoundNodeKind Kind => BoundNodeKind.UnaryOperationExpression;
public BoundUnaryOperator Op { get; }
public BoundExpression Operand { get; }
}
public class BoundUnquotedStringLiteralExpression : BoundExpression
{
public BoundUnquotedStringLiteralExpression(SyntaxNode syntax)
: base(syntax)
{
}
public override BoundNodeKind Kind => BoundNodeKind.UnquotedStringLiteralExpression;
}
public class BoundElseifClause : BoundNode
{
public BoundElseifClause(SyntaxNode syntax, BoundExpression condition, BoundStatement body)
: base(syntax)
{
Condition = condition;
Body = body;
}
public BoundExpression Condition { get; }
public BoundStatement Body { get; }
public override BoundNodeKind Kind => BoundNodeKind.ElseIfClause;
}
}

View File

@ -0,0 +1,393 @@
using System;
using System.Collections.Immutable;
using static Parser.Binding.BoundNodeFactory;
namespace Parser.Binding
{
public abstract class BoundTreeRewriter
{
public virtual BoundStatement RewriteStatement(BoundStatement node)
{
return node.Kind switch
{
BoundNodeKind.AbstractMethodDeclaration =>
RewriteAbstractMethodDeclaration((BoundAbstractMethodDeclaration)node),
BoundNodeKind.BlockStatement =>
RewriteBlockStatement((BoundBlockStatement)node),
BoundNodeKind.ClassDeclaration =>
RewriteClassDeclaration((BoundClassDeclaration)node),
BoundNodeKind.ConcreteMethodDeclaration =>
RewriteConcreteMethodDeclaration((BoundConcreteMethodDeclaration)node),
BoundNodeKind.ConditionalGotoStatement =>
RewriteConditionalGotoStatement((BoundConditionalGotoStatement)node),
BoundNodeKind.EmptyStatement =>
RewriteEmptyStatement((BoundEmptyStatement)node),
BoundNodeKind.ExpressionStatement =>
RewriteExpressionStatement((BoundExpressionStatement)node),
BoundNodeKind.ForStatement =>
RewriteForStatement((BoundForStatement)node),
BoundNodeKind.FunctionDeclaration =>
RewriteFunctionDeclaration((BoundFunctionDeclaration)node),
BoundNodeKind.GotoStatement =>
RewriteGotoStatement((BoundGotoStatement)node),
BoundNodeKind.IfStatement =>
RewriteIfStatement((BoundIfStatement)node),
BoundNodeKind.LabelStatement =>
RewriteLabelStatement((BoundLabelStatement)node),
BoundNodeKind.SwitchStatement =>
RewriteSwitchStatement((BoundSwitchStatement)node),
BoundNodeKind.TryCatchStatement =>
RewriteTryCatchStatement((BoundTryCatchStatement)node),
BoundNodeKind.WhileStatement =>
RewriteWhileStatement((BoundWhileStatement)node),
_ =>
throw new Exception($"Invalid statement kind {node.Kind}."),
};
}
public virtual BoundStatement RewriteGotoStatement(BoundGotoStatement node)
{
return node;
}
public virtual BoundStatement RewriteConditionalGotoStatement(BoundConditionalGotoStatement node)
{
var condition = RewriteExpression(node.Condition);
if (condition == node.Condition)
{
return node;
}
return ConditionalGoto(node.Syntax, condition, node.Label, node.GotoIfTrue);
}
public virtual BoundStatement RewriteWhileStatement(BoundWhileStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteTryCatchStatement(BoundTryCatchStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteSwitchStatement(BoundSwitchStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteLabelStatement(BoundLabelStatement node)
{
return node;
}
public virtual BoundStatement RewriteIfStatement(BoundIfStatement node)
{
var condition = RewriteExpression(node.Condition);
var body = RewriteStatement(node.Body);
ImmutableArray<BoundElseifClause>.Builder? builder = null;
for (var i = 0; i < node.ElseifClauses.Length; i++)
{
var oldClause = node.ElseifClauses[i];
var newClause = RewriteElseifClause(oldClause);
if (oldClause != newClause && builder is null)
{
builder = ImmutableArray.CreateBuilder<BoundElseifClause>(node.ElseifClauses.Length);
for (var j = 0; j < i; j++)
{
builder.Add(node.ElseifClauses[j]);
}
}
if (builder is not null)
{
builder.Add(newClause);
}
}
var elseIfClauses = builder is null ? node.ElseifClauses : builder.MoveToImmutable();
var elseClause = node.ElseClause is null ? null : RewriteStatement(node.ElseClause);
if (condition == node.Condition &&
body == node.Body &&
elseIfClauses == node.ElseifClauses &&
elseClause == node.ElseClause )
{
return node;
}
return IfStatement(node.Syntax, condition, body, elseIfClauses, elseClause);
}
public virtual BoundElseifClause RewriteElseifClause(BoundElseifClause node)
{
var condition = RewriteExpression(node.Condition);
var body = RewriteStatement(node.Body);
if (condition == node.Condition && body == node.Body)
{
return node;
}
return ElseifClause(node.Syntax, condition, body);
}
public virtual BoundStatement RewriteFunctionDeclaration(BoundFunctionDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteForStatement(BoundForStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteExpressionStatement(BoundExpressionStatement node)
{
var expression = RewriteExpression(node.Expression);
if (expression == node.Expression)
{
return node;
}
return ExpressionStatement(node.Syntax, expression);
}
public virtual BoundStatement RewriteEmptyStatement(BoundEmptyStatement node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteConcreteMethodDeclaration(BoundConcreteMethodDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteClassDeclaration(BoundClassDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node)
{
ImmutableArray<BoundStatement>.Builder? builder = null;
for (var i = 0; i < node.Statements.Length; i++)
{
var oldStatement = node.Statements[i];
var newStatement = RewriteStatement(oldStatement);
if (oldStatement != newStatement && builder is null)
{
builder = ImmutableArray.CreateBuilder<BoundStatement>(node.Statements.Length);
for (var j = 0; j < i; j++)
{
builder.Add(node.Statements[j]);
}
}
if (builder is not null)
{
builder.Add(newStatement);
}
}
if (builder is null)
{
return node;
}
return Block(node.Syntax, builder.MoveToImmutable());
}
public virtual BoundStatement RewriteAbstractMethodDeclaration(BoundAbstractMethodDeclaration node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteExpression(BoundExpression node)
{
return node.Kind switch
{
BoundNodeKind.ArrayLiteralExpression =>
RewriteArrayLiteralExpression((BoundArrayLiteralExpression)node),
BoundNodeKind.AssignmentExpression =>
RewriteAssignmentExpression((BoundAssignmentExpression)node),
BoundNodeKind.BinaryOperationExpression =>
RewriteBinaryOperationExpression((BoundBinaryOperationExpression)node),
BoundNodeKind.CellArrayElementAccessExpression =>
RewriteCellArrayElementAccessExpression((BoundCellArrayElementAccessExpression)node),
BoundNodeKind.CellArrayLiteralExpression =>
RewriteCellArrayLiteralExpression((BoundCellArrayLiteralExpression)node),
BoundNodeKind.ClassInvokationExpression =>
RewriteClassInvokationExpression((BoundClassInvokationExpression)node),
BoundNodeKind.CommandExpression =>
RewriteCommandExpression((BoundCommandExpression)node),
BoundNodeKind.CompoundNameExpression =>
RewriteCompoundNameExpression((BoundCompoundNameExpression)node),
BoundNodeKind.DoubleQuotedStringLiteralExpression =>
RewriteDoubleQuotedStringLiteralExpression((BoundDoubleQuotedStringLiteralExpression)node),
BoundNodeKind.EmptyExpression =>
RewriteEmptyExpression((BoundEmptyExpression)node),
BoundNodeKind.FunctionCallExpression =>
RewriteFunctionCallExpression((BoundFunctionCallExpression)node),
BoundNodeKind.IdentifierNameExpression =>
RewriteIdentifierNameExpression((BoundIdentifierNameExpression)node),
BoundNodeKind.IndirectMemberAccessExpression =>
RewriteIndirectMemberAccessExpression((BoundIndirectMemberAccessExpression)node),
BoundNodeKind.LambdaExpression =>
RewriteLambdaExpression((BoundLambdaExpression)node),
BoundNodeKind.MemberAccessExpression =>
RewriteMemberAccessExpression((BoundMemberAccessExpression)node),
BoundNodeKind.NamedFunctionHandleExpression =>
RewriteNamedFunctionHandleExpression((BoundNamedFunctionHandleExpression)node),
BoundNodeKind.NumberLiteralExpression =>
RewriteNumberLiteralExpression((BoundNumberLiteralExpression)node),
BoundNodeKind.StringLiteralExpression =>
RewriteStringLiteralExpression((BoundStringLiteralExpression)node),
BoundNodeKind.UnaryOperationExpression =>
RewriteUnaryOperationExpression((BoundUnaryOperationExpression)node),
BoundNodeKind.UnquotedStringLiteralExpression =>
RewriteUnquotedStringLiteralExpression((BoundUnquotedStringLiteralExpression)node),
_ =>
throw new Exception($"Invalid expression kind {node.Kind}."),
};
}
public virtual BoundExpression RewriteUnquotedStringLiteralExpression(BoundUnquotedStringLiteralExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteUnaryOperationExpression(BoundUnaryOperationExpression node)
{
var operand = RewriteExpression(node.Operand);
return new BoundUnaryOperationExpression(node.Syntax, node.Op, operand);
}
public virtual BoundExpression RewriteStringLiteralExpression(BoundStringLiteralExpression node)
{
return node;
}
public virtual BoundExpression RewriteNumberLiteralExpression(BoundNumberLiteralExpression node)
{
return node;
}
public virtual BoundExpression RewriteNamedFunctionHandleExpression(BoundNamedFunctionHandleExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteMemberAccessExpression(BoundMemberAccessExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteLambdaExpression(BoundLambdaExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteIndirectMemberAccessExpression(BoundIndirectMemberAccessExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteIdentifierNameExpression(BoundIdentifierNameExpression node)
{
return node;
}
public virtual BoundExpression RewriteFunctionCallExpression(BoundFunctionCallExpression node)
{
ImmutableArray<BoundExpression>.Builder? builder = null;
for (var i = 0; i < node.Arguments.Length; i++)
{
var oldArgument = node.Arguments[i];
var newArgument = RewriteExpression(oldArgument);
if (oldArgument != newArgument && builder is null)
{
builder = ImmutableArray.CreateBuilder<BoundExpression>(node.Arguments.Length);
for (var j = 0; j < i; j++)
{
builder.Add(node.Arguments[j]);
}
}
if (builder is not null)
{
builder.Add(newArgument);
}
}
if (builder is null)
{
return node;
}
return FunctionCall(node.Syntax, node.Name, builder.MoveToImmutable());
}
public virtual BoundExpression RewriteEmptyExpression(BoundEmptyExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteDoubleQuotedStringLiteralExpression(BoundDoubleQuotedStringLiteralExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCommandExpression(BoundCommandExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCompoundNameExpression(BoundCompoundNameExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteClassInvokationExpression(BoundClassInvokationExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCellArrayLiteralExpression(BoundCellArrayLiteralExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteCellArrayElementAccessExpression(BoundCellArrayElementAccessExpression node)
{
throw new NotImplementedException();
}
public virtual BoundExpression RewriteBinaryOperationExpression(BoundBinaryOperationExpression node)
{
var left = RewriteExpression(node.Left);
var right = RewriteExpression(node.Right);
if (left == node.Left && right == node.Right)
{
return node;
}
return new BoundBinaryOperationExpression(node.Syntax, left, node.Op, right);
}
public virtual BoundExpression RewriteAssignmentExpression(BoundAssignmentExpression node)
{
var left = RewriteExpression(node.Left);
var right = RewriteExpression(node.Right);
if (left == node.Left && right == node.Right)
{
return node;
}
return Assignment(node.Syntax, left, right);
}
public virtual BoundExpression RewriteArrayLiteralExpression(BoundArrayLiteralExpression node)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,26 @@
using System.Linq;
namespace Parser.Binding
{
public class BoundUnaryOperator
{
private static BoundUnaryOperator[] _operators =
{
new BoundUnaryOperator(TokenKind.MinusToken, BoundUnaryOperatorKind.Minus),
};
public BoundUnaryOperator(TokenKind syntaxKind, BoundUnaryOperatorKind kind)
{
SyntaxKind = syntaxKind;
Kind = kind;
}
public TokenKind SyntaxKind { get; }
public BoundUnaryOperatorKind Kind { get; }
internal static BoundUnaryOperator? GetOperator(TokenKind kind)
{
return _operators.FirstOrDefault(op => op.SyntaxKind == kind);
}
}
}

View File

@ -0,0 +1,7 @@
namespace Parser.Binding
{
public enum BoundUnaryOperatorKind
{
Minus,
}
}

View File

@ -0,0 +1,13 @@
namespace Parser.Binding
{
public class FunctionSymbol
{
public FunctionSymbol(
string name)
{
Name = name;
}
public string Name { get; }
}
}

View File

@ -0,0 +1,26 @@
using System.Collections.Immutable;
namespace Parser.Binding
{
public class LoweredFunction {
public LoweredFunction(
BoundFunctionDeclaration declaration,
string name,
ImmutableArray<ParameterSymbol> inputDescription,
ImmutableArray<ParameterSymbol> outputDescription,
BoundBlockStatement body)
{
Declaration = declaration;
Name = name;
InputDescription = inputDescription;
OutputDescription = outputDescription;
Body = body;
}
public BoundFunctionDeclaration Declaration { get; }
public string Name { get; }
public ImmutableArray<ParameterSymbol> InputDescription { get; }
public ImmutableArray<ParameterSymbol> OutputDescription { get; }
public BoundBlockStatement Body { get; }
}
}

View File

@ -0,0 +1,12 @@
namespace Parser.Binding
{
public class ParameterSymbol
{
public ParameterSymbol(string name)
{
Name = name;
}
public string Name { get; }
}
}

36
Parser/Compilation.cs Normal file
View File

@ -0,0 +1,36 @@
using Parser.Binding;
namespace Parser
{
public class Compilation
{
private readonly SyntaxTree _syntaxTree;
private Compilation(SyntaxTree syntaxTree)
{
_syntaxTree = syntaxTree;
}
public static Compilation Create(SyntaxTree syntaxTree)
{
return new Compilation(syntaxTree);
}
private BoundProgram GetBoundProgram()
{
return Binder.BindProgram(_syntaxTree);
}
public EvaluationResult Evaluate(CompilationContext context, bool inRepl)
{
var program = GetBoundProgram();
if (program.Diagnostics.Length > 0)
{
return new EvaluationResult(null, program.Diagnostics);
}
var evaluator = new Evaluator(program, context, inRepl);
return evaluator.Evaluate();
}
}
}

View File

@ -0,0 +1,11 @@
using Parser.Objects;
using System.Collections.Generic;
namespace Parser
{
public class CompilationContext
{
public Dictionary<string, MObject> Variables { get; } = new Dictionary<string, MObject>();
public static CompilationContext Empty => new CompilationContext();
}
}

View File

@ -0,0 +1,19 @@
using Parser.Internal;
using Parser.Objects;
using System.Collections.Immutable;
namespace Parser
{
public class EvaluationResult
{
public EvaluationResult(MObject? value, ImmutableArray<Diagnostic> diagnostics)
{
Value = value;
Diagnostics = diagnostics;
}
public MObject? Value { get; }
public ImmutableArray<Diagnostic> Diagnostics { get; }
}
}

10
Parser/EvaluationScope.cs Normal file
View File

@ -0,0 +1,10 @@
using Parser.Objects;
using System.Collections.Generic;
namespace Parser
{
internal class EvaluationScope
{
public Dictionary<string, MObject> Variables { get; } = new Dictionary<string, MObject>();
}
}

552
Parser/Evaluator.cs Normal file
View File

@ -0,0 +1,552 @@
using Parser.Binding;
using Parser.Internal;
using Parser.MFunctions;
using Parser.Objects;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace Parser
{
internal class Evaluator
{
private readonly BoundProgram _program;
private readonly CompilationContext _context;
private readonly DiagnosticsBag _diagnostics = new DiagnosticsBag();
private bool _inRepl = false;
private readonly Stack<EvaluationScope> _scopeStack = new Stack<EvaluationScope>();
private readonly Dictionary<FunctionSymbol, LoweredFunction> _functions = new Dictionary<FunctionSymbol, LoweredFunction>();
public Evaluator(BoundProgram program, CompilationContext context, bool inRepl)
{
_program = program;
_context = context;
var outerScope = new EvaluationScope();
_scopeStack.Push(outerScope);
_inRepl = inRepl;
foreach (var pair in program.Functions)
{
_functions[pair.Key] = pair.Value;
}
}
internal EvaluationResult Evaluate()
{
if (_program.MainFunction is { } mainFunctionSymbol)
{
var mainFunction = _program.Functions[mainFunctionSymbol];
if (mainFunction.InputDescription.Length > 0)
{
_diagnostics.ReportNotEnoughInputs(
new TextSpan(mainFunction.Body.Syntax.Position, mainFunction.Body.Syntax.Position + mainFunction.Body.Syntax.FullWidth),
mainFunction.Name);
return new EvaluationResult(null, _diagnostics.ToImmutableArray());
}
else
{
var result = EvaluateBlockStatement(mainFunction.Body);
return new EvaluationResult(result, _diagnostics.ToImmutableArray());
}
}
else if (_program.ScriptFunction is { } scriptFunctionSymbol)
{
var scriptFunction = _program.Functions[scriptFunctionSymbol];
var result = EvaluateBlockStatement(scriptFunction.Body);
return new EvaluationResult(result, _diagnostics.ToImmutableArray());
}
else
{
return new EvaluationResult(null, _diagnostics.ToImmutableArray());
}
}
private MObject? EvaluateFile(BoundFile root)
{
return EvaluateStatement(root.Body);
}
private MObject? EvaluateBlockStatement(BoundBlockStatement node)
{
var labelToIndex = new Dictionary<BoundLabel, int>();
for (var i = 0; i < node.Statements.Length; i++)
{
var statement = node.Statements[i];
if (statement.Kind == BoundNodeKind.LabelStatement)
{
labelToIndex[((BoundLabelStatement)statement).Label] = i;
}
}
MObject? lastResult = null;
var index = 0;
while (index < node.Statements.Length)
{
var statement = node.Statements[index];
switch (statement.Kind)
{
case BoundNodeKind.GotoStatement:
var gs = (BoundGotoStatement)statement;
index = labelToIndex[gs.Label];
break;
case BoundNodeKind.ConditionalGotoStatement:
var cgs = (BoundConditionalGotoStatement)statement;
var value = EvaluateExpression(cgs.Condition);
var truth = IsTruthyValue(value);
if ((cgs.GotoIfTrue && truth) ||
(!cgs.GotoIfTrue && !truth))
{
index = labelToIndex[cgs.Label];
}
else
{
index++;
}
break;
case BoundNodeKind.LabelStatement:
index++;
break;
default:
lastResult = EvaluateStatement(statement) ?? lastResult;
index++;
break;
}
}
return lastResult;
}
private bool IsTruthyValue(MObject? expression)
{
if (expression is MLogical { Value: true })
{
return true;
}
return false;
}
private MObject? EvaluateStatement(BoundStatement node)
{
return node.Kind switch
{
BoundNodeKind.AbstractMethodDeclaration =>
EvaluateAbstractMethodDeclaration((BoundAbstractMethodDeclaration)node),
BoundNodeKind.BlockStatement =>
EvaluateBlockStatement((BoundBlockStatement)node),
BoundNodeKind.ClassDeclaration =>
EvaluateClassDeclaration((BoundClassDeclaration)node),
BoundNodeKind.EmptyStatement =>
EvaluateEmptyStatement((BoundEmptyStatement)node),
BoundNodeKind.ExpressionStatement =>
EvaluateExpressionStatement((BoundExpressionStatement)node),
BoundNodeKind.ForStatement =>
EvaluateForStatement((BoundForStatement)node),
BoundNodeKind.FunctionDeclaration =>
EvaluateFunctionDeclaration((BoundFunctionDeclaration)node),
BoundNodeKind.IfStatement =>
EvaluateIfStatement((BoundIfStatement)node),
BoundNodeKind.ConcreteMethodDeclaration =>
EvaluateMethodDefinition((BoundConcreteMethodDeclaration)node),
BoundNodeKind.SwitchStatement =>
EvaluateSwitchStatement((BoundSwitchStatement)node),
BoundNodeKind.TryCatchStatement =>
EvaluateTryCatchStatement((BoundTryCatchStatement)node),
BoundNodeKind.WhileStatement =>
EvaluateWhileStatement((BoundWhileStatement)node),
_ => throw new NotImplementedException($"Invalid statement kind '{node.Kind}'."),
};
}
private MObject? EvaluateClassDeclaration(BoundClassDeclaration node)
{
throw new NotImplementedException();
}
private MObject? EvaluateEmptyStatement(BoundEmptyStatement node)
{
throw new NotImplementedException();
}
private MObject? EvaluateTryCatchStatement(BoundTryCatchStatement node)
{
throw new NotImplementedException();
}
private MObject? EvaluateForStatement(BoundForStatement node)
{
throw new NotImplementedException();
}
private MObject? EvaluateIfStatement(BoundIfStatement node)
{
throw new NotImplementedException();
}
private MObject? EvaluateWhileStatement(BoundWhileStatement node)
{
throw new NotImplementedException();
}
private MObject? EvaluateSwitchStatement(BoundSwitchStatement node)
{
throw new NotImplementedException();
}
private MObject? EvaluateFunctionDeclaration(BoundFunctionDeclaration node)
{
throw new NotImplementedException();
}
private MObject? EvaluateAbstractMethodDeclaration(BoundAbstractMethodDeclaration node)
{
throw new NotImplementedException();
}
private MObject? EvaluateMethodDefinition(BoundConcreteMethodDeclaration node)
{
throw new NotImplementedException();
}
private MObject? EvaluateExpressionStatement(BoundExpressionStatement node)
{
return EvaluateExpression(node.Expression);
}
private MObject? EvaluateExpression(BoundExpression node)
{
return node.Kind switch
{
BoundNodeKind.ArrayLiteralExpression =>
EvaluateArrayLiteralExpression((BoundArrayLiteralExpression)node),
BoundNodeKind.AssignmentExpression =>
EvaluateAssignmentExpression((BoundAssignmentExpression)node),
BoundNodeKind.BinaryOperationExpression =>
EvaluateBinaryOperation((BoundBinaryOperationExpression)node),
BoundNodeKind.CellArrayElementAccessExpression =>
EvaluateCellArrayElementAccess((BoundCellArrayElementAccessExpression)node),
BoundNodeKind.CellArrayLiteralExpression =>
EvaluateCellArrayLiteralExpression((BoundCellArrayLiteralExpression)node),
BoundNodeKind.ClassInvokationExpression =>
EvaluateClassInvokation((BoundClassInvokationExpression)node),
BoundNodeKind.CommandExpression =>
EvaluateCommand((BoundCommandExpression)node),
BoundNodeKind.CompoundNameExpression =>
EvaluateCompoundName((BoundCompoundNameExpression)node),
BoundNodeKind.DoubleQuotedStringLiteralExpression =>
EvaluateDoubleQuotedStringLiteralExpression((BoundDoubleQuotedStringLiteralExpression)node),
BoundNodeKind.EmptyExpression =>
EvaluateEmptyExpression((BoundEmptyExpression)node),
BoundNodeKind.FunctionCallExpression =>
EvaluateFunctionCall((BoundFunctionCallExpression)node),
BoundNodeKind.IdentifierNameExpression =>
EvaluateIdentifierNameExpression((BoundIdentifierNameExpression)node),
BoundNodeKind.IndirectMemberAccessExpression =>
EvaluateIndirectMemberAccess((BoundIndirectMemberAccessExpression)node),
BoundNodeKind.LambdaExpression =>
EvaluateLambdaExpression((BoundLambdaExpression)node),
BoundNodeKind.MemberAccessExpression =>
EvaluateMemberAccess((BoundMemberAccessExpression)node),
BoundNodeKind.NamedFunctionHandleExpression =>
EvaluateNamedFunctionHandleExpression((BoundNamedFunctionHandleExpression)node),
BoundNodeKind.NumberLiteralExpression =>
EvaluateNumberLiteralExpression((BoundNumberLiteralExpression)node),
BoundNodeKind.StringLiteralExpression =>
EvaluateStringLiteralExpression((BoundStringLiteralExpression)node),
BoundNodeKind.UnaryOperationExpression =>
EvaluateUnaryOperationExpression((BoundUnaryOperationExpression)node),
BoundNodeKind.UnquotedStringLiteralExpression =>
EvaluateUnquotedStringLiteralExpression((BoundUnquotedStringLiteralExpression)node),
_ => throw new NotImplementedException($"Invalid expression kind '{node.Kind}'."),
};
}
private MObject? EvaluateClassInvokation(BoundClassInvokationExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateCommand(BoundCommandExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateIndirectMemberAccess(BoundIndirectMemberAccessExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateMemberAccess(BoundMemberAccessExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateFunctionCall(BoundFunctionCallExpression node)
{
var arguments = new List<MObject>();
var allGood = true;
foreach (var argument in node.Arguments)
{
var evaluatedArgument = EvaluateExpression(argument);
if (argument is null)
{
_diagnostics.ReportCannotEvaluateExpression(
new TextSpan(argument.Syntax.Position, argument.Syntax.FullWidth));
allGood = false;
}
else
{
arguments.Add(evaluatedArgument);
}
}
if (!allGood)
{
return null;
}
var function = GetFunctionSymbol(node.Name);
if (function.Name == "disp")
{
return EvaluateDisp(arguments);
}
else
{
var resolvedFunction = ResolveFunction(function);
if (resolvedFunction is null)
{
_diagnostics.ReportFunctionNotFound(
new TextSpan(
node.Name.Syntax.Position,
node.Name.Syntax.Position + node.Name.Syntax.FullWidth),
function.Name);
return null;
}
else
{
// bring arguments into context
var newScope = new EvaluationScope();
var counter = 0;
foreach (var expectedArgument in resolvedFunction.InputDescription)
{
if (counter >= arguments.Count)
{
break;
}
newScope.Variables.Add(expectedArgument.Name, arguments[counter]);
counter++;
}
if (counter < arguments.Count)
{
_diagnostics.ReportTooManyInputs(
new TextSpan(
node.Arguments[counter].Syntax.Position,
node.Arguments[counter].Syntax.Position + node.Arguments[counter].Syntax.FullWidth),
function.Name);
return null;
}
_scopeStack.Push(newScope);
var result = EvaluateBlockStatement(resolvedFunction.Body);
_scopeStack.Pop();
return result;
}
}
}
private LoweredFunction? ResolveFunction(UnresolvedFunctionSymbol functionSymbol)
{
var maybeKey = _functions.Keys.FirstOrDefault(k => k.Name == functionSymbol.Name);
return maybeKey switch
{
{ } key => _functions[key],
_ => null,
};
}
private MObject? EvaluateDisp(List<MObject> arguments)
{
if (arguments.Count != 1)
{
throw new NotImplementedException($"Cannot evaluate disp() with {arguments.Count} arguments.");
}
Console.WriteLine(arguments[0]);
return arguments[0];
}
private UnresolvedFunctionSymbol GetFunctionSymbol(BoundExpression functionName)
{
if (functionName.Kind == BoundNodeKind.IdentifierNameExpression)
{
return new UnresolvedFunctionSymbol(((BoundIdentifierNameExpression)functionName).Name);
}
throw new NotImplementedException($"Unknown function symbol '{functionName.Syntax.Text}'.");
}
private MObject? EvaluateCellArrayElementAccess(BoundCellArrayElementAccessExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateCellArrayLiteralExpression(BoundCellArrayLiteralExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateArrayLiteralExpression(BoundArrayLiteralExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateUnquotedStringLiteralExpression(BoundUnquotedStringLiteralExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateDoubleQuotedStringLiteralExpression(BoundDoubleQuotedStringLiteralExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateStringLiteralExpression(BoundStringLiteralExpression node)
{
return node.Value switch
{
string s => MObject.CreateCharArray(s.ToCharArray()),
_ => null,
};
}
private MObject? EvaluateNumberLiteralExpression(BoundNumberLiteralExpression node)
{
return MObject.CreateDoubleNumber(node.Value);
}
private MObject? EvaluateIdentifierNameExpression(BoundIdentifierNameExpression node)
{
var variableName = node.Name;
var maybeValue = GetVariableValue(variableName);
if (maybeValue is null)
{
_diagnostics.ReportVariableNotFound(
new TextSpan(node.Syntax.Position, node.Syntax.FullWidth),
variableName);
}
return maybeValue;
}
private MObject? EvaluateBinaryOperation(BoundBinaryOperationExpression node)
{
var left = EvaluateExpression(node.Left);
if (left is null)
{
return null;
}
var right = EvaluateExpression(node.Right);
if (right is null)
{
return null;
}
return node.Op.Kind switch
{
BoundBinaryOperatorKind.Plus => MOperations.Plus(left, right),
BoundBinaryOperatorKind.Minus => MOperations.Minus(left, right),
BoundBinaryOperatorKind.Star => MOperations.Star(left, right),
BoundBinaryOperatorKind.Slash => MOperations.Slash(left, right),
BoundBinaryOperatorKind.Greater => MOperations.Greater(left, right),
BoundBinaryOperatorKind.GreaterOrEquals => MOperations.GreaterOrEquals(left, right),
BoundBinaryOperatorKind.Less => MOperations.Less(left, right),
BoundBinaryOperatorKind.LessOrEquals => MOperations.LessOrEquals(left, right),
_ => throw new NotImplementedException($"Binary operation {node.Op.Kind} is not implemented."),
};
}
private MObject? EvaluateCompoundName(BoundCompoundNameExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateUnaryOperationExpression(BoundUnaryOperationExpression node)
{
var operand = EvaluateExpression(node.Operand);
if (operand is null)
{
return null;
}
return node.Op.Kind switch
{
BoundUnaryOperatorKind.Minus => MOperations.Minus(operand),
_ => throw new NotImplementedException($"Unary operation {node.Op.Kind} is not implemented."),
};
}
private MObject? EvaluateEmptyExpression(BoundEmptyExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateAssignmentExpression(BoundAssignmentExpression node)
{
var rightValue = EvaluateExpression(node.Right);
if (rightValue is null)
{
_diagnostics.ReportCannotEvaluateExpression(
new TextSpan(node.Right.Syntax.Position, node.Right.Syntax.Position + node.Right.Syntax.FullWidth));
return null;
}
var left = node.Left;
if (left.Kind == BoundNodeKind.IdentifierNameExpression)
{
var leftIdentifier = (BoundIdentifierNameExpression)left;
var variableName = leftIdentifier.Name;
SetVariableValue(variableName, rightValue);
return rightValue;
}
throw new NotImplementedException();
}
private MObject? GetVariableValue(string name)
{
if (_inRepl)
{
return _context.Variables.TryGetValue(name, out var globalValue) ? globalValue : null;
}
else
{
var currentScope = _scopeStack.Peek();
return currentScope.Variables.TryGetValue(name, out var localValue) ? localValue : null;
}
}
private void SetVariableValue(string name, MObject value)
{
if (_inRepl)
{
_context.Variables[name] = value;
}
else
{
var currentScope = _scopeStack.Peek();
currentScope.Variables[name] = value;
}
}
private MObject? EvaluateLambdaExpression(BoundLambdaExpression node)
{
throw new NotImplementedException();
}
private MObject? EvaluateNamedFunctionHandleExpression(BoundNamedFunctionHandleExpression node)
{
throw new NotImplementedException();
}
}
}

View File

@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@ -37,6 +38,11 @@ namespace Parser.Internal
Report(span, "Unexpected end of file.");
}
internal void ReportNotEnoughInputs(TextSpan span, string functionName)
{
Report(span, $"Not enough inputs for function '{functionName}'.");
}
internal void ReportUnexpectedCharacterWhileParsingNumber(TextSpan span, char c)
{
Report(span, $"Unexpected character '{c}' while parsing a number.");
@ -67,6 +73,11 @@ namespace Parser.Internal
Report(span, "Unmatched open parenthesis by the end of file.");
}
internal void ReportCannotEvaluateExpression(TextSpan span)
{
Report(span, $"Cannot evaluate expression.");
}
public IEnumerator<Diagnostic> GetEnumerator()
{
return _diagnostics.GetEnumerator();
@ -77,5 +88,19 @@ namespace Parser.Internal
return GetEnumerator();
}
internal void ReportVariableNotFound(TextSpan span, string variableName)
{
Report(span, $"Variable '{variableName}' not found.");
}
internal void ReportFunctionNotFound(TextSpan span, string functionName)
{
Report(span, $"Function '{functionName}' not found.");
}
internal void ReportTooManyInputs(TextSpan span, string functionName)
{
Report(span, $"Too many inputs in the call to '{functionName}'.");
}
}
}

View File

@ -43,6 +43,11 @@ namespace Parser.Internal
internal abstract Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position);
public virtual object? GetValue()
{
return null;
}
protected int _fullWidth;
public int FullWidth => _fullWidth;

View File

@ -13,6 +13,7 @@ namespace Parser.Internal
public string Text { get; set; } = "";
public string StringValue { get; set; } = "";
public double DoubleValue { get; set; }
public bool ImaginaryFlag { get; set; }
}
private ITextWindow Window { get; }
@ -358,20 +359,48 @@ namespace Parser.Internal
if (success)
{
tokenInfo.Kind = TokenKind.NumberLiteralToken;
Range rangeToParse;
if (Window.PeekChar(n) == 'i' || Window.PeekChar(n) == 'j')
{
tokenInfo.ImaginaryFlag = true;
n++;
rangeToParse = ..^1;
}
else
{
rangeToParse = ..;
}
var s = Window.GetAndConsumeChars(n);
tokenInfo.Kind = TokenKind.NumberLiteralToken;
var s = Window.GetAndConsumeChars(n);
tokenInfo.Text = s;
return true;
var maybeValue = ParseDoubleValue(s[rangeToParse]);
if (maybeValue is double value)
{
tokenInfo.DoubleValue = value;
return true;
}
else
{
tokenInfo.DoubleValue = double.NaN;
return true;
}
}
return false;
}
private double? ParseDoubleValue(string s)
{
if (double.TryParse(s, out var doubleValue))
{
return doubleValue;
} else
{
return null;
}
}
private bool ContinueLexingGeneralStringLiteral(ref TokenInfo tokenInfo, char quote)
{
var status = 0; // no errors

View File

@ -113,7 +113,7 @@ namespace Parser.Internal
}
firstToken = false;
outputs.Add(Factory.IdentifierNameSyntax(EatToken(TokenKind.IdentifierToken)));
outputs.Add(Factory.IdentifierNameExpressionSyntax(EatToken(TokenKind.IdentifierToken)));
}
return outputs.ToList();
@ -141,7 +141,7 @@ namespace Parser.Internal
if (PeekToken(1).Kind == TokenKind.EqualsToken)
{
var identifierToken = EatIdentifier();
builder.Add(Factory.IdentifierNameSyntax(identifierToken));
builder.Add(Factory.IdentifierNameExpressionSyntax(identifierToken));
assignmentSign = EatToken(TokenKind.EqualsToken);
}
else
@ -175,12 +175,12 @@ namespace Parser.Internal
if (CurrentToken.Kind == TokenKind.TildeToken)
{
var notToken = EatToken();
builder.Add(notToken);
builder.Add(Factory.IdentifierNameExpressionSyntax(notToken));
}
else
{
var identifierToken = EatToken(TokenKind.IdentifierToken);
builder.Add(Factory.IdentifierNameSyntax(identifierToken));
builder.Add(Factory.IdentifierNameExpressionSyntax(identifierToken));
}
}
@ -212,7 +212,7 @@ namespace Parser.Internal
var name = EatToken(TokenKind.IdentifierToken);
var inputDescription = ParseFunctionInputDescription();
var commas = ParseOptionalCommas();
var body = ParseStatementList();
var body = ParseBlockStatement();
var endKeyword = ParseEndKeyword();
//var endKeyword =
return Factory.FunctionDeclarationSyntax(
@ -307,13 +307,13 @@ namespace Parser.Internal
switch (token.Kind)
{
case TokenKind.NumberLiteralToken:
expression = Factory.NumberLiteralSyntax(EatToken());
expression = Factory.NumberLiteralExpressionSyntax(EatToken());
break;
case TokenKind.StringLiteralToken:
expression = Factory.StringLiteralSyntax(EatToken());
expression = Factory.StringLiteralExpressionSyntax(EatToken());
break;
case TokenKind.DoubleQuotedStringLiteralToken:
expression = Factory.DoubleQuotedStringLiteralSyntax(EatToken());
expression = Factory.DoubleQuotedStringLiteralExpressionSyntax(EatToken());
break;
case TokenKind.OpenSquareBracketToken:
expression = ParseArrayLiteral();
@ -329,7 +329,7 @@ namespace Parser.Internal
break;
default:
var id = EatToken(TokenKind.IdentifierToken);
expression = Factory.IdentifierNameSyntax(id);
expression = Factory.IdentifierNameExpressionSyntax(id);
break;
}
@ -377,14 +377,14 @@ namespace Parser.Internal
closingBracket);
break;
case TokenKind.DotToken: // member access
if (expression is IdentifierNameSyntaxNode
|| expression is MemberAccessSyntaxNode
if (expression is IdentifierNameExpressionSyntaxNode
|| expression is MemberAccessExpressionSyntaxNode
|| expression is FunctionCallExpressionSyntaxNode
|| expression is CellArrayElementAccessExpressionSyntaxNode)
{
var dot = EatToken();
var member = ParseMemberAccess();
expression = Factory.MemberAccessSyntax(expression, dot, member);
expression = Factory.MemberAccessExpressionSyntax(expression, dot, member);
}
else
{
@ -396,7 +396,7 @@ namespace Parser.Internal
case TokenKind.ApostropheToken:
case TokenKind.DotApostropheToken:
var operation = EatToken();
expression = Factory.UnaryPostixOperationExpressionSyntax(expression, operation);
expression = Factory.UnaryPostfixOperationExpressionSyntax(expression, operation);
break;
case TokenKind.UnquotedStringLiteralToken:
return ParseCommandExpression(expression);
@ -414,15 +414,15 @@ namespace Parser.Internal
private CommandExpressionSyntaxNode ParseCommandExpression(ExpressionSyntaxNode expression)
{
if (expression is IdentifierNameSyntaxNode idNameNode)
if (expression is IdentifierNameExpressionSyntaxNode idNameNode)
{
var builder = new SyntaxListBuilder<UnquotedStringLiteralSyntaxNode>();
var builder = new SyntaxListBuilder<UnquotedStringLiteralExpressionSyntaxNode>();
while (CurrentToken.Kind == TokenKind.UnquotedStringLiteralToken)
{
builder.Add(Factory.UnquotedStringLiteralSyntax(EatToken()));
builder.Add(Factory.UnquotedStringLiteralExpressionSyntax(EatToken()));
}
return Factory.CommandExpressionSyntax(idNameNode, builder.ToList());
return Factory.CommandExpressionSyntax(idNameNode._name, builder.ToList());
}
if (expression is null)
@ -432,9 +432,9 @@ namespace Parser.Internal
throw new ParsingException($"Unexpected token \"{CurrentToken}\" while parsing expression \"{expression.FullText}\" at {CurrentPosition}.");
}
private BaseClassInvokationSyntaxNode ParseBaseClassInvokation(ExpressionSyntaxNode expression)
private ClassInvokationExpressionSyntaxNode ParseBaseClassInvokation(ExpressionSyntaxNode expression)
{
if (expression is IdentifierNameSyntaxNode methodName
if (expression is IdentifierNameExpressionSyntaxNode methodName
&& !expression.TrailingTrivia.Any())
{
var atToken = EatToken();
@ -443,9 +443,9 @@ namespace Parser.Internal
{
throw new Exception($"Base class name cannot be empty.");
}
return Factory.BaseClassInvokationSyntax(methodName, atToken, baseClassNameWithArguments);
return Factory.ClassInvokationExpressionSyntax(methodName, atToken, baseClassNameWithArguments);
}
if (expression is MemberAccessSyntaxNode memberAccess
if (expression is MemberAccessExpressionSyntaxNode memberAccess
&& !expression.TrailingTrivia.Any())
{
var atToken = EatToken();
@ -454,7 +454,7 @@ namespace Parser.Internal
{
throw new Exception($"Base class name cannot be empty.");
}
return Factory.BaseClassInvokationSyntax(memberAccess, atToken, baseClassNameWithArguments);
return Factory.ClassInvokationExpressionSyntax(memberAccess, atToken, baseClassNameWithArguments);
}
throw new ParsingException($"Unexpected token \"{CurrentToken}\" at {CurrentPosition}.");
}
@ -463,7 +463,7 @@ namespace Parser.Internal
{
if (CurrentToken.Kind == TokenKind.IdentifierToken)
{
return Factory.IdentifierNameSyntax(EatToken());
return Factory.IdentifierNameExpressionSyntax(EatToken());
}
if (CurrentToken.Kind == TokenKind.OpenParenthesisToken)
{
@ -474,7 +474,7 @@ namespace Parser.Internal
throw new Exception("Indirect member invokation cannot be empty.");
}
var closingBracket = EatToken(TokenKind.CloseParenthesisToken);
return Factory.IndirectMemberAccessSyntax(
return Factory.IndirectMemberAccessExpressionSyntax(
openingBracket,
indirectMember,
closingBracket);
@ -523,7 +523,7 @@ namespace Parser.Internal
closeParen);
}
private CompoundNameSyntaxNode ParseCompoundName()
private CompoundNameExpressionSyntaxNode ParseCompoundName()
{
var lastToken = EatToken(TokenKind.IdentifierToken);
var firstName = lastToken;
@ -538,16 +538,16 @@ namespace Parser.Internal
builder.Add(lastToken);
}
return Factory.CompoundNameSyntax(builder.ToList());
return Factory.CompoundNameExpressionSyntax(builder.ToList());
}
private FunctionHandleSyntaxNode ParseFunctionHandle()
private FunctionHandleExpressionSyntaxNode ParseFunctionHandle()
{
var atSign = EatToken();
if (CurrentToken.Kind == TokenKind.IdentifierToken)
{
var compoundName = ParseCompoundName();
return Factory.NamedFunctionHandleSyntax(
return Factory.NamedFunctionHandleExpressionSyntax(
atSign,
compoundName);
}
@ -563,7 +563,7 @@ namespace Parser.Internal
{
throw new Exception($"Lambda expression body cannot be empty.");
}
return Factory.LambdaSyntax(atSign, inputs, body);
return Factory.LambdaExpressionSyntax(atSign, inputs, body);
}
throw new ParsingException($"Unexpected token {CurrentToken} while parsing function handle at {CurrentPosition}.");
}
@ -685,8 +685,8 @@ namespace Parser.Internal
throw new Exception("Case label cannot be empty.");
}
var commas = ParseOptionalCommas();
var statementList = ParseStatementList();
return Factory.SwitchCaseSyntax(caseKeyword, caseId, commas, statementList);
var body = ParseBlockStatement();
return Factory.SwitchCaseSyntax(caseKeyword, caseId, commas, body);
}
private SwitchStatementSyntaxNode ParseSwitchStatement()
@ -722,7 +722,7 @@ namespace Parser.Internal
}
var commas = ParseOptionalCommas();
var body = ParseStatementList();
var body = ParseBlockStatement();
var endKeyword = EatIdentifier("end");
return Factory.WhileStatementSyntax(
whileKeyword,
@ -741,14 +741,14 @@ namespace Parser.Internal
throw new Exception("Condition in elseif clause cannot be empty.");
}
var commas = ParseOptionalCommas();
var body = ParseStatementList();
var body = ParseBlockStatement();
return Factory.ElseifClause(elseifKeyword, condition, commas, body);
}
private ElseClause ParseElseClause()
{
var elseKeyword = EatIdentifier("else");
var body = ParseStatementList();
var body = ParseBlockStatement();
return Factory.ElseClause(elseKeyword, body);
}
@ -761,7 +761,7 @@ namespace Parser.Internal
throw new Exception("Condition in if statement cannot be empty.");
}
var commas = ParseOptionalSemicolonsOrCommas();
var body = ParseStatementList();
var body = ParseBlockStatement();
var elseifClauses = new SyntaxListBuilder<ElseifClause>();
ElseClause? elseClause = null;
while (true)
@ -804,7 +804,7 @@ namespace Parser.Internal
var forAssignment = (AssignmentExpressionSyntaxNode) expression;
var commas = ParseOptionalSemicolonsOrCommas();
var body = ParseStatementList();
var body = ParseBlockStatement();
var endKeyword = EatIdentifier("end");
return Factory.ForStatementSyntax(
forKeyword,
@ -831,7 +831,7 @@ namespace Parser.Internal
private TryCatchStatementSyntaxNode ParseTryCatchStatement()
{
var tryKeyword = EatIdentifier("try");
var tryBody = ParseStatementList();
var tryBody = ParseBlockStatement();
var catchClause = ParseCatchClause();
var endKeyword = EatIdentifier("end");
return Factory.TryCatchStatementSyntax(tryKeyword, tryBody, catchClause, endKeyword);
@ -866,7 +866,7 @@ namespace Parser.Internal
private AttributeSyntaxNode ParseAttribute()
{
var name = Factory.IdentifierNameSyntax(EatToken(TokenKind.IdentifierToken));
var name = EatToken(TokenKind.IdentifierToken);
var assignment = ParseAttributeAssignment();
return Factory.AttributeSyntax(name, assignment);
}
@ -920,16 +920,16 @@ namespace Parser.Internal
throw new ParsingException($"Unexpected token {CurrentToken} while parsing method declaration at {CurrentPosition}.");
}
private MethodDefinitionSyntaxNode ParseMethodDefinition()
private ConcreteMethodDeclarationSyntaxNode ParseMethodDefinition()
{
var functionKeyword = EatIdentifier("function");
var outputDescription = ParseFunctionOutputDescription();
var name = ParseCompoundName();
var inputDescription = ParseFunctionInputDescription();
var commas = ParseOptionalCommas();
var body = ParseStatementList();
var body = ParseBlockStatement();
var endKeyword = ParseEndKeyword();
return Factory.MethodDefinitionSyntax(
return Factory.ConcreteMethodDeclarationSyntax(
functionKeyword,
outputDescription,
name,
@ -1023,7 +1023,7 @@ namespace Parser.Internal
private EnumerationItemSyntaxNode ParseEnumerationItem()
{
var name = Factory.IdentifierNameSyntax(EatToken());
var name = EatToken();
var values = ParseEnumerationValue();
var commas = ParseOptionalCommas();
return Factory.EnumerationItemSyntax(name, values, commas);
@ -1104,7 +1104,7 @@ namespace Parser.Internal
{
attributes = ParseAttributesList();
}
var className = Factory.IdentifierNameSyntax(EatToken(TokenKind.IdentifierToken));
var className = EatToken(TokenKind.IdentifierToken);
BaseClassListSyntaxNode? baseClassList = null;
if (CurrentToken.Kind == TokenKind.LessToken)
{
@ -1190,6 +1190,12 @@ namespace Parser.Internal
}
return ParseExpressionStatement();
}
private BlockStatementSyntaxNode ParseBlockStatement()
{
var statements = ParseStatementList();
return Factory.BlockStatementSyntax(statements);
}
private SyntaxList ParseStatementList()
{
@ -1214,7 +1220,7 @@ namespace Parser.Internal
public FileSyntaxNode ParseFile()
{
var statementList = ParseStatementList();
var statementList = ParseBlockStatement();
var endOfFileToken = EatToken();
return Factory.FileSyntax(statementList, endOfFileToken);
}

View File

@ -3,12 +3,17 @@ namespace Parser.Internal
{
internal partial class SyntaxFactory
{
public FileSyntaxNode FileSyntax(SyntaxList statementList, SyntaxToken endOfFile)
public FileSyntaxNode FileSyntax(BlockStatementSyntaxNode body, SyntaxToken endOfFile)
{
return new FileSyntaxNode(statementList, endOfFile);
return new FileSyntaxNode(body, endOfFile);
}
public FunctionDeclarationSyntaxNode FunctionDeclarationSyntax(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, SyntaxToken name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, SyntaxList body, EndKeywordSyntaxNode? endKeyword)
public BlockStatementSyntaxNode BlockStatementSyntax(SyntaxList statements)
{
return new BlockStatementSyntaxNode(statements);
}
public FunctionDeclarationSyntaxNode FunctionDeclarationSyntax(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, SyntaxToken name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, StatementSyntaxNode body, EndKeywordSyntaxNode? endKeyword)
{
return new FunctionDeclarationSyntaxNode(functionKeyword, outputDescription, name, inputDescription, commas, body, endKeyword);
}
@ -28,32 +33,32 @@ namespace Parser.Internal
return new SwitchStatementSyntaxNode(switchKeyword, switchExpression, optionalCommas, cases, endKeyword);
}
public SwitchCaseSyntaxNode SwitchCaseSyntax(SyntaxToken caseKeyword, ExpressionSyntaxNode caseIdentifier, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body)
public SwitchCaseSyntaxNode SwitchCaseSyntax(SyntaxToken caseKeyword, ExpressionSyntaxNode caseIdentifier, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body)
{
return new SwitchCaseSyntaxNode(caseKeyword, caseIdentifier, optionalCommas, body);
}
public WhileStatementSyntaxNode WhileStatementSyntax(SyntaxToken whileKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxToken endKeyword)
public WhileStatementSyntaxNode WhileStatementSyntax(SyntaxToken whileKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxToken endKeyword)
{
return new WhileStatementSyntaxNode(whileKeyword, condition, optionalCommas, body, endKeyword);
}
public ElseifClause ElseifClause(SyntaxToken elseifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body)
public ElseifClause ElseifClause(SyntaxToken elseifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body)
{
return new ElseifClause(elseifKeyword, condition, optionalCommas, body);
}
public ElseClause ElseClause(SyntaxToken elseKeyword, SyntaxList body)
public ElseClause ElseClause(SyntaxToken elseKeyword, StatementSyntaxNode body)
{
return new ElseClause(elseKeyword, body);
}
public IfStatementSyntaxNode IfStatementSyntax(SyntaxToken ifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxList<ElseifClause> elseifClauses, ElseClause? elseClause, SyntaxToken endKeyword)
public IfStatementSyntaxNode IfStatementSyntax(SyntaxToken ifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxList<ElseifClause> elseifClauses, ElseClause? elseClause, SyntaxToken endKeyword)
{
return new IfStatementSyntaxNode(ifKeyword, condition, optionalCommas, body, elseifClauses, elseClause, endKeyword);
}
public ForStatementSyntaxNode ForStatementSyntax(SyntaxToken forKeyword, AssignmentExpressionSyntaxNode assignment, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxToken endKeyword)
public ForStatementSyntaxNode ForStatementSyntax(SyntaxToken forKeyword, AssignmentExpressionSyntaxNode assignment, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxToken endKeyword)
{
return new ForStatementSyntaxNode(forKeyword, assignment, optionalCommas, body, endKeyword);
}
@ -68,7 +73,7 @@ namespace Parser.Internal
return new CatchClauseSyntaxNode(catchKeyword, catchBody);
}
public TryCatchStatementSyntaxNode TryCatchStatementSyntax(SyntaxToken tryKeyword, SyntaxList tryBody, CatchClauseSyntaxNode? catchClause, SyntaxToken endKeyword)
public TryCatchStatementSyntaxNode TryCatchStatementSyntax(SyntaxToken tryKeyword, StatementSyntaxNode tryBody, CatchClauseSyntaxNode? catchClause, SyntaxToken endKeyword)
{
return new TryCatchStatementSyntaxNode(tryKeyword, tryBody, catchClause, endKeyword);
}
@ -93,19 +98,19 @@ namespace Parser.Internal
return new UnaryPrefixOperationExpressionSyntaxNode(operation, operand);
}
public CompoundNameSyntaxNode CompoundNameSyntax(SyntaxList nodes)
public CompoundNameExpressionSyntaxNode CompoundNameExpressionSyntax(SyntaxList nodes)
{
return new CompoundNameSyntaxNode(nodes);
return new CompoundNameExpressionSyntaxNode(nodes);
}
public NamedFunctionHandleSyntaxNode NamedFunctionHandleSyntax(SyntaxToken atSign, CompoundNameSyntaxNode functionName)
public NamedFunctionHandleExpressionSyntaxNode NamedFunctionHandleExpressionSyntax(SyntaxToken atSign, CompoundNameExpressionSyntaxNode functionName)
{
return new NamedFunctionHandleSyntaxNode(atSign, functionName);
return new NamedFunctionHandleExpressionSyntaxNode(atSign, functionName);
}
public LambdaSyntaxNode LambdaSyntax(SyntaxToken atSign, FunctionInputDescriptionSyntaxNode input, ExpressionSyntaxNode body)
public LambdaExpressionSyntaxNode LambdaExpressionSyntax(SyntaxToken atSign, FunctionInputDescriptionSyntaxNode input, ExpressionSyntaxNode body)
{
return new LambdaSyntaxNode(atSign, input, body);
return new LambdaExpressionSyntaxNode(atSign, input, body);
}
public BinaryOperationExpressionSyntaxNode BinaryOperationExpressionSyntax(ExpressionSyntaxNode lhs, SyntaxToken operation, ExpressionSyntaxNode rhs)
@ -113,29 +118,29 @@ namespace Parser.Internal
return new BinaryOperationExpressionSyntaxNode(lhs, operation, rhs);
}
public IdentifierNameSyntaxNode IdentifierNameSyntax(SyntaxToken name)
public IdentifierNameExpressionSyntaxNode IdentifierNameExpressionSyntax(SyntaxToken name)
{
return new IdentifierNameSyntaxNode(name);
return new IdentifierNameExpressionSyntaxNode(name);
}
public NumberLiteralSyntaxNode NumberLiteralSyntax(SyntaxToken number)
public NumberLiteralExpressionSyntaxNode NumberLiteralExpressionSyntax(SyntaxToken number)
{
return new NumberLiteralSyntaxNode(number);
return new NumberLiteralExpressionSyntaxNode(number);
}
public StringLiteralSyntaxNode StringLiteralSyntax(SyntaxToken stringToken)
public StringLiteralExpressionSyntaxNode StringLiteralExpressionSyntax(SyntaxToken stringToken)
{
return new StringLiteralSyntaxNode(stringToken);
return new StringLiteralExpressionSyntaxNode(stringToken);
}
public DoubleQuotedStringLiteralSyntaxNode DoubleQuotedStringLiteralSyntax(SyntaxToken stringToken)
public DoubleQuotedStringLiteralExpressionSyntaxNode DoubleQuotedStringLiteralExpressionSyntax(SyntaxToken stringToken)
{
return new DoubleQuotedStringLiteralSyntaxNode(stringToken);
return new DoubleQuotedStringLiteralExpressionSyntaxNode(stringToken);
}
public UnquotedStringLiteralSyntaxNode UnquotedStringLiteralSyntax(SyntaxToken stringToken)
public UnquotedStringLiteralExpressionSyntaxNode UnquotedStringLiteralExpressionSyntax(SyntaxToken stringToken)
{
return new UnquotedStringLiteralSyntaxNode(stringToken);
return new UnquotedStringLiteralExpressionSyntaxNode(stringToken);
}
public ArrayLiteralExpressionSyntaxNode ArrayLiteralExpressionSyntax(SyntaxToken openingSquareBracket, SyntaxList nodes, SyntaxToken closingSquareBracket)
@ -163,29 +168,29 @@ namespace Parser.Internal
return new FunctionCallExpressionSyntaxNode(functionName, openingBracket, nodes, closingBracket);
}
public MemberAccessSyntaxNode MemberAccessSyntax(SyntaxNode leftOperand, SyntaxToken dot, SyntaxNode rightOperand)
public MemberAccessExpressionSyntaxNode MemberAccessExpressionSyntax(SyntaxNode leftOperand, SyntaxToken dot, SyntaxNode rightOperand)
{
return new MemberAccessSyntaxNode(leftOperand, dot, rightOperand);
return new MemberAccessExpressionSyntaxNode(leftOperand, dot, rightOperand);
}
public UnaryPostixOperationExpressionSyntaxNode UnaryPostixOperationExpressionSyntax(ExpressionSyntaxNode operand, SyntaxToken operation)
public UnaryPostfixOperationExpressionSyntaxNode UnaryPostfixOperationExpressionSyntax(ExpressionSyntaxNode operand, SyntaxToken operation)
{
return new UnaryPostixOperationExpressionSyntaxNode(operand, operation);
return new UnaryPostfixOperationExpressionSyntaxNode(operand, operation);
}
public IndirectMemberAccessSyntaxNode IndirectMemberAccessSyntax(SyntaxToken openingBracket, ExpressionSyntaxNode expression, SyntaxToken closingBracket)
public IndirectMemberAccessExpressionSyntaxNode IndirectMemberAccessExpressionSyntax(SyntaxToken openingBracket, ExpressionSyntaxNode expression, SyntaxToken closingBracket)
{
return new IndirectMemberAccessSyntaxNode(openingBracket, expression, closingBracket);
return new IndirectMemberAccessExpressionSyntaxNode(openingBracket, expression, closingBracket);
}
public CommandExpressionSyntaxNode CommandExpressionSyntax(IdentifierNameSyntaxNode commandName, SyntaxList<UnquotedStringLiteralSyntaxNode> arguments)
public CommandExpressionSyntaxNode CommandExpressionSyntax(SyntaxToken commandName, SyntaxList<UnquotedStringLiteralExpressionSyntaxNode> arguments)
{
return new CommandExpressionSyntaxNode(commandName, arguments);
}
public BaseClassInvokationSyntaxNode BaseClassInvokationSyntax(ExpressionSyntaxNode methodName, SyntaxToken atSign, ExpressionSyntaxNode baseClassNameAndArguments)
public ClassInvokationExpressionSyntaxNode ClassInvokationExpressionSyntax(ExpressionSyntaxNode methodName, SyntaxToken atSign, ExpressionSyntaxNode baseClassNameAndArguments)
{
return new BaseClassInvokationSyntaxNode(methodName, atSign, baseClassNameAndArguments);
return new ClassInvokationExpressionSyntaxNode(methodName, atSign, baseClassNameAndArguments);
}
public AttributeAssignmentSyntaxNode AttributeAssignmentSyntax(SyntaxToken assignmentSign, ExpressionSyntaxNode value)
@ -193,7 +198,7 @@ namespace Parser.Internal
return new AttributeAssignmentSyntaxNode(assignmentSign, value);
}
public AttributeSyntaxNode AttributeSyntax(IdentifierNameSyntaxNode name, AttributeAssignmentSyntaxNode? assignment)
public AttributeSyntaxNode AttributeSyntax(SyntaxToken name, AttributeAssignmentSyntaxNode? assignment)
{
return new AttributeSyntaxNode(name, assignment);
}
@ -203,12 +208,12 @@ namespace Parser.Internal
return new AttributeListSyntaxNode(openingBracket, nodes, closingBracket);
}
public MethodDefinitionSyntaxNode MethodDefinitionSyntax(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, SyntaxList body, EndKeywordSyntaxNode? endKeyword)
public ConcreteMethodDeclarationSyntaxNode ConcreteMethodDeclarationSyntax(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameExpressionSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, StatementSyntaxNode body, EndKeywordSyntaxNode? endKeyword)
{
return new MethodDefinitionSyntaxNode(functionKeyword, outputDescription, name, inputDescription, commas, body, endKeyword);
return new ConcreteMethodDeclarationSyntaxNode(functionKeyword, outputDescription, name, inputDescription, commas, body, endKeyword);
}
public AbstractMethodDeclarationSyntaxNode AbstractMethodDeclarationSyntax(FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription)
public AbstractMethodDeclarationSyntaxNode AbstractMethodDeclarationSyntax(FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameExpressionSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription)
{
return new AbstractMethodDeclarationSyntaxNode(outputDescription, name, inputDescription);
}
@ -228,7 +233,7 @@ namespace Parser.Internal
return new BaseClassListSyntaxNode(lessSign, baseClasses);
}
public ClassDeclarationSyntaxNode ClassDeclarationSyntax(SyntaxToken classdefKeyword, AttributeListSyntaxNode? attributes, IdentifierNameSyntaxNode className, BaseClassListSyntaxNode? baseClassList, SyntaxList nodes, SyntaxToken endKeyword)
public ClassDeclarationSyntaxNode ClassDeclarationSyntax(SyntaxToken classdefKeyword, AttributeListSyntaxNode? attributes, SyntaxToken className, BaseClassListSyntaxNode? baseClassList, SyntaxList nodes, SyntaxToken endKeyword)
{
return new ClassDeclarationSyntaxNode(classdefKeyword, attributes, className, baseClassList, nodes, endKeyword);
}
@ -238,7 +243,7 @@ namespace Parser.Internal
return new EnumerationItemValueSyntaxNode(openingBracket, values, closingBracket);
}
public EnumerationItemSyntaxNode EnumerationItemSyntax(IdentifierNameSyntaxNode name, EnumerationItemValueSyntaxNode? values, SyntaxList<SyntaxToken> commas)
public EnumerationItemSyntaxNode EnumerationItemSyntax(SyntaxToken name, EnumerationItemValueSyntaxNode? values, SyntaxList<SyntaxToken> commas)
{
return new EnumerationItemSyntaxNode(name, values, commas);
}

View File

@ -3,22 +3,22 @@ namespace Parser.Internal
{
internal class FileSyntaxNode : SyntaxNode
{
internal readonly SyntaxList _statementList;
internal readonly BlockStatementSyntaxNode _body;
internal readonly SyntaxToken _endOfFile;
internal FileSyntaxNode(SyntaxList statementList, SyntaxToken endOfFile): base(TokenKind.File)
internal FileSyntaxNode(BlockStatementSyntaxNode body, SyntaxToken endOfFile): base(TokenKind.File)
{
Slots = 2;
this.AdjustWidth(statementList);
_statementList = statementList;
this.AdjustWidth(body);
_body = body;
this.AdjustWidth(endOfFile);
_endOfFile = endOfFile;
}
internal FileSyntaxNode(SyntaxList statementList, SyntaxToken endOfFile, TokenDiagnostic[] diagnostics): base(TokenKind.File, diagnostics)
internal FileSyntaxNode(BlockStatementSyntaxNode body, SyntaxToken endOfFile, TokenDiagnostic[] diagnostics): base(TokenKind.File, diagnostics)
{
Slots = 2;
this.AdjustWidth(statementList);
_statementList = statementList;
this.AdjustWidth(body);
_body = body;
this.AdjustWidth(endOfFile);
_endOfFile = endOfFile;
}
@ -30,14 +30,52 @@ namespace Parser.Internal
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new FileSyntaxNode(_statementList, _endOfFile, diagnostics);
return new FileSyntaxNode(_body, _endOfFile, diagnostics);
}
public override GreenNode? GetSlot(int i)
{
return i switch
{
0 => _statementList, 1 => _endOfFile, _ => null
0 => _body, 1 => _endOfFile, _ => null
}
;
}
}
internal class BlockStatementSyntaxNode : StatementSyntaxNode
{
internal readonly SyntaxList _statements;
internal BlockStatementSyntaxNode(SyntaxList statements): base(TokenKind.BlockStatement)
{
Slots = 1;
this.AdjustWidth(statements);
_statements = statements;
}
internal BlockStatementSyntaxNode(SyntaxList statements, TokenDiagnostic[] diagnostics): base(TokenKind.BlockStatement, diagnostics)
{
Slots = 1;
this.AdjustWidth(statements);
_statements = statements;
}
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.BlockStatementSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new BlockStatementSyntaxNode(_statements, diagnostics);
}
public override GreenNode? GetSlot(int i)
{
return i switch
{
0 => _statements, _ => null
}
;
@ -51,9 +89,9 @@ namespace Parser.Internal
internal readonly SyntaxToken _name;
internal readonly FunctionInputDescriptionSyntaxNode? _inputDescription;
internal readonly SyntaxList<SyntaxToken> _commas;
internal readonly SyntaxList _body;
internal readonly StatementSyntaxNode _body;
internal readonly EndKeywordSyntaxNode? _endKeyword;
internal FunctionDeclarationSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, SyntaxToken name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, SyntaxList body, EndKeywordSyntaxNode? endKeyword): base(TokenKind.FunctionDeclaration)
internal FunctionDeclarationSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, SyntaxToken name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, StatementSyntaxNode body, EndKeywordSyntaxNode? endKeyword): base(TokenKind.FunctionDeclaration)
{
Slots = 7;
this.AdjustWidth(functionKeyword);
@ -72,7 +110,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal FunctionDeclarationSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, SyntaxToken name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, SyntaxList body, EndKeywordSyntaxNode? endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.FunctionDeclaration, diagnostics)
internal FunctionDeclarationSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, SyntaxToken name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, StatementSyntaxNode body, EndKeywordSyntaxNode? endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.FunctionDeclaration, diagnostics)
{
Slots = 7;
this.AdjustWidth(functionKeyword);
@ -266,8 +304,8 @@ namespace Parser.Internal
internal readonly SyntaxToken _caseKeyword;
internal readonly ExpressionSyntaxNode _caseIdentifier;
internal readonly SyntaxList<SyntaxToken> _optionalCommas;
internal readonly SyntaxList _body;
internal SwitchCaseSyntaxNode(SyntaxToken caseKeyword, ExpressionSyntaxNode caseIdentifier, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body): base(TokenKind.SwitchCase)
internal readonly StatementSyntaxNode _body;
internal SwitchCaseSyntaxNode(SyntaxToken caseKeyword, ExpressionSyntaxNode caseIdentifier, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body): base(TokenKind.SwitchCase)
{
Slots = 4;
this.AdjustWidth(caseKeyword);
@ -280,7 +318,7 @@ namespace Parser.Internal
_body = body;
}
internal SwitchCaseSyntaxNode(SyntaxToken caseKeyword, ExpressionSyntaxNode caseIdentifier, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, TokenDiagnostic[] diagnostics): base(TokenKind.SwitchCase, diagnostics)
internal SwitchCaseSyntaxNode(SyntaxToken caseKeyword, ExpressionSyntaxNode caseIdentifier, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, TokenDiagnostic[] diagnostics): base(TokenKind.SwitchCase, diagnostics)
{
Slots = 4;
this.AdjustWidth(caseKeyword);
@ -319,9 +357,9 @@ namespace Parser.Internal
internal readonly SyntaxToken _whileKeyword;
internal readonly ExpressionSyntaxNode _condition;
internal readonly SyntaxList<SyntaxToken> _optionalCommas;
internal readonly SyntaxList _body;
internal readonly StatementSyntaxNode _body;
internal readonly SyntaxToken _endKeyword;
internal WhileStatementSyntaxNode(SyntaxToken whileKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxToken endKeyword): base(TokenKind.WhileStatement)
internal WhileStatementSyntaxNode(SyntaxToken whileKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxToken endKeyword): base(TokenKind.WhileStatement)
{
Slots = 5;
this.AdjustWidth(whileKeyword);
@ -336,7 +374,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal WhileStatementSyntaxNode(SyntaxToken whileKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.WhileStatement, diagnostics)
internal WhileStatementSyntaxNode(SyntaxToken whileKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.WhileStatement, diagnostics)
{
Slots = 5;
this.AdjustWidth(whileKeyword);
@ -377,8 +415,8 @@ namespace Parser.Internal
internal readonly SyntaxToken _elseifKeyword;
internal readonly ExpressionSyntaxNode _condition;
internal readonly SyntaxList<SyntaxToken> _optionalCommas;
internal readonly SyntaxList _body;
internal ElseifClause(SyntaxToken elseifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body): base(TokenKind.ElseifClause)
internal readonly StatementSyntaxNode _body;
internal ElseifClause(SyntaxToken elseifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body): base(TokenKind.ElseifClause)
{
Slots = 4;
this.AdjustWidth(elseifKeyword);
@ -391,7 +429,7 @@ namespace Parser.Internal
_body = body;
}
internal ElseifClause(SyntaxToken elseifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, TokenDiagnostic[] diagnostics): base(TokenKind.ElseifClause, diagnostics)
internal ElseifClause(SyntaxToken elseifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, TokenDiagnostic[] diagnostics): base(TokenKind.ElseifClause, diagnostics)
{
Slots = 4;
this.AdjustWidth(elseifKeyword);
@ -428,8 +466,8 @@ namespace Parser.Internal
internal class ElseClause : SyntaxNode
{
internal readonly SyntaxToken _elseKeyword;
internal readonly SyntaxList _body;
internal ElseClause(SyntaxToken elseKeyword, SyntaxList body): base(TokenKind.ElseClause)
internal readonly StatementSyntaxNode _body;
internal ElseClause(SyntaxToken elseKeyword, StatementSyntaxNode body): base(TokenKind.ElseClause)
{
Slots = 2;
this.AdjustWidth(elseKeyword);
@ -438,7 +476,7 @@ namespace Parser.Internal
_body = body;
}
internal ElseClause(SyntaxToken elseKeyword, SyntaxList body, TokenDiagnostic[] diagnostics): base(TokenKind.ElseClause, diagnostics)
internal ElseClause(SyntaxToken elseKeyword, StatementSyntaxNode body, TokenDiagnostic[] diagnostics): base(TokenKind.ElseClause, diagnostics)
{
Slots = 2;
this.AdjustWidth(elseKeyword);
@ -473,11 +511,11 @@ namespace Parser.Internal
internal readonly SyntaxToken _ifKeyword;
internal readonly ExpressionSyntaxNode _condition;
internal readonly SyntaxList<SyntaxToken> _optionalCommas;
internal readonly SyntaxList _body;
internal readonly StatementSyntaxNode _body;
internal readonly SyntaxList<ElseifClause> _elseifClauses;
internal readonly ElseClause? _elseClause;
internal readonly SyntaxToken _endKeyword;
internal IfStatementSyntaxNode(SyntaxToken ifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxList<ElseifClause> elseifClauses, ElseClause? elseClause, SyntaxToken endKeyword): base(TokenKind.IfStatement)
internal IfStatementSyntaxNode(SyntaxToken ifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxList<ElseifClause> elseifClauses, ElseClause? elseClause, SyntaxToken endKeyword): base(TokenKind.IfStatement)
{
Slots = 7;
this.AdjustWidth(ifKeyword);
@ -496,7 +534,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal IfStatementSyntaxNode(SyntaxToken ifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxList<ElseifClause> elseifClauses, ElseClause? elseClause, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.IfStatement, diagnostics)
internal IfStatementSyntaxNode(SyntaxToken ifKeyword, ExpressionSyntaxNode condition, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxList<ElseifClause> elseifClauses, ElseClause? elseClause, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.IfStatement, diagnostics)
{
Slots = 7;
this.AdjustWidth(ifKeyword);
@ -541,9 +579,9 @@ namespace Parser.Internal
internal readonly SyntaxToken _forKeyword;
internal readonly AssignmentExpressionSyntaxNode _assignment;
internal readonly SyntaxList<SyntaxToken> _optionalCommas;
internal readonly SyntaxList _body;
internal readonly StatementSyntaxNode _body;
internal readonly SyntaxToken _endKeyword;
internal ForStatementSyntaxNode(SyntaxToken forKeyword, AssignmentExpressionSyntaxNode assignment, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxToken endKeyword): base(TokenKind.ForStatement)
internal ForStatementSyntaxNode(SyntaxToken forKeyword, AssignmentExpressionSyntaxNode assignment, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxToken endKeyword): base(TokenKind.ForStatement)
{
Slots = 5;
this.AdjustWidth(forKeyword);
@ -558,7 +596,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal ForStatementSyntaxNode(SyntaxToken forKeyword, AssignmentExpressionSyntaxNode assignment, SyntaxList<SyntaxToken> optionalCommas, SyntaxList body, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.ForStatement, diagnostics)
internal ForStatementSyntaxNode(SyntaxToken forKeyword, AssignmentExpressionSyntaxNode assignment, SyntaxList<SyntaxToken> optionalCommas, StatementSyntaxNode body, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.ForStatement, diagnostics)
{
Slots = 5;
this.AdjustWidth(forKeyword);
@ -688,10 +726,10 @@ namespace Parser.Internal
internal class TryCatchStatementSyntaxNode : StatementSyntaxNode
{
internal readonly SyntaxToken _tryKeyword;
internal readonly SyntaxList _tryBody;
internal readonly StatementSyntaxNode _tryBody;
internal readonly CatchClauseSyntaxNode? _catchClause;
internal readonly SyntaxToken _endKeyword;
internal TryCatchStatementSyntaxNode(SyntaxToken tryKeyword, SyntaxList tryBody, CatchClauseSyntaxNode? catchClause, SyntaxToken endKeyword): base(TokenKind.TryCatchStatement)
internal TryCatchStatementSyntaxNode(SyntaxToken tryKeyword, StatementSyntaxNode tryBody, CatchClauseSyntaxNode? catchClause, SyntaxToken endKeyword): base(TokenKind.TryCatchStatement)
{
Slots = 4;
this.AdjustWidth(tryKeyword);
@ -704,7 +742,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal TryCatchStatementSyntaxNode(SyntaxToken tryKeyword, SyntaxList tryBody, CatchClauseSyntaxNode? catchClause, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.TryCatchStatement, diagnostics)
internal TryCatchStatementSyntaxNode(SyntaxToken tryKeyword, StatementSyntaxNode tryBody, CatchClauseSyntaxNode? catchClause, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.TryCatchStatement, diagnostics)
{
Slots = 4;
this.AdjustWidth(tryKeyword);
@ -890,17 +928,17 @@ namespace Parser.Internal
}
}
internal class CompoundNameSyntaxNode : ExpressionSyntaxNode
internal class CompoundNameExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxList _nodes;
internal CompoundNameSyntaxNode(SyntaxList nodes): base(TokenKind.CompoundName)
internal CompoundNameExpressionSyntaxNode(SyntaxList nodes): base(TokenKind.CompoundNameExpression)
{
Slots = 1;
this.AdjustWidth(nodes);
_nodes = nodes;
}
internal CompoundNameSyntaxNode(SyntaxList nodes, TokenDiagnostic[] diagnostics): base(TokenKind.CompoundName, diagnostics)
internal CompoundNameExpressionSyntaxNode(SyntaxList nodes, TokenDiagnostic[] diagnostics): base(TokenKind.CompoundNameExpression, diagnostics)
{
Slots = 1;
this.AdjustWidth(nodes);
@ -909,12 +947,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.CompoundNameSyntaxNode(parent, this, position);
return new Parser.CompoundNameExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new CompoundNameSyntaxNode(_nodes, diagnostics);
return new CompoundNameExpressionSyntaxNode(_nodes, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -928,11 +966,11 @@ namespace Parser.Internal
}
}
internal class NamedFunctionHandleSyntaxNode : FunctionHandleSyntaxNode
internal class NamedFunctionHandleExpressionSyntaxNode : FunctionHandleExpressionSyntaxNode
{
internal readonly SyntaxToken _atSign;
internal readonly CompoundNameSyntaxNode _functionName;
internal NamedFunctionHandleSyntaxNode(SyntaxToken atSign, CompoundNameSyntaxNode functionName): base(TokenKind.NamedFunctionHandle)
internal readonly CompoundNameExpressionSyntaxNode _functionName;
internal NamedFunctionHandleExpressionSyntaxNode(SyntaxToken atSign, CompoundNameExpressionSyntaxNode functionName): base(TokenKind.NamedFunctionHandleExpression)
{
Slots = 2;
this.AdjustWidth(atSign);
@ -941,7 +979,7 @@ namespace Parser.Internal
_functionName = functionName;
}
internal NamedFunctionHandleSyntaxNode(SyntaxToken atSign, CompoundNameSyntaxNode functionName, TokenDiagnostic[] diagnostics): base(TokenKind.NamedFunctionHandle, diagnostics)
internal NamedFunctionHandleExpressionSyntaxNode(SyntaxToken atSign, CompoundNameExpressionSyntaxNode functionName, TokenDiagnostic[] diagnostics): base(TokenKind.NamedFunctionHandleExpression, diagnostics)
{
Slots = 2;
this.AdjustWidth(atSign);
@ -952,12 +990,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.NamedFunctionHandleSyntaxNode(parent, this, position);
return new Parser.NamedFunctionHandleExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new NamedFunctionHandleSyntaxNode(_atSign, _functionName, diagnostics);
return new NamedFunctionHandleExpressionSyntaxNode(_atSign, _functionName, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -971,12 +1009,12 @@ namespace Parser.Internal
}
}
internal class LambdaSyntaxNode : FunctionHandleSyntaxNode
internal class LambdaExpressionSyntaxNode : FunctionHandleExpressionSyntaxNode
{
internal readonly SyntaxToken _atSign;
internal readonly FunctionInputDescriptionSyntaxNode _input;
internal readonly ExpressionSyntaxNode _body;
internal LambdaSyntaxNode(SyntaxToken atSign, FunctionInputDescriptionSyntaxNode input, ExpressionSyntaxNode body): base(TokenKind.Lambda)
internal LambdaExpressionSyntaxNode(SyntaxToken atSign, FunctionInputDescriptionSyntaxNode input, ExpressionSyntaxNode body): base(TokenKind.LambdaExpression)
{
Slots = 3;
this.AdjustWidth(atSign);
@ -987,7 +1025,7 @@ namespace Parser.Internal
_body = body;
}
internal LambdaSyntaxNode(SyntaxToken atSign, FunctionInputDescriptionSyntaxNode input, ExpressionSyntaxNode body, TokenDiagnostic[] diagnostics): base(TokenKind.Lambda, diagnostics)
internal LambdaExpressionSyntaxNode(SyntaxToken atSign, FunctionInputDescriptionSyntaxNode input, ExpressionSyntaxNode body, TokenDiagnostic[] diagnostics): base(TokenKind.LambdaExpression, diagnostics)
{
Slots = 3;
this.AdjustWidth(atSign);
@ -1000,12 +1038,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.LambdaSyntaxNode(parent, this, position);
return new Parser.LambdaExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new LambdaSyntaxNode(_atSign, _input, _body, diagnostics);
return new LambdaExpressionSyntaxNode(_atSign, _input, _body, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1024,7 +1062,7 @@ namespace Parser.Internal
internal readonly ExpressionSyntaxNode _lhs;
internal readonly SyntaxToken _operation;
internal readonly ExpressionSyntaxNode _rhs;
internal BinaryOperationExpressionSyntaxNode(ExpressionSyntaxNode lhs, SyntaxToken operation, ExpressionSyntaxNode rhs): base(TokenKind.BinaryOperation)
internal BinaryOperationExpressionSyntaxNode(ExpressionSyntaxNode lhs, SyntaxToken operation, ExpressionSyntaxNode rhs): base(TokenKind.BinaryOperationExpression)
{
Slots = 3;
this.AdjustWidth(lhs);
@ -1035,7 +1073,7 @@ namespace Parser.Internal
_rhs = rhs;
}
internal BinaryOperationExpressionSyntaxNode(ExpressionSyntaxNode lhs, SyntaxToken operation, ExpressionSyntaxNode rhs, TokenDiagnostic[] diagnostics): base(TokenKind.BinaryOperation, diagnostics)
internal BinaryOperationExpressionSyntaxNode(ExpressionSyntaxNode lhs, SyntaxToken operation, ExpressionSyntaxNode rhs, TokenDiagnostic[] diagnostics): base(TokenKind.BinaryOperationExpression, diagnostics)
{
Slots = 3;
this.AdjustWidth(lhs);
@ -1067,17 +1105,17 @@ namespace Parser.Internal
}
}
internal class IdentifierNameSyntaxNode : ExpressionSyntaxNode
internal class IdentifierNameExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxToken _name;
internal IdentifierNameSyntaxNode(SyntaxToken name): base(TokenKind.IdentifierName)
internal IdentifierNameExpressionSyntaxNode(SyntaxToken name): base(TokenKind.IdentifierNameExpression)
{
Slots = 1;
this.AdjustWidth(name);
_name = name;
}
internal IdentifierNameSyntaxNode(SyntaxToken name, TokenDiagnostic[] diagnostics): base(TokenKind.IdentifierName, diagnostics)
internal IdentifierNameExpressionSyntaxNode(SyntaxToken name, TokenDiagnostic[] diagnostics): base(TokenKind.IdentifierNameExpression, diagnostics)
{
Slots = 1;
this.AdjustWidth(name);
@ -1086,12 +1124,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.IdentifierNameSyntaxNode(parent, this, position);
return new Parser.IdentifierNameExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new IdentifierNameSyntaxNode(_name, diagnostics);
return new IdentifierNameExpressionSyntaxNode(_name, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1105,17 +1143,17 @@ namespace Parser.Internal
}
}
internal class NumberLiteralSyntaxNode : ExpressionSyntaxNode
internal class NumberLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxToken _number;
internal NumberLiteralSyntaxNode(SyntaxToken number): base(TokenKind.NumberLiteralExpression)
internal NumberLiteralExpressionSyntaxNode(SyntaxToken number): base(TokenKind.NumberLiteralExpression)
{
Slots = 1;
this.AdjustWidth(number);
_number = number;
}
internal NumberLiteralSyntaxNode(SyntaxToken number, TokenDiagnostic[] diagnostics): base(TokenKind.NumberLiteralExpression, diagnostics)
internal NumberLiteralExpressionSyntaxNode(SyntaxToken number, TokenDiagnostic[] diagnostics): base(TokenKind.NumberLiteralExpression, diagnostics)
{
Slots = 1;
this.AdjustWidth(number);
@ -1124,12 +1162,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.NumberLiteralSyntaxNode(parent, this, position);
return new Parser.NumberLiteralExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new NumberLiteralSyntaxNode(_number, diagnostics);
return new NumberLiteralExpressionSyntaxNode(_number, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1143,17 +1181,17 @@ namespace Parser.Internal
}
}
internal class StringLiteralSyntaxNode : ExpressionSyntaxNode
internal class StringLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxToken _stringToken;
internal StringLiteralSyntaxNode(SyntaxToken stringToken): base(TokenKind.StringLiteralExpression)
internal StringLiteralExpressionSyntaxNode(SyntaxToken stringToken): base(TokenKind.StringLiteralExpression)
{
Slots = 1;
this.AdjustWidth(stringToken);
_stringToken = stringToken;
}
internal StringLiteralSyntaxNode(SyntaxToken stringToken, TokenDiagnostic[] diagnostics): base(TokenKind.StringLiteralExpression, diagnostics)
internal StringLiteralExpressionSyntaxNode(SyntaxToken stringToken, TokenDiagnostic[] diagnostics): base(TokenKind.StringLiteralExpression, diagnostics)
{
Slots = 1;
this.AdjustWidth(stringToken);
@ -1162,12 +1200,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.StringLiteralSyntaxNode(parent, this, position);
return new Parser.StringLiteralExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new StringLiteralSyntaxNode(_stringToken, diagnostics);
return new StringLiteralExpressionSyntaxNode(_stringToken, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1181,17 +1219,17 @@ namespace Parser.Internal
}
}
internal class DoubleQuotedStringLiteralSyntaxNode : ExpressionSyntaxNode
internal class DoubleQuotedStringLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxToken _stringToken;
internal DoubleQuotedStringLiteralSyntaxNode(SyntaxToken stringToken): base(TokenKind.DoubleQuotedStringLiteralExpression)
internal DoubleQuotedStringLiteralExpressionSyntaxNode(SyntaxToken stringToken): base(TokenKind.DoubleQuotedStringLiteralExpression)
{
Slots = 1;
this.AdjustWidth(stringToken);
_stringToken = stringToken;
}
internal DoubleQuotedStringLiteralSyntaxNode(SyntaxToken stringToken, TokenDiagnostic[] diagnostics): base(TokenKind.DoubleQuotedStringLiteralExpression, diagnostics)
internal DoubleQuotedStringLiteralExpressionSyntaxNode(SyntaxToken stringToken, TokenDiagnostic[] diagnostics): base(TokenKind.DoubleQuotedStringLiteralExpression, diagnostics)
{
Slots = 1;
this.AdjustWidth(stringToken);
@ -1200,12 +1238,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.DoubleQuotedStringLiteralSyntaxNode(parent, this, position);
return new Parser.DoubleQuotedStringLiteralExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new DoubleQuotedStringLiteralSyntaxNode(_stringToken, diagnostics);
return new DoubleQuotedStringLiteralExpressionSyntaxNode(_stringToken, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1219,17 +1257,17 @@ namespace Parser.Internal
}
}
internal class UnquotedStringLiteralSyntaxNode : ExpressionSyntaxNode
internal class UnquotedStringLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxToken _stringToken;
internal UnquotedStringLiteralSyntaxNode(SyntaxToken stringToken): base(TokenKind.UnquotedStringLiteralExpression)
internal UnquotedStringLiteralExpressionSyntaxNode(SyntaxToken stringToken): base(TokenKind.UnquotedStringLiteralExpression)
{
Slots = 1;
this.AdjustWidth(stringToken);
_stringToken = stringToken;
}
internal UnquotedStringLiteralSyntaxNode(SyntaxToken stringToken, TokenDiagnostic[] diagnostics): base(TokenKind.UnquotedStringLiteralExpression, diagnostics)
internal UnquotedStringLiteralExpressionSyntaxNode(SyntaxToken stringToken, TokenDiagnostic[] diagnostics): base(TokenKind.UnquotedStringLiteralExpression, diagnostics)
{
Slots = 1;
this.AdjustWidth(stringToken);
@ -1238,12 +1276,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.UnquotedStringLiteralSyntaxNode(parent, this, position);
return new Parser.UnquotedStringLiteralExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new UnquotedStringLiteralSyntaxNode(_stringToken, diagnostics);
return new UnquotedStringLiteralExpressionSyntaxNode(_stringToken, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1407,7 +1445,7 @@ namespace Parser.Internal
internal readonly SyntaxToken _openingBrace;
internal readonly SyntaxList _nodes;
internal readonly SyntaxToken _closingBrace;
internal CellArrayElementAccessExpressionSyntaxNode(ExpressionSyntaxNode expression, SyntaxToken openingBrace, SyntaxList nodes, SyntaxToken closingBrace): base(TokenKind.CellArrayElementAccess)
internal CellArrayElementAccessExpressionSyntaxNode(ExpressionSyntaxNode expression, SyntaxToken openingBrace, SyntaxList nodes, SyntaxToken closingBrace): base(TokenKind.CellArrayElementAccessExpression)
{
Slots = 4;
this.AdjustWidth(expression);
@ -1420,7 +1458,7 @@ namespace Parser.Internal
_closingBrace = closingBrace;
}
internal CellArrayElementAccessExpressionSyntaxNode(ExpressionSyntaxNode expression, SyntaxToken openingBrace, SyntaxList nodes, SyntaxToken closingBrace, TokenDiagnostic[] diagnostics): base(TokenKind.CellArrayElementAccess, diagnostics)
internal CellArrayElementAccessExpressionSyntaxNode(ExpressionSyntaxNode expression, SyntaxToken openingBrace, SyntaxList nodes, SyntaxToken closingBrace, TokenDiagnostic[] diagnostics): base(TokenKind.CellArrayElementAccessExpression, diagnostics)
{
Slots = 4;
this.AdjustWidth(expression);
@ -1460,7 +1498,7 @@ namespace Parser.Internal
internal readonly SyntaxToken _openingBracket;
internal readonly SyntaxList _nodes;
internal readonly SyntaxToken _closingBracket;
internal FunctionCallExpressionSyntaxNode(ExpressionSyntaxNode functionName, SyntaxToken openingBracket, SyntaxList nodes, SyntaxToken closingBracket): base(TokenKind.FunctionCall)
internal FunctionCallExpressionSyntaxNode(ExpressionSyntaxNode functionName, SyntaxToken openingBracket, SyntaxList nodes, SyntaxToken closingBracket): base(TokenKind.FunctionCallExpression)
{
Slots = 4;
this.AdjustWidth(functionName);
@ -1473,7 +1511,7 @@ namespace Parser.Internal
_closingBracket = closingBracket;
}
internal FunctionCallExpressionSyntaxNode(ExpressionSyntaxNode functionName, SyntaxToken openingBracket, SyntaxList nodes, SyntaxToken closingBracket, TokenDiagnostic[] diagnostics): base(TokenKind.FunctionCall, diagnostics)
internal FunctionCallExpressionSyntaxNode(ExpressionSyntaxNode functionName, SyntaxToken openingBracket, SyntaxList nodes, SyntaxToken closingBracket, TokenDiagnostic[] diagnostics): base(TokenKind.FunctionCallExpression, diagnostics)
{
Slots = 4;
this.AdjustWidth(functionName);
@ -1507,12 +1545,12 @@ namespace Parser.Internal
}
}
internal class MemberAccessSyntaxNode : ExpressionSyntaxNode
internal class MemberAccessExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxNode _leftOperand;
internal readonly SyntaxToken _dot;
internal readonly SyntaxNode _rightOperand;
internal MemberAccessSyntaxNode(SyntaxNode leftOperand, SyntaxToken dot, SyntaxNode rightOperand): base(TokenKind.MemberAccess)
internal MemberAccessExpressionSyntaxNode(SyntaxNode leftOperand, SyntaxToken dot, SyntaxNode rightOperand): base(TokenKind.MemberAccessExpression)
{
Slots = 3;
this.AdjustWidth(leftOperand);
@ -1523,7 +1561,7 @@ namespace Parser.Internal
_rightOperand = rightOperand;
}
internal MemberAccessSyntaxNode(SyntaxNode leftOperand, SyntaxToken dot, SyntaxNode rightOperand, TokenDiagnostic[] diagnostics): base(TokenKind.MemberAccess, diagnostics)
internal MemberAccessExpressionSyntaxNode(SyntaxNode leftOperand, SyntaxToken dot, SyntaxNode rightOperand, TokenDiagnostic[] diagnostics): base(TokenKind.MemberAccessExpression, diagnostics)
{
Slots = 3;
this.AdjustWidth(leftOperand);
@ -1536,12 +1574,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.MemberAccessSyntaxNode(parent, this, position);
return new Parser.MemberAccessExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new MemberAccessSyntaxNode(_leftOperand, _dot, _rightOperand, diagnostics);
return new MemberAccessExpressionSyntaxNode(_leftOperand, _dot, _rightOperand, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1555,11 +1593,11 @@ namespace Parser.Internal
}
}
internal class UnaryPostixOperationExpressionSyntaxNode : ExpressionSyntaxNode
internal class UnaryPostfixOperationExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly ExpressionSyntaxNode _operand;
internal readonly SyntaxToken _operation;
internal UnaryPostixOperationExpressionSyntaxNode(ExpressionSyntaxNode operand, SyntaxToken operation): base(TokenKind.UnaryPostfixOperationExpression)
internal UnaryPostfixOperationExpressionSyntaxNode(ExpressionSyntaxNode operand, SyntaxToken operation): base(TokenKind.UnaryPostfixOperationExpression)
{
Slots = 2;
this.AdjustWidth(operand);
@ -1568,7 +1606,7 @@ namespace Parser.Internal
_operation = operation;
}
internal UnaryPostixOperationExpressionSyntaxNode(ExpressionSyntaxNode operand, SyntaxToken operation, TokenDiagnostic[] diagnostics): base(TokenKind.UnaryPostfixOperationExpression, diagnostics)
internal UnaryPostfixOperationExpressionSyntaxNode(ExpressionSyntaxNode operand, SyntaxToken operation, TokenDiagnostic[] diagnostics): base(TokenKind.UnaryPostfixOperationExpression, diagnostics)
{
Slots = 2;
this.AdjustWidth(operand);
@ -1579,12 +1617,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.UnaryPostixOperationExpressionSyntaxNode(parent, this, position);
return new Parser.UnaryPostfixOperationExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new UnaryPostixOperationExpressionSyntaxNode(_operand, _operation, diagnostics);
return new UnaryPostfixOperationExpressionSyntaxNode(_operand, _operation, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1598,12 +1636,12 @@ namespace Parser.Internal
}
}
internal class IndirectMemberAccessSyntaxNode : ExpressionSyntaxNode
internal class IndirectMemberAccessExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly SyntaxToken _openingBracket;
internal readonly ExpressionSyntaxNode _expression;
internal readonly SyntaxToken _closingBracket;
internal IndirectMemberAccessSyntaxNode(SyntaxToken openingBracket, ExpressionSyntaxNode expression, SyntaxToken closingBracket): base(TokenKind.IndirectMemberAccess)
internal IndirectMemberAccessExpressionSyntaxNode(SyntaxToken openingBracket, ExpressionSyntaxNode expression, SyntaxToken closingBracket): base(TokenKind.IndirectMemberAccessExpression)
{
Slots = 3;
this.AdjustWidth(openingBracket);
@ -1614,7 +1652,7 @@ namespace Parser.Internal
_closingBracket = closingBracket;
}
internal IndirectMemberAccessSyntaxNode(SyntaxToken openingBracket, ExpressionSyntaxNode expression, SyntaxToken closingBracket, TokenDiagnostic[] diagnostics): base(TokenKind.IndirectMemberAccess, diagnostics)
internal IndirectMemberAccessExpressionSyntaxNode(SyntaxToken openingBracket, ExpressionSyntaxNode expression, SyntaxToken closingBracket, TokenDiagnostic[] diagnostics): base(TokenKind.IndirectMemberAccessExpression, diagnostics)
{
Slots = 3;
this.AdjustWidth(openingBracket);
@ -1627,12 +1665,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.IndirectMemberAccessSyntaxNode(parent, this, position);
return new Parser.IndirectMemberAccessExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new IndirectMemberAccessSyntaxNode(_openingBracket, _expression, _closingBracket, diagnostics);
return new IndirectMemberAccessExpressionSyntaxNode(_openingBracket, _expression, _closingBracket, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1648,9 +1686,9 @@ namespace Parser.Internal
internal class CommandExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly IdentifierNameSyntaxNode _commandName;
internal readonly SyntaxList<UnquotedStringLiteralSyntaxNode> _arguments;
internal CommandExpressionSyntaxNode(IdentifierNameSyntaxNode commandName, SyntaxList<UnquotedStringLiteralSyntaxNode> arguments): base(TokenKind.Command)
internal readonly SyntaxToken _commandName;
internal readonly SyntaxList<UnquotedStringLiteralExpressionSyntaxNode> _arguments;
internal CommandExpressionSyntaxNode(SyntaxToken commandName, SyntaxList<UnquotedStringLiteralExpressionSyntaxNode> arguments): base(TokenKind.CommandExpression)
{
Slots = 2;
this.AdjustWidth(commandName);
@ -1659,7 +1697,7 @@ namespace Parser.Internal
_arguments = arguments;
}
internal CommandExpressionSyntaxNode(IdentifierNameSyntaxNode commandName, SyntaxList<UnquotedStringLiteralSyntaxNode> arguments, TokenDiagnostic[] diagnostics): base(TokenKind.Command, diagnostics)
internal CommandExpressionSyntaxNode(SyntaxToken commandName, SyntaxList<UnquotedStringLiteralExpressionSyntaxNode> arguments, TokenDiagnostic[] diagnostics): base(TokenKind.CommandExpression, diagnostics)
{
Slots = 2;
this.AdjustWidth(commandName);
@ -1689,12 +1727,12 @@ namespace Parser.Internal
}
}
internal class BaseClassInvokationSyntaxNode : ExpressionSyntaxNode
internal class ClassInvokationExpressionSyntaxNode : ExpressionSyntaxNode
{
internal readonly ExpressionSyntaxNode _methodName;
internal readonly SyntaxToken _atSign;
internal readonly ExpressionSyntaxNode _baseClassNameAndArguments;
internal BaseClassInvokationSyntaxNode(ExpressionSyntaxNode methodName, SyntaxToken atSign, ExpressionSyntaxNode baseClassNameAndArguments): base(TokenKind.ClassInvokation)
internal ClassInvokationExpressionSyntaxNode(ExpressionSyntaxNode methodName, SyntaxToken atSign, ExpressionSyntaxNode baseClassNameAndArguments): base(TokenKind.ClassInvokationExpression)
{
Slots = 3;
this.AdjustWidth(methodName);
@ -1705,7 +1743,7 @@ namespace Parser.Internal
_baseClassNameAndArguments = baseClassNameAndArguments;
}
internal BaseClassInvokationSyntaxNode(ExpressionSyntaxNode methodName, SyntaxToken atSign, ExpressionSyntaxNode baseClassNameAndArguments, TokenDiagnostic[] diagnostics): base(TokenKind.ClassInvokation, diagnostics)
internal ClassInvokationExpressionSyntaxNode(ExpressionSyntaxNode methodName, SyntaxToken atSign, ExpressionSyntaxNode baseClassNameAndArguments, TokenDiagnostic[] diagnostics): base(TokenKind.ClassInvokationExpression, diagnostics)
{
Slots = 3;
this.AdjustWidth(methodName);
@ -1718,12 +1756,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.BaseClassInvokationSyntaxNode(parent, this, position);
return new Parser.ClassInvokationExpressionSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new BaseClassInvokationSyntaxNode(_methodName, _atSign, _baseClassNameAndArguments, diagnostics);
return new ClassInvokationExpressionSyntaxNode(_methodName, _atSign, _baseClassNameAndArguments, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1782,9 +1820,9 @@ namespace Parser.Internal
internal class AttributeSyntaxNode : SyntaxNode
{
internal readonly IdentifierNameSyntaxNode _name;
internal readonly SyntaxToken _name;
internal readonly AttributeAssignmentSyntaxNode? _assignment;
internal AttributeSyntaxNode(IdentifierNameSyntaxNode name, AttributeAssignmentSyntaxNode? assignment): base(TokenKind.Attribute)
internal AttributeSyntaxNode(SyntaxToken name, AttributeAssignmentSyntaxNode? assignment): base(TokenKind.Attribute)
{
Slots = 2;
this.AdjustWidth(name);
@ -1793,7 +1831,7 @@ namespace Parser.Internal
_assignment = assignment;
}
internal AttributeSyntaxNode(IdentifierNameSyntaxNode name, AttributeAssignmentSyntaxNode? assignment, TokenDiagnostic[] diagnostics): base(TokenKind.Attribute, diagnostics)
internal AttributeSyntaxNode(SyntaxToken name, AttributeAssignmentSyntaxNode? assignment, TokenDiagnostic[] diagnostics): base(TokenKind.Attribute, diagnostics)
{
Slots = 2;
this.AdjustWidth(name);
@ -1871,16 +1909,16 @@ namespace Parser.Internal
}
}
internal class MethodDefinitionSyntaxNode : MethodDeclarationSyntaxNode
internal class ConcreteMethodDeclarationSyntaxNode : MethodDeclarationSyntaxNode
{
internal readonly SyntaxToken _functionKeyword;
internal readonly FunctionOutputDescriptionSyntaxNode? _outputDescription;
internal readonly CompoundNameSyntaxNode _name;
internal readonly CompoundNameExpressionSyntaxNode _name;
internal readonly FunctionInputDescriptionSyntaxNode? _inputDescription;
internal readonly SyntaxList<SyntaxToken> _commas;
internal readonly SyntaxList _body;
internal readonly StatementSyntaxNode _body;
internal readonly EndKeywordSyntaxNode? _endKeyword;
internal MethodDefinitionSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, SyntaxList body, EndKeywordSyntaxNode? endKeyword): base(TokenKind.MethodDefinition)
internal ConcreteMethodDeclarationSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameExpressionSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, StatementSyntaxNode body, EndKeywordSyntaxNode? endKeyword): base(TokenKind.ConcreteMethodDeclaration)
{
Slots = 7;
this.AdjustWidth(functionKeyword);
@ -1899,7 +1937,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal MethodDefinitionSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, SyntaxList body, EndKeywordSyntaxNode? endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.MethodDefinition, diagnostics)
internal ConcreteMethodDeclarationSyntaxNode(SyntaxToken functionKeyword, FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameExpressionSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, SyntaxList<SyntaxToken> commas, StatementSyntaxNode body, EndKeywordSyntaxNode? endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.ConcreteMethodDeclaration, diagnostics)
{
Slots = 7;
this.AdjustWidth(functionKeyword);
@ -1920,12 +1958,12 @@ namespace Parser.Internal
internal override Parser.SyntaxNode CreateRed(Parser.SyntaxNode parent, int position)
{
return new Parser.MethodDefinitionSyntaxNode(parent, this, position);
return new Parser.ConcreteMethodDeclarationSyntaxNode(parent, this, position);
}
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new MethodDefinitionSyntaxNode(_functionKeyword, _outputDescription, _name, _inputDescription, _commas, _body, _endKeyword, diagnostics);
return new ConcreteMethodDeclarationSyntaxNode(_functionKeyword, _outputDescription, _name, _inputDescription, _commas, _body, _endKeyword, diagnostics);
}
public override GreenNode? GetSlot(int i)
@ -1942,9 +1980,9 @@ namespace Parser.Internal
internal class AbstractMethodDeclarationSyntaxNode : MethodDeclarationSyntaxNode
{
internal readonly FunctionOutputDescriptionSyntaxNode? _outputDescription;
internal readonly CompoundNameSyntaxNode _name;
internal readonly CompoundNameExpressionSyntaxNode _name;
internal readonly FunctionInputDescriptionSyntaxNode? _inputDescription;
internal AbstractMethodDeclarationSyntaxNode(FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription): base(TokenKind.AbstractMethodDeclaration)
internal AbstractMethodDeclarationSyntaxNode(FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameExpressionSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription): base(TokenKind.AbstractMethodDeclaration)
{
Slots = 3;
this.AdjustWidth(outputDescription);
@ -1955,7 +1993,7 @@ namespace Parser.Internal
_inputDescription = inputDescription;
}
internal AbstractMethodDeclarationSyntaxNode(FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, TokenDiagnostic[] diagnostics): base(TokenKind.AbstractMethodDeclaration, diagnostics)
internal AbstractMethodDeclarationSyntaxNode(FunctionOutputDescriptionSyntaxNode? outputDescription, CompoundNameExpressionSyntaxNode name, FunctionInputDescriptionSyntaxNode? inputDescription, TokenDiagnostic[] diagnostics): base(TokenKind.AbstractMethodDeclaration, diagnostics)
{
Slots = 3;
this.AdjustWidth(outputDescription);
@ -2140,11 +2178,11 @@ namespace Parser.Internal
{
internal readonly SyntaxToken _classdefKeyword;
internal readonly AttributeListSyntaxNode? _attributes;
internal readonly IdentifierNameSyntaxNode _className;
internal readonly SyntaxToken _className;
internal readonly BaseClassListSyntaxNode? _baseClassList;
internal readonly SyntaxList _nodes;
internal readonly SyntaxToken _endKeyword;
internal ClassDeclarationSyntaxNode(SyntaxToken classdefKeyword, AttributeListSyntaxNode? attributes, IdentifierNameSyntaxNode className, BaseClassListSyntaxNode? baseClassList, SyntaxList nodes, SyntaxToken endKeyword): base(TokenKind.ClassDeclaration)
internal ClassDeclarationSyntaxNode(SyntaxToken classdefKeyword, AttributeListSyntaxNode? attributes, SyntaxToken className, BaseClassListSyntaxNode? baseClassList, SyntaxList nodes, SyntaxToken endKeyword): base(TokenKind.ClassDeclaration)
{
Slots = 6;
this.AdjustWidth(classdefKeyword);
@ -2161,7 +2199,7 @@ namespace Parser.Internal
_endKeyword = endKeyword;
}
internal ClassDeclarationSyntaxNode(SyntaxToken classdefKeyword, AttributeListSyntaxNode? attributes, IdentifierNameSyntaxNode className, BaseClassListSyntaxNode? baseClassList, SyntaxList nodes, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.ClassDeclaration, diagnostics)
internal ClassDeclarationSyntaxNode(SyntaxToken classdefKeyword, AttributeListSyntaxNode? attributes, SyntaxToken className, BaseClassListSyntaxNode? baseClassList, SyntaxList nodes, SyntaxToken endKeyword, TokenDiagnostic[] diagnostics): base(TokenKind.ClassDeclaration, diagnostics)
{
Slots = 6;
this.AdjustWidth(classdefKeyword);
@ -2249,10 +2287,10 @@ namespace Parser.Internal
internal class EnumerationItemSyntaxNode : SyntaxNode
{
internal readonly IdentifierNameSyntaxNode _name;
internal readonly SyntaxToken _name;
internal readonly EnumerationItemValueSyntaxNode? _values;
internal readonly SyntaxList<SyntaxToken> _commas;
internal EnumerationItemSyntaxNode(IdentifierNameSyntaxNode name, EnumerationItemValueSyntaxNode? values, SyntaxList<SyntaxToken> commas): base(TokenKind.EnumerationItem)
internal EnumerationItemSyntaxNode(SyntaxToken name, EnumerationItemValueSyntaxNode? values, SyntaxList<SyntaxToken> commas): base(TokenKind.EnumerationItem)
{
Slots = 3;
this.AdjustWidth(name);
@ -2263,7 +2301,7 @@ namespace Parser.Internal
_commas = commas;
}
internal EnumerationItemSyntaxNode(IdentifierNameSyntaxNode name, EnumerationItemValueSyntaxNode? values, SyntaxList<SyntaxToken> commas, TokenDiagnostic[] diagnostics): base(TokenKind.EnumerationItem, diagnostics)
internal EnumerationItemSyntaxNode(SyntaxToken name, EnumerationItemValueSyntaxNode? values, SyntaxList<SyntaxToken> commas, TokenDiagnostic[] diagnostics): base(TokenKind.EnumerationItem, diagnostics)
{
Slots = 3;
this.AdjustWidth(name);

View File

@ -79,13 +79,13 @@ namespace Parser.Internal
}
}
internal abstract class FunctionHandleSyntaxNode : ExpressionSyntaxNode
internal abstract class FunctionHandleExpressionSyntaxNode : ExpressionSyntaxNode
{
protected FunctionHandleSyntaxNode(TokenKind kind) : base(kind)
protected FunctionHandleExpressionSyntaxNode(TokenKind kind) : base(kind)
{
}
protected FunctionHandleSyntaxNode(TokenKind kind, TokenDiagnostic[] diagnostics) : base(kind, diagnostics)
protected FunctionHandleExpressionSyntaxNode(TokenKind kind, TokenDiagnostic[] diagnostics) : base(kind, diagnostics)
{
}
}

View File

@ -116,6 +116,7 @@ namespace Parser.Internal
_fullWidth = text?.Length ?? 0;
}
public override void WriteTokenTo(TextWriter writer, bool leading, bool trailing)
{
writer.Write(_text);
@ -126,7 +127,9 @@ namespace Parser.Internal
return new SyntaxTokenWithValue<T>(Kind, _text, _value, diagnostics);
}
public T Value => _value;
public T TypedValue => _value;
public override object? Value => TypedValue;
}
internal class SyntaxTokenWithValueAndTrivia<T> : SyntaxTokenWithValue<T>
@ -181,7 +184,7 @@ namespace Parser.Internal
public override GreenNode SetDiagnostics(TokenDiagnostic[] diagnostics)
{
return new SyntaxTokenWithValueAndTrivia<T>(Kind, _text, Value, LeadingTrivia, TrailingTrivia, diagnostics);
return new SyntaxTokenWithValueAndTrivia<T>(Kind, _text, TypedValue, LeadingTrivia, TrailingTrivia, diagnostics);
}
}
@ -311,6 +314,10 @@ namespace Parser.Internal
internal static SyntaxToken NoneToken => new MissingTokenWithTrivia(TokenKind.None, s_EmptySyntaxTriviaList, s_EmptySyntaxTriviaList);
public virtual object? Value => null;
public override object? GetValue() => Value;
public virtual int Width => Text.Length;
public override IReadOnlyList<SyntaxTrivia> LeadingTriviaCore => s_EmptySyntaxTriviaList;

116
Parser/Lowering/Lowerer.cs Normal file
View File

@ -0,0 +1,116 @@
using Parser.Binding;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using static Parser.Binding.BoundNodeFactory;
namespace Parser.Lowering
{
internal class Lowerer : BoundTreeRewriter
{
private int _labelNumber = 0;
private Lowerer()
{
}
private BoundLabel GenerateLabel()
{
var name = $"Label{++_labelNumber}";
return new BoundLabel(name);
}
public override BoundStatement RewriteIfStatement(BoundIfStatement node)
{
// if cond
// body
// elseif cond1
// body1
// elseif cond2
// body2
// else
// body3
//
// gotoFalse cond Label1
// body
// goto LabelEnd
// Label1:
// gotoFalse cond1 Label2
// body1
// goto LabelEnd
// Label2:
// gotoFalse cond2 Label3
// body2
// goto LabelEnd
// Label3:
// body3
// LabelEnd:
var builder = ImmutableArray.CreateBuilder<BoundStatement>();
var numberOfLabelsNeeded = 1 + node.ElseifClauses.Length + (node.ElseClause is null ? 0 : 1);
var labels = new BoundLabel[numberOfLabelsNeeded];
for (var i = 0; i < numberOfLabelsNeeded; i++)
{
labels[i] = GenerateLabel();
}
builder.Add(GotoIfFalse(node.Syntax, node.Condition, labels[0]));
builder.Add(node.Body);
if (numberOfLabelsNeeded >= 2)
{
var counter = 0;
foreach (var elseifClause in node.ElseifClauses)
{
builder.Add(Goto(node.Syntax, labels[^1]));
builder.Add(LabelStatement(node.Syntax, labels[counter]));
counter++;
builder.Add(GotoIfFalse(node.Syntax, elseifClause.Condition, labels[counter]));
builder.Add(elseifClause.Body);
}
if (node.ElseClause is { } elseClause)
{
builder.Add(Goto(node.Syntax, labels[^1]));
builder.Add(LabelStatement(node.Syntax, labels[counter]));
builder.Add(elseClause);
}
}
builder.Add(LabelStatement(node.Syntax, labels[^1]));
return RewriteBlockStatement(Block(node.Syntax, builder.ToArray()));
}
public static BoundBlockStatement Lower(BoundStatement statement)
{
var lowerer = new Lowerer();
var result = lowerer.RewriteStatement(statement);
var flatResult = lowerer.Flatten(result);
return flatResult;
}
private BoundBlockStatement Flatten(BoundStatement statement)
{
var builder = ImmutableArray.CreateBuilder<BoundStatement>();
var stack = new Stack<BoundStatement>();
stack.Push(statement);
while (stack.Count() > 0)
{
var current = stack.Pop();
if (current is BoundBlockStatement block)
{
foreach (var s in block.Statements.Reverse())
{
stack.Push(s);
}
}
else
{
builder.Add(current);
}
}
return Block(statement.Syntax, builder.ToImmutable());
}
}
}

View File

@ -0,0 +1,105 @@
using Parser.Objects;
namespace Parser.MFunctions
{
public static class MOperations
{
public static MObject? Plus(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateDoubleNumber(lValue + rValue);
}
return null;
}
public static MObject? Minus(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateDoubleNumber(lValue - rValue);
}
return null;
}
public static MObject? Star(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateDoubleNumber(lValue * rValue);
}
return null;
}
public static MObject? Slash(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateDoubleNumber(lValue / rValue);
}
return null;
}
public static MObject? Greater(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateLogical(lValue > rValue);
}
return null;
}
public static MObject? GreaterOrEquals(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateLogical(lValue >= rValue);
}
return null;
}
public static MObject? Less(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateLogical(lValue < rValue);
}
return null;
}
public static MObject? LessOrEquals(MObject left, MObject right)
{
if (left is MDoubleNumber { Value: var lValue }
&& right is MDoubleNumber { Value: var rValue })
{
return MObject.CreateLogical(lValue <= rValue);
}
return null;
}
public static MObject? Minus(MObject operand)
{
if (operand is MDoubleNumber { Value: var value })
{
return MObject.CreateDoubleNumber(-value);
}
return null;
}
}
}

View File

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using Parser.Internal;
using Parser.Internal;
using System.Linq;
namespace Parser
@ -27,18 +25,4 @@ namespace Parser
return new SyntaxTree(root, totalDiagnostics);
}
}
public class SyntaxTree
{
public SyntaxTree(RootSyntaxNode nullRoot, DiagnosticsBag diagnostics)
{
NullRoot = nullRoot ?? throw new ArgumentNullException(nameof(nullRoot));
Diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics));
}
public RootSyntaxNode NullRoot { get; }
public FileSyntaxNode Root => NullRoot.File;
public DiagnosticsBag Diagnostics { get; }
}
}

View File

@ -0,0 +1,22 @@
namespace Parser.Objects
{
public class MCharArray : MObject
{
private MCharArray(char[] chars)
{
Chars = chars;
}
public char[] Chars { get; }
public static MCharArray Create(char[] chars)
{
return new MCharArray(chars);
}
public override string ToString()
{
return new string(Chars);
}
}
}

View File

@ -0,0 +1,24 @@
using System.Globalization;
namespace Parser.Objects
{
public class MDoubleNumber : MObject
{
private MDoubleNumber(double value)
{
Value = value;
}
public double Value { get; }
public static MDoubleNumber Create(double value)
{
return new MDoubleNumber(value);
}
public override string ToString()
{
return Value.ToString(CultureInfo.InvariantCulture);
}
}
}

View File

@ -0,0 +1,24 @@
using System.Globalization;
namespace Parser.Objects
{
public class MLogical : MObject
{
public MLogical(bool value)
{
Value = value;
}
public bool Value { get; }
public static MLogical Create(bool value)
{
return new MLogical(value);
}
public override string ToString()
{
return Value.ToString(CultureInfo.InvariantCulture);
}
}
}

20
Parser/Objects/MObject.cs Normal file
View File

@ -0,0 +1,20 @@
namespace Parser.Objects
{
public abstract class MObject
{
public static MDoubleNumber CreateDoubleNumber(double value)
{
return MDoubleNumber.Create(value);
}
public static MCharArray CreateCharArray(char[] chars)
{
return MCharArray.Create(chars);
}
public static MLogical CreateLogical(bool value)
{
return MLogical.Create(value);
}
}
}

View File

@ -3,6 +3,7 @@
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />

View File

@ -1,16 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Syntax xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Class Name="FileSyntaxNode" BaseClass="SyntaxNode" Kind="File">
<Field Type="SyntaxList" Name="statementList" />
<Field Type="BlockStatementSyntaxNode" Name="body" />
<Field Type="SyntaxToken" Name="endOfFile" />
</Class>
<Class Name="BlockStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="BlockStatement">
<Field Type="SyntaxList" Name="statements" />
</Class>
<Class Name="FunctionDeclarationSyntaxNode" BaseClass="StatementSyntaxNode" Kind="FunctionDeclaration">
<Field Type="SyntaxToken" Name="functionKeyword" />
<Field Type="FunctionOutputDescriptionSyntaxNode" Name="outputDescription" Nullable="true" />
<Field Type="SyntaxToken" Name="name" />
<Field Type="FunctionInputDescriptionSyntaxNode" Name="inputDescription" Nullable="true"/>
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="commas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
<Field Type="EndKeywordSyntaxNode" Name="endKeyword" Nullable="true"/>
</Class>
<Class Name="FunctionOutputDescriptionSyntaxNode" BaseClass="SyntaxNode" Kind="FunctionOutputDescription">
@ -33,30 +36,30 @@
<Field Type="SyntaxToken" Name="caseKeyword" />
<Field Type="ExpressionSyntaxNode" Name="caseIdentifier" />
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="optionalCommas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
</Class>
<Class Name="WhileStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="WhileStatement">
<Field Type="SyntaxToken" Name="whileKeyword" />
<Field Type="ExpressionSyntaxNode" Name="condition" />
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="optionalCommas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
<Field Type="SyntaxToken" Name="endKeyword" />
</Class>
<Class Name="ElseifClause" BaseClass="SyntaxNode" Kind="ElseifClause">
<Field Type="SyntaxToken" Name="elseifKeyword" />
<Field Type="ExpressionSyntaxNode" Name="condition" />
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="optionalCommas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
</Class>
<Class Name="ElseClause" BaseClass="SyntaxNode" Kind="ElseClause">
<Field Type="SyntaxToken" Name="elseKeyword" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
</Class>
<Class Name="IfStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="IfStatement">
<Field Type="SyntaxToken" Name="ifKeyword" />
<Field Type="ExpressionSyntaxNode" Name="condition" />
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="optionalCommas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
<Field Type="SyntaxList&lt;ElseifClause&gt;" Name="elseifClauses" />
<Field Type="ElseClause" Name="elseClause" Nullable="true" />
<Field Type="SyntaxToken" Name="endKeyword" />
@ -65,7 +68,7 @@
<Field Type="SyntaxToken" Name="forKeyword" />
<Field Type="AssignmentExpressionSyntaxNode" Name="assignment" />
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="optionalCommas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
<Field Type="SyntaxToken" Name="endKeyword" />
</Class>
<Class Name="AssignmentExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="AssignmentExpression">
@ -79,7 +82,7 @@
</Class>
<Class Name="TryCatchStatementSyntaxNode" BaseClass="StatementSyntaxNode" Kind="TryCatchStatement">
<Field Type="SyntaxToken" Name="tryKeyword" />
<Field Type="SyntaxList" Name="tryBody" />
<Field Type="StatementSyntaxNode" Name="tryBody" />
<Field Type="CatchClauseSyntaxNode" Name="catchClause" Nullable="true" />
<Field Type="SyntaxToken" Name="endKeyword" />
</Class>
@ -95,36 +98,36 @@
<Field Type="SyntaxToken" Name="operation" />
<Field Type="ExpressionSyntaxNode" Name="operand" />
</Class>
<Class Name="CompoundNameSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="CompoundName">
<Class Name="CompoundNameExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="CompoundNameExpression">
<Field Type="SyntaxList" Name="nodes" />
</Class>
<Class Name="NamedFunctionHandleSyntaxNode" BaseClass="FunctionHandleSyntaxNode" Kind="NamedFunctionHandle">
<Class Name="NamedFunctionHandleExpressionSyntaxNode" BaseClass="FunctionHandleExpressionSyntaxNode" Kind="NamedFunctionHandleExpression">
<Field Type="SyntaxToken" Name="atSign" />
<Field Type="CompoundNameSyntaxNode" Name="functionName" />
<Field Type="CompoundNameExpressionSyntaxNode" Name="functionName" />
</Class>
<Class Name="LambdaSyntaxNode" BaseClass="FunctionHandleSyntaxNode" Kind="Lambda">
<Class Name="LambdaExpressionSyntaxNode" BaseClass="FunctionHandleExpressionSyntaxNode" Kind="LambdaExpression">
<Field Type="SyntaxToken" Name="atSign" />
<Field Type="FunctionInputDescriptionSyntaxNode" Name="input" />
<Field Type="ExpressionSyntaxNode" Name="body" />
</Class>
<Class Name="BinaryOperationExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="BinaryOperation">
<Class Name="BinaryOperationExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="BinaryOperationExpression">
<Field Type="ExpressionSyntaxNode" Name="lhs" />
<Field Type="SyntaxToken" Name="operation" />
<Field Type="ExpressionSyntaxNode" Name="rhs" />
</Class>
<Class Name="IdentifierNameSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="IdentifierName">
<Class Name="IdentifierNameExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="IdentifierNameExpression">
<Field Type="SyntaxToken" Name="name" />
</Class>
<Class Name="NumberLiteralSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="NumberLiteralExpression">
<Class Name="NumberLiteralExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="NumberLiteralExpression">
<Field Type="SyntaxToken" Name="number" />
</Class>
<Class Name="StringLiteralSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="StringLiteralExpression">
<Class Name="StringLiteralExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="StringLiteralExpression">
<Field Type="SyntaxToken" Name="stringToken" />
</Class>
<Class Name="DoubleQuotedStringLiteralSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="DoubleQuotedStringLiteralExpression">
<Class Name="DoubleQuotedStringLiteralExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="DoubleQuotedStringLiteralExpression">
<Field Type="SyntaxToken" Name="stringToken" />
</Class>
<Class Name="UnquotedStringLiteralSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="UnquotedStringLiteralExpression">
<Class Name="UnquotedStringLiteralExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="UnquotedStringLiteralExpression">
<Field Type="SyntaxToken" Name="stringToken" />
</Class>
<Class Name="ArrayLiteralExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="ArrayLiteralExpression">
@ -142,37 +145,37 @@
<Field Type="ExpressionSyntaxNode" Name="expression" />
<Field Type="SyntaxToken" Name="closingBracket" />
</Class>
<Class Name="CellArrayElementAccessExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="CellArrayElementAccess">
<Class Name="CellArrayElementAccessExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="CellArrayElementAccessExpression">
<Field Type="ExpressionSyntaxNode" Name="expression" />
<Field Type="SyntaxToken" Name="openingBrace" />
<Field Type="SyntaxList" Name="nodes" />
<Field Type="SyntaxToken" Name="closingBrace" />
</Class>
<Class Name="FunctionCallExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="FunctionCall">
<Class Name="FunctionCallExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="FunctionCallExpression">
<Field Type="ExpressionSyntaxNode" Name="functionName" />
<Field Type="SyntaxToken" Name="openingBracket" />
<Field Type="SyntaxList" Name="nodes" />
<Field Type="SyntaxToken" Name="closingBracket" />
</Class>
<Class Name="MemberAccessSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="MemberAccess">
<Class Name="MemberAccessExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="MemberAccessExpression">
<Field Type="SyntaxNode" Name="leftOperand" />
<Field Type="SyntaxToken" Name="dot" />
<Field Type="SyntaxNode" Name="rightOperand" />
</Class>
<Class Name="UnaryPostixOperationExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="UnaryPostfixOperationExpression">
<Class Name="UnaryPostfixOperationExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="UnaryPostfixOperationExpression">
<Field Type="ExpressionSyntaxNode" Name="operand" />
<Field Type="SyntaxToken" Name="operation" />
</Class>
<Class Name="IndirectMemberAccessSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="IndirectMemberAccess">
<Class Name="IndirectMemberAccessExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="IndirectMemberAccessExpression">
<Field Type="SyntaxToken" Name="openingBracket" />
<Field Type="ExpressionSyntaxNode" Name="expression" />
<Field Type="SyntaxToken" Name="closingBracket" />
</Class>
<Class Name="CommandExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="Command">
<Field Type="IdentifierNameSyntaxNode" Name="commandName" />
<Field Type="SyntaxList&lt;UnquotedStringLiteralSyntaxNode&gt;" Name="arguments" />
<Class Name="CommandExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="CommandExpression">
<Field Type="SyntaxToken" Name="commandName" />
<Field Type="SyntaxList&lt;UnquotedStringLiteralExpressionSyntaxNode&gt;" Name="arguments" />
</Class>
<Class Name="BaseClassInvokationSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="ClassInvokation">
<Class Name="ClassInvokationExpressionSyntaxNode" BaseClass="ExpressionSyntaxNode" Kind="ClassInvokationExpression">
<Field Type="ExpressionSyntaxNode" Name="methodName" />
<Field Type="SyntaxToken" Name="atSign" />
<Field Type="ExpressionSyntaxNode" Name="baseClassNameAndArguments" />
@ -182,7 +185,7 @@
<Field Type="ExpressionSyntaxNode" Name="value" />
</Class>
<Class Name="AttributeSyntaxNode" BaseClass="SyntaxNode" Kind="Attribute">
<Field Type="IdentifierNameSyntaxNode" Name="name" />
<Field Type="SyntaxToken" Name="name" />
<Field Type="AttributeAssignmentSyntaxNode" Name="assignment" Nullable="true" />
</Class>
<Class Name="AttributeListSyntaxNode" BaseClass="SyntaxNode" Kind="AttributeList">
@ -190,18 +193,18 @@
<Field Type="SyntaxList" Name="nodes" />
<Field Type="SyntaxToken" Name="closingBracket" />
</Class>
<Class Name="MethodDefinitionSyntaxNode" BaseClass="MethodDeclarationSyntaxNode" Kind="MethodDefinition">
<Class Name="ConcreteMethodDeclarationSyntaxNode" BaseClass="MethodDeclarationSyntaxNode" Kind="ConcreteMethodDeclaration">
<Field Type="SyntaxToken" Name="functionKeyword" />
<Field Type="FunctionOutputDescriptionSyntaxNode" Name="outputDescription" Nullable="true" />
<Field Type="CompoundNameSyntaxNode" Name="name" />
<Field Type="CompoundNameExpressionSyntaxNode" Name="name" />
<Field Type="FunctionInputDescriptionSyntaxNode" Name="inputDescription" Nullable="true"/>
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="commas" />
<Field Type="SyntaxList" Name="body" />
<Field Type="StatementSyntaxNode" Name="body" />
<Field Type="EndKeywordSyntaxNode" Name="endKeyword" Nullable="true" />
</Class>
<Class Name="AbstractMethodDeclarationSyntaxNode" BaseClass="MethodDeclarationSyntaxNode" Kind="AbstractMethodDeclaration">
<Field Type="FunctionOutputDescriptionSyntaxNode" Name="outputDescription" Nullable="true" />
<Field Type="CompoundNameSyntaxNode" Name="name" />
<Field Type="CompoundNameExpressionSyntaxNode" Name="name" />
<Field Type="FunctionInputDescriptionSyntaxNode" Name="inputDescription" Nullable="true"/>
</Class>
<Class Name="MethodsListSyntaxNode" BaseClass="SyntaxNode" Kind="MethodsList">
@ -223,7 +226,7 @@
<Class Name="ClassDeclarationSyntaxNode" BaseClass="StatementSyntaxNode" Kind="ClassDeclaration">
<Field Type="SyntaxToken" Name="classdefKeyword" />
<Field Type="AttributeListSyntaxNode" Name="attributes" Nullable="true" />
<Field Type="IdentifierNameSyntaxNode" Name="className" />
<Field Type="SyntaxToken" Name="className" />
<Field Type="BaseClassListSyntaxNode" Name="baseClassList" Nullable="true" />
<Field Type="SyntaxList" Name="nodes" />
<Field Type="SyntaxToken" Name="endKeyword" />
@ -234,7 +237,7 @@
<Field Type="SyntaxToken" Name="closingBracket" />
</Class>
<Class Name="EnumerationItemSyntaxNode" BaseClass="SyntaxNode" Kind="EnumerationItem">
<Field Type="IdentifierNameSyntaxNode" Name="name" />
<Field Type="SyntaxToken" Name="name" />
<Field Type="EnumerationItemValueSyntaxNode" Name="values" Nullable="true"/>
<Field Type="SyntaxList&lt;SyntaxToken&gt;" Name="commas" />
</Class>

View File

@ -3,7 +3,7 @@ namespace Parser
{
public class FileSyntaxNode : SyntaxNode
{
private SyntaxNode? _statementList;
private SyntaxNode? _body;
internal FileSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -16,12 +16,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList StatementList
public BlockStatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._statementList!, 0);
return red is null ? throw new System.Exception("statementList cannot be null.") : (SyntaxNodeOrTokenList)red;
var red = this.GetRed(ref this._body!, 0);
return red is null ? throw new System.Exception("body cannot be null.") : (BlockStatementSyntaxNode)red;
}
}
@ -29,7 +29,7 @@ namespace Parser
{
return i switch
{
0 => GetRed(ref _statementList!, 0), _ => null
0 => GetRed(ref _body!, 0), _ => null
}
;
@ -41,6 +41,38 @@ namespace Parser
}
}
public class BlockStatementSyntaxNode : StatementSyntaxNode
{
private SyntaxNode? _statements;
internal BlockStatementSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
public SyntaxNodeOrTokenList Statements
{
get
{
var red = this.GetRed(ref this._statements!, 0);
return red is null ? throw new System.Exception("statements cannot be null.") : (SyntaxNodeOrTokenList)red;
}
}
internal override SyntaxNode? GetNode(int i)
{
return i switch
{
0 => GetRed(ref _statements!, 0), _ => null
}
;
}
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitBlockStatement(this);
}
}
public class FunctionDeclarationSyntaxNode : StatementSyntaxNode
{
private SyntaxNode? _outputDescription;
@ -95,12 +127,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 5);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -320,12 +352,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 3);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -388,12 +420,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 3);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -448,12 +480,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 3);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -488,12 +520,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 1);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -558,12 +590,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 3);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -644,12 +676,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 3);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -783,12 +815,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList TryBody
public StatementSyntaxNode TryBody
{
get
{
var red = this.GetRed(ref this._tryBody!, 1);
return red is null ? throw new System.Exception("tryBody cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("tryBody cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -941,10 +973,10 @@ namespace Parser
}
}
public class CompoundNameSyntaxNode : ExpressionSyntaxNode
public class CompoundNameExpressionSyntaxNode : ExpressionSyntaxNode
{
private SyntaxNode? _nodes;
internal CompoundNameSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal CompoundNameExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -969,14 +1001,14 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitCompoundName(this);
visitor.VisitCompoundNameExpression(this);
}
}
public class NamedFunctionHandleSyntaxNode : FunctionHandleSyntaxNode
public class NamedFunctionHandleExpressionSyntaxNode : FunctionHandleExpressionSyntaxNode
{
private SyntaxNode? _functionName;
internal NamedFunctionHandleSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal NamedFunctionHandleExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -984,16 +1016,16 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.NamedFunctionHandleSyntaxNode)_green)._atSign, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.NamedFunctionHandleExpressionSyntaxNode)_green)._atSign, this.GetChildPosition(0));
}
}
public CompoundNameSyntaxNode FunctionName
public CompoundNameExpressionSyntaxNode FunctionName
{
get
{
var red = this.GetRed(ref this._functionName!, 1);
return red is null ? throw new System.Exception("functionName cannot be null.") : (CompoundNameSyntaxNode)red;
return red is null ? throw new System.Exception("functionName cannot be null.") : (CompoundNameExpressionSyntaxNode)red;
}
}
@ -1009,15 +1041,15 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitNamedFunctionHandle(this);
visitor.VisitNamedFunctionHandleExpression(this);
}
}
public class LambdaSyntaxNode : FunctionHandleSyntaxNode
public class LambdaExpressionSyntaxNode : FunctionHandleExpressionSyntaxNode
{
private SyntaxNode? _input;
private SyntaxNode? _body;
internal LambdaSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal LambdaExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1025,7 +1057,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.LambdaSyntaxNode)_green)._atSign, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.LambdaExpressionSyntaxNode)_green)._atSign, this.GetChildPosition(0));
}
}
@ -1059,7 +1091,7 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitLambda(this);
visitor.VisitLambdaExpression(this);
}
}
@ -1113,9 +1145,9 @@ namespace Parser
}
}
public class IdentifierNameSyntaxNode : ExpressionSyntaxNode
public class IdentifierNameExpressionSyntaxNode : ExpressionSyntaxNode
{
internal IdentifierNameSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal IdentifierNameExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1123,7 +1155,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.IdentifierNameSyntaxNode)_green)._name, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.IdentifierNameExpressionSyntaxNode)_green)._name, this.GetChildPosition(0));
}
}
@ -1139,13 +1171,13 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitIdentifierName(this);
visitor.VisitIdentifierNameExpression(this);
}
}
public class NumberLiteralSyntaxNode : ExpressionSyntaxNode
public class NumberLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal NumberLiteralSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal NumberLiteralExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1153,7 +1185,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.NumberLiteralSyntaxNode)_green)._number, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.NumberLiteralExpressionSyntaxNode)_green)._number, this.GetChildPosition(0));
}
}
@ -1169,13 +1201,13 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitNumberLiteral(this);
visitor.VisitNumberLiteralExpression(this);
}
}
public class StringLiteralSyntaxNode : ExpressionSyntaxNode
public class StringLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal StringLiteralSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal StringLiteralExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1183,7 +1215,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.StringLiteralSyntaxNode)_green)._stringToken, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.StringLiteralExpressionSyntaxNode)_green)._stringToken, this.GetChildPosition(0));
}
}
@ -1199,13 +1231,13 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitStringLiteral(this);
visitor.VisitStringLiteralExpression(this);
}
}
public class DoubleQuotedStringLiteralSyntaxNode : ExpressionSyntaxNode
public class DoubleQuotedStringLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal DoubleQuotedStringLiteralSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal DoubleQuotedStringLiteralExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1213,7 +1245,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.DoubleQuotedStringLiteralSyntaxNode)_green)._stringToken, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.DoubleQuotedStringLiteralExpressionSyntaxNode)_green)._stringToken, this.GetChildPosition(0));
}
}
@ -1229,13 +1261,13 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitDoubleQuotedStringLiteral(this);
visitor.VisitDoubleQuotedStringLiteralExpression(this);
}
}
public class UnquotedStringLiteralSyntaxNode : ExpressionSyntaxNode
public class UnquotedStringLiteralExpressionSyntaxNode : ExpressionSyntaxNode
{
internal UnquotedStringLiteralSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal UnquotedStringLiteralExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1243,7 +1275,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.UnquotedStringLiteralSyntaxNode)_green)._stringToken, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.UnquotedStringLiteralExpressionSyntaxNode)_green)._stringToken, this.GetChildPosition(0));
}
}
@ -1259,7 +1291,7 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitUnquotedStringLiteral(this);
visitor.VisitUnquotedStringLiteralExpression(this);
}
}
@ -1523,11 +1555,11 @@ namespace Parser
}
}
public class MemberAccessSyntaxNode : ExpressionSyntaxNode
public class MemberAccessExpressionSyntaxNode : ExpressionSyntaxNode
{
private SyntaxNode? _leftOperand;
private SyntaxNode? _rightOperand;
internal MemberAccessSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal MemberAccessExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1535,7 +1567,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.MemberAccessSyntaxNode)_green)._dot, this.GetChildPosition(1));
return new SyntaxToken(this, ((Parser.Internal.MemberAccessExpressionSyntaxNode)_green)._dot, this.GetChildPosition(1));
}
}
@ -1569,14 +1601,14 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitMemberAccess(this);
visitor.VisitMemberAccessExpression(this);
}
}
public class UnaryPostixOperationExpressionSyntaxNode : ExpressionSyntaxNode
public class UnaryPostfixOperationExpressionSyntaxNode : ExpressionSyntaxNode
{
private SyntaxNode? _operand;
internal UnaryPostixOperationExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal UnaryPostfixOperationExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1584,7 +1616,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.UnaryPostixOperationExpressionSyntaxNode)_green)._operation, this.GetChildPosition(1));
return new SyntaxToken(this, ((Parser.Internal.UnaryPostfixOperationExpressionSyntaxNode)_green)._operation, this.GetChildPosition(1));
}
}
@ -1609,14 +1641,14 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitUnaryPostixOperationExpression(this);
visitor.VisitUnaryPostfixOperationExpression(this);
}
}
public class IndirectMemberAccessSyntaxNode : ExpressionSyntaxNode
public class IndirectMemberAccessExpressionSyntaxNode : ExpressionSyntaxNode
{
private SyntaxNode? _expression;
internal IndirectMemberAccessSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal IndirectMemberAccessExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1624,7 +1656,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.IndirectMemberAccessSyntaxNode)_green)._openingBracket, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.IndirectMemberAccessExpressionSyntaxNode)_green)._openingBracket, this.GetChildPosition(0));
}
}
@ -1632,7 +1664,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.IndirectMemberAccessSyntaxNode)_green)._closingBracket, this.GetChildPosition(2));
return new SyntaxToken(this, ((Parser.Internal.IndirectMemberAccessExpressionSyntaxNode)_green)._closingBracket, this.GetChildPosition(2));
}
}
@ -1657,24 +1689,22 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitIndirectMemberAccess(this);
visitor.VisitIndirectMemberAccessExpression(this);
}
}
public class CommandExpressionSyntaxNode : ExpressionSyntaxNode
{
private SyntaxNode? _commandName;
private SyntaxNode? _arguments;
internal CommandExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
public IdentifierNameSyntaxNode CommandName
public SyntaxToken CommandName
{
get
{
var red = this.GetRed(ref this._commandName!, 0);
return red is null ? throw new System.Exception("commandName cannot be null.") : (IdentifierNameSyntaxNode)red;
return new SyntaxToken(this, ((Parser.Internal.CommandExpressionSyntaxNode)_green)._commandName, this.GetChildPosition(0));
}
}
@ -1691,7 +1721,7 @@ namespace Parser
{
return i switch
{
0 => GetRed(ref _commandName!, 0), 1 => GetRed(ref _arguments!, 1), _ => null
1 => GetRed(ref _arguments!, 1), _ => null
}
;
@ -1703,11 +1733,11 @@ namespace Parser
}
}
public class BaseClassInvokationSyntaxNode : ExpressionSyntaxNode
public class ClassInvokationExpressionSyntaxNode : ExpressionSyntaxNode
{
private SyntaxNode? _methodName;
private SyntaxNode? _baseClassNameAndArguments;
internal BaseClassInvokationSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal ClassInvokationExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1715,7 +1745,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.BaseClassInvokationSyntaxNode)_green)._atSign, this.GetChildPosition(1));
return new SyntaxToken(this, ((Parser.Internal.ClassInvokationExpressionSyntaxNode)_green)._atSign, this.GetChildPosition(1));
}
}
@ -1749,7 +1779,7 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitBaseClassInvokation(this);
visitor.VisitClassInvokationExpression(this);
}
}
@ -1795,18 +1825,16 @@ namespace Parser
public class AttributeSyntaxNode : SyntaxNode
{
private SyntaxNode? _name;
private SyntaxNode? _assignment;
internal AttributeSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
public IdentifierNameSyntaxNode Name
public SyntaxToken Name
{
get
{
var red = this.GetRed(ref this._name!, 0);
return red is null ? throw new System.Exception("name cannot be null.") : (IdentifierNameSyntaxNode)red;
return new SyntaxToken(this, ((Parser.Internal.AttributeSyntaxNode)_green)._name, this.GetChildPosition(0));
}
}
@ -1823,7 +1851,7 @@ namespace Parser
{
return i switch
{
0 => GetRed(ref _name!, 0), 1 => GetRed(ref _assignment, 1), _ => null
1 => GetRed(ref _assignment, 1), _ => null
}
;
@ -1883,7 +1911,7 @@ namespace Parser
}
}
public class MethodDefinitionSyntaxNode : MethodDeclarationSyntaxNode
public class ConcreteMethodDeclarationSyntaxNode : MethodDeclarationSyntaxNode
{
private SyntaxNode? _outputDescription;
private SyntaxNode? _name;
@ -1891,7 +1919,7 @@ namespace Parser
private SyntaxNode? _commas;
private SyntaxNode? _body;
private SyntaxNode? _endKeyword;
internal MethodDefinitionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
internal ConcreteMethodDeclarationSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
@ -1899,7 +1927,7 @@ namespace Parser
{
get
{
return new SyntaxToken(this, ((Parser.Internal.MethodDefinitionSyntaxNode)_green)._functionKeyword, this.GetChildPosition(0));
return new SyntaxToken(this, ((Parser.Internal.ConcreteMethodDeclarationSyntaxNode)_green)._functionKeyword, this.GetChildPosition(0));
}
}
@ -1912,12 +1940,12 @@ namespace Parser
}
}
public CompoundNameSyntaxNode Name
public CompoundNameExpressionSyntaxNode Name
{
get
{
var red = this.GetRed(ref this._name!, 2);
return red is null ? throw new System.Exception("name cannot be null.") : (CompoundNameSyntaxNode)red;
return red is null ? throw new System.Exception("name cannot be null.") : (CompoundNameExpressionSyntaxNode)red;
}
}
@ -1939,12 +1967,12 @@ namespace Parser
}
}
public SyntaxNodeOrTokenList Body
public StatementSyntaxNode Body
{
get
{
var red = this.GetRed(ref this._body!, 5);
return red is null ? throw new System.Exception("body cannot be null.") : (SyntaxNodeOrTokenList)red;
return red is null ? throw new System.Exception("body cannot be null.") : (StatementSyntaxNode)red;
}
}
@ -1969,7 +1997,7 @@ namespace Parser
public override void Accept(SyntaxVisitor visitor)
{
visitor.VisitMethodDefinition(this);
visitor.VisitConcreteMethodDeclaration(this);
}
}
@ -1991,12 +2019,12 @@ namespace Parser
}
}
public CompoundNameSyntaxNode Name
public CompoundNameExpressionSyntaxNode Name
{
get
{
var red = this.GetRed(ref this._name!, 1);
return red is null ? throw new System.Exception("name cannot be null.") : (CompoundNameSyntaxNode)red;
return red is null ? throw new System.Exception("name cannot be null.") : (CompoundNameExpressionSyntaxNode)red;
}
}
@ -2184,7 +2212,6 @@ namespace Parser
public class ClassDeclarationSyntaxNode : StatementSyntaxNode
{
private SyntaxNode? _attributes;
private SyntaxNode? _className;
private SyntaxNode? _baseClassList;
private SyntaxNode? _nodes;
internal ClassDeclarationSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
@ -2199,6 +2226,14 @@ namespace Parser
}
}
public SyntaxToken ClassName
{
get
{
return new SyntaxToken(this, ((Parser.Internal.ClassDeclarationSyntaxNode)_green)._className, this.GetChildPosition(2));
}
}
public SyntaxToken EndKeyword
{
get
@ -2216,15 +2251,6 @@ namespace Parser
}
}
public IdentifierNameSyntaxNode ClassName
{
get
{
var red = this.GetRed(ref this._className!, 2);
return red is null ? throw new System.Exception("className cannot be null.") : (IdentifierNameSyntaxNode)red;
}
}
public BaseClassListSyntaxNode? BaseClassList
{
get
@ -2247,7 +2273,7 @@ namespace Parser
{
return i switch
{
1 => GetRed(ref _attributes, 1), 2 => GetRed(ref _className!, 2), 3 => GetRed(ref _baseClassList, 3), 4 => GetRed(ref _nodes!, 4), _ => null
1 => GetRed(ref _attributes, 1), 3 => GetRed(ref _baseClassList, 3), 4 => GetRed(ref _nodes!, 4), _ => null
}
;
@ -2309,19 +2335,17 @@ namespace Parser
public class EnumerationItemSyntaxNode : SyntaxNode
{
private SyntaxNode? _name;
private SyntaxNode? _values;
private SyntaxNode? _commas;
internal EnumerationItemSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position): base(parent, green, position)
{
}
public IdentifierNameSyntaxNode Name
public SyntaxToken Name
{
get
{
var red = this.GetRed(ref this._name!, 0);
return red is null ? throw new System.Exception("name cannot be null.") : (IdentifierNameSyntaxNode)red;
return new SyntaxToken(this, ((Parser.Internal.EnumerationItemSyntaxNode)_green)._name, this.GetChildPosition(0));
}
}
@ -2347,7 +2371,7 @@ namespace Parser
{
return i switch
{
0 => GetRed(ref _name!, 0), 1 => GetRed(ref _values, 1), 2 => GetRed(ref _commas!, 2), _ => null
1 => GetRed(ref _values, 1), 2 => GetRed(ref _commas!, 2), _ => null
}
;

View File

@ -141,9 +141,9 @@ namespace Parser
}
}
public abstract class FunctionHandleSyntaxNode : ExpressionSyntaxNode
public abstract class FunctionHandleExpressionSyntaxNode : ExpressionSyntaxNode
{
internal FunctionHandleSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position) : base(parent, green, position)
internal FunctionHandleExpressionSyntaxNode(SyntaxNode parent, Internal.GreenNode green, int position) : base(parent, green, position)
{
}
}

View File

@ -29,6 +29,8 @@ namespace Parser
public int Position { get; }
public object? Value => _token.GetValue();
public bool Equals(SyntaxToken other)
{
return Equals(_parent, other._parent) && Equals(_token, other._token);

27
Parser/SyntaxTree.cs Normal file
View File

@ -0,0 +1,27 @@
using System;
using Parser.Internal;
namespace Parser
{
public class SyntaxTree
{
public SyntaxTree(RootSyntaxNode nullRoot, DiagnosticsBag diagnostics)
{
NullRoot = nullRoot ?? throw new ArgumentNullException(nameof(nullRoot));
Diagnostics = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics));
}
public RootSyntaxNode NullRoot { get; }
public FileSyntaxNode Root => NullRoot.File;
public DiagnosticsBag Diagnostics { get; }
public static SyntaxTree Parse(string text)
{
var window = new TextWindowWithNull(text);
var parser = new MParser(window);
var tree = parser.Parse();
return tree;
}
}
}

View File

@ -8,6 +8,11 @@ namespace Parser
DefaultVisit(node);
}
public virtual void VisitBlockStatement(BlockStatementSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitFunctionDeclaration(FunctionDeclarationSyntaxNode node)
{
DefaultVisit(node);
@ -93,17 +98,17 @@ namespace Parser
DefaultVisit(node);
}
public virtual void VisitCompoundName(CompoundNameSyntaxNode node)
public virtual void VisitCompoundNameExpression(CompoundNameExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitNamedFunctionHandle(NamedFunctionHandleSyntaxNode node)
public virtual void VisitNamedFunctionHandleExpression(NamedFunctionHandleExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitLambda(LambdaSyntaxNode node)
public virtual void VisitLambdaExpression(LambdaExpressionSyntaxNode node)
{
DefaultVisit(node);
}
@ -113,27 +118,27 @@ namespace Parser
DefaultVisit(node);
}
public virtual void VisitIdentifierName(IdentifierNameSyntaxNode node)
public virtual void VisitIdentifierNameExpression(IdentifierNameExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitNumberLiteral(NumberLiteralSyntaxNode node)
public virtual void VisitNumberLiteralExpression(NumberLiteralExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitStringLiteral(StringLiteralSyntaxNode node)
public virtual void VisitStringLiteralExpression(StringLiteralExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitDoubleQuotedStringLiteral(DoubleQuotedStringLiteralSyntaxNode node)
public virtual void VisitDoubleQuotedStringLiteralExpression(DoubleQuotedStringLiteralExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitUnquotedStringLiteral(UnquotedStringLiteralSyntaxNode node)
public virtual void VisitUnquotedStringLiteralExpression(UnquotedStringLiteralExpressionSyntaxNode node)
{
DefaultVisit(node);
}
@ -163,17 +168,17 @@ namespace Parser
DefaultVisit(node);
}
public virtual void VisitMemberAccess(MemberAccessSyntaxNode node)
public virtual void VisitMemberAccessExpression(MemberAccessExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitUnaryPostixOperationExpression(UnaryPostixOperationExpressionSyntaxNode node)
public virtual void VisitUnaryPostfixOperationExpression(UnaryPostfixOperationExpressionSyntaxNode node)
{
DefaultVisit(node);
}
public virtual void VisitIndirectMemberAccess(IndirectMemberAccessSyntaxNode node)
public virtual void VisitIndirectMemberAccessExpression(IndirectMemberAccessExpressionSyntaxNode node)
{
DefaultVisit(node);
}
@ -183,7 +188,7 @@ namespace Parser
DefaultVisit(node);
}
public virtual void VisitBaseClassInvokation(BaseClassInvokationSyntaxNode node)
public virtual void VisitClassInvokationExpression(ClassInvokationExpressionSyntaxNode node)
{
DefaultVisit(node);
}
@ -203,7 +208,7 @@ namespace Parser
DefaultVisit(node);
}
public virtual void VisitMethodDefinition(MethodDefinitionSyntaxNode node)
public virtual void VisitConcreteMethodDeclaration(ConcreteMethodDeclarationSyntaxNode node)
{
DefaultVisit(node);
}

View File

@ -3,7 +3,9 @@
// We use the same set of kinds for syntax tokens & syntax nodes.
public enum TokenKind
{
// SYNTAX TOKENS
// *****************
// * SYNTAX TOKENS *
// *****************
None = 0,
BadToken = 1,
@ -123,31 +125,58 @@
UnaryNot = 59,
UnaryQuestionMark = 60,
// SYNTAX NODES
// ****************
// * SYNTAX NODES *
// ****************
// The whole file.
File = 100,
// a list of syntax nodes and/or tokens.
List,
// STATEMENTS
// The name ends with "Declaration" or "Statement".
// result = abstractMethod(object)
AbstractMethodDeclaration,
// statement1
// statement2;
BlockStatement,
// classdef MyClass < BaseClass, AnotherBaseClass
// properties
// y
// end
// methods
// <...>
// end
// end
ClassDeclaration,
// function result = method(obj)
// <...>
// end
ConcreteMethodDeclaration,
//
EmptyStatement,
// a = 5;
ExpressionStatement,
// for a = 1:5
// process(a);
// end
ForStatement,
// [output1, output2] = function(input1, input2)
// <...>
// end
FunctionDeclaration,
// (input1, input2)
FunctionInputDescription,
// [output1, output2] =
FunctionOutputDescription,
// switch a
// case 1
// <...>
// end
SwitchStatement,
// case 1
// doSomething();
SwitchCase,
// while a < 10
// doSomething();
// end
WhileStatement,
// if a < 5
// doSomething();
// elseif a > 10
@ -156,84 +185,125 @@
// GiveUp();
// end
IfStatement,
// elseif a > 10
// doSomethingElse();
ElseifClause,
// else
// GiveUp();
ElseClause,
// for a = 1:5
// process(a);
// switch a
// case 1
// <...>
// end
ForStatement,
// a = 1:5
AssignmentExpression,
// catch e
// dealWithIt(e);
// end
CatchClause,
SwitchStatement,
// try
// somethingWeird();
// catch e
// dealWithIt(e);
// end
TryCatchStatement,
// a = 5;
ExpressionStatement,
//
EmptyStatement,
//
EmptyExpression,
// -13
UnaryPrefixOperationExpression,
// some.complex.name
CompoundName,
// @func
NamedFunctionHandle,
// @(x) x + 1
Lambda,
// +
BinaryOperation,
// a
IdentifierName,
// 123
NumberLiteralExpression,
// 'abc'
StringLiteralExpression,
// "abc"
DoubleQuotedStringLiteralExpression,
// abc
UnquotedStringLiteralExpression,
// while a < 10
// doSomething();
// end
WhileStatement,
// EXPRESSIONS
// The name ends with "Expression".
// [1, 2; 3 4]
ArrayLiteralExpression,
// a = 1:5
AssignmentExpression,
// +
BinaryOperationExpression,
// abc{2}
CellArrayElementAccessExpression,
// {1, 3, 'abc'}
CellArrayLiteralExpression,
// method@SuperClass(object)
ClassInvokationExpression,
// cd some/+folder/
CommandExpression,
// some.complex.name
CompoundNameExpression,
// "abc"
DoubleQuotedStringLiteralExpression,
//
EmptyExpression,
// doSomething(5)
FunctionCallExpression,
// a
IdentifierNameExpression,
// struct.(field)
IndirectMemberAccessExpression,
// @(x) x + 1
LambdaExpression,
// object.member
MemberAccessExpression,
// @func
NamedFunctionHandleExpression,
// 123
NumberLiteralExpression,
// (1 + 2 * 3)
ParenthesizedExpression,
// abc{2}
CellArrayElementAccess,
// doSomething(5)
FunctionCall,
// object.member
MemberAccess,
// 'abc'
StringLiteralExpression,
// -13
UnaryPrefixOperationExpression,
// [1 2 3]'
UnaryPostfixOperationExpression,
// struct.(field)
IndirectMemberAccess,
// cd some/+folder/
Command,
// method@SuperClass(object)
ClassInvokation,
// abc
UnquotedStringLiteralExpression,
// PARTS OF STATEMENTS & EXPRESSIONS
// (input1, input2)
FunctionInputDescription,
// [output1, output2] =
FunctionOutputDescription,
// case 1
// doSomething();
SwitchCase,
// elseif a > 10
// doSomethingElse();
ElseifClause,
// else
// GiveUp();
ElseClause,
// catch e
// dealWithIt(e);
// end
CatchClause,
// = true
AttributeAssignment,
// Sealed = true
Attribute,
// (Sealed = true)
AttributeList,
// function result = method(obj)
// <...>
// end
MethodDefinition,
// methods
// function result = method(obj)
// <...>
@ -247,15 +317,7 @@
PropertiesList,
// < BaseClass, AnotherBaseClass
BaseClassList,
// classdef MyClass < BaseClass, AnotherBaseClass
// properties
// y
// end
// methods
// <...>
// end
// end
ClassDeclaration,
// (1)
EnumerationItemValue,
// One (1)
@ -265,8 +327,6 @@
// Two (2)
// end
EnumerationList,
// result = abstractMethod(object)
AbstractMethodDeclaration,
// events
// ToggleSomething
// end

View File

@ -0,0 +1,12 @@
namespace Parser
{
internal class UnresolvedFunctionSymbol
{
public string Name { get; }
public UnresolvedFunctionSymbol(string name)
{
Name = name;
}
}
}

View File

@ -1,67 +1,80 @@
using System;
using System.Linq;
using Parser;
namespace Repl
{
public class MRepl
{
private readonly CompilationContext _context;
public MRepl()
{
_context = CompilationContext.Empty;
}
public void Run()
{
while (true)
{
Console.Write("> ");
var line = Console.ReadLine();
var window = new TextWindowWithNull(line);
var parser = new MParser(window);
var tree = parser.Parse();
if (tree.Diagnostics.Diagnostics.Count > 0)
var line = Read();
if (line.StartsWith('#'))
{
foreach (var diagnostic in tree.Diagnostics.Diagnostics)
line = line.Trim();
if (line == "#q")
{
Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}");
break;
}
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"Unknown command '{line}'.");
Console.ResetColor();
continue;
}
var result = Evaluate(line);
Print(result);
}
}
private void Print(string result)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(result);
Console.ResetColor();
}
private string Read()
{
Console.Write("> ");
return Console.ReadLine();
}
private string Evaluate(string submission)
{
var tree = SyntaxTree.Parse(submission);
if (tree.Diagnostics.Any())
{
foreach (var diagnostic in tree.Diagnostics.Diagnostics)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}");
Console.ResetColor();
}
TreeRenderer.RenderTree(tree);
return string.Empty;
}
}
}
public class TreeRenderer
{
private static void RenderToken(SyntaxToken token, string indent, bool isLast)
{
Console.Write(indent + (isLast ? "└── " : "├── "));
Console.Write($"<{token.Kind}>");
Console.Write($" {token.Text}");
Console.WriteLine();
}
TreeRenderer.RenderTree(tree);
var compilation = Compilation.Create(tree);
var evaluationResult = compilation.Evaluate(_context, inRepl: true);
private static void RenderNode(SyntaxNode node, string indent, bool isLast)
{
Console.Write(indent);
Console.Write(isLast ? "└── " : "├── ");
Console.Write($"<{node.Kind}>");
Console.WriteLine();
var children = node.GetChildNodesAndTokens();
var last = children.Count - 1;
indent += isLast ? " " : "│ ";
for (var index = 0; index <= last; index++)
foreach (var diagnostic in evaluationResult.Diagnostics)
{
var child = children[index];
if (child.IsNode)
{
RenderNode(child.AsNode(), indent, index == last);
}
else if (child.IsToken)
{
RenderToken(child.AsToken(), indent, index == last);
}
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}");
Console.ResetColor();
}
}
public static void RenderTree(SyntaxTree tree)
{
RenderNode(tree.Root, "", true);
return evaluationResult.Value?.ToString() ?? string.Empty;
}
}
}

44
Repl/TreeRenderer.cs Normal file
View File

@ -0,0 +1,44 @@
using System;
using Parser;
namespace Repl
{
public class TreeRenderer
{
private static void RenderToken(SyntaxToken token, string indent, bool isLast)
{
Console.Write(indent + (isLast ? "└── " : "├── "));
Console.Write($"<{token.Kind}>");
Console.Write($" {token.Text}");
Console.WriteLine();
}
private static void RenderNode(SyntaxNode node, string indent, bool isLast)
{
Console.Write(indent);
Console.Write(isLast ? "└── " : "├── ");
Console.Write($"<{node.Kind}>");
Console.WriteLine();
var children = node.GetChildNodesAndTokens();
var last = children.Count - 1;
indent += isLast ? " " : "│ ";
for (var index = 0; index <= last; index++)
{
var child = children[index];
if (child.IsNode)
{
RenderNode(child.AsNode(), indent, index == last);
}
else if (child.IsToken)
{
RenderToken(child.AsToken(), indent, index == last);
}
}
}
public static void RenderTree(SyntaxTree tree)
{
RenderNode(tree.Root, "", true);
}
}
}

View File

@ -7,7 +7,7 @@ namespace Semantics
{
public class GetClass
{
private static MMethod MethodFromDefinition(MethodDefinitionSyntaxNode methodDefinition)
private static MMethod MethodFromDefinition(ConcreteMethodDeclarationSyntaxNode methodDefinition)
{
var name = methodDefinition.Name.Text;
var description = "";
@ -42,7 +42,7 @@ namespace Semantics
continue;
}
if (method.AsNode() is MethodDefinitionSyntaxNode methodDefinition)
if (method.AsNode() is ConcreteMethodDeclarationSyntaxNode methodDefinition)
{
result.Add(MethodFromDefinition(methodDefinition));
}
@ -58,7 +58,7 @@ namespace Semantics
public static MClass FromTree(FileSyntaxNode tree, string fileName)
{
var classDeclaration = tree.StatementList[0].AsNode() as ClassDeclarationSyntaxNode;
var classDeclaration = tree.Body.Statements[0].AsNode() as ClassDeclarationSyntaxNode;
if (classDeclaration == null)
{
return null;

View File

@ -21,7 +21,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repl", "Repl\Repl.csproj", "{8FEDFE5D-3320-418F-88A6-09C1B51C4441}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MApplication", "MApplication\MApplication.csproj", "{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MApplication", "MApplication\MApplication.csproj", "{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cmi", "cmi\cmi.csproj", "{C2447F0B-733D-4755-A104-5B82E24D3F47}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -57,6 +59,10 @@ Global
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7EE271C-8822-43EA-BA13-5D6D5DC5B581}.Release|Any CPU.Build.0 = Release|Any CPU
{C2447F0B-733D-4755-A104-5B82E24D3F47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2447F0B-733D-4755-A104-5B82E24D3F47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2447F0B-733D-4755-A104-5B82E24D3F47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2447F0B-733D-4755-A104-5B82E24D3F47}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -844,7 +844,8 @@ namespace SyntaxGenerator
public static void Input()
{
var serializer = new XmlSerializer(typeof(SyntaxDescription));
using var stream = new FileStream("input.xml", FileMode.Open);
var syntaxDefinitionFileName = Path.Combine(_outputPath, "SyntaxDefinition.xml");
using var stream = new FileStream(syntaxDefinitionFileName, FileMode.Open);
if (!(serializer.Deserialize(stream) is SyntaxDescription syntax))
{
Console.WriteLine("Couldn't deserialize syntax.");

1
cmi.cmd Normal file
View File

@ -0,0 +1 @@
dotnet run --project cmi -- %*

55
cmi/Program.cs Normal file
View File

@ -0,0 +1,55 @@
using Parser;
using System;
using System.IO;
namespace cmi
{
class Program
{
static void Main(string[] args)
{
string fileName;
if (args.Length != 1)
{
Console.Error.WriteLine("Usage: cmi <file.m>");
fileName = @"C:\repos\MParser\examples\helloworld\hello.m";
}
else
{
fileName = args[0];
}
var text = File.ReadAllText(fileName);
var tree = SyntaxTree.Parse(text);
var compilation = Compilation.Create(tree);
TreeRenderer.RenderTree(tree);
if (tree.Diagnostics.Diagnostics.Count > 0)
{
foreach (var diagnostic in tree.Diagnostics.Diagnostics)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}");
Console.ResetColor();
return;
}
}
var context = new CompilationContext();
var evaluationResult = compilation.Evaluate(context, inRepl: false);
foreach (var diagnostic in evaluationResult.Diagnostics)
{
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}");
Console.ResetColor();
}
var result = evaluationResult.Value?.ToString();
if (result is not null)
{
Console.WriteLine(result);
}
}
}
}

44
cmi/TreeRenderer.cs Normal file
View File

@ -0,0 +1,44 @@
using Parser;
using System;
namespace cmi
{
public class TreeRenderer
{
private static void RenderToken(SyntaxToken token, string indent, bool isLast)
{
Console.Write(indent + (isLast ? "└── " : "├── "));
Console.Write($"<{token.Kind}>");
Console.Write($" {token.Text}");
Console.WriteLine();
}
private static void RenderNode(SyntaxNode node, string indent, bool isLast)
{
Console.Write(indent);
Console.Write(isLast ? "└── " : "├── ");
Console.Write($"<{node.Kind}>");
Console.WriteLine();
var children = node.GetChildNodesAndTokens();
var last = children.Count - 1;
indent += isLast ? " " : "│ ";
for (var index = 0; index <= last; index++)
{
var child = children[index];
if (child.IsNode)
{
RenderNode(child.AsNode(), indent, index == last);
}
else if (child.IsToken)
{
RenderToken(child.AsToken(), indent, index == last);
}
}
}
public static void RenderTree(SyntaxTree tree)
{
RenderNode(tree.Root, "", true);
}
}
}

14
cmi/cmi.csproj Normal file
View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Parser\Parser.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,11 @@
x = 2;
f(x);
f(x);
function f(x)
disp('X was');
disp(x);
x = x + 1;
disp('X is')
disp(x);
end