diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e7b26c4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libpreproc"] + path = libpreproc + url = git@github.com:lunaboards-dev/libpreproc.git diff --git a/libpreproc b/libpreproc new file mode 160000 index 0000000..af74760 --- /dev/null +++ b/libpreproc @@ -0,0 +1 @@ +Subproject commit af74760d6113fee5e509cc983163f140a674ae07 diff --git a/luacomp3/init.lua b/luacomp3/init.lua new file mode 100644 index 0000000..4f39ee6 --- /dev/null +++ b/luacomp3/init.lua @@ -0,0 +1,12 @@ +--@[[if false then]] +local parser = require("luacomp3.parser") +--@[[else]] +--#include "parser.lua" "parser" +--@[[end]] + +local p = setmetatable({}, {__index=parser}) +p:init() +local f = io.open(arg[1], "rb") +local d = f:read("a") +f:close() +p:parse(d) \ No newline at end of file diff --git a/luacomp3/parser.lua b/luacomp3/parser.lua new file mode 100644 index 0000000..cba2dff --- /dev/null +++ b/luacomp3/parser.lua @@ -0,0 +1,68 @@ +local lpp = require("libpreproc") +local p = function(a)return lpp.pattern(a, true)end +local parser = {} + +function parser:single_pass() + +end + +local span = lpp.block(p"[{", p"}]") +local block = lpp.block(p"[[", p"]]") +local parens = lpp.block(p"(", p")") +local luacode = lpp.pattern("@(%d*)") +local shellcode = p"$" +local directive = lpp.pattern("--#!*") + +function parser:init() + local parse = lpp.instance() + + --Lua code span + parse:add_token(lpp.prefix(luacode, span), function(stream, instance, result) + if #result.matches == 2 and result.matches[1] and result.matches[1] ~= "" then + result.matches.pass = tonumber(result.matches[1], 10) + if (result.matches.pass > 0) then + instance:emit(string.format("@%d[{%s}]", result.matches.pass, result.matches[2])) + return + end + end + instance:write(string.format("write(%s)", result.matches[#result.matches])) + end) + + -- Lua code block + parse:add_token(lpp.prefix(luacode, block), function(stream, instance, result) + --print("", table.unpack(result.matches)) + if #result.matches == 2 and result.matches[1] and result.matches[1] ~= "" then + result.matches.pass = tonumber(result.matches[1], 10) + if (result.matches.pass > 0) then + instance:emit(string.format("@%d[[%s]]", result.matches.pass, result.matches[2])) + return + end + end + instance:write(result.matches[#result.matches]) + end) + + -- Shell variable + parse:add_token(lpp.prefix(shellcode, span), function(stream, instance, result) + instance:write(string.format("write(os.getenv(%q))", result.matches[1])) + end) + + -- Shell variable, wrapped in quotes + parse:add_token(lpp.prefix(shellcode, parens), function(stream, instance, result) + instance:write(string.format("write('\"'..os.getenv(%q)..'\"')", result.matches[1])) + end) + + -- Shell block + parse:add_token(lpp.prefix(shellcode, block), function(stream, instance, matches) + + end) + self.parser = parse +end + +function parser:parse(code) + self.parser:compile(code) + print(self.parser.code) + local res = self.parser:generate() + print(res) +end + +return parser \ No newline at end of file