Omega

Omega language reference

Everything an agent needs to write Omega that the pinned compiler accepts and that does what it should: program shape, types, declarations, statements, words, OM-2, the host words, every compiler error and trap exit code, common mistakes, and 98 worked examples that each passed the examples gate.

An Omega program writes this page: om/omega-reference/page.om in the aienos.com repository reads the guide skills/writing-omega/SKILL.md and the examples of omega-harness commit 0aba14876fdd8d65cc886a8b5dc0984f16bb4a0e and prints every file byte for byte. The compiler pin is omega-mv e5b32567a7aff3ce594e3254a622a846a6cd190b, omc sha256 2c82480596bbdc50cda9626866209ef662d5834f278f839ff4ce0250c495029f. The same text is in llms-full.txt.

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 and of this repository. Every rule below was observed with a program at the pin in the table; the programs are in examples/ and 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.

PinValue
omega-mv commite5b32567a7aff3ce594e3254a622a846a6cd190b
compiler seed/out/omcsha256 2c82480596bbdc50cda9626866209ef662d5834f278f839ff4ce0250c495029f
language referencedocs/one_layer/OMEGESE.md at that commit
hostLinux 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). 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, 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):

FormWhereNotes
note ANY TEXTany linea comment line
om2, om2 debug, om2 release, om2 diag, om2 diag debug, om2 diag releasefirst line that is not blank or noteopts the unit into OM-2 (section 9); release erases contract checks, diag adds a machine-readable stderr record
om2 fmtthe first line, at byte 0prints the canonical text of the rest of the input instead of compiling it
text NAME "bytes"top levela read-only uchar array
global NAME T Ntop level, program modezero-filled array, never an argument
const NAME T LITERALtop levelan integer or float value, visible after its line
struct S f1 T1 f2 T2 ... endtop level, before the first fnone line; a field f T N is an array of 1..64
layout NAME SIZE, field F T [COUNT] at OFF little/big lines, endOM-2, top level, before the first fnan external byte layout of SIZE 1..4096 bytes
abstract NAME T [ops W ...], holds NAME dup32OM-2, top level, before the first fnT uint or ulong; W from rotr rotl and or xor
fn NAME p1 T1 ... to R ... endtop levelinline after R in OM-2; export fn marks an OM-2 function-mode entry
parameter p Tfn linea scalar
parameter a view T N / a edit T Nfn linea sized array, read-only or writable
parameter a view T * / a edit T *fn line, OM-2an array of any length
parameter s edit T N freshfn line, OM-2scratch: every element written before it is read
parameter p view S / p edit Sfn linea struct, or an OM-2 layout
parameter o out T Nfn line, OM-2written by the unit; the calling host copies it out after status 0
name = valuefunction bodythe first assignment creates the name
put A i v, put p f vfunction bodystore into an array element or a field
f v1 v2 ...function bodya call to a void function
if C ... else ... endfunction bodyelse is optional; no else if
while C bound N ... endfunction bodyN 1..999999
for i T K ... endfunction bodyunroll after K in OM-2, K 1..64
break, continueinside a loop
ret, ret vfunction bodyret v in a function with a result
exit N, trap Nfunction bodyexit status N; trap N 1..14 exits 100+N
requires C, ensures COM-2, the first lines of a functionresult names the returned value
invariant COM-2, the first line of a loop body

3. Types and values

TypeMeaning
booltrue / false, the result of comparisons
uchar, ushort, uint, ulongunsigned 8, 16, 32, 64 bit (also spelled u8 u16 u32 u64)
byte, short, int, longsigned 8, 16, 32, 64 bit (also spelled i8 i16 i32 i64); byte is signed, and char is not a type (error 3)
f32, f64IEEE binary32, binary64
voidno 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

KindWords
arithmeticadd sub mul div rem neg
bitsand or xor not shl shr (rotr rotl in OM-2)
compare (give bool)eq ne lt le gt ge
floatadd sub mul div neg, fsqrt fabs fmin fmax
arraysnew, get A i, put A i v, len A
structsnew S v1 v2 ..., get p f, put p f v
controlif / else / end, while COND bound N, for i T K, break, continue, ret, exit, trap N
conversionthe type words, bitcast T v
I/Oread 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). Compare first when you want a bool.
  • and / or on bools evaluate both sides; there is no short circuit (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.

CauseTrapExitExample
signed overflow in add sub mul neg1101examples/trap1_overflow.om
div or rem by zero, and signed minimum divided by -12102trap2_divzero.om
array index or I/O slice out of bounds3103trap3_bounds.om
a loop past its bound4104trap4_loop.om
an integer conversion whose value does not fit5105trap5_conv.om
stack exhausted (8 MiB) by calls or local arrays6106trap6_stack.om
shift or rotate amount outside 0..width-17107trap7_shift.om
a contract check that fails (OM-2)9, 10109, 110contract_requires.om, contract_ensures.om
trap N, N 1..14N100+Ntrap_code.om (trap 14, exit 114)
  • Unsigned arithmetic wraps modulo 2^width and never traps (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). 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).
  • Bytes on the wire: build them with shifts and masks into a uchar array (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).

Examples: om2_tour.om, om2_views.om, om2_hex_rotr.om, 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).
  • 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) and the environment with envcnt and envread (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.

AreaWords
filesfopen 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
pathschmod 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
processesgetpid, 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, randomnessargcnt, argread index A off capacity, envcnt, envread index A off capacity, random A off n flags
timemonons, realns, sleepns interval
socketssocknew 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.

CodeMeaningExampleFix
1omc could not read its inputerr01_input (stdin is a directory)give omc a readable file on stdin
2omc could not write its outputerr02_output (stdout is /dev/full)send stdout to a writable file with space
3unknown name, field or functionerr03_unknown_nameassign the name before use; check the spelling
4the line ends before the statement is completeerr04_line_endsgive every word all of its values
5words left after a complete statementerr05_extra_wordscount each word's values; there is no infix
6malformed numbererr06_bad_numberdecimal digits; hex only in OM-2, lowercase
7type mismatcherr07_type_mismatchconvert with a type word: add int 1 int u
8number out of rangeerr08_out_of_rangea literal that fits its type; a bound 1..999999; a trap code 1..14
9a word in a place where it is not allowederr09_disallowedmove it: new only in a function's outermost block, struct before the first fn
10duplicate nameerr10_duplicatechoose a name that is not visible, not a function, not a struct
11a number with nothing to give it a typeerr11_ambiguousx = uint 5
12register pool exhausted (16 per function)err12_registersfewer live names, a helper function, shorter expressions (section 8)
13name too longerr13_long_nameat most 8 characters (function names 63)
14compiler capacity: names, functions, exports, expansionerr14_capacitysplit the function or the unit
15the input ends inside an open blockerr15_missing_endclose every block with end
16syntax: unknown word or misplaced formerr16_syntaxstart each line with a statement word; comments are note lines
17a line after ret, break, continue, trap or exit in the same blockerr17_after_pathdelete the line or move it above
18a function with a result whose end is reachableerr18_missing_retend every path with ret v
19a global as an argument, or one array twice in a callerr19_global_argname the global inside the function; pass distinct arrays
20writing to a text or a viewerr20_readonlyan edit parameter, or a local copy
21a literal index outside the arrayerr21_const_indexan index 0..N-1
22a text escape other than \n \t \\ \"err22_text_escapebuild other bytes with put
23array or pool size limiterr23_sizesmaller arrays (section 8 limits)
24a conditional branch farther than 1 MiB of codegenerated, belowmove long bodies into functions
25, 26never emitted at the pinnonenone
27OM-2 fresh element read before it is writtenerr27_freshput every element before the get
28OM-2 seal outside the constructorerr28_sealseal only as the whole body of fn NAMEmk ... to NAME
29OM-2 layout field past the size or overlappingerr29_layoutkeep every field inside SIZE and apart
30OM-2 contract clause not allowederr30_contractinteger 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.

MistakeWrite insteadRefusalExample
y = x + 1y = add x 1error 5mistake_infix.om
f(1, 2)f 1 2error 6mistake_c_call.om
if x > 0if gt x 0error 7mistake_compare_operator.om
'A'uchar 65error 3mistake_char_literal.om
// commentnote commenterror 16mistake_slash_comment.om
x = 1;x = uint 1error 6mistake_semicolon.om
return xret xerror 18 (silent assignment)mistake_return.om
else if celse, then a nested if cerror 5mistake_else_if.om
fn main argc int to intargcnt, argreaderror 9mistake_main_args.om
for i ulong n bound 10while lt i n bound 10error 5mistake_for_bound.om
while c bound 1000000a bound 1..999999error 8mistake_bound_range.om
a = new uchar n 0a literal or const lengtherror 16mistake_new_var_len.om
free anothing: no heaperror 9mistake_free.om
len = ...another nameerror 16mistake_reserved_name.om
neg = ... or text neg "a"another name: neg is the negation worderror 16mistake_neg_name.om
a bare call f 1 with a resultv = f 1error 7mistake_value_stmt.om
a 7th parametera struct or an arrayerror 9mistake_seven_params.om
2 view T * plus 3 scalars (7 slots)a sized view, a struct, or fewer scalarserror 9mistake_om2_param_slots.om
emit buf with buf a globalname the global inside the functionerror 19err19_global_arg.om
a view uchar 8 given a 16-element arraythe exact length, or OM-2 view uchar *error 7mistake_param_length.om
trap 15trap 1 .. trap 14error 8mistake_trap_range.om
struct after a fnevery struct before the first fnerror 9mistake_struct_after_fn.om
rotr or hex without om2an om2 first lineerror 3mistake_om1_rotr.om
0X10 or 0xFF0x10, 0xfferror 6mistake_om2_upper_hex.om
int 0xffffffffint -1error 8mistake_om2_int_hex.om
part of a globalpart of a localerror 19mistake_om2_part_global.om
part to a sized parameteran unsized view T * parametererror 7mistake_om2_part_sized.om
s = part a 0 2part only as an argumenterror 9mistake_om2_part_statement.om
if and lt i n eq get a i 0 (C short circuit)an outer if lt i ntrap 3, exit 103mistake_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 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).
  • 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).
  • 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/; 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.

  • 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

Say hello to Aien?

Hey, you just clicked an ad. I just want you to know that if you didn't intend to click an ad, that's cool. Just click No and this popup will close. Nothing will be tracked by my X pixel. Your browser may not let me close a page I didn't open.

Privacy, what X receives, and your choice