Added logic and restructured labels

This commit is contained in:
= 2020-06-05 13:41:52 -04:00
parent a6a16e614a
commit 4669f33760
8 changed files with 629 additions and 141 deletions

View File

@ -421,7 +421,9 @@ function Interpreter:new(parser)
end end
function c:visit_BinOp(node) function c:visit_BinOp(node)
if node.op.type == PLUS then if node.op.type == PLUS then
return self:visit(node.left) + self:visit(node.right) local a,b = self:visit(node.left),self:visit(node.right)
print("ADD ",a,b)
return a + b
elseif node.op.type == MINUS then elseif node.op.type == MINUS then
return self:visit(node.left) - self:visit(node.right) return self:visit(node.left) - self:visit(node.right)
elseif node.op.type == MUL then elseif node.op.type == MUL then
@ -450,31 +452,25 @@ end
text = [[ text = [[
BEGIN BEGIN
BEGIN ret := 11+a;
number := 2;
a := number;
b := 10 * a + 10 * number / 4;
c := a - - b
END;
x := 11;
END. END.
]] ]]
lexer = Lexer:new(text) lexer = Lexer:new(text)
parser = Parser:new(lexer) parser = Parser:new(lexer)
interpreter = Interpreter:new(parser) interpreter = Interpreter:new(parser)
tprint(parser) interpreter.GLOBAL_SCOPE = {a=100}
-- interpreter:interpret() interpreter:interpret()
-- for i,v in pairs(interpreter.GLOBAL_SCOPE) do for i,v in pairs(interpreter.GLOBAL_SCOPE) do
-- print(i,v) print(i,v)
-- end end
-- while true do while true do
-- io.write("calc> ") io.write("calc> ")
-- local text = io.read() local text = io.read()
-- if text then if text then
-- lexer = Lexer:new(text) lexer = Lexer:new(text)
-- parser = Parser:new(lexer) parser = Parser:new(lexer)
-- interpreter = Interpreter:new(parser) interpreter = Interpreter:new(parser)
-- result = interpreter:interpret() result = interpreter:interpret()
-- print(result) print(result)
-- end end
-- end end

View File

@ -15,13 +15,13 @@ function Chunk:new(cname,ctype,filename)
c.chunkname = cname c.chunkname = cname
c.chunktype = ctype c.chunktype = ctype
c.filename = filename c.filename = filename
c.variables = {}
c.pos = 0 c.pos = 0
c.cmds = {} c.cmds = {}
c.labels = {} -- ["label"] = pos
return c return c
end end
function Chunk:addLabel(label) function Chunk:addVariable(value)
self.labels[label] = self:count() self.varaiables[value.name] = value.value
end end
function Chunk:addCmd(cmd) function Chunk:addCmd(cmd)
cmd.chunk = self cmd.chunk = self

8
dms/expr.lua Normal file
View File

@ -0,0 +1,8 @@
local Expr = {}
Expr.__index = Expr
function Expr:new(expr)
local c = {}
setmetatable(c,self)
return c
end

View File

