⚠️ 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