From ef3de7a707acd0ee6094702ec04e9e8abdfce1a7 Mon Sep 17 00:00:00 2001 From: Brandon Dyck Date: Sun, 2 Jul 2023 14:56:50 -0600 Subject: [PATCH] Generate pattern-matching nodes --- Expr.g.cs | 30 +++++++++++++++--------------- Pattern.g.cs | 46 ++++++++++++++++++++++++++++++++++++++++++++++ ast_classes.fsx | 39 ++++++++++++++++++++++++++++++--------- 3 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 Pattern.g.cs diff --git a/Expr.g.cs b/Expr.g.cs index d517e1a..c14052d 100644 --- a/Expr.g.cs +++ b/Expr.g.cs @@ -8,9 +8,9 @@ namespace Finn.AST; public abstract record Expr() { - public abstract T accept(IVisitor visitor); + public abstract T accept(IExprVisitor visitor); } -public interface IVisitor { +public interface IExprVisitor { T visitSequenceExpr(Sequence expr); T visitBinaryExpr(Binary expr); T visitGroupingExpr(Grouping expr); @@ -27,91 +27,91 @@ public interface IVisitor { } public partial record Sequence(Expr Left, Expr Right) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitSequenceExpr(this); } } public partial record Binary(Expr Left, Token Op, Expr Right) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitBinaryExpr(this); } } public partial record Grouping(Expr Expression) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitGroupingExpr(this); } } public partial record Literal(System.Object Value) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitLiteralExpr(this); } } public partial record Unary(Token Op, Expr Right) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitUnaryExpr(this); } } public partial record If(Expr Condition, Expr Then, Expr Else) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitIfExpr(this); } } public partial record Identifier(Name Value) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitIdentifierExpr(this); } } public partial record List(Expr[] Elements) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitListExpr(this); } } public partial record Variant(Name Tag, Expr? Argument) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitVariantExpr(this); } } public partial record Record(Field[] Extensions, BaseRecord? Base) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitRecordExpr(this); } } public partial record Selector(Expr Left, Name FieldName) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitSelectorExpr(this); } } public partial record Indexer(Expr Left, Expr Index) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitIndexerExpr(this); } } public partial record Call(Expr Left, Expr?[] Arguments) : Expr() { - public override T accept(IVisitor visitor) + public override T accept(IExprVisitor visitor) { return visitor.visitCallExpr(this); } diff --git a/Pattern.g.cs b/Pattern.g.cs new file mode 100644 index 0000000..6c449fd --- /dev/null +++ b/Pattern.g.cs @@ -0,0 +1,46 @@ +//////////////////////////////////////////////////////////// +// THIS FILE IS GENERATED. // +// DO NOT EDIT. // +//////////////////////////////////////////////////////////// + +#nullable enable + +namespace Finn.AST; + +public abstract record Pattern() { + public abstract T accept(IPatternVisitor visitor); +} +public interface IPatternVisitor { + T visitIdentifierPatternPattern(IdentifierPattern pattern); + T visitVariantPatternPattern(VariantPattern pattern); + T visitFieldPatternPattern(FieldPattern pattern); + T visitRecordPatternPattern(RecordPattern pattern); +} +public partial record IdentifierPattern(Name? Identifier) : Pattern() +{ + public override T accept(IPatternVisitor visitor) + { + return visitor.visitIdentifierPatternPattern(this); + } +} +public partial record VariantPattern(Name Tag, Pattern? Argument) : Pattern() +{ + public override T accept(IPatternVisitor visitor) + { + return visitor.visitVariantPatternPattern(this); + } +} +public partial record FieldPattern(Name Name, Pattern? Pattern) : Pattern() +{ + public override T accept(IPatternVisitor visitor) + { + return visitor.visitFieldPatternPattern(this); + } +} +public partial record RecordPattern(FieldPattern[] Fields, IdentifierPattern Rest) : Pattern() +{ + public override T accept(IPatternVisitor visitor) + { + return visitor.visitRecordPatternPattern(this); + } +} diff --git a/ast_classes.fsx b/ast_classes.fsx index e19018a..750ed0d 100644 --- a/ast_classes.fsx +++ b/ast_classes.fsx @@ -1,7 +1,7 @@ type Field = { Type: string; Name: string } type Type = { Name: string; Fields: list } -let types = +let exprTypes = [ { Name = "Sequence" Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Right" } ] } { Name = "Binary" @@ -40,10 +40,24 @@ let types = { Name = "Call" Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr?[]"; Name = "Arguments" } ] } ] +let patternTypes = + [ { Name = "IdentifierPattern" + Fields = [ { Type = "Name?"; Name = "Identifier" } ] } + { Name = "VariantPattern" + Fields = [ { Type = "Name"; Name = "Tag" }; { Type = "Pattern?"; Name = "Argument" } ] } + { Name = "FieldPattern" + Fields = [ { Type = "Name"; Name = "Name" }; { Type = "Pattern?"; Name = "Pattern" } ] } + { Name = "RecordPattern" + Fields = + [ { Type = "FieldPattern[]" + Name = "Fields" } + { Type = "IdentifierPattern" + Name = "Rest" } ] } ] + let visitorMethod baseName t = $"visit{t.Name}{baseName}" let renderIVisitor (sw: System.IO.StreamWriter) (baseName: string) types = - sw.Write($"public interface IVisitor {{\n") + sw.Write($"public interface I{baseName}Visitor {{\n") for t in types do sw.Write($"\tT {visitorMethod baseName t}({t.Name} {baseName.ToLower()});\n") @@ -52,14 +66,20 @@ let renderIVisitor (sw: System.IO.StreamWriter) (baseName: string) types = let renderType (sw: System.IO.StreamWriter) baseName t = let writeField i field = - if i > 0 then sw.Write(", ") - sw.Write $"{field.Type} {field.Name}" + if i > 0 then + sw.Write(", ") + + sw.Write $"{field.Type} {field.Name}" + sw.Write $"public partial record {t.Name}(" List.iteri writeField t.Fields - sw.Write $") : {baseName}() -{{\n" + sw.Write - $"\tpublic override T accept(IVisitor visitor) + $") : {baseName}() +{{\n" + + sw.Write + $"\tpublic override T accept(I{baseName}Visitor visitor) \t{{ \t\treturn visitor.{visitorMethod baseName t}(this); \t}}\n" @@ -81,10 +101,11 @@ let renderAST outputDir baseName types = namespace Finn.AST; public abstract record {baseName}() {{ -\tpublic abstract T accept(IVisitor visitor); +\tpublic abstract T accept(I{baseName}Visitor visitor); }}\n" renderIVisitor sw baseName types List.iter (renderType sw baseName) types -renderAST "." "Expr" types +renderAST "." "Expr" exprTypes +renderAST "." "Pattern" patternTypes