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;
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 visitBinaryExpr(Binary expr);
T visitGroupingExpr(Grouping expr);
@ -27,91 +27,91 @@ public interface IVisitor<T> {
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}
}
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);
}

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 Type = { Name: string; Fields: list<Field> }
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<T> {{\n")
sw.Write($"public interface I{baseName}Visitor<T> {{\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(", ")
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<T>(IVisitor<T> visitor)
$") : {baseName}()
{{\n"
sw.Write
$"\tpublic override T accept<T>(I{baseName}Visitor<T> 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<T>(IVisitor<T> visitor);
\tpublic abstract T accept<T>(I{baseName}Visitor<T> visitor);
}}\n"
renderIVisitor sw baseName types
List.iter (renderType sw baseName) types
renderAST "." "Expr" types
renderAST "." "Expr" exprTypes
renderAST "." "Pattern" patternTypes