BrainF*** Compiler

I made a program that can run code in the esoteric language of BrainF***.

EDIT: Forgot to mention that there are no loops or byte write functions yet.
EDIT 2: V0.2 adds byte reading compability (aka the dot OR . )
EDIT 3: V0.3 adds an output screen, which means that you don’t have to restart the program to return to your code.
EDIT 4: V0.4 makes compiling slower, but adds graphical improvements and loops.

-- v0.4
function setup()
    displayMode(FULLSCREEN_NO_BUTTONS)
    supportedOrientations(PORTRAIT_ANY)
    code = ""
    out = {}
    outstr = ""
    p=0
    trueinfalseout=true
    
    run=false
    i=0
    loopStart = 0
    
    btns = {Button("Edit", WIDTH-50, 25, color(0, 0, 0, 100), showKeyboard),
    Button("Close", WIDTH/2, 25, color(0, 0, 0, 100), close),
    Button("Cmpl", 50, 25, color(0, 0, 0, 100), compile),
    Button("Clear", WIDTH/2, 100, color(0, 0, 0, 100), clr),
    Button("Output", 75, 100, color(0, 0, 0, 100), switchmode),
    Button("Paste", WIDTH-63, 100, color(0,0,0,100), paste)}
    backbtn = Button("< Back", 100, 75, color(245, 0, 0, 240), switchmode)
    textWrapWidth(WIDTH-30)
    
    code = readGlobalData("bfCodeSave") or ""
    noStroke()
end
function draw()
    if (trueinfalseout) then
        background(255, 255, 255, 255)
        fill(0, 0, 0, 255)
        fontSize(96)
        textMode(CENTER)
        font("ArialMT")
        text("BrainF*** Editor", WIDTH/2, HEIGHT-100)
        fill(160, 160, 160, 255)
        rect(WIDTH/2, 60, WIDTH, 150)
        fill(0, 0, 0, 255)
        fontSize(36)
        textMode(CORNER)
        text(code, 15, HEIGHT/2)
        fontSize(24)
        for i,v in pairs(btns) do
            v:draw()
        end
        if (run) then
            text("Compiling... "..i.."/"..string.len(code), 150, 150)
        end
    else
        background(0, 0, 0, 255)
        fill(255, 255, 255, 255)
        fontSize(36)
        textMode(CENTER)
        font("Inconsolata")
        text(outstr, WIDTH/2, HEIGHT/2)
        fontSize(24)
        if (run) then
            text("Compiling... "..i.."/"..string.len(code), WIDTH-150, 50)
        end
        backbtn:draw()
    end
    if (run) then
        c=string.sub(code, i, i)
        if (c=="+") then
            out[p] = out[p] + 1
        elseif (c=="-") then
            out[p] = out[p] - 1
        elseif (c=="<") then
            p = p - 1
            if (out[p]==nil) then
                out[p]=0
            end
        elseif (c==">") then
            p = p + 1
            if (out[p]==nil) then
                out[p]=0
            end
        elseif (c==".") then
            outstr = outstr .. string.char(out[p]) .. " "
        elseif (i > string.len(code)) then
            saveGlobalData("bfCodeSave", code)
            for k,v in pairs(out) do
                outstr = outstr .. "[" .. k .. "]" .. "=" .. v ..",  "
            end
            run=false
        elseif (c=="[") then
            loopStart = i
        elseif (c=="]") then
            if (out[p] < 0 or out[p] > 0) then
                i = loopStart
            end
        end
        i = i + 1
    end
end
function touched(touch)
    if (trueinfalseout) then
        for i,v in pairs(btns) do
            v:touched(touch)
        end
    else
        backbtn:touched(touch)
    end
end
function keyboard(key)
    if (key==RETURN) then
        hideKeyboard()
    elseif (key==BACKSPACE) then
        code=string.sub(code, 0, -2)
    else
        code=code..key
    end
end
function compile()
    i=0
    p=0
    out = {}
    out[0]=0
    outstr = ""
    run = true
    --[[for i=0, string.len(code) do
        c=string.sub(code, i, i)
        if (c=="+") then
            out[p] = out[p] + 1
        elseif (c=="-") then
            out[p] = out[p] - 1
        elseif (c=="<") then
            p = p - 1
            if (out[p]==nil) then
                out[p]=0
            end
        elseif (c==">") then
            p = p + 1
            if (out[p]==nil) then
                out[p]=0
            end
        elseif (c==".") then
            outstr = outstr .. string.char(out[p]) .. " "
        end
    end
    saveGlobalData("bfCodeSave", code)
    for k,v in pairs(out) do
        outstr = outstr .. k .. ": " .. v ..",  "
    end ]]--
end
function paste()
    code = pasteboard.text
end
function clr()
    code=""
end
function switchmode()
    if (trueinfalseout) then trueinfalseout = false else trueinfalseout=true end
end

--# Button
Button = class()

function Button:init(t,x,y,col,cb)
    -- you can accept and set parameters here
    self.text = t
    self.x = x
    self.y = y
    self.color = col
    self.callback = cb or function() end
end

function Button:draw()
    -- Codea does not automatically call this method
    noStroke()
    rectMode(CENTER)
    fill(self.color)
    rect(self.x, self.y, string.len(self.text)*fontSize(), fontSize()*1.75)
    textMode(CENTER)
    fill(0, 0, 0, 118)
    text(self.text, self.x, self.y)
end

function Button:touched(touch)
    -- Codea does not automatically call this method
    if (touch.x > self.x-string.len(self.text)*fontSize()/2 and
    touch.x < self.x+string.len(self.text)*fontSize()/2 and
    touch.y > self.y-string.len(self.text)*fontSize()/2 and
    touch.y < self.y+string.len(self.text)*fontSize()/2 and
    touch.state == BEGAN) then
        self.callback()
    end
end

Nice! :o I’m a big fan of the esoteric language FALSE. :wink:

@quezadav Never heard of it. I’ll have to check it out! Thank you for the feedback!

@niorg2606 In fact, FALSE inspired Brainf… and other esoteric languages. A longstanding dream of mine is to have in Codea a FALSE interpreter like this in JavaScript: http://www.quirkster.com/iano/js/false-js.html
The problem is, I don’t know how to do it. :smiley:
Congrats again for your compiler and my best wishes for Xmas.

@quezadav I could help you with that.

@niorg2606 that would be great!
Here is the source code of the above mentioned JavaScript FALSE interpreter: http://www.quirkster.com/iano/js/false.js
My plan was to translate it “word-by-word” into lua, but unfortunately, I don’t know the JavaScript language.