@ -1,8 +1,10 @@
require("dms.utils") require("dms.utils")
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 ENTR,ENAB,DISA,LOAD,VERN,USIN,STAT,DISP,ASGN,LABL,CHOI,OPTN,FORE,UNWN,WHLE,FNWR,FNNR,IFFF,ELIF,ELSE,DEFN = "ENTR","ENAB","DISA","LOAD","VERN","USIN","STAT","DISP","ASGN","LABL","CHOI","OPTN","FORE","????","WHLE","FNWR","FNNR","IFFF","ELIF","ELSE","DEFN" local Value = require("dms.value")
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 = "ENTR","ENAB","DISA","LOAD","VERN","USIN","STAT","DISP","ASGN","LABL","CHOI","OPTN","FORE","????","WHLE","FNWR","FNNR","IFFF","ELIF","ELSE","DEFN","SKIP","COMP","INDX","JMPZ"
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 = {
@ -103,6 +105,137 @@ function parser:isRecognizedFlag(flag)
end end
return false return false
end end
function parser:split(s,pat,l)
local pat=pat or ","
local res = {}
local start = 1
local state = 0
local c = '.'
local elem = ''
local function helper()
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 function next()
counter = counter + 1
return s:sub(counter,counter)
end
local function peek()
return s:sub(counter + 1,counter + 1)
end
local function getarr()
local a = peek()
local str = ""
local open = 1
while open~=0 and a~="" do
a = next()
if a == "{" then
open = open+1
end
if a == "}" then
open = open-1
if open == 0 then
next()
return str
end
end
str = str .. a
a = peek()
end
next()
return str
end
c = true
while c~="" do
c = next()
if state == 0 or state == 3 then -- start state or space after comma
if state == 3 and c == ' ' then
state = 0 -- skipped the space after the comma
else
state = 0
if c == '"' or c=="'" then
state = 1
elem = elem .. '"'
elseif c=="{" then
local t = self:split(getarr(),nil,true)
res[#res + 1] = t
elem = ''
state = 3
elseif c == pat then
helper()
res[#res + 1] = elem
elem = ''
state = 3 -- skip over the next space if present
elseif c == "(" then
state = 1
elem = elem .. '('
else
elem = elem .. c
end
end
elseif state == 1 then -- inside quotes
if c == '"' or c=="'" then --quote detection could be done here
state = 0
elem = elem .. '"'
elseif c=="}" then
state = 0
elem = elem .. '}'
elseif c==")" then
state = 0
elem = elem .. ')'
elseif c == '\\' then
state = 2
else
elem = elem .. c
end
elseif state == 2 then -- after \ in string
elem = elem .. c
state = 1
end
end
helper()
if elem ~= "" then
res[#res + 1] = elem
end
if l then
setmetatable(res,{
__tostring = function(self)
local str = "{"
for i,v in ipairs(self) do
str = str .. tostring(v) .. ", "
end
return str:sub(1,-3).."}"
end
})
else
setmetatable(res,{
__tostring = function(self)
local str = "("
for i,v in ipairs(self) do
str = str .. tostring(v) .. ", "
end
return str:sub(1,-3)..")"
end
})
end
return res
end
function parser:parse() function parser:parse()
local link = self local link = self
local line_num = 0 local line_num = 0
@ -158,6 +291,7 @@ function parser:parse()
end end
if line=="" then goto continue end if line=="" then goto continue end
::back:: ::back::
self.current_lineStats = {line_num,self.filename}
if line:match("^%[[_:,%w%(%)]+%]") then if line:match("^%[[_:,%w%(%)]+%]") then
groupStack:append{line_num,group,STAT,self.filename,line:trim()} groupStack:append{line_num,group,STAT,self.filename,line:trim()}
noblock = false noblock = false
@ -191,20 +325,20 @@ function parser:parse()
else else
goto back goto back
end end
elseif line:match("[%s,_%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:match(".-%(.+%)") then
groupStack:append{line_num,group,FNNR,self.filename,line:trim()}
elseif line:match("[%s,_%w]*=(.+)") then
groupStack:append{line_num,group,ASGN,self.filename,line:trim()}
elseif line:match("\"(.+)\"") then
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()}
elseif line:match("if%s*(.+)") then elseif line:match("if%s*(.+)") then
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("[%s,%$_%w]*=(.+)") then
groupStack:append{line_num,group,ASGN,self.filename,line:trim()}
elseif line:match("[%l_][%w_]-%(.+%)") then
groupStack:append{line_num,group,FNNR,self.filename,line:trim()}
elseif line:match("\"(.+)\"") then
groupStack:append{line_num,group,DISP,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()}
end end
@ -240,8 +374,10 @@ function parser:parse()
if chunks[cname] then self:error("Chunk \""..cname.."\" has already been defined!",v) end if chunks[cname] then self:error("Chunk \""..cname.."\" has already been defined!",v) end
elseif v[3] == CHOI then elseif v[3] == CHOI then
self:parseChoice(v) self:parseChoice(v)
elseif v[3] == IFFF then
self:parseIFFF(v)
else else
--print("CTRL",table.concat(v,"\t")) print("CTRL",table.concat(v,"\t"))
end end
else else
if v[3] == DISP then if v[3] == DISP then
@ -253,9 +389,9 @@ function parser:parse()
elseif v[3] == ASGN then elseif v[3] == ASGN then
self:parseASGN(v) self:parseASGN(v)
elseif v[3] == LABL then elseif v[3] == LABL then
self.current_chunk:addLabel(v[5]:match("::(.+)::")) self:parseLABL(v)
end end
--print("FUNC",table.concat(v,"\t")) print("FUNC",table.concat(v,"\t"))
end end
v = self:next() v = self:next()
end end
@ -266,19 +402,356 @@ function parser:parse()
print(i,v) print(i,v)
end end
end end
local EQ,GTE,LTE,NEQ,GT,LT = "=",char(242),char(243),char(247),">","<"
function parser:parseIFFF(line)
print(line[5])
print(self:logicChop(line[5]))
end
function parser:buildLogic(l,o,r,v)
local cmd = Cmd:new({self.current_lineStats[1],0,COMP,self.current_lineStats[2],"?"},COMP,{left=l,op=o,right=r,var=v})
function cmd:tostring()
return table.concat({self.args.op,tostring(self.args.left),tostring(self.args.right)},", ").." -> "..self.args.var
end
self.current_chunk:addCmd(cmd)
end
function parser:buildIndex(name,ind,v)
local cmd = Cmd:new({self.current_lineStats[1],0,INDX,self.current_lineStats[2],"?"},INDX,{name = name, index = ind, var = v})
function cmd:tostring()
return table.concat({tostring(self.args.name),tostring(self.args.index)},", ").." -> "..self.args.var
end
self.current_chunk:addCmd(cmd)
end
function parser:logicChop(expr)
expr = expr:gsub("([_%w]+)(%b())",function(func,args)
local v = gen("$")
print(v.." = "..func..args)
local fnwr = {self.current_lineStats[1],0,FWNR,self.current_lineStats[2],v.." = "..func..args}
self:parseFNWR(fnwr)
return v
end)
local counter = 0
local v
local function next()
counter = counter + 1
return expr:sub(counter,counter)
end
local function prev()
counter = counter - 1
end
local function peek()
return expr:sub(counter + 1,counter + 1)
end
local c = "."
local l,o,r = '','',''
local state = 0
local start = 1
local elem = ""
local function setOp(op)
if l~='' then
o = op
else
self:error("Invalid Syntax 2")
end
end
local function index(right)
local ind = ""
c = peek()
while c ~= "]" do
next()
ind = ind..c
c = peek()
end
c = next()
if right then
local vv = gen("$")
v = gen("$")
r = right
self:buildIndex(r,ind,vv)
self:buildLogic(l,o,vv,v)
l,o,r = '','',''
elem = elem .. v
elseif l~= "" and r=="" then
v = gen("$")
print(l.."["..ind.."] -> "..v)
l = v
end
if not(c=="]") then
self:error("']' expected to close '['")
end
end
local function default()
if c == "=" and peek()=="=" then
next() -- eat second =
setOp(EQ)
elseif c == ">" and peek()=="=" then
next()
setOp(GTE)
elseif c == "<" and peek()=="=" then
next()
setOp(LTE)
elseif c == "!" or c == "~" and peek()== "=" then
next()
setOp(NEQ)
elseif c == "<" then
setOp(LT)
elseif c == ">" then
setOp(GT)
elseif c == "[" then -- handle index stuff
index()
elseif c == "o" and peek()=="r" then
next()
elem = elem .. "+"
elseif c == "a" and peek()=="n" then
if next() == "n" and peek()=="d" then
next()
elem = elem .. "*"
else
--self:error("Invalid syntax!"..c) -- Grab the current line
end
elseif c == "i" and peek()=="f" then
next()
elseif c == ' ' then
-- Ignore white space if not part of a string
elseif isDigit(c) then
local dot = false
prev()
c = peek()
local digit = ""
while isDigit(c) or (dot==false and c==".") do
next()
if c=="." then
dot = true
digit = digit .. "."
elseif isDigit(c) then
digit = digit .. c
end
c = peek()
end
digit = tonumber(digit)
if l=="" then
l = digit
elseif r=="" then
r = digit
v = gen("$")
self:buildLogic(l,o,r,v)
l,o,r = '','',''
elem = elem .. v
end
elseif isLetter(c) then
if l=='' then
l=c
local k = peek()
while isLetter(k) or isDigit(k) do
next()
l=l..k
k = peek()
end
if l == "true" then
l = true
elseif l == "false" then
l = false
else
l = "\1" .. l
end
elseif o~= '' then
r=c
local k = peek()
while isLetter(k) or isDigit(k) do
next()
r=r..k
k = peek()
end
if k == "[" then
next()
index(r)
else
if r == "true" then
r = true
elseif r == "false" then
r = false
else
r = "\1" .. r
end
v = gen("$")
self:buildLogic(l,o,r,v)
l,o,r = '','',''
elem = elem .. v
end
else
print(l,o,r)
self:error("Invalid syntax!")
end
else
elem = elem .. c
end
end
local str = ""
while c~="" do
c = next()
if c == '"' then
c = peek()
str = ""
while c~="\"" do
next()
if c=="\\" and peek()=="\"" then
next()
str = str .. "\""
else
str = str .. c
end
c = peek()
end
if l=="" then
l = str
elseif r=="" then
r = str
v = gen("$")
self:buildLogic(l,o,r,v)
l,o,r = '','',''
elem = elem .. v
end
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
if l=="" then
l = str
elseif r=="" then
r = str
v = gen("$")
self:buildLogic(l,o,r,v)
l,o,r = '','',''
elem = elem .. v
end
next()
else
default()
end
end
return elem
end
function parser:chop(expr)
for l,o,r in expr:gmatch("(.-)([/%^%+%-%*%%])(.+)") do
if r:match("(.-)([/%^%+%-%*%%])(.+)") then
local v = gen("$")
--print(l,o,self:chop(r),"->",v)
self:buildMFunc(l,o,self:chop(r),v)
return v
else
local v = gen("$")
--print(l,o,r,"->",v)
self:buildMFunc(l,o,r,v)
return v
end
end
end
function parser:buildMFunc(l,o,r,v)
local fnwr = {self.current_lineStats[1],0,FWNR,self.current_lineStats[2]}
local line
if o == "+" then
line = v.." = ADD("..table.concat({l,r},",")..")"
elseif o == "-" then
line = v.." = SUB("..table.concat({l,r},",")..")"
elseif o == "*" then
line = v.." = MUL("..table.concat({l,r},",")..")"
elseif o == "/" then
line = v.." = DIV("..table.concat({l,r},",")..")"
elseif o == "%" then
line = v.." = MOD("..table.concat({l,r},",")..")"
elseif o == "^" then
line = v.." = POW("..table.concat({l,r},",")..")"
else
-- Soon we will allow for custom symbols for now error
end
table.insert(fnwr,line)
self:parseFNWR(fnwr)
end
function parser:parseExpr(expr)
-- handle pharanses
expr=expr:gsub("([%W])(%-%d)",function(b,a)
return b.."(0-"..a:match("%d+")..")"
end)
-- Work on functions
expr = expr:gsub("([_%w]+)(%b())",function(func,args)
local v = gen("$")
local fnwr = {self.current_lineStats[1],0,FWNR,self.current_lineStats[2],v.." = "..func..args}
self:parseFNWR(fnwr)
return v
end)
expr = expr:gsub("(%b())",function(a)
return self:parseExpr(a:sub(2,-2))
end)
return self:chop(expr)
end
function parser:parseChoice(line)
local text = line[5]:match("\"(.+)\"")
local copt = self:peek()
local choice = {text = text,options = {}}
local cmd = Cmd:new(line,CHOI,choice)
function cmd:tostring()
return "\""..self.args.text.."\" {"..table.concat(self.args.options,", ").."}"-- disp choices
end
self.current_chunk:addCmd(cmd)
if copt[3]~=OPTN then
self:error("Choices must have at least one option to choose!")
return
end
local opts = {}
while copt do
copt = self:next()
local a,b = copt[5]:match("(.+) %s*(.+)")
table.insert(choice.options,a)
table.insert(opts,b)
copt = self:peek()
if copt[3]~=OPTN then
break
end
end
local s = ((#opts-1)*2-1)
local c = s
for i=1,#opts do
self:parseFNNR({copt[1],copt[2],FNNR,copt[4],opts[i]})
if i~=#opts then
self:parseFNNR({copt[1],copt[2],FNNR,copt[4],"SKIP(".. c ..")"})
end
c=c-2
end
end
function parser:parseFNNR(line) function parser:parseFNNR(line)
local fname, args = line[5]:match("(.-)%((.+)%)") local fname, args = line[5]:match("(.-)%((.*)%)")
args = args:split() if #args==0 then
args = {}
else
args = self:split(args)
end
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()
return table.concat({fname,table.concat(args,", ")},", ") if #args==0 then
return fname
else
return table.concat({fname,table.concat(args,", ")},", ")
end
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
end end
function parser:parseFNWR(line) function parser:parseFNWR(line)
local vars, fname, args = line[5]:match("(.-)%s*=%s*(.-)%((.+)%)") local vars, fname, args = line[5]:match("(.-)%s*=%s*(.-)%((.+)%)")
vars = vars:split() vars = self:split(vars)
args = args:split() if #args==0 then
args = {}
else
args = self:split(args)
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,", ")},", ").." -> ".. table.concat(vars,", ")
@ -287,34 +760,33 @@ function parser:parseFNWR(line)
end end
function parser:parseASGN(line) function parser:parseASGN(line)
local vars,assigns = line[5]:match("(.-)%s*=%s*(.+)") local vars,assigns = line[5]:match("(.-)%s*=%s*(.+)")
vars = vars:split() vars = self:split(vars)
assigns = assigns:split() assigns = self:split(assigns)
local cmd = Cmd:new(line,ASGN,{vars = vars, assigns = assigns}) local list = {}
for i,v in ipairs(vars) do
table.insert(list,Value:new(v,assigns[i]))
end
local cmd = Cmd:new(line,ASGN,list)
function cmd:tostring() function cmd:tostring()
return "DATA -> "..table.concat(vars,", ") local str = ""
for i,v in ipairs(self.args) do
str = str .. "(" .. tostring(v) .. " -> ".. v.name ..")" .. ", "
end
return str:sub(1,-3)
end end
self.current_chunk:addCmd(cmd) self.current_chunk:addCmd(cmd)
-- TODO: make dict lookups builtin -- TODO: make dict lookups builtin
end end
function parser:parseChoice(line) function parser:parseLABL(line)
local text = line[5]:match("\"(.+)\"") local label = line[5]:match("::(.+)::")
local copt = self:peek() if not label then
local choice = {text = text} self:error("Invalid Label Definition",line)
local cmd = Cmd:new(line,CHOI,choice)
if copt[3]~=OPTN then
self:error("Choices must have at least one option to choose!")
return
end end
while copt do local cmd = Cmd:new(line,LABL,{label = label})
copt = self:next() function cmd:tostring()
local a,b = copt[5]:match("(.+) %s*(.+)") return self.args.label
print(a,"|",b)
copt = self:peek()
if copt[3]~=OPTN then
break
end
end end
-- We need to get functions working first self.current_chunk:addCmd(cmd)
end end
function parser:parseDialogue(line) function parser:parseDialogue(line)
local targ,text = line[5]:match("(%w*)%s*(.*)") local targ,text = line[5]:match("(%w*)%s*(.*)")

View File

@ -1,4 +1,37 @@
-- Utils modify the global enviroment -- Utils modify the global enviroment
local symcount = {}
local syms = {}
for i=65,90 do
syms[#syms+1] = string.char(i)
end
for i=97,122 do
syms[#syms+1] = string.char(i)
end
local count = #syms+1
function gen(symbol,flush)
if flush == true then
symcount[symbol] = {1, 0}
return
end
symbol = symbol or "__"
if symcount[symbol] then
symcount[symbol][2] = symcount[symbol][2] + 1
if symcount[symbol][2]%count==0 then
symcount[symbol][2] = 1
symcount[symbol][1] = symcount[symbol][1] + 1
end
return symbol .. syms[symcount[symbol][1]%count]..syms[symcount[symbol][2]%count]
else
symcount[symbol] = {1, 0}
return gen(symbol)
end
end
function isLetter(c)
return c:lower():match("[%$_%l]")
end
function isDigit(c)
return c:lower():match("%d")
end
function string.tabs(str) function string.tabs(str)
local c = 0 local c = 0
for i in str:gmatch(".") do for i in str:gmatch(".") do
@ -21,80 +54,9 @@ function tprint (tbl, indent)
print(formatting) print(formatting)
tprint(v, indent+1) tprint(v, indent+1)
elseif type(v) == 'boolean' then elseif type(v) == 'boolean' then
print(formatting .. tostring(v)) print(formatting .. "<" .. type(v).. ">" .. tostring(v))
else else
print(formatting .. v) print(formatting .. "<" .. type(v).. ">" .. tostring(v))
end end
end end
end
function string.split(s,pat)
local pat=pat or ","
local res = {}
local start = 1
local state = 0
local c = '.'
local elem = ''
local function helper()
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 = elem:sub(2,-2):split()
else
elem = "\1"..elem
end
end
for i = 1, #s do
c = s:sub(i, i)
if state == 0 or state == 3 then -- start state or space after comma
if state == 3 and c == ' ' then
state = 0 -- skipped the space after the comma
else
state = 0
if c == '"' or c=="'" then
state = 1
elem = elem .. '"'
elseif c=="{" then
state = 1
elem = elem .. '{'
elseif c == pat then
helper()
res[#res + 1] = elem
elem = ''
state = 3 -- skip over the next space if present
elseif c == "(" then
state = 1
elem = elem .. '('
else
elem = elem .. c
end
end
elseif state == 1 then -- inside quotes
if c == '"' or c=="'" then --quote detection could be done here
state = 0
elem = elem .. '"'
elseif c=="}" then
state = 0
elem = elem .. '}'
elseif c==")" then
state = 0
elem = elem .. ')'
elseif c == '\\' then
state = 2
else
elem = elem .. c
end
elseif state == 2 then -- after \ in string
elem = elem .. c
state = 1
end
end
helper()
res[#res + 1] = elem
return res
end end

33
dms/value.lua Normal file
View File

@ -0,0 +1,33 @@
local Value = {}
Value.__index = Value
local c = string.char
local types = {
string = c(0x0),
lookup = "",
boolean = c(0x2),
table = c(0x3),
number = c(0x4)
}
function Value:__tostring()
local t = self.type
return types[t]..tostring(self.value)
end
function Value:new(name,value)
local c = {}
setmetatable(c,self)
c.type = type(value)
c.value = value
if c.type=="string" and c.value:sub(1,1)=="\1" then
c.type = "lookup"
end
c.name = name
return c
end
function Value:set(value)
self.type = type(value)
self.value = value
end
function Value:get()
return self.value
end
return Value

View File

@ -13,8 +13,10 @@ using extendedDefine as
Ryan "Hello how are you doing?" // this is a comment Ryan "Hello how are you doing?" // this is a comment
Bob "I'm good you?" Bob "I'm good you?"
tester = "Hello"
list = {1,2,3},true,"This is a string!",false, {3,2,1} list,test = {{1,2+food,3},true,tester,123,"This is a string!",false, {3,2,1}},5
a = list[1] a = list[1]
/* /*
heheheh heheheh
@ -22,15 +24,19 @@ using extendedDefine as
ghgfh ghgfh
kjuty kjuty
*/ */
hungry = (-2+4-((5*5)/sqrt(144+5)))^2*2+2
list[1] = "Hello" list[1] = "Hello"
var1,var2 = func(1,"string", 2+5) var1,var2 = func(1,"string", 2+5)
func(1,"string", 2+5) a = 100 + func(1,"string", 2+5) + 100
func(1,"string", 2+5)
::label:: ::label::
//Hello im testing stuff //Hello im testing stuff
choice "Pick one:" choice "Pick one:"
"first" func() "first" func()
"second" func() "second" func()
"third" func() "third" func()
"forth" func()
for x = 1,10 for x = 1,10
for y = 1,10 for y = 1,10
@ -43,8 +49,8 @@ using extendedDefine as
while cond while cond
... ...
if cond if (func(123)!=name[1] or true == "Bob") and foodCount >= 10.34
... "test=true or test2=false!"
elseif cond elseif cond
... ...
else else

11
test.lua Normal file
View File

@ -0,0 +1,11 @@
package.path="?.lua;?/init.lua;?.lua;?/?/init.lua;"..package.path
require("dms.utils")
--require("dms.parser")
parser = {}
print(parser:logicChop([[if (func(123)!=name[1] or true == "Bob") and foodCount >= 10.34]]))
-- function parser:parseLogic(expr)
-- expr = expr:gsub("")
-- end
-- print(parser:parseLogic([[if (name=="Ryan" or name == "Bob") and foodCount >= 10]]))