XXIIVV

Uxntal Notation

The Uxntal notation follows that of the Forth programming language, where each item on the left of the -- spacer is the state of the stack before, and to the right, the state of the stack after:

@routine ( a b -- a b c )
	ADDk JMP2r

By default, single items are a byte long, and shorts are indicated with a * suffix, the order in which they appear is the order of the stack with the top item to the right:

@routine ( a b* -- b* a )
	ROT JMP2r

The dot notation is used to indicate that stack effects to the right of the dot are happening on the return stack:

@routine ( a . b -- c )
	STHr ADD JMP2r

If a routine is a vector, it uses the arrow notation.

@on-event ( -> )
	BRK

Validation

Program validation is done at compile-time by comparing a routine's stack effect, against the resulting balance of all stack changes occurring in the routine's code. Words that do not pass the stack-checker are generating a warning, and so essentially this defines a very basic and permissive type system that nevertheless catches some invalid programs and enables compiler optimizations. For more details, see Uxnbal.

The simplest case is when a piece of code does not have any branches or recursion, and merely pushes literals and calls words. The stack effect routines is always known statically from the declaration.

@add-eight ( a -- a+8 )
	#0008 ADD JMP2r
Working-stack imbalance of +1, in add-eight.

In the case of branching, each branch is evaluated and if an imbalance occurs inside one of the branches, the branch name is indicated:

@branching ( a* -- c )
	LDAk #01 EQU ?&one
	LDAk #02 EQU ?&two
	POP2 #ff JMP2r
	&one ( a* -- c ) POP2 #12 JMP2r
	&two ( a* -- c d ) ADD JMP2r
Working-stack imbalance of -1, in branching/two.

In the case of a recursion, the validator will use the stack effect instead of repeatedly walking through the body of the routine.

@print-string ( str* -- )
	LDAk DUP ?{ POP POP2 JMP2r }
	emit-letter 
	INC2 !print-string

For loops that exits without affecting the stack depth, a > prefixed label is used as a shorthand to reduce the need for extraneous stack effect definitions in cases where it can be inferred:

@many-times ( a -- )
	DUP
	&>l
		INC DUP ?&>l
	POP2 JMP2r

Routines that pull items from the stack beyond their allowed depth will also raise a warning, making the stack effect act a sort of boundary:

@shallow ( a -- )
	POP2 JMP2r
Working-stack depth error of 1, in shallow.

Lastly, a runtime specific solution to validate the stack state at any one point during the execution of a program, is to read the System/wst port and compare it against a given stack pointer byte value.

@on-reset ( -> )
	#abcd DUP2 
	.System/wst DEI #05 EQU ?{
		#01 .System/debug DEO }
	BRK

Comments

A comment starts with any token beginning with opened parenthesis, and ends at its corresponding closed parenthesis. Comments may be nested, the enclosed comments parentheses must be whitespace separated on both sides.

( ( nested ) )
( 1+2*(4/3) )

Outermost comments may be named, which means that sometimes the open parenthesis is immediately followed by a word used to indicates some meaning to external tools.

(doc
	This is a docstring. )

Brackets

The square brackets do nothing, they are there merely for readability and formatting, they are useful for making explicit certain things like grouping behaviors, joining literals or indicating lookup tables.

@routine ( -- )
	[ LIT2 20 -Console/write ] DEO JMP2r

%min ( a b -- r ) {
	GTHk [ JMP SWP ] POP }

@sprite [ 00 66 ff ff ff 7e 3c 18 ]

incoming drifblim uxntal syntax uxntal reference uxnfor 2023