---
title: "Omega language reference | AienOS"
description: "The Omega language for agents: program shape, types, declarations, statements, words, OM-2, host words, every compiler error and trap exit code, common mistakes and every gated worked example with its expected output."
last_updated: "2026-10-28"
canonical_url: "https://www.aienos.com/omega/reference/"
---

## Writing Omega programs

This guide is for any agent or person writing .om on any machine. It needs only a clone of
[aien-dev/omega-mv](https://github.com/aien-dev/omega-mv) and of this repository. Every rule
below was observed with a program at the pin in the table; the programs are in
[examples/](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/) and [examples/gate.sh](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/gate.sh) reruns all of them.
For compiler internals, register rules, wire formats and the reasons behind each rule, read
[skills/omega-encoding/SKILL.md](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/skills/omega-encoding/SKILL.md).

Pin Value

omega-mv commit e5b32567a7aff3ce594e3254a622a846a6cd190b

compiler seed/out/omc sha256 2c82480596bbdc50cda9626866209ef662d5834f278f839ff4ce0250c495029f

language reference docs/one_layer/OMEGESE.md at that commit

host Linux AArch64 only; omc writes a static AArch64 Linux ELF

The language reference is normative. Where this guide and OMEGESE disagree, the compiler at the pin
decides; this guide records the known disagreements.

### 1. Compile and run

```
git clone https://github.com/aien-dev/omega-mv && cd omega-mv
git checkout e5b32567a7aff3ce594e3254a622a846a6cd190b
sha256sum seed/out/omc      # must print the pinned hash
sh seed/omega-from-seed.sh  # optional: rebuild omc from the 408-byte loader
seed/out/omc < prog.om > prog; echo "compile $?"
chmod +x prog && ./prog; echo "exit $?"
```

- omc reads the unit on stdin and writes the executable on stdout. Exit 0 means accepted. Any other
exit is the error number, and stderr has one line omc: line N: error K .

- Never run the output of a refused compile : stdout may still hold bytes.

- A unit with fn main is program mode (an executable). A unit without it is function mode (raw
machine words for a host to call); never execute function-mode output directly.

- Check behavior, not compile success: compare stdout bytes and the exit status with what you
expected, and run one deliberately wrong variant to see the check fail.

- To check a whole set the way this repository does:
examples/gate.sh path/to/seed/out/omc prints PASS name or FAIL name: reason per program and
ends GATE PASS examples=N ... or GATE FAIL ... (exit 1); a different compiler hash exits 2.

### 2. Program shape

```
note hello: the smallest complete program
text msg "hello, world\n"
fn main to int
k = write 1 msg 0 len msg
if ne k long len msg
ret 1
end
ret 0
end
```

( [examples/hello.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/hello.om)). The rules it shows:

- One statement per line. No semicolons, no braces. Blocks ( fn , if , else , while , for ,
struct ) close with end . Indentation is optional.

- Prefix words only. Every operation is a word followed by its values: add x 1 ,
mul add a b c , lt i n . Each word has a fixed number of values. Parentheses may group a value
and add nothing: (add a b) .

- Comments are note lines. // and # are refused (error 16).

- fn NAME p1 T1 p2 T2 ... to R , result R a type or void . Parameters fill 6 slots : an
OM-2 unsized view T * / edit T * takes 2 (pointer and count), every other parameter 1 (a
scalar, a sized array, a struct). Two unsized views plus three scalars is error 9
( [examples/om2_param_slots.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/om2_param_slots.om),
mistake_om2_param_slots.om ). fn main to int takes no parameters and its ret value is the exit
status (0..255).

- Assignment is name = value . The first assignment creates the name with the value's type. The
= is optional, which is a trap: return x is accepted as "assign x to a new name return ".

- A function may call a function defined later in the unit, and program-mode functions may recurse.

- Top-level lines are note , fn , text , global , const , struct , and in OM-2 units
layout , abstract , holds and export fn . struct and layout lines come before the first
fn (error 9 after it). A const is visible only after its line.

Every declaration and statement form at the pin (OMEGESE sections 9 to 12 are the full rules):

Form Where Notes

note ANY TEXT any line a comment line

om2 , om2 debug , om2 release , om2 diag , om2 diag debug , om2 diag release first line that is not blank or note opts the unit into OM-2 (section 9); release erases contract checks, diag adds a machine-readable stderr record

om2 fmt the first line, at byte 0 prints the canonical text of the rest of the input instead of compiling it

text NAME "bytes" top level a read-only uchar array

global NAME T N top level, program mode zero-filled array, never an argument

const NAME T LITERAL top level an integer or float value, visible after its line

struct S f1 T1 f2 T2 ... end top level, before the first fn one line; a field f T N is an array of 1..64

layout NAME SIZE , field F T [COUNT] at OFF little / big lines, end OM-2, top level, before the first fn an external byte layout of SIZE 1..4096 bytes

abstract NAME T [ops W ...] , holds NAME dup32 OM-2, top level, before the first fn T uint or ulong ; W from rotr rotl and or xor

fn NAME p1 T1 ... to R ... end top level inline after R in OM-2; export fn marks an OM-2 function-mode entry

parameter p T fn line a scalar

parameter a view T N / a edit T N fn line a sized array, read-only or writable

parameter a view T * / a edit T * fn line, OM-2 an array of any length

parameter s edit T N fresh fn line, OM-2 scratch: every element written before it is read

parameter p view S / p edit S fn line a struct, or an OM-2 layout

parameter o out T N fn line, OM-2 written by the unit; the calling host copies it out after status 0

name = value function body the first assignment creates the name

put A i v , put p f v function body store into an array element or a field

f v1 v2 ... function body a call to a void function

if C ... else ... end function body else is optional; no else if

while C bound N ... end function body N 1..999999

for i T K ... end function body unroll after K in OM-2, K 1..64

break , continue inside a loop

ret , ret v function body ret v in a function with a result

exit N , trap N function body exit status N; trap N 1..14 exits 100+N

requires C , ensures C OM-2, the first lines of a function result names the returned value

invariant C OM-2, the first line of a loop body

### 3. Types and values

Type Meaning

bool true / false , the result of comparisons

uchar , ushort , uint , ulong unsigned 8, 16, 32, 64 bit (also spelled u8 u16 u32 u64 )

byte , short , int , long signed 8, 16, 32, 64 bit (also spelled i8 i16 i32 i64 ); byte is signed , and char is not a type (error 3)

f32 , f64 IEEE binary32, binary64

void no result (function result only)

- No implicit conversion. Both values of an operation have one type (error 7). Convert with the
type word: long x , uint b , f64 n .

- A bare number takes its type from context : the other value of its operation, the parameter it
is passed to, the result type at ret . With no context it is error 11: write x = uint 5 , never
x = 5 for a new name.

- Integer literals are decimal with an optional leading - . A literal that does not fit its type
is error 8. No character literals: write uchar 65 , not 'A' (error 3).

- Float literals need digits on both sides of the dot: 2.0f64 , 1.0e30f64 , 0.5f32 . The suffix is
optional where context gives the type.

- Hex only in OM-2 (section 9): lowercase 0x and lowercase digits, value must fit
( int 0xffffffff is error 8; write int -1 ).

- sizeof T , sizeof S and offsetof S f are compile-time ulong constants.

### 4. Words

Kind Words

arithmetic add sub mul div rem neg

bits and or xor not shl shr ( rotr rotl in OM-2)

compare (give bool ) eq ne lt le gt ge

float add sub mul div neg , fsqrt fabs fmin fmax

arrays new , get A i , put A i v , len A

structs new S v1 v2 ... , get p f , put p f v

control if / else / end , while COND bound N , for i T K , break , continue , ret , exit , trap N

conversion the type words, bitcast T v

I/O read fd A off n , write fd A off n , pread / pwrite fd A off n pos , and the 67 host words of section 10

- and , or , xor on integers of any width are bitwise, not logical: and ulong 12 ulong 10 is 8
( [examples/int_bits_and.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/int_bits_and.om)). Compare first when you want a bool.

- and / or on bools evaluate both sides; there is no short circuit
( [examples/mistake_short_circuit.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/mistake_short_circuit.om) traps 3 on the
index the C reader would expect to be skipped). Test the index in an outer if .

- Comparisons follow the type: on ulong , lt x y with x = 2^64-1 and y = 1 is false.

- div and rem on signed values round toward zero; rem takes the dividend's sign;
shr on a signed value keeps the sign.

- A function with a result is a value, not a statement: write v = f 1 , never a bare f 1
(error 7). A void function is called as a statement.

- A call is the name then its values with no brackets or commas: ret f 1 2 .

### 5. Traps: what stops a running program

A trap ends the process with exit status 100 + N. Output already written stays written.

Cause Trap Exit Example

signed overflow in add sub mul neg 1 101 examples/trap1_overflow.om

div or rem by zero, and signed minimum divided by -1 2 102 trap2_divzero.om

array index or I/O slice out of bounds 3 103 trap3_bounds.om

a loop past its bound 4 104 trap4_loop.om

an integer conversion whose value does not fit 5 105 trap5_conv.om

stack exhausted (8 MiB) by calls or local arrays 6 106 trap6_stack.om

shift or rotate amount outside 0..width-1 7 107 trap7_shift.om

a contract check that fails (OM-2) 9, 10 109, 110 contract_requires.om , contract_ensures.om

trap N , N 1..14 N 100+N trap_code.om ( trap 14 , exit 114)

- Unsigned arithmetic wraps modulo 2^width and never traps
( [examples/unsigned_wrap.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/unsigned_wrap.om)).

- Integer conversions are checked: uchar x with x = 300 traps 5. Keep the low bits on purpose with
a mask: uchar and x 255 .

- Float to integer truncates toward zero and saturates at the type's limits; NaN gives 0; it never
traps ( [examples/float_to_int.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/float_to_int.om)). No float operation traps:
1/0 is infinity, 0/0 is NaN, and NaN compares false except with ne .

- exit N ends the process with status N directly, without the trap convention.

### 6. Loops and bounds

- while COND bound N runs the body at most N times, N 1..999999 (error 8 outside). Without
bound the limit is 1000000. One more pass traps 4. Choose N from an argument you can write down
in a note , for example "every pass consumes at least one byte of a 65536-byte input".

- for i T K runs i from 0 to K-1. for takes no bound (error 5); K is the limit.

- break and continue work in both loops. There is no else if : nest an if inside else .

- No loop runs forever and recursion is bounded by the stack.

### 7. Arrays, texts, globals, structs

- Local array: a = new T N v , N elements each v, only in a function's outermost block (error 9
inside a block). N is a literal or an integer const ; a variable N is error 16. There is no heap
and no free (error 9).

