commit b3ce57c5b4ce2def042be084edfdb5a2bb7e3255 Author: HybridDog Date: Sun Nov 13 14:42:57 2016 +0100 :boom: A .gitignore A LICENSE.txt A README.md A depends.txt A faden.lua A init.lua A parser.lua A standardbefehlssatz.lua A textures/pdisc.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..098d2de --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +## Generic ignorable patterns and files +*~ +debug.txt +*.patch diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..bc0b1db --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1 @@ +WTFPL diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6cc9a2 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +commands are read line by line + +```[:] [ [[,]``` + +arguments can be either variables, labels or immediates, +labels are replaced with immediates which have the line numbers of the labels as their values +true/false: boolean (immediate) +12.6: number (immediate) +$hello nwae: string (immediate) +nodolla: either a label is called so (immediate) or it's a variable diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default diff --git a/faden.lua b/faden.lua new file mode 100644 index 0000000..be241eb --- /dev/null +++ b/faden.lua @@ -0,0 +1,93 @@ +local function befehl_ausfuhren(faden) + local is = faden.is + local imms = faden.imms + local vars = faden.vars + local befehl, args = unpack(faden.liste[faden.ip]) + for i = 1,#is do + local bfunk = is[i] + if bfunk then + local fa = {} + local ersetzbar = {} + if args then + for i = 1,#args do + local arg = args[i] + if type(arg) == "number" then + fa[i] = imms[arg] + else + fa[i] = vars[arg] + ersetzbar[i] = true + end + end + end + local weiter, ergebnis = bfunk(fa, faden) + if not weiter then + return false, "Command " .. befehl .. ": " .. ergebnis + end + if ergebnis ~= nil then + if type(ergebnis) ~= "table" then + ergebnis = {ergebnis} + end + for i,v in pairs(ergebnis) do + if not ersetzbar[i] then + return false, "Attempt on changing an immediate" + end + vars[args[i]] = v + end + end + faden.ip = faden.ip + 1 + if faden.ip > #faden.liste then + return false, "Done" + end + return true + end + end + return false, 'Unknown command "' .. befehl .. '"' +end + +local function programm_ausfuhren(faden) + local weiter,msg = befehl_ausfuhren(faden) + if not weiter then + faden.log = faden.log .. "Aborted: " .. msg .. "\n" + faden.exit() + return + end + return not faden.stopped and programm_ausfuhren(faden) +end + +return function (faden_manip, parsed) + local faden = { + log = "", + ip = 1, + sp = 50, + sb = 50, + stack = {}, + is = {pdisc.standard_befehlssatz}, + suscitate = programm_ausfuhren, + flush = function(self) + print(self.log) + self.log = "" + return true + end, + stop = function(self) + self.stopped = true + end, + continue = function(self) + self.stopped = false + self:suscitate() + end, + try_rebirth = function(self) + if minetest.get_gametime() < self.rebirth then + self:continue() + end + end, + exit = function(self) + self:flush() + end, + } + if parsed then + faden.imms = parsed[1] + faden.liste = parsed[2] + end + faden_manip(faden) + return faden +end diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..e7f1b6c --- /dev/null +++ b/init.lua @@ -0,0 +1,19 @@ +local load_time_start = minetest.get_us_time() + + +local mpath = minetest.get_modpath"pdisc" .. "/" + +pdisc = { + parse = dofile(mpath .. "parser.lua"), + standard_befehlssatz = dofile(mpath .. "standardbefehlssatz.lua"), + create_thread = dofile(mpath .. "faden.lua") +} + + +local time = (minetest.get_us_time() - load_time_start) / 1000000 +local msg = "[pdisc] loaded after ca. " .. time .. " seconds." +if time > 0.01 then + print(msg) +else + minetest.log("info", msg) +end diff --git a/parser.lua b/parser.lua new file mode 100644 index 0000000..7314b50 --- /dev/null +++ b/parser.lua @@ -0,0 +1,87 @@ +local function parse_zeile(marken, imms, z, zn) + -- Kommentar entfernen + local komment = z:find";" + if komment then + z = z:sub(1, komment-1) + end + + z = z:trim() + if #z == 0 then + return {} + end + + -- Marke erkennen + local marke = z:find":" + if marke then + mname = z:sub(1, marke - 1) + marken[mname] = zn + + z = z:sub(marke+1):trim() + if #z == 0 then + return {} + end + end + + -- Befehl erkennen + local immn = #imms+1 + local befehl = z + local args + local leernb = z:find" " + if leernb then + befehl = z:sub(1, leernb - 1) + + -- Argument(e) erkennen + z = z:sub(leernb+1):trim() + args = z:split"," + for i = 1,#args do + local arg = args[i]:trim() + if #arg == 0 + or arg == "false" then + arg = false + elseif arg == "true" then + arg = true + elseif arg:sub(1, 1) == "$" then + imms[immn] = arg:sub(2) + arg = immn + immn = immn+1 + elseif tonumber(arg) then + imms[immn] = tonumber(arg) + arg = immn + immn = immn+1 + end + args[i] = arg + end + end + + return {befehl, args} +end + +return function(programm) + local imms = {} + local marken = {} + + -- Programm erkennen + local liste = programm:split"\n" + local zn = #liste + for i = 1,zn do + liste[i] = parse_zeile(marken, imms, liste[i], i) + end + local immn = #imms+1 + + -- Marken durch immediates ersetzen + for i = 1,zn do + local args = liste[i][2] + if args then + for i = 1,#args do + local mwert = marken[args[i]] + if mwert then + imms[immn] = mwert + args[i] = immn + immn = immn+1 + end + end + end + end + + return {imms, liste} +end diff --git a/standardbefehlssatz.lua b/standardbefehlssatz.lua new file mode 100644 index 0000000..9b6ae89 --- /dev/null +++ b/standardbefehlssatz.lua @@ -0,0 +1,138 @@ +local WNOA = "wrong number of arguments" +local UAT = "unsupported argument type" +local SE = "error with cmd-cmd executing: " + +local s +s = { + mov = function(params, faden) + if #params ~= 2 then + return false, WNOA + end + return true, params[2] + end, + + add = function(params) + if #params ~= 2 then + return false, WNOA + end + local p1,p2 = unpack(params) + local t1 = type(p1) + local t2 = type(p2) + if t1 ~= t2 then + return false, "different argument types" + end + + if t1 == "number" then + return true, p1 + p2 + end + if t1 == "string" then + return true, p1 .. p2 + end + return false, UAT + end, + + jmp = function(params, faden) + if #params ~= 1 then + return false, WNOA + end + local p = params[1] + if type(p) ~= "number" then + return false, UAT + end + if p < 1 + or p%1 ~= 0 + or p > #faden.liste + 1 then + return false, "jump target out of range" + end + faden.ip = p-1 + if not s.sleep({0}, faden) then + error(SE) + end + return true + end, + + jif = function(params, faden) + if #params ~= 2 then + return false, WNOA + end + if params[1] then + local jmpd,msg = s.jmp({params[2]}, faden) + if not jmpd then + return false, SE .. msg + end + end + return true + end, + + push = function(params, faden) + local pc = #params + if pc == 0 then + return false, WNOA + end + for i = 1,pc do + faden.stack[faden.sp] = params[i] + faden.sp = faden.sp-1 + end + if faden.sp < 0 then + return false, "stack overflow" + end + return true + end, + + pop = function(params, faden) + local pc = #params + if pc == 0 then + return false, WNOA + end + local rt = {} + for i = 1,pc do + faden.sp = faden.sp+1 + rt[i] = faden.stack[faden.sp] + end + if faden.sp > faden.sb then + return false, "stack underflow" + end + return true, rt + end, + + equal = function(params, faden) + if #params ~= 2 then + return false, WNOA + end + return true, params[1] == params[2] + end, + + less = function(params, faden) + if #params ~= 2 then + return false, WNOA + end + local t1 = type(p1) + local t2 = type(p2) + if t1 ~= t2 then + return false, "different argument types" + end + if t1 ~= "number" + and t1 ~= "string" then + return false, UAT + end + return true, params[1] < params[2] + end, + + sleep = function(params, faden) + if #params ~= 1 then + return false, WNOA + end + local p = params[1] + if type(p) ~= "number" then + return false, UAT + end + faden.rebirth = minetest.get_gametime() + p + faden:stop() + return true + end, + + flush = function(params, faden) + return faden:flush(params) + end, +} +return s diff --git a/textures/pdisc.png b/textures/pdisc.png new file mode 100644 index 0000000..f146ebd Binary files /dev/null and b/textures/pdisc.png differ