Start implementing Evaluator
This commit is contained in:
parent
f4921ac9f9
commit
8c1ddb0cf7
@ -1,5 +1,4 @@
|
|||||||
using Parser;
|
using Parser;
|
||||||
using Semantics;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -72,7 +71,7 @@ namespace ConsoleDemo
|
|||||||
var childNodesAndTokens = root.GetChildNodesAndTokens();
|
var childNodesAndTokens = root.GetChildNodesAndTokens();
|
||||||
var node = childNodesAndTokens[0].AsNode();
|
var node = childNodesAndTokens[0].AsNode();
|
||||||
var classChildNodesAndTokens = node.GetChildNodesAndTokens();
|
var classChildNodesAndTokens = node.GetChildNodesAndTokens();
|
||||||
var c = GetClass.FromTree(root, fileName);
|
var c = Semantics.GetClass.FromTree(root, fileName);
|
||||||
Console.WriteLine(c.Name);
|
Console.WriteLine(c.Name);
|
||||||
foreach (var m in c.Methods)
|
foreach (var m in c.Methods)
|
||||||
{
|
{
|
||||||
@ -86,13 +85,13 @@ namespace ConsoleDemo
|
|||||||
|
|
||||||
public static void ContextDemo()
|
public static void ContextDemo()
|
||||||
{
|
{
|
||||||
var context = new Context();
|
var context = new Semantics.Context();
|
||||||
context.ScanPath(BaseDirectory);
|
context.ScanPath(BaseDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DumbPrinterDemo()
|
public static void DumbPrinterDemo()
|
||||||
{
|
{
|
||||||
var context = new Context();
|
var context = new Semantics.Context();
|
||||||
context.ScanPath(BaseDirectory);
|
context.ScanPath(BaseDirectory);
|
||||||
var fileName = Path.Combine(
|
var fileName = Path.Combine(
|
||||||
BaseDirectory,
|
BaseDirectory,
|
||||||
@ -105,7 +104,7 @@ namespace ConsoleDemo
|
|||||||
|
|
||||||
public static void UsageDemo()
|
public static void UsageDemo()
|
||||||
{
|
{
|
||||||
var context = new Context();
|
var context = new Semantics.Context();
|
||||||
context.ScanPath(BaseDirectory);
|
context.ScanPath(BaseDirectory);
|
||||||
var fileName = Path.Combine(
|
var fileName = Path.Combine(
|
||||||
BaseDirectory,
|
BaseDirectory,
|
||||||
@ -130,7 +129,6 @@ namespace ConsoleDemo
|
|||||||
//ContextDemo();
|
//ContextDemo();
|
||||||
//DumbPrinterDemo();
|
//DumbPrinterDemo();
|
||||||
//UsageDemo();
|
//UsageDemo();
|
||||||
Console.ReadKey();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
Parser/Compilation.cs
Normal file
23
Parser/Compilation.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EvaluationResult Evaluate(CompilationContext context)
|
||||||
|
{
|
||||||
|
var evaluator = new Evaluator(_syntaxTree, context);
|
||||||
|
return evaluator.Evaluate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
Parser/CompilationContext.cs
Normal file
7
Parser/CompilationContext.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Parser
|
||||||
|
{
|
||||||
|
public class CompilationContext
|
||||||
|
{
|
||||||
|
public static CompilationContext Empty => new CompilationContext();
|
||||||
|
}
|
||||||
|
}
|
19
Parser/EvaluationResult.cs
Normal file
19
Parser/EvaluationResult.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
282
Parser/Evaluator.cs
Normal file
282
Parser/Evaluator.cs
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
using Parser.Internal;
|
||||||
|
using Parser.Objects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
|
namespace Parser
|
||||||
|
{
|
||||||
|
internal class Evaluator
|
||||||
|
{
|
||||||
|
private SyntaxTree _syntaxTree;
|
||||||
|
private CompilationContext _context;
|
||||||
|
private DiagnosticsBag _diagnostics;
|
||||||
|
|
||||||
|
public Evaluator(SyntaxTree syntaxTree, CompilationContext context)
|
||||||
|
{
|
||||||
|
_syntaxTree = syntaxTree;
|
||||||
|
_context = context;
|
||||||
|
_diagnostics = new DiagnosticsBag();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal EvaluationResult Evaluate()
|
||||||
|
{
|
||||||
|
var result = EvaluateFile(_syntaxTree.Root);
|
||||||
|
return new EvaluationResult(result, _diagnostics.ToImmutableArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateFile(FileSyntaxNode root)
|
||||||
|
{
|
||||||
|
MObject? lastResult = null;
|
||||||
|
foreach (var nodeOrToken in root.StatementList)
|
||||||
|
{
|
||||||
|
if (nodeOrToken.IsNode)
|
||||||
|
{
|
||||||
|
var statement = (StatementSyntaxNode)nodeOrToken.AsNode()!;
|
||||||
|
lastResult = EvaluateStatement(statement) ?? lastResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateStatement(StatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
return statement.Kind switch
|
||||||
|
{
|
||||||
|
TokenKind.ExpressionStatement =>
|
||||||
|
EvaluateExpressionStatement((ExpressionStatementSyntaxNode)statement),
|
||||||
|
TokenKind.MethodDefinition =>
|
||||||
|
EvaluateMethodDefinition((MethodDefinitionSyntaxNode)statement),
|
||||||
|
TokenKind.AbstractMethodDeclaration =>
|
||||||
|
EvaluateAbstractMethodDeclaration((AbstractMethodDeclarationSyntaxNode)statement),
|
||||||
|
TokenKind.FunctionDeclaration =>
|
||||||
|
EvaluateFunctionDeclaration((FunctionDeclarationSyntaxNode)statement),
|
||||||
|
TokenKind.SwitchStatement =>
|
||||||
|
EvaluateSwitchStatement((SwitchStatementSyntaxNode)statement),
|
||||||
|
TokenKind.WhileStatement =>
|
||||||
|
EvaluateWhileStatement((WhileStatementSyntaxNode)statement),
|
||||||
|
TokenKind.IfStatement =>
|
||||||
|
EvaluateIfStatement((IfStatementSyntaxNode)statement),
|
||||||
|
TokenKind.ForStatement =>
|
||||||
|
EvaluateForStatement((ForStatementSyntaxNode)statement),
|
||||||
|
TokenKind.TryCatchStatement =>
|
||||||
|
EvaluateTryCatchStatement((TryCatchStatementSyntaxNode)statement),
|
||||||
|
TokenKind.EmptyStatement =>
|
||||||
|
EvaluateEmptyStatement((EmptyStatementSyntaxNode)statement),
|
||||||
|
TokenKind.ClassDeclaration =>
|
||||||
|
EvaluateClassDeclaration((ClassDeclarationSyntaxNode)statement),
|
||||||
|
_ => throw new NotImplementedException($"Invalid statement kind '{statement.Kind}'."),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateClassDeclaration(ClassDeclarationSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateEmptyStatement(EmptyStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateTryCatchStatement(TryCatchStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateForStatement(ForStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateIfStatement(IfStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateWhileStatement(WhileStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateSwitchStatement(SwitchStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateFunctionDeclaration(FunctionDeclarationSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateAbstractMethodDeclaration(AbstractMethodDeclarationSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateMethodDefinition(MethodDefinitionSyntaxNode statement)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateExpressionStatement(ExpressionStatementSyntaxNode statement)
|
||||||
|
{
|
||||||
|
return EvaluateExpression(statement.Expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateExpression(ExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
return expression.Kind switch
|
||||||
|
{
|
||||||
|
TokenKind.Lambda =>
|
||||||
|
EvaluateLambda((LambdaSyntaxNode)expression),
|
||||||
|
TokenKind.AssignmentExpression =>
|
||||||
|
EvaluateAssignmentExpression((AssignmentExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.EmptyExpression =>
|
||||||
|
EvaluateEmptyExpression((EmptyExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.UnaryPrefixOperationExpression =>
|
||||||
|
EvaluateUnaryPrefixOperationExpression((UnaryPrefixOperationExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.CompoundName =>
|
||||||
|
EvaluateCompoundName((CompoundNameSyntaxNode)expression),
|
||||||
|
TokenKind.BinaryOperation =>
|
||||||
|
EvaluateBinaryOperation((BinaryOperationExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.IdentifierName =>
|
||||||
|
EvaluateIdentifierName((IdentifierNameSyntaxNode)expression),
|
||||||
|
TokenKind.NumberLiteralExpression =>
|
||||||
|
EvaluateNumberLiteralExpression((NumberLiteralSyntaxNode)expression),
|
||||||
|
TokenKind.StringLiteralExpression =>
|
||||||
|
EvaluateStringLiteralExpression((StringLiteralSyntaxNode)expression),
|
||||||
|
TokenKind.DoubleQuotedStringLiteralExpression =>
|
||||||
|
EvaluateDoubleQuotedStringLiteralExpression((DoubleQuotedStringLiteralSyntaxNode)expression),
|
||||||
|
TokenKind.UnquotedStringLiteralExpression =>
|
||||||
|
EvaluateUnquotedStringLiteralExpression((UnquotedStringLiteralSyntaxNode)expression),
|
||||||
|
TokenKind.ArrayLiteralExpression =>
|
||||||
|
EvaluateArrayLiteralExpression((ArrayLiteralExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.CellArrayLiteralExpression =>
|
||||||
|
EvaluateCellArrayLiteralExpression((CellArrayLiteralExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.ParenthesizedExpression =>
|
||||||
|
EvaluateNamedFunctionHandle((NamedFunctionHandleSyntaxNode)expression),
|
||||||
|
TokenKind.CellArrayElementAccess =>
|
||||||
|
EvaluateCellArrayElementAccess((CellArrayElementAccessExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.FunctionCall =>
|
||||||
|
EvaluateFunctionCall((FunctionCallExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.MemberAccess =>
|
||||||
|
EvaluateMemberAccess((MemberAccessSyntaxNode)expression),
|
||||||
|
TokenKind.UnaryPostfixOperationExpression =>
|
||||||
|
EvaluateUnaryPostfixOperationExpression((UnaryPostixOperationExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.IndirectMemberAccess =>
|
||||||
|
EvaluateIndirectMemberAccess((IndirectMemberAccessSyntaxNode)expression),
|
||||||
|
TokenKind.Command =>
|
||||||
|
EvaluateCommand((CommandExpressionSyntaxNode)expression),
|
||||||
|
TokenKind.ClassInvokation =>
|
||||||
|
EvaluateClassInvokation((BaseClassInvokationSyntaxNode)expression),
|
||||||
|
_ => throw new NotImplementedException($"Invalid expression kind '{expression.Kind}'."),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateClassInvokation(BaseClassInvokationSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateCommand(CommandExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateIndirectMemberAccess(IndirectMemberAccessSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateUnaryPostfixOperationExpression(UnaryPostixOperationExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateMemberAccess(MemberAccessSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateFunctionCall(FunctionCallExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateCellArrayElementAccess(CellArrayElementAccessExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateCellArrayLiteralExpression(CellArrayLiteralExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateArrayLiteralExpression(ArrayLiteralExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateUnquotedStringLiteralExpression(UnquotedStringLiteralSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateDoubleQuotedStringLiteralExpression(DoubleQuotedStringLiteralSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateStringLiteralExpression(StringLiteralSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateNumberLiteralExpression(NumberLiteralSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateIdentifierName(IdentifierNameSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateBinaryOperation(BinaryOperationExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateCompoundName(CompoundNameSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateUnaryPrefixOperationExpression(UnaryPrefixOperationExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateEmptyExpression(EmptyExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateAssignmentExpression(AssignmentExpressionSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateLambda(LambdaSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MObject? EvaluateNamedFunctionHandle(NamedFunctionHandleSyntaxNode expression)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,4 @@
|
|||||||
using System;
|
using Parser.Internal;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Parser.Internal;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Parser
|
namespace Parser
|
||||||
@ -27,18 +25,4 @@ namespace Parser
|
|||||||
return new SyntaxTree(root, totalDiagnostics);
|
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; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
6
Parser/Objects/MDoubleNumber.cs
Normal file
6
Parser/Objects/MDoubleNumber.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Parser.Objects
|
||||||
|
{
|
||||||
|
public class MDoubleNumber : MObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
6
Parser/Objects/MObject.cs
Normal file
6
Parser/Objects/MObject.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace Parser.Objects
|
||||||
|
{
|
||||||
|
public abstract class MObject
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
27
Parser/SyntaxTree.cs
Normal file
27
Parser/SyntaxTree.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,63 +5,74 @@ namespace Repl
|
|||||||
{
|
{
|
||||||
public class MRepl
|
public class MRepl
|
||||||
{
|
{
|
||||||
|
private readonly CompilationContext _context;
|
||||||
|
|
||||||
|
public MRepl()
|
||||||
|
{
|
||||||
|
_context = CompilationContext.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Console.Write("> ");
|
var line = Read();
|
||||||
var line = Console.ReadLine();
|
if (line.StartsWith('#'))
|
||||||
var window = new TextWindowWithNull(line);
|
|
||||||
var parser = new MParser(window);
|
|
||||||
var tree = parser.Parse();
|
|
||||||
if (tree.Diagnostics.Diagnostics.Count > 0)
|
|
||||||
{
|
{
|
||||||
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.Write(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string Read()
|
||||||
|
{
|
||||||
|
Console.Write("> ");
|
||||||
|
return Console.ReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string Evaluate(string submission)
|
||||||
|
{
|
||||||
|
var tree = SyntaxTree.Parse(submission);
|
||||||
|
var compilation = Compilation.Create(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();
|
||||||
}
|
}
|
||||||
TreeRenderer.RenderTree(tree);
|
TreeRenderer.RenderTree(tree);
|
||||||
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TreeRenderer
|
TreeRenderer.RenderTree(tree);
|
||||||
{
|
|
||||||
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)
|
var evaluationResult = compilation.Evaluate(_context);
|
||||||
{
|
|
||||||
Console.Write(indent);
|
foreach (var diagnostic in evaluationResult.Diagnostics)
|
||||||
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];
|
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||||
if (child.IsNode)
|
Console.WriteLine($"{diagnostic.Span}: {diagnostic.Message}");
|
||||||
{
|
Console.ResetColor();
|
||||||
RenderNode(child.AsNode(), indent, index == last);
|
|
||||||
}
|
|
||||||
else if (child.IsToken)
|
|
||||||
{
|
|
||||||
RenderToken(child.AsToken(), indent, index == last);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static void RenderTree(SyntaxTree tree)
|
return evaluationResult.Value?.ToString() ?? string.Empty;
|
||||||
{
|
|
||||||
RenderNode(tree.Root, "", true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
Repl/TreeRenderer.cs
Normal file
44
Repl/TreeRenderer.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user