added utiliy module, turned test script into unit tests

This commit is contained in:
theFox6 2020-02-14 08:45:49 +01:00
parent 38c5dc9339
commit 28b67d2833
Signed by: theFox6
GPG Key ID: C884FE8D3BCE128A
5 changed files with 382 additions and 225 deletions

View File

@ -24,8 +24,8 @@ end
```
### comments
for comments --, // and ## can be used
if something follows a -- it will always be treated as comment
for comments `--`, `//` and `##` can be used
if something follows a `--` it will always be treated as comment
### curly braces
The `do`,`then` and `end` statements can be replaced by curly brace syntax.
@ -181,7 +181,7 @@ It returns a function that runs the generated lua.
It's argument can be a relative or absolute path to the file that should be translated.
It returns the generated lua as string.
##todo
## todo
- generate lua from a venus string
- perhaps write generated lua files to disk
- perhaps generate venus from lua

236
init.lua
View File

@ -1,3 +1,5 @@
local vp_util = dofile("vp_util.lua")
local parser = {}
local elements = {
@ -9,44 +11,12 @@ local elements = {
lambda_args = "[,%(%)]"
}
--FIXME: do not parse in single line comments
local non_space_elements = {elements.special_combined,elements.special,elements.strings}
function parser.warn(msg)
print("VenusParser warning: " .. msg)
end
--FIXME: allow multiple paterns
local function optmatch(str,pat)
local cutstr = str
return function()
if not cutstr then return end
local spos,epos = cutstr:find(pat)
local match
local found = (spos == 1)
if found then
match = cutstr:sub(spos,epos)
cutstr = cutstr:sub(epos+1)
--print("f",match,cutstr,pat)
elseif not spos then
match = cutstr
cutstr = nil
--print("n",match,pat)
else
match = cutstr:sub(1,spos-1)
cutstr = cutstr:sub(spos)
--print("p",match,cutstr,pat)
end
return match, found
end
end
function parser.test_optmatch()
assert(optmatch("123","123")() == "123")
assert(optmatch("123","321")() == "123")
assert(optmatch("123","1")() == "1")
assert(optmatch("123","2")() == "1")
end
--TODO: make some functions handling each group of commands
local function parse_element(el,pc)
if el == "" then
@ -72,8 +42,10 @@ local function parse_element(el,pc)
pc.deccheck = false
pc.optassign = false
if cpos == true then
pc.slcomm = true
return "--"..el
else
pc.slcomm = true
return "--"..cpos..el
end
end
@ -221,6 +193,7 @@ local function parse_element(el,pc)
end
elseif el == "//" or el=="##" then
if not pc.instring then
pc.slcomm = true
return "--",prefix
end
elseif el == "--" then
@ -228,6 +201,7 @@ local function parse_element(el,pc)
pc.deccheck = true
return "",prefix
else
pc.slcomm = true
return el,prefix
end
elseif el == "++" then
@ -296,7 +270,7 @@ end
local function parse_line(l,pc)
local pl = ""
local i = 0
for sp,s in optmatch(l,elements.spaces) do
for sp,s in vp_util.optmatch(l,elements.spaces) do
if s then
if pc.lambargs then
pc.lambargs = pc.lambargs .. sp
@ -315,79 +289,79 @@ local function parse_line(l,pc)
end
end
else
for sc in optmatch(sp,elements.special_combined) do
for ss in optmatch(sc,elements.special) do
for st in optmatch(ss,elements.strings) do
local el,pre = parse_element(st,pc)
local lpre
if pre then
while pre:match("\n") do
if lpre then
lpre = lpre .. pre:sub(1,pre:find("\n"))
else
lpre = pre:sub(1,pre:find("\n"))
end
pre = pre:sub(pre:find("\n")+1)
end
local pres = pre:match("^%s*") or ""
if lpre then
lpre = lpre .. pres
else
lpre = pres
end
pre = pre:sub(#pres+1)
--[[
if (pre ~= "") then
print("pre:".. pre..":")
else
print("prel:" .. el)
end
--]]
if el == "" then
el = pre
elseif pre ~= "" then
el = pre .. " " .. el
end
end
if pc.newlamb then
if pc.lambargs then
el = pc.lambargs .. el
end
pc.lambargs = pc.newlamb
pc.newlamb = false
--print("newl:", pc.lambargs, el)
elseif pc.lambargs then
if el:match(elements.names) or el:match(elements.lambda_args) then
pc.lambargs = pc.lambargs .. el
el = ""
elseif el ~= "" then
el = pc.lambargs .. el
pc.lambargs = false
pc.lambend = false
--print("notl:", el)
end
end
if pc.optassign and el ~= "" then
if pc.linestart and el:match(elements.names) then
if pc.optassign == true then
pc.optassign = el
else
pc.optassign = pc.optassign .. el
end
elseif el ~= "--" then
pc.optassign = false
end
end
if lpre then
pl = pl .. lpre .. el
for st in vp_util.optmatch(sp,non_space_elements) do
if pc.slcomm then
pl = pl .. st
else
pl = pl .. el
local el,pre = parse_element(st,pc)
local lpre
if pre then
while pre:match("\n") do
if lpre then
lpre = lpre .. pre:sub(1,pre:find("\n"))
else
lpre = pre:sub(1,pre:find("\n"))
end
pre = pre:sub(pre:find("\n")+1)
end
local pres = pre:match("^%s*") or ""
if lpre then
lpre = lpre .. pres
else
lpre = pres
end
pre = pre:sub(#pres+1)
--[[
if (pre ~= "") then
print("pre:".. pre..":")
else
print("prel:" .. el)
end
--]]
if el == "" then
el = pre
elseif pre ~= "" then
el = pre .. " " .. el
end
end
if pc.newlamb then
if pc.lambargs then
el = pc.lambargs .. el
end
pc.lambargs = pc.newlamb
pc.newlamb = false
--print("newl:", pc.lambargs, el)
elseif pc.lambargs then
if el:match(elements.names) or el:match(elements.lambda_args) then
pc.lambargs = pc.lambargs .. el
el = ""
elseif el ~= "" then
el = pc.lambargs .. el
pc.lambargs = false
pc.lambend = false
--print("notl:", el)
end
end
if pc.optassign and el ~= "" then
if pc.linestart and el:match(elements.names) then
if pc.optassign == true then
pc.optassign = el
else
pc.optassign = pc.optassign .. el
end
elseif el ~= "--" then
pc.optassign = false
end
end
if lpre then
pl = pl .. lpre .. el
else
pl = pl .. el
end
if pc.linestart then
pc.linestart = false
end
end
if pc.linestart then
pc.linestart = false
end
end
end
end
end
end
@ -403,29 +377,34 @@ function parser.translate_venus(file)
pc.linestart = true
pc.optassign = true
fc = fc .. parse_line(l,pc)
if pc.ifend then
if pc.linestart then
fc = fc .. pc.ifend
else
fc = fc .. " " .. pc.ifend
end
pc.ifend = false
end
if pc.deccheck then
if pc.optassign == false then
pc.deccheck = false
elseif pc.optassign == true then
pc.deccheck = false
else
fc = fc .. " = " .. pc.optassign .. " - 1"
pc.deccheck = false
pc.optassign = false
end
end
if pc.lambargs then
pc.lambargs = pc.lambargs .. "\n"
else
if pc.slcomm then
pc.slcomm = false
fc = fc .. "\n"
else
if pc.ifend then
if pc.linestart then
fc = fc .. pc.ifend
else
fc = fc .. " " .. pc.ifend
end
pc.ifend = false
end
if pc.deccheck then
if pc.optassign == false then
pc.deccheck = false
elseif pc.optassign == true then
pc.deccheck = false
else
fc = fc .. " = " .. pc.optassign .. " - 1"
pc.deccheck = false
pc.optassign = false
end
end
if pc.lambargs then
pc.lambargs = pc.lambargs .. "\n"
else
fc = fc .. "\n"
end
end
end
if (#pc.opencurly > 0) then
@ -451,7 +430,4 @@ function parser.dovenus(file)
return ff()
end
-- in case anybody wants to use it too
parser.optmatch = optmatch
return parser

View File

@ -1,93 +1,130 @@
print("venus test")
print("running venus test script")
local testt = {
venus = "awesome",
"lots of test",1,2,
test2 = "hi"
}
local vp_util = dofile("vp_util.lua")
local a = 0
local function for_range_test()
local a = 0
for i = 0,5 do
a = a + i
for i = 0,5 do
a = a + i
end
assert(a == 15)
end
assert(a == 15)
for_range_test()
for i,el in pairs(testt) do
print(i.." = "..el)
local function for_in_test()
local testt = {
venus = "awesome",
"lots of test",1,2,
test2 = "hi"
}
local reft = {}
for i,el in pairs(testt) do
reft[i] = el
end
assert(vp_util.dftc(reft, testt))
reft = {}
for _,el in pairs(testt) do
table.insert(reft,el)
end
local reft2 = {}
foreach el in testt do
table.insert(reft2,el)
end
assert(vp_util.dftc(reft, reft2))
end
foreach el in testt do
print(el)
end
for_in_test()
// comment
## comment
// comments
## yay a comment
//comment
assert("//"=="/".."/")
-- comment
-- another comment
assert([[
##]]=="#".."#","comment within [[string]] falsely detected")
fn a()
return "function"
end
assert(a()=="function")
assert([[
fn]]=="f".."n")
do
(fn(...)
local a = {...}
foreach a in a do
print(a)
end
end)("a","still a","also a")
local function shadow_test()
local fn a()
return "function"
end
assert(a()=="function")
local reft = {}
do
(fn(...)
local a = {...}
foreach a in a do
table.insert(reft,a)
end
end)("a","still a","also a")
end
assert(vp_util.dftc(reft, {"a","still a","also a"}))
local n
{
local a = 12
n = a
}
assert(n == 12)
assert(a()=="function")
end
{
local a = 12
print(a)
}
a()
shadow_test()
function t() {
local function t() {
return "hi"
}
assert(t()=="hi")
fn t2() {
local fn t2() {
return "also hi"
}
assert(type(t2)=="function")
assert(t2()=="also hi")
local b = true
if (true) {
print("weewoo")
b = "weewoo"
}
assert(b == "weewoo")
local reft = {}
for i = 0, 10 {
print(i)
table.insert(reft,i)
}
assert(vp_util.dftc(reft,{0,1,2,3,4,5,6,7,8,9,10}))
local reft2 = {}
foreach el in {"lot's of test",2,"3",1} {
print(el)
table.insert(reft2,el)
}
assert(vp_util.dftc(reft2,{"lot's of test",2,"3",1}))
{
local reft = {}
local i = 0
while i < 10 {
i = i + 1
if i%3 == 0 {
print(i)
table.insert(reft,i)
} elseif i%4 == 0 {
print(i/4)
table.insert(reft,i/4)
}
}
assert(vp_util.dftc(reft,{3,1,6,2,9}))
}
function callit(fun,t1,t2)
local function callit(fun,t1,t2)
return fun(t1,t2)
end
@ -110,6 +147,8 @@ assert(
}, 10, 6) == 16
)
assert(callit(()=>{},false)==nil)
---
--comment
--
@ -120,14 +159,14 @@ local j = 0
i = i + 1
j = j + 2
function decj()
local function decj()
j--
return j-- not a decrement, only returns n, this is a comment
end
assert(decj()==1)
assert(j == 1)
function reti()
local fn reti()
-- this only returns i the -- is a comment
return i--
end
@ -150,4 +189,4 @@ assert(j ==32)
j .=" test"
assert(j == "32 test")
print("test end")
print("venus test end")

View File

@ -1,93 +1,130 @@
print("venus test")
print("running venus test script")
local testt = {
venus = "awesome",
"lots of test",1,2,
test2 = "hi"
}
local vp_util = dofile("vp_util.lua")
local a = 0
local function for_range_test()
local a = 0
for i = 0,5 do
a = a + i
for i = 0,5 do
a = a + i
end
assert(a == 15)
end
assert(a == 15)
for_range_test()
for i,el in pairs(testt) do
print(i.." = "..el)
local function for_in_test()
local testt = {
venus = "awesome",
"lots of test",1,2,
test2 = "hi"
}
local reft = {}
for i,el in pairs(testt) do
reft[i] = el
end
assert(vp_util.dftc(reft, testt) )
reft = {}
for _,el in pairs(testt) do
table.insert(reft,el)
end
local reft2 = {}
for _, el in pairs(testt ) do
table.insert(reft2,el)
end
assert(vp_util.dftc(reft, reft2) )
end
for _, el in pairs(testt ) do
print(el)
end
for_in_test()
-- comment
-- comment
-- comments
-- yay a comment
--comment
assert("//"=="/".."/")
-- comment
-- another comment
assert([[
##]]=="#".."#","comment within [[string]] falsely detected")
function a()
return "function"
end
assert(a() =="function")
assert([[
fn]]=="f".."n")
do
(function(...)
local a = {...}
for _, a in pairs(a ) do
print(a)
end
end)("a","still a","also a")
local function shadow_test()
local function a()
return "function"
end
assert(a() =="function")
local reft = {}
do
(function(...)
local a = {...}
for _, a in pairs(a ) do
table.insert(reft,a)
end
end)("a","still a","also a")
end
assert(vp_util.dftc(reft, {"a","still a","also a"}))
local n
do
local a = 12
n = a
end
assert(n == 12)
assert(a() =="function")
end
do
local a = 12
print(a)
end
a()
shadow_test()
function t()
local function t()
return "hi"
end
assert(t() =="hi")
function t2()
local function t2()
return "also hi"
end
assert(type(t2) =="function")
assert(t2() =="also hi")
local b = true
if (true) then
print("weewoo")
b = "weewoo"
end
assert(b == "weewoo")
local reft = {}
for i = 0, 10 do
print(i)
table.insert(reft,i)
end
assert(vp_util.dftc(reft,{0,1,2,3,4,5,6,7,8,9,10}))
local reft2 = {}
for _, el in pairs({"lot's of test",2,"3",1} ) do
print(el)
table.insert(reft2,el)
end
assert(vp_util.dftc(reft2,{"lot's of test",2,"3",1}))
do
local reft = {}
local i = 0
while i < 10 do
i = i + 1
if i%3 == 0 then
print(i)
table.insert(reft,i)
elseif i%4 == 0 then
print(i/4)
table.insert(reft,i/4)
end
end
assert(vp_util.dftc(reft,{3,1,6,2,9}))
end
function callit(fun,t1,t2)
local function callit(fun,t1,t2)
return fun(t1,t2)
end
@ -110,6 +147,8 @@ assert(
end, 10, 6) == 16
)
assert(callit(function() end,false)==nil)
---
--comment
@ -120,14 +159,14 @@ local j = 0
i = i + 1
j = j + 2
function decj()
local function decj()
j = j - 1
return j-- not a decrement, only returns n, this is a comment
end
assert(decj() ==1)
assert(j == 1)
function reti()
local function reti()
-- this only returns i the -- is a comment
return i--
end
@ -150,4 +189,4 @@ assert(j ==32)
j = j .." test"
assert(j == "32 test")
print("test end")
print("venus test end")

103
vp_util.lua Normal file
View File

@ -0,0 +1,103 @@
local vp_util = {}
--TODO: documentation
function vp_util.find_min_match(str,patterns)
local pats
local patt = type(patterns)
if patt == "string" then
pats = {patterns}
elseif patt == "table" then
pats = patterns
else
error(("bad argument #2 to optmatch, expected string or table got %s"):format(patterns),2)
end
local minspos
local matchepos
for _, pat in pairs(pats) do
local spos,epos = str:find(pat)
if spos then
if not minspos then
minspos = spos
matchepos = epos
elseif spos < minspos then
minspos = spos
matchepos = epos
elseif spos == minspos then
if epos < matchepos then
minspos = spos
matchepos = epos
end
end
end
end
return minspos, matchepos
end
function vp_util.optmatch(str,patterns)
local cutstr = str
return function()
if not cutstr then return end
local spos, epos = vp_util.find_min_match(cutstr,patterns)
local match
local found = (spos == 1)
if found then
match = cutstr:sub(1,epos)
cutstr = cutstr:sub(epos+1)
--print("f",match,cutstr,pat)
elseif not spos then
if cutstr == "" then
match = nil
else
match = cutstr
end
cutstr = nil
--print("n",match,pat)
else
match = cutstr:sub(1,spos-1)
cutstr = cutstr:sub(spos)
--print("p",match,cutstr,pat)
end
return match, found
end
end
function vp_util.gen1_table(gen,...)
local tab = {}
for el in gen(...) do
table.insert(tab,el)
end
return tab
end
-- double_flat_table_compare
function vp_util.dftc(t1,t2)
for i,el in pairs(t1) do
if t2[i] ~= el then
return false
end
end
for i,el in pairs(t2) do
if t1[i] ~= el then
return false
end
end
return true
end
local function tests()
assert(vp_util.dftc({},{}))
assert(vp_util.dftc({1},{1}))
assert(not vp_util.dftc({1},{2}))
assert(vp_util.dftc({1,"2",true},{1,"2",true}))
assert(not vp_util.dftc({true,"1",1},{1,1,1}))
assert(vp_util.dftc(vp_util.gen1_table(vp_util.optmatch,"123","123"),{"123"}))
assert(vp_util.dftc(vp_util.gen1_table(vp_util.optmatch,"123","321"),{"123"}))
assert(vp_util.dftc(vp_util.gen1_table(vp_util.optmatch,"123", "1"), {"1","23"}))
assert(vp_util.dftc(vp_util.gen1_table(vp_util.optmatch,"123", "2"), {"1","2","3"}))
end
tests()
return vp_util