This commit is contained in:
Ryan Wardm 2020-07-21 12:08:01 -04:00
parent 4e43a93337
commit b93af86841
9 changed files with 138 additions and 67 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
local Interpreter = require("dms.interpreter") local Interpreter = require("dms.interpreter")
local i = Interpreter:new("test.dms") local i = Interpreter:new("test.dms")
print(i:dump()) print(i:dump("dump.dat"))

2
dms/compiler3.lua Normal file
View File

@ -0,0 +1,2 @@
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
-- I like using the state machine much better than the regex method.

View File

@ -16,15 +16,27 @@ function Interpreter:compile(file)
if not file then error("You must provide a file path to compile!") end if not file then error("You must provide a file path to compile!") end
self.chunks = Parser:new(file,self.chunks):parse() self.chunks = Parser:new(file,self.chunks):parse()
end end
function Interpreter:dump() function Interpreter:dump(filename)
local filedat = "" local filedat = ""
local entry = self.parser.entry
if entry then
filedat = "ENTR "..entry.."\n"
end
local flags = self.parser.flags
for i,v in pairs(flags) do
filedat = filedat.."FLAG "..i..":"..tostring(v).."\n"
end
for i,v in pairs(self.chunks) do for i,v in pairs(self.chunks) do
filedat = filedat..tostring(v) .. "\n" filedat = filedat..tostring(v) .. "\n"
end end
if filename then
file = io.open("dump.dat","wb")
file:write(filedat)
file:flush()
end
return filedat return filedat
end end
function Interpreter:interprete() function Interpreter:interprete()
--
end end
return Interpreter return Interpreter

View File

