stringtranslate.com

Lua (lenguaje de programación)

Lua ( / ˈl ə / LOO ; del portugués : lua [ˈlu(w)ɐ] que significa luna ) es un lenguaje de programación ligero , de alto nivel y multiparadigma diseñado principalmente para uso integrado en aplicaciones. [3] Lua es un software multiplataforma , ya que el intérprete del bytecode compilado está escrito en ANSI C , [4] y Lua tiene una interfaz de programación de aplicaciones ( API ) C relativamente simple para integrarlo en aplicaciones. [5]

Lua se originó en 1993 como un lenguaje para extender aplicaciones de software y satisfacer la creciente demanda de personalización de la época. Proveía las funciones básicas de la mayoría de los lenguajes de programación procedimental , pero no incluía características más complicadas o específicas del dominio ; en cambio, incluía mecanismos para extender el lenguaje, lo que permitía a los programadores implementar dichas características. Como Lua estaba destinado a ser un lenguaje de extensión integrable general, los diseñadores de Lua se enfocaron en mejorar su velocidad , portabilidad , extensibilidad y facilidad de uso en el desarrollo.

Historia

Lua fue creada en 1993 por Roberto Ierusalimschy , Luiz Henrique de Figueiredo y Waldemar Celes, miembros del Grupo de Tecnología Gráfica Computacional (Tecgraf) de la Pontificia Universidad Católica de Río de Janeiro , en Brasil .

Desde 1977 hasta 1992, Brasil mantuvo una política de fuertes barreras comerciales (denominadas reserva de mercado) para hardware y software de computadoras , creyendo que Brasil podía y debía producir su propio hardware y software. En ese clima, los clientes de Tecgraf no podían permitirse, ni política ni financieramente, comprar software personalizado del exterior; bajo la reserva de mercado, los clientes tendrían que pasar por un complejo proceso burocrático para demostrar que sus necesidades no podían ser satisfechas por empresas brasileñas. Esas razones llevaron a Tecgraf a implementar las herramientas básicas que necesitaba desde cero. [6]

Los predecesores de Lua fueron los lenguajes de descripción/configuración de datos Simple Object Language (SOL) y el lenguaje de entrada de datos (DEL). [7] Se habían desarrollado de forma independiente en Tecgraf en 1992-1993 para añadir algo de flexibilidad a dos proyectos diferentes (ambos eran programas gráficos interactivos para aplicaciones de ingeniería en la empresa Petrobras ). Había una falta de estructuras de control de flujo en SOL y DEL, y Petrobras sintió una creciente necesidad de añadirles potencia de programación completa.

En La evolución de Lua , los autores del lenguaje escribieron: [6]

En 1993, el único contendiente real era Tcl , que había sido diseñado explícitamente para ser integrado en aplicaciones. Sin embargo, Tcl tenía una sintaxis desconocida, no ofrecía un buen soporte para la descripción de datos y solo se ejecutaba en plataformas Unix. No consideramos LISP ni Scheme debido a su sintaxis poco amigable. Python todavía estaba en su infancia. En la atmósfera libre y de "hazlo tú mismo" que reinaba entonces en Tecgraf, era bastante natural que intentáramos desarrollar nuestro propio lenguaje de scripting... Debido a que muchos usuarios potenciales del lenguaje no eran programadores profesionales, el lenguaje debía evitar la sintaxis y la semántica crípticas. La implementación del nuevo lenguaje debía ser altamente portable, porque los clientes de Tecgraf tenían una colección muy diversa de plataformas informáticas. Finalmente, dado que esperábamos que otros productos de Tecgraf también necesitaran integrar un lenguaje de scripting, el nuevo lenguaje debía seguir el ejemplo de SOL y proporcionarse como una biblioteca con una API de C.

Lua 1.0 fue diseñado de tal manera que sus constructores de objetos, siendo entonces ligeramente diferentes del estilo ligero y flexible actual, incorporaron la sintaxis de descripción de datos de SOL (de ahí el nombre Lua: Sol significa "Sol" en portugués, y Lua significa "Luna"). La sintaxis de Lua para las estructuras de control fue tomada prestada principalmente de Modula ( if, while, repeat/ until), pero también había tomado influencia de CLU (múltiples asignaciones y múltiples retornos de llamadas de función, como una alternativa más simple a los parámetros de referencia o punteros explícitos ), C++ ("buena idea de permitir que una variable local se declare solo donde la necesitamos" [6] ), SNOBOL y AWK ( matrices asociativas ). En un artículo publicado en Dr. Dobb's Journal , los creadores de Lua también afirman que LISP y Scheme con su mecanismo de estructura de datos único y ubicuo (la lista ) fueron una influencia importante en su decisión de desarrollar la tabla como la estructura de datos principal de Lua. [8]

