This document describes how the brainlite compiler (brainuf) works internally.
The compiler takes brainlite source code and transpiles it into brainfuck. It does not execute anything.
The brainlite class is instantiated and initialized with:
pointer to track the current position within the line being lexed.memory_pointer to track which brainfuck memory cell is logically active at compile time.validTokens — the set of all recognized keywords.execTokens — an unordered map dispatching each keyword to its corresponding function.lexCode() is called once per line. It:
# (comments).? — if so, skipIfError is set to true for that line, suppressing errors.validTokens.exec_func().argsCollectedLength is returned by keyword handlers to tell the lexer how many characters were consumed as arguments, so the lexer skips past them.The compiler accumulates brainfuck output into compiled_code, a std::vector<std::string>. Each keyword handler appends one or more brainfuck strings to this vector.
getCode() returns this vector to the caller.
<value>Sets the current memory cell to a specific value (0–255). Emits a string of + characters equal to the value.
The value is passed through ringBuffer() to clamp it into the 0–255 range.
Does not move the memory pointer.
Aliases for the same operation. Emits > and increments memory_pointer.
Aliases for the same operation. Emits < and decrements memory_pointer.
Emits a single +.
Emits a single -.
<limit>Reads the current logical value of the cell (by scanning compiled_code backwards until a pointer movement is found), then emits enough + characters to reach the limit from the current value.
<limit>Same as inctill but decrements. Emits - characters from the current value down to the limit.
<n>Moves the memory pointer by N cells. Emits N > or < characters depending on direction.
move 0 resets the pointer to cell 0 by emitting as many < as needed.
move -N moves backwards N cells.
"string"Accepts a quoted string. For each character in the string:
set() with the ASCII value of the character..> to print the character and advance the pointer.Supports escape sequences: \n, \t, \\.
Double quotes are required. Single quotes do not work.
<n>Emits N , characters, collecting N characters of input from stdin into sequential memory cells.
<n>Sets the current cell to N (using set() internally), marks isLooping = true, and records memory_pointer as the loop base address.
The body of the loop is lexed normally by the outer loop in the caller. The end keyword closes it.
Closes the most recently opened loop. Emits pointer movements back to the loop’s base address, then emits -] to form the brainfuck loop close.
If end is encountered with no active loop, it exits with an error.
"query"A debug keyword. Accepts "memorypointer" as the only valid query. Emits brainfuck that sets the current cell to the compile-time value of memory_pointer and prints it.
Known bug: The brainfuck . instruction outputs ASCII, not the raw integer. So if the memory pointer is at address 65, it prints A, not 65.
Emits a single .. Prints whatever ASCII character is currently in the active memory cell.
On any error, the compiler prints a message with the offending line and exits. If the line ends with ?, errors are suppressed (skipIfError = true) and the instruction is silently skipped instead.
Error codes used:
COMPILER_ERR_INVALID_KEYWORDCOMPILER_ERR_SET_KEYWORD_MISSING_ARGUMENTCOMPILER_ERR_INCTILL_MISSING_ARGUMENTCOMPILER_ERR_DECTILL_MISSING_ARGUMENTCOMPILER_ERR_MOVE_MISSING_ARGUMENTCOMPILER_ERR_PRINT_MISSING_QUOTECOMPILER_ERR_PRINT_MISSING_ARGUMENTCOMPILER_ERR_INPUT_MISSING_ARGUMENTCOMPILER_ERR_WHATIS_MISSING_QUOTECOMPILER_ERR_WHATIS_MISSING_ARGUMENTCOMPILER_ERR_END_LOOP_WITHOUT_STARTThat covers the compiler’s internal behavior. It makes no attempt at optimization. The output brainfuck is correct but naive.