Advertisement
Guest User

build

a guest
Jan 1st, 2018
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.21 KB | None | 0 0
  1. local tArgs = { ... }
  2.  
  3. local DEBUG = false
  4.  
  5. if #tArgs ~= 2 or
  6.     type(tArgs[1]) ~= "string" or
  7.     type(tArgs[2]) ~= "string" then
  8.    
  9.     if DEBUG then
  10.         tArgs[1] = "wmain.lua"
  11.         tArgs[2] = "mfile.lua"
  12.     else
  13.         error("Usage: build <in_filename> <out_filename>", 0)
  14.     end
  15. end
  16.  
  17. if not fs.exists("src/"..tArgs[1]) then
  18.     error("File does not exist", 0)
  19. end
  20.  
  21. local inFilename = tArgs[1]
  22. local outFilename = tArgs[2]
  23.  
  24. local fOut = fs.open("out/"..outFilename, "w")
  25.  
  26. -- Find path in table
  27. local getffTable = function(sInput, tFull)
  28.     for sLine in string.gmatch(sInput, "(%w+)/") do
  29.         tFull = tFull[sLine]
  30.     end
  31.    
  32.     return tFull
  33. end
  34.  
  35. -- load all files
  36.  tPath = { }
  37. loadPath = function(path, cPath)
  38.     local tDir = fs.list(path)
  39.    
  40.     for _, sName in pairs(tDir) do
  41.         if fs.isDir(path..sName) then
  42.             cPath[sName] = { }
  43.             loadPath(path..sName.."/", cPath[sName])
  44.         else
  45.             local file = fs.open(path..sName, "r")
  46.             cPath[sName] = file.readAll()
  47.             file.close()
  48.         end
  49.     end
  50. end
  51. loadPath("src/", tPath)
  52. loadPath = nil
  53.  
  54. -- split parameter for macros
  55. local splitParam = function(sParam)
  56.     local tParam = { }
  57.     for sp in sParam:gmatch("%s*,?%s*([^,]*)%s*") do
  58.         table.insert(tParam, sp)
  59.     end
  60.     return table.unpack(tParam)
  61. end
  62.  
  63. -- convert raw bytecode to string bytecode
  64. rawtostr = function(bytecode)
  65.     local sReturn = ""
  66.     for ch in bytecode:gmatch(".") do
  67.         sReturn = sReturn.."\\"..string.byte(ch)
  68.     end
  69.     return sReturn
  70. end
  71.  
  72. -- load macros and convert to bytecode
  73. doFile = function(path, sFilename, sMode, tParam)
  74.     local sFile = ""
  75.     local sFiledef = ""
  76.    
  77.     local nLine = 0
  78.     for sLine in path[sFilename]:gmatch("([^\n]*)[\n]*") do
  79.         nLine = nLine + 1
  80.         local sMacro, sParam = string.match(sLine, "^#(.*)[(](.*)[)]")
  81.        
  82.         if sMacro then
  83.             local bMacro = false
  84.        
  85.             -- File definitions
  86.             if sMacro == "LIB" or
  87.                sMacro == "SOURCE" then
  88.                sFiledef = sMacro
  89.                
  90.                bMacro = true
  91.             else
  92.                 -- Public macro definitions
  93.                
  94.                 if sMacro == "GLIBFUNC" then
  95.                     bMacro = true
  96.                    
  97.                     if tParam.gfunct == nil then
  98.                         tParam.gfunct = { }
  99.                     end
  100.                    
  101.                     -- #GETLIBFUNCTION(module/abc, functionname)
  102.                     local sLib, sName = splitParam(sParam)
  103.                    
  104.                     if tParam.gfunct[sLib] == nil then
  105.                         tParam.gfunct[sLib] = { }
  106.                     end
  107.                    
  108.                     table.insert(tParam.gfunct[sLib], sName)
  109.                 elseif sMacro == "IMPORTLIB" then
  110.                     bMacro = true
  111.                    
  112.                     local iFile, svName = splitParam(sParam)
  113.                     local tFileDir = getffTable(iFile, path)
  114.                    
  115.                     local thisgfunct = tParam.gfunct[iFile]
  116.                    
  117.                     if tFileDir ~= path then
  118.                         iFile = iFile:match(".*[\\/](.*)")
  119.                     end
  120.                    
  121.                     if doFile(tFileDir, iFile, "DEFAULT", { pfunct = thisgfunct }) then
  122.                         return true
  123.                     end
  124.                    
  125.                     sFile = sFile.."local "..svName.." = \""
  126.                     sFile = sFile..tFileDir[iFile].."\"\n"
  127.                 end
  128.                
  129.                 -- Source file definitions
  130.                 if sFiledef == "SOURCE" then
  131.                     if sMacro == "IMPORT" then
  132.                         bMacro = true
  133.                    
  134.                         local iFile, svName = splitParam(sParam)
  135.                         local tFileDir = getffTable(iFile, path)
  136.                        
  137.                         if tFileDir ~= path then
  138.                             iFile = iFile:match(".*[\\/](.*)")
  139.                         end
  140.  
  141.                         if doFile(tFileDir, iFile, "DEFAULT", { }) then
  142.                             return true
  143.                         end
  144.                        
  145.                         sFile = sFile.."local "..svName.." = \""
  146.                         sFile = sFile..tFileDir[iFile].."\"\n"
  147.                     end
  148.                 end
  149.                
  150.                 print(sFiledef.." : "..sMacro)
  151.                 -- Libary file definitions
  152.                 if sFiledef == "LIB" then
  153.                     print(sMacro.." : "..sMode)
  154.                     if sMacro == "BEGINFUNCTION" and sMode ~= "FUNCTION" then
  155.                         bMacro = true
  156.                        
  157.                         if tParam.pfunct == nil then
  158.                             tParam.bLoadAllFunction = true
  159.                             tParam.bLoadFunction = true
  160.                         end
  161.                        
  162.                         sMode = "FUNCTION"
  163.                     elseif sMacro == "ENDFUNCTION" then
  164.                         bMacro = true
  165.                    
  166.                         sMode = "DEFAULT"
  167.                     elseif sMacro == "FUNCTION" and sMode == "FUNCTION" then
  168.                         bMacro = true
  169.                        
  170.                         if not tParam.bLoadAllFunction then
  171.                             local bContains = false
  172.                            
  173.                             for _, sFunction in pairs(tParam.pfunct) do
  174.                                 if sFunction == sParam then
  175.                                     bContains = true
  176.                                     break
  177.                                 end
  178.                             end
  179.                            
  180.                             tParam.bLoadFunction = bContains
  181.                         end
  182.                     end
  183.                 end
  184.             end
  185.            
  186.             if not bMacro then
  187.                 printError("Unable to resolve macro in file \""..sFilename.."\": \""..sMacro.."\" at line '"..nLine.."'")
  188.                 return true
  189.             end
  190.         elseif sMode == "DEFAULT" then
  191.             sFile = sFile..sLine.."\n"
  192.         elseif sMode == "FUNCTION" and tParam.bLoadFunction then
  193.             sFile = sFile..sLine.."\n"
  194.         end
  195.     end
  196.  
  197.     local file = fs.open("_"..sFilename, "w")
  198.     file.write(sFile)
  199.     file.close()
  200.    
  201.     local fFile, sError = loadstring(sFile)
  202.     if sError then
  203.         printError("Error in file \""..sFilename.."\": "..sError)
  204.  
  205.         return true
  206.     end
  207.    
  208.     --if sFilename == "wmain.lua" then
  209.     --  path[sFilename] = (string.dump( fFile ))
  210.     --else
  211.     path[sFilename] = rawtostr(string.dump( fFile ))
  212.     --end
  213. end
  214.  
  215. if doFile(tPath, inFilename, "DEFAULT", { }) then
  216.     return
  217. end
  218.  
  219. doFile = nil
  220. rawtostr = nil
  221.  
  222. fOut.write("loadstring(\"")
  223. fOut.write(tPath[ inFilename ])
  224. fOut.write("\")()")
  225.  
  226. fOut.close()
  227.  
  228. print(string.len(tPath[inFilename]).." bytes have been written to: out/"..outFilename)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement