#5 A stack-based concatenative forthlike system. Not intended as a toy, but probableeee a damn toy.
##Example Code FUNC star 42 EMIT ENDFUNC star Output: *
| pc=1 --program counter | |
| program = {} --array of words in program | |
| dict = {} --dictionary of user defined words | |
| prim = {} --language keywords | |
| stack= {} --working stack | |
| rstack = {} --2nd stack | |
| mem = {} --memory | |
| mode = "interpret" | |
| alive = true --used for halting and error | |
| c_word = "" | |
| function push(n) | |
| stack[#stack+1]=n | |
| end | |
| function pop() | |
| if #stack > 0 then | |
| temp = stack[#stack] | |
| stack[#stack]=nil | |
| else | |
| io.write("Stack Underflow") | |
| temp = 0 | |
| end | |
| return temp | |
| end | |
| prim["+"] = function() push(pop()+pop()) end | |
| prim["*"] = function() push(pop()*pop()) end | |
| prim["-"] = function() local a = pop(); push(pop()-a) end | |
| prim["/"] = function() local a = pop(); push(pop()/a) end | |
| prim["."] = function() io.write(pop()) end | |
| prim["@"] = function() local addr = pop(); local data = mem[addr] or 0; push(data) end | |
| prim["!"] = function() local addr = pop(); mem[addr] = pop() end | |
| prim.BL = function() io.write(" ") end | |
| prim.EMIT = function() io.write(string.char(pop())) end | |
| prim.FUNC = function() mode = "pre-compile" end | |
| eval = function(s) | |
| if prim[s] then --if word is a language primitive | |
| prim[s]() --execute it | |
| elseif dict[s] then --if word is a user defined function | |
| for i = 1,#dict[s] do --step through each word in definition | |
| process(dict[s][i]) --and process it | |
| end | |
| elseif type(tonumber(s)) == 'number' then --if word is a number | |
| push(tonumber(s)) --push it on the stack | |
| else --otherwise report the error | |
| io.write("\nError: ",s) | |
| alive=false | |
| end | |
| end | |
| process = function(s) --process by mode and update modes | |
| if mode == "interpret" then | |
| eval(s) | |
| elseif mode == "pre-compile" then | |
| dict[s]={} | |
| c_word = s | |
| mode = "compile" | |
| elseif mode == "compile" then | |
| if s ~= "ENDFUNC" then | |
| dict[c_word][#dict[c_word]+1] = s | |
| else | |
| mode = "interpret" | |
| end | |
| end | |
| end | |
| -- ******* MAIN LOOP ******** | |
| io.write('>') --display our prompt | |
| for line in io.lines(arg[1]) do --grab each line of std input | |
| program=nil;program={} | |
| for word in string.gmatch(line, '([^%s]+)') do --separate each whitespace delimited word | |
| program[#program+1] = string.upper(word) --and put word into program array | |
| end | |
| pc=0;alive=true | |
| while alive==true do | |
| pc=pc+1 | |
| if pc > #program then | |
| alive = false | |
| else | |
| process(program[pc]) | |
| end | |
| end | |
| io.write('\n>') --display our prompt before looping back for more input | |
| end |