Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function run(tbl, name, debug, limitx, limity)
- w, h = term.getSize()
- limitx, limity = limitx or w, limity or h
- for _x=0, limitx do
- if not tbl[_x] then tbl[_x] = {} end
- for _y=0, limity do
- if not tbl[_x][_y] then
- tbl[_x][_y] = " "
- end
- end
- end
- local x, y = 0, 0
- local vx, vy = 1, 0
- local stringmode = false
- local stack = {}
- local bExit = false
- local function push(n)
- table.insert(stack, n)
- end
- local function pop()
- if stack[#stack] then
- return table.remove(stack, #stack)
- else
- error((name or "befunge")..": ("..x..", "..y..") Stack is empty!", 0)
- end
- end
- local lastchar = " "
- local lastx, lasty = 1, 1
- local first = true
- local function draw()
- if debug then
- for _x,v in pairs(tbl) do
- for _y,char in pairs(v) do
- if _x == x and _y == y then
- term.setBackgroundColor(colors.yellow)
- lastchar = char
- lastx, lasty = _x, _y
- else
- term.setBackgroundColor(colors.black)
- end
- if ((char ~= " ") and first) or (_x==x and _y==y)then
- term.setCursorPos(_x+1, _y+1)
- write(char)
- end
- end
- end
- sleep(0.1)
- term.setBackgroundColor(colors.black)
- term.setCursorPos(lastx+1, lasty+1)
- term.write(lastchar)
- first = false
- end
- end
- local cmds = {
- -- Befunge-93 Instruction List from http://en.wikipedia.org/wiki/Befunge
- ["+"] = function() a = pop() b = pop() push(a+b) end, -- Addition: Pop a and b, then push a+b
- ["-"] = function() a = pop() b = pop() push(a-b) end, -- Subtraction: Pop a and b, then push b-a
- ["*"] = function() a = pop() b = pop() push(a*b) end, -- Multiplication: Pop a and b, then push a*b
- ["/"] = function() a = pop() b = pop() push(a/b) end, -- Integer division: Pop a and b, then push b/a, rounded down. If a is zero, ask the user what result they want
- ["%"] = function() a = pop() b = pop() push(a%b) end, -- Modulo: Pop a and b, then push the remainder of the integer division of b/a. If a is zero, ask the user what result they want
- ["!"] = function() a = pop() if a == 0 then push(1) else push(0) end end, -- Logical NOT: Pop a value. If the value is zero, push 1; otherwise, push zero
- ["`"] = function() a = pop() b = pop() if b>a then push(1) else push(0) end end, -- Greater than: Pop a and b, then push 1 if b>a, otherwise zero
- [">"] = function() vx, vy = 1, 0 end, -- Start moving right
- ["<"] = function() vx, vy = -1, 0 end, -- Start moving left
- ["^"] = function() vx, vy = 0, -1 end, -- Start moving up
- ["v"] = function() vx, vy = 0, 1 end, -- Start moving down
- ["?"] = function() -- Start moving in a random cardinal direction
- local dir = math.random(1, 4)
- if dir == 1 then vx, vy = 1, 0
- elseif dir == 2 then vx, vy = -1, 0
- elseif dir == 3 then vx, vy = 0, -1
- elseif dir == 4 then vx, vy = 0, 1
- end
- end,
- ["_"] = function() a = pop() -- Pop a value; move right if value=0, left otherwise
- if a == 0 then
- vx, vy = 1, 0
- else
- vx, vy = -1, 0
- end
- end,
- ["|"] = function() a = pop() -- Pop a value; move down if value=0, up otherwise
- if a == 0 then
- vx, vy = 0, 1
- else
- vx, vy = 0, -1
- end
- end,
- ['"'] = function() stringmode = not stringmode end, -- Start string mode: push each character's ASCII value all the way up to the next "
- [":"] = function() push(stack[#stack]) end, -- Duplicate value on top of the stack
- ["\\"] = function() a = pop() b = pop() push(a) push(b) end, -- Swap two values on top of the stack
- ["$"] = function() pop() end, -- Pop value from the stack
- ["."] = function() -- Pop value and output as an integer
- if debug then term.setCursorPos(1, h) end
- write(pop())
- if debug then sleep(0.1) end
- end,
- [","] = function() -- Pop value and output as ASCII character
- if debug then term.setCursorPos(1, h) end
- write(string.char(pop()))
- if debug then sleep(0.1) end
- end,
- ["#"] = function() x, y = x+vx, y+vy end, -- Trampoline: Skip next cell
- ["p"] = function() -- A "put" call (a way to store a value for later use). Pop y, x and v, then change the character at the position (x,y) in the program to the character with ASCII value v
- local _y, _x, v = pop(), pop(), pop()
- tbl[_x][_y] = string.char(v)
- first = true
- end,
- ["g"] = function()
- local _y, _x = pop(), pop()
- push(string.byte(tbl[_x][_y]))
- end, -- A "get" call (a way to retrieve data in storage). Pop y and x, then push ASCII value of the character at that position in the program
- ["&"] = function() -- Ask user for a number and push it
- if debug then term.setCursorPos(1, h) end
- num = read()
- push(tonumber(num) or 0)
- term.clear()
- first = true
- end,
- ["~"] = function() -- Ask user for a character and push its ASCII value
- if debug then term.setCursorPos(1, h) end
- char = read()
- push(string.byte(string.sub(char, 1, 1)))
- term.clear()
- first = true
- end,
- ["@"] = function() bExit = true end, -- End program
- [" "] = function() end, -- No-op. Does nothing
- ["s"] = function() sleep(0) end -- Sleep, add to avoid "Too Long without Yielding" error
- }
- term.clear()
- while not bExit do
- draw()
- --if not tbl[x] or not tbl[x][y]then
- -- error((name or "befunge")..": ("..x..", "..y..") Instruction does not exist!", 0)
- --end
- local cmd
- if tbl[x] then
- cmd = tbl[x][y] or " "
- else
- cmd = " "
- end
- if stringmode and cmd ~= '"' then -- within ""
- push(string.byte(cmd))
- elseif string.match(cmd, "%d") then -- a number
- push(tonumber(cmd))
- else -- a command
- if cmds[cmd] then
- cmds[cmd]()
- else
- error((name or "befunge")..": ("..x..", "..y..") Unknown instruction!", 0)
- end
- end
- x, y = (x+vx)%80, (y+vy)%20
- end
- print("")
- end
- function load(path)
- local file = io.open(path, "r")
- local tbl = {}
- local y = 0
- for line in file:lines() do
- for x=1, line:len() do
- if not tbl[x-1] then tbl[x-1] = {} end
- tbl[x-1][y] = string.sub(line, x, x)
- end
- y = y + 1
- end
- return tbl
- end
- tArgs = {...}
- run(load(tArgs[1]), tArgs[1], tArgs[2])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement