Skip to content

Commit

Permalink
Implement rewriter generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
GGG-KILLER committed Jan 29, 2024
1 parent 9f0aad1 commit 2d68e46
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -425,5 +425,17 @@ protected override void DefaultVisit(global::Tsu.Trees.RedGreen.Sample.Internal.
}
}
}

public partial class SampleRewriter : Tsu.Trees.RedGreen.Sample.SampleVisitor<global::Tsu.Trees.RedGreen.Sample.SampleNode>
{
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitIdentifierExpression(global::Tsu.Trees.RedGreen.Sample.IdentifierExpressionSample node) =>
node.Update(node.Name);
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitNumericalLiteralExpression(global::Tsu.Trees.RedGreen.Sample.NumericalLiteralExpressionSample node) =>
node.Update(node.Value);
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitBinaryOperationExpression(global::Tsu.Trees.RedGreen.Sample.BinaryOperationExpressionSample node) =>
node.Update(node.Kind, (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.Left) ?? throw new global::System.InvalidOperationException("Left cannot be null."), (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.Right) ?? throw new global::System.InvalidOperationException("Right cannot be null."));
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitFunctionCallExpression(global::Tsu.Trees.RedGreen.Sample.FunctionCallExpressionSample node) =>
node.Update((global::Tsu.Trees.RedGreen.Sample.IdentifierExpressionSample?)Visit(node.Identifier) ?? throw new global::System.InvalidOperationException("Identifier cannot be null."), (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.FirstArg) ?? throw new global::System.InvalidOperationException("FirstArg cannot be null."), (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.SecondArg));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ protected override void DefaultVisit(global::Tsu.Trees.RedGreen.Sample.SampleNod
}
}


public partial class SampleRewriter : Tsu.Trees.RedGreen.Sample.SampleVisitor<global::Tsu.Trees.RedGreen.Sample.SampleNode>
{
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitIdentifierExpression(global::Tsu.Trees.RedGreen.Sample.IdentifierExpressionSample node) =>
node.Update(node.Name);
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitNumericalLiteralExpression(global::Tsu.Trees.RedGreen.Sample.NumericalLiteralExpressionSample node) =>
node.Update(node.Value);
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitBinaryOperationExpression(global::Tsu.Trees.RedGreen.Sample.BinaryOperationExpressionSample node) =>
node.Update(node.Kind, (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.Left) ?? throw new global::System.InvalidOperationException("Left cannot be null."), (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.Right) ?? throw new global::System.InvalidOperationException("Right cannot be null."));
public override global::Tsu.Trees.RedGreen.Sample.SampleNode VisitFunctionCallExpression(global::Tsu.Trees.RedGreen.Sample.FunctionCallExpressionSample node) =>
node.Update((global::Tsu.Trees.RedGreen.Sample.IdentifierExpressionSample?)Visit(node.Identifier) ?? throw new global::System.InvalidOperationException("Identifier cannot be null."), (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.FirstArg) ?? throw new global::System.InvalidOperationException("FirstArg cannot be null."), (global::Tsu.Trees.RedGreen.Sample.ExpressionSample?)Visit(node.SecondArg));
}
public static class SampleFactory
{
public static global::Tsu.Trees.RedGreen.Sample.IdentifierExpressionSample IdentifierExpression(global::System.String name) =>
Expand Down
6 changes: 6 additions & 0 deletions Tsu.Trees.RedGreen/sourcegen/GreenTreeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ public static void RegisterGreenOutput(this IncrementalGeneratorInitializationCo
writer.WriteWalker(tree, tree.GreenBase);
}

if (tree.CreateRewriter)
{
writer.WriteLineNoTabs("");
writer.WriteRewriter(tree, tree.RedBase);
}

writer.Indent--;
writer.WriteLine('}');
writer.WriteLineNoTabs("");
Expand Down
5 changes: 5 additions & 0 deletions Tsu.Trees.RedGreen/sourcegen/RedTreeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ public static void RegisterRedMainOutput(this IncrementalGeneratorInitialization
writer.WriteLineNoTabs("");
}

if (tree.CreateRewriter)
{
writer.WriteLineNoTabs("");
writer.WriteRewriter(tree, tree.RedBase);
}

writer.WriteRedFactory(tree);
}
Expand Down
70 changes: 70 additions & 0 deletions Tsu.Trees.RedGreen/sourcegen/VisitorGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,74 @@ protected override void DefaultVisit({{baseType.ToCSharpString()}} node)
}
""");
}

public static void WriteRewriter(this IndentedTextWriter writer, Tree tree, INamedTypeSymbol baseType)
{
if (!tree.CreateVisitors)
{
writer.WriteVisitor(tree, baseType, 1);
writer.WriteLineNoTabs("");
}

writer.WriteLine("{0} partial class {1}Rewriter : {2}.{1}Visitor<{3}>",
baseType.DeclaredAccessibility.ToCSharpString(),
tree.Suffix,
baseType.ContainingNamespace.ToCSharpString(true),
baseType.ToCSharpString(false));
writer.WriteLine('{');
writer.Indent++;
{
var queue = new Queue<Node>();
foreach (var desc in tree.Root.Descendants)
queue.Enqueue(desc);

while (queue.Count > 0)
{
var node = queue.Dequeue();
if (node.Descendants.Any())
{
foreach (var desc in node.Descendants)
queue.Enqueue(desc);
}
else
{
writer.WriteLine("public override {0} Visit{1}({2}.{3} node) =>",
baseType.ToCSharpString(),
node.TypeSymbol.Name.WithoutSuffix(tree.Suffix),
baseType.ContainingNamespace.ToCSharpString(false),
node.TypeSymbol.Name);
writer.Indent++;
{
writer.Write("node.Update(");
var first = true;
foreach (var component in node.RequiredComponents)
{
if (!first) writer.Write(", ");
first = false;

if (component.Type.DerivesFrom(tree.GreenBase))
{
writer.Write("({0}.{1}?)Visit(node.{2})",
baseType.ContainingNamespace.ToCSharpString(false),
component.Type.Name,
component.PropertyName);
if (!component.IsOptional)
{
writer.Write(" ?? throw new global::System.InvalidOperationException(\"{0} cannot be null.\")", component.PropertyName);
}
}
else
{
writer.Write("node.{0}", component.PropertyName);
}
}
writer.WriteLine(");");
}
writer.Indent--;
}
}
}
writer.Indent--;
writer.WriteLine('}');
}
}

0 comments on commit 2d68e46

Please sign in to comment.