@ -1,12 +1,10 @@
require("dms.utils") require("dms.utils")
file = io.open("dump.dat","wb")
local char = string.char local char = string.char
local Stack = require("dms.stack") local Stack = require("dms.stack")
local Chunk = require("dms.chunk") local Chunk = require("dms.chunk")
local Cmd = require("dms.cmd") local Cmd = require("dms.cmd")
local Value = require("dms.value")
local Queue = require("dms.queue") local Queue = require("dms.queue")
local ENTR,ENAB,DISA,LOAD,VERN,USIN,STAT,DISP,ASGN,LABL,CHOI,OPTN,FORE,UNWN,WHLE,FNWR,FNNR,IFFF,ELIF,ELSE,DEFN,SKIP,COMP,INDX,JMPZ,NOOP = "ENTR","ENAB","DISA","LOAD","VERN","USIN","STAT","DISP","ASGN","LABL","CHOI","OPTN","FORE","????","WHLE","FNWR","FNNR","IFFF","ELIF","ELSE","DEFN","SKIP","COMP","INDX","JMPZ","NOOP" local ENTR,ENAB,DISA,LOAD,VERN,USIN,STAT,DISP,ASGN,LABL,CHOI,OPTN,FORE,UNWN,WHLE,FNWR,FNNR,IFFF,ELIF,ELSE,DEFN,SKIP,COMP,INDX,JMPZ,NOOP,INST = "ENTR","ENAB","DISA","LOAD","VERN","USIN","STAT","DISP","ASGN","LABL","CHOI","OPTN","FORE","????","WHLE","FNWR","FNNR","IFFF","ELIF","ELSE","DEFN","SKIP","COMP","INDX","JMPZ","NOOP","INST"
local controls = {STAT,CHOI,FORE,WHLE,IFFF,ELIF,ELSE} local controls = {STAT,CHOI,FORE,WHLE,IFFF,ELIF,ELSE}
local flags = {ENTR,ENAB,DISA,LOAD,VERN,USIN,DEFN} local flags = {ENTR,ENAB,DISA,LOAD,VERN,USIN,DEFN}
local recognizedFlags = { local recognizedFlags = {
@ -118,25 +116,7 @@ function parser:split(s,pat,l)
local state = 0 local state = 0
local c = '.' local c = '.'
local elem = '' local elem = ''
local function helper() local v
if tonumber(elem) then
elem = tonumber(elem)
elseif elem:sub(1,1) == "\"" and elem:sub(-1,-1) == "\"" then
elem = elem:sub(2,-2)
elseif elem == "true" then
elem = true
elseif elem == "false" then
elem = false
elseif elem:sub(1,1)=="{" and elem:sub(-1,-1)=="}" then
elem = self:split(elem:sub(2,-2),nil,true)
elseif elem:match("[%-%+/%%%(%)%*%^]") then
gen("$",true) -- Flush the temp variables
elem = "\1"..self:parseExpr(elem)
else
-- \1 Tells the interperter that we need to do a lookup
elem = "\1"..elem
end
end
local counter = 0 local counter = 0
local function next() local function next()
counter = counter + 1 counter = counter + 1
@ -145,6 +125,54 @@ function parser:split(s,pat,l)
local function peek() local function peek()
return s:sub(counter + 1,counter + 1) return s:sub(counter + 1,counter + 1)
end end
local function index(right)
local ind = ""
c = peek()
while c ~= "]" do
next()
ind = ind..c
c = peek()
end
c = next()
print(elem,ind)
local vv = gen("$")
self:buildIndex(elem,ind,vv)
elem = vv
if not(c=="]") then
self:error("']' expected to close '['")
end
end
local function packTable(tab)
print("Doing list!")
local vv = gen("&")
for i,k in ipairs(tab) do
v = gen("&")
self:parseASGN({self.current_line[1],self.current_line[2],ASGN,self.current_line[4],v.." = "..tostring(k)})
self:buildInsert(vv,i,v)
print(vv,i,v,k)
end
return vv
end
local function helper()
if tonumber(elem) then
elem = tonumber(elem)
elseif elem:sub(1,1) == "\"" and elem:sub(-1,-1) == "\"" then
elem = elem
elseif elem == "true" then
elem = true
elseif elem == "false" then
elem = false
elseif elem:sub(1,1)=="{" and elem:sub(-1,-1)=="}" then
elem = packTable()
elseif elem:match("[%-%+/%%%(%)%*%^]") then
gen("$",true) -- Flush the temp variables
elem = self:parseExpr(elem)
else
--\1 Tells the interperter that we need to do a lookup
elem = elem
end
end
local function getarr() local function getarr()
local a = peek() local a = peek()
local str = "" local str = ""
@ -167,7 +195,6 @@ function parser:split(s,pat,l)
next() next()
return str return str
end end
c = true
while c~="" do while c~="" do
c = next() c = next()
if state == 0 or state == 3 then -- start state or space after comma if state == 0 or state == 3 then -- start state or space after comma
@ -175,12 +202,41 @@ function parser:split(s,pat,l)
state = 0 -- skipped the space after the comma state = 0 -- skipped the space after the comma
else else
state = 0 state = 0
if c == '"' or c=="'" then if c == '"' then
state = 1 c = peek()
elem = elem .. '"' str = ""
while c~="\"" do
next()
if c=="\\" and peek()=="\"" then
next()
str = str .. "\""
else
str = str .. c
end
c = peek()
end
elem = elem .. "\""..str.."\""
next()
elseif c == "'" then
elem = elem .. "'"
c = peek()
while c~="'" do
next()
if c=="\\" and peek()=="'" then
next()
elem = elem + "'"
else
elem = elem .. c
end
c = peek()
end
elem = elem .. "\""..str.."\""
next()
elseif c == "[" then
index()
elseif c=="{" then elseif c=="{" then
local t = self:split(getarr(),nil,true) local t = self:split(getarr(),nil,true)
res[#res + 1] = t res[#res + 1] = packTable(t)
elem = '' elem = ''
state = 3 state = 3
elseif c == pat then elseif c == pat then
@ -196,10 +252,7 @@ function parser:split(s,pat,l)
end end
end end
elseif state == 1 then -- inside quotes elseif state == 1 then -- inside quotes
if c == '"' or c=="'" then --quote detection could be done here if c=="}" then
state = 0
elem = elem .. '"'
elseif c=="}" then
state = 0 state = 0
elem = elem .. '}' elem = elem .. '}'
elseif c==")" then elseif c==")" then
@ -330,9 +383,9 @@ function parser:parse()
else else
goto back goto back
end end
elseif line:match("[%s,%$_%w]*=%s*[%l_][%w_]-%(.+%)") then elseif line:match("[%s,_%w]*=%s*[%l_][%w_]-%(.+%)") then
groupStack:append{line_num,group,FNWR,self.filename,line:trim()} groupStack:append{line_num,group,FNWR,self.filename,line:trim()}
elseif line:trim():match("[%s,%$_%w]-\".+\"") == line:trim():match(".+") then elseif line:trim():match("[%s_%w]-\".+\"") == line:trim():match(".+") then
groupStack:append{line_num,group,DISP,self.filename,line:trim()} groupStack:append{line_num,group,DISP,self.filename,line:trim()}
elseif line:match("elseif%s*(.+)") then elseif line:match("elseif%s*(.+)") then
groupStack:append{line_num,group,ELIF,self.filename,line:trim()} groupStack:append{line_num,group,ELIF,self.filename,line:trim()}
@ -340,9 +393,9 @@ function parser:parse()
groupStack:append{line_num,group,IFFF,self.filename,line:trim()} groupStack:append{line_num,group,IFFF,self.filename,line:trim()}
elseif line:match("else%s*(.+)") then elseif line:match("else%s*(.+)") then
groupStack:append{line_num,group,ELSE,self.filename,line:trim()} groupStack:append{line_num,group,ELSE,self.filename,line:trim()}
elseif line:match("[%l_][%w_]-%(.+%)") and not line:match("[%s,%$_%w]-=(.+)") then elseif line:match("[%l_][%w_]-%(.+%)") and not line:match("[%s,_%w]-=(.+)") then
groupStack:append{line_num,group,FNNR,self.filename,line:trim()} groupStack:append{line_num,group,FNNR,self.filename,line:trim()}
elseif line:match("[%s,%$_%w]-=(.+)") and not line:match("[%l_][%w_]-%(.+%)") then elseif line:match("[%s,_%w]-=(.+)") and not line:match("[%l_][%w_]-%(.+%)") then
groupStack:append{line_num,group,ASGN,self.filename,line:trim()} groupStack:append{line_num,group,ASGN,self.filename,line:trim()}
else else
groupStack:append{line_num,group,UNWN,self.filename,line:trim()} groupStack:append{line_num,group,UNWN,self.filename,line:trim()}
@ -409,14 +462,6 @@ function parser:parse()
self.current_chunk:finished() self.current_chunk:finished()
self.chunks[self.current_chunk.chunkname] = self.current_chunk self.chunks[self.current_chunk.chunkname] = self.current_chunk
end end
if not self.internal then
local filedat = ""
for i,v in pairs(self.chunks) do
filedat = filedat..tostring(v) .. "\n"
end
file:write(filedat)
file:flush()
end
return self.chunks return self.chunks
end end
local EQ,GTE,LTE,NEQ,GT,LT = "=",char(242),char(243),char(247),">","<" local EQ,GTE,LTE,NEQ,GT,LT = "=",char(242),char(243),char(247),">","<"
@ -424,7 +469,7 @@ function parser:JMPZ(v,label)
if not v then error("Fix this now!!!") end if not v then error("Fix this now!!!") end
local cmd = Cmd:new({self.current_line[1],self.current_line[2],JMPZ,self.current_line[4],"?"},JMPZ,{label = label,var = v}) local cmd = Cmd:new({self.current_line[1],self.current_line[2],JMPZ,self.current_line[4],"?"},JMPZ,{label = label,var = v})
function cmd:tostring() function cmd:tostring()
return self.args.var .. ", " ..self.args.label return self.args.var.."\0" .. ", " ..self.args.label.."\0"
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end
@ -508,14 +553,21 @@ end
function parser:buildLogic(l,o,r,v) function parser:buildLogic(l,o,r,v)
local cmd = Cmd:new({self.current_line[1],self.current_line[2],COMP,self.current_line[4],"?"},COMP,{left=l,op=o,right=r,var=v}) local cmd = Cmd:new({self.current_line[1],self.current_line[2],COMP,self.current_line[4],"?"},COMP,{left=l,op=o,right=r,var=v})
function cmd:tostring() function cmd:tostring()
return table.concat({self.args.op,tostring(self.args.left),tostring(self.args.right)},", ").." -> "..self.args.var return table.concat({self.args.op,tostring(self.args.left).."\0",tostring(self.args.right).."\0"},", ")..", "..self.args.var.."\0"
end
self.current_chunk:addCmd(cmd)
end
function parser:buildInsert(name,ind,v)
local cmd = Cmd:new({self.current_line[1],self.current_line[2],INST,self.current_line[3],"?"},INST,{name = name, index = ind, var = v})
function cmd:tostring()
return table.concat({tostring(self.args.name),tostring(self.args.index)},"\0, ")..", "..self.args.var.."\0"
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end
function parser:buildIndex(name,ind,v) function parser:buildIndex(name,ind,v)
local cmd = Cmd:new({self.current_line[1],self.current_line[2],INDX,self.current_line[3],"?"},INDX,{name = name, index = ind, var = v}) local cmd = Cmd:new({self.current_line[1],self.current_line[2],INDX,self.current_line[3],"?"},INDX,{name = name, index = ind, var = v})
function cmd:tostring() function cmd:tostring()
return table.concat({tostring(self.args.name),tostring(self.args.index)},", ").." -> "..self.args.var return table.concat({tostring(self.args.name),tostring(self.args.index)},"\0, ")..", "..self.args.var.."\0"
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end
@ -647,7 +699,7 @@ function parser:logicChop(expr)
elseif l == "false" then elseif l == "false" then
l = false l = false
else else
l = "\1" .. l l = l
end end
elseif o~= '' then elseif o~= '' then
r=c r=c
@ -666,7 +718,7 @@ function parser:logicChop(expr)
elseif r == "false" then elseif r == "false" then
r = false r = false
else else
r = "\1" .. r r = r
end end
v = gen("$") v = gen("$")
self:buildLogic(l,o,r,v) self:buildLogic(l,o,r,v)
@ -696,6 +748,7 @@ function parser:logicChop(expr)
end end
c = peek() c = peek()
end end
str = "\""..str.."\""
if l=="" then if l=="" then
l = str l = str
elseif r=="" then elseif r=="" then
@ -711,14 +764,15 @@ function parser:logicChop(expr)
c = peek() c = peek()
while c~="\"" do while c~="\"" do
next() next()
if c=="\\" and peek()=="\"" then if c=="\\" and peek()=="'" then
next() next()
elem = elem + "\"" elem = elem + "'"
else else
elem = elem .. c elem = elem .. c
end end
c = peek() c = peek()
end end
str = "\""..str.."\""
if l=="" then if l=="" then
l = str l = str
elseif r=="" then elseif r=="" then
@ -793,7 +847,7 @@ function parser:parseChoice(line)
local choice = {text = text,options = {}} local choice = {text = text,options = {}}
local cmd = Cmd:new(line,CHOI,choice) local cmd = Cmd:new(line,CHOI,choice)
function cmd:tostring() function cmd:tostring()
return "\""..self.args.text.."\", "..table.concat(self.args.options,", ")-- disp choices return self.args.text.."\0, "..table.concat(self.args.options,"\0, ").."\0"-- disp choices
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
if copt[3]~=OPTN then if copt[3]~=OPTN then
@ -804,7 +858,7 @@ function parser:parseChoice(line)
while copt do while copt do
copt = self:next() copt = self:next()
local a,b = copt[5]:match("(.+) %s*(.+)") local a,b = copt[5]:match("(.+) %s*(.+)")
table.insert(choice.options,a) table.insert(choice.options,a:sub(2,-2))
table.insert(opts,b) table.insert(opts,b)
copt = self:peek() copt = self:peek()
if copt[3]~=OPTN then if copt[3]~=OPTN then
@ -831,9 +885,9 @@ function parser:parseFNNR(line)
local cmd = Cmd:new(line,FNNR,{func=fname,args=args}) local cmd = Cmd:new(line,FNNR,{func=fname,args=args})
function cmd:tostring() function cmd:tostring()
if #args==0 then if #args==0 then
return fname return fname.."\0"
else else
return table.concat({fname,table.concat(args,", ")},", ") return table.concat({fname,table.concat(args,"\0, ")},"\0, ").."\0"
end end
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
@ -848,7 +902,7 @@ function parser:parseFNWR(line)
end end
local cmd = Cmd:new(line,FNWR,{func=fname,args=args,vars=vars}) local cmd = Cmd:new(line,FNWR,{func=fname,args=args,vars=vars})
function cmd:tostring() function cmd:tostring()
return table.concat({fname,table.concat(args,", ")},", ").." -> ".. table.concat(vars,", ") return table.concat({fname,table.concat(args,"\0, ")},"\0, ").."\0, ".. table.concat(vars,"\0, ").."\0"
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end
@ -858,18 +912,17 @@ function parser:parseASGN(line)
assigns = self:split(assigns) assigns = self:split(assigns)
local list = {} local list = {}
for i,v in ipairs(vars) do for i,v in ipairs(vars) do
table.insert(list,Value:new(v,assigns[i])) table.insert(list,{tostring(assigns[i]).."\0",v.."\0"})
end end
local cmd = Cmd:new(line,ASGN,list) local cmd = Cmd:new(line,ASGN,list)
function cmd:tostring() function cmd:tostring()
local str = "" local str = ""
for i,v in ipairs(self.args) do for i,v in ipairs(self.args) do
str = str .. "(" .. tostring(v) .. " -> ".. v.name ..")" .. ", " str = str .. "(" .. tostring(v[1]) .. ", ".. v[2] ..")" .. ", "
end end
return str:sub(1,-3) return str:sub(1,-3)
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
-- TODO: make dict lookups builtin
end end
function parser:parseLABL(line) function parser:parseLABL(line)
local label = line[5]:match("::(.+)::") local label = line[5]:match("::(.+)::")
@ -878,7 +931,7 @@ function parser:parseLABL(line)
end end
local cmd = Cmd:new(line,LABL,{label = label}) local cmd = Cmd:new(line,LABL,{label = label})
function cmd:tostring() function cmd:tostring()
return self.args.label return self.args.label.."\0"
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end
@ -887,7 +940,7 @@ function parser:parseDialogue(line)
if #targ == 0 then targ = nil end if #targ == 0 then targ = nil end
local cmd = Cmd:new(line,DISP,{text=text,target=targ}) local cmd = Cmd:new(line,DISP,{text=text,target=targ})
function cmd:tostring() function cmd:tostring()
return table.concat({targ or "@",text},", ") return table.concat({targ or "@",text},"\0, ").."\0"
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end

View File

@ -3,7 +3,7 @@ Value.__index = Value
local c = string.char local c = string.char
local types = { local types = {
string = c(0x0), string = c(0x0),
lookup = "", lookup = c(0x1),
boolean = c(0x2), boolean = c(0x2),
table = c(0x3), table = c(0x3),
number = c(0x4) number = c(0x4)

BIN
dump.dat

Binary file not shown.

View File

@ -16,7 +16,11 @@ using extendedDefine as
tester = "Hello" tester = "Hello"
list,test = {{1,2+food,3},true,tester,123,"This is a string!",false, {3,2,1}},5 food = 3
hi = {1,2,3}
list,test = {{1,2+food,hi[3]},true,tester,123,"This is a string!",false, {3,2,1}},5
a = list[1] a = list[1]
/* /*
heheheh heheheh