I thought I'd share this short summary in case it helps anyone interested in contributing to the new zig compiler. It's a small example working with the Parser and s-expressions with our snapshot tool.
I started by translating the old test_syntax snapshot from crates/compiler/test_syntax/tests/snapshots/pass/add_var_with_spaces.expr.roc
to soemthing like the below at src/snapshots/if_then_else.txt
~~~META
description=Correct formatting for if-then-else statement
~~~SOURCE
module [foo]
foo =
if
h
then
A
else &e
s#
~~~FORMATTED
module [foo]
foo =
if
h
then
A
else
&e
s #
However, running the snapshot tool zig build snapshot
gave me an error ...
thread 2240469 panic: TODO: problem for no else UpperIdent@14
/Users/luke/Documents/GitHub/roc/src/check/parse/Parser.zig:868:32: 0x1007758c7 in parseExprWithBp (snapshot)
I expected to run into something like this. The issue here I think is that we've changed the syntax for if-then-else
.
This snapshot is no longer relevant at least in it's current form.
So I modified it to use the new syntax taking inspiration from Anthony's "grab bag" unit test and used deliberately using sloppy formatting so I can validate the formatting also.
~~~META
description=Example if-then-else statement
~~~SOURCE
module [foo]
foo = if true A
else {
B
}
However running it with zig build snapshot
gave errors telling me I had unimplemented paths for generating a s-expression.
Following the compiler errors like a bouncing ball, I implemented those.
Here's what I wrote.
// (tag <tag>)
.tag => |tag| {
var node = sexpr.Expr.init(env.gpa, "tag");
node.appendStringChild(env.gpa, ir.resolve(tag.token));
return node;
},
// (if_then_else <condition> <then> <else>)
.if_then_else => |stmt| {
var node = sexpr.Expr.init(env.gpa, "if_then_else");
var condition = ir.store.getExpr(stmt.condition).toSExpr(env, ir);
var then = ir.store.getExpr(stmt.then).toSExpr(env, ir);
var else_ = ir.store.getExpr(stmt.@"else").toSExpr(env, ir);
node.appendNodeChild(env.gpa, &condition);
node.appendNodeChild(env.gpa, &then);
node.appendNodeChild(env.gpa, &else_);
return node;
},
Finally running the snapshot tool gave me the following final golden output which I can commit to the repository. You can see it now includes the FORMATTED and PARSE sections which were generated from the SOURCE.
~~~META
description=Example if-then-else statement
~~~SOURCE
module [foo]
foo = if true A
else {
B
}
~~~FORMATTED
module [foo]
foo = if true A else B
~~~PARSE
(file
(header 'foo')
(decl
(ident 'foo')
(if_then_else
(ident '' 'true')
(tag 'A')
(block (tag 'B')))))
Relevant commit https://github.com/roc-lang/roc/pull/7669/commits/7d793aa6ee0e933a7d021f80df78fa554d7a5e9f
Last updated: Jul 06 2025 at 12:14 UTC