Generate pattern-matching nodes

This commit is contained in:
Brandon Dyck 2023-07-02 14:56:50 -06:00
parent 82d911d5dd
commit ef3de7a707
3 changed files with 91 additions and 24 deletions

View File

@ -8,9 +8,9 @@
namespace Finn.AST; namespace Finn.AST;
public abstract record Expr() { public abstract record Expr() {
public abstract T accept<T>(IVisitor<T> visitor); public abstract T accept<T>(IExprVisitor<T> visitor);
} }
public interface IVisitor<T> { public interface IExprVisitor<T> {
T visitSequenceExpr(Sequence expr); T visitSequenceExpr(Sequence expr);
T visitBinaryExpr(Binary expr); T visitBinaryExpr(Binary expr);
T visitGroupingExpr(Grouping expr); T visitGroupingExpr(Grouping expr);
@ -27,91 +27,91 @@ public interface IVisitor<T> {
} }
public partial record Sequence(Expr Left, Expr Right) : Expr() public partial record Sequence(Expr Left, Expr Right) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitSequenceExpr(this); return visitor.visitSequenceExpr(this);
} }
} }
public partial record Binary(Expr Left, Token Op, Expr Right) : Expr() public partial record Binary(Expr Left, Token Op, Expr Right) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitBinaryExpr(this); return visitor.visitBinaryExpr(this);
} }
} }
public partial record Grouping(Expr Expression) : Expr() public partial record Grouping(Expr Expression) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitGroupingExpr(this); return visitor.visitGroupingExpr(this);
} }
} }
public partial record Literal(System.Object Value) : Expr() public partial record Literal(System.Object Value) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitLiteralExpr(this); return visitor.visitLiteralExpr(this);
} }
} }
public partial record Unary(Token Op, Expr Right) : Expr() public partial record Unary(Token Op, Expr Right) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitUnaryExpr(this); return visitor.visitUnaryExpr(this);
} }
} }
public partial record If(Expr Condition, Expr Then, Expr Else) : Expr() public partial record If(Expr Condition, Expr Then, Expr Else) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitIfExpr(this); return visitor.visitIfExpr(this);
} }
} }
public partial record Identifier(Name Value) : Expr() public partial record Identifier(Name Value) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitIdentifierExpr(this); return visitor.visitIdentifierExpr(this);
} }
} }
public partial record List(Expr[] Elements) : Expr() public partial record List(Expr[] Elements) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitListExpr(this); return visitor.visitListExpr(this);
} }
} }
public partial record Variant(Name Tag, Expr? Argument) : Expr() public partial record Variant(Name Tag, Expr? Argument) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitVariantExpr(this); return visitor.visitVariantExpr(this);
} }
} }
public partial record Record(Field[] Extensions, BaseRecord? Base) : Expr() public partial record Record(Field[] Extensions, BaseRecord? Base) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitRecordExpr(this); return visitor.visitRecordExpr(this);
} }
} }
public partial record Selector(Expr Left, Name FieldName) : Expr() public partial record Selector(Expr Left, Name FieldName) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitSelectorExpr(this); return visitor.visitSelectorExpr(this);
} }
} }
public partial record Indexer(Expr Left, Expr Index) : Expr() public partial record Indexer(Expr Left, Expr Index) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitIndexerExpr(this); return visitor.visitIndexerExpr(this);
} }
} }
public partial record Call(Expr Left, Expr?[] Arguments) : Expr() public partial record Call(Expr Left, Expr?[] Arguments) : Expr()
{ {
public override T accept<T>(IVisitor<T> visitor) public override T accept<T>(IExprVisitor<T> visitor)
{ {
return visitor.visitCallExpr(this); return visitor.visitCallExpr(this);
} }

46
Pattern.g.cs Normal file
View File

@ -0,0 +1,46 @@
////////////////////////////////////////////////////////////
// THIS FILE IS GENERATED. //
// DO NOT EDIT. //
////////////////////////////////////////////////////////////
#nullable enable
namespace Finn.AST;
public abstract record Pattern() {
public abstract T accept<T>(IPatternVisitor<T> visitor);
}
public interface IPatternVisitor<T> {
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<T>(IPatternVisitor<T> visitor)
{
return visitor.visitIdentifierPatternPattern(this);
}
}
public partial record VariantPattern(Name Tag, Pattern? Argument) : Pattern()
{
public override T accept<T>(IPatternVisitor<T> visitor)
{
return visitor.visitVariantPatternPattern(this);
}
}
public partial record FieldPattern(Name Name, Pattern? Pattern) : Pattern()
{
public override T accept<T>(IPatternVisitor<T> visitor)
{
return visitor.visitFieldPatternPattern(this);
}
}
public partial record RecordPattern(FieldPattern[] Fields, IdentifierPattern Rest) : Pattern()
{
public override T accept<T>(IPatternVisitor<T> visitor)
{
return visitor.visitRecordPatternPattern(this);
}
}

View File

@ -1,7 +1,7 @@
type Field = { Type: string; Name: string } type Field = { Type: string; Name: string }
type Type = { Name: string; Fields: list<Field> } type Type = { Name: string; Fields: list<Field> }
let types = let exprTypes =
[ { Name = "Sequence" [ { Name = "Sequence"
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Right" } ] } Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Right" } ] }
{ Name = "Binary" { Name = "Binary"
@ -40,10 +40,24 @@ let types =
{ Name = "Call" { Name = "Call"
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr?[]"; Name = "Arguments" } ] } ] 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 visitorMethod baseName t = $"visit{t.Name}{baseName}"
let renderIVisitor (sw: System.IO.StreamWriter) (baseName: string) types = let renderIVisitor (sw: System.IO.StreamWriter) (baseName: string) types =
sw.Write($"public interface IVisitor<T> {{\n") sw.Write($"public interface I{baseName}Visitor<T> {{\n")
for t in types do for t in types do
sw.Write($"\tT {visitorMethod baseName t}({t.Name} {baseName.ToLower()});\n") 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 renderType (sw: System.IO.StreamWriter) baseName t =
let writeField i field = let writeField i field =
if i > 0 then sw.Write(", ") if i > 0 then
sw.Write(", ")
sw.Write $"{field.Type} {field.Name}" sw.Write $"{field.Type} {field.Name}"
sw.Write $"public partial record {t.Name}(" sw.Write $"public partial record {t.Name}("
List.iteri writeField t.Fields List.iteri writeField t.Fields
sw.Write $") : {baseName}()
{{\n"
sw.Write sw.Write
$"\tpublic override T accept<T>(IVisitor<T> visitor) $") : {baseName}()
{{\n"
sw.Write
$"\tpublic override T accept<T>(I{baseName}Visitor<T> visitor)
\t{{ \t{{
\t\treturn visitor.{visitorMethod baseName t}(this); \t\treturn visitor.{visitorMethod baseName t}(this);
\t}}\n" \t}}\n"
@ -81,10 +101,11 @@ let renderAST outputDir baseName types =
namespace Finn.AST; namespace Finn.AST;
public abstract record {baseName}() {{ public abstract record {baseName}() {{
\tpublic abstract T accept<T>(IVisitor<T> visitor); \tpublic abstract T accept<T>(I{baseName}Visitor<T> visitor);
}}\n" }}\n"
renderIVisitor sw baseName types renderIVisitor sw baseName types
List.iter (renderType sw baseName) types List.iter (renderType sw baseName) types
renderAST "." "Expr" types renderAST "." "Expr" exprTypes
renderAST "." "Pattern" patternTypes