La semántica de Lua ha sido influenciada cada vez más por Scheme con el paso del tiempo, [6] especialmente con la introducción de funciones anónimas y alcance léxico completo . Se agregaron varias características en las nuevas versiones de Lua.

Las versiones de Lua anteriores a la versión 5.0 se publicaron bajo una licencia similar a la licencia BSD . A partir de la versión 5.0, Lua se ha licenciado bajo la licencia MIT . Ambas son licencias de software libre permisivas y son casi idénticas.

Características

Lua se describe comúnmente como un lenguaje " multiparadigma ", que proporciona un pequeño conjunto de características generales que se pueden ampliar para adaptarse a diferentes tipos de problemas. Lua no contiene soporte explícito para la herencia , pero permite que se implemente con metatablas. De manera similar, Lua permite a los programadores implementar espacios de nombres , clases y otras características relacionadas utilizando su implementación de tabla única; las funciones de primera clase permiten el empleo de muchas técnicas de programación funcional y el alcance léxico completo permite ocultar información de grano fino para hacer cumplir el principio del mínimo privilegio .

En general, Lua intenta proporcionar metacaracterísticas simples y flexibles que se puedan ampliar según sea necesario, en lugar de proporcionar un conjunto de características específicas para un paradigma de programación. Como resultado, el lenguaje base es ligero ; el intérprete de referencia completo solo pesa unos 247  kB compilados [4] y se adapta fácilmente a una amplia gama de aplicaciones.

Como lenguaje de tipado dinámico pensado para su uso como lenguaje de extensión o lenguaje de script , Lua es lo suficientemente compacto como para adaptarse a una variedad de plataformas de host. Admite solo una pequeña cantidad de estructuras de datos atómicas, como valores booleanos , números ( coma flotante de doble precisión y enteros de 64 bits de manera predeterminada) y cadenas . Las estructuras de datos típicas, como matrices , conjuntos , listas y registros, se pueden representar utilizando la única estructura de datos nativa de Lua, la tabla, que es esencialmente una matriz asociativa heterogénea .

Lua implementa un pequeño conjunto de características avanzadas , tales como funciones de primera clase , recolección de basura , cierres , llamadas de cola adecuadas , coerción (conversión automática entre valores de cadena y números en tiempo de ejecución), corrutinas (multitarea cooperativa) y carga dinámica de módulos .

Sintaxis

El clásico programa "¡Hola, mundo!" se puede escribir de la siguiente manera, con o sin paréntesis: [9] [a]

imprimir ( "¡Hola, mundo!" )
imprimir  "¡Hola, mundo!"

Un comentario en Lua comienza con un doble guion y se extiende hasta el final de la línea, de forma similar a Ada , Eiffel , Haskell , SQL y VHDL . Las cadenas de varias líneas y los comentarios se marcan con corchetes dobles.

--Comentario de una sola línea --[[ Comentario de varias líneas-- ]]

La función factorial se implementa en este ejemplo:

función  factorial ( n )  local  x  =  1  para  i  =  2 ,  n  hacer  x  =  x  *  i  fin  devolver  x fin

Flujo de control

Lua tiene un tipo de prueba condicional : if then endcon construcciones opcionales elsey elseif thende control de ejecución.

La if then enddeclaración genérica requiere las tres palabras clave:

Si  la condición  es entonces --cuerpo de la declaración final

La elsepalabra clave se puede agregar con un bloque de declaración adjunto para controlar la ejecución cuando la ifcondición se evalúa como false:

si  condición  entonces --cuerpo de la declaración de lo contrario --cuerpo de la declaración fin

La ejecución también se puede controlar según múltiples condiciones utilizando las elseif thenpalabras clave:

si  condición  entonces --cuerpo de la declaración elsesi  condición  entonces --cuerpo de la declaración else  --opcional --opcional predeterminado cuerpo de la declaración fin

Lua tiene cuatro tipos de bucles condicionales: el whilebucle , el repeatbucle (similar a un do whilebucle ), el forbucle numérico y el bucle genérico for.

--condición = verdaderomientras  la condición  haga  --declaraciones terminanrepetir  --declaraciones hasta que se cumpla  la condiciónpara  i  =  primero ,  último ,  delta  hacer  --delta puede ser negativo, lo que permite que el bucle for cuente hacia atrás o hacia arriba  --declaraciones  --ejemplo: print(i) fin

Este bucle genérico foriteraría sobre la tabla _Gutilizando la función iteradora estándar pairs, hasta que retorne nil:

para  clave ,  valor  en  pares ( _G )  hacer  print ( clave ,  valor ) fin

Los bucles también se pueden anidar (colocar dentro de otro bucle).

 cuadrícula  local =  {  {  11 ,  12 ,  13  },  {  21 ,  22 ,  23  },  {  31 ,  32 ,  33  } }para  y ,  fila  en  pares ( cuadrícula )  hacer  para  x ,  valor  en  pares ( fila )  hacer  imprimir ( x ,  y ,  valor )  fin fin

Funciones

El tratamiento que Lua hace de las funciones como valores de primera clase se muestra en el siguiente ejemplo, donde se modifica el comportamiento de la función de impresión:

do  local  oldprint  =  print  -- Almacena la función de impresión actual como  la función oldprint  print ( s )  --[[ Redefine la función de impresión. La función de impresión habitual todavía se puede usar  a través de oldprint. La nueva tiene solo un argumento.]]  oldprint ( s  ==  "foo"  y  "bar"  o  s )  end end

Cualquier llamada futura a printahora será enrutada a través de la nueva función y, debido al alcance léxico de Lua , la antigua función print solo será accesible mediante la nueva función print modificada.

Lua también admite cierres , como se muestra a continuación:

function  addto ( x )  - Devuelve una nueva función que agrega x al argumento  return  function ( y )  -[[Cuando hacemos referencia a la variable x, que está fuera del  alcance actual y cuyo tiempo de vida sería más corto que el de esta  función anónima, Lua crea un cierre.]]  return  x  +  y  end end fourplus  =  addto ( 4 ) print ( fourplus ( 3 ))  - Imprime 7--Esto también se puede lograr llamando a la función de la siguiente manera: print ( addto ( 4 )( 3 )) --[[Esto se debe a que estamos llamando a la función devuelta desde 'addto(4)' con el argumento '3' directamente.  Esto también ayuda a reducir el costo de datos y mejorar el rendimiento si se llama de forma iterativa.]]

xCada vez que se llama a una variable, se crea un nuevo cierre para la variable addto, de modo que cada nueva función anónima devuelta siempre accederá a su propio xparámetro. El cierre lo gestiona el recolector de elementos no utilizados de Lua, al igual que cualquier otro objeto.

Tablas

Las tablas son las estructuras de datos más importantes (y, por diseño, el único tipo de datos compuesto integrado ) en Lua y son la base de todos los tipos creados por el usuario. Son matrices asociativas con la adición de una clave numérica automática y una sintaxis especial.

Una tabla es un conjunto de pares de claves y datos, donde los datos están referenciados por clave; en otras palabras, es una matriz asociativa heterogénea con algoritmo hash .

Las tablas se crean utilizando la {}sintaxis del constructor.

a_table  =  {}  – Crea una nueva tabla vacía

Las tablas siempre se pasan por referencia (ver Llamada por compartición ).

Una clave (índice) puede ser cualquier valor excepto nily NaN , incluidas las funciones.

a_table  =  { x  =  10 }  - Crea una nueva tabla, con una entrada que asigna "x" al número 10. print ( a_table [ "x" ])  - Imprime el valor asociado con la clave de cadena, en este caso 10. b_table  =  a_table b_table [ "x" ]  =  20  - El valor en la tabla ha sido cambiado a 20. print ( b_table [ "x" ])  - Imprime 20. print ( a_table [ "x" ])  - También imprime 20, porque a_table y b_table hacen referencia a la misma tabla.

A menudo se utiliza una tabla como estructura (o registro ) mediante cadenas como claves. Debido a que este uso es muy común, Lua cuenta con una sintaxis especial para acceder a dichos campos. [11]

punto  =  {  x  =  10 ,  y  =  20  }  - Crea una nueva tabla print ( punto [ "x" ])  - Imprime 10 print ( punto.x ) - Tiene exactamente el mismo significado que la línea anterior. La notación de puntos, más fácil de leer, es simplemente una sintaxis más simple . 

Al utilizar una tabla para almacenar funciones relacionadas, puede actuar como un espacio de nombres.

Punto  =  {}Punto . nuevo  =  función ( x ,  y )  return  { x  =  x ,  y  =  y }  -- return {["x"] = x, ["y"] = y} finPunto . set_x  =  función ( punto ,  x )  punto . x  =  x  -- punto["x"] = x; fin

A las tablas se les asigna automáticamente una clave numérica, lo que permite utilizarlas como un tipo de datos de matriz . El primer índice automático es 1 en lugar de 0, como ocurre en muchos otros lenguajes de programación (aunque se permite un índice explícito de 0).

Una clave numérica 1es distinta de una clave de cadena "1".

array  =  {  "a" ,  "b" ,  "c" ,  "d"  }  - Los índices se asignan automáticamente. print ( array [ 2 ])  - Imprime "b". La indexación automática en Lua comienza en 1. print ( # array )  - Imprime 4. # es el operador de longitud para tablas y cadenas. array [ 0 ]  =  "z"  - Cero es un índice legal. print ( # array )  - Sigue imprimiendo 4, ya que los arrays de Lua están basados ​​en 1.

La longitud de una tabla tse define como cualquier índice entero ntal que t[n]no sea nilni t[n+1]sea nil; además, si t[1]es nil, npuede ser cero. Para una matriz regular, con valores distintos de nulos desde 1 hasta un determinado n, su longitud es exactamente esa n, el índice de su último valor. Si la matriz tiene "huecos" (es decir, valores nulos entre otros valores distintos de nulos), entonces #tpuede ser cualquiera de los índices que preceden directamente a un nilvalor (es decir, puede considerar cualquier valor nulo como el final de la matriz). [12]

ExampleTable  = {  { 1 ,  2 ,  3 ,  4 },  { 5 ,  6 ,  7 ,  8 } } print ( ExampleTable [ 1 ][ 3 ])  -- Imprime "3" print ( ExampleTable [ 2 ][ 4 ])  -- Imprime "8"

Una tabla puede ser una matriz de objetos.

function  Punto ( x ,  y )  -- Constructor del objeto "Punto"  return  {  x  =  x ,  y  =  y  }  -- Crea y devuelve un nuevo objeto (tabla) end array  =  {  Punto ( 10,20 )  , Punto ( 30,40 ), Punto ( 50,60 ) } -- Crea una matriz de puntos -- array = { { x = 10 , y = 20 }, { x = 30, y = 40 }, { x = 50, y = 60 } }; print ( array [ 2 ] .y ) -- Imprime 40        

El uso de un mapa hash para emular una matriz normalmente es más lento que el uso de una matriz real; sin embargo, las tablas Lua están optimizadas para su uso como matrices para ayudar a evitar este problema. [13]

Metatablas

La semántica extensible es una característica clave de Lua, y el concepto de metatabla permite una potente personalización de las tablas. El siguiente ejemplo demuestra una tabla "infinita". Para cualquier n, fibs[n]dará el n-ésimo número de Fibonacci mediante programación dinámica y memorización .

fibs  =  {  1 ,  1  }  -- Valores iniciales para fibs[1] y fibs[2]. setmetatable ( fibs ,  {  __index  =  function ( values ,  n )  --[[__index es una función predefinida por Lua,  se llama si la clave "n" no existe.]]  values [ n ]  =  values [ n  -  1 ]  +  values [ n  -  2 ]  -- Calcular y memorizar fibs[n].  return  values [ n ]  end })

Programación orientada a objetos

Aunque Lua no tiene un concepto de clases incorporado , la programación orientada a objetos se puede emular utilizando funciones y tablas. Un objeto se forma colocando métodos y campos en una tabla. La herencia (tanto simple como múltiple) se puede implementar con metatablas, delegando métodos y campos inexistentes a un objeto padre.

Con estas técnicas no existe el concepto de "clase", sino que se utilizan prototipos , similares a Self o JavaScript . Los objetos nuevos se crean con un método de fábrica (que construye objetos nuevos desde cero) o clonando un objeto existente.

Creando un objeto vectorial básico :

 Vector  local =  {} VectorMeta local  = { __índice = Vector }     función  Vector . new ( x ,  y ,  z )  -- El constructor  retorna  setmetatable ({ x  =  x ,  y  =  y ,  z  =  z },  VectorMeta ) finfunción  Vector .magnitud ( self ) - Otro método return math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) fin       local  vec  =  Vector . new ( 0 ,  1 ,  0 )  -- Crea un vector print ( vec . magnitude ( vec ))  -- Llama a un método (salida: 1) print ( vec . x )  -- Accede a una variable miembro (salida: 0)

Aquí, setmetatablele indica a Lua que busque un elemento en la Vectortabla si no está presente en vecella. , que es equivalente a , primero busca el elemento en la tabla . La tabla no tiene un elemento, pero su metatabla delega a la tabla el elemento cuando no se encuentra en la tabla.vec.magnitudevec["magnitude"]vecmagnitudevecmagnitudeVectormagnitudevec

