Set up AST class generation
This commit is contained in:
parent
f3e99ee76d
commit
e27c6c6165
52
Expr.g.cs
Normal file
52
Expr.g.cs
Normal file
@ -0,0 +1,52 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS GENERATED. //
|
||||
// DO NOT EDIT. //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
namespace Finn.AST;
|
||||
|
||||
public abstract class Expr {
|
||||
public abstract T accept<T>(IVisitor<T> visitor);
|
||||
}
|
||||
public interface IVisitor<T> {
|
||||
T visitBinaryExpr(Binary expr);
|
||||
T visitGroupingExpr(Grouping expr);
|
||||
T visitLiteralExpr(Literal expr);
|
||||
T visitUnaryExpr(Unary expr);
|
||||
}
|
||||
public class Binary : Expr
|
||||
{
|
||||
public required Expr Left { get; init; }
|
||||
public required Token Op { get; init; }
|
||||
public required Expr Right { get; init; }
|
||||
public override T accept<T>(IVisitor<T> visitor)
|
||||
{
|
||||
return visitor.visitBinaryExpr(this);
|
||||
}
|
||||
}
|
||||
public class Grouping : Expr
|
||||
{
|
||||
public required Expr Expression { get; init; }
|
||||
public override T accept<T>(IVisitor<T> visitor)
|
||||
{
|
||||
return visitor.visitGroupingExpr(this);
|
||||
}
|
||||
}
|
||||
public class Literal : Expr
|
||||
{
|
||||
public required System.Object Value { get; init; }
|
||||
public override T accept<T>(IVisitor<T> visitor)
|
||||
{
|
||||
return visitor.visitLiteralExpr(this);
|
||||
}
|
||||
}
|
||||
public class Unary : Expr
|
||||
{
|
||||
public required Token Op { get; init; }
|
||||
public required Expr Right { get; init; }
|
||||
public override T accept<T>(IVisitor<T> visitor)
|
||||
{
|
||||
return visitor.visitUnaryExpr(this);
|
||||
}
|
||||
}
|
65
ast_classes.fsx
Normal file
65
ast_classes.fsx
Normal file
@ -0,0 +1,65 @@
|
||||
type Field = { Type: string; Name: string }
|
||||
type Type = { Name: string; Fields: list<Field> }
|
||||
|
||||
let types =
|
||||
[ { Name = "Binary"
|
||||
Fields =
|
||||
[ { Type = "Expr"; Name = "Left" }
|
||||
{ Type = "Token"; Name = "Op" }
|
||||
{ Type = "Expr"; Name = "Right" } ] }
|
||||
{ Name = "Grouping"
|
||||
Fields = [ { Type = "Expr"; Name = "Expression" } ] }
|
||||
{ Name = "Literal"
|
||||
Fields =
|
||||
[ { Type = "System.Object"
|
||||
Name = "Value" } ] }
|
||||
{ Name = "Unary"
|
||||
Fields = [ { Type = "Token"; Name = "Op" }; { Type = "Expr"; Name = "Right" } ] } ]
|
||||
|
||||
let visitorMethod baseName t = $"visit{t.Name}{baseName}"
|
||||
|
||||
let renderIVisitor (sw: System.IO.StreamWriter) (baseName: string) types =
|
||||
sw.Write($"public interface IVisitor<T> {{\n")
|
||||
|
||||
for t in types do
|
||||
sw.Write($"\tT {visitorMethod baseName t}({t.Name} {baseName.ToLower()});\n")
|
||||
|
||||
sw.Write("}\n")
|
||||
|
||||
let renderType (sw: System.IO.StreamWriter) baseName t =
|
||||
sw.Write
|
||||
$"public class {t.Name} : {baseName}
|
||||
{{\n"
|
||||
|
||||
for f in t.Fields do
|
||||
sw.Write $"\tpublic required {f.Type} {f.Name} {{ get; init; }}\n"
|
||||
|
||||
sw.Write
|
||||
$"\tpublic override T accept<T>(IVisitor<T> visitor)
|
||||
\t{{
|
||||
\t\treturn visitor.{visitorMethod baseName t}(this);
|
||||
\t}}\n"
|
||||
|
||||
sw.Write("}\n")
|
||||
|
||||
let renderAST outputDir baseName types =
|
||||
let path = System.IO.Path.Combine(outputDir, baseName + ".g.cs")
|
||||
use sw = new System.IO.StreamWriter(path)
|
||||
|
||||
sw.Write
|
||||
$"////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS GENERATED. //
|
||||
// DO NOT EDIT. //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
using System;
|
||||
namespace Finn.AST;
|
||||
|
||||
public abstract class {baseName} {{
|
||||
\tpublic abstract T accept<T>(IVisitor<T> visitor);
|
||||
}}\n"
|
||||
|
||||
renderIVisitor sw baseName types
|
||||
List.iter (renderType sw baseName) types
|
||||
|
||||
renderAST "." "Expr" types
|
@ -5,4 +5,7 @@
|
||||
<RootNamespace>Finn</RootNamespace>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<Target Name="GenerateASTClasses" BeforeTargets="BeforeBuild">
|
||||
<Exec Command="dotnet fsi .\ast_classes.fsx" />
|
||||
</Target>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user