Manual de Referencia de Lua 5.1
(Traducción de Julio Manuel Fernández-Díaz; véanse las notas sobre la misma al final del documento.)
Copyright © 2007-2008 Lua.org, PUC-Rio. Libremente disponible bajo los términos de la licencia de Lua.
contenido · índice · english · português · español
Lua es un lenguage de programación extensible diseñado para una programación procedimental general con utilidades para la descripción de datos. También ofrece un buen soporte para la programación orientada a objetos, programación funcional y programación orientada a datos. Se pretende que Lua sea usado como un lenguaje de script potente y ligero para cualquier programa que lo necesite. Lua está implementado como una biblioteca escrita en C limpio (esto es, en el subconjunto común de ANSI C y C++).
Siendo un lenguaje de extensión, Lua no tiene noción de programa principal (main): sólo funciona embebido en un cliente anfitrión, denominado programa contenedor o simplemente anfitrión (host). Éste puede invocar funciones para ejecutar un trozo de código Lua, puede escribir y leer variables de Lua y puede registrar funciones C para que sean llamadas por el código Lua. A través del uso de funciones C, Lua puede ser aumentado para abarcar un amplio rango de diferentes dominios, creando entonces lenguajes de programación personalizados que comparten el mismo marco sintáctico. La distribución de Lua incluye un programa anfitrión de muestra denominado lua, que usa la biblioteca de Lua para ofrecer un intérprete de Lua completo e independiente.
Lua es software libre, y se proporciona, como es usual, sin garantías, como se establece en su licencia. La implementación descrita en este manual está disponible en el sitio web oficial de Lua, www.lua.org.
Como cualquier otro manual de referencia, este documento es parco en algunos lugares. Para una discusión de las decisiones detrás del diseño de Lua, véanse los artículos técnicos disponibles en el sitio web de Lua. Para una detallada introducción a la programación en Lua, véase el libro de Roberto, Programming in Lua (Second Edition).
Esta sección describe el léxico, la sintaxis y la semántica de Lua. En otras palabras, esta sección describe qué elementos (tokens) son válidos, cómo deben combinarse y qué significa su combinación.
Las construcciones del lenguaje se explicarán usando la notación BNF extendida usual, en la que {a} significa 0 o más aes, y [a] significa una a opcional. Los símbolos no terminales se muestran en itálica, las palabras clave (keywords) se muestran en negrita, y los otros símbolos terminales se muestran en un tipo de letra de paso fijo (typewriter), encerrada entre comillas simples. La sintaxis completa de Lua se encuentra al final de este manual.
Los nombres (también llamados identificadores) en Lua pueden ser cualquier tira de caracteres (string) sólo con letras, dígitos y caracteres de subrayado (underscore), no comenzando por un dígito. Esto coincide con la definición de los nombres en la mayoría de los lenguajes. (La definición de letra depende de la implementación local actual a través del sistema locale: cualquier carácter considerado alfabético en el sistema local puede ser usado en un identificador.) Los identificadores se usan para nombrar variables y campos de tablas.
Las siguientes palabras clave (keywords) están reservadas y no pueden usarse como nombres:
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while
En Lua las letras mayúsculas y las minúsculas se consideran diferentes: and es una palabra reservada, pero And y AND son dos nombres diferentes válidos. Como convención, los nombres que comienzan por un subrayado seguido por letras en mayúsculas (como _VERSION) están reservados para uso como variables globales internas de Lua.
Los siguientes strings denotan otros elementos:
+ - * / % ^ #
== ~= <= >= < > =
( ) { } [ ]
; : , . .. ...
Los strings literales pueden ser delimitados por comillas simples (apóstrofes) o dobles, y pueden contener las siguientes secuencias de escape de C:
'\a' (pitido, bell)
'\b' (retroceso, backspace),
'\f' (salto de página, form feed),
'\n' (nueva línea, newline),
'\r' (retorno de carro, carriage return),
'\t' (tabulador horizontal, horizontal tab),
'\v' (tabulador vertical, vertical tab),
'\\' (barra inversa, backslash),
'\"' (comilla doble, quotation mark o double quote) y
'\'' (apóstrofe, apostrophe o single quote).
Además, una '\newline' (esto es, una barra inversa seguida por un salto de línea real) produce un salto de línea en el string. Un carácter en un string puede también especificarse por su valor numérico usando la secuencia de escape '\ddd', donde ddd es una secuencia de tres dígitos decimales. (Tenga presente que si la secuencia numérica de escape está seguida de un dígito debe ser expresada usando exactamente tres dígitos.) Los strings en Lua pueden contener cualquier valor de 8 bits, incluyendo el carácter cero, el cual puede ser especificado mediante '\0'.
Para poner una comilla (simple) doble, una barra inversa, un retorno de carro o un carácter cero dentro de un string literal encerrado por comillas (simples) dobles se debe usar una secuencia de escape. Cualquier otro carácter puede ser incluido en el literal. (Algunos caracteres de control pueden causar problemas con el sistema de ficheros, pero Lua no tiene problemas con ellos.)
Los strings literales pueden definirse usando un formato largo, encerrados en corchetes largos. Definimos un corchete largo de abrir de nivel n como un corchete de abrir seguido de n signos igual (=) seguidos de otro corchete de abrir. Así, un corchete largo de abrir de nivel 0 se escribe [[, un corchete largo de abrir de nivel 1 se escribe [=[, y así sucesivamente. Los corchetes largos de cerrar se define de manera similar; por ejemplo, un corchete largo de cerrar de nivel 4 se expresa ]====]. Un string largo comienza en un corchete largo de abrir de cualquier nivel y termina en el primer corchete largo de cerrar del mismo nivel. Los strings literales delimitados de esta manera pueden extenderse por varias líneas, las secuencias de escape no son interpretadas y se ignoran los corchetes largos de cualquier otro nivel. Por tanto, pueden contener cualquier cosa excepto un corchete de cerrar del mismo nivel o caracteres cero.
Por conveniencia, cuando un corchete largo de abrir es seguido inmediatamente de un carácter de nueva línea, éste no es incluido en el string. Por ejemplo, usando el código de caracteres ASCII (en el cual 'a' se codifica como 97, el carácter de nueva línea se codifica como 10, y '1' se codifica como 49), los cinco literales siguientes denotan el mismo string:
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]
Las constantes numéricas pueden contener una parte decimal opcional y también un exponente opcional. Lua también acepta constantes enteras hexadecimales, escritas anteponiendo el prefijo 0x. Algunos ejemplos de constantes numéricas válidas son
3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
Los comentarios comienzan con un doble guión (--) en cualquier lugar fuera de un string. Si el texto que sigue inmediatamente después de -- no es un corchete largo de abrir el comentario es corto y llega hasta el final de línea. En otro caso tenemos un comentario largo, que alcanza hasta el correspondiente corchete largo de cerrar. Los comentarios largos se usan frecuentemente para deshabilitar temporalmente trozos de código.
Lua es un lenguaje dinámicamente tipado. Esto significa que las variables no tienen tipos; sólo tienen tipo los valores. No existen definiciones de tipo en el lenguaje. Todos los valores almacenan su propio tipo.
Todos los valores en Lua son valores de primera clase. Esto significa que todos ellos pueden ser almacenados en variables, pueden ser pasados como argumentos de funciones, y también ser devueltos como resultados.
Existen ocho tipos básicos en Lua:
nil, boolean, number,
string, function, userdata,
thread y table.
Nil es el tipo del valor nil, cuya principal propiedad es ser
diferente de cualquier otro valor; normalmente representa la ausencia de un valor útil.
Boolean es el tipo de los valores false (falso) y true (verdadero).
Tanto nil como false hacen una condición falsa;
cualquier otro valor la hace verdadera.
Number representa números reales (en coma flotante y doble precision).
(Es fácil construir intérpretes de Lua que usen otra representación interna para
los números, ya sea en coma flotante con precisión simple o enteros largos.
Véase el fichero luaconf.h.)
String representa una tira de caracteres.
Lua trabaja con 8 bits: los strings pueden contener cualquier carácter de 8 bits, incluyendo el carácter cero ('\0') (véase §2.1).
Lua puede llamar (y manejar) funciones escritas en Lua y funciones escritas en C (véase §2.5.8).
El tipo userdata se incluye para permitir guardar en variables de Lua datos arbitrarios en C. Este tipo corresponde a bloques de memoria y no tienen asociadas operaciones predefinidas en Lua, excepto la asignación y el test de identidad. Sin embargo, usando §metatablas, el programador puede definir operaciones asociadas a valores de tipo userdata (véase §2.8). Los valores de este tipo no pueden ser creados o modificados en Lua, sino sólo a través de la API de C. Esto garantiza la integridad de los datos propiedad del programa anfitrión.
El tipo thread representa procesos de ejecución y es usado para implementar co-rutinas (véase §2.11). No deben confundirse los procesos de Lua con los del sistema operativo. Lua soporta co-rutinas en todos los sistemas, incluso en aquéllos que no soporten procesos.
El tipo table (tabla) implementa arrays asociativos, esto es, arrays que pueden ser indexados no sólo con números, sino también con cualquier valor (excepto nil). Las tablas pueden ser heterogéneas, ya que pueden contener valores de todos los tipos (excepto nil). Las tablas son el único mecanismo de estructuración de datos en Lua; pueden ser usadas para representar arrays ordinarios, tablas de símbolos, conjuntos, registros, grafos, árboles, etc. Para representar registros Lua usa el nombre del campo como índice. El lenguaje soporta esta representación haciendo la notación b.nombre equivalente a b["nombre"]. Existen varias maneras convenientes de crear tablas en Lua (véase §2.5.7).
Como índices, también los valores de los campos de una tabla pueden ser de cualquier tipo (excepto nil). En particular, debido a que las funciones son valores de primera clase, los campos de las tablas pueden contener funciones. Entonces las tablas pueden contener también métodos (véase §2.5.9).
Los valores de las tablas, las funciones, los procesos y los userdata (completos) son objetos: las variables no contienen realmente esos valores, sino que sólo los referencian. La asignación, el paso de argumentos y el retorno de las funciones siempre manejan referencias a esos valores; esas operaciones no implican ningún tipo de copia.
La función de biblioteca type retorna un string que describe el tipo de un valor dado.
Lua puede convertir automáticamente entre valores string y valores numéricos en tiempo de ejecución. Cualquier operación aritmética aplicada a un string intenta convertir el mismo en un número, siguiendo las reglas normales de conversión. Y viceversa, cuando un número se usa donde se espera un string el número se convierte a string, con un formato razonable. Para un control completo en la conversión de números en strings debe usarse la función format de la biblioteca de manejo de strings (véase string.format).
Las variables son lugares donde se almacenan valores. Existen tres tipos de variables en Lua: globales, locales y campos de tabla.
Un único nombre puede denotar una variable local o una global (o un argumento formal de una función, el cual es una forma particular de una variable local):
var ::= nombre
nombre denota identificadores, como se definen en §2.1.
Lua asume que las variables son globales, a no ser que sean declaradas explícitamente como locales (véase §2.4.7). Las variables locales tienen un ámbito (scope) definido léxicamente: pueden ser accedidas libremente desde dentro de las funciones definidas en su mismo ámbito (véase §2.6).
Antes de la primera asignación el valor de una variable es nil.
Los corchetes se usan para indexar una tabla:
var ::= prefixexp '[' exp ']'La primera expresión (prefixexp) debe dar como resultado un valor tabla; la segunda expresión (exp) identifica una entrada específica en esta tabla. La expresión que denota la tabla que es indexada tienen una sintaxis restringida; véase §2.5 para más detalles.
La sintaxis var.nombre es otra manera de expresar
var["nombre"] y se usa para denotar campos de tablas:
var ::= prefixexp '.' nombre
La manera en qué se accede a las variables globales y a los campos de las tablas puede ser cambiada mediante metatablas. Un acceso a la variable indexada t[i] equivale a una llamada a gettable_event(t,i) (véase §2.8 para una completa descripción de la función gettable_event. Esta función no está definida ni es invocable desde Lua. Se usa aquí sólo con propósitos ilustrativos).
Todas las variables globales se almacenan como campos de tablas ordinarias en Lua, denominadas tablas de entorno o simplemente entornos (véase §2.9). Cada función tiene su propia referencia a un entorno, así que todas las variables globales de esta función se refieren a esa tabla de entorno. Cuando se crea una función, ésta hereda el entorno de la función que la creó. Para obtener la tabla de entorno de una función en código Lua, se invoca a getfenv. Para reemplazarla se llama a setfenv. (Se pueden manejar los entornos de una función C, pero sólo a través de la biblioteca de depuración; véase §5.9.)
Un acceso a la variable global x equivale a _env.x, que a su vez equivale a
gettable_event(_env, "x")donde
_env es el entorno de la función que se está ejecutando en ese momento (véase §2.8 para una completa descripción de la función gettable_event. Esta función no está definida ni es invocable desde Lua. Igualmente, la variable _env no está definida en Lua. Se usan aquí sólo con propósitos ilustrativos.)
Lua soporta un conjunto casi convencional de sentencias, similar a los de Pascal o C. Este conjunto incluye la asignación, estructuras de control de flujo, llamadas a funciones, constructores de tablas y declaraciones de variables.
La unidad de ejecución en Lua se denomina chunk, el cual es simplemente un conjunto de sentencias que se ejecutan secuencialmente. Cada sentencia puede llevar opcionalmente al final un punto y coma:
chunk ::= {sentencia [';']}
No existen sentencias vacías en Lua y por tanto ';;' no es legal.
Lua maneja cada chunk como el cuerpo de una función anónima con un número variable de argumentos (véase §2.5.9). Los chunks pueden definir variables locales, recibir argumentos y retornar valores.
Un chunk puede ser almacenado en un fichero o en un string dentro de un programa anfitrión. Cuando se ejecuta un chunk primero se precompila, creándose instrucciones para una máquina virtual, y es entonces cuando el código compilado es ejecutado por un intérprete de la máquina virtual.
Los chunks pueden también estar precompilados en forma binaria; véase el programa luac para más detalles. Las formas fuente y compilada de los programas son intercambiables; Lua detecta automáticamente el tipo de fichero y actúa de manera acorde.
bloque ::= chunk
Un bloque puede ser delimitado explícitamente para producir una sentencia simple:
sentencia ::= do bloque endLos bloques explícitos son útiles para controlar el ámbito de las declaraciones de variable. También se utilizan a veces para añadir sentencias return o break en medio de otro bloque (véase §2.4.4).
Lua permite asignaciones múltiples. Por tanto la sintaxis de una asignación define una lista de variables a la izquierda y una lista de expresiones a la derecha. Los elementos de ambas listas están separados por comas:
sentencia ::= varlist '=' explist
varlist ::= var {',' var}
explist ::= exp {',' exp}
Las expresiones se analizan en §2.5.
Antes de una asignación la lista de expresiones se ajusta a la longitud de la lista de variables. Si existen más valores de los necesarios el exceso se descarta. Si existen menos valores de los necesarios la lista se extiende con tantos valores nil como se necesiten. Si la lista de expresiones finaliza con una llamada a una función entonces todos los valores devueltos en la llamada pueden entrar en la lista de valores antes del ajuste (excepto cuando se encierra entre paréntesis; véase §2.5).
La sentencia de asignación primero evalúa todas sus expresiones y sólo después se hace la asignación. Entonces, el código
i = 3
i, b[i] = i+1, 20
asigna 20 a b[3], sin afectar a b[4] debido a que i en b[i] se evalúa (a 3) antes de que se le asigne el valor 4. Similarmente, la línea
x, y = y, xintercambia los valores de
x e y.
El mecanismo de asignación a las variables globales y a los campos de tablas puede ser modificado mediante metatablas. Una asignación a una variable indexada t[i] = val equivale a settable_event(t,i,val). (Véase §2.8 para una completa descripción de la función settable_event. Esta función no está definida ni es invocable desde Lua. Se usa sólo con propósitos ilustrativos.)
Una asignación a la variable global x = val
equivale a la asignación _env.x = val,
que a su vez equivalen a
settable_event(_env, "x", val)donde
_env es el entorno de la función que está ejecutándose en ese momento.
(La variable _env no está definida en Lua.
Se utiliza aquí sólo con propósitos ilustrativos.)
sentencia ::= while exp do bloque end
sentencia ::= repeat bloque until exp
sentencia ::= if exp then bloque {elseif exp then bloque} [else bloque] end
Lua tiene también una sentencia for, en dos formatos (véase §2.4.5).
La condición de una expresión de una estructura de control puede retornar cualquier valor. Tanto false como nil se consideran falsos. Todos los valores diferentes de nil y false se consideran verdaderos (en particular, el número 0 y el string vacío son también verdaderos).
En el bucle repeat–until el bloque interno no acaba en la palabra clave until sino detrás de la condición. De esta manera la condición puede referirse a variables locales declaradas dentro del bloque del bucle.
La orden return se usa para devolver valores desde una función o un chunk (el cual es justamente una función). Las funciones y los chunks pueden retornar más de un valor, por lo que la sintaxis para return es
sentencia ::= return [explist]
La orden break se usa para terminar la ejecución de los bucles while, repeat y for, saltando a la sentencia que sigue después del bucle:
sentencia ::= breakUn break finaliza el bucle más interno que esté activo.
Las órdenes return y break pueden aparecer sólo como última sentencia dentro de un bloque. Si se necesita realmente un return o un break en medio de un bloque se debe usar un bloque más interno explícitamente, como en 'do return end' y 'do break end', debido a que así return y break son las últimas sentencias en su propio bloque.
La sentencia for tiene dos formas: una numérica y otra genérica.
La forma numérica del bucle for repite un bloque mientras una variable de control sigue una progresión aritmética. Tiene la sintaxis siguiente:
sentencia ::= for nombre '=' exp1 ',' exp2 [',' exp3] do bloque endEl bloque se repite para los valores de nombre comenzando en exp1 hasta que sobrepasa exp2 usando como paso exp3. Más precisamente una sentencia for como
for v = e1, e2, e3 do bloque endequivale al código:
do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
local v = var
bloque
var = var + step
end
end
Nótese lo siguiente:
v es local dentro del bucle; no se puede utilizar su valor después de que finalice el bucle for o después de una salida del mismo con break. Si se necesita el valor de la variable var entonces debe asignarse a otra variable antes del break o de la salida del bucle.
La sentencia for genérica trabaja con funciones, denominadas iteradores. En cada iteración se invoca a la función iterador que produce un nuevo valor, parándose la iteración cuando el nuevo valor es nil. El bucle for genérico tiene la siguiente sintaxis:
sentencia ::= for lista_de_nombres in explist do bloque end
lista_de_nombres ::= nombre {',' nombre}
Una sentencia for como
for var_1, ..., var_n in explist do bloque endequivale al código:
do
local f, s, var = explist
while true do
local var_1, ... , var_n = f(s, var)
var = var_1
if var == nil then break end
bloque
end
end
Nótese lo siguiente:
sentencia ::= llamada_a_funcEn ese caso todos los valores retornados se descartan. Las llamadas a función están explicadas en §2.5.8.
sentencia ::= local lista_de_nombres ['=' explist]Si está presente, una asignación inicial tiene la misma semántica que una asignación múltiple (véase §2.4.3). En otro caso todas las variables son inicializadas con nil.
Un chunk es también un bloque (véase §2.4.1), así que las variables locales pueden ser declaradas en un chunk fuera de cualquier bloque explícito. El ámbito de esas variables se extiende hasta el final del chunk.
Las reglas de visibilidad para las variables locales se exponen en §2.6.
Las expresiones básicas en Lua son las siguientes:
exp ::= prefixexp
exp ::= nil | false | true
exp ::= Número
exp ::= String
exp ::= func
exp ::= constructor_de_tabla
exp ::= '...'
exp ::= exp operador_binario exp
exp ::= operador_unario exp
prefixexp ::= var | llamada_a_func | '(' exp ')'
Los números y los string literales se explican en §2.1; las variables se explican en §2.3; la definición de funciones se explica en §2.5.9; las llamadas a función se explican en §2.5.8; los constructores de tablas se explican en §2.5.7. Las expresiones vararg (que indican un número variable de argumentos en una función), denotadas mediante tres puntos ('...'), pueden ser usadas directamente sólo cuando están dentro de las funciones con vararg; se explican en §2.5.9.
Los operadores binarios comprenden los operadores aritméticos (véase §2.5.1), los operadores relacionales (véase §2.5.2) y los operadores lógicos (véase §2.5.3). Los operadores unarios compenden el menos unario (véase §2.5.1), el not unario (véase §2.5.3) y el operador de longitud unario (véase §2.5.5).
Tanto las llamadas a función como las expresiones vararg pueden resultar en valores múltiples. Si la expresión se usa como una sentencia (véase §2.4.6) (sólo posible con llamadas a función), entonces su lista de valores retornados se ajusta a cero elementos, descartando todos los valores retornados. Si la expresión se usa como el último (o único) elemento de una lista de expresiones entonces no se realiza ningún ajuste (a no ser que la llamada se encierre entre paréntesis). En todos los demás contextos Lua ajusta el resultado de la lista a un solo elemento, descartando todos los valores excepto el primero.
He aquí varios ejemplos:
f() -- ajustado a 0 resultados
g(f(), x) -- f() es ajustado a 1 resultado
g(x, f()) -- g toma x y todos los valores devueltos por f()
a,b,c = f(), x -- f() se ajusta a 1 resultado (c toma el valor nil)
a,b = ... -- a toma el primer argumento vararg, b toma
-- el segundo (a y b pueden ser nil si no existen los
-- correspondientes argumentos vararg)
a,b,c = x, f() -- f() se ajusta a 2 resultados
a,b,c = f() -- f() se ajusta a 3 resultados
return f() -- retorna todos los valores devueltos por f()
return ... -- retorna todos los argumentos vararg recibidos
return x,y,f() -- retorna x, y, y todos los valores devueltos por f()
{f()} -- crea una lista con todos los valores retornados por f()
{...} -- crea una lista con todos los argumentos vararg
{f(), nil} -- f() se ajusta a 1 resultado
Una expresión encerrada en paréntesis siempre resulta en un único valor. Entonces, (f(x,y,z)) siempre es un valor único, incluso si f retorna varios valores. (El valor de (f(x,y,z)) es el primer valor retornado por f o nil si f no retorna ningún valor).
+ (adición), - (substracción), * (multiplicación), / (división), % (módulo) y ^ (exponenciación); y el unario - (negación). Si los operandos son números o strings que se convierten a números (véase §2.2.1), entonces todas las operaciones tienen el significado corriente. La exponenciación trabaja con cualquier exponente. Por ejemplo, x^(-0.5) calcula la inversa de la raiz cuadrada de x. El módulo se define como
a % b == a - math.floor(a/b)*bEsto es, es el resto de la división que redondea el cociente hacia menos infinito.
== ~= < > <= >=Devuelven siempre un resultado false o true.
La igualdad (==) primero compara el tipo de los operandos. Si son diferentes entonces el resultado es false. En otro caso se comparan los valores de los operandos. Los números y los strings se comparan de la manera usual. Los objetos (tablas, userdata, procesos y funciones) se comparan por referencia: dos objetos se consideran iguales sólo si son el mismo objeto. Cada vez que se crea un nuevo objeto (una tabla, userdata, proceso o función) este nuevo objeto es diferente de todos los demás objetos preexistentes.
Se puede cambiar la manera en que Lua compara tablas y userdata usando el metamétodo "eq" (véase §2.8).
Las reglas de conversión de §2.2.1 no se aplican en las comparaciones de igualdad. De este modo "0"==0 es false, y t[0] y t["0"] denotan diferentes entradas en una tabla.
El operador ~= es exactamente la negación de la igualdad (==).
El orden de los operadores funciona de la siguiente manera. Si ambos argumentos son números entonces se comparan como tales. En otro caso, si ambos argumentos son strings sus valores se comparan de acuerdo al sistema local. En otro caso, Lua trata de usar los metamétodos "lt" o "le" (véase §2.8).
El operador negación not siempre retorna false o true. El operador conjunción and retorna su primer operando si su valor es false o nil; en caso contrario and retorna su segundo operando. El operador disyunción or retorna su primer operando si su valor es diferente de nil y false; en caso contrario or retorna su segundo argumento. Tanto and como or usan evaluación de cortocircuito; esto es, su segundo operando se evalúa sólo si es necesario. He aquí varios ejemplos:
10 or 20 --> 10
10 or error() --> 10
nil or "a" --> "a"
nil and 10 --> nil
false and error() --> false
false and nil --> false
false or nil --> nil
10 and 20 --> 20
(En este manual '-->' indica el resultado de la expresión precedente.)
..'). Si ambos operandos son strings o números entonces se convierten a strings mediante las reglas mencionadas en §2.2.1. En otro caso se invoca al metamétodo "concat" (véase §2.8).
El operador longitud se denota mediante #. La longitud de un string es su número de bytes (significado normal de la longitud de un string cuando cada carácter ocupa un byte).
La longitud de una tabla t se define como un índice entero n tal que t[n] no es nil y t[n+1] es nil; además, si t[1] es nil entonces n puede ser cero. Para un array regular, con valores no nil desde 1 hasta un n dado, la longitud es exactamente n, el índice es su último valor. Si el array tiene "agujeros" (esto es, valores nil entre otros valores que no lo son), entonces #t puede ser cualquiera de los índices que preceden a un valor nil (esto es, Lua puede considerar ese valor nil como el final del array).
or
and
< > <= >= ~= ==
..
+ -
* / %
not # - (unario)
^
Como es usual, se pueden usar paréntesis para cambiar la precedencia en una expresión. Los operadores de concatenación ('..') y de exponenciación ('^') son asociativos por la derecha. Todos los demás operadores son asociativos por la izquierda.
constructor_de_tabla ::= '{' [lista_de_campos] '}'
lista_de_campos ::= campo {separador_de_campos campo} [separador_de_campos]
campo ::= '[' exp ']' '=' exp | nombre '=' exp | exp
separador_de_campos ::= ',' | ';'
Cada campo de la forma [exp1] = exp2 añade una entrada a la nueva tabla con la clave exp1 y con el valor exp2. Un campo de la forma nombre = exp equivale a ["nombre"] = exp. Finalmente, campos de la forma exp son equivalentes a [i] = exp, donde i son números enteros consecutivos, comenzando con 1. Los campos en el otro formato no afectan este contador. Por ejemplo,
a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }
equivale a
do
local t = {}
t[f(1)] = g
t[1] = "x" -- 1ª exp
t[2] = "y" -- 2ª exp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3ª exp
t[30] = 23
t[4] = 45 -- 4ª exp
a = t
end
Si el último campo en la lista tiene la forma exp y la expresión es una llamada a función o una expresión vararg, entonces todos los valores retornados por esta expresión entran en la lista consecutivamente (véase §2.5.8). Para evitar esto debe encerrarse la llamada a la función (o la expresión vararg) entre paréntesis (véase §2.5).
La lista de campos puede tener un separador opcional al final, una conveniencia para código fuente generado de manera automática.
llamada_a_func ::= prefixexp argumentosEn una llamada a función, se evalúan primero prefixexp y los argumentos. Si el valor de prefixexp es del tipo function, entonces se invoca a esta función con los argumentos dados. En caso contrario se invoca el metamétodo "call", pasando como primer argumento el valor de prefixexp seguido por los argumentos originales de la llamada (véase §2.8).
La forma
llamada_a_func ::= prefixexp ':' nombre argumentospuede ser usada para invocar "métodos". Una llamada
v:nombre(...)
es otra manera de expresar v.nombre(v,...),
excepto que v se evalúa sólo una vez.
Los argumentos tienen la siguiente sintaxis:
argumentos ::= '(' [explist] ')'
argumentos ::= constructor_de_tabla
argumentos ::= String
Todos los argumentos de la expresión se evalúan antes de la llamada. Un llamada de la forma f{...} es otra manera de expresar f({...}); esto es, la lista de argumentos es una nueva tabla simple. Una llamada de la forma f'...' (o f"..." o f[[...]]) es otra manera de expresar f('...'); esto es, la lista de argumentos es un string literal simple.
Como excepción a la sintaxis de formato libre de Lua, no se puede poner una rotura de línea antes de '(' en una llamada a función. Esta restricción evita algunas ambigüedades en el lenguaje. Si se escribe
a = f
(g).x(a)
Lua podría ententerlo como una sentencia simple, a = f(g).x(a). Entonces, si se desean dos sentencias se debe añadir un punto y coma entre ellas. Si realmente se desea llamar a f, se debe eliminar la rotura de línea antes de (g).
Una llamada de la forma return llamada_a_func se denomina una llamada de cola. Lua implementa llamadas de cola correctas (o recursión de cola correcta): en una llamada de cola la función invocada reutiliza la entrada en la pila de la función que la está llamando. Por tanto no existe límite en el número de llamadas de cola anidadas que un programa puede ejecutar. Sin embargo una llamada de cola borra cualquier información de depuración relativa a la función invocante. Nótese que una llamada de cola sólo ocurre con una sintaxis particular donde el return tiene una llamada simple a función como argumento; esta sintásis hace que la función invocante devuelva exactamente el retorno de la función invocada. Según esto ninguno de los siguientes ejemplos son llamadas de cola:
return (f(x)) -- resultados ajustados a 1
return 2 * f(x)
return x, f(x) -- resultados adicionales
f(x); return -- resultados descartados
return x or f(x) -- resultados ajustados a 1
La sintaxis para la definición de funciones es
func ::= function cuerpo_de_func
cuerpo_de_func ::= '(' [lista_de_argumentos] ')' bloque end
La siguiente forma simplifica la definición de funciones:
sentencia ::= function nombre_de_func cuerpo_de_func
sentencia ::= local function nombre cuerpo_de_func
nombre_de_func ::= nombre {'.' nombre} [':' nombre]
La sentencia
function f () cuerpo_de_función endse traduce en
f = function () cuerpo_de_función endLa sentencia
function t.a.b.c.f () cuerpo_de_función endse traduce en
t.a.b.c.f = function () cuerpo_de_función endLa sentencia
local function f () cuerpo_de_función endse traduce en
local f; f = function () cuerpo_de_función endno en:
local f = function () cuerpo_de_función end(Esto sólo entraña diferencias cuando el cuerpo de la función contiene referencias a
f.)
Una definición de función es una expresión ejecutable, cuyo valor tiene el tipo function. Cuando Lua precompila un chunk todos sus cuerpos de función son también precompilados. Entonces cuando Lua ejecuta la definición de función, la misma es instanciada (o cerrada). Esta instancia de función (o closure) es el valor final de la expresión. Diferentes instancias de la misma función pueden referirse a diferentes variables locales externas y pueden tener diferentes tablas de entorno.
Los argumentos formales de una función actúan como variables locales que son inicializadas con los valores actuales de los argumentos:
lista_de_argumentos ::= lista_de_nombres [',' '...'] | '...'Cuando se invoca una función, la lista de argumentos actuales se ajusta a la longitud de la lista de argumentos formales, a no ser que la función sea de tipo vararg, lo que se indica por tres puntos ('
...') al final de la lista de argumentos formales. Una función vararg no ajusta su lista de argumentos; en su lugar recolecta todos los argumentos actuales extra y se los pasa a la función a través de una expresión vararg, lo que también se indica por medio de tres puntos. El valor de esta expresión es una lista de todos los argumentos actuales extra, similar a una función con resultados múltiples. Si la expresión vararg se usa en el interior de otra expresión o en el medio de una lista de expresiones, entonces su retorno se ajusta a un sólo elemento. Si la expresión es usada como el último elemento de una lista de expresiones entonces no se hace ningún ajuste (a no ser que la llamada se realice entre paréntesis).
Como ejemplo, consideremos las siguientes definiciones:
function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 end
Entonces tenemos la siguiente correspondencia de los argumentos actuales a los formales y a la expresión vararg:
LLAMADA ARGUMENTOS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4
f(r(), 10) a=1, b=10
f(r()) a=1, b=2
g(3) a=3, b=nil, ... --> (nada)
g(3, 4) a=3, b=4, ... --> (nada)
g(3, 4, 5, 8) a=3, b=4, ... --> 5 8
g(5, r()) a=5, b=1, ... --> 2 3
Los resultados se devuelven usando la sentencia return (véase §2.4.4). Si el flujo del programa alcanza el final de una función sin encontrar una sentencia return entonces la función retorna sin resultados.
La sintaxis con dos puntos (':') se usa para definir métodos, esto es, funciones que tienen un argumento extra denominado self. Entonces la sentencia
function t.a.b.c:f (params) cuerpo_de_función endes otra manera de expresar
t.a.b.c.f = function (self, params) cuerpo_de_función end
Lua es un lenguaje con ámbito léxico. El ámbito de las variables comienza en la primera sentencia después de su declaración y termina al final del bloque más interno que incluya la declaración. Consideremos el siguiente ejemplo:
x = 10 -- variable global
do -- nuevo bloque
local x = x -- nueva 'x', con valor 10
print(x) --> 10
x = x+1
do -- otro bloque
local x = x+1 -- otra 'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (el valor de la variable global)
Tengase presente que en una declaración como local x = x, la nueva x que está siendo declarada no tiene ámbito todavía, y la segunda x se refiere a la variable externa.
Debido a las reglas de ámbito léxico, las variables locales pueden ser accedidas por funciones definidas en el interior de su propio ámbito. Una variable local usada en una función interna se denomina upvalue o variable local externa en el interior de la función.
Nótese que cada ejecución de una sentencia local define nuevas variables locales. Considérese el siguiente ejemplo:
a = {}
local x = 20
for i=1,10 do
local y = 0
a[i] = function () y=y+1; return x+y end
end
El bucle crea diez closures (esto es, diez instancias de una función anónima). Cada uno de estas instancias usa una variable y diferente, mientras que todas ellas comparten la misma x.
Debido a que Lua es un lenguaje de extensión embebido, todas las acciones de Lua comienzan con código C en el programa anfitrión llamando a una función de la biblioteca de Lua (véase lua_pcall). Cada vez que ocurra un error durante la compilación o ejecución de Lua, el control retorna a C, que puede tomar las medidas apropiadas (tales como imprimir un mensaje de error).
Se puede generar (o activar) explícitamente en Lua un error invocando la función error. Si se necesita capturar errores en Lua se puede usar la función pcall.
Cada valor en Lua puede tener una metatabla. Ésta es una tabla ordinaria de Lua que define el comportamiento del valor original para ciertas operaciones especiales. Se pueden cambiar varios aspectos del comportamiento de las operaciones realizadas sobre un valor estableciendo campos específicos en su metatabla. Por ejemplo, cuando un valor no numérico es un operando de una adición Lua busca una función en el campo "__add" de su metatabla. Si se encuentra una, entonces se invoca esa función para realizar la adición.
Llamamos eventos a los campos de una metatabla y a los valores los denominamos metamétodos. En el ejemplo anterior el evento es "add" mientras que el metamétodo es la función que realiza la adición.
Se puede solicitar la metatabla de cualquier valor a través de la función getmetatable.
Se puede reemplazar la metatabla de una tabla a través de la función setmetatable. No se puede cambiar la metatabla de otros tipos de datos desde Lua (excepto usando la biblioteca de depuración); se debe usar la API de C para ello.
Las tablas y los userdata completos tienen metatablas individuales (aunque varias tablas y userdata pueden compartir sus metatablas); los valores de los otros tipos comparten una única metatabla por tipo. Por tanto, existe una única metatabla para todos los números, otra para todos los strings, etc.
Una metatabla puede controlar cómo se comporta un objeto en las operaciones aritméticas, en las comparaciones de orden, en la concatenación, en la operación longitud y en el indexado. Una metatabla puede también definir una función que será invocada cuando se libera memoria ocupada (garbage collection) por userdata. A cada una de esas operaciones Lua le asocia una clave específica denominada evento. Cuando Lua realiza una de esas operaciones con un valor, comprueba si éste tiene una metatabla con el correspondiente evento. Si es así, el valor asociado con esa clave (el metamétodo) controla cómo realiza Lua la operación.
Las metatablas controlan las operaciones listadas a continuación. Cada operación se identifica por su correspondiente nombre. La clave asociada a cada operación es un string con su nombre prefijado con dos subrayados, '__'; por ejemplo, la clave para la operación "add" es el string "__add". La semántica de esas operaciones está mejor expuesta a través de una función Lua que describe cómo ejecuta el intérprete la operación.
El código Lua mostrado aquí es sólo ilustrativo; el comportamiento real está codificado internamente en el intérprete y es mucho más eficiente que esta simulación. Todas las funciones usadas en estas descripciones (rawget, tonumber, etc.) están descritas en §5.1. En particular, para recuperar el metamétodo de un objeto dado, usamos la expresión
metatable(objeto)[evento]Esto puede también ser expresado mediante
rawget(getmetatable(objeto) or {}, evento)
Por tanto, el acceso a un metamétodo no invoca otros metamétodos, y el acceso a los objetos sin metatablas no falla (simplemente devuelve nil).
+.
La función getbinhandler que aparece más abajo define cómo escoge Lua un manejador de la operación binaria. Primero Lua prueba el primer operando. Si su tipo no define un manejador para la operación entonces Lua lo intenta con el segundo operando.
function getbinhandler (op1, op2, evento) return metatable(op1)[evento] or metatable(op2)[evento] endUsando esta función el comportamiento del código
op1 + op2 es
function add_event (op1, op2)
local o1, o2 = tonumber(op1), tonumber(op2)
if o1 and o2 then -- ¿son numéricos ambos operandos?
return o1 + o2 -- '+' aquí es la primitiva 'add'
else -- al menos uno de los operandos es no numérico
local h = getbinhandler(op1, op2, "__add")
if h then
-- invoca el manejador de ambos operandos
return (h(op1, op2))
else -- no existe un manejador disponible: comportamiento por defecto
error(···)
end
end
end
-.
El comportamiento es similar a la operación "add".
*.
El comportamiento es similar a la operación "add".
/.
El comportamiento es similar a la operación "add".
%.
El comportamiento es similar a la operación "add", usando o1 - floor(o1/o2)*o2 como operación primitiva.
^ (exponenciación).
El comportamiento es similar a la operación "add", con la función pow (de la biblioteca matemática de C) como operación primitiva.
- unaria.
function unm_event (op)
local o = tonumber(op)
if o then -- ¿es numérico el operando?
return -o -- '-' aquí es la función primitiva 'unm'
else -- el operando no es numérico.
-- intentar obtener un manejador para el operando
local h = metatable(op).__unm
if h then
-- invocar el manejador con el operando
return (h(op))
else -- no hay manejador disponible: comportamiento por defecto
error(···)
end
end
end
.. (concatenación).
function concat_event (op1, op2)
if (type(op1) == "string" or type(op1) == "number") and
(type(op2) == "string" or type(op2) == "number") then
return op1 .. op2 -- concatenación primitiva de strings
else
local h = getbinhandler(op1, op2, "__concat")
if h then
return (h(op1, op2))
else
error(···)
end
end
end
#.
function len_event (op)
if type(op) == "string" then
return strlen(op) -- longitud primitiva de string
elseif type(op) == "table" then
return #op -- longitud primitiva de tabla
else
local h = metatable(op).__len
if h then
-- invocar el manejador con el operando
return (h(op))
else -- no hay manejador disponible: comportamiento por defecto
error(···)
end
end
end
Véase §2.5.5 para una descripción de la longitud de una tabla.
==.
La función getcomphandler define cómo elige Lua un metamétodo para el operador de comparación. Se selecciona un metamétodo cuando ambos objetos que son comparados tienen el mismo tipo y el mismo metamétodo para la operación dada.
function getcomphandler (op1, op2, evento) if type(op1) ~= type(op2) then return nil end local mm1 = metatable(op1)[evento] local mm2 = metatable(op2)[evento] if mm1 == mm2 then return mm1 else return nil end endEl evento "eq" se define así:
function eq_event (op1, op2)
if type(op1) ~= type(op2) then -- ¿diferentes tipos?
return false -- diferentes objetos
end
if op1 == op2 then -- ¿iguales primitivas?
return true -- los objetos son iguales
end
-- probar un metamétodo
local h = getcomphandler(op1, op2, "__eq")
if h then
return (h(op1, op2))
else
return false
end
end
a ~= b equivale a not (a == b).
<.
function lt_event (op1, op2)
if type(op1) == "number" and type(op2) == "number" then
return op1 < op2 -- comparación numérica
elseif type(op1) == "string" and type(op2) == "string" then
return op1 < op2 -- comparación lexicográfica
else
local h = getcomphandler(op1, op2, "__lt")
if h then
return (h(op1, op2))
else
error(···);
end
end
end
a > b equivale a b < a.
<=.
function le_event (op1, op2)
if type(op1) == "number" and type(op2) == "number" then
return op1 <= op2 -- comparación numérica
elseif type(op1) == "string" and type(op2) == "string" then
return op1 <= op2 -- comparación lexicográfica
else
local h = getcomphandler(op1, op2, "__le")
if h then
return h(op1, op2)
else
h = getcomphandler(op1, op2, "__lt")
if h then
return not h(op2, op1)
else
error(···);
end
end
end
end
a >= b equivale a b <= a. Téngase presente que en ausencia de un metamétodo "le" Lua intenta usar el de "lt", asumiendo que a <= b equivale a not (b < a).
tabla[clave].
function gettable_event (tabla, clave)
local h
if type(tabla) == "table" then
local v = rawget(tabla, clave)
if v ~= nil then return v end
h = metatable(tabla).__index
if h == nil then return nil end
else
h = metatable(tabla).__index
if h == nil then
error(···);
end
end
if type(h) == "function" then
return (h(tabla, clave)) -- invocar el manejador
else return h[clave] -- o repetir la operación con él
end
end
tabla[clave] = valor.
function settable_event (tabla, clave, valor)
local h
if type(tabla) == "table" then
local v = rawget(tabla, clave)
if v ~= nil then rawset(tabla, clave, valor); return end
h = metatable(tabla).__newindex
if h == nil then rawset(tabla, clave, valor); return end
else
h = metatable(tabla).__newindex
if h == nil then
error(···);
end
end
if type(h) == "function" then
h(tabla, clave, valor) -- invoca el manejador
else h[clave] = valor -- o repite la operación con él
end
end
function function_event (func, ...)
if type(func) == "function" then
return func(...) -- llamada primitiva
else
local h = metatable(func).__call
if h then
return h(func, ...)
else
error(···)
end
end
end
Además de metatablas, los objetos de tipo proceso, las funciones y los userdata tienen otra tabla asociada, denominada entorno. Como las metatablas los entornos son tablas normales y varios objetos pueden compartir el mismo entorno.
Los entornos asociados con userdata no tienen significado en Lua. Es sólo una característica para los programadores asociar una tabla con userdata.
Los entornos asociados con procesos se denominan entornos globales. Son usados como entornos por defecto para los procesos y para las funciones no anidadas creadas por el proceso (a través de loadfile, loadstring o load) y pueden ser accedidas directamente por el código en C (véase §3.3).
Los entornos asociados con funciones C pueden ser accedidos directamente por el código en C (véase §3.3). Son usadas como entornos por defecto por otras funciones C creadas por la función dada.
Los entornos asociados con funciones en Lua son utilizados para resolver todos los accesos a las variables globales dentro de la función (véase §2.3). Son usados también como entornos por defecto por otras funciones en Lua creadas por la función.
Se puede cambiar el entorno de una función Lua o de un proceso en ejecución invocando setfenv. Se puede obtener el entorno de una función Lua o del proceso en ejecución invocando getfenv. Para manejar el entorno de otros objetos (userdata, funciones C, otros procesos) se debe usar la API de C.
Lua realiza automáticamente la gestión de la memoria. Esto significa que no debemos preocuparnos ni de asignar (o reservar) memoria para nuevos objetos ni de liberarla cuando los objetos dejan de ser necesarios. Lua gestiona la memoria automáticamente ejecutando un liberador de memoria (garbage collector) de cuando en cuando para eliminar todos los objetos muertos (esos objetos que ya no son accesibles desde Lua). Todos los objetos en Lua son susceptibles de gestión automática: tablas, userdata, funciones, procesos y strings.
Lua implementa un liberador de memoria del tipo marcado-barrido incremental. Utiliza dos números para controlar sus ciclos de liberación de memoria: la pausa del liberador de memoria y el multiplicador del paso del liberador de memoria.
La pausa del liberador de memoria controla cuánto tiempo debe esperar el liberador de memoria antes de comenzar un nuevo ciclo. Valores grandes hacen al liberador menos agresivo. Valores menores que 1 significan que el liberador no esperará para comenzar un nuevo ciclo. Un valor de 2 significa que el liberador espera que la memoria total en uso se doble antes de comenzar un nuevo ciclo.
El multiplicador del paso controla la velocidad relativa del liberador en cuanto a asignación de memoria. Los valores más largos hacen el liberador más agresivo pero también aumentan el tamaño de cada paso incremental. Valores menores que 1 hacen el liberador demasiado lento y puede resultar en que el liberador nunca acabe un ciclo. El número por defecto, 2, significa que el liberador se ejecuta a una velocidad doble que la asignación de memoria.
Se pueden cambiar esos números invocando en C a lua_gc o en Lua a collectgarbage. Ambos tienen como argumentos un porcentaje (y entonces un argumento 100 significa un valor real de 1). Con esas funciones se puede también controlar el liberador directamente (por ejemplo, pararlo y reiniciarlo).
Usando la API de C se pueden establecer metamétodos liberadores de memoria para userdata (véase §2.8). Esos metamétodos se denominan también finalizadores. Éstos permiten coordinar el sistema de liberación de memoria de Lua con gestores externos de recursos (tales como cerrar ficheros, conexiones de red o de bases de datos, o liberar su propia memoria).
Los userdata que se van a liberar con un campo __gc en sus metatablas no son liberados inmediatamente por el liberador de memoria. En su lugar Lua los pone en una lista. Después de eso Lua hace el equivalente a la siguiente función para cada userdata en la lista:
function gc_event (udata)
local h = metatable(udata).__gc
if h then
h(udata)
end
end
Al final de cada ciclo de liberación de memoria, los finalizadores de userdata que aparecen en la lista que va a ser liberada son invocados en orden inverso al de su creación. Esto es, el primer finalizador en ser invocado es el que está asociado con el userdata creado en último lugar por el programa. El propio userdata puede ser liberado sólo en el próximo ciclo de liberación de memoria.
Una tabla débil es una tabla cuyos elementos son referencias débiles. Una referencia débil es ignorada por el liberador de memoria. En otras palabras, si las únicas referencias a un objeto son referencias débiles entonces se libera la memoria asociada con este objeto.
Una tabla débil puede tener claves débiles, valores débiles o ambas cosas. Una tabla con claves débiles permite la liberación de sus claves, pero prohibe la liberación de sus valores. Una tabla con claves débiles y valores débiles permite la liberación tanto de claves como de valores. En cualquier caso, ya sea la clave o el valor el liberado, el par completo es eliminado de la tabla. La debilidad de una tabla está controlada por el campo __mode de su metatabla. Si el campo __mode es un string que contiene el carácter 'k', las claves en la tabla son débiles. Si __mode contiene 'v', los valores en la tabla son débiles.
Después de usar una tabla como metatabla no se debería cambiar el valor de su campo __mode. En caso contrario el comportamiento débil de las tablas controladas por esa metatabla es indefinido.
Lua tiene co-rutinas, también denominadas multiprocesos colaborativos. En Lua una co-rutina representa un proceso de ejecución independiente. A diferencia de los sistemas multiproceso, en Lua una co-rutina sólo suspende su ejecución invocando de manera explícita una función yield (cesión).
Se pueden crear co-rutinas con una llamada a coroutine.create. El único argumento de esta función es otra función que es la función principal de la co-rutina.
Cuando se llama por primera vez a coroutine.resume, pasándole como argumento el proceso retornado por coroutine.create, la co-rutina comienza a ejecutarse en la primera línea de su función principal. Los argumentos extra pasados a coroutine.resume se pasan a su vez a la función principal de la co-rutina. Después de que la co-rutina empieza a ejecutarse lo hace hasta que termina o se produce una cesión del control de flujo del programa.
Una co-rutina puede terminar su ejecución de dos maneras: normalmente, cuando su función principal retorna (explícita o implícitamente, después de su última instrucción); y anormalmente, si se produjo un error no protegido. En el primer caso, coroutine.resume devuelve true, más cualquier valor retornado por la función principal de la co-rutina. En caso de error coroutine.resume devuelve false más un mensaje de error.
Una co-rutina cede el control invocando a coroutine.yield. Cuando una co-rutina cede el control la correspondiente coroutine.resume retorna inmediatamente, incluso si la cesión ocurre dentro de una llamada a una función anidada (esto es, no en la función principal, sino en una función directa o indirectamente invocada desde la función principal). En el caso de una cesión, coroutine.resume también devuelve true, más cualesquiera valores pasados a coroutine.yield. La próxima vez que se resuma la misma co-rutina, continuará su ejecución desde el punto en que fue realizada la cesión, con la llamada a coroutine.yield devolviendo cualquier argumento extra pasado a coroutine.resume.
La función coroutine.wrap crea una co-rutina, justo igual que lo haría coroutine.create, pero en lugar de retornar la co-rutina misma, devuelve una función que, cuando es invocada resume la co-rutina. Cualesquiera argumentos pasados a esta función pasan como argumentos a coroutine.resume. coroutine.wrap devuelve todos los valores retornados por coroutine.resume, excepto el primero (el código booleano de error). A diferencia de coroutine.resume, coroutine.wrap no captura errores; cualquier error se propaga a la rutina invocante.
Como ejemplo, considérese el siguiente código:
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))
Cuando se ejecuta se produce la siguiente salida:
co-body 1 10 foo 2 main true 4 co-body r main true 11 -9 co-body x y main true 10 end main false cannot resume dead coroutine
Esta sección describe la API de C para Lua, esto es, el conjunto de funciones C disponibles para que el programa anfitrión se comunique con Lua. Todas las funciones de la API y sus tipos y constantes relacionados están declaradas en el fichero de cabecera lua.h.
Aunque se usa el término "function", algunas rutinas en la API pueden ser macros. Todas esas macros usan cada uno de sus argumentos exactamente una vez (excepto su primer argumento, que es siempre el estado de Lua), y por tanto no generan efectos laterales ocultos.
Como en la mayoría de las bibliotecas de C, la funciones API de Lua no verifican la validez ni la consistencia de sus argumentos. Sin embargo se puede cambiar este comportamiento compilando Lua con las definiciones adecuadas para la macro luai_apicheck, en el fichero luaconf.h.
Lua usa una pila virtual para pasar valores a y desde C. Cada elemento en esta pila representa un valor de Lua (nil, número, string, etc.).
Siempre que Lua llame al C, la función llamada obtiene una nueva pila, que es independiente de las pilas anteriores y de las pilas de las funciones C que todavía están activas. Esta pila contiene inicialmente cualquier argumento de la función C y es donde ésta coloca los resultados que deben ser devueltos a la rutina invocadora (véase lua_CFunction).
Por conveniencia, la mayoría de las operaciones de petición de la API no siguen una disciplina estricta de pila. En su lugar pueden referirse a cualquier elemento en la pila usando un índice: un valor positivo representa una posición absoluta en la pila (comenzando en 1); un valor negativo representa un desplazamiento relativo a la parte superior de la pila. Más específicamente, si la pila tiene n elementos, entonces el índice 1 representa el primer elemento (esto es, el elemento que fue colocado primero en la pila) y un índice n representa el último elemento; un índice -1 también representa el último elemento (esto es, el elemento en la parte superior) y un índice -n representa el primer elemento. Decimos que un índice es válido si tiene un valor comprendido entre 1 y la parte superior de la pila (esto es, si 1 ≤ abs(índice) ≤ top).
Cuando el programador interacciona con la API de Lua es responsable de asegurar la consistencia. En particular es responsable de controlar el crecimiento correcto de la pila. Se puede usar la función lua_checkstack para hacer crecer el tamaño de la pila.
Siempre que Lua llama al C, se asegura de que al menos existen LUA_MINSTACK posiciones disponibles en la pila. LUA_MINSTACK está definida como 20, así que normalmente el programador no tiene que preocuparse del espacio en la pila, a no ser que su código tenga bucles que coloquen elementos en la pila.
La mayoría de las funciones de petición aceptan como índice cualquier valor dentro del espacio disponible en la pila, o sea índices hasta el máximo del tamaño de la pila establecido mediante lua_checkstack. Esos índices se denominan índices aceptables.
Más formalmente, definimos un índice aceptable de la siguiente manera:
(índice < 0 && abs(índice) <= top) ||
(índice > 0 && índice <= stackspace)
Nótese que 0 no es nunca un índice aceptable.
Excepto en los casos en que se indique, cualquier función que acepta índices válidos también puede ser invocada con pseudoíndices, los cuales representan algunos valores en Lua que son accesibles desde el código en C pero que no están en la pila. Los pseudoíndices son usados para acceder al entorno del proceso, al entorno de la función, al registro y a los upvalues de una función C (véase §3.4).
El entorno del proceso (donde "viven" las variables globales) está siempre en el pseudoíndice LUA_GLOBALSINDEX. El entorno de una función C que está en ejecución está siempre en el pseudoíndice LUA_ENVIRONINDEX.
Para acceder y cambiar el valor de una variable global se pueden usar operaciones normales de tabla en la tabla de entorno. Por ejemplo, para acceder al valor de una variable global se hace
lua_getfield(L, LUA_GLOBALSINDEX, nombre_de_variable_global);
Cuando se crea una función C es posible asociarle algunos valores, creando una instancia en C; esos valores se denominan upvalues y son accesibles a la función en cualquier momento en que sea invocada (véase lua_pushcclosure).
Siempre que se invoque a una función C sus upvalues se localizan en pseudoíndices específicos. Éstos se producen mediante la macro lua_upvalueindex. El primer valor asociado con una función está en la posición lua_upvalueindex(1), y así sucesivamente. Cualquier acceso a lua_upvalueindex(n), donde n es mayor que el número de upvalues de la función actual produce un índice aceptable pero inválido.
Lua proporciona un registro, una tabla predefinida que puede ser usada por cualquier código en C para almacenar cualquier valor que Lua necesite guardar. Esta tabla se localiza siempre en el pseudoíndice LUA_REGISTRYINDEX. Cualquier biblioteca de C puede almacenar datos en esta tabla, pero debería tener cuidado de elegir claves diferentes de aquéllas usadas por otras bibliotecas, para evitar conflictos. Típicamente se podría usar como clave un string conteniendo el nombre de la biblioteca o userdata "ligeros" con la dirección de un objeto de C en el código.
Las claves de tipo entero en el registro son usadas como mecanismo para referenciar, implementado en la biblioteca auxiliar, y por tanto no deberían ser usados para otros propósitos diferentes.
Internamente Lua usa la función de C longjmp para facilitar el manejo de errores. (Se puede también elegir usar directamente excepciones si se trabaja en C++; véase el fichero luaconf.h.) Cuando Lua se encuentra con cualquier error (tal como un error de asignación de memoria, un error de tipo, un error de sintaxis o un error de ejecución) entonces activa un error, esto es, realiza un salto largo en la memoria. Un entorno protegido usa setjmp para establecer un punto de recuperación; cualquier error provoca un salto al punto de recuperación activo más reciente.
Muchas funciones de la API pueden activar un error, por ejemplo debido a un problema de asignación de memoria. La documentación de cada función indica si puede activar un error.
Dentro de una función C se puede activar un error invocando lua_error.
He aquí la lista de todas las funciones y tipos de la API de C por orden alfabético. Cada función tiene un indicador como éste: [-o, +p, x]
El primer campo, o, indica cuántos elementos elimina la función en la pila. El segundo campo, p, es cuantos elementos coloca la función en la pila. (Toda función siempre coloca sus resultados después de eliminar sus argumentos.) Un campo de la forma x|y significa que la función puede colocar (o eliminar) x ó y elementos, dependiendo de la situación; un signo de interrogación '?' significa que no se puede conocer cuántos elementos coloca/elimina la función observando sólo sus argumentos (por ejemplo, puede depender de lo qué esté en la pila). El tercer, campo x, indica si la función puede activar errores: '-' significa que la función nunca activa errores; 'm' indica que la función puede activar un error sólo debido a falta de memoria; 'e' indica que la función puede activar otros tipos de errores; 'v' indica que la función puede activar un error a propósito.
lua_Alloc
typedef void * (*lua_Alloc) (void *ud,
void *ptr,
size_t osize,
size_t nsize);
El tipo de la función que maneja la memoria usada por los estados de Lua. La función que maneja memoria debe proporcionar una funcionalidad similar a realloc, pero no exactamente la misma. Sus argumentos son: ud, un puntero opaco pasado a lua_newstate; ptr, un puntero al bloque que está siendo reservado/reasignado/liberado; osize, el tamaño original del bloque; nsize, el nuevo tamaño del bloque. ptr es NULL si y sólo si osize es cero. Cuando nsize es cero, el manejador debe retornar NULL; si osize no es cero debe ser liberado el bloque apuntado por ptr. Cuando nsize no es cero el manejador retorna NULL si y sólo si no puede ejecutar la petición. Cuando nsize no es cero y osize es cero el manejador debería comportarse como malloc. Cuando nsize y osize no son cero, el manejador se comporta como realloc. Lua asume que el manejador nunca falla cuando osize >= nsize.
He aquí una implementación simple para la función manejadora de memoria. Es usada en la biblioteca auxiliar por lua_newstate.
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void) ud; (void) osize; /* no usadas */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
Este código asume que free(NULL) no tiene efecto y que realloc(NULL, size) es equivalente a malloc(size). ANSI C asegura ambos comportamientos.
lua_atpanic[-0, +0, -]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Establece una nueva función de pánico y devuelve la vieja.
Si ocurre un error fuera de cualquier entorno protegido Lua llama a la función pánico y luego invoca exit(EXIT_FAILURE), saliendo por tanto de la aplicación anfitriona. Si usa otra función de pánico diferente, ésta puede evitar esta salida sin retorno (por ejemplo, haciendo un salto largo).
La función de pánico puede acceder al mensaje de error en la parte superior de la pila.
lua_call[-(nargs + 1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
Llama a una función.
Para llamar a una función se debe usar el siguiente protocolo: primero, la función a ser invocada se coloca en la parte superior de la pila; entonces, se colocan también en la pila los argumentos de la función en orden directo; esto es, el primer argumento se coloca primero. Finalmente, se llama a lua_call; nargs es el número de argumentos que se han colocado en la pila. Todos los argumentos y el valor de la función se eliminan de la pila cuando la función es invocada. Los resultados de la función se colocan en la parte superior de la pila cuando retorna la función. El número de resultados se ajusta a nresults, a no ser que nresults sea LUA_MULTRET. En este caso se colocan todos los resultados de la función. Lua tiene cuidado de que los valores retornados se ajusten en el espacio de pila. Los resultados de la función son colocados en la pila en orden directo (el primero es colocado antes), por lo que después de la llamada el último resultado aparece en la parte superior de la pila.
Cualquier error dentro de la función llamada se propaga hacia atrás (con un longjmp).
El siguiente ejemplo muestra cómo puede el programa anfitrión hacer algo equivalente a este código en Lua:
a = f("how", t.x, 14)
Aquí está en C:
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* función que es llamada */
lua_pushstring(L, "how"); /* primer argumento */
lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* tabla que es indexada */
lua_getfield(L, -1, "x"); /* coloca en la pila t.x (2º argumento) */
lua_remove(L, -2); /* elimina 't' de la pila */
lua_pushinteger(L, 14); /* 3º argumento */
lua_call(L, 3, 1); /* llama a la función con 3 argumentos y 1 resultado */
lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* modifica la variable global 'a' */
Téngase presente que el código de arriba está "equilibrado" al final, pues la pila ha vuelto a su configuración inicial. Esto está considerado como una buena práctica de programación.
lua_atpanic[-0, +0, -]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
Tipo para las funciones C.
Con objeto de comunicar adecuadamente con Lua, una función C debe usar el siguiente protocolo, el cual define la manera en que son pasados los argumentos y los resultados: una función C recibe sus argumentos desde Lua en su pila en orden directo (el primer argumento se coloca primero). Por tanto, cuando comienza una función, lua_gettop(L) devuelve el número de argumentos recibidos por la función. Su primer argumento (si existe) está en el índice 1 y su último argumento está en el índice lua_gettop(L). Para retornar valores a Lua una función C sólo los coloca en la pila, en orden directo (el primer resultado va primero), y retorna el número de resultados. Cualquier otro valor en la pila por debajo de los resultados debe ser adecuadamente descartado por Lua. Como una función Lua, una función C llamada desde Lua puede retornar varios resultados.
Como ejemplo, la siguiente función recibe un número variable de argumentos numéricos y retorna su media y su suma:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* número de argumentos */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "argumento incorrecto en la función 'media'");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* primer resultado */
lua_pushnumber(L, sum); /* segundo resultado */
return 2; /* número de resultados */
}
lua_checkstack[-0, +0, m]
int lua_checkstack (lua_State *L, int extra);
Se asegura de que hay al menos extra posiciones libres en la pila. Devuelve false si no puede hacer crecer la pila hasta ese tamaño. Esta función nunca disminuye la pila; si la pila es ya más grande que el nuevo tamaño la deja sin modificar.
lua_close[-0, +0, -]
void lua_close (lua_State *L);
Destruye todos los objetos en el estado dado de Lua (llamando al correspondiente metamétodo de liberación de memoria, si existe) y libera toda la memoria dinámica usada por este estado. En algunas plataformas puede no ser necesario llamar a esta función, debido a que todos los recursos se liberan de manera natural cuando finaliza el programa anfitrión. Por otro lado, programas de ejecución larga, como puede ser el demonio de un servidor web, pueden necesitar la liberación de estados tan pronto como éstos no se necesiten para evitar un crecimiento desmesurado.
lua_concat[-n, +1, e]
void lua_concat (lua_State *L, int n);
Concatena los n valores de la parte superior de la pila, los elimina y deja el resultado en la parte superior de la pila. Si n es 1 el resultado es el valor simple en la pila (esto es, la función no hace nada); si n es 0 el resultado es un string vacío. La concatenación se realiza siguiendo la semántica normal de Lua (véase §2.5.4).
lua_cpcall[-0, +(0|1), -]
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
Invoca la función C func en modo protegido. func comienza con un solo elemento en su pila, un userdata ligero conteniendo ud. En caso de errores lua_cpcall devuelve el mismo código de error que lua_pcall, además del objeto error en la parte superior de la pila; en caso contrario retorna cero y no cambia la pila. Todos los valores retornados por func se descartan.
lua_createtable[-0, +1, m]
void lua_createtable (lua_State *L, int narr, int nrec);
Crea una nueva tabla vacía y la coloca en la pila. La nueva tabla tiene espacio reservado para narr elementos array y nrec elementos no array. Esta reserva es útil cuando no se sabe cuántos elementos va a contener la tabla. En otro caso se puede usar la función lua_newtable.
lua_dump[-0, +0, m]
int lua_dump (lua_State *L, lua_Writer writer, void *data);
Vuelca una función en forma de chunk binario. Recibe una función de Lua en la parte superior de la pila y produce un chunk binario que si se carga de nuevo resulta en una función equivalente a la volcada previamente. Según va produciendo partes del chunk, lua_dump invoca a la función writer (véase lua_Writer) con los datos data para escribirlos.
El valor retornado es el código de error devuelto por la última llamada a Writer; 0 significa no error.
Esta función no elimina de la pila la función de Lua.
lua_equal[-0, +0, e]
int lua_equal (lua_State *L, int index1, int index2);
Retorna 1 si los dos valores en los índices aceptables index1 e index2 son iguales, siguiendo la semántica del operador == de Lua (esto es, puede invocar metamétodos). En otro caso retorna 0. También devuelve 0 si alguno de los índices no es válido.
lua_error[-1, +0, v]
int lua_error (lua_State *L);
Genera un error de Lua. El mensaje de error (que puede ser realmente un valor de Lua de cualquier tipo) debe de estar en la parte superior de la pila. Esta función realiza un salto largo, y por tanto nunca retorna. (véase luaL_error).
lua_gc[-0, +0, e]
int lua_gc (lua_State *L, int what, int data);
Controla el liberador de memoria.
Esta función realiza varias tareas, de acuerdo con el valor del argumento what:
LUA_GCSTOP --- detiene el liberador de memoria.
LUA_GCRESTART --- reinicia el liberador de memoria.
LUA_GCCOLLECT --- realiza un ciclo completo de liberación de memoria.
LUA_GCCOUNT --- retorna la cantidad actual de
memoria (en Kbytes) en uso por Lua.
LUA_GCCOUNTB --- retorna el resto de dividir por 1024 la cantidad actual de memoria en bytes en uso por Lua.
LUA_GCSTEP --- realiza un paso incremental de liberación de memoria. El "tamaño" del paso está controlado por data (un valor mayor significa más pasos) de una manera no especificada. Si se desea controlar el tamaño del paso se debe afinar experimentalmente el valor de data. La función retorna 1 si el paso acabó con un ciclo de liberación de memoria.
LUA_GCSETPAUSE --- establece data/100 como el nuevo valor de la pausa del liberador de memoria (véase §2.10). La función retorna el valor previo de la pausa.
LUA_GCSETSTEPMUL --- establece data/100 como el nuevo valor del multiplicador del paso del liberador de memoria (véase §2.10). La función retorna el valor previo del multiplicador.
lua_getallocf[-0, +0, -]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
Retorna la función manejadora de memoria de un estado dado. Si ud no es NULL Lua guarda en *ud el puntero opaco pasado a lua_newstate.
lua_getfenv[-0, +1, -]
void lua_getfenv (lua_State *L, int index);
Coloca en la pila la tabla de entorno de un valor en el índice dado.
lua_getfield[-0, +1, e]
void lua_getfield (lua_State *L, int index, const char *k);
Coloca en la pila el valor t[k], donde t es el valor dado por el índice válido. Como en Lua esta función puede activar un metamétodo para el evento "index" (véase §2.8).
lua_getglobal[-0, +1, e]
void lua_getglobal (lua_State *L, const char *name);
Coloca en la pila el valor del nombre global. Está definida como macro:
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
lua_getmetatable[-0, +(0|1), -]
int lua_getmetatable (lua_State *L, int index);
Coloca en la pila la metatabla del valor situado en el índice aceptable dado. Si el índice no es válido o si el valor no tiene metatabla, la función retorna 0 y no coloca nada en la pila.
lua_gettable[-1, +1, e]
void lua_gettable (lua_State *L, int index);
Coloca en la pila el valor t[k], donde t es el valor en el índice válido y k es el valor situado en la parte superior de la pila.
Esta función quita la clave de la parte superior de la pila (colocando a su vez el valor resultante en su lugar). Como en Lua esta función puede activar un metamétodo para el evento "index" (véase §2.8).
lua_gettop[-0, +0, -]
int lua_gettop (lua_State *L);
Retorna el índice del elemento situado en la parte superior de la pila. Debido a que los índices comienzan en 1 este resultado es igual al número de elementos en la pila (y así, 0 significa una pila vacía).
lua_insert[-1, +1, -]
void lua_insert (lua_State *L, int index);
Mueve el elemento situado en la parte superior de la pila hacia el índice válido dado, desplazando hacia arriba los elementos por encima de este índice para abrir hueco. No puede ser invocada con un pseudoíndice debido a que éste no es una posición real en la pila.
lua_Integertypedef ptrdiff_t lua_Integer;
El tipo usado por la API de Lua para representar valores enteros.
Por defecto es ptrdiff_t, que es normalmente el tipo entero con signo más grande que la máquina maneja "confortablemente".
lua_isboolean[-0, +0, -]
int lua_isboolean (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable tiene tipo booleano y 0 en caso contrario.
lua_iscfunction[-0, +0, -]
int lua_iscfunction (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es una función C y 0 en caso contrario.
lua_isfunction[-0, +0, -]
int lua_isfunction (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es una función (en C o en Lua) y 0 en caso contrario.
lua_islightuserdata[-0, +0, -]
int lua_islightuserdata (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es un userdata ligero y 0 en caso contrario.
lua_isnil[-0, +0, -]
int lua_isnil (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es nil y 0 en caso contrario.
lua_isnone[-0, +0, -]
int lua_isnone (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es no válido (esto es, si se refiere a un elemento fuera de la pila actual) y 0 en caso contrario.
lua_isnoneornil[-0, +0, -]
int lua_isnoneornil (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es no válido (esto es, si se refiere a un elemento fuera de la pila actual) o si el valor en este índice es nil, y 0 en caso contrario.
lua_isnumber[-0, +0, -]
int lua_isnumber (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es un número o un string convertible a número y 0 en caso contrario.
lua_isstring[-0, +0, -]
int lua_isstring (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es un string o un número (que es siempre convertible a un string) y 0 en caso contrario.
lua_istable[-0, +0, -]
int lua_istable (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es una tabla y 0 en caso contrario.
lua_isthread[-0, +0, -]
int lua_isthread (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es un proceso y 0 en caso contrario.
lua_isuserdata[-0, +0, -]
int lua_isuserdata (lua_State *L, int index);
Retorna 1 si el valor en la situación del índice aceptable es un userdata (ligero o completo) y 0 en caso contrario.
lua_lessthan[-0, +0, e]
int lua_lessthan (lua_State *L, int index1, int index2);
Retorna 1 si el valor situado en la posición del índice aceptable index1 es menor que el situado en la posición del índice aceptable index2, siguiendo la semántica del operador < de Lua (esto es, puede invocar metamétodos). En caso contrario retorna 0. También retorna 0 si alguno de los índices es inválido.
lua_load[-0, +1, -]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *chunkname);
Carga un chunk de Lua. Si no hay errores, lua_load coloca el chunk compilado en la parte superior de la pila. En caso contrario coloca ahí un mensaje de error. Los valores de retorno de lua_load son:
LUA_ERRSYNTAX ---
error de sintaxis durante la precompilación.
LUA_ERRMEM ---
error de reserva de memoria.
lua_load detecta automáticametne si el chunk está en binario o en forma de texto, y lo carga de acuerdo con esto (véase el programa luac).
lua_load usa una función lectora suplida por el usuario para leer el chunk (véase lua_Reader). El argumento data es un valor opaco pasado a la función lectora.
El argumento chunkname da un nombre al chunk. el cual es usado en los mensajes de error y en la información de depuración (véase §3.8).
lua_newstate[-0, +0, -]
lua_State *lua_newstate (lua_Alloc f, void *ud);
Crea un nuevo estado independiente. Retorna NULL si no puede crear el estado (debido a falta de memoria). El argumento f es la función de reserva de memoria; Lua hace toda la reserva de memoria para este estado a través de esta función. El segundo argumento, ud, es un puntero opaco que Lua simplemente pasa al reservador de memoria en cada llamada.
lua_newtable[-0, +1, m]
void lua_newtable (lua_State *L);
Crea una nueva tabla vacía y la coloca en la pila. Equivale a lua_createtable(L, 0, 0).
lua_newthread[-0, +1, m]
lua_State *lua_newthread (lua_State *L);
Crea un nuevo proceso, lo coloca en la pila y retorna un puntero a un lua_State que representa este nuevo proceso. El nuevo estado retornado por esta función comparte con el original todos los objetos globales (como las tablas), pero tiene una pila de ejecución independiente.
No existe una función explícita para cerrar o destruir un proceso. Los procesos están sujetos a liberación de memoria, como cualquier otro objeto de Lua.
lua_newuserdata[-0, +1, m]
void *lua_newuserdata (lua_State *L, size_t size);
Esta función reserva un nuevo bloque de memoria con el tamaño dado, coloca en la pila un nuevo userdata completo con la dirección del bloque de memoria y retorna esta dirección.
Los userdata representan valores de C en Lua. Un userdata completo representa un bloque de memoria. Es un objeto (como una tabla): se puede crear, puede tener su propia metatabla y se puede detectar cuándo está siendo eliminado de memoria. Un userdata completo es sólo igual a sí mismo (en un test de igualdad directa).
Cuando Lua libera un userdata completo con un metamétodo gc, llama al metamétodo y marca el userdata como finalizado. Cuando este userdata es liberado de nuevo entonces es cuando Lua libera definitivamente la memoria correspondiente.
lua_next[-1, +(2|0), e]
int lua_next (lua_State *L, int index);
Elimina una clave de la pila y coloca un par clave-valor de una tabla en el índice dado (la "siguiente" pareja después de la clave dada). Si no hay más elementos en la tabla entonces lua_next retorna 0 (y no coloca nada en la pila).
Una típica iteración de recorrido de tabla sería:
/* la tabla está en la pila en el índice 't' */
lua_pushnil(L); /* primera clave */
while (lua_next(L, t) != 0) {
/* 'clave' está en el índice -2 y 'valor' en el índice -1 */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* elimina 'valor'; mantiene 'clave' para la siguiente iteración */
lua_pop(L, 1);
}
Mientras se recorre una tabla no debe llamarse a lua_tolstring directamente en una clave a no ser que se conozca que la clave es realmente un string. Recuerde que lua_tolstring cambia el valor en el índice dado; esto confunde a la siguiente llamada a lua_next.
lua_Numbertypedef double lua_Number;
El tipo de los números en Lua. Por defecto es un double, pero puede ser cambiado en luaconf.h.
A través del fichero de configuración se puede cambiar Lua para que opere con otro tipo de números (por ejemplo, float o long).
lua_objlen[-0, +0, -]
size_t lua_objlen (lua_State *L, int index);
Retorna la "longitud" de un valor situado en el índice aceptable: para un string, es la longitud del mismo; para una tabla, es el resultado del operador longitud ('#'); para un userdata, es el tamaño del bloque de memoria reservado para el mismo; para otros valores es 0.
lua_pcall[-(nargs + 1), +(nresults|1), -]
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
Invoca una función en modo protegido.
Tanto nargs como nresults tienen el mismo significado que en lua_call. Si no hay errores durante la llamada, lua_pcall se comporta exactamente igual que lua_call. Sin embargo en caso de error lua_pcall lo captura, colocando un único valor en la pila (el mensaje de error) y retorna un código de error. Como lua_call, lua_pcall siempre elimina la función y sus argumentos de la pila.
Si errfunc es 0 entonces el mensaje de error retornado en la pila es exactamente el mensaje original. En otro caso, errfunc es el índice en la pila de una función manejadora de error. (En la implementación actual, este índice no puede ser un pseudoíndice.) En caso de errores de ejecución esta función será llamada con el mensaje de error y el valor devuelto será el mensaje retornado en la pila por lua_pcall.
Típicamente la función manejadora de error se usa para añadir más información de depuración al mensaje de error, tal como un "trazado inverso" de la pila. Esa información no puede ser recolectada después del retorno de lua_pcall, puesto que por entonces la pila ya no tiene esa información.
La función lua_pcall retorna 0 en caso de éxito o uno de los siguientes códigos de error (definidos en lua.h):
LUA_ERRRUN --- un error de ejecución.
LUA_ERRMEM --- un error de reserva de memoria. Para este error Lua no llama a la función manejadora de error.
LUA_ERRERR ---
error mientras se está ejecutando la función manejadora de error.
lua_pop[-n, +0, -]
void lua_pop (lua_State *L, int n);
Elimina n elementos de la pila.
lua_pushboolean[-0, +1, -]
void lua_pushboolean (lua_State *L, int b);
Coloca el valor booleano b en la pila.
lua_pushcclosure[-n, +1, m]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
Coloca en la pila una nueva instancia en C.
Cuando se crea una función C es posible asociarle algunos valores, creando entonces una instancia en C (véase §3.4); estos valores son entonces accesibles a la función en cualquier momento en que sea invocada. Para asociar valores a una función C, primero éstos deberían colocarse en la pila (cuando hay varios, el primero se coloca antes). Entonces se invoca lua_pushcclosure para crear y colocar la función C en la pila, con el argumento n indicando cuantos valores están asociados con la misma. lua_pushcclosure también elimina esos valores de la pila.
lua_pushcfunction[-0, +1, m]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
Coloca una función C en la pila. Esta función recibe un puntero a una función C y coloca en la pila un valor de Lua de tipo function que, cuando se llama, invoca la correspondiente función C.
Cualquier función que sea registrada en Lua debe seguir el protocolo correcto para recibir sus argumentos y devolver sus resultados (véase lua_CFunction).
lua_pushcfunction(L, f) está definida como una macro:
#define lua_pushcfunction(L, f) lua_pushcclosure(L, f, 0)
lua_pushfstring[-0, +1, m]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
Coloca en la pila un string formateado y retorna un puntero a este string. Es similar a la función sprintf de C, pero tiene con ella algunas importantes diferencias:
%%' (inserta un '%' en el string), '%s' (inserta un string terminado en cero sin restricciones de tamaño), '%f' (inserta un lua_Number), '%p' (inserta un puntero como número hexadecimal), '%d' (inserta un int), y '%c' (inserta un int como carácter).
lua_pushinteger[-0, +1, -]
void lua_pushinteger (lua_State *L, lua_Integer n);
Coloca un número entero de valor n en la pila.
lua_pushlightuserdata[-0, +1, -]
void lua_pushlightuserdata (lua_State *L, void *p);
Coloca un userdata ligero en la pila.
Los userdata representan valores de C en Lua. Un userdata ligero representa un puntero. Es un valor (como un número): no se crea ni tiene metatablas y no sufre liberación de memoria (puesto que nunca fue reservada). En una comparación de igualdad, un userdata ligero es igual que cualquier otro userdata ligero con la misma dirección en C.
lua_pushliteral[-0, +1, m]
void lua_pushliteral (lua_State *L, const char *s);
Esta macro es equivalente a lua_pushlstring,
pero puede ser usada solamente cuando s es un string literal.
En esos casos, proporciona automáticamente la longitud del string.
lua_pushlstring[-0, +1, m]
void lua_pushlstring (lua_State *L, const char *s, size_t len);
Coloca el string apuntado por s con tamaño len en la pila. Lua realiza (o reutiliza) una copia interna del string dado, así que la memoria en s puede ser liberada o reutilizada inmediamente después de que la función retorne. El string puede contener ceros.
lua_pushnil[-0, +1, -]
void lua_pushnil (lua_State *L);
Coloca un valor nil en la pila.
lua_pushnumber[-0, +1, -]
void lua_pushnumber (lua_State *L, lua_Number n);
Coloca un número con valor n en la pila.
lua_pushstring[-0, +1, m]
void lua_pushstring (lua_State *L, const char *s);
Coloca el string terminado en cero al que apunta s en la pila. Lua realiza (o reutiliza) una copia interna del string dado, así que la memoria en s puede ser liberada o reutilizada inmediamente después de que la función retorne. El string no puede contener caracteres cero; se asume que el final del mismo es el primer carácter cero que aparezca.
lua_pushthread[-0, +1, -]
int lua_pushthread (lua_State *L);
Coloca un proceso representado por L en la pila. Retorna 1 si este proceso es el proceso principal de su estado.
lua_pushvalue[-0, +1, -]
void lua_pushvalue (lua_State *L, int index);
Coloca una copia del elemento situado en el índice válido dado en la pila.
lua_pushvfstring[-0, +1, m]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);
Equivalente a lua_pushfstring, excepto que recibe un argumento de tipo va_list en lugar de un número variable de argumentos.
lua_rawequal[-0, +0, -]
int lua_rawequal (lua_State *L, int index1, int index2);
Retorna 1 si los dos valores situados en los índices aceptables index1 e index2 son iguales de manera primitiva (esto es, sin invocar metamétodos). En caso contrario retorna 0. También retorna 0 si alguno de los índices no es válido.
lua_rawget[-1, +1, -]
void lua_rawget (lua_State *L, int index);
Similar a lua_gettable, pero realiza un acceso directo (sin metamétodos).
lua_rawgeti[-0, +1, -]
void lua_rawgeti (lua_State *L, int index, int n);
Coloca en la pila el valor t[n], donde t es el valor en el índice válido. El acceso es directo, esto es, sin invocar metamétodos.
lua_rawset[-2, +0, m]
void lua_rawset (lua_State *L, int index);
Similar a lua_settable, pero realizando una asignación directa (sin invocar metamétodos).
lua_rawseti[-1, +0, m]
void lua_rawseti (lua_State *L, int index, int n);
Realiza el equivalente a t[n] = v, donde t es el valor en el índice válido y v es el valor en la parte superior de la pila.
Esta función elimina el valor de la parte superior de la pila. La asignación es directa, sin invocar metamétodos.
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size);
La función de lectura usada por lua_load. Cada vez que necesita otro fragmento de chunk, lua_load llama al "lector", pasándole su argumento data. El lector debe retornar un puntero a un bloque de memoria con un nuevo fragmento de chunk y establece size como el tamaño del bloque. El bloque debe existir hasta que la función lectora se invoque de nuevo. Para señalar el final del chunk el lector debe retornar NULL. La función lectora puede retornar fragmentos de cualquier tamaño mayor que cero.
lua_register[-0, +0, e]
void lua_register (lua_State *L,
const char *name,
lua_CFunction f);
Establece la función C f como el nuevo valor del nombre global. Está definida en la macro:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove[-1, +0, -]
void lua_remove (lua_State *L, int index);
Elimina el elemento en la posición del índice válido dado, desplazando hacia abajo los elementos que estaban por encima de este índice para llenar el hueco. No puede ser llamada con un pseudoíndice, debido a que éste no es una posición real en la pila.
lua_replace[-1, +0, -]
void lua_replace (lua_State *L, int index);
Mueve el elemento que está en la parte superior de la pila a la posición dada (y lo elimina de la parte superior de la pila), sin desplazar ningún elemento de la misma (por tanto reemplazando el valor en la posición dada).
lua_resume[-?, +?, -]
int lua_resume (lua_State *L, int narg);
Comienza y resume una co-rutina en un proceso dado.
Para comenzar una co-rutina se debe crear un nuevo proceso (véase lua_newthread); entonces se coloca en su propia pila la función principal más cualquier posible argumento; posteriormente se invoca lua_resume, con narg siendo el número de argumentos. Esta llamada retorna cuando la co-rutina suspende o finaliza su ejecución. Cuando retorna, la pila contiene todos los valores pasados a lua_yield, o todos los valores retornados por el cuerpo de la función. lua_resume retorna LUA_YIELD si la co-rutina cedió el control, 0 si la co-rutina acabó su ejecución sin errores, o un código de error en caso de errores (véase lua_pcall). En caso de error, se deja información en la pila, así que se puede usar la API de depuración con ella. El mensaje de error está en la parte superior de la pila. Para reiniciar una co-rutina se ponen en la pila sólo los valores que son pasados como resultado de yield, y entonces se invoca lua_resume.
lua_setallocf[-0, +0, -]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
Utiliza f con el userdata ud como función de reserva de memoria de un estado dado .
lua_setfenv[-1, +0, -]
int lua_setfenv (lua_State *L, int index);
Elimina una tabla de la parte superior de la pila y la toma como nuevo entorno para el valor situado en la posición del índice. Si el valor dado no es ni una función ni un proceso ni un userdata entonces lua_setfenv retorna 0. En caso contrario retorna 1.
lua_setfield[-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);
Realiza el equivalente a t[k] = v, donde t es el valor en la posición del índice válido y v es el valor en la parte superior de la pila.
Esta función elimina el valor de la pila. Como en Lua, esta función puede activar un metamétodo para el evento "newindex" (véase §2.8).
lua_setglobal[-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);
Elimina un valor de la pila y lo toma como nuevo valor del
nombre global. Está definida en una macro:
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
lua_setmetatable[-1, +0, -]
int lua_setmetatable (lua_State *L, int index);
Elimina una tabla de la pila y la toma como nueva metatabla para el valor en la situación del índice aceptable.
lua_settable[-2, +0, e]
void lua_settable (lua_State *L, int index);
Hace el equivalente a t[k] = v, donde t es el valor en la posición del índice válido, v es el valor en la parte superior de la pila y k es el valor justamente debajo.
Esta función elimina de la pila tanto la clave como el valor. Como en Lua, esta función puede activar un metamétodo para el evento "newindex" (véase §2.8).
lua_settop[-?, +?, -]
void lua_settop (lua_State *L, int index);
Acepta cualquier índice aceptable ó 0 y establece la parte superior de la pila en este índice. Si ese valor es mayor que el antiguo entonces los nuevos elementos se rellenan con nil. Si index es 0 entonces todos los elementos de la pila se eliminan.
lua_Statetypedef struct lua_State lua_State;
Estructura opaca que almacena todo el estado de un intérprete de Lua. La biblioteca de Lua es totalmente re-entrante: no tiene variables globales. Toda la información acerca de un estado se guarda en esta estructura.
Un puntero a este estado debe ser pasado como primer argumento a cualquier función de la biblioteca, excepto a lua_newstate, la cual crea un nuevo estado de Lua desde cero.
lua_status[-0, +0, -]
int lua_status (lua_State *L);
Retorna el estatus del proceso L.
El estatus puede ser 0 para un proceso normal, un código de error si el proceso finaliza su ejecución con un error, o LUA_YIELD si el proceso está suspendido.
lua_toboolean[-0, +0, -]
int lua_toboolean (lua_State *L, int index);
Convierte el valor de Lua situado en la posición del índice aceptable en un booleano de C (0 ó 1). Como todos los test en Lua, lua_toboolean retorna 1 para cada valor de Lua diferente de false y nil; en caso contrario retorna 0. También retorna 0 cuando se invoca sin un índice válido. (Si se desea aceptar sólo los valores booleanos reales, úsese lua_isboolean para verificar el tipo del valor.)
lua_tocfunction[-0, +0, -]
lua_CFunction lua_tocfunction (lua_State *L, int index);
Convierte en una función C el valor situado en el índice aceptable. Este valor debe ser una función C; en caso contrario retorna NULL.
lua_tointeger[-0, +0, -]
lua_Integer lua_tointeger (lua_State *L, int index);
Convierte el valor de Lua situado en el índice aceptable en un entero sin signo del tipo lua_Integer. El valor de Lua debe ser un número o un string convertible a un número (véase §2.2.1); en otro caso lua_tointeger retorna 0.
Si el número no es entero se trunca de una manera no especificada.
lua_tolstring[-0, +0, m]