Anuncios
Anuncios

Bienvenidos sean a este post, hoy comenzaremos con una serie de posts donde veremos diferentes tecnicas para escribir funciones de C, en total veremos tres pero comenzaremos con la primera que es la manipulacion de Arrays.

“Array” en Lua es solo el nombre para una tabla usado de una forma especifica, lo vimos en este post, esto nos da la posibilidad de manipular a este tipo de variable usando las mismas funciones que utilizamos para manipular tablas, lua_settable y lua_gettable, sin embargo la API provee funciones especiales para la manipulacion del array, una razon para estas funciones extras es la performance ya que habitualmente tenemos una operacion de acceso a array dentro de un bucle interno de un algoritmo (p.e. sorting), asi que cualquier mejora en la performance dentro de la operacion puede tener un gran impacto en la performance general del algoritmo, otra razon es la conveniencia, esto es debido a que las clave de cadena y de enteros son bastante comunes como para recibir un tratamiento especial, la API nos provee dos funciones especiales para la manipulacion de arrays:

void lua_rawgeti(lua_State *L, int indice, int clave);
void lua_rawseti(lua_State *L, int indice, int clave);
Anuncios

La descripcion de estas dos funciones puede ser algo confusa porque contiene dos indices: indice es la posicion donde la tabla va a estar en la pila y clave es donde el elemento esta en la tabla, la llamada lua_rawgeti(L, t, clave) es equivalente a la siguiente secuencia cuando t es positiva, de lo contrario debes compensarlo por el nuevo item en la pila:

lua_pushnumber(L, clave);
lua_rawgeti(L, t);
Anuncios

La llamada lua_rawseti(L, t, clave), siempre con un t positivo, es equivalente a esta secuencia:

lua_pushnumber(L, clave);
lua_insert(L, -2); /* pone a 'clave' por debajo de los valores anteriores */
lua_rawset(L, t);
Anuncios

Ambas funciones usan operaciones “crudas” (raw) que son mas rapidas y las tablas usadas como arrays rara vez usan metametodos, veamos el siguiente codigo:

int l_map(lua_State *L)
{
	int i, n;
	
	luaL_checktype(L, 1, LUA_TTABLE);
	
	luaL_checktype(L, 2, LUA_TFUNCTION);

	n = lua_objlen(L, 1);

	for(i = 1; i <= n; i++)
	{
		lua_pushvalue(L, 2);
		lua_rawgeti(L, 1, i);
		lua_call(L, 1, 1);
		lua_rawseti(L, 1, i);
	}

	return 0;
}
Anuncios

Este codigo implementa la funcion map, aplica una funcion dada a todos los elementos de un array, reemplazando cada elemento por el resultado de la llamada, este codigo tambien introduce dos nuevas funciones, la funcion luaL_checktype (de lauxlib.h) asegura que el argumento informado tenga el tipo necesitado, de lo contrario devuelve un error, despues guardaremos en n el tamaño de la tabla, luego tendremos un bucle for donde pasaremos por todos los elementos de la tabla, en el bucle la primera linea empuja la funcion a la pila, luego empuja a la pila la posicion de la tabla, despues utilizamos a la funcion lua_call que hace una llamada desprotegida, trabaja de forma similar a lua_pcall pero en caso de error lo propaga en lugar de devolver un codigo de error, cuando escribis el codigo principal en una aplicacion deberias no usar lua_pcall porque debes capturar cualquier error, sin embargo cuando escribis funciones es una buena idea usar lua_call si hay un error solo deja que alguno se encargue de ello, por ultimo return 0 devuelve que la funcion se ejecuto correctamente.

Anuncios

En resumen, hoy hemos visto como manipular array por medio de la API, hemos visto como las puede manejar Lua, unas funciones para una mejor performance, sus equivalencias, un ejemplo con algunas funciones nuevas por medio de la API, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00