diff --git a/DMS.xml b/DMS.xml
index 28419f3..651e031 100644
--- a/DMS.xml
+++ b/DMS.xml
@@ -25,9 +25,9 @@
*/
ENABLE DISABLE LOAD ENTRY USING VERSION as
- if then return and or True False
+ if then return and or True False for while
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 getInput sleep getVar setVar newThread
+ 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 newThread setGlobalVar getGlobalVar
_VERSION
filesystem extendedDefine
diff --git a/parseManager/init.lua b/parseManager/init.lua
index b011fd3..967aa2d 100644
--- a/parseManager/init.lua
+++ b/parseManager/init.lua
@@ -1,6 +1,6 @@
require("bin")
parseManager={}
-parseManager.VERSION = 4.1
+parseManager.VERSION = 5
parseManager.__index=parseManager
parseManager.chunks={}
parseManager.stats={warnings = true}
@@ -58,7 +58,6 @@ function parseManager:run(block)
while dat do
dat = self:mainRunner()
end
- -- print("done")
end
function readonlytable(tab)
return setmetatable({},{
@@ -204,12 +203,22 @@ function parseManager:load(path,c)
parseManager.currentHandleName=name
parseManager.currentHandle=c
c:compile(name,ctype,data)
+ c.runtime = true
end
--c.chunks=readonlytable(c.chunks)
c.mainENV["False"]=false
c.mainENV["True"]=true
return c
end
+function push(s,n)
+ table.insert(s,n)
+end
+function pop(s)
+ return table.remove(s)
+end
+function peek(s)
+ return s[#s]
+end
function parseManager:extractState()
return {name=self.currentChunk.name,pos = self.currentChunk.pos,variables = self.mainENV,cc = self.currentENV}
end
@@ -367,23 +376,26 @@ 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 run = "Compile Time Error! "
+ if self.runtime then
+ run = "Run Time Error! "
+ end
+ if not self.currentChunk then print("ERROR compiling: ",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.." <"..sym.."> At line: "..i.." "..(lines[i]:gsub("^\t+","")))
+ print(run..err.." <"..sym.."> At line: "..i.." "..(lines[i]:gsub("^\t+","")))
break
end
elseif chunk.Type=="fwor" or chunk.Type=="fwr" then
if lines[i]:match(chunk.Func.."%(") then
- print(err.." At line: "..i.." "..(lines[i]:gsub("^\t+","")).." ("..tostring(sym)..")")
+ print(run..err.." At line: "..i.." "..(lines[i]:gsub("^\t+","")).." ("..tostring(sym)..")")
break
end
else
- print(err.." Line: ?")
+ print(run..err.." Line: ?")
break
end
end
@@ -401,7 +413,6 @@ local function pieceList(list,self,name)
local L={}
for i=1,#list do
if list[i]:match("[%w_]-%[.-%]") and list[i]:sub(1,1)~='"' then
- -- print("dict")
local dict,sym=list[i]:match("([%w_]-)%[(.-)%]")
if tonumber(sym) then
L[#L+1]={"\1"..dict,tonumber(sym),IsALookup=true}
@@ -414,35 +425,26 @@ local function pieceList(list,self,name)
L[#L+1]="\1"..sym
end
elseif list[i]:sub(1,1)=="\"" and list[i]:sub(-1,-1)=="\"" then
- -- print("string")
L[#L+1]=list[i]:sub(2,-2)
elseif list[i]:sub(1,1)=="[" and list[i]:sub(-1,-1)=="]" then
- -- print("index")
L[#L+1]=pieceList(list[i]:sub(2,-2),self,name)
elseif tonumber(list[i]) then
- -- print("number")
L[#L+1]=tonumber(list[i])
elseif list[i]=="true" then
- -- print("true")
L[#L+1]=true
elseif list[i]=="false" then
- -- print("false")
L[#L+1]=false
elseif list[i]:match("[%w_]+")==list[i] then
- -- print("var?")
L[#L+1]="\1"..list[i]
elseif list[i]:match("[%w_]-%..-") then
- -- print("dict?")
local dict,sym=list[i]:match("([%w_]-)%.(.+)")
L[#L+1]={"\1"..dict,sym,IsALookup=true}
elseif list[i]:match("^([%w_]+)%s*%((.*)%)$") then
- -- print("func")
local func,args = list[i]:match("^([%w_]+)%s*%((.*)%)$")
local sym = getSymbol("`")
self:compileFWR(func,sym,args,name)
L[#L+1]="\1"..sym
elseif list[i]:match("[_%w%+%-/%*%^%(%)%%]+") and list[i]:match("[%+%-/%*%^%%]+") then
- -- print("math")
local char=getSymbol("$")
self:compileExpr(char,list[i],name)
L[#L+1]="\1"..char
@@ -528,6 +530,8 @@ function parseManager:compileAssign(assignA,assignB,name)
assign.vals[#assign.vals+1]={"\1"..dict,tonumber(sym),IsALookup=true}
elseif sym:sub(1,1)=="\"" and sym:sub(-1,-1)=="\"" then
assign.vals[#assign.vals+1]={"\1"..dict,sym:sub(2,-2),IsALookup=true}
+ else
+ assign.vals[#assign.vals+1]={"\1"..dict,"\1"..sym,IsALookup=true}
end
elseif listB[k]:match("[%w_]-%..-") and not listB[k]:match("(%d-)%.(%d-)") then
local dict,sym=listB[k]:match("([%w_]-)%.(.+)")
@@ -553,7 +557,9 @@ function parseManager:compileAssign(assignA,assignB,name)
self:debug(assignA,assignB,name)
end
end
- table.insert(self.chunks[name],assign)
+ if #assign.vars~=0 then
+ table.insert(self.chunks[name],assign)
+ end
end
function parseManager:compileCondition(condition,iff,elsee,name)
self:compileLogic(condition,iff,elsee,name)
@@ -655,9 +661,8 @@ function parseManager:compileExpr(eql,expr,name)
packFunc("\3"..i,self:pieceExpr(a))
return "@"
end)
- end--self.cFuncs
+ end
expr=expr:gsub("%b()",function(a)
- -- print(">",a)
return self:pieceExpr(a:sub(2,-2))
end)
local loop
@@ -676,7 +681,6 @@ function parseManager:compileExpr(eql,expr,name)
end
end
if expr:match("[!%$%s&_%w%+%-,/%*%.%^%(%)%%]+")==expr then
- -- print(expr)
expr = expr:gsub("%s","")
parseManager:pieceExpr(expr)
cmds[#cmds]["vars"]={"\1"..eql}
@@ -739,7 +743,7 @@ function parseManager:compileLogic(condition,iff,elsee,name)
local mathass=0
_conds=conds:gsub("%s*\5".."1==0","")
local cmds={}
- for l,eq,r in conds:gmatch("(.-)([=~!><][=]*)(.-)%s*[\4\5]") do
+ for l,eq,r in conds:gmatch("(.-)%s*([=~!><][=]*)(.-)%s*[\4\5]") do
charL=string.char(count+65)
charM=string.char(mathass+65)
count=count+1
@@ -793,6 +797,9 @@ function parseManager:compileLogic(condition,iff,elsee,name)
_conds=_conds:gsub("\4","*")
_conds=_conds:gsub("\5","+")
if not _conds:find("%*") and not _conds:find("%+") then
+ if not cmds.vars then
+ self:pushError("Invalid condition passed!",condition)
+ end
cmds.vars[1]="\1L$"
else
self:compileExpr("L$",_conds,name)
@@ -841,21 +848,55 @@ function parseManager:compile(name,ctype,data)
self:debug("COMPILING Block: "..name)
local data=bin.new(data):lines()
local choiceBlock=false
+ local stack = {}
+ local choiceBlockLOOP=false
local choice={}
for i=1,#data do
data[i]=trim1(data[i])
if data[i]~="" then
- if data[i]:match(".-\"<%s*") then
+ if data[i]:match("for[%s%w=%-]-[%d%-,%s]-<") then
+ choiceBlockFor=true
+ local sym = getSymbol("FOR")
+ local var,a,b,c = data[i]:match("for%s*([%w_]+)%s*=%s*(%-*[%d]+),%s*(%-*[%d]+)%s*,*%s*(%-*[%d]*)")
+ local s = getSymbol(getSymbol("LOOPEND"))
+ push(stack,{sym,var,a,b,s,1,c}) -- 1 for loop, 2 while loop
+ data[i] = "::"..sym.."::"
+ self:compileAssign(var,a,name)
+ elseif data[i]:match("while ([_%w=><~!%-%s]+)<$") then
+ -- WHILE LOOP
+ local sym = getSymbol("WHILE")
+ local s = getSymbol(getSymbol("LOOPEND"))
+ self:compileLabel(sym,name)
+ local cond = data[i]:match("while ([_%w=><~!%-%s]-)%s*<$")
+ data[i]="if "..cond.." then SKIP(0)|GOTO(\""..s.."\")"
+ push(stack,{sym,0,0,0,s,2}) -- 1 for loop, 2 while loop
+ elseif data[i]:match(".-\"%s*<%s*") then
choiceBlock=true
choice={}
j=0
end
+ if (choiceBlockLOOP or #stack~=0) and not choiceBlock then
+ if data[i]==">" then
+ choiceBlockLOOP=false
+ local dat = pop(stack)
+ local s = dat[5]
+ local cmd = dat[6]
+ if cmd==1 then
+ self:compileAssign(dat[2],dat[2] .. (tonumber(dat[7]) or "+1"),name)
+ self:compileCondition(dat[2].."=="..tonumber(dat[4])+(tonumber(dat[7]) or 1),"GOTO(\""..s.."\")","GOTO(\""..dat[1].."\")",name)
+ data[i] = "::"..s.."::"
+ elseif cmd == 2 then
+ self:compileFWOR("GOTO","\""..dat[1].."\"",name)
+ data[i]="::"..s.."::"
+ end
+ end
+ end
if choiceBlock then
- if data[i]:find(">") then
+ if data[i]==">" then
choiceBlock=false
table.insert(self.chunks[name],choice)
else
- dat=data[i]:gsub("<","")
+ dat=data[i]:gsub("%s*<","")
if j==0 then
choice.Type="choice"
choice.prompt=dat:sub(2,-2)
@@ -863,12 +904,12 @@ function parseManager:compile(name,ctype,data)
else
local a,b=dat:match("\"(.-)\"%s*(.+)")
if b then
- local f,ag=b:match("^([%w_]+)%s*%((.*)%)")
+ local f,ag=b:match("^([%w_]+)%s*(%b())")
if ag~="" then
choice[#choice+1]={a,{
Type="fwor",
Func=f,
- args=pieceList(ag,self,name),
+ args=pieceList(ag:sub(2,-2),self,name),
}}
else
choice[#choice+1]={a,{
@@ -900,19 +941,14 @@ function parseManager:compile(name,ctype,data)
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
@@ -922,7 +958,6 @@ function parseManager:compile(name,ctype,data)
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
@@ -932,29 +967,23 @@ function parseManager:compile(name,ctype,data)
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],
@@ -1006,15 +1035,6 @@ function parseManager:define(t)
self.methods[i]=v
end
end
-function push(s,n)
- table.insert(s,n)
-end
-function pop(s)
- return table.remove(s)
-end
-function peek(s)
- return s[#s]
-end
function parseManager:Invoke(func,vars,...)
local name=func
local func=self.chunks[func]
@@ -1222,6 +1242,7 @@ function parseManager:next(block,choice)
chunk.pos=chunk.pos+1
data=chunk[chunk.pos]
end
+ if not data then return end
chunk.pos=chunk.pos+1
self:debug("TYPE: "..data.Type)
if data.Type=="text" then
diff --git a/parseManager/standardDefine.lua b/parseManager/standardDefine.lua
index 275a0f3..d6f09b8 100644
--- a/parseManager/standardDefine.lua
+++ b/parseManager/standardDefine.lua
@@ -15,6 +15,12 @@ parseManager:define{
error=function(self,msg)
self:pushError(msg,"\2")
end,
+ setGlobalVar=function(self,var,val)
+ self.mainENV[var]=val
+ end,
+ getGlobalVar=function(self,var,val)
+ self.mainENV[var]=val
+ end,
QUIT=function()
os.exit()
end,
@@ -299,18 +305,33 @@ parseManager:define{
end
end,
COMPARE=function(self,v1,v2,sym)
- if sym==nil then self:pushError("Unexpected Error has occured!",":(") end
+ if sym==nil then self:pushError("Unexpected Error has occurred!","non-existing variable!") end
if sym=="==" then
if v1==v2 then return 1 else return 0 end
elseif sym==">=" then
+ if v1 == nil or v2 == nil then
+ self:pushError("Conditional mathematical args are non-existing!")
+ end
if v1>=v2 then return 1 else return 0 end
elseif sym=="<=" then
+ if v1 == nil or v2 == nil then
+ self:pushError("Conditional mathematical args are non-existing!")
+ end
if v1<=v2 then return 1 else return 0 end
elseif sym==">" then
+ if v1 == nil or v2 == nil then
+ self:pushError("Conditional mathematical args are non-existing!")
+ end
if v1>v2 then return 1 else return 0 end
elseif sym=="<" then
+ if v1 == nil or v2 == nil then
+ self:pushError("Conditional mathematical args are non-existing!")
+ end
if v1
+ >
+ ::leave::
+ print("t = $t$ i = $i$")
}
+// [hmm:function(a,b)]{
+ // return a+b
+// }
+// [A1]{
+ // "At: 1"
+// }
+// [A2]{
+ // "At: 2"
+// }
+// [A3]{
+ // "At: 3"
+// }
// [TEST]{
// newThread("TEST2")
// ::loop::
diff --git a/test.lua b/test.lua
index 383f140..9bd0a22 100644
--- a/test.lua
+++ b/test.lua
@@ -4,6 +4,8 @@ local multi = require("multi")
require("parseManager")
test=parseManager:load("test.dms")--load("StoryTest/init.dms")
print(test:dump())
+
+
--Code would happen here anyway
t=test:next()
while t do
@@ -20,13 +22,13 @@ while t do
elseif t.Type=="method" then
t=test:next()
elseif t.Type=="choice" then
- print(t.text)
- for i=1,#t.choices do
- print(i..". "..t.choices[i])
+ print(t.prompt)
+ for i=1,#t[1] do
+ print(i..". "..t[1][i])
end
io.write("Choose#: ")
cm=tonumber(io.read())
- t=test:next(nil,cm,nil,t)
+ t=test:next(nil,cm)
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()
@@ -39,3 +41,72 @@ while t do
t=test:next()
end
end
+--[[
+MAIN:
+ 1:
+ Type: assign
+ vals:
+ 1: 1
+ vars:
+ 1: x
+ 2:
+ Type: label
+ pos: 2
+ label: FORA
+ 3:
+ Type: fwor
+ Func: print
+ args:
+ 1: x
+ 2: y
+ 4:
+ Func: ADD
+ Type: fwr
+ vars:
+ 1: x
+ args:
+ 1: x
+ 2: 1
+ 5:
+ Type: assign
+ vals:
+ vars:
+ 6:
+ Type: fwr
+ vars:
+ 1: L$
+ Func: COMPARE
+ args:
+ 1: x
+ 2: 11
+ 3: ==
+ 7:
+ Type: fwor
+ Func: CSIM
+ args:
+ 1: L$
+ 8:
+ Type: fwor
+ Func: GOTO
+ args:
+ 1: FORENDA
+ path: test.dms
+ pos: 1
+ 11:
+ Type: text
+ text: Tests
+ labels:
+ FORA: 2
+ FORENDA: 10
+ type: BLOCK
+ 10:
+ Type: label
+ pos: 10
+ label: FORENDA
+ name: MAIN
+ 9:
+ Type: fwor
+ Func: GOTO
+ args:
+ 1: FORA
+]]