diff --git a/DMS.xml b/DMS.xml index 0cad60e..82db8c6 100644 --- a/DMS.xml +++ b/DMS.xml @@ -24,26 +24,26 @@ /* */ - ENABLE DISABLE LOAD ENTRY VERSION - if then return and or + ENABLE DISABLE LOAD ENTRY USING VERSION as + if then return and or True False leaking debugging warnings - ceil tan CSIM log10 sinh GOTOE lshift deg MUL QUIT cosh exp rad GOTO SUB log ADD JUMP error POW randomseed floor tanh max atan SKIP acos DIV abs rshif COMPARE print atan2 asin cos sin mod sqrt function random getInput - + ceil tan CSIM log10 sinh GOTOE lshift deg MUL QUIT cosh exp rad GOTO SUB log ADD JUMP error POW randomseed floor tanh max atan SKIP acos DIV abs rshif COMPARE print atan2 asin cos sin mod sqrt function getInput sleep getVar setVar + _VERSION 00:: 01 02:: 03$ 04 05$ 06" 07 08" 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - - - + + + - + diff --git a/WeCanWriteEm.txt b/WeCanWriteEm.txt new file mode 100644 index 0000000..32f95c0 --- /dev/null +++ b/WeCanWriteEm.txt @@ -0,0 +1 @@ +hi \ No newline at end of file diff --git a/parseManager/extendedDefine.lua b/parseManager/extendedDefine.lua index 15953cd..be4a456 100644 --- a/parseManager/extendedDefine.lua +++ b/parseManager/extendedDefine.lua @@ -1,10 +1,84 @@ +local multi,bin,GLOBAL,sThread +local loaded, err = pcall(function() + multi = require("multi") + local plat = multi:getPlatform() + if plat == "lanes" then + GLOBAL, sThread = require("multi.integration.lanesManager").init() + elseif plat == "love2d" then + GLOBAL, sThread = require("multi.integration.loveManager").init() + end + GLOBAL["TEST"]=true + bin = require("bin") +end) function parseManager:extendedDefine() + if not loaded then self:pushWarning("Could not load the extendedDefine module!") print(err) end + local tc = 1 self:define{ - newThread = function() - -- We allow for thread creation + setVar = function(self,name,val) + GLOBAL[name]=val end, - testfunc = function() - print("It worked") + getVar = function(self,name) + return sThread.waitFor(name) + end, + newThread = function(self,block,name) + multi:newSystemThread(name or "NewThread"..tc,function(blck,path,name) + local bin = require("bin") + local multi = require("multi") + require("parseManager") + if multi:getPlatform()=="love2d" then + GLOBAL=_G.GLOBAL + sThread=_G.sThread + end + local test=parseManager:load(path) + t=test:next(blck) + test:define{ + sleep = function(self,n) + thread.sleep(n) + end, + setVar = function(self,name,val) + GLOBAL[name]=val + end, + getVar = function(self,name) + return sThread.waitFor(name) + end, + test = function(self,text) + os.execute("title "..text.."") + end + } + multi:newThread("Runner",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 + end + end) + multi:mainloop() + end,block,self.currentChunk.path,name or "NewThread"..tc) + tc=tc+1 + end, } end diff --git a/parseManager/filesystem.lua b/parseManager/filesystem.lua new file mode 100644 index 0000000..3a7b4b1 --- /dev/null +++ b/parseManager/filesystem.lua @@ -0,0 +1,3 @@ +function parseManager:filesystem() + return bin +end diff --git a/parseManager/init.lua b/parseManager/init.lua index c8c1504..1fd63fc 100644 --- a/parseManager/init.lua +++ b/parseManager/init.lua @@ -1,12 +1,12 @@ require("bin") parseManager={} -parseManager.VERSION = 3.4 +parseManager.VERSION = 4 parseManager.__index=parseManager parseManager.chunks={} -parseManager.stats={} +parseManager.stats={warnings = true} parseManager.stack={} parseManager.cFuncs={} -parseManager.mainENV={} +parseManager.mainENV={_VERSION = parseManager.VERSION} parseManager.__INTERNAL = {} parseManager.currentENV=parseManager.mainENV parseManager.entry="START" @@ -28,6 +28,9 @@ function parseManager:debug(...) print("",...) end end +function parseManager:defualtRunner(func) + -- +end function parseManager:newENV() local env={} function env:getParent() @@ -52,6 +55,23 @@ function factorial(n) return n * factorial(n - 1) end end +function parseManager:ENABLE(fn) + self.stats[string.lower(fn)]=true +end +function parseManager:DISABLE(fn) + self.stats[string.lower(fn)]=false +end +function parseManager:USING(fn,name) + local m = require("parseManager."..fn) + if not m then + self:pushError(fn.." was not found as an import that can be used!") + else + local ret = self[fn](self) + if ret then + self.mainENV[name or fn]=ret + end + end +end function parseManager:load(path,c) local c = c if not c then @@ -88,32 +108,33 @@ function parseManager:load(path,c) file.data=file.data:gsub("\2","//") file.data=file.data:gsub("\t","") file:trim() - for fn in file:gmatch("ENABLE (.-)\n") do + local header = file:match("(.-)%[") + for fn in header:gmatch("ENABLE (.-)\n") do self:debug("E",fn) - c.stats[string.lower(fn)]=true + c:ENABLE(fn) end - for fn in file:gmatch("LOAD (.-)\n") do + for fn in header:gmatch("LOAD (.-)\n") do self:debug("L",fn) c:load(fn,c) end - for fn in file:gmatch("DISABLE (.-)\n") do + for fn in header:gmatch("DISABLE (.-)\n") do self:debug("D",fn) - c.stats[string.lower(fn)]=false + c:DISABLE(fn) end - for fn in file:gmatch("ENTRY (.-)\n") do + for fn in header:gmatch("ENTRY (.-)\n") do self:debug("E",fn) c.entry=fn end - for fn in file:gmatch("USING (.-)\n") do + for fn in header:gmatch("USING (.-)\n") do self:debug("U",fn) - local m = require("parseManager."..fn) - if not m then - self:pushError(fn.." was not found as an import that can be used!") + if fn:find("as") then + local use,name = fn:match("(.-) as (.+)") + c:USING(use,name) else - c[fn](c) + c:USING(fn) end end - for fn in file:gmatch("VERSION (.-)\n") do + for fn in header:gmatch("VERSION (.-)\n") do self:debug("V",fn) local num = tonumber(fn) local int = tonumber(c.VERSION) @@ -121,7 +142,7 @@ function parseManager:load(path,c) c:pushWarning("VERSION: "..fn.." is not valid! Assuming "..c.VERSION) else if num>int then - c:pushWarning("This script was written for a version that is greater than what this interperter was built for!") + c:pushWarning("This script was written for a later version! Some features may not work properly!") end end end @@ -266,6 +287,8 @@ function parseManager:dump() str=str.."\tDISP_MSG \""..v[k].text.."\"\n" elseif v[k].Type=="assign" then str=str.."\t"..concat(v[k].vars,", ").." <- "..concat(v[k].vals,", ").."\n" + elseif v[k].Type=="toggle" then + str = str.."\t"..v[k].Flags.." "..v[k].Target.."\n" else str=str.."\tUnknown Code!: "..tostring(v[k].data).."\n" end @@ -286,13 +309,14 @@ function table.print(tbl, indent) end end function parseManager:pushError(err,sym) + if not self.currentChunk then print("ERROR: ",err,sym) os.exit() end local lines = bin.load(self.currentChunk.path):lines() local chunk = self.currentChunk[self.currentChunk.pos-1] -- table.print(chunk) for i=1,#lines do if sym then if lines[i]:find(sym) then - print(err.." At line: "..i.." "..(lines[i]:gsub("^\t+","")).." ("..tostring(sym)..")") + print(err.." <"..sym.."> At line: "..i.." "..(lines[i]:gsub("^\t+",""))) break end elseif chunk.Type=="fwor" or chunk.Type=="fwr" then @@ -301,10 +325,10 @@ function parseManager:pushError(err,sym) break end else - + print(err.." Line: ?") + break end end - io.read() os.exit() end function parseManager:pushWarning(warn) @@ -318,6 +342,7 @@ local function pieceList(list,self,name) local list=parseManager.split(list) local L={} local mathass=1 + local cc = 0 for i=1,#list do if list[i]:match("[%w_]-%[.-%]") and list[i]:sub(1,1)~='"' then local dict,sym=list[i]:match("([%w_]-)%[(.-)%]") @@ -325,6 +350,11 @@ local function pieceList(list,self,name) L[#L+1]={"\1"..dict,tonumber(sym),IsALookup=true} elseif sym:sub(1,1)=="\"" and sym:sub(-1,-1)=="\"" then L[#L+1]={"\1"..dict,sym:sub(2,-2),IsALookup=true} + else + local sym = "`"..string.char(65+cc) + self:compileFWR("__PUSHPARSE",sym,'"$'..list[i]..'$"',name) + cc=cc+1 + L[#L+1]="\1"..sym end elseif list[i]:sub(1,1)=="\"" and list[i]:sub(-1,-1)=="\"" then L[#L+1]=list[i]:sub(2,-2) @@ -360,18 +390,18 @@ local function pieceAssign(a,self,name) var={dict,ind:sub(2,-2)} elseif tonumber(ind) then var={dict,tonumber(ind)} - elseif ind:match("[%w_]+")==ind then + elseif ind:match("[%w_`]+")==ind then var={dict,"\1"..ind} - elseif ind:match("[_%w%+%-/%*%^%(%)%%]+") then + elseif ind:match("[_%w%+%-`/%*%^%(%)%%]+") then local sym="@A" self:compileExpr(sym,ind,name) var={dict,"\1"..sym} else self:pushError("Invalid way to index a dictonary/array!",ind) end - elseif a:match("[%$%w_]+")==a then + elseif a:match("[%$%w_`]+")==a then var="\1"..a - elseif a:match("[%$%w_]-%..-") then + elseif a:match("[%$%w_`]-%..-") then local dict,sym=a:match("([%w_]-)%.(.+)") var={dict,sym,IsALookup=true} elseif a:find(",") then @@ -412,6 +442,10 @@ function parseManager:compileAssign(assignA,assignB,name) self:debug("NAME: "..listA[k]) if tonumber(listB[k]) then assign.vals[#assign.vals+1]=tonumber(listB[k]) + elseif listB[k]:match("%w-%.%w+")==listB[k] then + local dict,sym=listB[k]:match("(%w-)%.(%w+)") + print(dict,sym) + assign.vals[#assign.vals+1]={"\1"..dict,sym,IsALookup=true} elseif listB[k]:sub(1,1)=="[" and listB[k]:sub(-1,-1)=="]" then if listB[k]:match("%[%]") then assign.vals[#assign.vals+1]={} @@ -439,7 +473,7 @@ function parseManager:compileAssign(assignA,assignB,name) assign.vals[#assign.vals+1]=false elseif listB[k]:match("[%w_]+")==listB[k] then assign.vals[#assign.vals+1]="\1"..listB[k] - elseif listB[k]:match("[_%$%w%+%-/%*%^%(%)%.%%%s]+")==listB[k] then + elseif listB[k]:match("[_%$%w%+%-/%*%^%(%)%.%%%s]+")==listB[k] and not(listB[k]:match("%w-%.%w+")==listB[k]) then mathTest=true workit = self:compileFuncInExpr(listB[k],name) self:compileExpr(listA[k],workit,name) @@ -794,39 +828,64 @@ function parseManager:compile(name,ctype,data) if not args2 then FWOR2,args2=data[i]:match("^([%.:%w_]+)%s*%((.*)%)$") end + local flags,target = data[i]:match("(%u+)%s([%w%s]+)") ------ if line then + -- print(1) self:compileLine(line,name) elseif condition then + -- print(2) self:compileCondition(condition,iff,elsee,name) elseif FWR then + -- print(3) self:compileFWR(FWR,vars,args,name) elseif FWOR then + -- print(4) self:compileFWOR(FWOR,args,name) elseif FWR2 then + -- print(5) local dict,dot,sym=FWR2:match("([%w_]-)([%.:])(.+)") if dot==":" then args2=dict..","..args2 + if args2:sub(-1,-1)=="," then + args2 = args2:sub(1,-2) + end end self:compileFWR({dict,sym,IsALookup=true},vars2,args2,name) elseif FWOR2 then + -- print(6) local dict,dot,sym=FWOR2:match("([%w_]-)([%.:])(.+)") if dot==":" then args2=dict..","..args2 + if args2:sub(-1,-1)=="," then + args2 = args2:sub(1,-2) + end end self:compileFWOR({dict,sym,IsALookup=true},args2,name) elseif assignA then + -- print(7) self:compileAssign(assignA,assignB,name) elseif label then + -- print(8) self:compileLabel(label,name) elseif Return and isFBlock then + -- print(9) table.insert(self.chunks[name],{ Type="return", RETArgs=pieceList(RETArgs,self,name) }) elseif Return and not(isFBlock) then + -- print(10) self:pushError("Attempt to call return in a non function block!",data[i]) + elseif flags and target then + -- print(11) + table.insert(self.chunks[name],{ + Type = "toggle", + Flags = flags, + Target = target + }) else + -- print(12) table.insert(self.chunks[name],{ Type="customdata", data=data[i], @@ -1149,6 +1208,8 @@ function parseManager:next(block,choice) local args=self:dataToValue(data.args) local Func local Ext=false + -- table.print(data.args) + table.print(args) if type(data.Func)=="table" then Ext=true Func=self.currentENV[data.Func[1]][data.Func[2]] @@ -1178,6 +1239,23 @@ function parseManager:next(block,choice) self:pairAssign(data.vars,data.vals) self.lastCall=nil return {Type="assign"} + elseif data.Type=="toggle" then + local flags,target = data.Flags,data.Target + if flags == "USING" then + if target:find("as") then + local use,name = target:match("(.-) as (.+)") + self:USING(use,name) + else + self:USING(target) + end + elseif flags == "ENABLE" then + self:ENABLE(target) + elseif flags == "DISABLE" then + self:DISABLE(target) + else + self:pushWarning("Invalid flag: "..flag.."!") + end + return {Type="method"} -- you cannot interact with the interpreter yet! else self.lastCall=nil return {Type="Custom Syntax"} diff --git a/parseManager/standardDefine.lua b/parseManager/standardDefine.lua index fe97a9d..275a0f3 100644 --- a/parseManager/standardDefine.lua +++ b/parseManager/standardDefine.lua @@ -1,3 +1,4 @@ +local clock = os.clock parseManager:define{ __PUSHPARSE = function(self,dat) return dat @@ -17,6 +18,10 @@ parseManager:define{ QUIT=function() os.exit() end, + sleep=function(self,n) + local t0 = clock() + while clock() - t0 <= n do end + end, JUMP=function(self,block) if self.chunks[block] then self.chunks[block].pos=1 diff --git a/test.lua b/test.lua index 92aced6..5189b80 100644 --- a/test.lua +++ b/test.lua @@ -15,7 +15,7 @@ require("bit") --~ end --~ }) test=parseManager:load("textadventure.dms") ---~ print(test:dump()) +print(test:dump()) t=test:next() while true do if not t then break end @@ -51,3 +51,6 @@ while true do t=test:next() end end +--["vars"]={"\1%"..string.char(mathAss+64)} +--cmds[#cmds+1]={Func="MOD",args={l,(r or "")}} +-- diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..0031a8e --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +Hello testing file reading \ No newline at end of file diff --git a/test2.lua b/test2.lua index a1a652e..b53d8db 100644 --- a/test2.lua +++ b/test2.lua @@ -1,8 +1,13 @@ -io.flush() -i = io.input() -i:seek("cur") -i:read(2) -print(i) +local GLOBAL, sThread = require("multi.integration.lanesManager").init() +GLOBAL["Test"]=true +multi:newSystemThread("NewThread",function(blck,path,name) + print(GLOBAL["Test"]) +end) +--~ io.flush() +--~ i = io.input() +--~ i:seek("cur") +--~ i:read(2) +--~ print(i) --~ g={} --~ while t~="q" do --~ g[#g+1]=t diff --git a/textadventure.dms b/textadventure.dms index 13e3977..aca12cb 100644 --- a/textadventure.dms +++ b/textadventure.dms @@ -1,14 +1,30 @@ ENTRY MAIN -VERSION 3.4 -USING extendedDefine -ENABLE warnings -// ENABLE debugging [MAIN]{ - ::name:: - name = getInput("Enter your name: ") - if name=="" then GOTO("name")|SKIP(0) - ::good:: - print("Player Name: $name$") - choice = getInput("Is this name correct? (y/n): ") - if choice=="y" then SKIP(0)|GOTO("name") -} \ No newline at end of file + //Check for version compatibility + if _VERSION>=3.4 then GOTO("define")|GOTO("nodefine") + ::nodefine:: + print("We cannot use the filesystem or the extendedDefine module! Exiting program!") + QUIT() + ::define:: + // USING filesystem as bin + // USING extendedDefine + // setVar("name","Thread Test") + // newThread("LoopTest") + // in = getInput("Enter Something: ") + // file = bin.new(in) + // file:tofile("WeCanWriteEm.txt") + "Let's test simple object creation" + obj = [] + obj.test = say + obj.test("Hello!") + "Hmm..." +} +// [LoopTest]{ + // a=0 + // name = getVar("name") + // ::loop:: + // a=a+1 + // test("$name$ $a$") + // sleep(1) + // GOTO("loop") +// } \ No newline at end of file