- Global array: global NAME T N at top level, zero-filled, program mode only. A global is
never an argument (error 19); a function uses it by naming it.

- Text: text NAME "bytes" is a read-only uchar array. Escapes are only \n \t \\ \"
(error 22 for others).

- Array parameters state type and exact length: a view uchar 64 (read-only) or
a edit uchar 64 (writable). Another length is error 7. In OM-2, a view T * / a edit T * take
any length. Writing to a view or text is error 20.

- get A i / put A i v : a literal index outside the array is error 21; every other index is checked
at run time (trap 3). There are no pointers and no address arithmetic.

- Structs: struct Pair a uint b long end , before the first fn . Every field is an 8-byte cell,
so a struct is never a wire or file layout. p = new Pair 5 -12 , pass as p edit Pair or
p view Pair ( [examples/structs.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/structs.om)).

- Bytes on the wire: build them with shifts and masks into a uchar array
( [examples/wire_le.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/wire_le.om)); OM-2 also has layout .

### 8. Names and limits

- Variable, parameter, global, text, const, struct and field names: at most 8 characters (error 13).
Function names: at most 63, but see section 13 for names that start with an 8-letter keyword.

- A new name may not repeat a visible name, a function or a struct (error 10). A name first assigned
inside a block ends at that block's end ; assign it before the block to keep it.

- Reserved words cannot be names, including `len read write text new free view edit global note
exit const bound and every host word ( stat , link , send , random , fork , ...). len` as a
name is error 16, free is error 9.

- 16 registers per function hold parameters, live names, loop counters and the temporaries of the
current statement. The 17th is error 12 ( examples/err12_registers.om ). The fix is structural:
move part of the work into a helper function that takes a few scalars and returns one value, end
the life of names you no longer need by computing them inside a block, and split a long nested
expression into several assignments of one or two words each.

- Size limits: an array up to 16777216 elements, 4 MiB of local arrays per function, 1 GiB of
globals (error 23).

### 9. OM-2 units

A unit whose first line that is not blank or note is exactly om2 is an OM-2 unit. OM-1 code keeps
its meaning inside it. OM-2 adds:

- lowercase hex literals; rotr x n , rotl x n on unsigned types (trap 7 for an amount outside
0..width-1);

- unsized parameters a view T * / a edit T * with len a the run-time count;

- part A off n , only as an argument to an unsized parameter: the n elements of A from off,
checked at run time (trap 3). A part of a global is error 19; as a value of its own it is error 9;
to a sized parameter it is error 7;

- for i T K unroll , fn ... inline , layout (external byte layouts), fresh scratch arrays
(error 27), abstract types with seal / open (error 28), export fn (at most 32, error 14);

- executable contracts: requires and ensures lines at the start of a function, invariant as the
first line of a loop body. A failing requires traps 9 (exit 109), a failing ensures or
invariant traps 10 (exit 110). A clause may not call a function, use floats or host words
(error 30). The first line om2 release erases the checks
( [examples/contract_release.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/contract_release.om)).

Examples: [om2_tour.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/om2_tour.om), [om2_views.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/om2_views.om),
[om2_hex_rotr.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/om2_hex_rotr.om), [contracts_ok.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/contracts_ok.om).

### 10. Host I/O

- Every host word returns a long : a count, or minus the Linux errno. read may return fewer bytes
than asked, 0 at end of input, or a negative error; write may write fewer. Loop until done and
handle k < 0 and k == 0 separately
( [examples/stdin_count.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/stdin_count.om)).

- Descriptors, flags and modes are int ; offsets, counts and capacities ulong ; buffers uchar
arrays. Slices are checked before the kernel call (trap 3).

- main takes no parameters: read arguments with argcnt and argread
( [examples/echo_args.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/echo_args.om)) and the environment with envcnt and
envread ( [examples/env_read.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/env_read.om)). Short capacity returns -105.

- Host words carry the process's own permissions; they are not a sandbox.

