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
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_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