Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
// This file: // http://anggtwu.net/lisptree/call-lua.c.html // http://anggtwu.net/lisptree/call-lua.c // (find-angg "lisptree/call-lua.c") // Author: Eduardo Ochs <eduardoochs@gmail.com> // Date: 2025sep21 // License: Public Domain // Based on: (find-angg "LUA/Gdb1.c") // // This file implements a way to call Lua from Common Lisp using CFFI. // The main C functions here are `lua_fs' and `lua_fss', that receive // strings and return a string, and that work like this: // // lua_fs ("myfun", "aaa") -> return tostring(myfun("aaa")) // lua_fss("myfun", "aaa", "bbb") -> return tostring(myfun("aaa, "bbb"")) // // The right way to do things would be to make CFFI handle objects of // the form "lua_State *L", but I am a beginner with Common Lisp, and // I found that the right way was too hard for me - so instead I // created a "static lua_State *L", that is initially NULL, but is // initialized be `lua_my_init'. // // I debugged this by modifiyng this file and doing `M-x c', where: // (defun c () (interactive) (find-lisptreesh "./call-lua.sh compileandrun")) // (defun cls () (interactive) (find-lisptree "call-lua.sh")) // (defun clc () (interactive) (find-lisptree "call-lua.c")) // (defun cll () (interactive) (find-lisptree "call-lua.lua")) // // This file: (find-lisptree "call-lua.c") // See: (find-lisptree "call-lua.lua") // (find-lisptree "call-lua.sh") // (find-lua53manual "#luaL_newstate") // (find-lua53manual "#luaL_openlibs") // (find-lua53manual "#lua_getglobal") // (find-lua53manual "#lua_pop") // (find-lua53manual "#lua_pushstring") // (find-lua53manual "#lua_pushvalue") // (find-lua53manual "#lua_tostring") // // «.lua_my_init» (to "lua_my_init") // «.lua_fs» (to "lua_fs") // «.lua_fss» (to "lua_fss") // «.PPstack» (to "PPstack") // «.main» (to "main") // «.tests» (to "tests") #include <lua.h> #include <lauxlib.h> #include <lualib.h> #include <stdio.h> static lua_State *L = NULL; // «lua_my_init» (to ".lua_my_init") void lua_my_init(void) { if (!L) { L = luaL_newstate(); luaL_openlibs (L); } } // «lua_fs» (to ".lua_fs") // Returns tostring(f(arg1)). const char *lua_fs(char *f, char *arg1) { const char *result; lua_getglobal (L, "tostring"); lua_getglobal (L, f); lua_pushstring (L, arg1); lua_call (L, 1, 1); lua_call (L, 1, 1); result = lua_tostring(L, -1); lua_pop(L, 1); return result; } // «lua_fss» (to ".lua_fss") // Returns tostring(f(arg1,arg2)). const char *lua_fss(char *f, char *arg1, char *arg2) { const char *result; lua_getglobal (L, "tostring"); lua_getglobal (L, f); lua_pushstring (L, arg1); lua_pushstring (L, arg2); lua_call (L, 2, 1); lua_call (L, 1, 1); result = lua_tostring(L, -1); lua_pop(L, 1); return result; } // «PPstack» (to ".PPstack") // I use this function for debugging when I write C functions that // call the Lua API - it prints all the items in the Lua API stack and // leaves the stack unchanged. In some cases I set PPstack=PP, where // PP is this function defined in my init file, // (find-angg "LUA/lua50init.lua" "PP") // and sometimes I use this, that has a prettier output: // (find-lisptree "vbtbox.lua" "PPstack") void PPstack(void) { int n = lua_gettop(L); int i; lua_getglobal (L, "PPstack"); for (i=0;i<n;++i) lua_pushvalue (L, -n-1); lua_call (L, n, 0); } // «main» (to ".main") // For tests. #ifdef MAIN int main(int argc, const char ** argv) { lua_my_init(); lua_fs ("print", "In: call-lua.c"); lua_fss("print", "In: call-lua.c", "(main)"); lua_fs ("dofile", "/home/edrx/LUA/lua50init.lua"); lua_fs ("eval", "foo = function (a,b) return 10*a+b end"); lua_fs ("eval", "PPexpr = function (str) PP(expr(str)) end"); lua_fs ("PPexpr", "2+3"); lua_fs ("PPexpr", "foo(2,3)"); // lua_fs ("eval", "PPstack = PP"); // lua_pushinteger(L, 100); lua_pushnumber (L, 200); lua_pushstring (L, "300"); lua_getglobal (L, "print"); // lua_fs ("print", ""); PPstack (); lua_fs ("dofile", "vbtbox.lua"); // redefines PPstack lua_fs ("print", ""); PPstack (); lua_fs ("print", ""); lua_pop(L, 4); PPstack (); // return 0; } #endif /* «tests» (to ".tests") * Uses: (find-lisptree "call-lua.sh") * (eepitch-shell) * (eepitch-kill) * (eepitch-shell) ./call-lua.sh compile ls -laF call-lua* ./call-lua * (eepitch-sbcl) * (eepitch-kill) * (eepitch-sbcl) (load #P"~/quicklisp/setup.lisp") (ql:quickload :cffi) (cffi:load-foreign-library "./call-lua.so") (defun lua-my-init () (cffi:foreign-funcall "lua_my_init")) (defun lua-fs (f arg1) (cffi:foreign-funcall "lua_fs" :string f :string arg1 :string)) (defun lua-fss (f arg1 arg2) (cffi:foreign-funcall "lua_fss" :string f :string arg1 :string arg2 :string)) ;; Rewrite this part: (lua-my-init) (lua-fs "dofile" "./call-lua.lua") ;; See: (find-lisptree "call-lua.lua" "requires") ;; (find-lisptree "call-lua.lua" "verbatim") (lua-fs "verbatimbgbox" "a__b") (lua-fs "verbatimbgbox" "a__. | | b c") */ // Local Variables: // coding: utf-8-unix // End: