⚠️ 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.
Lua
-- directions UP, DOWN, LEFT, RIGHT = 1, 2, 4, 8 -- snusp snIPC, snIPL, snMPT, snDIR, snMEMORY, snSTACK, snCODE = 1, 1, 1, RIGHT, {0}, {}, {} -- stackframe Stackframe = {} function Stackframe:new() local sf = { IPC, IPL, DIR = 0, 0, 0 } self.__index = self return setmetatable( sf, self ) end function memStep( a ) snMPT = snMPT + a if snMPT < 0 then return false end if snMPT > #snMEMORY then table.insert( snMEMORY, 0 ) end return true end function changeDir( d ) if d == RIGHT then if snDIR == RIGHT then snDIR = UP elseif snDIR == LEFT then snDIR = DOWN elseif snDIR == DOWN then snDIR = LEFT else snDIR = RIGHT end elseif d == LEFT then if snDIR == RIGHT then snDIR = DOWN elseif snDIR == LEFT then snDIR = UP elseif snDIR == DOWN then snDIR = RIGHT else snDIR = LEFT end end end function step() if snDIR == RIGHT then snIPC = snIPC + 1 elseif snDIR == LEFT then snIPC = snIPC - 1 elseif snDIR == DOWN then snIPL = snIPL + 1 elseif snDIR == UP then snIPL = snIPL - 1 end if snIPL > #snCODE or snIPL < 1 then return false end if snIPC > #snCODE[snIPL] or snIPC < 1 then return false end return true end function pushFrame() local sf = Stackframe:new(); sf.IPC = snIPC; if snDIR == RIGHT then sf.IPC = sf.IPC + 1 elseif snDIR == LEFT then sf.IPC = sf.IPC - 1 end sf.IPL = snIPL; if snDIR == DOWN then sf.IPL = sf.IPL + 1 elseif snDIR == UP then sf.IPL = sf.IPL - 1 end sf.DIR = snDIR table.insert( snSTACK, 1, sf ) end function popFrame() if #snSTACK < 1 then return false end local sf = table.remove( snSTACK, 1 ) snIPC = sf.IPC; snIPL = sf.IPL; snDIR = sf.DIR sf = nil return true end function exec( c ) local res = true if c == "<" then res = memStep( -1 ) elseif c == ">" then res = memStep( 1 ) elseif c == "+" then snMEMORY[snMPT] = snMEMORY[snMPT] + 1 elseif c == "-" then snMEMORY[snMPT] = snMEMORY[snMPT] - 1 elseif c == "." then io.write( string.char( snMEMORY[snMPT] ) ) elseif c == "," then snMEMORY[snMPT] = string.byte( io.read() ) elseif c == "!" then res = step() elseif c == "?" and snMEMORY[snMPT] == 0 then res = step() elseif c == "@" then pushFrame() elseif c == "#" then res = popFrame() elseif c == "/" then changeDir( RIGHT ) elseif c == "\\" then changeDir( LEFT ) end return res end function run( filename ) local i, lc = assert( io.open( filename, "rb" ) ), 1 for ln in io.lines( filename ) do for c = 1, #ln do if ln:sub( c, c ) == "$" then snIPL = lc; snIPC = c end end snCODE[#snCODE + 1] = ln lc = lc + 1 end repeat if not exec( snCODE[snIPL]:sub( snIPC, snIPC ) ) then break end until step() == false end -- [[ entry point ( argument = snusp program file name ) ]]-- if arg[1] ~= nil then run( arg[1] ) end