Macmac
Macmac is an esoteric programming language created by user:David.werecat in which every command is a function and loops are emulated using macros.
Instructions
To store values, there are two stacks and one storage register. All values are integer. Each line is executed sequentially. Each line must either be blank, null (an alias for 0), or a function. The parameters of a function may be null, an integer or another function. Functions are written using the syntax: name(parameter1,parameter2,...)
. Using a function as a parameter will pass its return code as the parameter. Macros are defined as: <name>{value}
. Macros can be defined anywhere in the code, even in function parameters (in which case null is passed as the parameter). Macros can only be executed if they are defined beforehand by using: [name]
. A macro usage can be put inside another macro even if that macro is not defined yet. Loops are achieved using macros that contain themselves. To comment a line, put >>
at the front of the line. All spaces and tabs are not interpreted. Usable functions are as follows:
Name | Parameter Count | Return Value | Description |
---|---|---|---|
store | 1 | Parameter 1 | Stores the value in parameter 1 in the storage register |
recall | 0 | Storage Register | Returns the value in the storage register |
peek1 | 0 | Stack1 top item | Returns the top item of stack1 without consuming it |
peek2 | 0 | Stack2 top item | Returns the top item of stack2 without consuming it |
pop1 | 0 | Stack1 top item | Returns the top item of stack1 and consumes it |
pop2 | 0 | Stack1 top item | Returns the top item of stack2 and consumes it |
push1 | 1 | Parameter 1 | Pushes the value of parameter 1 into stack1 |
push2 | 1 | Parameter 1 | Pushes the value of parameter 1 into stack2 |
size1 | 0 | Number of items in stack1 | Returns the number of items in stack1 |
size2 | 0 | Number of items in stack2 | Returns the number of items in stack2 |
add | 2 | Parameter 1 + Parameter 2 | Integer addition |
sub | 2 | Parameter 1 - Parameter 2 | Integer subtraction |
mul | 2 | Parameter 1 * Parameter 2 | Integer multiplication |
div | 2 | Parameter 1 / Parameter 2 | Integer division |
mod | 2 | Parameter 1 modulo Parameter 2 | Integer modulus |
and | 2 | Parameter 1 AND Parameter 2 | Integer binary and |
or | 2 | Parameter 1 OR Parameter 2 | Integer binary or |
xor | 2 | Parameter 1 XOR Parameter 2 | Integer binary xor |
not | 1 | NOT Parameter 1 | Integer binary not |
get | 0 | Console character code | Reads a character from the console and returns the ASCII value |
put | 1 | Parameter 1 | Writes the character with ASCII value of parameter 1 to the console |
ifsame | 3 or 4 | (see description) | If parameter 1 is the same as parameter 2, then return the value of parameter 3; otherwise return 0 (or the value of parameter 4 if it exists) |
ifdiff | 3 or 4 | (see description) | If parameter 1 is not the same as parameter 2, then return the value of parameter 3; otherwise return 0 (or the value of parameter 4 if it exists) |
ifless | 3 or 4 | (see description) | If parameter 1 is less than parameter 2, then return the value of parameter 3; otherwise return 0 (or the value of parameter 4 if it exists) |
ifmore | 3 or 4 | (see description) | If parameter 1 is the greater than parameter 2, then return the value of parameter 3; otherwise return 0 (or the value of parameter 4 if it exists) |
exec | any number | 0 | Executes all parameters sequentially |
Examples
Cat Program
<cat>{exec(put(get()),[cat])} [cat]
Hello, World!
put(72) put(101) put(108) put(108) put(111) put(44) put(32) put(119) put(111) put(114) put(108) put(100) put(33)
Fibonacci Numbers
Prints the first few Fibonacci numbers.
<fib>{exec([write],store(pop1()),push2(add(recall(),pop1())),push1(recall()),push1(pop2()),ifless(peek1(),1000,[fib]))} <write>{exec(push2(0),push2(0),push2(0),store(peek1()),[hundreds],[tens],[ones],push1(0),ifmore(peek2(),0,exec(put(add(peek2(),48)),pop1(),push1(1))),pop2(),ifmore(peek2(),0,put(add(peek2(),48)),ifsame(recall(),1,put(add(peek2(),48)))),pop2(),put(add(pop2(),48)),pop1(),put(10))} <hundreds>{ifmore(recall(),99,exec(store(sub(recall(),100)),push2(add(pop2(),1)),[hundreds]))} <tens>{ifmore(recall(),9,exec(store(sub(recall(),10)),push1(pop2()),push2(add(pop2(),1)),push2(pop1()),[tens]))} <ones>{ifmore(recall(),0,exec(store(sub(recall(),1)),push1(pop2()),push1(pop2()),push2(add(pop2(),1)),push2(pop1()),push2(pop1()),[ones]))} push1(0) push1(1) [fib]
Conditional Macros
This shows how macros can be defined anywhere in the code (except inside other macros), and how that can be used to create macros with variable values.
<con>{ifsame(0,0,<mac>{put(33)},<mac>{null})} [con] [mac]