Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Brainfuck Interpreter
Index -> Programming, Turing -> Turing Submissions
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
frank26080115




PostPosted: Mon Dec 10, 2007 6:56 pm   Post subject: Brainfuck Interpreter

I made a simple Brainfuck interpreter, this is a step towards a microcontroller assembly/machine code simulation.
Learn about Brainfuck and its syntax here:
http://en.wikipedia.org/wiki/Brainfuck

Note that my version allows variables and pointers to decrement from 0 to 255 and increment from 255 to 0

Turing:

setscreen ("graphics:1000,600;position:center,center;offscreenonly;title:Brainfuck") %;nobuttonbar")
const maxAddress := 255
var address : array 0 .. maxAddress of int
var _pointer : int
var code : string := ""

var ch : string (1)

var loopCounter, location : int
var finished, _return : boolean

var chars : array char of boolean

fcn getInput (fieldName, starting : string, maxLength : int, interger : boolean) : string
    var character : string (1)
    var cursorLoc : int := 0
    var output : string := starting
    var legalString : string := " ~!@#$%\^&*()_+`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./QWERTYUIOP{}|ASDFGHJKL:\"ZXCVBNM<>?" %"<>+-,.[]"
    var exit123 : boolean := false
    if interger then
        legalString := "1234567890"
    end if

    loop
        if hasch then
            getch (character)
            if character = KEY_BACKSPACE then
                if length (output) > 0 and cursorLoc > 0 then
                    output := output (1 .. cursorLoc - 1) + output (cursorLoc + 1 .. *)
                    cursorLoc -= 1
                end if
            elsif character = KEY_DELETE then
                if cursorLoc < length (output) then
                    output := output (1 .. cursorLoc) + output (cursorLoc + 2 .. *)
                end if
            elsif character = KEY_ENTER then
                cursorLoc := 0
                exit123 := true
            elsif character = KEY_RIGHT_ARROW then
                if cursorLoc < length (output) then
                    cursorLoc += 1
                end if
            elsif character = KEY_LEFT_ARROW then
                if cursorLoc > 0 then
                    cursorLoc -= 1
                end if
            elsif character = KEY_HOME then
                cursorLoc := 0
            elsif character = KEY_END then
                cursorLoc := length (output)
            else
                if length (output) < maxLength and index (legalString, character) not= 0 then
                    output := output (1 .. cursorLoc) + character + output (cursorLoc + 1 .. *)
                    cursorLoc += 1
                end if
            end if
        end if

        Text.Locate (Text.WhatRow, 1)
        for i : 1 .. length (fieldName) + length (output) + 2
            put " " ..
        end for
        Text.Locate (Text.WhatRow, 1)
        put fieldName ..

        for i : 1 .. cursorLoc - 1
            put output (i) ..
        end for

        if (Time.Elapsed div 500) mod 2 = 1 and exit123 = false then
            if cursorLoc not= 0 then
                put output (cursorLoc) ..
            end if
            if cursorLoc = length (output) then
                put "|" ..
            else
                put "<" ..
            end if
            for i : cursorLoc + 2 .. length (output)
                if i not= 0 then
                    put output (i) ..
                end if
            end for
        else
            if cursorLoc not= 0 then
                put output (cursorLoc) ..
            end if
            for i : cursorLoc + 1 .. length (output)
                if i not= 0 then
                    put output (i) ..
                end if
            end for
        end if
        put " " ..

        View.Update

        Time.DelaySinceLast (100)
        exit when exit123
    end loop
    if interger and strintok (output) = false then
        output := "0"
    end if
    put ""
    result output
end getInput

