Execute Brain****/E
Appearance
Execute Brain****/E is an implementation of Brainf***.
Other implementations of Brainf***.
Execute Brain****/E is part of RCBF. You may find other members of RCBF at Category:RCBF.
This BF implementation compiles BF programs into functions (from strings to strings) in the host language, E.
It has a fixed-size memory defined in terms of characters, not bytes, and initialized to the null character. It does not permit the BF program to notice EOF.
pragma.syntax("0.9")
pragma.enable("accumulator")
def makeLiteralExpr := <elang:evm.makeLiteralExpr>
def makeSeqExpr := <elang:evm.makeSeqExpr>
def simpleInstructions := [
'>' => e`ptr += 1`,
'<' => e`ptr -= 1`,
'+' => e`array[ptr] next= ()`,
'-' => e`array[ptr] previous= ()`,
'.' => e`out += E.toString(array[ptr])`,
',' => e`array[ptr] := inputString[inPtr += 1]`,
]
def bfCompile(prog) {
# Stack holding nested loop bodies collected so far
def stack := [[]].diverge()
for ch in prog {
switch (ch) {
match =='[' {
stack.push([])
}
match ==']' {
# take enclosed program off top of stack and append to next down inside a loop
stack[stack.size() - 2] with= e`
while (array[ptr] != '\u0000') {
${makeSeqExpr(null, stack.pop(), null)}
}
`
}
match _ ? (simpleInstructions.maps(ch)) {
# XXX the {} will be unnecessary once e`` goes to using selfish temps
stack[stack.size() - 1] with= e`{${simpleInstructions[ch]}}`
}
match _ {}
}
}
# Take the one remaining stack item
def [bodyExprs] exit fn _{throw("Too few right brackets")} \
:= stack.snapshot()
# How the BF function object will appear
def printDesc := makeLiteralExpr(null, "<BF " + if (prog.indexOf(",") != -1) {"function"} else {"thunk"} + ">", null)
return e`
pragma.syntax("0.9")
def bfo := def _ {
to __printOn(out :TextWriter) {
out.print($printDesc)
}
/** Equivalent to passing the empty string */
to run() { return bfo("") }
to run(inputString) {
def array := ("\u0000" * 30000).diverge(char)
var ptr := 0
var inPtr := -1
var out := ""
${makeSeqExpr(null, bodyExprs, null)}
return out
}
}
`.eval(safeScope)
}
Example usage:
? def incr3 := bfCompiler(",>,>,><<<[+.>]")
# value: <BF function>
? incr3("abc")
# value: "bcd"