Lua proporciona cierta sintaxis para facilitar la orientación a objetos. Para declarar funciones miembro dentro de una tabla de prototipos, se puede utilizar , que es equivalente a . La llamada a métodos de clase también hace uso de los dos puntos: es equivalente a .function table:func(args)function table.func(self, args)object:func(args)object.func(object, args)

Con esto en mente, aquí hay una clase correspondiente con :azúcar sintáctica:

 Vector  local =  {} Vector . __índice  =  Vectorfunción  Vector : new ( x ,  y ,  z )  -- El constructor  -- Dado que la definición de función utiliza dos puntos,  -- su primer argumento es "self" que se refiere  -- a "Vector"  return  setmetatable ({ x  =  x ,  y  =  y ,  z  =  z },  self ) endfunción  Vector : magnitud ()  - Otro método  - Referencia al  objeto implícito utilizando self return  math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) fin    local  vec  =  Vector : new ( 0 ,  1 ,  0 )  -- Crea un vector print ( vec : magnitude ())  -- Llama a un método (salida: 1) print ( vec . x )  -- Accede a una variable miembro (salida: 0)

Herencia

Lua admite el uso de metatablas para otorgar herencia de clases a Lua. [14] En este ejemplo, permitimos que los vectores tengan sus valores multiplicados por una constante en una clase derivada.

 Vector  local =  {} Vector . __índice  =  Vectorfunción  Vector : new ( x ,  y ,  z )  -- El constructor  -- Aquí, self se refiere al método "nuevo" de cualquier clase  que -- llamemos. En una clase derivada, self será  la clase derivada; en la clase Vector, self  será Vector  return  setmetatable ({ x  =  x ,  y  =  y ,  z  =  z },  self ) endfunción  Vector : magnitud ()  - Otro método  - Referencia al  objeto implícito utilizando self return  math.sqrt ( self.x ^ 2 + self.y ^ 2 + self.z ^ 2 ) fin    -- Ejemplo de herencia de clase local  VectorMult  =  {} VectorMult . __index  =  VectorMult setmetatable ( VectorMult ,  Vector )  -- Hacer que VectorMult sea un hijo de Vectorfunción  VectorMult : multiplicar ( valor )  self . x  =  self . x  *  valor  self . y  =  self . y  *  valor  self . z  =  self . z  *  valor  return  self endlocal  vec  =  VectorMult : new ( 0 ,  1 ,  0 )  -- Crea un vector print ( vec : magnitude ())  -- Llama a un método (salida: 1) print ( vec . y )  -- Accede a una variable miembro (salida: 1) vec : multiplicar ( 2 )  -- Multiplica todos los componentes del vector por 2 print ( vec . y )  -- Accede al miembro nuevamente (salida: 2)

Lua también admite herencia múltiple ; __indexpuede ser una función o una tabla. [15] También se puede realizar una sobrecarga de operadores ; las metatablas de Lua pueden tener elementos como __add, __suby así sucesivamente. [16]

Implementación

Los programas Lua no se interpretan directamente desde el archivo textual de Lua, sino que se compilan en código de bytes, que luego se ejecuta en la máquina virtual (VM) de Lua. El proceso de compilación normalmente es invisible para el usuario y se realiza durante el tiempo de ejecución , especialmente cuando se utiliza un compilador de compilación justo a tiempo (JIT), pero se puede realizar sin conexión para aumentar el rendimiento de carga o reducir la huella de memoria del entorno host al dejar fuera el compilador. El código de bytes de Lua también se puede producir y ejecutar desde dentro de Lua, utilizando la dumpfunción de la biblioteca de cadenas y las load/loadstring/loadfilefunciones. La versión 5.3.4 de Lua está implementada en aproximadamente 24.000 líneas de código C. [3] [4]

Al igual que la mayoría de las CPU, y a diferencia de la mayoría de las máquinas virtuales (que están basadas en pilas ), la VM de Lua está basada en registros y, por lo tanto, se parece más a la mayoría de los diseños de hardware. La arquitectura de registros evita la copia excesiva de valores y reduce la cantidad total de instrucciones por función. La máquina virtual de Lua 5 es una de las primeras VM puras basadas en registros que tiene un uso amplio. [17] Parrot y Dalvik de Android son otras dos VM basadas en registros bien conocidas. La VM de PCScheme también estaba basada en registros. [18]

Este ejemplo es el listado de bytes de la función factorial definida anteriormente (como lo muestra el luaccompilador 5.1): [19]

función <factorial.lua:1,7> (9 instrucciones, 36 bytes en 0x8063c60)1 parámetro, 6 ranuras, 0 valores ascendentes, 6 variables locales, 2 constantes, 0 funciones1 [2] CARGAR 1 -1 ; 12 [3] CARGA 2 -2 ; 23 [3] MOVER 3 04 [3] CARGA 4 -1 ; 15 [3] FORPREP 2 1 ; a 76 [4] MUL 1 1 57 [3] FORLOOP 2 -2 ; hasta 68 [6] REGRESAR 1 29 [7] RETORNO 0 1

