Execute Brain****/E: Difference between revisions

From Rosetta Code
Content added Content deleted
m (Categorization now in master page)
m (Fixed syntax highlighting.)
 
(One intermediate revision by one other user not shown)
Line 5: Line 5:
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.
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.


<lang e>pragma.syntax("0.9")
<syntaxhighlight lang="e">pragma.syntax("0.9")
pragma.enable("accumulator")
pragma.enable("accumulator")


Line 80: Line 80:
}
}
`.eval(safeScope)
`.eval(safeScope)
}</lang>
}</syntaxhighlight>


Example usage:
Example usage:


<lang e>? def incr3 := bfCompiler(",>,>,><<<[+.>]")
<syntaxhighlight lang="e">? def incr3 := bfCompiler(",>,>,><<<[+.>]")
# value: <BF function>
# value: <BF function>


? incr3("abc")
? incr3("abc")
# value: "bcd"</lang>
# value: "bcd"</syntaxhighlight>

Latest revision as of 11:15, 1 September 2022

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"