Language Reference

Cryn 0.3.0. The definition of every word of the language is the table below. Supplementary tables follow for types, literals, conditions, open modes, defined behavior, limits, and diagnostics.

Ground rules, briefly: a program is one file of world cells and transformations. Whitespace has no meaning. Comments are [# ... #]. Names are letters, digits, and underscores, starting with a letter or underscore, case sensitive; every word in the tables below is reserved. Execution starts at main, which takes no parameters. Every program can be written on one line.

The language

Legend: wv is the working value. "stack" is the value stack. "focus" is the focused cell. Read the "needs" column as a compile time requirement unless the faults column says runtime.

GroupWordFormsNeedsDoeswv afterFaults
navigationmovemove namea cell name in frame or worldfocuses name, resets focus historyunchangedcompile: unknown cell
navigationmovemove nfocus on array, n in rangefocuses element nunchangedcompile: not an array, index out of range, negative or over 2^31-1
navigationmovemove indexfocus on array, wv an integerfocuses element number wvunchangedcompile: not an array, wv not integer. runtime: index out of bounds
navigationmovemove atwv an addressfocuses the cell at that addressunchangedcompile: wv not an address
navigationbackbackfocus deeper than frame rootundoes one relative moveunchangedcompile: already at root
navigationhomehomenothingfocus to frame root, history clearedunchangednever
addressesaddressaddressfocus not on frame rootwv becomes address of focused celladdress of cell typecompile: frame root
addressesaddressaddress namea cell or transformation namewv becomes its address, or a transform referenceaddress type, or transformcompile: no such name
addressesaddress(arithmetic) add n, subtract n, or stack formswv an address and other operand an integer, or both addresses for subtractmoves address by n elements, or gives element distanceaddress, or int64 for address minus addresscompile: other operations on addresses, mixed operands
cellsmakemake <type> [name]a scalar typenamed: zeroes the frame cell. unnamed: allocates one zeroed heap cellunnamed: address of the cellcompile: unsized array cell
cellsmakemake array n of <type> [name]n at least 1named: zeroes the array cell. unnamed: allocates on heapunnamed: address of arraycompile: bad size or element
cellsmakemake string "text" [name]string on one linenamed: fills the cell with text plus a zero byte. unnamed: uses a static writable byte arrayunnamed: address of bytesnever
cellsmakemake <size> of <type> [name]size: literal or integer cell name; element a value typeallocates a zeroed heap block of size elements; optional trailing name binds the address into a celladdress of unsized array of elementcompile: array or transform element. runtime: negative or oversized count, out of memory
cellsmaketop level make ...outside all transformationscreates a world cell, zeroed, or string filledn/acompile: duplicate name, name collides with transformation, unsized array
cellsfreefreewv an address of a heap blockreleases the blockunchangedcompile: wv not an address. runtime: not a heap block, null address
cellsreadreadfocus on a single cellwv becomes the cell value, with the cell typethe cell typecompile: frame root or array in focus
cellswritewritefocus on a single cell, wv same type, or integer literal that fits, or float64 into float32stores wv into the cellunchangedcompile: frame root or array in focus, type mismatch
wvsetset <literal>any literal, or set nothingwv becomes that literalthe literal type, or nothingcompile: no literal given
wvaddadd [literal]numeric operands, matching typeswv = wv + other (literal or popped)the pair typecompile: non numeric, mixed types needing convert, literal out of range. runtime: division class errors do not apply
wvsubtractsubtract [literal]same as addwv = wv - otherthe pair typeas add
wvmultiplymultiply [literal]same as addwv = wv * otherthe pair typeas add
wvdividedivide [literal]same as addwv = wv / other, cut toward zerothe pair typecompile: constant zero divisor. runtime: division by zero
wvremainderremainder [literal]same as addwv = remainder of wv / other, sign of wvthe pair typecompile: constant zero divisor. runtime: remainder by zero
wvnegatenegatewv a signed integer or floatwv = -wvsame typecompile: unsigned or non numeric
stackpushpushnothingputs wv on the stackunchangedcompile: stack deeper than 4096
stackpoppopnon empty stackwv becomes the top stack valuethat slot's typecompile: empty stack
stackswapswapnon empty stackexchanges wv with the stack topold topcompile: empty stack
comparisoncomparecompare [literal]numeric or char or bool wv, or address against address or nonnegative literal; other from literal or stackremembers the three way answerunchangedcompile: empty stack, incompatible operands
conversionconvertconvert <type>scalar wv, scalar targetchanges wv type, wrapping integers, saturating floats, reusing bits for address pairstarget typecompile: arrays, transform refs, nothing, float to address or back
controljumpjump labela label in this transformationcontinues at the labelunchanged at the label, joinedcompile: unknown label
controljumpjump label when condlabel plus a valid comparison on every pathjumps only when the remembered comparison matches condjoined at the labelcompile: unknown label, no comparison in reach
controlcallcall namearguments pushed left to right, matching typesruns the transformation, pops the argumentsits result, or unchanged if result is nothingcompile: wrong argument count or types, unknown name
controlcallcallwv a transform referenceruns it if it takes no parametersunchanged, result discardedruntime: reference to a transformation with parameters
controlreturnreturnempty stack, one result typeends the transformation, wv is the resultn/acompile: stack not empty, result type disagrees with other returns or the declaration
controlstopstopnothingends the program, exit code wv and 0xFFn/anever
ioinputinputnothingreads one byte from the current input streamint64, or -1 at endnever
iooutputoutputnumeric, bool, char, or address wvprints wv to the current output stream, no separatorunchangedcompile: nothing, array, transform
iooutputoutput textwv address to bytes or byte arrayprints the bytes at wv up to the first zerounchangedcompile: wv not a byte address
filesopenopen readwv address to a zero ended pathopens for reading, wv becomes the handleint64 handle, 1 or more, or -1runtime: none, failure gives -1
filesopenopen writeas aboveopens for writing, truncatesint64 handle or -1as above
filesopenopen bothas aboveopens for reading and writing, truncatesint64 handle or -1as above
filesopenopen appendas aboveopens for writing at the endint64 handle or -1as above
filesuseusewv an integer handleroutes input from the readable side, output to the writable side; unsupported sides keep their streamunchangedruntime: handle not open in this context
filesuseuse nn a nonnegative literalsame, with handle n; use 0 selects keyboard and terminalunchangedcompile: negative literal. runtime: handle not open
filesflushflushnothingpushes buffered bytes of the output stream outunchangedruntime: flush failure
filesseekseek [n]an open handle routed with use; n a nonnegative literal or an integer wvpositions the handle's streams at byte offset n (or wv) from the start; both sides of an open both stream are one file and move togetherint64: 0 success, -1 failurecompile: negative literal, wv not an integer. runtime: no current stream belongs to a handle
filescloseclosewv an integer handlecloses it, streams routed through it return to standardint64, 0 success, -1 close errorruntime: handle not open, closing 0
externalsystemsystemwv address to a zero ended commandruns it with the system shellint64 status from the hostnever
concurrencyspawnspawn namea zero parameter transformationstarts a thread running it in a fresh contextunchangedcompile: parameters, unknown name. runtime: more than 256 outstanding
concurrencywaitwaitnothingjoins every context this one spawnedint64 0never
atomicsexchangeexchangefocus a single cell of at most 8 bytes; wv exactly the cell type, or an integer literal that fits, or float64 into float32swaps wv with the cell in one indivisible acquire release stepthe cell typecompile: frame root, array, nothing, transform cell, type mismatch
programdefinedefine name {type param}... [result type]unique namedeclares a transformation; the body runs until endn/acompile: duplicate, array parameter or result
programendendinside a definecloses the transformationn/acompile: stray end
programmarkmark labelunique label in this transformationplaces a jump targetunchanged at the label, joinedcompile: duplicate or unreachable label

Conditions for jump ... when: less, equal, greater, different, less-or-equal, greater-or-equal. They read the answer left by compare, which compares wv with the other value.

Types

Type wordSizeValues
nothing0no value
bool1false, true
char1one byte, 0 to 255
int8 int16 int32 int641, 2, 4, 8signed whole numbers
uint8 uint16 uint32 uint641, 2, 4, 8unsigned whole numbers
float32 float644, 8IEEE 754 floats
address <type>8location of one <type>, or of nothing for a bare address
array n of <type>n times elementfixed row of cells; array of <type> without n only as a pointee of an address, meaning a runtime sized block
transform16a transformation reference for indirect call

Integer literal typing: a plain literal like 5 keeps its exact value until it meets a concrete type, then widens if it fits. Two plain literals together give int64. Joining a literal with a float type is rejected; materialize with set or convert first.

Literals

FormExamplesNotes
integer0, 42, -7decimal, magnitude up to 2^64-1
hexadecimal0x1F, 0xFFffno negative hex
float2.5, 0.5e-2, 1e3digit required both sides of the dot
character'a', '\n', '\''exactly one character or escape
string"hi\n"one line, zero ended when stored
booleantrue, false

Escapes in characters and strings: \n \t \r \0 \\ \' \".

Open modes

ModeOpens asReadingWritingPosition
read"rb"yesnostart
write"wb"noyesstart, content discarded
both"w+b"yesyesstart, content discarded
append"ab"noyesend, content kept

Handle numbers run 1 to 256 per context, are plain integers, and a closed handle's number may be handed out again. Handle 0 is the standard keyboard and terminal. Spawned contexts have their own tables and cannot use the parent's handles. seek is the positioning command: it works on the current streams of one context and only when those streams belong to an open handle. Standard streams cannot be positioned.

Defined behavior

SituationDefinition
integer overflowwraps modulo the width
division or remainder by zeroruntime abort
minimum integer divided by -1wraps to itself, no abort
float division by zeroIEEE infinity or NaN
float remainderC fmod semantics
float to integer conversionsaturates at the target range
integer conversionskeep the low bits
indexing out of rangeruntime abort naming index and size
freeing, or bounds checking through, a stale address (already freed, shifted into a block, or never a block)runtime abort; never an undefined read
freeing a non heap addressruntime abort
racing load or store, cell of 8 bytes or lessyields some value of the cell's type, never a torn mix
racing access to 16 byte transform cellsundefined
ordering between threadsonly wait and exchange
mixing reads and writes on one open both fileposition with seek between direction changes; without it behavior follows the host C library
exchangeindivisible, acquire release, never tears
exit statusstop value and 0xFF, 0 at normal end of main, 1 on runtime abort

Output formats

TypePrinted as
signed integers-5
unsigned integers18446744073709551615
floatsshortest digits that round trip, 2.75, nan
booltrue, false
char, uint8one raw byte
address0x7ffd00 style hexadecimal
integer literalsigned if it fits int64, else unsigned

Limits

LimitValue
focus history per context1024 entries
labels per transformation4096
cells per transformation4096
value stack depth proved by the checker4096
open files per context256
outstanding spawned contexts per context256
one make <size> of allocation16 TiB (2^44 bytes), overflow safe
distinct types in one programmemory bound

Diagnostics

Compile errors print file:line:col: error: message and list every problem found. Runtime aborts print cryn: runtime error: message and exit with code 1.

The language