Macmac

From Esolang
Jump to: navigation, search

Macmac is an esoteric programming language created by David Catt (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]

External resources