The 67 host words at the pin, with their values (OMEGESE section 10 has each one's exact contract).
A and B are uchar arrays, off , n and capacity are ulong , and descriptors, flags, modes
and ids are int . A path is the slice A off n ; a packed list is a u16 count, then u16 -length
records. Each word is reserved: using it as a name is error 16 at the pin, while an unreserved name
in the same program compiles.

Area Words

files fopen A off n flags mode , fclose fd , fsync fd , fdsync fd , syncfs fd , memfd A off n flags , fseek fd offset whence , ftrunc fd length , flock fd op , fstat fd A off n , getdnts fd A off n

paths chmod A off n mode , fchmod fd mode , chown A off n uid gid , faccess A off n mode , truncate A off n length , unlink A off n , makedir A off n mode , rmdir A off n , cwd A off capacity , chdir A off n , fchdir fd , readlnk A off n B off capacity , stat A off n B off capacity , lstat A off n B off capacity , renames A off n flags , link A off n , symlnk A off n , umask mask

processes getpid , getppid , getuid , geteuid , getgid , getegid , setsid , getpgid pid , getsid pid , setpgid pid pgid , fork , killpid pid signal , waitpid pid A off n options , pipefds A off n flags , dupfd fd target flags , execprog A off n

arguments, environment, randomness argcnt , argread index A off capacity , envcnt , envread index A off capacity , random A off n flags

time monons , realns , sleepns interval

sockets socknew domain kind protocol , bind fd A off n , connect fd A off n , listen fd backlog , accept fd flags , sockname fd A off n , sockopt fd level option A off n , recv fd A off n flags , send fd A off n flags , sendmsg fd A off n flags , shutdown fd how , waitio fd events interval , pollfds A off n interval , peercred fd A off capacity

### 11. Compiler errors

Exit status = error number. The only message is the one stderr line omc: line N: error K , where N
is the line being read (0 when no line was read). One refusal per code is in examples/errNN_*.om
with its exact stderr line in the matching .expect , except 24, which needs a generated program.

Code Meaning Example Fix

1 omc could not read its input err01_input (stdin is a directory) give omc a readable file on stdin

2 omc could not write its output err02_output (stdout is /dev/full ) send stdout to a writable file with space

3 unknown name, field or function err03_unknown_name assign the name before use; check the spelling

4 the line ends before the statement is complete err04_line_ends give every word all of its values

5 words left after a complete statement err05_extra_words count each word's values; there is no infix

6 malformed number err06_bad_number decimal digits; hex only in OM-2, lowercase

7 type mismatch err07_type_mismatch convert with a type word: add int 1 int u

8 number out of range err08_out_of_range a literal that fits its type; a bound 1..999999; a trap code 1..14

9 a word in a place where it is not allowed err09_disallowed move it: new only in a function's outermost block, struct before the first fn

10 duplicate name err10_duplicate choose a name that is not visible, not a function, not a struct

11 a number with nothing to give it a type err11_ambiguous x = uint 5

12 register pool exhausted (16 per function) err12_registers fewer live names, a helper function, shorter expressions (section 8)

13 name too long err13_long_name at most 8 characters (function names 63)

14 compiler capacity: names, functions, exports, expansion err14_capacity split the function or the unit

15 the input ends inside an open block err15_missing_end close every block with end

16 syntax: unknown word or misplaced form err16_syntax start each line with a statement word; comments are note lines

17 a line after ret , break , continue , trap or exit in the same block err17_after_path delete the line or move it above

18 a function with a result whose end is reachable err18_missing_ret end every path with ret v

19 a global as an argument, or one array twice in a call err19_global_arg name the global inside the function; pass distinct arrays

20 writing to a text or a view err20_readonly an edit parameter, or a local copy

21 a literal index outside the array err21_const_index an index 0..N-1

22 a text escape other than \n \t \\ \" err22_text_escape build other bytes with put

23 array or pool size limit err23_size smaller arrays (section 8 limits)

24 a conditional branch farther than 1 MiB of code generated, below move long bodies into functions

25, 26 never emitted at the pin none none

27 OM-2 fresh element read before it is written err27_fresh put every element before the get

28 OM-2 seal outside the constructor err28_seal seal only as the whole body of fn NAMEmk ... to NAME

29 OM-2 layout field past the size or overlapping err29_layout keep every field inside SIZE and apart

30 OM-2 contract clause not allowed err30_contract integer words on parameters only (and result in ensures ); no calls, floats or host words

How the emitted set was established at the pin: in seed/omc/omc.om , fn fail (line 293) writes
the stderr line and exits with the code ( exit int code , line 322). The only other exits are
exit int 0 and exit 0 , so every refusal goes through fail . Its callers pass the literals 1..24
and 27..30, or forward a literal 3, 4, 6, 8, 13 or 16 through lenval , nfail and unkfail . No
caller passes 25 or 26, so those two codes are never emitted. A trap inside omc itself would exit
100 + N, which is not an error code.

Error 24 needs more than 1 MiB of code inside one loop. This program, with 270000 copies of the
line x = add x 1 (4 bytes of code each), was refused with omc: line 270006: error 24 , the line
of the loop's end ; with 140000 copies it compiled:

```
{ printf 'fn main to int\nx = ulong 0\nc = true\nwhile c bound 1\n'
  yes 'x = add x 1' | head -n 270000
  printf 'c = false\nend\nret int and x 1\nend\n'; } > e24.om
seed/out/omc < e24.om > e24; echo "compile $?"   # compile 24
```

### 12. Common mistakes

Each row is a program in examples/ with its observed refusal.

Mistake Write instead Refusal Example

y = x + 1 y = add x 1 error 5 mistake_infix.om

f(1, 2) f 1 2 error 6 mistake_c_call.om

if x > 0 if gt x 0 error 7 mistake_compare_operator.om

'A' uchar 65 error 3 mistake_char_literal.om

// comment note comment error 16 mistake_slash_comment.om

x = 1; x = uint 1 error 6 mistake_semicolon.om

return x ret x error 18 (silent assignment) mistake_return.om

else if c else , then a nested if c error 5 mistake_else_if.om

fn main argc int to int argcnt , argread error 9 mistake_main_args.om

for i ulong n bound 10 while lt i n bound 10 error 5 mistake_for_bound.om

while c bound 1000000 a bound 1..999999 error 8 mistake_bound_range.om

a = new uchar n 0 a literal or const length error 16 mistake_new_var_len.om

free a nothing: no heap error 9 mistake_free.om

len = ... another name error 16 mistake_reserved_name.om

neg = ... or text neg "a" another name: neg is the negation word error 16 mistake_neg_name.om

a bare call f 1 with a result v = f 1 error 7 mistake_value_stmt.om

a 7th parameter a struct or an array error 9 mistake_seven_params.om

2 view T * plus 3 scalars (7 slots) a sized view, a struct, or fewer scalars error 9 mistake_om2_param_slots.om

emit buf with buf a global name the global inside the function error 19 err19_global_arg.om

a view uchar 8 given a 16-element array the exact length, or OM-2 view uchar * error 7 mistake_param_length.om

trap 15 trap 1 .. trap 14 error 8 mistake_trap_range.om

struct after a fn every struct before the first fn error 9 mistake_struct_after_fn.om

rotr or hex without om2 an om2 first line error 3 mistake_om1_rotr.om

0X10 or 0xFF 0x10 , 0xff error 6 mistake_om2_upper_hex.om

int 0xffffffff int -1 error 8 mistake_om2_int_hex.om

part of a global part of a local error 19 mistake_om2_part_global.om

part to a sized parameter an unsized view T * parameter error 7 mistake_om2_part_sized.om

s = part a 0 2 part only as an argument error 9 mistake_om2_part_statement.om

if and lt i n eq get a i 0 (C short circuit) an outer if lt i n trap 3, exit 103 mistake_short_circuit.om

### 13. Known compiler defects at the pin

- bitcast across signedness below 64 bits (fix proposed in draft omega-mv #896, not in the
pin): the result does not compare equal to the reinterpreted value. Observed wrong: uint to
int (4294967295 is not -1, and adding 2 traps 1), int to uint , ushort to and from
short , uchar to and from byte , and f32 to int (-1.0 is not -1082130432 and not below 0).
Observed correct: ulong to and from long , f64 to long , f32 to uint , int to f32 .
Until a fixed compiler is pinned, do not bitcast between narrow integer types or from f32 to
int ; decode signed 8, 16 and 32-bit values arithmetically: load into long , then subtract 2^32
(or 2^16, 2^8) when the value is at least 2^31 (2^15, 2^7), as
[examples/wire_le.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/wire_le.om) does. For float bits, bitcast uint of an
f32 is correct.

- Empty text through view uchar * (omega-mv issue #775): the parameter does not arrive with
len 0 (observed 60 and 28, depending on the other texts in the unit), so a loop over it runs past
the text (a crash has been reported; not reproduced here). Workaround: pass part e 0 0 , which
arrives with len 0
( [examples/empty_text_part.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/empty_text_part.om)).

- Function names that begin with an 8-letter keyword: a function name longer than 8 bytes whose
first 8 bytes are a keyword ( continue_x , truncate_number , sockname_x , execprog_x ,
peercred_x ) is error 16, although function names may be 63 characters. Shorter keyword prefixes
are fine ( breakx , whilex , getpid_x ). Workaround: rename ( cont_x , trunc_num )
( [examples/defect_keyword_prefix.om](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/defect_keyword_prefix.om)).

- A fix for both is in progress in omega-mv; until a new compiler is pinned, use the workarounds.

- OMEGESE 9.9 lists + - * / for floats; the compiler refuses them. Write add sub mul div .

### 14. Example index

All in [examples/](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/); each NAME.om has NAME.expect (compile status, exit status
or stderr line) and, when it prints, NAME.stdout with the exact bytes. Wolfram checks of the
arithmetic expectations are in [examples/WOLFRAM.md](https://github.com/aien-dev/omega-harness/blob/0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e/examples/WOLFRAM.md).

- Start here: hello , exit_status , print_decimal , functions , loops , arrays , text .

- Arithmetic: int_arith , int_bits_and , unsigned_wrap , checked_conv , float_arith ,
float_to_int , consts .

- Data: globals , structs , wire_le .

- I/O: stdin_count , echo_args , env_read , tmp_files .

- Traps: trap1_overflow .. trap7_shift , trap_code .

- OM-2 and contracts: om2_tour , om2_views , om2_hex_rotr , om2_part_trap , om2_param_slots ,
contracts_ok , contract_requires , contract_ensures , contract_invariant , contract_release .

- Known defects and their workarounds: empty_text_part , defect_keyword_prefix .

- Refusals: err01_input .. err30_contract , mistake_* .

## Worked examples

98 programs from examples/ and skills/omega-encoding/examples/ , each listed with its files. NAME.om is the program. NAME.expect is what the gate checks: compile N is the compiler's exit status, stderr LINE its whole stderr when N is not 0, exit N the program's exit status, input dir and output full the two refusals that need a special compiler input or output. NAME.stdout is the exact standard output, and an absent one means empty. NAME.stdin , NAME.args (one argument per line) and NAME.env (one KEY=VALUE per line) are what the program is given.

Each file is labelled File: PATH and followed by its bytes in one block. To copy a file out of llms-full.txt, take the lines between its two fences and end each with a newline. A label ending in (no final newline) means the file does not end in a newline, so drop the last one. A label ending in (hex bytes) means the block lists the bytes as two hex digits each, sixteen to a line. A label ending in (empty file) means the file has no bytes and no block follows.

### arrays

File: examples/arrays.om

```
note arrays: a local array is new T N v in the outermost block; N is a literal or an integer const
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
a = new uint 8 0
for i ulong 8
put a i uint mul add i 1 add i 1
end
s = ulong 0
for i ulong len a
s = add s ulong get a i
end
putu s
putu len a
putu ulong get a 7
ret 0
end
```

File: examples/arrays.expect

```
compile 0
exit 0
```

File: examples/arrays.stdout

```
204
8
64
```

### checked_conv

File: examples/checked_conv.om

```
note checked_conv: integer conversions check the value; mask first to keep low bits
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
x = uint 300
putu ulong uchar and x 255
y = long 2147483647
putl long int y
w = int -1
putl long w
putu ulong ushort 65535
ret 0
end
```

File: examples/checked_conv.expect

```
compile 0
exit 0
```

File: examples/checked_conv.stdout

```
44
2147483647
-1
65535
```

### consts

File: examples/consts.om

```
note consts: a top-level const is visible after its line and may size an array, bound a loop or name a trap
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
const N ulong 16
const PASSES ulong 16
const BAD ulong 12
fn main to int
a = new uchar N 1
s = ulong 0
i = ulong 0
while lt i len a bound PASSES
s = add s ulong get a i
i = add i 1
end
putu s
if ne s N
trap BAD
end
ret 0
end
```

File: examples/consts.expect

```
compile 0
exit 0
```

File: examples/consts.stdout

```
16
```

### contract_ensures

File: examples/contract_ensures.om

```
note contract_ensures: a false postcondition traps 10, exit 110; the bug here is the + 2
om2
text before "before\n"
fn inc x uint to uint
requires lt x 100
ensures eq result add x 1
ret add x 2
end
fn main to int
k = write 1 before 0 len before
h = inc 5
ret 0
end
```

File: examples/contract_ensures.expect

```
compile 0
exit 110
```

File: examples/contract_ensures.stdout

```
before
```

### contract_invariant

File: examples/contract_invariant.om

```
note contract_invariant: a false loop invariant traps 10, exit 110, at the top of the failing pass
om2
text before "before\n"
fn main to int
k = write 1 before 0 len before
i = uint 0
while lt i 10
invariant lt i 5
i = add i 1
end
ret 0
end
```

File: examples/contract_invariant.expect

```
compile 0
exit 110
```

File: examples/contract_invariant.stdout

```
before
```

### contract_release

File: examples/contract_release.om

```
note contract_release: om2 release erases contracts; the false precondition no longer traps
om2 release
fn half x uint to uint
requires eq rem x 2 0
ret div x 2
end
fn main to int
ret int half 7
end
```

File: examples/contract_release.expect

```
compile 0
exit 3
```

File: examples/contract_release.stdout (empty file)

### contract_requires

File: examples/contract_requires.om

```
note contract_requires: a false precondition traps 9, exit 109, before the body runs
om2
text before "before\n"
fn half x uint to uint
requires eq rem x 2 0
ret div x 2
end
fn main to int
k = write 1 before 0 len before
h = half 7
ret 0
end
```

File: examples/contract_requires.expect

```
compile 0
exit 109
```

File: examples/contract_requires.stdout

```
before
```

### contracts_ok

File: examples/contracts_ok.om

```
note contracts_ok: requires and ensures form a function's prefix; invariant opens a loop body
om2
fn step x uint to uint
requires lt x 10
ensures eq result add x 1
ret add x 1
end
fn main to int
i = uint 0
while lt i 3
invariant le i 3
i = step i
end
ret int sub i 3
end
```

File: examples/contracts_ok.expect

```
compile 0
exit 0
```

File: examples/contracts_ok.stdout (empty file)

### defect_keyword_prefix

File: examples/defect_keyword_prefix.om

```
note defect_keyword_prefix: known defect at the pin. A function name longer than 8 bytes whose first
note 8 bytes are an 8-letter keyword (continue, truncate, sockname, execprog, peercred) is refused error 16.
note Workaround: rename (cont_x, trunc_num). Expected to change when the compiler fix is pinned
fn continue_x to int
ret 7
end
fn main to int
ret continue_x
end
```

File: examples/defect_keyword_prefix.expect

```
compile 16
stderr omc: line 4: error 16
```

### echo_args

File: examples/echo_args.om

```
note echo_args: argcnt includes the program name; argread copies one argument without a terminator
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
global ab uchar 32
text toolong "(longer than 31 bytes)\n"
fn main to int
n = argcnt
putl n
i = ulong 1
while lt long i n bound 64
k = argread i ab 0 31
if eq k -105
w = write 1 toolong 0 len toolong
else
m = ulong k
put ab m 10
outbuf m
end
i = add i 1
end
ret 0
end
note outbuf: write ab[0 .. m] (the argument and its newline); exit 90 on an error
fn outbuf m ulong to void
e = add m 1
p = ulong 0
while lt p e bound 32
k = write 1 ab p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
```

File: examples/echo_args.expect

```
compile 0
exit 0
```

File: examples/echo_args.args

```
one
two words

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

File: examples/echo_args.stdout

```
5
one
two words

(longer than 31 bytes)
```

### empty_text_part

File: examples/empty_text_part.om

```
note empty_text_part: known defect at the pin (omega-mv #775): an empty text passed to an unsized view
note does not arrive with len 0. Workaround, shown here: pass part e 0 0, which arrives with len 0
om2
text e ""
text f "0123456789abcdef0123456789abcdef"
fn n a view uchar * to ulong
ret len a
end
fn main to int
k = n part e 0 0
if ne k 0
ret 1
end
m = n f
if ne m 32
ret 2
end
ret 0
end
```

File: examples/empty_text_part.expect

```
compile 0
exit 0
```

### env_read

File: examples/env_read.om

```
note env_read: envcnt counts the environment entries; envread copies one KEY=VALUE without a terminator
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
global eb uchar 64
fn main to int
n = envcnt
putl n
i = ulong 0
while lt long i n bound 64
k = envread i eb 0 63
if lt k 0
note -105: the entry is longer than the capacity; the buffer is unchanged
k = long 0
end
m = ulong k
put eb m 10
e = add m 1
p = ulong 0
while lt p e bound 64
w = write 1 eb p sub e p
if le w 0
exit 90
end
p = add p ulong w
end
i = add i 1
end
ret 0
end
```

File: examples/env_read.expect

```
compile 0
exit 0
```

File: examples/env_read.env

```
LANG=C
OMEGA_HOME=/opt/omega
EMPTY=
LONG=vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
```

File: examples/env_read.stdout

```
4
LANG=C
OMEGA_HOME=/opt/omega
EMPTY=

```

### err01_input

File: examples/err01_input.om

```
note err01_input: error 1, the compiler could not read its input. The gate feeds a directory as stdin; this file is a placeholder valid program
fn main to int
ret 0
end
```

File: examples/err01_input.expect

```
input dir
compile 1
stderr omc: line 0: error 1
```

### err02_output

File: examples/err02_output.om

```
note err02_output: error 2, the compiler could not write its output. The gate sends stdout to /dev/full; the program itself is valid
fn main to int
ret 0
end
```

File: examples/err02_output.expect

```
output full
compile 2
stderr omc: line 5: error 2
```

### err03_unknown_name

File: examples/err03_unknown_name.om

```
note err03_unknown_name: a name that was never assigned, or an unknown field. Fix: assign it first, check spelling
fn main to int
ret q
end
```

File: examples/err03_unknown_name.expect

```
compile 3
stderr omc: line 3: error 3
```

### err04_line_ends

File: examples/err04_line_ends.om

```
note err04_line_ends: the line ends before the statement is complete; here sub needs two values
fn main to int
x = int 5
ret sub x
end
```

File: examples/err04_line_ends.expect

```
compile 4
stderr omc: line 5: error 4
```

### err05_extra_words

File: examples/err05_extra_words.om

```
note err05_extra_words: words left over after a complete statement; prefix words have fixed arity
fn main to int
x = int 5
ret x 1
end
```

File: examples/err05_extra_words.expect

```
compile 5
stderr omc: line 4: error 5
```

### err06_bad_number

File: examples/err06_bad_number.om

```
note err06_bad_number: a malformed number; outside OM-2 there are no hex literals
fn main to int
x = uint 0x10
ret int x
end
```

File: examples/err06_bad_number.expect

```
compile 6
stderr omc: line 3: error 6
```

### err07_type_mismatch

File: examples/err07_type_mismatch.om

```
note err07_type_mismatch: no implicit conversions; both values of an op have one type. Fix: add int 1 int u
fn main to int
u = uint 2
x = add int 1 u
ret x
end
```

File: examples/err07_type_mismatch.expect

```
compile 7
stderr omc: line 4: error 7
```

### err08_out_of_range

File: examples/err08_out_of_range.om

```
note err08_out_of_range: a literal that does not fit its type; int is -2147483648 .. 2147483647
fn main to int
x = int 2147483648
ret 0
end
```

File: examples/err08_out_of_range.expect

```
compile 8
stderr omc: line 3: error 8
```

### err09_disallowed

File: examples/err09_disallowed.om

```
note err09_disallowed: a word in a place it is not allowed; new is only in a function's outermost block
fn main to int
if true
a = new uchar 4 0
end
ret 0
end
```

File: examples/err09_disallowed.expect

```
compile 9
stderr omc: line 4: error 9
```

### err10_duplicate

File: examples/err10_duplicate.om

```
note err10_duplicate: a new name may not repeat a visible name, a function or a struct
fn f x int x int to int
ret x
end
fn main to int
ret f 1 2
end
```

File: examples/err10_duplicate.expect

```
compile 10
stderr omc: line 2: error 10
```

### err11_ambiguous

File: examples/err11_ambiguous.om

```
note err11_ambiguous: a bare number with nothing to give it a type. Fix: x = uint 5
fn main to int
x = 5
ret 0
end
```

File: examples/err11_ambiguous.expect

```
compile 11
stderr omc: line 3: error 11
```

### err12_registers

File: examples/err12_registers.om

```
note err12_registers: the 17th live name exhausts the 16-register pool. Fix: fewer live names, smaller functions
fn main to int
a1 = int 1
a2 = int 2
a3 = int 3
a4 = int 4
a5 = int 5
a6 = int 6
a7 = int 7
a8 = int 8
a9 = int 9
a10 = int 10
a11 = int 11
a12 = int 12
a13 = int 13
a14 = int 14
a15 = int 15
a16 = int 16
a17 = int 17
ret add a1 add a2 add a3 add a4 add a5 add a6 add a7 add a8 add a9 add a10 add a11 add a12 add a13 add a14 add a15 add a16 a17
end
```

File: examples/err12_registers.expect

```
compile 12
stderr omc: line 19: error 12
```

### err13_long_name

File: examples/err13_long_name.om

```
note err13_long_name: a variable, parameter, global, text, const, struct or field name has at most 8 characters
fn main to int
counter1x = int 1
ret 0
end
```

File: examples/err13_long_name.expect

```
compile 13
stderr omc: line 3: error 13
```

### err14_capacity

File: examples/err14_capacity.om

```
note err14_capacity: a compiler capacity; here the 33rd export in one OM-2 unit (limit 32). Exports are function mode, so no main
om2
export fn e0 x uint to uint
ret x
end
export fn e1 x uint to uint
ret x
end
export fn e2 x uint to uint
ret x
end
export fn e3 x uint to uint
ret x
end
export fn e4 x uint to uint
ret x
end
export fn e5 x uint to uint
ret x
end
export fn e6 x uint to uint
ret x
end
export fn e7 x uint to uint
ret x
end
export fn e8 x uint to uint
ret x
end
export fn e9 x uint to uint
ret x
end
export fn e10 x uint to uint
ret x
end
export fn e11 x uint to uint
ret x
end
export fn e12 x uint to uint
ret x
end
export fn e13 x uint to uint
ret x
end
export fn e14 x uint to uint
ret x
end
export fn e15 x uint to uint
ret x
end
export fn e16 x uint to uint
ret x
end
export fn e17 x uint to uint
ret x
end
export fn e18 x uint to uint
ret x
end
export fn e19 x uint to uint
ret x
end
export fn e20 x uint to uint
ret x
end
export fn e21 x uint to uint
ret x
end
export fn e22 x uint to uint
ret x
end
export fn e23 x uint to uint
ret x
end
export fn e24 x uint to uint
ret x
end
export fn e25 x uint to uint
ret x
end
export fn e26 x uint to uint
ret x
end
export fn e27 x uint to uint
ret x
end
export fn e28 x uint to uint
ret x
end
export fn e29 x uint to uint
ret x
end
export fn e30 x uint to uint
ret x
end
export fn e31 x uint to uint
ret x
end
export fn e32 x uint to uint
ret x
end
```

File: examples/err14_capacity.expect

```
compile 14
stderr omc: line 99: error 14
```

### err15_missing_end

File: examples/err15_missing_end.om

```
note err15_missing_end: the input ends inside an open function or block
fn main to int
ret 0
```

File: examples/err15_missing_end.expect

```
compile 15
stderr omc: line 4: error 15
```

### err16_syntax

File: examples/err16_syntax.om

```
note err16_syntax: a line that starts with no statement word; C-style declarations are not Omega
int main to int
ret 0
end
```

File: examples/err16_syntax.expect

```
compile 16
stderr omc: line 2: error 16
```

### err17_after_path

File: examples/err17_after_path.om

```
note err17_after_path: a line after ret, break, continue, trap or exit in the same block can never run
fn main to int
ret 0
ret 1
end
```

File: examples/err17_after_path.expect

```
compile 17
stderr omc: line 4: error 17
```

### err18_missing_ret

File: examples/err18_missing_ret.om

```
note err18_missing_ret: a function with a result type whose end is reachable
fn f x int to int
if gt x 0
ret 1
end
end
fn main to int
ret f 1
end
```

File: examples/err18_missing_ret.expect

```
compile 18
stderr omc: line 7: error 18
```

### err19_global_arg

File: examples/err19_global_arg.om

```
note err19_global_arg: a global is never an argument. Fix: name the global inside the function
global g uchar 4
fn f a edit uchar 4 to void
put a 0 1
end
fn main to int
f g
ret 0
end
```

File: examples/err19_global_arg.expect

```
compile 19
stderr omc: line 7: error 19
```

### err20_readonly

File: examples/err20_readonly.om

```
note err20_readonly: a text or a view parameter is read-only
text t "abc"
fn main to int
put t 0 1
ret 0
end
```

File: examples/err20_readonly.expect

```
compile 20
stderr omc: line 4: error 20
```

### err21_const_index

File: examples/err21_const_index.om

```
note err21_const_index: a literal index outside the array is refused at compile time (a run-time index traps 3)
fn main to int
a = new uint 4 0
put a 4 1
ret 0
end
```

File: examples/err21_const_index.expect

```
compile 21
stderr omc: line 4: error 21
```

### err22_text_escape

File: examples/err22_text_escape.om

```
note err22_text_escape: a text escape other than backslash n, t, backslash or quote
text t "a\q"
fn main to int
ret 0
end
```

File: examples/err22_text_escape.expect

```
compile 22
stderr omc: line 2: error 22
```

### err23_size

File: examples/err23_size.om

```
note err23_size: an array over 16777216 elements, or over 4 MiB of local arrays, or 1 GiB of globals
fn main to int
a = new uchar 16777217 0
ret 0
end
```

File: examples/err23_size.expect

```
compile 23
stderr omc: line 3: error 23
```

### err27_fresh

File: examples/err27_fresh.om

```
note err27_fresh: OM-2 fresh means every element is written before it is read
om2
fn f s edit uint 4 fresh to uint
ret get s 0
end
fn main to int
a = new uint 4 0
ret int f a
end
```

File: examples/err27_fresh.expect

```
compile 27
stderr omc: line 4: error 27
```

### err28_seal

File: examples/err28_seal.om

```
note err28_seal: OM-2 seal is allowed only as the whole body of the abstract type's constructor
om2
abstract v32 ulong
holds v32 dup32
fn main to int
v = seal v32 ulong 0
ret 0
end
```

File: examples/err28_seal.expect

```
compile 28
stderr omc: line 6: error 28
```

### err29_layout

File: examples/err29_layout.om

```
note err29_layout: an OM-2 layout field past the layout's size, or overlapping another field
om2
layout blk 4
field lo uint at 2 little
end
fn main to int
ret 0
end
```

File: examples/err29_layout.expect

```
compile 29
stderr omc: line 4: error 29
```

### err30_contract

File: examples/err30_contract.om

```
note err30_contract: a contract clause may not call a function, use floats or host words; result needs a value postcondition
om2
fn g x uint to uint
ret x
end
fn f x uint to uint
requires lt g x 10
ret x
end
fn main to int
ret int f 1
end
```

File: examples/err30_contract.expect

```
compile 30
stderr omc: line 7: error 30
```

### exit_status

File: examples/exit_status.om

```
note exit_status: the exit status is main's value mod 256; 300 mod 256 = 44
fn main to int
ret 300
end
```

File: examples/exit_status.expect

```
compile 0
exit 44
```

File: examples/exit_status.stdout (empty file)

### float_arith

File: examples/float_arith.om

```
note float_arith: IEEE binary64, round to nearest even, no float operation traps
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
r = fsqrt 2.0f64
putl long mul r 1000000000.0
s = add 0.1f64 0.2
putu bitcast ulong s
putu bitcast ulong 1.0f64
z = f64 0.0
n = div z z
if ne n n
putu 1
end
if eq n n
putu 2
end
i = div 1.0 z
if gt i 1.0e308
putu 3
end
putl long fmin -2.5f64 3.0f64
putl long fabs -7.9f64
ret 0
end
```

File: examples/float_arith.expect

```
compile 0
exit 0
```

File: examples/float_arith.stdout

```
1414213562
4599075939470750516
4607182418800017408
1
3
-2
7
```

### float_to_int

File: examples/float_to_int.om

```
note float_to_int: float to integer truncates toward zero and saturates; NaN becomes 0; no trap
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
putl long 1.0e30f64
putl long -1.0e30f64
putl long -5.75f64
putu ulong uint -5.5f64
z = f64 0.0
putl long div z z
putu ulong uchar 300.0f64
ret 0
end
```

File: examples/float_to_int.expect

```
compile 0
exit 0
```

File: examples/float_to_int.stdout

```
9223372036854775807
-9223372036854775808
-5
0
0
255
```

### functions

File: examples/functions.om

```
note functions: at most 6 parameters; a call may name any function in the unit; recursion in program mode
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
putu fact 20
putu gcd 1071 462
putu ulong pick 1 2 3 4 5 6
ret 0
end
fn fact n ulong to ulong
if le n 1
ret 1
end
ret mul n fact sub n 1
end
fn gcd a ulong b ulong to ulong
x = a
y = b
while ne y 0 bound 200
t = rem x y
x = y
y = t
end
ret x
end
fn pick a int b int c int d int e int f int to int
ret add add a f mul b sub e d
end
```

File: examples/functions.expect

```
compile 0
exit 0
```

File: examples/functions.stdout

```
2432902008176640000
21
9
```

### globals

File: examples/globals.om

```
note globals: zero-filled pools in the program image, visible in every function, named directly
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
global hist ulong 10
note tally: count the decimal digits of v into hist
fn tally v ulong to void
n = v
while true bound 20
d = rem n 10
put hist d add get hist d 1
n = div n 10
if eq n 0
break
end
end
end
fn main to int
tally 1234567890
tally 9999
tally 0
putu get hist 9
putu get hist 0
putu get hist 5
ret 0
end
```

File: examples/globals.expect

```
compile 0
exit 0
```

File: examples/globals.stdout

```
5
2
1
```

### hello

File: examples/hello.om

```
note hello: the smallest complete program. A text is a read-only uchar array
text msg "hello, world\n"
fn main to int
k = write 1 msg 0 len msg
if ne k long len msg
ret 1
end
ret 0
end
```

File: examples/hello.expect

```
compile 0
exit 0
```

File: examples/hello.stdout

```
hello, world
```

### int_arith

File: examples/int_arith.om

```
note int_arith: signed div rounds toward zero, rem takes the dividend's sign, shr keeps the sign
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
a = long -7
b = long 2
putl div a b
putl rem a b
putl div 7 neg b
putl rem 7 neg b
putl mul 123456789 long 987654321
putl shr long -16 2
putl sub 0 a
ret 0
end
```

File: examples/int_arith.expect

```
compile 0
exit 0
```

File: examples/int_arith.stdout

```
-3
-1
-3
1
121932631112635269
-4
7
```

### int_bits_and

File: examples/int_bits_and.om

```
note int_bits_and: and, or, xor on integers are bitwise. 12 is 1100, 10 is 1010, so and gives 1000 = 8
fn main to int
x = ulong 12
y = and x ulong 10
z = and int 12 int 10
if ne int y z
ret 1
end
ret z
end
```

File: examples/int_bits_and.expect

```
compile 0
exit 8
```

### loops

File: examples/loops.om

```
note loops: while COND bound N (1..999999), for i T K, break and continue
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
note collatz: the step count to reach 1; the bound is a stated limit, not a proof, so exceeding it traps 4
fn collatz n ulong to ulong
x = n
c = ulong 0
while ne x 1 bound 1000
c = add c 1
if eq rem x 2 0
x = div x 2
continue
end
x = add mul x 3 1
end
ret c
end
fn main to int
putu collatz 27
s = ulong 0
for i ulong 100
if eq rem i 3 0
continue
end
if gt i 50
break
end
s = add s i
end
putu s
ret 0
end
```

File: examples/loops.expect

```
compile 0
exit 0
```

File: examples/loops.stdout

```
111
867
```

### mistake_bound_range

File: examples/mistake_bound_range.om

```
note mistake_bound_range: a while bound is 1..999999; without bound the limit is 1000000 passes
fn main to int
i = ulong 0
while lt i 3 bound 1000000
i = add i 1
end
ret 0
end
```

File: examples/mistake_bound_range.expect

```
compile 8
stderr omc: line 4: error 8
```

### mistake_c_call

File: examples/mistake_c_call.om

```
note mistake_c_call: a call is the function name then its values, no brackets or commas. Fix: ret f 1 2
fn f a int b int to int
ret add a b
end
fn main to int
ret f(1, 2)
end
```

File: examples/mistake_c_call.expect

```
compile 6
stderr omc: line 6: error 6
```

### mistake_char_literal

File: examples/mistake_char_literal.om

```
note mistake_char_literal: there are no character literals; write the byte value. Fix: x = uchar 65
fn main to int
x = uchar 'A'
ret 0
end
```

File: examples/mistake_char_literal.expect

```
compile 3
stderr omc: line 3: error 3
```

### mistake_compare_operator

File: examples/mistake_compare_operator.om

```
note mistake_compare_operator: conditions are bool values built with eq ne lt le gt ge; > is not a word. Fix: if gt x 0
fn main to int
x = int 1
if x > 0
ret 1
end
ret 0
end
```

File: examples/mistake_compare_operator.expect

```
compile 7
stderr omc: line 4: error 7
```

### mistake_else_if

File: examples/mistake_else_if.om

```
note mistake_else_if: there is no else if on one line; nest an if inside the else block
fn main to int
x = int 1
if eq x 0
ret 1
else if eq x 1
ret 2
end
ret 0
end
```

File: examples/mistake_else_if.expect

```
compile 5
stderr omc: line 6: error 5
```

### mistake_for_bound

File: examples/mistake_for_bound.om

```
note mistake_for_bound: for takes no bound; its count is the limit. Use while COND bound N for a bounded variable loop
fn main to int
n = ulong 5
s = ulong 0
for i ulong n bound 10
s = add s i
end
ret int s
end
```

File: examples/mistake_for_bound.expect

```
compile 5
stderr omc: line 5: error 5
```

### mistake_free

File: examples/mistake_free.om

```
note mistake_free: there is no heap and no free; arrays are new in the outermost block or global
fn main to int
free = int 1
ret 0
end
```

File: examples/mistake_free.expect

```
compile 9
stderr omc: line 3: error 9
```

### mistake_infix

File: examples/mistake_infix.om

```
note mistake_infix: there are no infix operators; write the prefix word. Fix: y = add x 1
fn main to int
x = int 1
y = x + 1
ret y
end
```

File: examples/mistake_infix.expect

```
compile 5
stderr omc: line 4: error 5
```

### mistake_main_args

File: examples/mistake_main_args.om

```
note mistake_main_args: main takes no parameters; read arguments with argcnt and argread
fn main argc int to int
ret 0
end
```

File: examples/mistake_main_args.expect

```
compile 9
stderr omc: line 5: error 9
```

### mistake_neg_name

File: examples/mistake_neg_name.om

```
note mistake_neg_name: neg is the negation word, so it cannot name a value or a text. Fix: pick another name, for example negv
fn main to int
neg = int 1
ret 0
end
```

File: examples/mistake_neg_name.expect

```
compile 16
stderr omc: line 3: error 16
```

### mistake_new_var_len

File: examples/mistake_new_var_len.om

```
note mistake_new_var_len: a new length is a literal or an integer const, never a variable; there are no run-time-sized arrays
fn main to int
n = ulong 4
a = new uchar n 0
ret 0
end
```

File: examples/mistake_new_var_len.expect

```
compile 16
stderr omc: line 4: error 16
```

### mistake_om1_rotr

File: examples/mistake_om1_rotr.om

```
note mistake_om1_rotr: rotr and hex need the om2 line; without it rotr is an unknown name
fn main to int
x = uint 1
ret int rotr x 1
end
```

File: examples/mistake_om1_rotr.expect

```
compile 3
stderr omc: line 4: error 3
```

### mistake_om2_int_hex

File: examples/mistake_om2_int_hex.om

```
note mistake_om2_int_hex: a hex literal must fit its type as a value; 0xffffffff is not an int. Fix: int -1
om2
fn main to int
x = int 0xffffffff
ret 0
end
```

File: examples/mistake_om2_int_hex.expect

```
compile 8
stderr omc: line 4: error 8
```

### mistake_om2_param_slots

File: examples/mistake_om2_param_slots.om

```
note mistake_om2_param_slots: 2 unsized views plus 3 scalars need 7 slots; the limit is 6. Fix: a sized view, a struct, or fewer scalars
om2
fn f a view uchar * b view uchar * x int y int z int to int
ret add add x y z
end
fn main to int
a = new uchar 4 0
ret f a a 1 2 3
end
```

File: examples/mistake_om2_param_slots.expect

```
compile 9
stderr omc: line 3: error 9
```

### mistake_om2_part_global

File: examples/mistake_om2_part_global.om

```
note mistake_om2_part_global: part of a global is refused like any global argument; slice a local array
om2
global g uchar 8
fn f a view uchar * to ulong
ret len a
end
fn main to int
ret int f part g 0 2
end
```

File: examples/mistake_om2_part_global.expect

```
compile 19
stderr omc: line 8: error 19
```

### mistake_om2_part_sized

File: examples/mistake_om2_part_sized.om

```
note mistake_om2_part_sized: part goes only to an unsized view T * parameter, not a sized one
om2
fn f a view uchar 2 to ulong
ret len a
end
fn main to int
b = new uchar 8 0
ret int f part b 0 2
end
```

File: examples/mistake_om2_part_sized.expect

```
compile 7
stderr omc: line 8: error 7
```

### mistake_om2_part_statement

File: examples/mistake_om2_part_statement.om

```
note mistake_om2_part_statement: part A off n is only an argument to an unsized view parameter, never a value of its own
om2
fn main to int
a = new uint 4 0
p = part a 0 2
ret 0
end
```

File: examples/mistake_om2_part_statement.expect

```
compile 9
stderr omc: line 5: error 9
```

### mistake_om2_upper_hex

File: examples/mistake_om2_upper_hex.om

```
note mistake_om2_upper_hex: OM-2 hex digits are lowercase after a lowercase 0x
om2
fn main to int
x = uint 0X10
ret 0
end
```

File: examples/mistake_om2_upper_hex.expect

```
compile 6
stderr omc: line 4: error 6
```

### mistake_param_length

File: examples/mistake_param_length.om

```
note mistake_param_length: a sized array parameter takes exactly that length; use OM-2 view T * for any length
fn f a view uchar 4 to uchar
ret get a 0
end
fn main to int
b = new uchar 8 0
ret int f b
end
```

File: examples/mistake_param_length.expect

```
compile 7
stderr omc: line 7: error 7
```

### mistake_reserved_name

File: examples/mistake_reserved_name.om

```
note mistake_reserved_name: len, text, read, write, stat and every host word are reserved; pick another name
fn main to int
len = int 1
ret 0
end
```

File: examples/mistake_reserved_name.expect

```
compile 16
stderr omc: line 3: error 16
```

### mistake_return

File: examples/mistake_return.om

```
note mistake_return: the word is ret. The = of an assignment is optional, so return x silently assigns x to a new name return; here the function then has no ret, error 18
fn main to int
x = int 1
return x
end
```

File: examples/mistake_return.expect

```
compile 18
stderr omc: line 6: error 18
```

### mistake_semicolon

File: examples/mistake_semicolon.om

```
note mistake_semicolon: one statement per line and no semicolons; the ; makes the number malformed
fn main to int
x = int 1;
ret 0
end
```

File: examples/mistake_semicolon.expect

```
compile 6
stderr omc: line 3: error 6
```

### mistake_seven_params

File: examples/mistake_seven_params.om

```
note mistake_seven_params: at most 6 parameters; pass a struct or an array for more
fn f a int b int c int d int e int g int h int to int
ret a
end
fn main to int
ret 0
end
```

File: examples/mistake_seven_params.expect

```
compile 9
stderr omc: line 2: error 9
```

### mistake_short_circuit

File: examples/mistake_short_circuit.om

```
note mistake_short_circuit: and/or evaluate both sides, so this still loads a[4] and traps 3 (exit 103)
note fix: test the bound in an outer if, then load inside it
fn main to int
a = new uchar 4 0
i = ulong 4
if and lt i len a eq get a i 0
ret 1
end
ret 0
end
```

File: examples/mistake_short_circuit.expect

```
compile 0
exit 103
```

File: examples/mistake_short_circuit.stdout (empty file)

### mistake_slash_comment

File: examples/mistake_slash_comment.om

```
note mistake_slash_comment: note is the only comment form; // and # are unknown words
// a comment
fn main to int
ret 0
end
```

File: examples/mistake_slash_comment.expect

```
compile 16
stderr omc: line 2: error 16
```

### mistake_struct_after_fn

File: examples/mistake_struct_after_fn.om

```
note mistake_struct_after_fn: a struct line comes before the first fn
fn main to int
ret 0
end
struct P a uint end
```

File: examples/mistake_struct_after_fn.expect

```
compile 9
stderr omc: line 5: error 9
```

### mistake_trap_range

File: examples/mistake_trap_range.om

```
note mistake_trap_range: trap takes 1..14; codes 9 and 10 are what contracts use, and the runtime owns 1..7
fn main to int
trap 15
end
```

File: examples/mistake_trap_range.expect

```
compile 8
stderr omc: line 3: error 8
```

### mistake_value_stmt

File: examples/mistake_value_stmt.om

```
note mistake_value_stmt: a function with a result cannot be a statement; bind its result. Fix: v = f
fn f to int
ret 1
end
fn main to int
f
ret 0
end
```

File: examples/mistake_value_stmt.expect

```
compile 7
stderr omc: line 6: error 7
```

### om2_hex_rotr

File: examples/om2_hex_rotr.om

```
note om2_hex_rotr: the first line that is not blank or a note opts in to OM-2: hex literals and rotr
om2
note ---- OM-2 output helpers: an unsized view parameter takes an array or text of any length
note outv: write all of a to stdout; a short write continues, 0 or an error exits 90
fn outv a view uchar * to void
e = len a
p = ulong 0
while lt p e bound 65536
k = write 1 a p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline
note a part of a global is error 19, so the digits go in a local array
fn putu v ulong to void
b = new uchar 21 0
i = ulong 20
put b 20 10
n = v
while true bound 20
i = sub i 1
put b i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outv part b i sub 21 i
end
fn main to int
x = uint 0xdeadbeef
putu ulong x
putu ulong rotr x 8
putu 0xffffffffffffffff
putu ulong and x 0xff
ret 0
end
```

File: examples/om2_hex_rotr.expect

```
compile 0
exit 0
```

File: examples/om2_hex_rotr.stdout

```
3735928559
4024348094
18446744073709551615
239
```

### om2_param_slots

File: examples/om2_param_slots.om

```
note om2_param_slots: six parameter slots; an unsized view T * or edit T * takes two (pointer, count), every other parameter one
note here 2 unsized views (4 slots) plus 2 scalars fill all six; a sized view uchar 4 would take one slot
om2
fn f a view uchar * b view uchar * x int y int to int
ret int add add len a len b ulong add x y
end
fn g a view uchar 4 b view uchar 4 c view uchar 4 x int y int z int to int
ret add add x y z
end
fn main to int
a = new uchar 4 0
b = new uchar 3 0
c = new uchar 4 0
d = new uchar 4 0
r = f a b 1 2
if ne r 10
ret 1
end
s = g a c d 1 2 3
if ne s 6
ret 2
end
ret 0
end
```

File: examples/om2_param_slots.expect

```
compile 0
exit 0
```

### om2_part_trap

File: examples/om2_part_trap.om

```
note om2_part_trap: part A off n checks off + n <= len A when it runs; past the end traps 3, exit 103
om2
text before "before\n"
fn sum a view uint * to ulong
s = ulong 0
for i ulong len a
s = add s ulong get a i
end
ret s
end
fn main to int
k = write 1 before 0 len before
a = new uint 4 1
o = ulong 3
t = sum part a o 2
ret 0
end
```

File: examples/om2_part_trap.expect

```
compile 0
exit 103
```

File: examples/om2_part_trap.stdout

```
before
```

### om2_tour

File: examples/om2_tour.om

```
note om2_tour: layout, abstract/holds/seal/open, fresh, unroll (after omega-mv examples/om2-tour.om)
om2
layout blk 8
field lo uint at 0 little
field hi uint at 4 big
end
abstract v32 ulong
holds v32 dup32
note the erasing constructor: the body is exactly this line
fn v32mk x uint to v32
ret seal v32 or shl ulong x 32 ulong x
end
note fresh: every element is written before it is read (error 27 otherwise)
fn seed s edit uint 8 fresh to uint
for i uint 8 unroll
put s i mul i 3
end
ret get s 7
end
fn stamp c edit blk to void
put c lo 0x01020304
put c hi 0x05060708
end
fn main to int
s = new uint 8 0
v = seed s
if ne v 21
ret 1
end
c = new uchar 8 0
stamp c
if ne get c 0 0x04
ret 2
end
if ne get c 4 0x05
ret 3
end
u = open v32mk 7
if ne u 0x0000000700000007
ret 4
end
ret 0
end
```

File: examples/om2_tour.expect

```
compile 0
exit 0
```

File: examples/om2_tour.stdout (empty file)

### om2_views

File: examples/om2_views.om

```
note om2_views: view T * is an unsized read-only parameter; part A off n passes a checked slice
om2
note ---- OM-2 output helpers: an unsized view parameter takes an array or text of any length
note outv: write all of a to stdout; a short write continues, 0 or an error exits 90
fn outv a view uchar * to void
e = len a
p = ulong 0
while lt p e bound 65536
k = write 1 a p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline
note a part of a global is error 19, so the digits go in a local array
fn putu v ulong to void
b = new uchar 21 0
i = ulong 20
put b 20 10
n = v
while true bound 20
i = sub i 1
put b i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outv part b i sub 21 i
end
text greet "views and slices\n"
fn sum a view uint * to ulong
s = ulong 0
for i ulong len a
s = add s ulong get a i
end
ret s
end
fn main to int
outv greet
a = new uint 6 0
for i ulong 6
put a i uint add i 1
end
putu sum a
putu sum part a 1 3
putu sum part a 5 1
outv part greet 0 6
outv part greet 16 1
ret 0
end
```

File: examples/om2_views.expect

```
compile 0
exit 0
```

File: examples/om2_views.stdout

```
views and slices
21
9
6
views 
```

### print_decimal

File: examples/print_decimal.om

```
note print_decimal: the output helpers every other example copies
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
putu 0
putu 42
putu 18446744073709551615
putl 9223372036854775807
putl -9223372036854775808
putl -1
ret 0
end
```

File: examples/print_decimal.expect

```
compile 0
exit 0
```

File: examples/print_decimal.stdout

```
0
42
18446744073709551615
9223372036854775807
-9223372036854775808
-1
```

### stdin_count

File: examples/stdin_count.om

```
note stdin_count: read stdin to its end in 7-byte reads, counting bytes and lines
note read may return fewer bytes than asked, 0 at the end, or minus the errno: handle all three
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
global buf uchar 7
fn main to int
bytes = ulong 0
lines = ulong 0
sum = ulong 0
note bound: every pass but the last reads at least one byte; this program accepts at most 65536 bytes
while true bound 65537
k = read 0 buf 0 7
if lt k 0
exit 91
end
if eq k 0
break
end
n = ulong k
for i ulong n
c = get buf i
sum = add sum ulong c
if eq c 10
lines = add lines 1
end
end
bytes = add bytes n
end
putu bytes
putu lines
putu sum
ret 0
end
```

File: examples/stdin_count.expect

```
compile 0
exit 0
```

File: examples/stdin_count.stdin (no final newline)

```
alpha
beta
gamma delta

end
```

File: examples/stdin_count.stdout

```
27
4
2350
```

### structs

File: examples/structs.om

```
note structs: 8-byte cells in order, no padding; a struct is never a wire layout
note a struct line comes before the first fn
struct Pair a uint b long end
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
note swapsum: an edit parameter may be written; a view parameter may not (error 20)
fn swapsum p edit Pair to long
t = long get p a
put p a uint 7
ret add t get p b
end
fn main to int
p = new Pair 5 -12
v = swapsum p
putl v
putu ulong get p a
putu sizeof Pair
putu offsetof Pair b
putu sizeof uint
ret 0
end
```

File: examples/structs.expect

```
compile 0
exit 0
```

File: examples/structs.stdout

```
-7
7
16
8
4
```

### text

File: examples/text.om

```
note text: escapes are only backslash n, t, backslash and quote; len of a text is its byte count
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
text t "tab\there \"q\" back\\slash\n"
fn main to int
k = write 1 t 0 len t
putu len t
putu ulong get t 0
ret 0
end
```

File: examples/text.expect

```
compile 0
exit 0
```

File: examples/text.stdout

```
tab	here "q" back\slash
24
116
```

### tmp_files

File: examples/tmp_files.om

```
note tmp_files: make a directory and a file relative to the current directory, read it back, clean up
note run it in an empty scratch directory. Linux AArch64 values: O_WRONLY|O_CREAT|O_EXCL = 193,
note mode 0600 = 384, 0700 = 448, st_size at byte 48 of the 128-byte stat structure
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
text dname "scratch"
text fname "scratch/f.txt"
text body "omega\n"
global rb uchar 16
global sb uchar 128
fn main to int
r = makedir dname 0 len dname 448
putl r
fd = fopen fname 0 len fname 193 384
if lt fd 0
exit 93
end
w = write int fd body 0 len body
putl w
c = fclose int fd
putl c
fd2 = fopen fname 0 len fname 0 0
if lt fd2 0
exit 94
end
k = read int fd2 rb 0 16
putl k
c2 = fclose int fd2
s = stat fname 0 len fname sb 0 128
putl s
sz = or uint get sb 48 shl uint get sb 49 8
putu ulong sz
if gt k 0
x = write 1 rb 0 ulong k
end
u = unlink fname 0 len fname
putl u
d = rmdir dname 0 len dname
putl d
gone = fopen fname 0 len fname 0 0
putl gone
ret 0
end
```

File: examples/tmp_files.expect

```
compile 0
exit 0
```

File: examples/tmp_files.stdout

```
0
6
0
6
0
6
omega
0
0
-2
```

### trap1_overflow

File: examples/trap1_overflow.om

```
note trap1_overflow: signed add past the maximum traps 1, exit 101; stdout written before stays
text before "before\n"
fn main to int
k = write 1 before 0 len before
x = long 9223372036854775807
y = add x 1
ret 0
end
```

File: examples/trap1_overflow.expect

```
compile 0
exit 101
```

File: examples/trap1_overflow.stdout

```
before
```

### trap2_div0

File: examples/trap2_div0.om

```
note trap2_div0: integer div or rem by zero traps 2, exit 102
text before "before\n"
fn main to int
k = write 1 before 0 len before
d = uint 0
q = div uint 10 d
ret 0
end
```

File: examples/trap2_div0.expect

```
compile 0
exit 102
```

File: examples/trap2_div0.stdout

```
before
```

### trap3_bounds

File: examples/trap3_bounds.om

```
note trap3_bounds: a run-time index outside the array traps 3, exit 103
text before "before\n"
fn main to int
k = write 1 before 0 len before
a = new uint 4 0
i = ulong 4
v = get a i
ret 0
end
```

File: examples/trap3_bounds.expect

```
compile 0
exit 103
```

File: examples/trap3_bounds.stdout

```
before
```

### trap4_loop

File: examples/trap4_loop.om

```
note trap4_loop: one pass more than the bound traps 4, exit 104
text before "before\n"
fn main to int
k = write 1 before 0 len before
i = ulong 0
while lt i 10 bound 5
i = add i 1
end
ret 0
end
```

File: examples/trap4_loop.expect

```
compile 0
exit 104
```

File: examples/trap4_loop.stdout

```
before
```

### trap5_conv

File: examples/trap5_conv.om

```
note trap5_conv: a conversion whose value does not fit traps 5, exit 105
text before "before\n"
fn main to int
k = write 1 before 0 len before
x = uint 300
c = uchar x
ret 0
end
```

File: examples/trap5_conv.expect

```
compile 0
exit 105
```

File: examples/trap5_conv.stdout

```
before
```

### trap6_stack

File: examples/trap6_stack.om

```
note trap6_stack: recursion below the 8 MiB stack traps 6, exit 106
text before "before\n"
fn deep n ulong to ulong
if eq n 0
ret 0
end
ret add 1 deep sub n 1
end
fn main to int
k = write 1 before 0 len before
x = deep 100000000
ret 0
end
```

File: examples/trap6_stack.expect

```
compile 0
exit 106
```

File: examples/trap6_stack.stdout

```
before
```

### trap7_shift

File: examples/trap7_shift.om

```
note trap7_shift: a shift amount outside 0..width-1 traps 7, exit 107
text before "before\n"
fn main to int
k = write 1 before 0 len before
s = uint 32
x = shl uint 1 s
ret 0
end
```

File: examples/trap7_shift.expect

```
compile 0
exit 107
```

File: examples/trap7_shift.stdout

```
before
```

### trap_code

File: examples/trap_code.om

```
note trap_code: trap N for N in 1..14 exits 100+N; use it for your own fatal codes
text before "before\n"
fn main to int
k = write 1 before 0 len before
trap 14
end
```

File: examples/trap_code.expect

```
compile 0
exit 114
```

File: examples/trap_code.stdout

```
before
```

### unsigned_wrap

File: examples/unsigned_wrap.om

```
note unsigned_wrap: unsigned add sub mul shl neg not wrap mod 2^width; comparisons follow the type
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
m = uint 4294967295
putu ulong add m 1
putu ulong sub uint 0 1
putu ulong mul uint 65536 65536
putu ulong neg uint 1
putu ulong not uint 0
putu ulong shl uint 1 31
big = ulong 18446744073709551615
if lt big 1
ret 1
end
putu add big 1
ret 0
end
```

File: examples/unsigned_wrap.expect

```
compile 0
exit 0
```

File: examples/unsigned_wrap.stdout

```
0
4294967295
0
4294967295
4294967295
2147483648
0
```

### wire_le

File: examples/wire_le.om

```
note wire_le: there is no byte-layout type; encode and decode integers with shifts and masks
note ---- output helpers: a function works on a global by naming it (a global is never an argument)
global ob uchar 32
note outb: write ob[off .. off+n) to stdout; a short write continues, 0 or an error exits 90
note bound: every pass writes at least one byte and n <= 32, so at most 32 passes
fn outb off ulong n ulong to void
e = add off n
p = off
while lt p e bound 32
k = write 1 ob p sub e p
if le k 0
exit 90
end
p = add p ulong k
end
end
note putu: v in decimal, then a newline. A ulong has at most 20 digits, so 20 passes
fn putu v ulong to void
i = ulong 31
put ob 31 10
n = v
while true bound 20
i = sub i 1
put ob i uchar add rem n 10 48
n = div n 10
if eq n 0
break
end
end
outb i sub 32 i
end
note putl: a signed value; -(v+1)+1 avoids negating the minimum, which would trap 1
fn putl v long to void
if lt v 0
put ob 0 45
outb 0 1
putu add ulong neg add v 1 1
ret
end
putu ulong v
end
fn main to int
b = new uchar 4 0
h = uint 305419896
put b 0 uchar and h 255
put b 1 uchar and shr h 8 255
put b 2 uchar and shr h 16 255
put b 3 uchar and shr h 24 255
for i ulong 4
putu ulong get b i
end
v = or uint get b 0 shl uint get b 1 8
v = or v shl uint get b 2 16
v = or v shl uint get b 3 24
putu ulong v
note a signed 32-bit decode without integer bitcast (see omega-encoding section 5)
s = long v
put b 3 255
u = or uint get b 0 shl uint get b 1 8
u = or u shl uint get b 2 16
u = or u shl uint get b 3 24
s = long u
if ge u 2147483648
s = sub s 4294967296
end
putl s
ret 0
end
```

File: examples/wire_le.expect

```
compile 0
exit 0
```

File: examples/wire_le.stdout

```
120
86
52
18
305419896
-13347208
```

### fnv1a32

File: skills/omega-encoding/examples/fnv1a32.om

```
note fnv1a32: read all of stdin (at most 65535 bytes), write its FNV-1a 32-bit hash as 4 little-endian bytes
note exit 0 ok, 2 read error or input of 65536 bytes or more, 3 short or failed write
global inb uchar 65536
global outb uchar 4
fn rdall to long
t = ulong 0
while lt t len inb bound 65536
k = read 0 inb t sub len inb t
if lt k 0
ret k
end
if eq k 0
ret long t
end
t = add t ulong k
end
ret neg long 27
end
fn fnv n ulong to uint
h = uint 2166136261
for i ulong n
h = mul xor h uint get inb i 16777619
end
ret h
end
fn put4 h uint to void
put outb 0 uchar and h 255
put outb 1 uchar and shr h 8 255
put outb 2 uchar and shr h 16 255
put outb 3 uchar and shr h 24 255
end
fn wrall n ulong to long
d = ulong 0
while lt d n bound 4
w = write 1 outb d sub n d
if le w 0
ret w
end
d = add d ulong w
end
ret long d
end
fn main to int
r = rdall
if lt r 0
ret 2
end
h = fnv ulong r
put4 h
w = wrall 4
if ne w 4
ret 3
end
ret 0
end
```

File: skills/omega-encoding/examples/fnv1a32.expect

```
compile 0
exit 0
```

File: skills/omega-encoding/examples/fnv1a32.stdin (no final newline)

```
abc
```

File: skills/omega-encoding/examples/fnv1a32.stdout (hex bytes)

```
0b e9 47 1a
```

### trap_narrow

File: skills/omega-encoding/examples/trap_narrow.om

```
note edge: narrowing a value that does not fit traps 5, so the program exits 105
note the masked store on line 6 is fine (300 and 255 = 44); the unmasked store on line 7 traps
global b uchar 2
fn main to int
x = uint 300
put b 0 uchar and x 255
put b 1 uchar x
ret int get b 0
end
```

File: skills/omega-encoding/examples/trap_narrow.expect

```
compile 0
exit 105
```

## Checking the examples

Write every file on this page into one directory tree with the paths in the labels, then run bash examples/gate.sh /path/to/omc . The gate refuses any compiler but the pinned one. It compiles each program, runs it with an empty environment plus its .env in an empty scratch directory under a 20 second timeout, compares the exit status and the stdout bytes, requires an empty stderr, prints one PASS or FAIL line per program and ends with GATE PASS examples=N when all of them match. The aienos.com build checks that the files in llms-full.txt are these files, and om/omega-reference/llms-check.sh extracts them from llms-full.txt and runs this gate on them.

File: examples/gate.sh

```
#!/usr/bin/env bash
# gate.sh OMC: compile and run every worked example against its expected result.
#
# Covers examples/*.om and skills/*/examples/*.om. Each NAME.om needs NAME.expect:
#   compile N         required; the compiler's exit status
#   stderr LINE       required when N is not 0; the compiler's whole stderr is exactly LINE
#   exit N            required when N is 0; the program's exit status
#   input dir         optional; the compiler reads a directory instead of NAME.om (error 1)
#   output full       optional; the compiler writes to /dev/full (error 2)
# Optional fixtures: NAME.stdout (exact stdout bytes, absent means empty), NAME.stdin (piped in,
# so reads can be partial), NAME.args (one argument per line), NAME.env (one KEY=VALUE per line).
# Every program runs with `env -i` plus NAME.env, in an empty scratch directory, under a 20 s
# timeout, and must write nothing to stderr. A compile that is not expected to succeed is never run.
#
# The compiler must match the pinned sha256 below; a different binary is refused, not tolerated.
# Exit 0 only when every example passes; 1 on any failure; 2 on a usage or pin error.
set -u

PIN_REV=e5b32567a7aff3ce594e3254a622a846a6cd190b
PIN_SHA=2c82480596bbdc50cda9626866209ef662d5834f278f839ff4ce0250c495029f

if [ "$#" -ne 1 ]; then
    echo "usage: $0 /path/to/omc   (omega-mv $PIN_REV seed/out/omc)" >&2
    exit 2
fi
omc=$(cd "$(dirname "$1")" && pwd)/$(basename "$1")
if [ ! -x "$omc" ]; then
    echo "GATE FAIL $1 is not an executable file" >&2
    exit 2
fi
got=$(sha256sum "$omc" | cut -d' ' -f1)
if [ "$got" != "$PIN_SHA" ]; then
    echo "GATE FAIL omc sha256 $got, pinned $PIN_SHA (omega-mv $PIN_REV)" >&2
    exit 2
fi

here=$(cd "$(dirname "$0")" && pwd)
root=$(dirname "$here")
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

pass=0
fail=0
total=0

bad() {
    echo "FAIL $name: $*"
    fail=$((fail + 1))
}

# Expected files without a program are a silent loss of coverage, so they fail too.
for f in "$root"/examples/*.expect "$root"/skills/*/examples/*.expect; do
    [ -e "$f" ] || continue
    if [ ! -e "${f%.expect}.om" ]; then
        name=$(basename "${f%.expect}")
        total=$((total + 1))
        bad "expect file without $name.om"
    fi
done

for src in "$root"/examples/*.om "$root"/skills/*/examples/*.om; do
    [ -e "$src" ] || continue
    base=${src%.om}
    name=${base#"$root"/}
    total=$((total + 1))
    if [ ! -f "$base.expect" ]; then
        bad "no $name.expect"
        continue
    fi
    want_compile= want_stderr= want_exit= input=file output=file
    while IFS= read -r line || [ -n "$line" ]; do
        case $line in
            "compile "*) want_compile=${line#compile } ;;
            "stderr "*) want_stderr=${line#stderr } ;;
            "exit "*) want_exit=${line#exit } ;;
            "input dir") input=dir ;;
            "output full") output=full ;;
            "") ;;
            *) want_compile=invalid ;;
        esac
    done < "$base.expect"
    case $want_compile in
        ''|invalid|*[!0-9]*) bad "malformed $name.expect"; continue ;;
    esac
    if [ "$want_compile" != 0 ] && [ -z "$want_stderr" ]; then
        bad "$name.expect has no stderr line"; continue
    fi
    if [ "$want_compile" = 0 ]; then
        case $want_exit in
            ''|*[!0-9]*) bad "$name.expect has no exit line"; continue ;;
        esac
    fi

    d=$work/$(echo "$name" | tr / _)
    mkdir -p "$d/run"
    in=$src
    [ "$input" = dir ] && in=$d/run
    out=$d/p
    [ "$output" = full ] && out=/dev/full
    "$omc" < "$in" > "$out" 2> "$d/cerr"
    rc=$?
    if [ "$rc" != "$want_compile" ]; then
        bad "compile exit $rc, expected $want_compile: $(cat "$d/cerr")"
        continue
    fi
    if [ "$want_compile" != 0 ]; then
        if printf '%s\n' "$want_stderr" | cmp -s - "$d/cerr"; then
            echo "PASS $name (compile $rc: $want_stderr)"
            pass=$((pass + 1))
        else
            bad "compiler stderr '$(cat "$d/cerr")', expected '$want_stderr'"
        fi
        continue
    fi
    if [ -s "$d/cerr" ]; then
        bad "compiler stderr not empty: $(cat "$d/cerr")"
        continue
    fi

    chmod +x "$d/p"
    args=()
    envs=()
    if [ -f "$base.args" ]; then mapfile -t args < "$base.args"; fi
    if [ -f "$base.env" ]; then mapfile -t envs < "$base.env"; fi
    if [ -f "$base.stdin" ]; then
        (cd "$d/run" && cat "$base.stdin" | timeout 20 env -i "${envs[@]}" "$d/p" "${args[@]}" > "$d/out" 2> "$d/rerr")
    else
        (cd "$d/run" && timeout 20 env -i "${envs[@]}" "$d/p" "${args[@]}" < /dev/null > "$d/out" 2> "$d/rerr")
    fi
    rc=$?
    want_out=/dev/null
    [ -f "$base.stdout" ] && want_out=$base.stdout
    if [ "$rc" != "$want_exit" ]; then
        bad "exit $rc, expected $want_exit"
    elif ! cmp -s "$want_out" "$d/out"; then
        bad "stdout differs from $(basename "$want_out"): $(od -An -c "$d/out" | tr -s ' ' | tr -d '\n' | cut -c1-200)"
    elif [ -s "$d/rerr" ]; then
        bad "program stderr not empty: $(cat "$d/rerr")"
    else
        echo "PASS $name (exit $rc, $(wc -c < "$d/out" | tr -d ' ') stdout bytes)"
        pass=$((pass + 1))
    fi
done

if [ "$total" = 0 ]; then
    echo "GATE FAIL no examples found under $root"
    exit 1
fi
if [ "$fail" = 0 ] && [ "$pass" = "$total" ]; then
    echo "GATE PASS examples=$total pass=$pass fail=0 omc=$PIN_SHA"
    exit 0
fi
echo "GATE FAIL examples=$total pass=$pass fail=$fail omc=$got"
exit 1
```

## Sitemap

See the full [sitemap](https://www.aienos.com/sitemap.md) for every page on aienos.com.
