⚠️ 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.
;---------------------------------------------------------------------------
; SNUSP Interpreter.ahk
; by wolf_II
;---------------------------------------------------------------------------
; interpreter for SNUSP code
;---------------------------------------------------------------------------
;---------------------------------------------------------------------------
Code = ; Goodbye, World!
;---------------------------------------------------------------------------
(
Example taken from RosettaCode.org
$@\G.@\o.o.@\d.--b.@\y.@\e.>@\comma.@\.<-@\W.+@\o.+++r.------l.@\d.>+.! #
| | \@------|# | \@@+@@++|+++#- \\ -
| \@@@@=+++++# | \===--------!\===!\-----|-------#-------/
\@@+@@@+++++# \!#+++++++++++++++++++++++#!/
)
;---------------------------------------------------------------------------
AutoExecute: ; auto-execute section of the script
;---------------------------------------------------------------------------
#SingleInstance, Force ; only one instance allowed
#NoEnv ; don't check empty variables
;-----------------------------------------------------------------------
AppName := "SNUSP"
Gosub, GuiCreate
Gui, Show,, %AppName%
Return
;---------------------------------------------------------------------------
GuiCreate: ; create the main window
;---------------------------------------------------------------------------
; GUI options
Gui, Margin,, 10
Gui, Add, Edit, y0 h0 ; catch the focus
Gui, Add, Checkbox, vWatch, Watch
; SNUSP Code
Gui, Add, GroupBox, w554 h265, SNUSP Code
Gui, Font, s8, Courier New
Gui, Add, Edit, xp+10 yp+20 w534 r15 -Wrap +HScroll vCode HwndhCode, %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 w554 h248, Output
Gui, Font, s8, Courier New
Gui, Add, Edit, xp+10 yp+20 w534 r15 ReadOnly vOutput HwndhOut
Gui, Font ; normal
Return
;---------------------------------------------------------------------------
ButtonLoadCode: ; load code from file
;---------------------------------------------------------------------------
Gui, +OwnDialogs
FileSelectFile, CodeFile,,, Load SNUSP Code, *.snusp
If (ErrorLevel = 1) {
; user dismissed the dialog
Gui, Show
Return
}
If Not SubStr(CodeFile, -5) = ".snusp"
CodeFile .= ".snusp"
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,, SNUSP Code, *.snusp
If (ErrorLevel = 1) {
; user dismissed the dialog
Gui, Show
Return
}
If Not SubStr(CodeFile, -5) = ".snusp"
CodeFile .= ".snusp"
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
;~ GuiControl, Disable, Code
GuiControl, Disable, Output
GuiControl, Disable, &Load
GuiControl, Disable, &Save
GuiControl, Disable, &Run
Gosub, PadCode
;~ GuiControl, Enable, Code
GuiControl, Enable, Output
GuiControl, Enable, &Load
GuiControl, Enable, &Save
GuiControl, Enable, &Run
Return
;---------------------------------------------------------------------------
PadCode: ; pad code with spaces
;---------------------------------------------------------------------------
mL := 0 ; max length
Loop, Parse, Code, `n
If (Len := StrLen(A_LoopField)) > mL
mL := Len
PaddedCode := ""
Loop, Parse, Code, `n
PaddedCode .= A_LoopField Repeat(" ", mL - StrLen(A_LoopField)) "`r`n"
GuiControl,, Code, % Code := PaddedCode
ml += 2
; find code entry point
InstrPtr := (pos := InStr(Code, "$")) ? pos : 1
;---------------------------------------------------------------------------
Interpreter: ; this is the SNUSP Interpreter
;---------------------------------------------------------------------------
; setup SNUSP environment
VarSetCapacity(SNUSP_MEM, 4096, 0)
DataPtr := InstrDir := 0
ControlFocus,, ahk_id %hCode%
Loop {
; read next instruction
getNext(InstrPtr)
CMD := SubStr(Code, InstrPtr, 1)
Data@Ptr := NumGet(SNUSP_MEM, DataPtr, "Char")
If Watch {
Highlight(InstrPtr)
Sleep, 25
;~ ListVars
;~ Pause
}
If (CMD = "+") ; increment the data at DataPointer
NumPut(Data@Ptr + 1, SNUSP_MEM, DataPtr, "Char")
Else If (CMD = "-") ; decrement the data at DataPointer
NumPut(Data@Ptr - 1, SNUSP_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(), SNUSP_MEM, DataPtr, "Char")
Else If (CMD = "\") ; LURD
LURD(InstrDir)
Else If (CMD = "/") ; RULD
RULD(InstrDir)
Else If (CMD = "!") ; SKIP
getNext(InstrPtr)
Else If (CMD = "?") { ; SKIPZ
If (Data@Ptr = 0)
getNext(InstrPtr)
} Else If (CMD = "@") { ; ENTER
Push("Stack", InstrPtr)
Push("Stack", InstrDir)
} Else If (CMD = "#") { ; LEAVE
InstrDir := Pop("Stack")
InstrPtr := Pop("Stack")
If (ErrorLevel = -1)
Break
Else
getNext(InstrPtr)
} Else If (CMD = "") ; this is the end of code
Break
}
Return
;---------------------------------------------------------------------------
getNext(ByRef InstrPtr) { ; get next instruction pointer
;---------------------------------------------------------------------------
; instruction directions
; Up = 3
; Left = 2 0 = Right
; 1 = Down
;-----------------------------------------------------------------------
global InstrDir, mL
InstrPtr += (InstrDir > 1 ? -1 : 1) * (InstrDir & 1 ? mL : 1)
}
;---------------------------------------------------------------------------
LURD(ByRef InstrDir) { ; reflect the instruction direction "\"
;---------------------------------------------------------------------------
;~ case 0 -> 1
;~ case 1 -> 0
;~ case 2 -> 3
;~ case 3 -> 2
;-----------------------------------------------------------------------
InstrDir += (InstrDir & 1 ? -1 : 1)
}
;---------------------------------------------------------------------------
RULD(ByRef InstrDir) { ; reflect the instruction direction "/"
;---------------------------------------------------------------------------
;~ case 0 -> 3
;~ case 1 -> 2
;~ case 2 -> 1
;~ case 3 -> 0
;-----------------------------------------------------------------------
InstrDir := 3 - InstrDir
}
;---------------------------------------------------------------------------
Repeat(String,Count) {
;---------------------------------------------------------------------------
Loop, %Count%
Result .= String
Return, Result
}
;---------------------------------------------------------------------------
GetChar() { ; retrieve a single char from StdIn (keyboard)
;---------------------------------------------------------------------------
Progress, b2 w150 zh0 fs9, SNUSP 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--
}
;---------------------------------------------------------------------------
Highlight(InstrPtr) { ; select current command in code
;---------------------------------------------------------------------------
global hCode
SendMessage, 0xB1, InstrPtr-1, InstrPtr,, ahk_id %hCode% ; EM_SETSEL
}
;---------------------------------------------------------------------------
Output(Text) { ; append text to output
;---------------------------------------------------------------------------
; for non-interruptable output
;-----------------------------------------------------------------------
global hOut
SendMessage, 0xC2,, &Text,, ahk_id %hOut% ; EM_REPLACESEL
}
;---------- end of file ----------------------------------------------------