function Rework in progress

Almost done, I have to rewrite the math parser though
Found a major issue with it which causes some things not to work
\
But when its done youll be able to do implicit multiplication and it should be compiled more efficently than before.
This commit is contained in:
Ryan Ward 2019-06-16 22:15:36 -04:00
parent 4adcba383a
commit ea72da76a6
6 changed files with 204 additions and 182 deletions

View File

@ -1,3 +1,4 @@
if parseManager.extendedDefineLoaded then return false end
local multi, bin, GLOBAL,sThread local multi, bin, GLOBAL,sThread
local loaded, err = pcall(function() local loaded, err = pcall(function()
multi = require("multi") multi = require("multi")
@ -10,6 +11,7 @@ local loaded, err = pcall(function()
bin = require("bin") bin = require("bin")
end) end)
function parseManager:extendedDefine() function parseManager:extendedDefine()
parseManager.extendedDefineLoaded = true
if not loaded then self:pushWarning("Could not load the extendedDefine module!") print(err) end if not loaded then self:pushWarning("Could not load the extendedDefine module!") print(err) end
local tc = 1 local tc = 1
self.mainENV=GLOBAL self.mainENV=GLOBAL

View File

@ -1,10 +1,4 @@
_print = print
local noprint local noprint
function print(...)
if not noprint then
_print(...)
end
end
require("bin") require("bin")
parseManager={} parseManager={}
parseManager.VERSION = 5 parseManager.VERSION = 5
@ -24,47 +18,9 @@ parseManager.currentHandleName=nil
parseManager.state = {} parseManager.state = {}
parseManager.active = true parseManager.active = true
parseManager.usings = {} parseManager.usings = {}
function parseManager:mainRunner(block) function parseManager.print(...)
local t = self:next(block) if not noprint then
if not t then return nil end print(...)
if t.Type=="text" then
io.write(t.text)
io.read()
t=self:next()
elseif t.Type=="condition" then
t=self:next()
elseif t.Type=="assignment" then
t=self:next()
elseif t.Type=="label" then
t=self:next()
elseif t.Type=="method" then
t=self:next()
elseif t.Type=="choice" then
_print(t.text)
for i=1,#t.choices do
_print(i..". "..t.choices[i])
end
io.write("Choose#: ")
cm=tonumber(io.read())
t=self:next(nil,cm,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=self:next()
else
os.exit()
end
elseif t.Type=="error" then
error(t.text)
else
t=self:next()
end
-- if true return t, else return false
return self.active and t
end
function parseManager:run(block)
local dat = self:mainRunner(block)
while dat do
dat = self:mainRunner()
end end
end end
function readonlytable(tab) function readonlytable(tab)
@ -78,7 +34,7 @@ function readonlytable(tab)
end end
function parseManager:debug(...) function parseManager:debug(...)
if self.stats.debugging then if self.stats.debugging then
print("<DEBUG>",...) parseManager.print("<DEBUG>",...)
end end
end end
function parseManager:newENV() function parseManager:newENV()
@ -107,7 +63,7 @@ function factorial(n)
end end
function parseManager:ENABLE(fn) function parseManager:ENABLE(fn)
if fn == "hostmsg" then if fn == "hostmsg" then
noprint = false noparseManager.print = false
end end
self.stats[string.lower(fn)]=true self.stats[string.lower(fn)]=true
end end
@ -175,7 +131,7 @@ function parseManager:loadCompiled(path)
c.usings = file:getBlock("t") c.usings = file:getBlock("t")
return c return c
end end
function parseManager:load(path,c) function parseManager:load(path,c,noload)
local c = c local c = c
if not c then if not c then
c = {} c = {}
@ -433,10 +389,10 @@ function table.print(tbl, indent)
for k, v in pairs(tbl) do for k, v in pairs(tbl) do
formatting = string.rep(' ', indent) .. k .. ': ' formatting = string.rep(' ', indent) .. k .. ': '
if type(v) == 'table' then if type(v) == 'table' then
print(formatting) parseManager.print(formatting)
table.print(v, indent+1) table.print(v, indent+1)
else else
print(formatting .. tostring(v)) parseManager.print(formatting .. tostring(v))
end end
end end
end end
@ -445,22 +401,22 @@ function parseManager:pushError(err,sym)
if self.runtime then if self.runtime then
run = "Run Time Error! " run = "Run Time Error! "
end end
if not self.currentChunk then print("ERROR compiling: ",err,sym) os.exit() end if not self.currentChunk then parseManager.print("ERROR compiling: ",err,sym) os.exit() end
local lines = bin.load(self.currentChunk.path):lines() local lines = bin.load(self.currentChunk.path):lines()
local chunk = self.currentChunk[self.currentChunk.pos-1] local chunk = self.currentChunk[self.currentChunk.pos-1]
for i=1,#lines do for i=1,#lines do
if sym then if sym then
if lines[i]:find(sym) then if lines[i]:find(sym) then
print(run..err.." <"..sym.."> At line: "..i.." "..(lines[i]:gsub("^\t+",""))) parseManager.print(run..err.." <"..sym.."> At line: "..i.." "..(lines[i]:gsub("^\t+","")))
break break
end end
elseif chunk.Type=="fwor" or chunk.Type=="fwr" then elseif chunk.Type=="fwor" or chunk.Type=="fwr" then
if lines[i]:match(chunk.Func.."%(") then if lines[i]:match(chunk.Func.."%(") then
print(run..err.." At line: "..i.." "..(lines[i]:gsub("^\t+","")).." ("..tostring(sym)..")") parseManager.print(run..err.." At line: "..i.." "..(lines[i]:gsub("^\t+","")).." ("..tostring(sym)..")")
break break
end end
else else
print(run..err.." Line: ?") parseManager.print(run..err.." Line: ?")
break break
end end
end end
@ -468,7 +424,7 @@ function parseManager:pushError(err,sym)
end end
function parseManager:pushWarning(warn) function parseManager:pushWarning(warn)
if not self.stats["warnings"] then return end if not self.stats["warnings"] then return end
print("WARNING: "..warn) parseManager.print("WARNING: "..warn)
end end
local function pieceList(list,self,name) local function pieceList(list,self,name)
if #list==0 then if #list==0 then
@ -964,7 +920,7 @@ function parseManager:compile(name,ctype,data)
if type(t)=="string" then if type(t)=="string" then
t="+"..t t="+"..t
end end
-- print(dat[2] .. (t or "+1")) -- parseManager.print(dat[2] .. (t or "+1"))
self:compileAssign(dat[2],dat[2] .. (t or "+1"),name) self:compileAssign(dat[2],dat[2] .. (t or "+1"),name)
self:compileCondition(dat[2].."=="..tonumber(dat[4])+(tonumber(dat[7]) or 1),"GOTO(\""..s.."\")","GOTO(\""..dat[1].."\")",name) self:compileCondition(dat[2].."=="..tonumber(dat[4])+(tonumber(dat[7]) or 1),"GOTO(\""..s.."\")","GOTO(\""..dat[1].."\")",name)
data[i] = "::"..s.."::" data[i] = "::"..s.."::"
@ -1320,34 +1276,33 @@ function parseManager:next(block,choice)
end end
local chunk = self.currentChunk or self.chunks[block] or self.chunks["START"] local chunk = self.currentChunk or self.chunks[block] or self.chunks["START"]
self.currentChunk=chunk self.currentChunk=chunk
if choice then
local c=self.choiceData[choice][2]
local args=self:dataToValue(c.args)
if not self.methods[c.Func] then
self.lastCall=self:Invoke(c.Func,"lastCall",unpack(args))
else
self.lastCall=self.methods[c.Func](self,unpack(args))
end
return {Type="method"}
end
local ret local ret
local data=chunk[chunk.pos] local data
if not choice then
data=chunk[chunk.pos]
else
data = self.choiceData[choice][2]
end
if not data then self.isrunning = false return end if not data then self.isrunning = false return end
local IRET
if data.Type=="label" then if data.Type=="label" then
chunk.pos=chunk.pos+1 chunk.pos=chunk.pos+1
data=chunk[chunk.pos] data=chunk[chunk.pos]
IRET = self.__LABEL(data.label,data.pos)
end end
if not data then self.isrunning = false return end if not data then self.isrunning = false return end
chunk.pos=chunk.pos+1 chunk.pos=chunk.pos+1
self:debug("TYPE: "..data.Type) self:debug("TYPE: "..data.Type)
if data.Type=="text" then if data.Type=="text" then
self.lastCall=nil self.lastCall=nil
return {Type="text",text=self:parseHeader(data.text)} IRET = self.__TEXT(self:parseHeader(data.text))
elseif data.Type=="funcblock" then elseif data.Type=="funcblock" then
-- self:pairAssign(data.args,self.fArgs) for i,v in ipairs(data.args) do
return {Type="FBLOCK"} self.currentENV[v:sub(2,-1)]=self.fArgs[i]
end
IRET = self.__FBLOCK(args)
elseif data.Type=="return" then elseif data.Type=="return" then
return {Type="method",Vars = vars, RetArgs = data.RETArgs} IRET = self.__RETURN(vars, data.RETArgs)
elseif data.Type=="fwr" then elseif data.Type=="fwr" then
local args=self:dataToValue(data.args,nil,data.Func == "__PUSHPARSE") local args=self:dataToValue(data.args,nil,data.Func == "__PUSHPARSE")
local rets={} local rets={}
@ -1363,11 +1318,12 @@ function parseManager:next(block,choice)
else else
rets={Func(self,unpack(args))} rets={Func(self,unpack(args))}
end end
table.print(rets)
if #rets~=0 then if #rets~=0 then
self:pairAssign(data.vars,rets) self:pairAssign(data.vars,rets)
end end
self.lastCall=nil self.lastCall=nil
return {Type="method",name=data.Func,args = args} IRET = self.__METHOD(data.Func,args)
elseif data.Type=="fwor" then elseif data.Type=="fwor" then
local args=self:dataToValue(data.args) local args=self:dataToValue(data.args)
local Func local Func
@ -1383,7 +1339,7 @@ function parseManager:next(block,choice)
else else
self.lastCall=Func(self,unpack(args)) self.lastCall=Func(self,unpack(args))
end end
return {Type="method",name=data.Func,args = args} IRET = self.__METHOD(data.Func,args)
elseif data.Type=="choice" then elseif data.Type=="choice" then
self.choiceData=data self.choiceData=data
local CList={} local CList={}
@ -1391,11 +1347,13 @@ function parseManager:next(block,choice)
CList[#CList+1]=self:parseHeader(data[i][1]) CList[#CList+1]=self:parseHeader(data[i][1])
end end
self.lastCall=nil self.lastCall=nil
return {Type="choice",prompt=self:parseHeader(data.prompt),CList} local cm = self.__CHOICE(self:parseHeader(data.prompt),CList)
self:next(nil,cm)
return true
elseif data.Type=="assign" then elseif data.Type=="assign" then
self:pairAssign(data.vars,data.vals) self:pairAssign(data.vars,data.vals)
self.lastCall=nil self.lastCall=nil
return {Type="assign"} IRET = self.__ASSIGN(vars,vals)
elseif data.Type=="toggle" then elseif data.Type=="toggle" then
local flags,target = data.Flags,data.Target local flags,target = data.Flags,data.Target
if flags == "USING" then if flags == "USING" then
@ -1412,11 +1370,70 @@ function parseManager:next(block,choice)
else else
self:pushWarning("Invalid flag: "..flag.."!") self:pushWarning("Invalid flag: "..flag.."!")
end end
return {Type="method"} -- you cannot interact with the interpreter yet! IRET = self.__TOGGLE(target,use,name)
else else
self.lastCall=nil self.lastCall=nil
return {Type="Custom Syntax"} IRET = self.__CS(data.data)
end
if IRET=="KILL" then
return false
end
self:next()
return true
end
parseManager.__TEXT = function(text)
io.write(text)
io.read()
end
parseManager.__METHOD = function()
--
end
parseManager.__CHOICE = function(prompt,list)
print(prompt)
for i=1,#list do
print(i..". "..list[i])
end
io.write("Choose#: ")
cm=tonumber(io.read())
return cm
end
parseManager.__LABEL = function()
--
end
parseManager.__TOGGLE = function()
--
end
parseManager.__ASSIGN = function()
--
end
parseManager.__FBLOCK = function()
--
end
parseManager.__CS = function()
--
end
parseManager.__RETURN = function()
end
function parseManager:Call(func,...)
local env = {}
local temp = parseManager:load(self.path,nil,true)
temp.fArgs = {...}
parseManager.__RETURN = function(vars,retargs)
env = temp:dataToEnv(retargs)
return "KILL"
end
temp.entry = func
active = true
while active do
active = temp:think()
end
return unpack(env)
end
function parseManager:think()
self:next()
function parseManager:think()
-- Finish this
end end
return rets
end end
require("parseManager.standardDefine") require("parseManager.standardDefine")

View File

@ -11,7 +11,7 @@ parseManager:define{
return io.read() return io.read()
end, end,
print=function(self,...) print=function(self,...)
_print(...) print(...)
end, end,
WATCH=function(self,...) WATCH=function(self,...)
if self.watchvars then return end if self.watchvars then return end

View File

@ -1,15 +1,27 @@
ENTRY INIT2 ENTRY INIT2
LOADFILE Story/bedroom.dms LOADFILE Story/bedroom.dms
USING extendedDefine // USING extendedDefine
DISABLE warnings DISABLE warnings
USING audio as audio USING audio as audio
// DISABLE hostmsg // DISABLE hostmsg
[INIT2]{ [INIT2]{
multi = external() "Text block"
multi:newTLoop(DoMe,1) "Testing default text handler"
g=DoMe(2)
print("WHAT!!! $g$")
}
[A]{
"Yay it works!"
} }
[DoMe:function(a)]{ [DoMe:function(a)]{
print("Hi",a) "handle me"
if a==0 then SKIP(0)|GOTO("end")
return 1
::end::
return a*SecondCall(a-1)
}
[SecondCall:function()]{
return 6
} }
/* /*
[INIT]{ [INIT]{

View File

@ -10,77 +10,14 @@ test:define{
return multi return multi
end end
} }
parseManager.print(test:dump())
--~ test = parseManager:loadCompiled("test.dmsc") --~ test = parseManager:loadCompiled("test.dmsc")
function parseManager:Call(func,...) --~ print(test.methods.DoMe(1))
local env = {} --~ print(test.methods.DoMe(1,2))
local temp = parseManager:load(self.path) test.__TEXT = function(text)
--~ local temp = {} print(text)
--~ setmetatable(temp,{__index = self})
temp.fArgs = {...}
local t = temp:next(func)
while t do
if t.Type=="text" then
io.write(t.text.."\n")
t=temp:next()
elseif t.Type=="condition" then
t=temp:next()
elseif t.Type=="assignment" then
t=temp:next()
elseif t.Type=="label" then
t=temp:next()
elseif t.Type=="method" then
env = temp:dataToEnv(t.RetArgs)
t=temp:next()
elseif t.Type=="choice" then
_print(t.prompt)
io.write("Choose#: ")
cm=tonumber(1,#t[1])
t=temp:next(nil,cm)
elseif t.Type=="end" then
print("Something went wrong!")
elseif t.Type=="error" then
error(t.text)
else
t=temp:next()
end
end
return unpack(env)
end end
--~ print(test.methods.DoMe(test,1,2)) local active = true
t=test:next() while active do
while t do active = test:think()
if t.Type=="text" then
io.write(t.text)
io.read()
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
_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)
elseif t.Type=="end" then
if t.text=="leaking" then
t=test:next()
else
os.exit()
end
elseif t.Type=="error" then
error(t.text)
else
t=test:next()
end
end end
multi:mainloop{
protect = true
}

106
test2.lua
View File

@ -1,27 +1,81 @@
--~ local GLOBAL, sThread = require("multi.integration.lanesManager").init() function table.print(tbl, indent)
--~ GLOBAL["Test"]=true if type(tbl)~="table" then return end
--~ multi:newSystemThread("NewThread",function(blck,path,name) if not indent then indent = 0 end
--~ print(GLOBAL["Test"]) for k, v in pairs(tbl) do
--~ end) formatting = string.rep(' ', indent) .. k .. ': '
--~ io.flush() if type(v) == 'table' then
--~ i = io.input() print(formatting)
--~ i:seek("cur") table.print(v, indent+1)
--~ i:read(2) else
--~ print(i) print(formatting .. tostring(v))
--~ g={} end
--~ while t~="q" do end
--~ g[#g+1]=t
--~ io.flush()
--~ t=io.read(1)
--~ io.write("\b")
--~ end
--~ print("done")
--~ io.write("\b")
--~ io.flush()
--~ io.read()
bool = true
function test()
local t = {}
return bool and t
end end
print(test()) local special = {["("]=true,[")"]=true,["+"]=true,["-"]=true,["/"]=true,["*"]=true,["%"]=true,["^"]=true}
function parse(e)
local cmds = {}
local state = 0
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
end
end
end
if nonSP or not wasNum then
cmds[#cmds+1] = {Tpye="const",data = group}
else
cmds[#cmds+1] = group
end
if cmds[1]=="" then table.remove(cmds,1) end
if cmds[#cmds]=="" then table.remove(cmds) end
return cmds
end
------------------
expr = "test(2.4+20)/sqrt(100) + food"
c=parse(expr)
table.print(c)