Advertisement
ecoMeco

luapp -- Lua Preprocessor

Oct 19th, 2016
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.17 KB | None | 0 0
  1. --LuaPreProcessor by Admicos
  2.  
  3. os.loadAPI("getopt")
  4.  
  5. local incdir  = "/etc/luapp/include/"
  6.  
  7. local version = "1.2.0"
  8. local outType = "normal"
  9.  
  10. local prefix = "--pp:"
  11. local output = shell.resolve("a.out")
  12.  
  13. local oBuf = ""
  14.  
  15. local _defines = {}
  16. local _ignblck = false
  17.  
  18. local function _print(verbose, ...)
  19.     if outType == "silent" then return end
  20.     if (outType ~= "verbose") and (outType ~= "verboser") and verbose then return end
  21.     if outType ~= "verboser" and verbose == "v" then return end
  22.  
  23.     print(table.unpack({ ... }))
  24. end
  25.  
  26. local function _err(err)
  27.     error("ERROR: " .. err, math.huge)
  28. end
  29.  
  30. function _trim(s)
  31.     return (s:gsub("^%s*(.-)%s*$", "%1"))
  32. end
  33.  
  34. local function _split(str, splitter)
  35.     local t = {}
  36.     local function helper(line) table.insert(t, line) return "" end
  37.         helper((str:gsub("(.-)" .. splitter, helper)))
  38.     return t
  39. end
  40.  
  41. local processFile = function(_) end;
  42. local pprocop = {
  43.     include = function(file)
  44.         local incfile = ""
  45.         _print("v", "Including file " .. file)
  46.  
  47.         if fs.exists(shell.resolve(file)) then
  48.             incfile = shell.resolve(file)
  49.         elseif fs.exists(fs.combine(incdir, file)) then
  50.             incfile = fs.combine(incdir, file)
  51.         elseif fs.exists(file) then
  52.             incfile = file
  53.         else
  54.             _err("Couldn't find a include for '" .. file .. "'")
  55.         end
  56.  
  57.         processFile(incfile)
  58.     end;
  59.  
  60.     define = function(thing, ...)
  61.         _print("v", "Defining " .. thing)
  62.         _defines[thing] = table.concat(arg, " ")
  63.     end;
  64.  
  65.     ifdef = function(defined)
  66.         if _defines[defined] == nil then
  67.             _print("v", "Starting a ignore block")
  68.             _ignblck = true
  69.         end
  70.     end;
  71.  
  72.     ifndef = function(defined)
  73.         if _defines[defined] ~= nil then
  74.             _print("v", "Starting a ignore block")
  75.             _ignblck = true
  76.         end
  77.     end;
  78.  
  79.     ["if"] = function(...)
  80.         local lstr = table.concat(arg, " ")
  81.         for def, val in pairs(_defines) do
  82.             lstr = lstr:gsub(def, val)
  83.         end
  84.  
  85.         if not loadstring("return " .. lstr)() then
  86.             _print("v", "Starting a ignore block")
  87.             _ignblck = true
  88.         end
  89.     end;
  90.  
  91.     ["ifn"] = function(...)
  92.         local lstr = table.concat(arg, " ")
  93.         for def, val in pairs(_defines) do
  94.             lstr = lstr:gsub(def, val)
  95.         end
  96.  
  97.         if loadstring("return " .. lstr)() then
  98.             _print("v", "Starting a ignore block")
  99.             _ignblck = true
  100.         end
  101.     end;
  102.  
  103.     ["else"] = function()
  104.         _ignblck = not _ignblck
  105.     end;
  106.  
  107.     ignorestart = function()
  108.         _print("v", "Starting a ignore block")
  109.         _ignblck = true
  110.     end;
  111.  
  112.     ignoreend = function()
  113.         _print("v", "Ending a ignore block")
  114.         _ignblck = false
  115.     end;
  116. }
  117.  
  118. processFile = function(file)
  119.     if not fs.exists(file) then error("File " .. file .. " doesn't exist") end
  120.     _print(true, "@@ /" .. file .. " @@")
  121.  
  122.     local ls = {}
  123.     local lIsPreprocessed = false;
  124.     for line in io.lines(file) do
  125.         lIsPreprocessed = false
  126.         ls = _split(_trim(line), " ")
  127.         if #ls >= 1 then
  128.             for _, line in ipairs(ls) do
  129.                 if line:sub(1, #prefix) == prefix then
  130.                     local proc = table.remove(ls, 1):sub(#prefix + 1)
  131.  
  132.                     if not pprocop[proc] then _err("'" .. proc .. "': not found") end
  133.  
  134.                     if _ignblck then
  135.                         if (proc == "ignoreend") or (proc == "else") then
  136.                             pprocop[proc](table.unpack(ls))
  137.                         end
  138.                     else
  139.                         pprocop[proc](table.unpack(ls))
  140.                     end
  141.  
  142.                     lIsPreprocessed = true
  143.                 end
  144.             end
  145.         end
  146.  
  147.         if (not lIsPreprocessed) and (not _ignblck) then
  148.             for def, val in pairs(_defines) do
  149.                 _print("v", "Replaced defined value " .. def)
  150.  
  151.                 line = line:gsub(def, val)
  152.             end
  153.  
  154.             oBuf = oBuf .. line .. "\n"
  155.         end
  156.     end
  157.  
  158.     local f = fs.open(output, "w")
  159.         f.write(oBuf)
  160.     f.close()
  161. end
  162.  
  163. local function main(args)
  164.     if args == nil then return end
  165.     if args["opt-1"] == nil then print("'luapp -h' for help") return end
  166.  
  167.     if args["verbose"]  then outType = "verbose" end
  168.     if args["verboser"] then outType = "verboser" end
  169.     if args["silent"]   then outType = "silent" end
  170.  
  171.     if args["prefix"] then prefix = args["prefix"] end
  172.     if args["output"] then output = shell.resolve(args["output"]) end
  173.  
  174.     local file = shell.resolve(args["opt-1"])
  175.  
  176.     _print(false, "luapp " .. version)
  177.     _print(true, "Prefix set as: " .. prefix)
  178.  
  179.     _print(false, "")
  180.  
  181.     processFile(file)
  182.     _print(false, "DONE: /" .. output)
  183. end
  184.  
  185. main(getopt.init("luapp", "Lua Preprocessor", {
  186.     ["prefix"] = {"Preprocessor Line Prefix", "p", "prefix"};
  187.     ["output"] = {"Processed file out", "o", "output"};
  188.     ["verbose"] = {"More output", "v", nil};
  189.     ["verboser"] = {"Even more output", "vv", nil};
  190.     ["silent"] = {"Less output", "s", nil};
  191. }, { ... }))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement