From 05cc1669256e5bda7908cb25bd273a328effe386 Mon Sep 17 00:00:00 2001 From: Ryan Ward Date: Tue, 25 Jun 2019 23:13:19 -0400 Subject: [PATCH] The function rework is done! Finally, this took way too long to get working. Major change to how one interacts with the interperter. No need to implicetly catch each case, defaults are set and can be overridden if needed. --- parseManager/init.lua | 21 ++- .../{extendedDefine.lua => threading.lua} | 42 +---- test.dms | 34 +--- test.lua | 11 +- test2.lua | 167 +++++++++++------- 5 files changed, 140 insertions(+), 135 deletions(-) rename parseManager/{extendedDefine.lua => threading.lua} (53%) diff --git a/parseManager/init.lua b/parseManager/init.lua index 80a7f58..0c5f66f 100644 --- a/parseManager/init.lua +++ b/parseManager/init.lua @@ -1,7 +1,7 @@ local noprint require("bin") parseManager={} -parseManager.VERSION = 5 +parseManager.VERSION = 6 parseManager.__index=parseManager parseManager.chunks={} parseManager.stats={warnings = true} @@ -1318,7 +1318,6 @@ function parseManager:next(block,choice) else rets={Func(self,unpack(args))} end - table.print(rets) if #rets~=0 then self:pairAssign(data.vars,rets) end @@ -1334,6 +1333,9 @@ function parseManager:next(block,choice) else Func=self.methods[data.Func] end + if Func == nil then + self:pushError("Attempt to call a non existing function!",data.Func) + end if Ext then self.lastCall=Func(unpack(args)) else @@ -1378,7 +1380,6 @@ function parseManager:next(block,choice) if IRET=="KILL" then return false end - self:next() return true end parseManager.__TEXT = function(text) @@ -1413,27 +1414,25 @@ parseManager.__CS = function() -- end parseManager.__RETURN = function() - + -- end function parseManager:Call(func,...) local env = {} - local temp = parseManager:load(self.path,nil,true) + local temp + temp = parseManager:load(self.path,nil,true) temp.fArgs = {...} - parseManager.__RETURN = function(vars,retargs) + temp.__RETURN = function(vars,retargs) env = temp:dataToEnv(retargs) return "KILL" end temp.entry = func - active = true + local active = true while active do active = temp:think() end return unpack(env) end function parseManager:think() - self:next() - function parseManager:think() - -- Finish this - end + return self:next() end require("parseManager.standardDefine") diff --git a/parseManager/extendedDefine.lua b/parseManager/threading.lua similarity index 53% rename from parseManager/extendedDefine.lua rename to parseManager/threading.lua index 64918f8..c2c341a 100644 --- a/parseManager/extendedDefine.lua +++ b/parseManager/threading.lua @@ -1,4 +1,4 @@ -if parseManager.extendedDefineLoaded then return false end +if parseManager.threadingLoaded then return false end local multi, bin, GLOBAL,sThread local loaded, err = pcall(function() multi = require("multi") @@ -10,9 +10,9 @@ local loaded, err = pcall(function() end bin = require("bin") end) -function parseManager:extendedDefine() - parseManager.extendedDefineLoaded = true - if not loaded then self:pushWarning("Could not load the extendedDefine module!") print(err) end +function parseManager:threading() + parseManager.threadingLoaded = true + if not loaded then self:pushWarning("Could not load the threading module!") print(err) end local tc = 1 self.mainENV=GLOBAL self.currentENV=GLOBAL @@ -31,6 +31,7 @@ function parseManager:extendedDefine() sThread=_G.sThread end local test=parseManager:load(path) + test.entry = blck test.mainENV = GLOBAL test.currentENV = GLOBAL test:define{ @@ -41,35 +42,10 @@ function parseManager:extendedDefine() os.execute("title "..t) end } - t=test:next(blck) - multi:newThread(name,function() - while true do - thread.skip(0) - if not t then error("Thread ended!") end - if t.Type=="text" then - log(t.text,name) - t=test:next() - elseif t.Type=="condition" then - t=test:next() - elseif t.Type=="assignment" then - t=test:next() - elseif t.Type=="label" then - t=test:next() - elseif t.Type=="method" then - t=test:next() - elseif t.Type=="choice" then - t=test:next(nil,math.random(1,#t.choices),nil,t) - elseif t.Type=="end" then - if t.text=="leaking" then -- go directly to the block right under the current block if it exists - t=test:next() - else - os.exit() - end - elseif t.Type=="error" then - error(t.text) - else - t=test:next() - end + local active = true + multi:newThread("Thread",function() + while active do + test:think() end end) multi:mainloop() diff --git a/test.dms b/test.dms index 5c6df8c..1eed31f 100644 --- a/test.dms +++ b/test.dms @@ -1,29 +1,9 @@ -ENTRY INIT2 +ENTRY INIT LOADFILE Story/bedroom.dms -// USING extendedDefine +USING threading DISABLE warnings USING audio as audio // DISABLE hostmsg -[INIT2]{ - "Text block" - "Testing default text handler" - g=DoMe(2) - print("WHAT!!! $g$") -} -[A]{ - "Yay it works!" -} -[DoMe:function(a)]{ - "handle me" - if a==0 then SKIP(0)|GOTO("end") - return 1 - ::end:: - return a*SecondCall(a-1) -} -[SecondCall:function()]{ - return 6 -} -/* [INIT]{ // The LOAD function will load variables and jump to the saved location. Be sure to setup runtime variables before the LOAD function is called! WATCH("money","name","day","chapter","passive") @@ -44,11 +24,9 @@ USING audio as audio JUMP("START") } [UPDATER]{ - maintheme=audio:new("Audio/Nadia.ogg") - maintheme:play(.5) ::loop:: EXECUTE("title $name$ $$money$ Day: $day$ Chap: $chapter$") - sleep(.1) + sleep(1) money = money + passive GOTO("loop") } @@ -63,11 +41,13 @@ USING audio as audio // > } [START]{ + maintheme=audio.new("Audio/Nadia.ogg") + maintheme:play(.5) "HI!" maintheme:setVolume(1) sleep(1) - Fade(maintheme) + // Fade(maintheme) "Yo" // JUMP("BEDROOM") } -*/ + diff --git a/test.lua b/test.lua index 1ec4b54..96cc993 100644 --- a/test.lua +++ b/test.lua @@ -6,18 +6,19 @@ require("parseManager") require("multi") test=parseManager:load("test.dms")--parseManager:compileToFile("test.dms","test.dmsc")-- test:define{ - external = function() + external = function(self) return multi + end, + tester = function() + print("!") end } parseManager.print(test:dump()) --~ test = parseManager:loadCompiled("test.dmsc") ---~ print(test.methods.DoMe(1)) +--~ print(test.methods.DoMe(2)) --~ print(test.methods.DoMe(1,2)) -test.__TEXT = function(text) - print(text) -end local active = true while active do active = test:think() end +--~ multi:mainloop() diff --git a/test2.lua b/test2.lua index 18a62b8..a350aae 100644 --- a/test2.lua +++ b/test2.lua @@ -11,71 +11,120 @@ function table.print(tbl, indent) end end end +local stack = { + __tostring = function(self) + return table.concat(self,", ") + end +} +stack.__index=stack +function stack:new(n) + local c = {} + setmetatable(c,stack) + c.limit = n + return c +end +function stack:push(dat) + if self.limit then return "StackOverflow!" end + table.insert(self,dat) +end +function stack:peek() + return self[#self] +end +function stack:pop() + return table.remove(self) +end local special = {["("]=true,[")"]=true,["+"]=true,["-"]=true,["/"]=true,["*"]=true,["%"]=true,["^"]=true} -function parse(e) - local cmds = {} - local state = 0 +function parseA(expr) + local data = {} local group = "" - local nonSP = false - local wasNum = false - for i in e:gmatch(".") do - if state == 0 then - if i==" " then - -- - elseif i=="(" and nonSP then ---~ state = 1 - nonSP = false - cmds[#cmds+1] = {Type="fwor",Func=group,args={{Type="ref",ref=true}}} - group = "" - cmds[#cmds+1]=i - elseif i == "(" and wasNum and not nonSP then - wasNum = false - cmds[#cmds+1] = {Type="fwor",Func="MUL",args={{Type="const",val=group},{Type="ref",ref=true}}} - group = "" - cmds[#cmds+1]=i - elseif tostring(tonumber(i))==i or i=="." then - wasNum = true - group = group .. i - elseif special[i] then - if not(group=="") and (nonSP or not wasNum) then - cmds[#cmds+1] = {Type="var",data = group} - group = "" - cmds[#cmds+1]=i - else - if group~="" then - cmds[#cmds+1] = group - group = "" - cmds[#cmds+1]=i - nonSP = false - else - cmds[#cmds+1]=i - nonSP = false - end - end - else - nonSP = true - group = group .. i - end - elseif state == 1 then - if i==")" then - cmds[#cmds+1]=parse(group) - group = "" - state = 0 - else - group = group .. i + for i in expr:gmatch(".") do + if special[i] then + if group~="" then + data[#data+1]=group end + data[#data+1]=i + group = "" + elseif i~=" " then + group = group .. i end end - if nonSP or not wasNum then - cmds[#cmds+1] = {Tpye="const",data = group} - else - cmds[#cmds+1] = group + return data +end +function parseB(dat) + local isNum = false + local isFunc = false + local isVar = false + local cmds = {} + local ref + local open = 0 + for i,v in ipairs(dat) do + if #v>1 and tostring(tonumber(v))~=v and dat[i+1] and dat[i+1]=="(" then + table.insert(cmds,{"Function",v}) + elseif tostring(tonumber(v))==v then + table.insert(cmds,{"Number",v}) + elseif #v>1 and tostring(tonumber(v))~=v then + table.insert(cmds,{"Variable",v}) + else + table.insert(cmds,v) + end end - if cmds[1]=="" then table.remove(cmds,1) end - if cmds[#cmds]=="" then table.remove(cmds) end return cmds end +function parseC(dat) + local a = {} + local ref + local pos = 0 + local open = 0 + local group = {} + for i,v in ipairs(dat) do + if v=="(" then + open = open + 1 + if not ref then + ref = {} + end + elseif v==")" then + open = open - 1 + if open == 0 then + table.insert(group,ref) + ref = nil + elseif open < 0 then + error("Unbalanced ()") + end + elseif ref == nil then + table.insert(group,v) + else + table.insert(ref,v) + end + end + return group +end +function parse(e) + local tokens = parseA(e) + local cmds = parseB(tokens) + local c = parseC(cmds) + table.print(c) +end ------------------ -expr = "test(2.4+20)/sqrt(100) + food" -c=parse(expr) -table.print(c) +expr = "test(2.4+(18+(20-4)))/(sqrt(100) + food) + 5(10 + 4)" +function prepare(expr) + local cmds = {} + local cc = 64 + function clean(expr) + expr = expr:gsub("(%b())",function(a) + local dat = a:sub(2,-2) + if not(dat:find("%(") or dat:find("%)")) then + cc=cc+1 + cmds["$"..string.char(cc)]=dat + return "$"..string.char(cc) + else + return clean(dat) + end + end) + return expr + end + local expr = clean(expr) + print(expr) + table.print(cmds) +end +prepare(expr) +--~ c=parse(expr)