Advertisement
Guest User

Convert Lua source to a C file

a guest
Jun 17th, 2010
1,628
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.22 KB | None | 0 0
  1. #!/usr/bin/env lua
  2.  
  3. ----- lua 5.1 script to convert a lua file into a C file
  4. -----
  5. ----- Usage: lua2c foo.lua > lfoo.c     # compiled, so not portable
  6. -----        lua2c -s foo.lua > lfoo.c  # source, and so portable
  7.  
  8.  
  9. ---------------- general utility functions -------------
  10.  
  11. function io.contents(filename)
  12.   local f, msg = io.open(filename, 'r')
  13.   if not f then return f, msg end
  14.   local s = assert(f:read '*a')
  15.   f:close()
  16.   return s
  17. end
  18.  
  19. function os.capture(cmd, raw)
  20.   local f = assert(io.popen(cmd, 'r'))
  21.   local s = assert(f:read('*a'))
  22.   f:close()
  23.   if raw then return s end
  24.   s = string.gsub(s, '^%s+', '')
  25.   s = string.gsub(s, '%s+$', '')
  26.   s = string.gsub(s, '[\n\r]+', ' ')
  27.   return s
  28. end
  29.  
  30. local quote_me = '[^%w%+%-%=%@%_%/]'
  31.                      -- easier to complement what doesn't need quotes
  32. local strfind = string.find
  33.  
  34. function os.quote(s)
  35.   if strfind(s, quote_me) or s == '' then
  36.     return "'" .. string.gsub(s, "'", [['"'"']]) .. "'"
  37.  else
  38.    return s
  39.  end
  40. end
  41.  
  42. function os.runf(...) return os.execute(string.format(...)) end
  43.  
  44. -------------------------------------------------------
  45. local lua -- program to be loaded (source or binary)
  46.  
  47. local libname
  48.  
  49. if arg[1]:find '^-lib' and arg[2] then
  50.  libname = arg[2]
  51.  table.remove(arg, 1)
  52.  table.remove(arg, 1)
  53. end
  54.  
  55.  
  56. if arg[1] == '-a' or arg[1] == '-s' then -- don't compile;
  57.                                      -- use ascii source
  58.   table.remove(arg, 1)
  59.   assert(#arg == 1)
  60.   lua = io.contents(arg[1]):gsub('^#!.-\n', '')
  61. else  
  62.   assert(#arg == 1)
  63.   local bin = os.capture 'PATH=/bin:$PATH tempfile'
  64.   assert(os.runf('luac -o %s %s', os.quote(bin), os.quote(arg[1])) == 0)
  65.   lua = io.contents(bin)
  66.   os.remove(bin)
  67. end
  68.  
  69. libname = libname or arg[1]:gsub('.*/', ''):gsub('%.lua$', '')
  70.  
  71. outfile = io.stdout
  72.  
  73. ------------------------
  74.  
  75. outfile:write [[
  76. #include <lua.h>
  77. #include <lauxlib.h>
  78.  
  79. static unsigned char program[] = {
  80. ]]
  81.  
  82. outfile:write '  '
  83.  
  84. local function printf(...) return outfile:write(string.format(...)) end
  85.  
  86. local last = lua:len()
  87.  
  88. for i = 1, last do
  89.   local n = string.byte(lua, i)
  90.   printf('%3d%s', n, i < last and ', ' or '')
  91.   if i % 10 == 0 then printf '\n  ' end
  92. end
  93.  
  94. printf '\n};\n\n'
  95.  
  96. outfile:write((([[
  97.  
  98. int luaload_$lib(lua_State *L) {
  99.   return luaL_loadbuffer(L, (const char*)program, sizeof(program), "@$source");
  100. }
  101.  
  102. int luaopen_$lib(lua_State *L) {
  103.   if (luaL_loadbuffer(L, (const char*)program, sizeof(program), "@$source"))
  104.     return luaL_error(L, "Internal library '%s' failed to parse", "$lib");
  105.   if (lua_pcall(L, 0, 1, 0))
  106.     return luaL_error(L, "Internal library '%s' failed to run: %s", "$lib",
  107.                       lua_tostring(L, -1));
  108.   if (lua_isnil(L, -1)) {
  109.     lua_pop(L, 1);
  110.     lua_pushboolean(L, 1);
  111.   }
  112.   lua_getglobal(L, "package");   // s: lib package
  113.   lua_getfield(L, -1, "loaded"); // s: lib package loaded
  114.   lua_remove(L, -2);             // s: lib loaded
  115.   lua_pushstring(L, "$lib");     // s: lib loaded libname
  116.   lua_pushvalue(L, -3);          // s: lib loaded libname lib
  117.   lua_settable(L, -3);           // s: lib loaded
  118.   lua_pop(L, 1);                 // s: lib
  119.   return 1;
  120. }
  121. ]]):gsub('$(%a+)', { lib = libname, source = arg[1]:gsub('.*/', '') })))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement