Functions still need some work

Almost done fixing functions
This commit is contained in:
Ryan Ward 2019-06-07 07:55:36 -04:00
parent bfb34916e3
commit 4adcba383a
13 changed files with 266 additions and 189 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
test.lua
*.ogg

View File

@ -24,10 +24,10 @@
<Keywords name="Folders in comment, open">/*</Keywords>
<Keywords name="Folders in comment, middle"></Keywords>
<Keywords name="Folders in comment, close">*/</Keywords>
<Keywords name="Keywords1">ENABLE DISABLE LOAD ENTRY USING VERSION as</Keywords>
<Keywords name="Keywords1">ENABLE DISABLE LOADFILE ENTRY USING VERSION as</Keywords>
<Keywords name="Keywords2">if then return and or True False for while</Keywords>
<Keywords name="Keywords3">leaking debugging warnings</Keywords>
<Keywords name="Keywords4">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</Keywords>
<Keywords name="Keywords3">leaking debugging warnings statesave hostmsg</Keywords>
<Keywords name="Keywords4">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 SAVE LOAD WATCH</Keywords>
<Keywords name="Keywords5">_VERSION</Keywords>
<Keywords name="Keywords6">filesystem extendedDefine</Keywords>
<Keywords name="Keywords7"></Keywords>

3
Story/bedroom.dms Normal file
View File

@ -0,0 +1,3 @@
[BEDROOM]{
}

29
parseManager/audio.lua Normal file
View File

@ -0,0 +1,29 @@
require("proAudioRt")
proAudio.create()
local audio = {}
audio.__index = audio
function audio:new(path)
local c = {}
c.path = path
c.handle = proAudio.sampleFromFile(path)
setmetatable(c,audio)
return c
end
function audio:play(volume,loop)
local volume = volume or 1
if loop then
proAudio.soundLoop(self.handle, volume, volume, 0, 1)
else
proAudio.soundPlay(self.handle, volume, volume, 0, 1)
end
end
function audio:stop()
if not self then proAudio.soundStop() return end
proAudio.soundStop(self.handle)
end
function audio:setVolume(volume)
proAudio.soundUpdate(self.handle,volume,volume)
end
function parseManager:audio()
return audio
end

View File

@ -1,4 +1,4 @@
local multi,bin,GLOBAL,sThread
local multi, bin, GLOBAL,sThread
local loaded, err = pcall(function()
multi = require("multi")
local plat = multi:getPlatform()
@ -7,18 +7,17 @@ local loaded, err = pcall(function()
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.mainENV=GLOBAL
self.currentENV=GLOBAL
self:define{
setVar = function(self,name,val)
GLOBAL[name]=val
end,
getVar = function(self,name)
return sThread.waitFor(name)
WATCH=function(self,...)
if self.watchvars then return end
self.watchvars = {...}
end,
newThread = function(self,block,name)
multi:newSystemThread(name or "NewThread"..tc,function(blck,path,name)
@ -30,22 +29,18 @@ function parseManager:extendedDefine()
sThread=_G.sThread
end
local test=parseManager:load(path)
t=test:next(blck)
test.mainENV = GLOBAL
test.currentENV = GLOBAL
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.."")
title = function(self,t)
os.execute("title "..t)
end
}
multi:newThread("Runner",function()
t=test:next(blck)
multi:newThread(name,function()
while true do
thread.skip(0)
if not t then error("Thread ended!") end
@ -78,7 +73,9 @@ function parseManager:extendedDefine()
multi:mainloop()
end,block,self.currentChunk.path,name or "NewThread"..tc)
tc=tc+1
end,
}
end
multi.OnError(function(...)
print(...)
end)

View File

@ -1,3 +1,10 @@
_print = print
local noprint
function print(...)
if not noprint then
_print(...)
end
end
require("bin")
parseManager={}
parseManager.VERSION = 5
@ -33,9 +40,9 @@ function parseManager:mainRunner(block)
elseif t.Type=="method" then
t=self:next()
elseif t.Type=="choice" then
print(t.text)
_print(t.text)
for i=1,#t.choices do
print(i..". "..t.choices[i])
_print(i..". "..t.choices[i])
end
io.write("Choose#: ")
cm=tonumber(io.read())
@ -99,9 +106,15 @@ function factorial(n)
end
end
function parseManager:ENABLE(fn)
if fn == "hostmsg" then
noprint = false
end
self.stats[string.lower(fn)]=true
end
function parseManager:DISABLE(fn)
if fn == "hostmsg" then
noprint = true
end
self.stats[string.lower(fn)]=false
end
function parseManager:USING(fn,name)
@ -168,6 +181,9 @@ function parseManager:load(path,c)
c = {}
setmetatable(c,parseManager)
end
if not c.path then
c.path = path
end
local file
if type(path)=="table" then
if path.Type=="bin" then
@ -203,7 +219,7 @@ function parseManager:load(path,c)
self:debug("E",fn)
c:ENABLE(fn)
end
for fn in header:gmatch("LOAD (.-)\n") do
for fn in header:gmatch("LOADFILE (.-)\n") do
self:debug("L",fn)
c:load(fn,c)
end
@ -412,6 +428,7 @@ function parseManager:dump()
return str
end
function table.print(tbl, indent)
if type(tbl)~="table" then return end
if not indent then indent = 0 end
for k, v in pairs(tbl) do
formatting = string.rep(' ', indent) .. k .. ': '
@ -469,7 +486,6 @@ local function pieceList(list,self,name)
else
local sym = getSymbol("`")
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
@ -871,18 +887,32 @@ end
local function trim1(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
local function extract(dat,name)
if type(dat)=="string" and dat:sub(1,1)=="\1" then
return dat:sub(2,-1)
elseif tonumber(dat)~=nil then
return tonumber(dat)
else
return dat
end
end
function parseManager:compile(name,ctype,data)
local isFBlock,FBArgs=ctype:match("(f)unction%((.*)%)")
--Check if we are dealing with a FBlock
if isFBlock=="f" then
if not self.isInternal then
self.isInternal = {}
end
self.cFuncs[name]=true
-- if self.methods[name] then
-- self:pushError("You cannot create a method with the same name as a standard method or duplicate method names!",name)
-- end
self.methods[name]=function(...)
self:Invoke(name,...)
--self:Invoke(name,...)
return self:Call(name,...)
end
self.__INTERNAL[name] = true
self.isInternal[name]=self.methods[name]
-- self.__INTERNAL[name] = true
-- if not self.variables.__internal then
-- self.variables.__internal = {}
-- end
@ -902,10 +932,10 @@ function parseManager:compile(name,ctype,data)
for i=1,#data do
data[i]=trim1(data[i])
if data[i]~="" then
if data[i]:match("for[%s%w=%-]-[%d%-,%s]-<") then
if data[i]:match("for[%s%w=%-]-[%d%-%w%(%),%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 var,a,b,c = data[i]:match("for%s*([%w_]+)%s*=%s*(%-*[%d%w%(%)]+),%s*(%-*[%d%w%(%)]+)%s*,*%s*(%-*[%d%w%(%)]*)")
local s = getSymbol(getSymbol("LOOPEND"))
push(stack,{sym,var,a,b,s,1,c}) -- 1 for loop, 2 while loop
data[i] = "::"..sym.."::"
@ -930,7 +960,12 @@ function parseManager:compile(name,ctype,data)
local s = dat[5]
local cmd = dat[6]
if cmd==1 then
self:compileAssign(dat[2],dat[2] .. (tonumber(dat[7]) or "+1"),name)
local t = extract(dat[7],name)
if type(t)=="string" then
t="+"..t
end
-- print(dat[2] .. (t or "+1"))
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)
data[i] = "::"..s.."::"
elseif cmd == 2 then
@ -1050,6 +1085,15 @@ function parseManager:testDict(dict)
return
end
end
function parseManager:dataToEnv(values)
local env = {}
if values then
for i,v in pairs(values) do
env[#env+1] = test:dataToValue(v)
end
end
return env
end
function parseManager:dataToValue(name,envF,b) -- includes \1\
envF=envF or self.currentENV
local tab=name
@ -1076,7 +1120,11 @@ function parseManager:dataToValue(name,envF,b) -- includes \1\
end
end
end
return tab or {}
if tab~= nil then
return tab
else
return {}
end
end
function parseManager:define(t)
for i,v in pairs(t) do
@ -1086,80 +1134,6 @@ end
function parseManager:handleChoice(func)
self.choiceManager = func
end
function parseManager:Invoke(func,vars,...)
if not self.isrunning then
self.isrunning = true
local t=self:next()
local name=func
local func=self.chunks[func]
if func then
if func.type:sub(1,1)=="f" then
local returndata={}
self.fArgs={...}
if #self.fArgs==0 then
self.fArgs={self.lastCall}
end
push(self.stack,{chunk=self.currentChunk,pos=self.currentChunk.pos,env=self.currentENV,vars=vars})
self.currentENV = self:newENV()
self.methods.JUMP(self,name)
-- return
else
self:pushError("Attempt to call a non function block!",name)
end
else
self:pushError("Attempt to call a non existing function!",name)
end
while t do
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
if self.choiceManager then
t=self:choiceManager(t)
else
t=self:next(nil,math.random(1,#t[1]))
end
elseif t.Type=="end" then
if t.text=="leaking" then
t=self:next()
end
elseif t.Type=="error" then
error(t.text)
else
t=self:next()
end
end
return
end
local name=func
local func=self.chunks[func]
if func then
if func.type:sub(1,1)=="f" then
local returndata={}
self.fArgs={...}
if #self.fArgs==0 then
self.fArgs={self.lastCall}
end
push(self.stack,{chunk=self.currentChunk,pos=self.currentChunk.pos,env=self.currentENV,vars=vars})
self.currentENV = self:newENV()
self.methods.JUMP(self,name)
return
else
self:pushError("Attempt to call a non function block!",name)
end
else
self:pushError("Attempt to call a non existing function!",name)
end
end
function round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
@ -1370,51 +1344,30 @@ function parseManager:next(block,choice)
self.lastCall=nil
return {Type="text",text=self:parseHeader(data.text)}
elseif data.Type=="funcblock" then
local env=self.currentENV
self.currentENV=self:newENV()
self:pairAssign(data.args,self.fArgs,env)
-- self:pairAssign(data.args,self.fArgs)
return {Type="FBLOCK"}
elseif data.Type=="return" then
local obj=pop(self.stack)
local chunk=obj.chunk
local pos=obj.pos
local env=obj.env
local vars=obj.vars
local name=chunk.name
local env=self.currentENV
chunk.pos=pos
self.currentENV=env
self:pairAssign(vars,data.RETArgs,env)
self.currentChunk=chunk
return {Type="method"}
return {Type="method",Vars = vars, RetArgs = data.RETArgs}
elseif data.Type=="fwr" then
local args=self:dataToValue(data.args,nil,data.Func == "__PUSHPARSE")
local rets={}
local Func
local Ext=false
if type(data.Func)=="table" then
Ext=true
Func=self.currentENV[data.Func[1]][data.Func[2]]
else
Func=self.methods[data.Func]
end
if Ext then
if self.isInternal[data.Func] then
rets={Func(unpack(args))}
elseif self.__INTERNAL[data.Func] then
self:Invoke(data.Func,data.vars,unpack(args))
else
if type(Func)~="function" then
rets={self:Invoke(data.Func,data.vars,unpack(args))}
return {Type="method"}
else
rets={Func(self,unpack(args))}
end
rets={Func(self,unpack(args))}
end
if #rets~=0 then
self:pairAssign(data.vars,rets)
end
self.lastCall=nil
return {Type="method"}
return {Type="method",name=data.Func,args = args}
elseif data.Type=="fwor" then
local args=self:dataToValue(data.args)
local Func
@ -1428,14 +1381,9 @@ function parseManager:next(block,choice)
if Ext then
self.lastCall=Func(unpack(args))
else
if type(Func)~="function" then
self.lastCall=self:Invoke(data.Func,"lastCall",unpack(args))
return {Type="method"}
else
self.lastCall=Func(self,unpack(args))
end
self.lastCall=Func(self,unpack(args))
end
return {Type="method"}
return {Type="method",name=data.Func,args = args}
elseif data.Type=="choice" then
self.choiceData=data
local CList={}

View File

@ -1,3 +1,4 @@
local bin = require("bin")
local clock = os.clock
parseManager:define{
__PUSHPARSE = function(self,dat)
@ -10,7 +11,39 @@ parseManager:define{
return io.read()
end,
print=function(self,...)
print(...)
_print(...)
end,
WATCH=function(self,...)
if self.watchvars then return end
self.watchvars = {...}
end,
SAVE=function(self,fn)
local file = bin.new()
local data = {}
for i=1,#self.watchvars do
data[self.watchvars[i]] = self.currentENV[self.watchvars[i]]
end
data["__CHUNK"] = self.methods.getCurrentChunk(self)
data["__POSITION"] = self.methods.getCurrentPosition(self)
file:addBlock(data)
file:tofile(fn or "save.dat")
end,
LOAD=function(self,fn)
if not bin.fileExists(fn or "save.dat") then return false end
local file = bin.load(fn or "save.dat")
t = file:getBlock("t")
local c,p = t.__CHUNK,t.__POSITION
t.__CHUNK,t.__POSITION = nil,nil
for i,v in pairs(t) do
self.mainENV[i] = v
end
if self.stats.statesave then
self.methods.JUMP(self,c, p)
end
return true,c,p
end,
EXECUTE = function(self,cmd)
os.execute(cmd)
end,
error=function(self,msg)
self:pushError(msg,"\2")
@ -21,16 +54,29 @@ parseManager:define{
getGlobalVar=function(self,var,val)
self.mainENV[var]=val
end,
len=function(self,t)
return #t
end,
QUIT=function()
os.exit()
end,
getCurrentChunk = function(self)
for i,v in pairs(self.chunks) do
if self.currentChunk == v then
return i
end
end
end,
getCurrentPosition = function(self)
return self.currentChunk.pos-1
end,
sleep=function(self,n)
local t0 = clock()
while clock() - t0 <= n do end
end,
JUMP=function(self,block)
JUMP=function(self,block,pos)
if self.chunks[block] then
self.chunks[block].pos=1
self.chunks[block].pos=pos or 1
self.currentChunk=self.chunks[block]
else
self:pushError("Attempt to jump to a non existing block:","\2")
@ -342,7 +388,4 @@ parseManager:define{
self.methods.SKIP(self,1)
end
end,
print=function(self,...)
print(...)
end
}

BIN
proAudioRt.dll Normal file

Binary file not shown.

BIN
rps.dmsc Normal file

Binary file not shown.

BIN
save.dat Normal file

Binary file not shown.

View File

@ -1,43 +1,61 @@
ENTRY MAIN
ENTRY INIT2
LOADFILE Story/bedroom.dms
USING extendedDefine
VERSION 4.1
[MAIN]{
// test = [1,2,3,4,5,6,7,8,9,10]
// t=0
// test2 = "Hello"
// str = $test2[1:-1]$
// print("$test2[-1:1]$")
// print(str)
// t=testfunc(1,2)
// print(t)
// for i = 1,10 <
// "Choice Test: $test[1]$" <
// "A" setGlobalVar("t",1)
// "B" continue()
// "C" setGlobalVar("t",3)
// >
// >
// ::leave::
// print("t = $t$ i = $i$")
val = 0
DISABLE warnings
USING audio as audio
// DISABLE hostmsg
[INIT2]{
multi = external()
multi:newTLoop(testfunc,1)
// multi:newTLoop(testfunc2)
// alarm = multi:newAlarm(3)
// alarm:OnRing(testfunc)
print("Hooked function!")
multi:newTLoop(DoMe,1)
}
[testfunc:function()]{
val = val + 1
print("Called $val$ times!")
return True
[DoMe:function(a)]{
print("Hi",a)
}
[testfunc2:function()]{
"Test"<
"1" print("A")
"2" print("B")
"3" print("C")
>
// print("Yo whats up!")
return True
/*
[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")
loaded,c,p = LOAD()
if loaded==false then JUMP("SETUP")|SKIP(0)
newThread("UPDATER","Thread_DisplayStats")
JUMP(c,p)
QUIT()
}
[SETUP]{
money = 100
name = getInput("Enter name: ")
day = 1
chapter = 1
passive = 1
newThread("UPDATER","Thread_DisplayStats")
SAVE()
JUMP("START")
}
[UPDATER]{
maintheme=audio:new("Audio/Nadia.ogg")
maintheme:play(.5)
::loop::
EXECUTE("title $name$ $$money$ Day: $day$ Chap: $chapter$")
sleep(.1)
money = money + passive
GOTO("loop")
}
[stop:function()]{
"hmm"
return 1,2
}
[Fade:function(obj)]{
// for x = 100, 0, -1 <
// sleep(.1)
// obj:setVolume(x/100)
// >
}
[START]{
"HI!"
maintheme:setVolume(1)
sleep(1)
Fade(maintheme)
"Yo"
// JUMP("BEDROOM")
}
*/

BIN
test.dmsc

Binary file not shown.

View File

@ -1,16 +1,52 @@
package.path="?/init.lua;lua/?/init.lua;lua/?.lua;"..package.path
package.cpath="?.dll;"..package.cpath
local bin = require("bin")
local multi = require("multi")
require("parseManager")
require("multi")
test=parseManager:compileToFile("test.dms","test.dmsc")--load("StoryTest/init.dms")
--~ test = parseManager:loadCompiled("test.dmsc")
print(test:dump())
test=parseManager:load("test.dms")--parseManager:compileToFile("test.dms","test.dmsc")--
test:define{
external=function(self)
external = function()
return multi
end
}
--~ test = parseManager:loadCompiled("test.dmsc")
function parseManager:Call(func,...)
local env = {}
local temp = parseManager:load(self.path)
--~ local temp = {}
--~ 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
--~ print(test.methods.DoMe(test,1,2))
t=test:next()
while t do
if t.Type=="text" then
@ -26,7 +62,7 @@ while t do
elseif t.Type=="method" then
t=test:next()
elseif t.Type=="choice" then
print(t.prompt)
_print(t.prompt)
for i=1,#t[1] do
print(i..". "..t[1][i])
end
@ -45,4 +81,6 @@ while t do
t=test:next()
end
end
multi:mainloop()
multi:mainloop{
protect = true
}