finn-lang/ast_classes.fsx

119 lines
4.1 KiB
Plaintext
Raw Normal View History

2023-06-25 01:15:37 +00:00
type Field = { Type: string; Name: string }
type Type = { Name: string; Fields: list<Field> }
2023-07-02 20:56:50 +00:00
let exprTypes =
2023-06-28 23:18:31 +00:00
[ { Name = "Sequence"
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Right" } ] }
{ Name = "Binary"
2023-06-25 01:15:37 +00:00
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"
2023-06-28 22:26:08 +00:00
Fields = [ { Type = "Token"; Name = "Op" }; { Type = "Expr"; Name = "Right" } ] }
{ Name = "If"
Fields =
[ { Type = "Expr"; Name = "Condition" }
{ Type = "Expr"; Name = "Then" }
{ Type = "Expr"; Name = "Else" } ] }
2023-07-08 03:29:17 +00:00
{ Name = "Variable"
Fields = [ { Type = "Name"; Name = "Value" } ] }
2023-07-02 05:13:24 +00:00
{ Name = "List"
Fields = [ { Type = "Expr[]"; Name = "Elements" } ] }
2023-07-02 05:30:24 +00:00
{ Name = "Variant"
Fields = [ { Type = "Name"; Name = "Tag" }; { Type = "Expr?"; Name = "Argument" } ] }
2023-07-02 17:38:48 +00:00
{ Name = "Record"
Fields =
2023-07-02 17:46:18 +00:00
[ { Type = "Field[]"
Name = "Extensions" }
2023-07-02 17:38:48 +00:00
{ Type = "BaseRecord?"; Name = "Base" } ] }
{ Name = "Selector"
2023-07-02 17:46:18 +00:00
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Name"; Name = "FieldName" } ] }
{ Name = "Indexer"
2023-07-02 18:05:46 +00:00
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr"; Name = "Index" } ] }
{ Name = "Call"
Fields = [ { Type = "Expr"; Name = "Left" }; { Type = "Expr?[]"; Name = "Arguments" } ] }
{ Name = "Let"
Fields =
[ { Type = "Binding[]"
Name = "Bindings" }
2023-07-05 14:52:14 +00:00
{ Type = "Expr"; Name = "Body" } ] }
{ Name = "When"
Fields = [ { Type = "Expr"; Name = "Head" }; { Type = "Binding[]"; Name = "Cases" } ] } ]
2023-06-25 01:15:37 +00:00
2023-07-02 20:56:50 +00:00
let patternTypes =
[ { Name = "SimplePattern"
2023-07-02 20:56:50 +00:00
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 = "SimplePattern?"
2023-07-02 20:56:50 +00:00
Name = "Rest" } ] } ]
2023-06-25 01:15:37 +00:00
let visitorMethod baseName t = $"visit{t.Name}{baseName}"
let renderIVisitor (sw: System.IO.StreamWriter) (baseName: string) types =
sw.Write($"public interface I{baseName}Visitor<TContext, TResult> {{\n")
2023-06-25 01:15:37 +00:00
for t in types do
sw.Write($"\tTResult {visitorMethod baseName t}(TContext context, {t.Name} {baseName.ToLower()});\n")
2023-06-25 01:15:37 +00:00
sw.Write("}\n")
let renderType (sw: System.IO.StreamWriter) baseName t =
2023-07-02 20:27:12 +00:00
let writeField i field =
2023-07-02 20:56:50 +00:00
if i > 0 then
sw.Write(", ")
sw.Write $"{field.Type} {field.Name}"
2023-07-02 20:27:12 +00:00
sw.Write $"public partial record {t.Name}("
List.iteri writeField t.Fields
2023-07-02 20:56:50 +00:00
sw.Write
$") : {baseName}()
2023-06-25 01:15:37 +00:00
{{\n"
2023-07-02 20:56:50 +00:00
2023-06-25 01:15:37 +00:00
sw.Write
$"\tpublic override TResult accept<TContext, TResult>(TContext context, I{baseName}Visitor<TContext, TResult> visitor)
2023-06-25 01:15:37 +00:00
\t{{
\t\treturn visitor.{visitorMethod baseName t}(context, this);
2023-06-25 01:15:37 +00:00
\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. //
////////////////////////////////////////////////////////////
2023-07-02 19:19:42 +00:00
#nullable enable
2023-07-02 05:13:24 +00:00
2023-06-25 01:15:37 +00:00
namespace Finn.AST;
2023-07-02 20:27:12 +00:00
public abstract record {baseName}() {{
\tpublic abstract TResult accept<TContext, TResult>(TContext context, I{baseName}Visitor<TContext, TResult> visitor);
2023-06-25 01:15:37 +00:00
}}\n"
renderIVisitor sw baseName types
List.iter (renderType sw baseName) types
2023-07-02 20:56:50 +00:00
renderAST "." "Expr" exprTypes
renderAST "." "Pattern" patternTypes