Skip to content

Latest commit

 

History

History
119 lines (101 loc) · 2.25 KB

4.2.md

File metadata and controls

119 lines (101 loc) · 2.25 KB

Lua as extension to applications

basics

e.g. a simple config file

-- define window size
width = 200
height = 300
void
load (lua_State *L, const char *fname, int *w, int *h)
{
	if (luaL_loadfile(L, fname) || lua_pcall(L, 0, 0, 0))
		error (L, "cannot run config. file: %s", lua_tostring(L, -1));
	lua_getglobal (L, "width");
	lua_getglobal (L, "height");
	if (!lua_isnumber(L, -2))
		error (L, "'width' should be a number\n");
	if (!lua_isnumber(L, -1))
		error (L, "'height' should be a number\n");
	*w = lua_tointeger (L, -2);
	*h = lua_tointeger (L, -1);
}

lua's advantage: such a config file is available

if getenv("DISPLAY") == ":0.0" then
	width = 300; height = 300
else
	width = 80; height = 24
end

table

config

width = 200
height = 300
-- background = { r = 0.30, g = 0.10, b = 0 }

BLUE = { r = 0, g = 0, b = 1 }
background = BLUE
lua_getglobal (L, "background");
if (!lua_istable(L, -1))
	error (L, "'background' is not a table");

red = getfield(L, "r"); /* getfield is not lua API */
green = getfield(L, "g");
blue = getfield(L, "b");

this is for int fields only.

#define MAX_COLOR 255
/* we assume that the target table is located at the top of stack */
int 
getfield (lua_State *L, const char *key)
{
	int result;

	{ /* method 1 */
		lua_pushstring(L, key);
		lua_gettable(L, -2); /* get background[key] */
	}
   	{ /* method 2 */
		lua_getfield(L, -1, key);
	}

	if (!lua_isnumber(L, -1))
		error (L, "invalid component in background color");
	result = (int)lua_tonumber(L, -1) * MAX_COLOR;
	lua_pop (L, 1); /* delete number */
	return result;
}

+placeholder
+placeholder

Call lua functions in C

Given a lua function in the configuration file

function f (x, y)
	return (x^2 * math.sin(y)/(1-x))
end

and it can be called in C like this

/* wrapper for lua function */
double f (double x, double y)
	double z;

	/* push function and its arguments */
	lua_getglobal (L, "f");
	lua_pushnumber (L, x);
	lua_pushnumber (L, y);
	/* call */
	if (lua_pcall(L, 2, 1, 0) != 0)
		error (L, "error running function 'f': %s", lua_tostring(L, -1));
	/* check result */
	if (!lua_isnumber(L, -1))
		error (L, "function 'f' must return a number");
	z = lua_tonumber (L, -1);
	lua_pop (L, 1);
	return z;
}

+placeholder