MacroBeep
Paradigm(s) | Imperative |
---|---|
Designed by | User:PixelatedStarfish |
Appeared in | 2021 |
Memory system | Cell-based |
Computational class | Turing complete |
Major implementations | *The latest version (1.4.2) can be downloaded here. |
Influenced by | bf, python |
File extension(s) | .mcbe |
MacroBeep is a language created by User:PixelatedStarfish. Development of the language began in December of 2021. The language is designed in response to common problems people face when learning to code in more conventional programming languages. The syntax is designed to communicate what the computer is doing in a clear and concise manner. For every MacroBeep program, there is an equivalent MacroBeep program that can described as a sequence of native instructions in a specific order.
A MacroBeep programmer does not have to search for the missing punctuation. They do not need to find the unmatched parenthesis, or count their braces. They do not need to deal with the particularities of data types or the difference between objects, classes, structs, and interfaces.
This language is not without cons. A programmer needs to manage program memory themselves. Data cannot be protected. It is up to the programmer to make sure that something is not overwritten before it should be. A MacroBeep programmer should also be familiar with Turing machines and the ASCII table.
Introduction
MacroBeep is an assembly style language with an instruction set, such that the programmer can define macros in order to describe and implement more complex operations.
MacroBeep is not a language in the functional language paradigm. There is no part of a MacroBeep program that can be considered stateless, and there are no pure functions in MacroBeep. Instead, a program modifies bytes on a tape using a pointer in a manner similar to bf, such that each cell on the tape can store a value between 0 and 255 inclusive.
A program in MacroBeep will always run the main macro before any other macro. This language has a call stack, and the main macro is the first item on that call stack.
To improve memory management, MacroBeep 1.4.2 features a mark stack and a strip. The mark stack is a stack of marks. Marks mark a specific cell so the tape pointer can return to it later. The strip stores data temporarily for use. So combined, these let a programmer move data from one part of the tape to another, modify the data and move it back to the last marked location. A debugger provides Information about the state of the program memory for each instruction.
Instruction Set
- Each operation can take an identifier or an integer value as an argument.
- A macro cannot be a reserved word or operation name.
- Operations are separated by a newline, and arguments by a space.
macro
- define macro; takes an identifier
do
- do macro identified in arg, call macro
rt
- return to macro call an execute next instruction
null
- set cell to 0
str
- store value of current cell in next cell, or offset from the current cell as specified such that -1 indicates storage in the left cell.
stat
- short for 'store at', this stores the value of the current cell at the cell given in an argument. 'stat 2' stores the value of the current cell 2 cells right of the head.
rand
- set cell a random from 0 to arg or 0 to 255
add
- add to cell; 1 if no arg
sub
- take from cell; 1 if no arg
right
- move pointer to the right; by 1 if no arg is given
left
- move pointer to the left; by 1 if no arg is given
head
- go to head of tape, or to specified offset from head
pos
- get position of cell pointer on tape and print it
inp
- get input; char, int, or string for args 0, 1 and 2
out
- print cell or arg
cout
- print char on cell or arg as char
pr
- print any value given as a string with a newline, newline if nothing. Use '[]' to print a space and '{}' to print a tab
beep
- it goes beep, use an argument to specify frequency in hertz. Default is 1000
label
- for an example of how to use a a label, see the false machine
send
- copy one or more cells to the head of the tape; mark the location of the first cell copied. Pushes a mark
reply
- copy one or more cells from the head of the tape to the cell location marked; this erases the strip of copied data and pops a mark of the stack.
solar
- branch if cell is greater than 0
lunar
- branch if cell is 0
venusian
- branch if cell is equal to next cell
martian
- branch if cell is not equal to next cell
jovian
- branch if cell is greater than next cell
plutonic
- branch if cell is less than next cell
vestian
- branch if cell is greater than or equal to next cell
sednian
- branch if cell is less than or equal to to next cell
halt
- end program
wait
- adds a delay of 100ms, or as specified by an argument
include
- include files at path identified
#
- inline comment
##
- start or end a multi-line comment
Grammar in EBNF
Key: ::= assignment, equivalence | or (group) {repeated at least one time} [optional] 'string literal' symbol , symbol concatination ; symbol terminator (*comment*)
Program ::= {statement} statement ::= macro | instruct macro ::= 'macro', s, alnum, n, {instruct}, ['rt']; (*be careful when leaving out 'rt'*) instruct ::= word, s, [arg], n; arg ::= alnum | inte alnum ::= {(lett | digit)}; word ::= {lett}; inte ::= {digit}; s ::= ' '; n ::= '\n'; digit ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; lett ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
Program Examples
It is good practice to indicate the scope of an instruction with tabs or spaces. This can be useful to indicate which instructions are part of a macro. Leading white space is not required. New lines are the only significant white space characters.
Hello World
macro main pr Hello[]World # Note that the [] is printed as a space
Truth Machine
macro main pr Type[]a[]0[]or[]1[]into[]the[]truth[]machine. inp 1 solar 3 pr 0 halt pr 1 wait solar -3
False Machine
macro main pr Type[]a[]0[]or[]1[]into[]the[]false[]machine. inp 1 lunar magic pr 1 halt label magic pr 0 wait lunar magic
Cat
macro main pr Give[]me[]a[]word[]and[]I[]will[]say[]it[]back! inp 2 head cout right solar -3
C scale
macro main beep 262 beep 294 beep 330 beep 349 beep 392 beep 440 beep 494 beep 523
Sum of Numbers
macro sum send 2
right label WhileCellTwoIsNotZero add -1 head add 1 right solar WhileCellTwoIsNotZero reply rt
macro init #initialize right 2 add right add 2 right add 3 right add 5 right add 8 right add 13 right add 21 rt
macro main do init head 2
#Loop through numbers and add them together label Loop right lunar ifTheCellIsZeroGoHere left do sum str right solar Loop
#Output label ifTheCellIsZeroGoHere left out rt
Proof of Turing Completeness
bf is Turing complete. By translating each bf command to MacroBeep, it can be shown that MacroBeep is also Turing complete.
MacroBeep | bf | Desc |
---|---|---|
right 1 | > | increment |
left 1 | < | decrement |
add 1 | + | add 1 to cell |
sub 1 | - | take 1 from cell |
cout | . | Output ASCII value at cell |
inp | , | Take input at cell |
lunar (by some positive number of instructions) | [ | jump past ' ] ' if cell is 0 |
solar (by some negative number of instructions) | ] | goto ' [ ' if cell is greater than 0 |
Error Codes
Error (0)
The Generic Error Message, for errors not described below.
Undefined Instruction (1)
Thrown when the interpreter encounters an instruction that is not defined in the instruction set.
File Not Found (2)
Either the file does not exist, or it is in the wrong directory.
Undefined Macro or Label (3)
The macro called by "do" has no matching definition; alternatively, the label branched to does not exist.
Missing Main Macro (4)
"macro main" is missing, the program cannot start.
Stack Overflow (5)
This error is most commonly caused by an infinite recursion. Too many macro calls on the call stack.
Not a Cell Error (6)
Occurs when a program tries to modify a cell that does not exist, such as cell -1 or cell infinity.
Include Statement in Macro (7)
An include statement cannot be written into a macro definition.
Preproccesor Error (8)
A preproccesor error that is not caught by any other error code. Check include statements carefully.
Duplicate Macro or Label (9)
A macro or label is defined more than once in the program. Calls to it are ambiguous.
Argument Error. Integer Expected (10)
An instruction that only takes an integer argument was not given an integer argument.
Bad Argument (11)
This is the error thrown when the interpreter reads statements that are syntactically correct, but incomputable in this language, such as "wait -100". Esoteric models of time notwithstanding, instructions that require negative time to compute would throw this error.
Astrological Error (12)
This error occurs when the next instruction to execute is located outside source entirely. It is as if you gave the interpreter a To-Do list of 10 or so items in an order, and then said "Hey, no need to do that fifth thing, go do item 24, or -5 instead." Confusion would be understandable, and nothing would get done!
Interpreter Status
1.4.2 is ready for use. Repl coming soon!
Change Log
1.3.0 >> 1.4.2
- Change Log (changes from v1.3.0)*
- Added send and reply instructions
- Added tom and mark instructions
- Implemented mark stack for memory management
- Implemented a debugger
- Implemented a library called SumDif
- Implemented a Help menu to print docs by section
- Bug fixes
- Updated and expanded docs
- Removed typos
External Links
Repl for Online Use
To try MacroBeep online, this repl is available. Beeps are silent because the IDE for repl.it cannot produce them.