proc executeCommand (toExe : string)
    if toExe = "<" then
        if _pointer = 0 then
            _pointer := maxAddress
        else
            _pointer -= 1
        end if
    elsif toExe = ">" then
        if _pointer = maxAddress then
            _pointer := 0
        else
            _pointer += 1
        end if
    elsif toExe = "+" then
        if address (_pointer) = 255 then
            address (_pointer) := 0
        else
            address (_pointer) += 1
        end if
    elsif toExe = "-" then
        if address (_pointer) = 0 then
            address (_pointer) := 255
        else
            address (_pointer) -= 1
        end if
    elsif toExe = "," then
        loop
            Time.DelaySinceLast (100)
            exit when hasch
        end loop
        getch (ch)
        if ord (ch) > 126 then
            address (_pointer) := 126
        elsif ord (ch) = 10 then
            address (_pointer) := 10
        elsif ord (ch) < 32 then
            address (_pointer) := 32
        else
            address (_pointer) := ord (ch)
        end if
    elsif toExe = "." then
        %put "Byte: ", address (_pointer), "  " ..
        if address (_pointer) >= 32 and address (_pointer) <= 126 or address (_pointer) = 10 then
            put chr (address (_pointer)) .. %put "Char: ", chr (address (_pointer))
        else
            %put ""
        end if
        View.Update
    end if
end executeCommand

loop
    put "Welcome to the Brainfuck Interpreter by Frank26080115"
    View.Update
    code := getInput ("Input Code: ", code, 250, false) + " "
    put "Begin Execution (EXE to stop)"
    put "Output:"
    put "-----------------------------"
    put ""
    View.Update

    _pointer := 0
    for i : 0 .. 255
        address (i) := 0
    end for
    loopCounter := 0
    location := 1
    finished := false

    loop
        for i : location .. length (code)
            _return := false
            executeCommand (code (i)) %executes simple code
           
            %these handle loops, loopCounter is used to
            %deal with nested loops
            if code (i) = "[" then
                if address (_pointer) = 0 then
                    for j : i + 1 .. length (code)
                        if code (j) = "[" then
                            loopCounter += 1
                        elsif code (j) = "]" then
                            if loopCounter = 0 then
                                exit
                            else
                                loopCounter -= 1
                            end if
                        end if
                    end for
                end if

            elsif code (i) = "]" then
                if address (_pointer) > 0 then
                    for decreasing j : i - 1 .. 1
                        if code (j) = "[" then
                            if loopCounter = 0 then
                                location := j
                                _return := true
                                exit
                            else
                                loopCounter -= 1
                            end if
                        end if
                    end for
                end if
            end if

            if i = length (code) then
                finished := true
            end if
            if _return then
                _return := false
                exit
            end if
            Input.KeyDown (chars)
            if chars (KEY_ESC) then
                finished := true
                exit
            end if
        end for
        exit when finished
    end loop

    put ""
    put ""
    put "-----------------------------"
    put "Finished Execution" ..
    if chars (KEY_ESC) then
        put " (User Interrupted)"
    end if
    put "\n"
end loop



for an example, "+[,.]" will become something like notepad, "+[.+]" will show all printable characters and then exit the loop, "+[.+.+]" will loop forever while printing all printable characters, have fun[/syntax]
Sponsor
Sponsor
Sponsor
sponsor
CodeMonkey2000




PostPosted: Mon Dec 10, 2007 7:11 pm   Post subject: RE:Brainfuck Interpreter

0_o Holy crap. This is amazing. But I still don't plan on ever using BF.
Ultrahex




PostPosted: Mon Dec 10, 2007 7:25 pm   Post subject: Re: Brainfuck Interpreter

Overall the program is excellent.

You should make it more "clean", so its not as over cumbersomely (hehe, no clue if that is correct english). For Example:

Quote:
Welcome to the Brainfuck Interpreter by Frank26080115

Input Below:

:: <>++++++[<-------->-],[<+>-]<.
::: 2
::: 3
5

:: ....(other examples)
Hello World

::


note that i may be the only one annoyed because I like to have clean looking interfaces, and most people that use interpreters understand that it is an input field etc... Just Some Ideas Smile
Tony




PostPosted: Mon Dec 10, 2007 7:48 pm   Post subject: RE:Brainfuck Interpreter

this is quite cool Smile +bits
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
shakin cookie




PostPosted: Sat Jan 05, 2008 11:15 am   Post subject: RE:Brainfuck Interpreter

I do not understand how this works...
StealthArcher




PostPosted: Sun Jan 13, 2008 10:17 pm   Post subject: RE:Brainfuck Interpreter

You have to know what Brain**** is first really.

Then you will be amazed.

And I am amazed. +bits
Display posts from previous:   
   Index -> Programming, Turing -> Turing Submissions
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 6 Posts ]
Jump to:   


Style:  
Search: