// ---- parse_test.rg driver (concatenated after lexer.rg + parser.rg) ---- fn ast_kind(n: map) str { return n["kind"]; } const src = "fn fib(n: int) int { if n < 2 { return n; } return fib(n - 1) + fib(n - 2); } var top = 10; const cfg = .{ name = \"r\", lim = 3 }; for v | [1, 2] { top = top + v; }"; const pr = parse(src); assert_eq(ast_kind(pr), "program"); const stmts = pr["stmts"]; assert_eq(len(stmts), 4); const fn0 = stmts[0]; assert_eq(ast_kind(fn0), "fn"); assert_eq(fn0["name"], "fib"); assert_eq(len(fn0["params"]), 1); assert_eq(ast_kind(fn0["body"]), "block"); const body_stmts = fn0["body"]["stmts"]; assert_eq(len(body_stmts), 2); assert_eq(ast_kind(body_stmts[0]), "if"); const ret2 = body_stmts[1]; assert_eq(ast_kind(ret2), "return"); assert_eq(ret2["value"]["kind"], "bin"); assert_eq(ret2["value"]["op"], "+"); assert_eq(ret2["value"]["l"]["kind"], "call"); assert_eq(ret2["value"]["l"]["callee"]["name"], "fib"); assert_eq(ret2["value"]["l"]["args"][0]["op"], "-"); const var1 = stmts[1]; assert_eq(ast_kind(var1), "var"); assert_eq(var1["name"], "top"); const cfg = stmts[2]; assert_eq(ast_kind(cfg), "var"); assert_eq(cfg["value"]["kind"], "map"); assert_eq(cfg["value"]["pairs"][0][0], "name"); assert_eq(cfg["value"]["pairs"][1][1]["text"], "3"); const loop = stmts[3]; assert_eq(ast_kind(loop), "for"); assert_eq(loop["var"], "v"); assert_eq(loop["iter"]["kind"], "array"); assert_eq(ast_kind(loop["body"]), "block"); std.print("parse_test OK ({} stmts)\n", .{len(stmts)});