User:XFire35/auo.lua
Jump to navigation
Jump to search
#!/usr/bin/env lua --[[ Copyright (c) 2009, Curt Strangward Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ]]-- _s = {} -- Stack _v = {} -- Variable Stack _j = {} -- Jump Stack _c = {} -- Code Stack _t = {} -- Temporary Array _l = {} -- Loop Array - Used in Control Flow Statements --------------------------------------------------------------------------------------------- -- Language Support Functions function print(text) -- Modifies lua's print to make it look nicer if text ~= nil then io.write ( ":: "..text.."\n" ); else end end function pA(array) -- Prints the array for k, v in pairs(array) do print(k..": "..array[k]); end end function c_v(var) -- Checks variable if _v[var] then if type(_v[var]) == "string" then return("'".._v[var].."'") else return(_v[var]) end else print("Unidentified Value: "..var) end end function c_vB(var) -- Checks variable B version if _v[var] then return(_v[var]) else print("Unidentified Value: "..var) end end function v_m(_cT) if string.match(_cT, "%$[%w+%_]+") then _cT = string.gsub(_cT, "%$([%w+%_]+)", c_v) end return(_cT) end --------------------------------------------------------------------------------------------- -- Language's Stack Functions function s_push(value) -- Push value to _s table.insert(_s, value) end function s_pop() -- Retrieve top _s item if table.getn(_s) == 0 then return ("0") else return(table.remove(_s)) end end function s_del() -- Remove top item from stack s_pop() end function s_mer() -- Merge top two items on stack local a, b = s_pop(), s_pop() s_push(tostring(a)..tostring(b)) end function s_dup() -- Duplicate top item on _s if table.getn(_s) == 0 then e("Stack","0") else local a = s_pop() s_push(a); s_push(a); end end function s_exh(value) -- Exchanges top two _s items local a, b = s_pop(), s_pop() s_push(a); s_push(b); end function s_clear() -- Clear the stack _s = {} end --------------------------------------------------------------------------------------------- -- Language's Functions function m_add(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then s_push(x+y) else print("Malformed Variables") end end function m_sub(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then s_push(x-y) else print("Malformed Variables") end end function m_mul(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then s_push(x*y) else print("Malformed Variables") end end function m_div(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then s_push(x/y) else print("Malformed Variables") end end function q_equ(x,y) if x ~= "" or nil and y ~= "" or nil then if x == y then s_push('true') else s_push('false') end end end function q_neq(x,y) if x ~= "" or nil and y ~= "" or nil then if x ~= y then s_push('true') else s_push('false') end end end function q_lss(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then if x < y then s_push('true') else s_push('false') end else print("Malformed Variables") end end function q_els(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then if x <= y then s_push('true') else s_push('false') end else print("Malformed Variables") end end function q_grt(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then if x > y then s_push('true') else s_push('false') end else print("Malformed Variables") end end function q_egr(x,y) local x, y = tonumber(x), tonumber(y) if type(x) == "number" and type(y) == "number" then if x >= y then s_push('true') else s_push('false') end else print("Malformed Variables") end end function t_len(x) if x ~= "" or nil then s_push(string.len(tostring(x))) end end function t_add(x,y) s_push(x..y) end function t_div(x,n) local _t, _t2, n = {}, {}, tonumber(n) for m in string.gfind(x, "[%w%p%s]") do table.insert(_t, m) end if n > table.getn(_t) then print("Error: Value exceeds string length") else for i = n, table.getn(_t),1 do table.insert(_t2, _t[i]) _t[i] = nil end _t, _t2 = table.concat(_t,""), table.concat(_t2,"") s_push(_t); s_push(_t2) end end function i_prt(text) if text ~= nil then io.write ( ":> "..text.."\n" ); else end end --------------------------------------------------------------------------------------------- -- Main Language Parser, Causes everything to be run function process(t) for token = 1, table.getn(t) do local _cT = t[token] -- Conditional Statements -- c.i:[%true],[%false] > q.g:$x,10 if string.match(_cT, "c%.i%:%[%%([%w%_]+)%],%[%%([%w%_]+)%][%s]*%>[%s]*%a%.%a%:([%w%p]+)%,([%w%p]+)") then _cT = string.gsub(_cT, "[%w%p%s]+(%a%.%a%:[%w%p]+%,[%w%p]+)", function(w) table.insert(_l,w); process(_l) end) _l = {} if s_pop() == "true" then _cT = string.gsub(_cT, "c%.i%:%[(%%[%w%_]+)%][%w%p%s]+", function(w) table.insert(_l,w); process(_l) end) elseif s_pop() == "false" then _cT = string.gsub(_cT, "c%.i%:[%w%p%s]+,%[(%%[%w%_]+)%][%w%p%s]", function(w) table.insert(_l,w); process(_l) end) end _l = {} -- c.f:[update],[%body] > q.g:$x,10 elseif string.match(_cT, "c%.f%:%[%a%.%a%:$[%w%_]+%,[%w%p]+%],%[%%[%w%_]+%][%s]*%>[%s]*%a%.%a%:[%w%p]+%,[%w%p]+") then local var = "" _cT = string.gsub(_cT, "[%w%p%s]+%>[%s]*(%a%.%a%:[%w%p]+%,[%w%p]+)", function(w) table.insert(_l,w); end) -- Argument _cT = string.gsub(_cT, "c%.f%:[%w%p%s]+,%[(%%[%w%_]+)%][%w%p%s]+", function(w) table.insert(_l,w); end) -- Body _cT = string.gsub(_cT, "c%.f%:%[(%a%.%a%:$[%w%_]+%,[%w%p]+)%][%w%p]+", function(w) table.insert(_l,w); end) -- Change _cT = string.gsub(_cT, "c%.f%:%[%a%.%a%:$([%w%_]+)%,[%w%p]+%][%w%p%s]", function(w) if _v[w] then var = w end end) while true do process(_l) _v[var] = s_pop() if s_pop() == "false" then break end end _l = {} -- c.w:[update],[%body] > q.g:$x,10 elseif string.match(_cT, "c%.w%:%[%%([%w%_]+)%][%s]*%>[%s]*%a%.%a%:([%w%p]+)%,([%w%p]+)") then _cT = string.gsub(_cT, "[%w%p%s]+%>[%s]*(%a%.%a%:[%w%p]+%,[%w%p]+)", function(w) table.insert(_l,w) end) _cT = string.gsub(_cT, "c%.w%:%[(%%[%w%_]+)%][%w%p%s]", function(w) table.insert(_l,w) end) while true do process(_l) if s_pop() == "false" then break end end _l = {} -- %foo -- Runs function 'foo' elseif string.match(_cT, "^%%([%w%_]+)") then _cT = string.gsub(_cT, "%%([%w%_]+)", function(w) if _j[w] then process(_j[w]); end end) end -- Math Functions -- m.a:x,y - Add x and y if string.match(_cT, "m%.a%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "m%.a%:(%w+),(%w+)", m_add) -- m.s:x,y - Add x and y elseif string.match(_cT, "m%.s%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "m%.s%:(%w+),(%w+)", m_sub) -- m.m:x,y - Add x and y elseif string.match(_cT, "m%.m%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "m%.m%:(%w+),(%w+)", m_mul) -- m.d:x,y - Add x and y elseif string.match(_cT, "m%.d%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "m%.d%:(%w+),(%w+)", m_div) -- Comparison Functions -- q.e:x,y Equal? elseif string.match(_cT, "q%.e%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "q%.e%:([%w%p%s]+),([%w%p%s]+)", q_equ) -- q.n:x,y Not equal? elseif string.match(_cT, "q%.n%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "q%.n%:%'?([%w%p%s]+)%'?,%'?([%w%p%s]+)%'?", q_neq) -- q.l:x,y x less than y elseif string.match(_cT, "q%.l%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "q%.l%:(%w+),(%w+)", q_lss) -- q.s:x,y x less than, equal to y elseif string.match(_cT, "q%.s%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "q%.a%:(%w+),(%w+)", q_els) -- q.g:x,y x greater than y elseif string.match(_cT, "q%.g%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "q%.g%:(%w+),(%w+)", q_grt) -- q.r:x,y x greater than, equal to y elseif string.match(_cT, "q%.r%:(%-?[%$%_%w%.?]+),(%-?[%$%_%w%.?]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "q%.r%:(%w+),(%w+)", q_egr) end -- String Functions -- s.l:x - Length of string x if string.match(_cT, "s%.l%:([%w%p]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "s%.l%:%'([%w%s%p]+)%'", t_len) -- s.a:x,y - Add strings x and y together elseif string.match(_cT, "s%.a%:([%w%p]+),([%w%p]+)") then _cT = v_m(_cT) _cT = string.gsub(_cT, "s%.a%:%'([%w%s%p]+)%','([%w%s%p]+)%'", t_add) -- s.s:x,n - Split string x at position n elseif string.match(_cT, "s%.s%:([%w%p]+),([%w%p]+)") then _cT = v_m(_cT) if string.match(_cT, "s%.s%:%'([%w%s%p]+)%',([%d]+)") then _cT = string.gsub(_cT, "s%.s%:%'([%w%s%p]+)%',([%d]+)", function(w,x) t_div(w,x) end) end end -- Stack Functions -- @ Pushes value to stack if string.match(_cT, "%'?([%$%_%w]+)%'?[%s]*%>[%s]*%@") then _cT = v_m(_cT) if string.match(_cT, "(%-?[%d%.?]+)[%s]*%>[%s]*%@") then _cT = string.gsub(_cT, "(%-?[%d%.?]+)[%s]*%>[%s]*%@", function(w) s_push(tonumber(w)) end) elseif string.match(_cT, "%'([%w%s%p]+)%'[%s]*%>[%s]*%@") then _cT = string.gsub(_cT, "%'([%w%s%p]+)%'[%s]*%>[%s]*%@", function(w) s_push(tostring(w)) end) end -- <@ Pops value from stack elseif string.match(_cT, "%<%@") then local var = s_pop() if type(var) == "number" then _cT = string.gsub(_cT, "%<%@", var) else _cT = string.gsub(_cT, "%<%@", "'"..var.."'") end -- -@ Disgards top item on stack elseif string.match(_cT, "%-%@") then s_del() -- *@ Duplicate top item on stack elseif string.match(_cT, "%*%@") then s_dup() -- +@ Merges the top two items on stack elseif string.match(_cT, "%+%@") then s_mer() -- ~@ Disgards top item on stack elseif string.match(_cT, "%~%@") then s_exh() -- /@ Clears the stack elseif string.match(_cT, "%@") then s_clear() end -- Variable Declaration Functions -- 5 > $a if string.match(_cT, "(%-?[%d%.?]+)[%s]*%>[%s]*%$([%w%_]+)") then _cT = string.gsub(_cT, "(%-?[%d%.?]+)[%s]*%>[%s]*%$([%w%_]+)", function(w,x) _v[x] = tonumber(w) end) -- 'foo' > $bar elseif string.match(_cT, "%'([%w%s%p]+)%'[%s]*%>[%s]*%$([%w%_]+)") then _cT = string.gsub(_cT, "%'([%w%s%p]+)%'[%s]*%>[%s]*%$([%w%_]+)", function(w,x) _v[x] = tostring(w) end) -- $nil > $foo, Clears value $foo elseif string.match(_cT, "%$nil[%s]*%>[%s]*%$([%w%_]+)") then _cT = string.gsub(_cT, "%$nil[%s]*%>[%s]*%$([%w%_]+)", function(w) _v[w] = nil end) -- $foo > $bar elseif string.match(_cT, "%$([%w%_]+)[%s]*%>[%s]*%$([%w%_]+)") then _cT = string.gsub(_cT, "%$([%w%_]+)[%s]*%>[%s]*%$([%w%_]+)", function(w,x) if _v[w] then _v[x] = c_v(w) end end) end -- Input/Output Functions -- i.o:['Message'] -- Writes message if string.match(_cT, "i%.o%:%[%'[%w+%s+%p+]+%'%]") then if string.match(_cT, "%$[%w+%_]+") then _cT = string.gsub(_cT, "%$([%w+%_]+)", c_vB) end _cT = string.gsub(_cT, "i%.o%:%[%'([%w+%s+%p+]+)%'%]", i_prt) -- i.i:$var -- User input >$var elseif string.match(_cT, "i%.i%:$([%w%_]+)") then io.write ( " > " ) local input = io.stdin:read"*l" if input ~= "" then _cT = string.gsub(_cT, "i%.i%:$([%w%_]+)", function(w) _v[w] = tostring(input) end) else _cT = string.gsub(_cT, "i%.i%:$([%w%_]+)", function(w) _v[w] = '' end) end -- i.r:['file'] -- Run File elseif string.match(_cT, "i%.r%:%[%'[%w+%s+%p+]+%'%]") then _cT = v_m(_cT) local input = "" _cT = string.gsub(_cT, "i%.r%:%[%'([%w+%s+%p+]+)%'%]", function (w) input = w end) if io.open (input, "r") then local file = io.open(input, "r") local str = file:read("*a") for match in string.gfind(str, "%s*([^\n]*%S)") do if string.match(match, "%#[%s+%w+%p+]+") then match = string.gsub(match, "%#[%s+%w+%p+]+", "") end if match == "" then match = nil else table.insert(_t,match) end end end jump_rec(_t); process(_t) _t = {} end end end --------------------------------------------------------------------------------------------- -- Jump Recorder: -- Inserts into a table what code is used for a 'jump' function jump_rec(t) for i = 1, table.getn(t) do _cT = t[i] if string.match(_cT, "%%([%w%_]+)%:[%s]*%{") then local title = "" _cT = string.gsub(_cT, "%%([%w%_]+)%:[%s]*%{", function(w) title = w end) if string.match(_cT, "%%([%w%_]+)%:[%s]*%{") then t[i] = "" local a = i + 1 local code = {} while true do _cA = t[a] if string.match(_cA, "^%}") then t[a] = "" break else table.insert(code, _cA) t[a] = "" end a = a + 1 end _j[title] = code end end end end --------------------------------------------------------------------------------------------- -- Splits the source into table arrrays function tokeniser(line) for match in string.gfind(line, "%s*([^\n]*%S)") do if string.match(match, "%#[%s+%w+%p+]+") then match = string.gsub(match, "%#[%s+%w+%p+]+", "") end if match == "" then match = nil else table.insert(_c,match) end end jump_rec(_c); end --------------------------------------------------------------------------------------------- -- Main Routine function main() -- Main program loop io.write ( ">> " ); local input = io.stdin:read"*l" if input == "quit" then os.exit() end if input ~= "" or nil then tokeniser(input); -- Ensure input is not blank process(_c); _c = {}; _l = {}; _t = {}; end main(); end io.write(":: Auo \n"); main()