Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://anggtwu.net/LUA/CLua1.lua.html -- http://anggtwu.net/LUA/CLua1.lua -- (find-angg "LUA/CLua1.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- -- Introduction -- ============ -- This file implements several ways to define Lua functions in C -- using templates. For example, suppose that we want to define a -- function "add" whose body is: -- -- lua_pushnumber(L, lua_tonumber(L, 1) - lua_tonumber(L, 2)); -- return 1; -- -- One way to do that is to run this, -- -- buildandload('add', [=[ -- lua_pushnumber(L, lua_tonumber(L, 1) - lua_tonumber(L, 2)); -- return 1; -- ]=]) -- -- that creates a file /tmp/clua_001.c with these contents, -- -- #include "lauxlib.h" -- #include <stdio.h> -- static int my_add(lua_State* L) { -- lua_pushnumber(L, lua_tonumber(L, 1) - lua_tonumber(L, 2)); -- return 1; -- } -- static const struct luaL_reg clua_001_lib[] = { -- {"add", my_add}, -- {NULL, NULL} -- }; -- LUALIB_API int luaopen_clua_001(lua_State *L) { -- lua_pushvalue(L, LUA_GLOBALSINDEX); -- luaL_openlib(L, NULL, clua_001_lib, 0); -- return 0; -- } -- -- and then it compiles it with gcc or clang, and then loads the -- resulting .so with either "require" or "package.loadlib". -- -- -- Testing -- ======= -- There are complete instructions here: -- -- (find-lua-tutorial-intro "4. CLua1.lua") -- (find-lua-tutorial-intro "5. CLua1.lua from the outside") -- http://anggtwu.net/eev-intros/find-lua-tutorial-intro.html#4 -- http://anggtwu.net/eev-intros/find-lua-tutorial-intro.html#5 -- -- Etc -- === -- See: (find-angg ".emacs.templates" "find-luaso-links") -- (find-es "lua5" "CLua1.lua") -- Index: -- «.templates» (to "templates") -- «.CLua» (to "CLua") -- «.CLua-tests» (to "CLua-tests") -- «.buildandload» (to "buildandload") -- «.buildandload-tests» (to "buildandload-tests") require "Dang1" -- (find-angg "LUA/Dang1.lua") -- _ _ _ -- | |_ ___ _ __ ___ _ __ | | __ _| |_ ___ ___ -- | __/ _ \ '_ ` _ \| '_ \| |/ _` | __/ _ \/ __| -- | || __/ | | | | | |_) | | (_| | || __/\__ \ -- \__\___|_| |_| |_| .__/|_|\__,_|\__\___||___/ -- |_| -- -- «templates» (to ".templates") -- CLua_C = Dang.from [=[ #include "lauxlib.h" #include <stdio.h> static int my_<<.funname>>(lua_State* L) { <<.funbody>> } static const struct luaL_reg <<.modname>>_lib[] = { {"<<.funname>>", my_<<.funname>>}, {NULL, NULL} }; LUALIB_API int luaopen_<<.modname>>(lua_State *L) { lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_openlib(L, NULL, <<.modname>>_lib, 0); return 0; } ]=] CLua_sh_debian = Dang.from [=[ CFLAGS="-g -Wall -shared" LUADIR=/usr/include/lua5.1 echo gcc $CFLAGS -I$LUADIR -o <<.fnamenoext>>.so <<.fnamenoext>>.c gcc $CFLAGS -I$LUADIR -o <<.fnamenoext>>.so <<.fnamenoext>>.c && echo OK ls -lAF <<.fnamenoext>>* ]=] CLua_sh_mac = Dang.from [=[ CFLAGS="-g -Wall -shared -undefined dynamic_lookup" LUADIR=/opt/local/include/lua5.1 echo gcc $CFLAGS -I$LUADIR -o <<.fnamenoext>>.so <<.fnamenoext>>.c gcc $CFLAGS -I$LUADIR -o <<.fnamenoext>>.so <<.fnamenoext>>.c && echo OK ls -lAF <<.fnamenoext>>* ]=] CLua_lua_require = Dang.from [=[ Path.prependtocpath "<<.dir>>?.so" require "<<.fnamebase>>" ]=] CLua_lua_loadlib = Dang.from [=[ package.loadlib("<<.fnamenoext>>.so", "luaopen_<<.modname>>")() ]=] -- ____ _ -- / ___| | _ _ __ _ -- | | | | | | | |/ _` | -- | |___| |__| |_| | (_| | -- \____|_____\__,_|\__,_| -- -- «CLua» (to ".CLua") CLua = Class { type = "CLua", n = 0, from3 = function (fnameC, funname, funbody) local fnamenoext = fnamesansextension(fnameC) local fnamebase = fnamebase(fnameC) local dir = fnamedirectory(fnameC) local modname = fnamebase return CLua {fnameC=fnameC, fnamenoext=fnamenoext, fnamebase=fnamebase, dir=dir, modname=modname, funname=funname, funbody=funbody} end, from2 = function (funname, funbody) CLua.n = CLua.n + 1 local fnameC = format("/tmp/clua_%03d.c", CLua.n) return CLua.from3(fnameC, funname, funbody) end, rm = function (clb) print(getoutput("rm -fv /tmp/clua*")) end, -- __tostring = function (clb) local f = function (k) return format(" %-11s %s", k..":", clb[k]) end return mapconcat(f, sortedkeys(clb), "\n") end, __index = { _C = function (clb) return CLua_C (clb) end, _debian = function (clb) return CLua_sh_debian (clb) end, _mac = function (clb) return CLua_sh_mac (clb) end, _require = function (clb) return CLua_lua_require(clb) end, _loadlib = function (clb) return CLua_lua_loadlib(clb) end, -- C = function (clb) ee_writefile(clb.fnameC, clb:_C()); return clb end, debian = function (clb) print(getoutput(clb:_debian())); return clb end, mac = function (clb) print(getoutput(clb:_mac())); return clb end, require = function (clb) eval(clb:_require()); return clb end, loadlib = function (clb) eval(clb:_loadlib()); return clb end, }, } -- «CLua-tests» (to ".CLua-tests") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "CLua1.lua" -- Choose one: CLua.__index.compile = CLua.__index.mac CLua.__index.compile = CLua.__index.debian clb = CLua.from3("/tmp/clua_042.c", "foo", "return 0;") PPV(clb) = clb = clb:_C() = clb:_debian() = clb:_mac() = clb:_require() = clb:_loadlib() = clb:C() clb:compile() clb:require() = foo() CLua.rm() CLua.n = 0 clb = CLua.from2("foo", "lua_pushnumber(L, 33); return 1;") = clb:C():compile():loadlib() = foo() clb = CLua.from2("foo", "lua_pushnumber(L, 333); return 1;") = clb:C():compile():loadlib() = foo() --]==] -- _ _ _ _ _ _ _ -- | |__ _ _(_) | __| | __ _ _ __ __| | | ___ __ _ __| | -- | '_ \| | | | | |/ _` |/ _` | '_ \ / _` | |/ _ \ / _` |/ _` | -- | |_) | |_| | | | (_| | (_| | | | | (_| | | (_) | (_| | (_| | -- |_.__/ \__,_|_|_|\__,_|\__,_|_| |_|\__,_|_|\___/ \__,_|\__,_| -- -- «buildandload» (to ".buildandload") buildandload = function (funname, funbody) clb = CLua.from2(funname, funbody) clb:C():compile():loadlib() return clb end -- «buildandload-tests» (to ".buildandload-tests") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "CLua1.lua" -- Choose one: CLua.__index.compile = CLua.__index.mac CLua.__index.compile = CLua.__index.debian CLua.rm() buildandload("foo", [=[ lua_pushstring(L,"orig"); return 1; ]=]) = foo() buildandload("foo", [=[ lua_pushstring(L,"redefined"); return 1; ]=]) = foo() = clb = clb:_C() = clb:_debian() = clb:_loadlib() = clb:_require() --]==] -- Local Variables: -- coding: utf-8-unix -- End: