Skip to content

Instantly share code, notes, and snippets.

@operator-DD3
Last active March 10, 2016 19:17
Show Gist options
  • Save operator-DD3/6b24abad594ac56acc6c to your computer and use it in GitHub Desktop.
Save operator-DD3/6b24abad594ac56acc6c to your computer and use it in GitHub Desktop.
A concatenative programming language inspired by FORTH and implemented in Lua.
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

#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: *

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment