@@ -5,9 +5,9 @@ namespace Canon.Generator.Extensions;
|
||||
|
||||
public static class RootCommandExtension
|
||||
{
|
||||
public static void AddGenerateCommand(this RootCommand rootCommand)
|
||||
public static void AddGrammarCommand(this RootCommand rootCommand)
|
||||
{
|
||||
Command generateCommand = new("generate", "Generate source files.");
|
||||
Command generateCommand = new("grammar", "Generate grammar parser source files.");
|
||||
|
||||
Argument<string> filenameArgument = new(name: "filename",
|
||||
description: "determines the generated file name.",
|
||||
@@ -37,4 +37,16 @@ public static class RootCommandExtension
|
||||
|
||||
rootCommand.AddCommand(generateCommand);
|
||||
}
|
||||
|
||||
public static void AddSyntaxVisitorCommand(this RootCommand rootCommand)
|
||||
{
|
||||
Command syntaxCommand = new("syntax", "Generate syntax visitor source code.");
|
||||
|
||||
syntaxCommand.SetHandler(async () =>
|
||||
{
|
||||
await SyntaxVisitorGenerator.SyntaxVisitorGenerator.Generate();
|
||||
});
|
||||
|
||||
rootCommand.AddCommand(syntaxCommand);
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ using Canon.Generator.Extensions;
|
||||
|
||||
RootCommand rootCommand = new("Canon Compiler Source Generator");
|
||||
|
||||
rootCommand.AddGenerateCommand();
|
||||
rootCommand.AddGrammarCommand();
|
||||
rootCommand.AddSyntaxVisitorCommand();
|
||||
|
||||
await rootCommand.InvokeAsync(args);
|
||||
|
@@ -0,0 +1,78 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Canon.Generator.SyntaxVisitorGenerator;
|
||||
|
||||
public static class SyntaxVisitorGenerator
|
||||
{
|
||||
private static readonly List<string> s_nodes =
|
||||
[
|
||||
"AddOperator",
|
||||
"BasicType",
|
||||
"CompoundStatement",
|
||||
"ConstDeclaration",
|
||||
"ConstDeclarations",
|
||||
"ConstValue",
|
||||
"ElsePart",
|
||||
"Expression",
|
||||
"ExpressionList",
|
||||
"Factor",
|
||||
"FormalParameter",
|
||||
"IdentifierList",
|
||||
"IdentifierVarPart",
|
||||
"MultiplyOperator",
|
||||
"Parameter",
|
||||
"ParameterList",
|
||||
"Period",
|
||||
"ProcedureCall",
|
||||
"ProgramBody",
|
||||
"ProgramHead",
|
||||
"ProgramStruct",
|
||||
"RelationOperator",
|
||||
"SimpleExpression",
|
||||
"Statement",
|
||||
"StatementList",
|
||||
"Subprogram",
|
||||
"SubprogramBody",
|
||||
"SubprogramDeclarations",
|
||||
"SubprogramHead",
|
||||
"Term",
|
||||
"TypeSyntaxNode",
|
||||
"ValueParameter",
|
||||
"VarDeclaration",
|
||||
"VarDeclarations",
|
||||
"Variable",
|
||||
"VarParameter"
|
||||
];
|
||||
|
||||
public static async Task Generate()
|
||||
{
|
||||
FileInfo output = new(Path.Combine(Environment.CurrentDirectory, "SyntaxNodeVisitor.cs"));
|
||||
|
||||
StringBuilder builder = new();
|
||||
|
||||
builder.Append("using Canon.Core.SyntaxNodes;\n").Append('\n');
|
||||
builder.Append("namespace Canon.Core.Abstractions;\n").Append('\n');
|
||||
|
||||
builder.Append("public abstract class SyntaxNodeVisitor\n").Append("{\n");
|
||||
|
||||
foreach (string node in s_nodes)
|
||||
{
|
||||
string nodeName = node.Substring(0, 1).ToLower() + node.Substring(1);
|
||||
|
||||
builder.Append($" public virtual void PreVisit({node} {nodeName})\n")
|
||||
.Append(" {\n")
|
||||
.Append(" }\n")
|
||||
.Append('\n');
|
||||
|
||||
builder.Append($" public virtual void PostVisit({node} {nodeName})\n")
|
||||
.Append(" {\n")
|
||||
.Append(" }\n")
|
||||
.Append('\n');
|
||||
}
|
||||
|
||||
builder.Append('}');
|
||||
|
||||
await using StreamWriter writer = output.CreateText();
|
||||
await writer.WriteAsync(builder.ToString());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user