⚠️ Warning: This is a draft ⚠️
This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.
If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.
;---------------------------------------------------------------------------
; Brainfuck Interpreter.ahk
; by wolf_II
;---------------------------------------------------------------------------
; interpreter for Brainfuck code
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
Code = ; Goodbye, World!
;---------------------------------------------------------------------------
(LTrim
Example taken from RosettaCode:org
++++++++++[>+>+++>++++>+++++++>++++++++>+++++++++>++++++++++
>+++++++++++>++++++++++++<<<<<<<<<-]>>>>+.>>>>+..<.<++++++++
.>>>+.<<+.<<<<++++.<++.>>>+++++++.>>>.+++.<+++++++.--------.
<<<<<+.<+++.---.
)
;---------------------------------------------------------------------------
AutoExecute: ; auto-execute section of the script
;---------------------------------------------------------------------------
#SingleInstance, Force ; only one instance allowed
#NoEnv ; don't check empty variables
;-----------------------------------------------------------------------
AppName := "Brainfuck"
Gosub, GuiCreate
Gui, Show,, %AppName%
Return
;---------------------------------------------------------------------------
GuiCreate: ; create the main window
;---------------------------------------------------------------------------
; GUI options
Gui, Margin,, 10
Gui, Add, Edit, y0 h0 ; catch the focus
; Brainfuck Code
Gui, Add, GroupBox, w462 h248, Brainfuck Code
Gui, Font, s8, Courier New
Gui, Add, Edit, xp+10 yp+20 w442 r15 vCode, %Code%
Gui, Font ; normal
; buttons
Gui, Add, Button, xm w101 h30, &Load Code
Gui, Add, Button, x+19 wp hp, &Save Code As
Gui, Add, Button, x+19 wp hp Default, &Run Code
Gui, Add, Button, x+19 wp hp, E&xit
; Output
Gui, Add, GroupBox, xm w462 h248, Output
Gui, Font, s8, Courier New
Gui, Add, Edit, xp+10 yp+20 w442 r15 ReadOnly vOutput HwndhOut
Gui, Font ; normal
Return
;---------------------------------------------------------------------------
ButtonLoadCode: ; load code from file
;---------------------------------------------------------------------------
Gui, +OwnDialogs
FileSelectFile, CodeFile,,, Load Brain*** Code, *.bf
If (ErrorLevel = 1) {
; user dismissed the dialog
Gui, Show
Return
}
If Not SubStr(CodeFile, -2) = ".bf"
CodeFile .= ".bf"
If FileExist(CodeFile) {
FileRead, Code, %CodeFile%
GuiControl,, Code, %Code%
} Else
MsgBox, 16, Error - %AppName%, File not found:`n`n"%CodeFile%"
GuiControl,, Output ; clear all output
Gui, Show
Return
;---------------------------------------------------------------------------
ButtonSaveCodeAs: ; save code to file
;---------------------------------------------------------------------------
Gui, +OwnDialogs
Gui, Submit, NoHide
FileSelectFile, CodeFile, S16,, Brain*** Code, *.bf
If (ErrorLevel = 1) {
; user dismissed the dialog
Gui, Show
Return
}
If Not SubStr(CodeFile, -2) = ".bf"
CodeFile .= ".bf"
FileDelete, %CodeFile%
FileAppend, %Code%, %CodeFile%
Gui, Show
Return
;---------------------------------------------------------------------------
GuiClose: ; {Alt-F4} pressed, [X] clicked
;---------------------------------------------------------------------------
ButtonExit: ; Exit button clicked
;---------------------------------------------------------------------------
ExitApp
Return
;---------------------------------------------------------------------------
ButtonRunCode: ; run the code from the edit field
;---------------------------------------------------------------------------
Gui, Submit, NoHide ; get code from GUI
Gosub, set_JumpPointers ; set jump pointers
GuiControl, Disable, Output
GuiControl, Disable, &Load
GuiControl, Disable, &Save
GuiControl, Disable, &Run
Gosub, Interpreter ; do your stuff, kid
GuiControl, Enable, Output
GuiControl, Enable, &Load
GuiControl, Enable, &Save
GuiControl, Enable, &Run
Return
;---------------------------------------------------------------------------
Interpreter: ; This is the Brainfuck Interpreter
;---------------------------------------------------------------------------
; setup BF environment
VarSetCapacity(BF_MEM, 4096, 0)
DataPtr := InstrPtr := 0
Loop {
; read next instruction
CMD := SubStr(Code, ++InstrPtr, 1)
Data@Ptr := NumGet(BF_MEM, DataPtr, "Char")
If (CMD = "+") ; increment the data at DataPointer
NumPut(Data@Ptr + 1, BF_MEM, DataPtr, "Char")
Else If (CMD = "-") ; decrement the data at DataPointer
NumPut(Data@Ptr - 1, BF_MEM, DataPtr, "Char")
Else If (CMD = ">") ; increment the DataPointer
DataPtr++
Else If (CMD = "<") ; decrement the DataPointer
DataPtr--
Else If (CMD = ".") ; print the char at DataPointer
Output(Chr(Data@Ptr))
Else If (CMD = ",") ; get a char from stdin (keyboard)
NumPut(GetChar(), BF_MEM, DataPtr, "Char")
Else If (CMD = "[") { ; conditional jump
If (Data@Ptr = 0)
; continue after the corresponding "]"
InstrPtr := Jump[%InstrPtr%]
} Else If (CMD = "]") { ; conditional jump
If (Data@Ptr != 0)
; continue after the corresponding "["
InstrPtr := Jump[%InstrPtr%]
} Else If (CMD = "") ; this is the end of code
Break
}
Return
;---------------------------------------------------------------------------
set_JumpPointers: ; setup all the jump pointers in two passes
;---------------------------------------------------------------------------
Loop, % Len := StrLen(Code) ; first pass
If (CMD := SubStr(Code, A_Index, 1)) = "["
Push("Stack", A_Index)
Else If (CMD = "]")
Jump[%A_Index%] := Pop("Stack")
Loop, % Len ; second pass goes backwards
If (CMD := SubStr(Code, Index:=Len-A_Index, 1)) = "]"
Push("Stack", Index)
Else If (CMD = "[")
Jump[%Index%] := Pop("Stack")
Return
;---------------------------------------------------------------------------
GetChar() { ; retrieve a single char from StdIn (keyboard)
;---------------------------------------------------------------------------
Progress, b2 w150 zh0 fs9, Brainfuck Interpreter waits for input ...
Input, InKey$, L1
Progress, Off
Return, Asc(InKey$)
}
;---------------------------------------------------------------------------
Push(Stack, x) { ; push x onto stack named "Stack"
;---------------------------------------------------------------------------
local pos
%Stack%_0 := pos := %Stack%_0 ? %Stack%_0 + 1 : 1
%Stack%_%pos% := x
}
;---------------------------------------------------------------------------
Pop(Stack) { ; pop value from stack named "Stack"
;---------------------------------------------------------------------------
local pos
If (pos := %Stack%_0) < 1 ; already empty
Return,, ErrorLevel := -1
Return, %Stack%_%pos%, %Stack%_0--
}
;---------------------------------------------------------------------------
Output(Text) { ; append text to output
;---------------------------------------------------------------------------
; for non-interruptable output
;-----------------------------------------------------------------------
global hOut
SendMessage, 0xC2,, &Text,, ahk_id %hOut% ; EM_REPLACESEL
}
;---------- end of file ----------------------------------------------------
[[Image:BrainfGUI.png]]