API C

Lua está pensado para ser integrado en otras aplicaciones y proporciona una API C para este propósito. La API se divide en dos partes: el núcleo de Lua y la biblioteca auxiliar de Lua. [20] El diseño de la API de Lua elimina la necesidad de contar referencias manualmente (administrar) en código C, a diferencia de la API de Python . La API, al igual que el lenguaje, es minimalista. Las funciones avanzadas las proporciona la biblioteca auxiliar, que consta principalmente de macros de preprocesador que ayudan con operaciones de tabla complejas.

La API de Lua C se basa en la pila . Lua proporciona funciones para insertar y extraer los tipos de datos más simples de C (enteros, flotantes, etc.) de la pila y funciones para manipular tablas a través de la pila. La pila de Lua es algo diferente de una pila tradicional; la pila se puede indexar directamente, por ejemplo. Los índices negativos indican desplazamientos desde la parte superior de la pila. Por ejemplo, −1 es la parte superior (el valor insertado más recientemente), mientras que los índices positivos indican desplazamientos desde la parte inferior (el valor más antiguo). La ordenación de datos entre funciones de C y Lua también se realiza utilizando la pila. Para llamar a una función de Lua, los argumentos se insertan en la pila y luego se lua_callutiliza para llamar a la función real. Al escribir una función de C para que se llame directamente desde Lua, los argumentos se leen desde la pila.

A continuación se muestra un ejemplo de cómo llamar a una función Lua desde C:

#include <stdio.h> #include <lua.h> // Biblioteca principal de Lua (lua_*) #include <lauxlib.h> // Biblioteca auxiliar de Lua (luaL_*)   int main ( void ) { // crea un estado Lua lua_State * L = luaL_newstate ();       // cargar y ejecutar una cadena si ( luaL_dostring ( L , "función foo (x,y) devolver x+y fin" )) { lua_close ( L ); devolver -1 ; }         // inserta el valor de "foo" global (la función definida arriba) // en la pila, seguido de los enteros 5 y 3 lua_getglobal ( L , "foo" ); lua_pushinteger ( L , 5 ); lua_pushinteger ( L , 3 ); lua_call ( L , 2 , 1 ); // llama a una función con dos argumentos y un valor de retorno printf ( "Resultado: %d \n " , lua_tointeger ( L , -1 )); // imprime el valor entero del elemento en la parte superior de la pila lua_pop ( L , 1 ); // devuelve la pila al estado original lua_close ( L ); // cierra el estado de Lua return 0 ; }                      

Al ejecutar este ejemplo se obtiene lo siguiente:

$ cc  -o  ejemplo  ejemplo.c  -llua $ ./ejemplo Resultado: 8

La API de C también proporciona algunas tablas especiales, ubicadas en varios "pseudoíndices" en la pila de Lua. En la LUA_GLOBALSINDEXversión anterior a Lua 5.2 [21] se encuentra la tabla globals, _Gde Lua, que es el espacio de nombres principal . También hay un registro ubicado en LUA_REGISTRYINDEXdonde los programas de C pueden almacenar valores de Lua para su posterior recuperación.

Módulos

Además de los módulos de la biblioteca estándar (núcleo), es posible escribir extensiones utilizando la API de Lua. Los módulos de extensión son objetos compartidos que se pueden utilizar para ampliar las funciones del intérprete proporcionando facilidades nativas a los scripts de Lua. Los scripts de Lua pueden cargar módulos de extensión utilizando require, [20] al igual que los módulos escritos en Lua mismo, o con package.loadlib. [22] Cuando se carga una biblioteca C a través de Lua, buscará la función y la llamará, que actúa como cualquier función C invocable desde Lua y generalmente devuelve una tabla llena de métodos. Un conjunto creciente de módulos denominados rocks están disponibles a través de un sistema de gestión de paquetes llamado LuaRocks , [23] en el espíritu de CPAN , RubyGems y Python eggs. Existen enlaces Lua preescritos para los lenguajes de programación más populares, incluidos otros lenguajes de script. [24] Para C++, hay una serie de enfoques basados ​​en plantillas y algunos generadores de enlaces automáticos.require('foo')luaopen_foo

Aplicaciones

En el desarrollo de videojuegos , Lua se usa ampliamente como lenguaje de scripting , principalmente debido a su facilidad percibida para incrustar, ejecución rápida y curva de aprendizaje corta . [25] Los juegos notables que usan Lua incluyen Roblox , [26] Garry's Mod , World of Warcraft , Payday 2 , Phantasy Star Online 2 , Dota 2 , Crysis , [27] y muchos otros. Algunos juegos que no admiten de forma nativa la programación o scripting de Lua, tienen esta función agregada por mods, como lo hace ComputerCraft para Minecraft . Además, Lua se usa en software que no es de videojuegos, como Adobe Lightroom , Moho , iClone , Aerospike y algún software de sistema en FreeBSD y NetBSD , y se usa como un lenguaje de scripting de plantilla en MediaWiki usando la extensión Scribunto. [28]

En 2003, una encuesta realizada por GameDev.net mostró que Lua era el lenguaje de programación de juegos más popular. [29] El 12 de enero de 2012, Lua fue anunciado como ganador del premio Front Line Award 2011 de la revista Game Developer en la categoría Herramientas de programación. [30]

Muchas aplicaciones que no son juegos también usan Lua para extensibilidad, como LuaTeX , una implementación del lenguaje de composición tipográfica TeX , Redis , una base de datos clave-valor , ScyllaDB , un almacén de columnas anchas , Neovim , un editor de texto, Nginx , un servidor web , y Wireshark , un analizador de paquetes de red.

A través de la extensión Scribunto, Lua está disponible como un lenguaje de programación del lado del servidor en el software MediaWiki que ejecuta Wikipedia y otras wikis. [31] Entre sus usos se encuentran permitir la integración de datos de Wikidata en artículos, [32] y potenciar el sistema automatizado taxobox .

Lenguas derivadas

Idiomas que se compilan en Lua

Dialectos

Además, la comunidad de usuarios de Lua proporciona algunos parches de potencia sobre la implementación de referencia de C. [44]

Véase también

Notas

  1. ^ Azúcar sintáctico, una construcción de tabla o cadena literal que sigue a un identificador es una llamada de función válida. [10]

