MacroBeep

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.
 Conversion Table 
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==
*The latest version (1.4.2) can be downloaded here.
*Documentation
===Repl for Online Use===
To try MacroBeep online, this repl is available. Beeps are silent because the IDE for repl.it cannot produce them.
*Version 1.4.2r can be tried online here.
Category:Languages Category:Implemented Category:Low-level Category:2021 Category:Stack-based Category:Cell-based Category:Turing complete