Zahlen

Zahlen is a stack-based processor specification discovered by User:Orby during March of 2019 (and revisited during February of 2021). Zahlen is particularly suited toward solving numerical problems in a small amount of space. This page is a work in progress. Many operators are yet undocumented. Please contribute comments and ideas on the discussion page.
==Introduction==
Zahlen is intended for use in code golf competitions involving numbers. Each Zahlen instruction is represented by an 8-bit code. This makes Zahlen instructions more compact, but also restricts the number of available instructions. The codes 0xA0 through 0xFF are reserved for future expansion.
==Types==
Zahlen operates on two types: logicals and numericals. Logical values are matrices whose cells are 32-bit unsigned integers. Operations performed on logical values are performed bit-wise. Numerical values are matrices whose cells are IEEE 754 double precision floating point values. In this documentation, matrices are enclosed in brackets.
==Opcodes==
What follows is a comprehensive list of opcodes.
===Unary operators===
Each unary operator pops a value from the stack which we refer to here as A. The i,j-th cell of A is referred to as ai,j. The value pushed is dependent upon the type of A and the operator selected. Each operation is named after its effect on a numerical.
====Count====
Pneumonic: count
If A is not 1 x 1 or a1,1 is zero, then the result is undefined.
0x80 	Result
Logical 	[ 1, 2, ..., a1,1 ] for 1 x 1 matrix A
Numerical	[ 1, 2, ..., floor(a1,1) ] for 1 x 1 matrix A
====Increment====
Pneumonic: inc
0x81 	Result
Logical 	[ ai,j + 1 ]
Numerical	[ ai,j + 1 ]
====Decrement====
Pneumonic: dec
0x82 	Result
Logical 	[ ai,j - 1 ]
Numerical	[ ai,j - 1 ]
====Negate====
Pneumonic: neg
Alternate pneumonic: not
0x83 	Result
Logical	[ not ai,j ]
Set 	[ -ai,j ]
==== Cast ====
Pneumonic: cast
0x84 	Result
Logical 	A as numerical (no precision lost)
Numerical	A as logical (floor(ai,j))
==== Transpose ====
Pneumonic: trans
0x85 	Result
Logical 	[ aj,i ]
Numerical	[ aj,i ]
==== Sign ====
Pneumonic: sign
0x86 	Result
Logical 	[ sign(ai,j) ]
Numerical	[ sign(ai,j) ]
===Trigonometric functions===
These operators all push numerical results.
====Sine====
Pneumonic: sin
0x87 	Result
Logical 	[ ai,j << 1 ]
Numerical	[ sin(ai,j) ]
====Cosine====
Pneumonic: cos
0x88 	Result
Logical 	[ ai,j >> 1 ]
Numerical	[ cos(ai,j) ]
===Binary operators===
All binary operators in Zahlen pop two arguments from the stack and push the result. The first argument on the stack is represented as A and its type is provided in the first column of each table. The second argument on the stack is represented as B and its type is provided in the first row of each table. The operation performed depends upon the types of those arguments. Each operation is named after its effect on two numericals. If A is 1 x 1 and B is m x n, then A is expanded to m x n and filled with a1,1.
====Addition====
Pneumonic: add
Alternate pneumonic: xor
0x8A 	Logical 	Numerical
Logical 	[ ai,j xor bi,j ]	[ ai,j + bi,j ]
Numerical	[ ai,j + bi,j ] 	[ ai,j + bi,j ]
====Subtraction====
Pneumonic: sub
0x8B 	Logical 	Numerical
Logical 	[ ai,j xor bi,j ]	[ ai,j - bi,j ]
Numerical	[ ai,j - bi,j ] 	[ ai,j - bi,j ]
====Multiplication====
Pneumonic: mul
0x8C 	Logical 	Number
Logical 	[ (ai,1 and b1,j) xor (ai,2 and b2,j) ... ]	[ (ai,1 * b1,j) + (ai,2 * b2,j) ... ]
Numerical	[ (ai,1 * b1,j) + (ai,2 * b2,j) ... ] 	[ (ai,1 * b1,j) + (ai,2 * b2,j) ... ]
====Pointwise Multiplication====
Pneumonic: pmul
Alternate pneumonic: and
0x8D 	Logical 	Number
Logical 	[ ai,j and b1,j ]	[ ai,j * bi,j ]
Numerical	[ ai,j * bi,j ] 	[ ai,j * bi,j ]
====Pointwise Division====
Pneumonic: pdiv
Alternate pneumonic: or
0x8E 	Logical 	Numerical
Logical 	[ ai,j or bi,j ]	[ ai,j / bi,j ]
Numerical	[ ai,j / bi,j ] 	[ ai,j / bi,j ]
====Remainder====
Pneumonic: mod
0x8F 	Logical 	Numerical
Logical 	[ ] 	[ ai,j % bi,j ]
Numerical	[ ai,j % bi,j ]	[ ai,j % bi,j ]
====Power====
Pneumonic: pow
Alternate pneumonic: <<
The notation << denotes left shift.
0x90 	Logical 	Numerical
Logical 	[ ai,j << bi,j ]	[ ai,jbi,j ]
Numerical	[ ai,jbi,j ] 	[ ai,jbi,j ]
====Logarithm====
Pneumonic: log
Alternate pneumonic: >>
The notation >> denotes right shift.
0x91 	Logical 	Numerical
Logical 	[ ai,j >> bi,j ] 	[ logai,j(bi,j) ]
Numerical	[ logai,j(bi,j) ]	[ logai,j(bi,j) ]
===Matrix manipulation===
These operations are for decomposing and building matrices.
====Car====
Pneumonic: car
Notice this pushes two results: the first row of A and A with the first row removed.
00x92 	Result
Logical 	[ a1 ], [ a2, a3, ... ]
Numerical	[ a1 ], [ a2, a3, ... ]
====Cons====
Pneumonic: cons
This is the opposite of car. It takes two matrices and concatenates them row-wise. A must have the same number of columns as B.
0x93 	Logical 	Numerical
Logical 	[ A, B ]	[ A, B ]
Numerical	[ A, B ]	[ A, B ]
===Subroutines===
TODO Think about passing a column vector of addresses to call for concurrent function calls.
====Call====
Pneumonic: call
Opcode: 0x94
Pop A from the stack. If A is 1 x 1, then call the subroutine at a1,1.
====Return====
Pneumonic: ret
Opcode: 0x95
Return from subroutine.
===Ternary operator===
Pneumonic: if
Opcode: 0x96
Pops three arguments off the stack A, B, and C.
If A, B, and C are logical then the result is the logical [ (ai,j and bi,j) or (not ai,j and ci,j) ].
If A, B, or C are numerical, then the result is the numerical [ ai,j != 0 ? bi,j : ci,j ]
===Memory operators===
====Store====
Pneumonic: st
If A is 1 x 1, then write B sequentially starting at a1,1. Otherwise the dimensions of A and B must match.
0x97 	Result
Logical 	Write bi,j to address ai,j.
Numerical	Write bi,j to address ai,j.
====Load====
Pneumonic: ld
0x98 	Result
Logical 	Push matrix whose i,j-th cell is the memory contents of address ai,j.
Numerical	Push matrix whose i,j-th cell is the memory contents of address ai,j.
===Miscellaneous operators===
The following operators manipulate the stack and control flow.
Encoding 	Pneumonic 	Description
0x99 	swap 	Swap top two arguments on the stack.
0x9A 	drop 	Pop the stack,
0x9B 	dup 	Duplicate the element on top of the stack.
0x9C 	rot 	Pop A. If A is n x 1, then rotate the first a1,1 elements of the stack, then rotate the first a2,1 elements of the stack, etc.
0x9D 	jz 	Pop A. Pop B. If a is 1 x 1 and B does not contain any non-zero values, then set IP to a1,1.
0x9F X 	128, ..., 65535	Push 16-bit immediate value to stack as 1 x 1 logical.
b0xxxxxxx	0, 1, ..., 127 	Push 7-bit immediate value xxxxxxx to the stack as 1 x 1 logical.
==Examples==
Assuming display is 256 x 256 and mapped to the first 65,536 memory addresses in the normal way.
===Reverse first n elements on stack===
 n count rot
3 bytes.
===AND pattern===
 256 ; [ 256 ]
 count dup ; [ 1, ..., 256 ], [ 1, ..., 256 ] logical column vectors
 trans mul ; [ x and y ]
 0 st ; Write [ x and y ] to 0x00000000
9 bytes.
===Extract bits from logical===
Suppose a 1 x 1 logical x is on the stack.
 32 count sign swap cast pmul cast ; [ x, x, ..., x (32 times) ]
 32 count dec cast 2 pow cast ; [ 1, 2, 4, 8, ..., 2^31 ], [ x, x, ..., x (32 times) ]
 and sign ; [ x[0], x[1], x[2], ..., x[31] ]
15 bytes.
==See also==
* GolfScript is the canonical golfing language.
* Jelly, Pyth, and CJam are also quite popular.
* FlogScript is an interesting golfing language, too.
Category:Golfing language
Category:Stack-based
Category:2019
Category:Languages