diff --git a/Expr.g.cs b/Expr.g.cs new file mode 100644 index 0000000..290bbf4 --- /dev/null +++ b/Expr.g.cs @@ -0,0 +1,52 @@ +//////////////////////////////////////////////////////////// +// THIS FILE IS GENERATED. // +// DO NOT EDIT. // +//////////////////////////////////////////////////////////// + +using System; +namespace Finn.AST; + +public abstract class Expr { + public abstract T accept(IVisitor visitor); +} +public interface IVisitor { + 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(IVisitor visitor) + { + return visitor.visitBinaryExpr(this); + } +} +public class Grouping : Expr +{ + public required Expr Expression { get; init; } + public override T accept(IVisitor visitor) + { + return visitor.visitGroupingExpr(this); + } +} +public class Literal : Expr +{ + public required System.Object Value { get; init; } + public override T accept(IVisitor 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(IVisitor visitor) + { + return visitor.visitUnaryExpr(this); + } +} diff --git a/ast_classes.fsx b/ast_classes.fsx new file mode 100644 index 0000000..5b7b09f --- /dev/null +++ b/ast_classes.fsx @@ -0,0 +1,65 @@ +type Field = { Type: string; Name: string } +type Type = { Name: string; Fields: list } + +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 {{\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(IVisitor 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(IVisitor visitor); +}}\n" + + renderIVisitor sw baseName types + List.iter (renderType sw baseName) types + +renderAST "." "Expr" types diff --git a/finn.csproj b/finn.csproj index d4cb908..583aa95 100644 --- a/finn.csproj +++ b/finn.csproj @@ -5,4 +5,7 @@ Finn enable + + + \ No newline at end of file