Referencias

  1. ^ "[ANN] Lua 5.4.7 ya está disponible". 25 de junio de 2024. Consultado el 27 de junio de 2024 .
  2. ^ Ring Team (5 de diciembre de 2017). «El lenguaje de programación Ring y otros lenguajes». ring-lang.net . Archivado desde el original el 25 de diciembre de 2018 . Consultado el 5 de diciembre de 2017 .
  3. ^ ab Ierusalimschy, Roberto; de Figueiredo, Luiz Henrique; Filho, Waldemar Celes (junio de 1996). "Lua: un lenguaje de extensión extensible". Software: práctica y experiencia . 26 (6): 635–652. doi :10.1002/(SICI)1097-024X(199606)26:6<635::AID-SPE26>3.0.CO;2-P. S2CID  61066194 . Consultado el 24 de octubre de 2015 .
  4. ^ abc "Acerca de Lua". Lua.org . Consultado el 11 de agosto de 2011 .
  5. ^ Takhteyev, Yuri (21 de abril de 2013). «De Brasil a Wikipedia». Foreign Affairs . Consultado el 25 de abril de 2013 .
  6. ^ abcd Ierusalimschy, R .; Figueiredo, LH; Celes, W. (2007). "La evolución de Lua" (PDF) . Actas de la tercera conferencia ACM SIGPLAN sobre Historia de los lenguajes de programación. págs. 2–1–2–26. doi :10.1145/1238844.1238846. ISBN 978-1-59593-766-7.S2CID 475143  .
  7. ^ "La evolución de un lenguaje de extensión: una historia de Lua". 2001. Consultado el 18 de diciembre de 2008 .
  8. ^ Figueiredo, LH; Ierusalimschy, R.; Celes, W. (diciembre de 1996). "Lua: un lenguaje integrado extensible. Unos pocos metamecanismos reemplazan una serie de características". Dr. Dobb's Journal . Vol. 21, no. 12. págs. 26–33.
  9. ^ "Programación en Lua: 1".
  10. ^ "Manual de referencia de Lua 5.0, 2.5.7, Llamadas de función".
  11. ^ "Manual de referencia de Lua 5.1". 2014 . Consultado el 27 de febrero de 2014 .
  12. ^ "Manual de referencia de Lua 5.1". 2012 . Consultado el 16 de octubre de 2012 .
  13. ^ "Código fuente de Lua 5.1". 2006. Consultado el 24 de marzo de 2011 .
  14. ^ Roberto Ierusalimschy. Programación en Lua, 4ª edición . pág. 165.
  15. ^ "Programación en Lua: 16.3". Lua . Consultado el 16 de septiembre de 2021 .
  16. ^ "Tutorial de metamétodos". Wiki de lua-users . Archivado desde el original el 16 de septiembre de 2021. Consultado el 16 de septiembre de 2021 .
  17. ^ Ierusalimschy, R.; Figueiredo, LH; Celes, W. (2005). "La implementación de Lua 5.0". J. Of Universal Comp. Sci . 11 (7): 1159–1176. doi : 10.3217/jucs-011-07-1159 .
  18. ^ Texas Instruments (1990). PC Scheme: Guía del usuario y manual de referencia del lenguaje, edición comercial . MIP Press. ISBN 0-262-70040-9.
  19. ^ Man, Kein-Hong (2006). "Una introducción sencilla a las instrucciones de máquinas virtuales Lua 5.1" (PDF) .
  20. ^ ab "Manual de referencia de Lua 5.2". Lua.org . Consultado el 23 de octubre de 2012 .
  21. ^ Jerusalén, Roberto; de Figueiredo, Luiz Henrique; Celes, Waldemar (2011-2013). Cambios en la API. Lua.org . Consultado el 9 de mayo de 2014 . {{cite book}}: |work=ignorado ( ayuda )
  22. ^ Jerusalén, Roberto; de Figueiredo, Luiz Henrique; Celes, Waldemar. "Manual de referencia de Lua 5.4". Lúa . Consultado el 1 de junio de 2022 .
  23. ^ "LuaRocks". luarocks.org . Consultado el 24 de mayo de 2009 .
  24. ^ "Código de enlace a Lua". Wiki de usuarios de Lua. Archivado desde el original el 27 de julio de 2009. Consultado el 24 de mayo de 2009 .
  25. ^ "¿Por qué se considera Lua un lenguaje de juegos?". Stack Overflow . Archivado desde el original el 20 de agosto de 2013. Consultado el 22 de abril de 2017 .
  26. ^ "¿Por qué Luau?". Luau . Consultado el 23 de marzo de 2022 .
  27. ^ "Introducción a la modificación del lado del servidor de Crysis" . Consultado el 23 de marzo de 2022 .
  28. ^ "Funciones de Lua". wow.gamepedia.com . Consultado el 1 de marzo de 2021 .
  29. ^ "Resultados de la encuesta". Archivado desde el original el 7 de diciembre de 2003. Consultado el 22 de abril de 2017 .{{cite web}}: CS1 maint: bot: estado de URL original desconocido ( enlace )
  30. ^ "Se anunciaron los ganadores del premio Front Line". Archivado desde el original el 15 de junio de 2013. Consultado el 22 de abril de 2017 .
  31. ^ "Extensión: Scribunto - MediaWiki". MediaWiki.org . Consultado el 21 de febrero de 2019 .
  32. ^ "Wikidata: Tutorial de Infobox - Wikidata". www.wikidata.org . Consultado el 21 de diciembre de 2018 .
  33. ^ "Guía de lenguaje - MoonScript 0.5.0". moonscript.org . Consultado el 25 de septiembre de 2020 .
  34. ^ leaf (23 de septiembre de 2020). "leafo/moonscript" . Consultado el 25 de septiembre de 2020 .
  35. ^ ab Garzia, Andre Alves. "Lenguajes que compilan a Lua". AndreGarzia.com . Consultado el 25 de septiembre de 2020 .
  36. ^ "Urn: Una implementación de Lisp para Lua | Urn". urn-lang.com . Consultado el 12 de enero de 2021 .
  37. ^ "Amuleto ML". amulet.works . Consultado el 12 de enero de 2021 .
  38. ^ "LuaJIT". LuaJIT .
  39. ^ "Extensiones". LuaJIT .
  40. ^ "¿Por qué Luau?". Luau . Consultado el 3 de agosto de 2024 . Todo esto nos motivó a comenzar a remodelar Lua 5.1 con el que comenzamos en un nuevo lenguaje derivado que llamamos Luau. Nuestro objetivo es hacer que el lenguaje tenga más rendimiento y más funciones, y facilitar la escritura de código sólido mediante una combinación de linting y verificación de tipos utilizando un sistema de tipos gradual.
  41. ^ "Lenguaje de programación Ravi". GitHub .
  42. ^ Hundt, Richard (22 de abril de 2021). "richardhundt/brillo". GitHub .
  43. ^ "Wiki de Garry's Mod". wiki.facepunch.com .
  44. ^ "Parches de potencia de Lua". lua-users.org . Archivado desde el original el 18 de mayo de 2021 . Consultado el 18 de mayo de 2021 .

Lectura adicional

Enlaces externos