Skip to content

--emit Flags

zolo build runs a full pipeline by default:

.zolo ──parse/typeck──▶ AST ──lower──▶ ZoloIR ──Cranelift──▶ .o ──link──▶ binary
                                        │ --emit ir           │ --emit obj   (default)

The --emit flag lets you stop at any intermediate stage.

--emit ir

--emit ir prints the textual intermediate representation (ZoloIR) to stdout instead of producing a binary. Nothing is written to disk. Useful for understanding how a construct is lowered before codegen, or for debugging the compiler:

zolo build --emit ir shows the ZoloIR for the double function and the call to print.

02-emit-ir.zolo
// Feature: inspect ZoloIR — `zolo build --emit ir`
// Syntax: `zolo build file.zolo --emit ir`
// When to use: see the intermediate representation the native backend
//   lowers to before codegen — handy for debugging codegen or learning
//   how a construct compiles.

// Run:
//   zolo build 30-compilation/02-emit-ir.zolo --emit ir
//
// `--emit ir` prints the textual ZoloIR to stdout instead of producing
// a binary. Nothing is written to disk.

fn double(n: int) -> int {
  return n * 2
}

print(double(21))

// Abbreviated IR for the `print(double(21))` call:
//
//   ; ZoloIR Module
//   ; String pool:
//   ;   s0 = "print"
//   fn @__entry() -> val {
//     entry:
//       %0 = get_global "print"
//       %1 = call @double(21)
//       %2 = call %0(%1)
//       return
//   }
//
// expected (when run normally): 42

Requires the Zolo CLI/host — open in the playground or run locally.

--emit obj

--emit obj compiles the code up to the object file (.o/.obj) and stops before the linking step — no executable is produced. The file is written next to the source. Useful for integration with external toolchains and FFI experiments:

zolo build --emit obj writes 03-emit-obj.o and exits before the link step.

03-emit-obj.zolo
// Feature: object file without linking — `zolo build --emit obj`
// Syntax: `zolo build file.zolo --emit obj`
// When to use: produce a `.o`/`.obj` to hand to an external linker, or
//   to inspect the generated machine code without a full link step.

// Run:
//   zolo build 30-compilation/03-emit-obj.zolo --emit obj
//   # -> Wrote 03-emit-obj.o
//
// `--emit obj` writes the compiled object file next to the source and
// stops before linking — no executable is produced. Useful for FFI
// experiments and toolchain integration.

let xs = [1, 2, 3, 4]
var total = 0
for x in xs {
  total += x
}
print("sum =", total)

// expected (when run): sum =	10

Requires the Zolo CLI/host — open in the playground or run locally.

Challenge

Use --emit ir on the 03-emit-obj.zolo example and observe how the for loop appears in the IR. How does it differ from a regular function call?

enespt-br