Improve Zig AST developer experience

- Convert string-based type discrimination to type-safe enums
  - ContainerKind (struct, enum, union, opaque)
  - LiteralKind (int, float, string, char)
  - LoopKind (for, while)
- Remove duplicate AST nodes (consolidated init lists, removed unused types)
- Add comprehensive helper functions for all AST constructions
- Implement formatters for all AST nodes (expressions, statements, types)
- Add typed literal constructors: IntLit, FloatLit, StringLit, CharLit
- Improve documentation and add deprecation notices

This makes the AST more intuitive and type-safe for developers.
This commit is contained in:
2025-06-05 21:07:02 -05:00
parent 258b3c8e9b
commit 2af696078d
4 changed files with 339 additions and 129 deletions

View File

@@ -63,7 +63,7 @@ fn main() void {
{
Decl: zig.DeclareGlobalVar("std", zig.Call(
zig.Id("@import"),
zig.Lit("string", "std"),
zig.StringLit("std"),
), zig.GlobalVarConst),
},
{
@@ -77,7 +77,7 @@ fn main() void {
zig.FieldAccess(zig.Id("std"), "debug"),
"print",
),
zig.Lit("string", `Hello, world!\n`),
zig.StringLit(`Hello, world!\n`),
zig.InitList(),
),
),
@@ -144,7 +144,7 @@ test "processData" {
zig.ErrorUnionType(zig.Id("ProcessError"), zig.Id("i32")),
zig.NewBlock(
// var result: i32 = 0;
zig.DeclareVarStmt(false, []string{"result"}, zig.Id("i32"), zig.Lit("int", "0")),
zig.DeclareVarStmt(false, []string{"result"}, zig.Id("i32"), zig.IntLit("0")),
// defer std.debug.print("Cleanup\n", .{});
zig.Defer(
zig.NewExprStmt(
@@ -153,7 +153,7 @@ test "processData" {
zig.FieldAccess(zig.Id("std"), "debug"),
"print",
),
zig.Lit("string", `Cleanup\n`),
zig.StringLit(`Cleanup\n`),
zig.InitList(),
),
),
@@ -162,7 +162,7 @@ test "processData" {
zig.ForLoop(
[]zig.ForArg{
zig.ForArgExpr(zig.Id("values")),
{Expr: zig.Lit("int", "0"), From: zig.Lit("", "")},
{Expr: zig.IntLit("0"), From: zig.IntLit("")},
},
zig.PayloadNames([]string{"opt_val", "idx"}, []bool{false, false}),
zig.NewBlockStmt(
@@ -178,8 +178,8 @@ test "processData" {
zig.Prong(
[]*zig.SwitchCase{
zig.Case(
zig.Unary("-", zig.Lit("int", "10")),
zig.Unary("-", zig.Lit("int", "1")),
zig.Unary("-", zig.IntLit("10")),
zig.Unary("-", zig.IntLit("1")),
),
},
nil,
@@ -193,7 +193,7 @@ test "processData" {
// 0 => continue,
zig.Prong(
[]*zig.SwitchCase{
zig.Case(zig.Lit("int", "0"), nil),
zig.Case(zig.IntLit("0"), nil),
},
nil,
zig.Continue(""),
@@ -201,12 +201,12 @@ test "processData" {
// 1...10 => { ... }
zig.Prong(
[]*zig.SwitchCase{
zig.Case(zig.Lit("int", "1"), zig.Lit("int", "10")),
zig.Case(zig.IntLit("1"), zig.IntLit("10")),
},
nil,
zig.NewBlockStmt(
zig.If(
zig.Binary(">", zig.Id("idx"), zig.Lit("int", "3")),
zig.Binary(">", zig.Id("idx"), zig.IntLit("3")),
zig.Break("", nil),
nil,
),
@@ -228,7 +228,7 @@ test "processData" {
// else block
zig.NewBlockStmt(
zig.If(
zig.Binary("==", zig.Id("idx"), zig.Lit("int", "0")),
zig.Binary("==", zig.Id("idx"), zig.IntLit("0")),
zig.Return(zig.FieldAccess(zig.Id("ProcessError"), "InvalidInput")),
nil,
),
@@ -241,7 +241,7 @@ test "processData" {
// if (values[0] == null) { unreachable; }
zig.If(
zig.Binary("==",
zig.Index(zig.Id("values"), zig.Lit("int", "0")),
zig.Index(zig.Id("values"), zig.IntLit("0")),
zig.Id("null"),
),
zig.NewBlockStmt(
@@ -253,7 +253,7 @@ test "processData" {
zig.Return(zig.Id("result")),
),
[]*zig.ParamDecl{
zig.Param("values", zig.ArrayType(zig.Lit("int", "5"), zig.OptionalType(zig.Id("i32")))),
zig.Param("values", zig.ArrayType(zig.IntLit("5"), zig.OptionalType(zig.Id("i32")))),
},
0,
),
@@ -265,11 +265,11 @@ test "processData" {
zig.DeclareVarStmt(true, []string{"data"}, nil,
&zig.InitListExpr{
Values: []zig.Expr{
zig.Lit("int", "5"),
zig.Unary("-", zig.Lit("int", "3")),
zig.Lit("int", "0"),
zig.IntLit("5"),
zig.Unary("-", zig.IntLit("3")),
zig.IntLit("0"),
zig.Id("null"),
zig.Lit("int", "10"),
zig.IntLit("10"),
},
},
),
@@ -288,7 +288,7 @@ test "processData" {
zig.Call(
zig.Id("@as"),
zig.Id("i32"),
zig.Lit("int", "8"),
zig.IntLit("8"),
),
zig.Id("result"),
),
@@ -328,7 +328,7 @@ pub fn main() !void {
Decl: zig.DeclareGlobalVar("std",
zig.Call(
zig.Id("@import"),
zig.Lit("string", "std"),
zig.StringLit("std"),
),
zig.GlobalVarConst,
),
@@ -353,26 +353,24 @@ pub fn main() !void {
),
),
// var i: i32 = 1;
zig.DeclareVarStmt(false, []string{"i"}, zig.Id("i32"), zig.Lit("int", "1")),
zig.DeclareVarStmt(false, []string{"i"}, zig.Id("i32"), zig.IntLit("1")),
// while (i <= 5) : (i += 1) { ... }
&zig.LoopStmt{
Kind: "while",
Prefix: &zig.WhilePrefix{
Cond: zig.Binary("<=", zig.Id("i"), zig.Lit("int", "5")),
Continue: zig.Binary("+=", zig.Id("i"), zig.Lit("int", "1")),
},
Body: zig.NewBlockStmt(
zig.WhileLoop(
zig.Binary("<=", zig.Id("i"), zig.IntLit("5")),
zig.Binary("+=", zig.Id("i"), zig.IntLit("1")),
nil,
zig.NewBlockStmt(
&zig.IfStmt{
Cond: zig.Binary("==",
zig.Binary("%", zig.Id("i"), zig.Lit("int", "2")),
zig.Lit("int", "0"),
zig.Binary("%", zig.Id("i"), zig.IntLit("2")),
zig.IntLit("0"),
),
Then: zig.NewBlockStmt(
zig.NewExprStmt(
zig.Try(
zig.Call(
zig.FieldAccess(zig.Id("stdout"), "writeAll"),
zig.Lit("string", `even: {d}\n`),
zig.StringLit(`even: {d}\n`),
zig.InitList(zig.Id("i")),
),
),
@@ -383,7 +381,7 @@ pub fn main() !void {
zig.Try(
zig.Call(
zig.FieldAccess(zig.Id("stdout"), "writeAll"),
zig.Lit("string", `odd: {d}\n`),
zig.StringLit(`odd: {d}\n`),
zig.InitList(zig.Id("i")),
),
),
@@ -391,7 +389,8 @@ pub fn main() !void {
),
},
),
},
nil,
),
),
nil,
zig.FnExport,
@@ -430,7 +429,7 @@ func TestStructWithFieldsAndMethod(t *testing.T) {
zig.NewExprStmt(
zig.Binary("=",
zig.FieldAccess(zig.Id("self"), "count"),
zig.Lit("int", "0"),
zig.IntLit("0"),
),
),
),