A Linguagem Lua Características das Linguagens de Programação Nome: Rodrigo da S. Yanagisawa 1 Visão geral Lua é uma linguagem de programação interpretada imperativa, procedural, pequena e leve, projetada para expandir aplicações em geral, para ser usada como linguagem extensível (que une partes de um programa feitas em mais de uma linguagem). Lua é normalmente descrito como uma linguagem de múltiplos paradigmas, oferecendo um pequeno conjunto de características gerais que podem ser estendidas para encaixar diferentes tipos de problemas, em vez de fornecer uma especificação mais complexa e rígida para combinar com um único paradigma. 2 Visão geral Lua é uma linguagem que suporta apenas um pequeno número de estruturas de dados, tais como valores booleanos, números (tipicamente double), e strings. Matrizes, listas e registros podem ser representados por meio da única estrutura de dados presente na linguagem que é a Tabela (Table). Devido à sua eficiência, clareza e facilidade de aprendizado, passou a ser usada em diversos ramos da programação, como no desenvolvimento de jogos, controle de robôs, processamento de texto, etc. 3 Visão geral A distribuição de Lua é gratuita: Lua pode ser usada para quaisquer propósitos, tanto acadêmicos quanto comerciais, sem nenhum custo. Lua foi projetada e implementada por uma equipe no Tecgraf, o Grupo de Computação Gráfica da Puc-Rio (Pontifícia Universidade Católica do Rio de Janeiro). 4 Um pouco de História... 5 Origens DEL – Data-Entry Language Linguagem para Especificação de Diálogos SOL – Simple Object Language Linguagem para Descrição de Objetos 6 Origens Origens Essas duas linguagens foram desenvolvidas de forma independente entre os anos de 92 e 93, e tinham como preocupação adicionar flexibilidade a dois diferentes projetos (ambos eram programas gráficos interativos para aplicações de engenharia na Petrobras). Mas... 7 1993 DEL e SOL tinham vários problemas em comum. Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes se juntaram para achar uma solução comum a seus problemas... 8 O que eles precisavam? • Uma “linguagem de configuração genérica”; • Uma linguagem “completa”; • Facilmente acoplável; • Portátil; • O mais simples possível; • Sintaxe não intimidante. Para usuários finais (engenheiros, geólogos etc.) 9 “Como estávamos largando ‘Sol’, um amigo sugeriu um novo nome...” 10 E daí surgiu a “Lua” 11 Logo, vários projetos no Tecgraf estavam usando Lua 12 "63% of the main Lightroom-team authored code is Lua", Troy Gaul, Adobe 13 Utilização Lua é utilizada também para implementar software embutido em equipamentos de rede (switches ethernet), aplicações de simulação em laboratórios de física (tendo sido esta uma de suas primeiras utilizações fora da PUC-Rio, no Observatório Astrofísico de Smithsonian) etc. 14 Utilização Por ter sido desenvolvida completamente em ANSI C, as bibliotecas de Lua podem ser usadas em qualquer plataforma que tenha um compilador compatível com o padrão ANSI. Lua já foi compilada para, entre outras, DOS, Linux, Windows 9x/NT/2000/Me, Solaris, SunOs, AIX, Irix, EPOC, PalmOs, Macintosh, Playstation 2 e PSP- a lista cresce a cada dia. 15 Lua nos Games (o início) From: Bret Mogilefsky <[email protected]> To: "'[email protected]'" <[email protected]> Subject: LUA rocks! Question, too. Date: Thu, 9 Jan 1997 13:21:41 -0800 Hi there... After reading the Dr. Dobbs article on Lua I was very eager to check it out, and so far it has exceeded my expectations in every way! It‘s elegance and simplicity astound me. Congratulations on developing such a well-thought out language. Some background: I am working on an adventure game for the LucasArts Entertainment Co., and I want to try replacing our older adventure game scripting language, SCUMM, with Lua. 16 17 18 19 20 21 22 23 Utilização Lua no desenvolvimento de games Uma pesquisa realizada em setembro de 2003 pela gamedev.net que a grande maioria dos jogos (72%) é desenvolvida com o auxílio de uma linguagem de script. Acoplar uma linguagem de script em um jogo traz vários benefícios. A linguagem de script pode ser usada para efetivamente implementar o script do jogo, para definir objetos e seus comportamentos, para gerenciar os algoritmos de inteligência artificial e controlar os personagens, e ainda para tratar os eventos de entrada e descrever a interface com o usuário. 24 Utilização Lua no desenvolvimento de games A escolha de uma linguagem de script simples permite ainda que seja dado a roteiristas e artistas acesso programável ao jogo, a fim de que eles que possam experimentar novas idéias e variações. Esses profissionais conduzem a maior parte do desenvolvimento real do jogo mas não são em geral programadores profissionais e não estão familiarizados com técnicas sofisticadas de programação. Pesquisa na gamedev.net (set/2003): • 20% usam Lua • 7% usam Phyton 25 Características Lua é uma linguagem de extensão projetada para dar suporte à programação procedural, oferecendo facilidades para descrição de dados. No contexto da programação de jogos, isso significa que Lua possibilita combinar a descrição de objetos e a programação de seus comportamentos num mesmo contexto. Lua é uma biblioteca implementada em C, podendo ser compilada em qualquer plataforma que tenha um compilador C padrão. Lua também pode ser compilada sem alterações como uma biblioteca C++. 26 Características Por ser uma linguagem de extensão, Lua trabalha acoplada a uma aplicação hospedeira (host). Essa aplicação pode criar e ler valores armazenados em Lua, executar funções de Lua e registrar funções C no ambiente de Lua. As funções C registradas em Lua, por sua vez, podem ser invocadas de programas Lua. Dessa forma, podemos conciliar as facilidades de uma linguagem de script oferecidas por Lua com a eficiência das linguagens C e C++. A distribuição da linguagem Lua inclui um programa hospedeiro, lua.c, que pode ser usado para executar scripts Lua interativamente ou em batch. 27 Características Para que uma aplicação tenha acesso a Lua, precisamos abrir a biblioteca. Ao final, a aplicação deve fechar a biblioteca. Após a abertura da biblioteca, a aplicação pode usar os recursos oferecidos por Lua, como por exemplo, executar scripts Lua e acessar dados armazenados em Lua. Programas ou scripts Lua são armazenados em arquivos (usualmente com extensão .lua) ou em strings da aplicação. Um arquivo ou string com código Lua caracteriza o que chamamos de chunk, que é simplesmente uma seqüência de comandos Lua. 28 A Linguagem 29 Variáveis e Tipos Em Lua, as variáveis não têm tipos associados a elas: os tipos estão associados aos valores armazenados nas variáveis. Dessa forma, uma mesma variável pode num momento armazenar um valor de um tipo e depois passar a armazenar o valor de outro tipo (naturalmente, a variável deixa de armazenar o valor inicial). O trecho de código abaixo ilustra o uso de variáveis armazenando diferentes valores: a = "Exemplo" b = 1.23 ... b = nil a=3 -- a armazena string -- b armazena numero -- b armazena nil -- a armazena numero 30 Variáveis e Tipos Em Lua, variáveis globais não precisam ser declaradas. Quando escrevemos a = 3, a variável a é, por default, uma variável global. Se desejarmos que uma variável tenha escopo local (a um bloco ou chunk), devemos declará-la previamente usando a palavra reservada local. Por exemplo: local a ... a=3 31 Os valores em Lua podem ser de oito tipos: Tipo nil O tipo nil representa o valor indefinido. Todas as variáveis ainda não inicializadas assumem o valor nil. Assim, se o código: a=b for encontrado antes de qualquer atribuição à variável b, então esta é assumida como contendo o valor nil, o que significa que a também passa a armazenar nil, independentemente do valor anteriormente armazenado em a. 32 Tipo number O tipo number representa valores numéricos. Lua não faz distinção entre valores numéricos com valores inteiros e reais. Todos os valores numéricos são tratados como sendo do tipo number. Assim, o código a=4 b = 4.0 c = 0.4e1 d = 40e-1 armazena o valor numérico quatro nas variáveis a, b, c e d. 33 Tipo string O tipo string representa cadeia de caracteres. Uma cadeia de caracateres em Lua é definida por uma seqüência de caracteres delimitadas por aspas simples (' ') ou duplas (" "). Por simplicidade, quando a cadeia de caracteres é delimitada por aspas duplas, pode-se usar aspas simples no seu conteúdo, sem necessidade de tratá-las como seqüências de escape. Entretanto, para reproduzir na cadeia de caracteres as aspas usadas como delimitadoras, é necessário usar os caracteres de escape. Assim, são válidas e equivalentes as seguintes atribuições: s = "Olho d'agua" s = 'Olho d\'agua' 34 Tipo function Funções em Lua são consideradas valores de primeira classe. Isto significa que funções podem ser armazenadas em variáveis, passadas como parâmetros para outras funções, ou retornadas como resultados. A definição de uma função equivale a atribuir a uma variável global o valor do código que executa a função. function func1 (...) ... end que pode posteriormente ser executada através de uma chamada de função: func1(...) 35 Tipo userdata O tipo userdata permite que dados C arbitrários possam ser armazenados em variáveis Lua. Este tipo corresponde a um bloco de memória e não tem operações prédefinidas em Lua, exceto atribuição e teste de identidade. Contudo, através do uso de metatables, o programador pode definir operações para valores userdata. Valores userdata não podem ser criados ou modificados em Lua, somente através da API C. Isto garante a integridade dos dados que pertencem ao programa hospedeiro. 36 Tipo table O tipo table implementa arrays associativos, isto é, arrays que podem ser indexados não apenas por números, mas por qualquer valor (exceto nil). Tabelas podem ser heterogêneas; isto é, elas podem conter valores de todos os tipos (exceto nil). Tabelas são o único mecanismo de estruturação de dados em Lua; elas podem ser usadas para representar arrays comuns, tabelas de símbolos, conjuntos, registros, grafos, árvores, etc. Para representar registros, Lua usa o nome do campo como um índice. 37 Tipo thread O tipo thread representa fluxos de execução independentes e é usado para implementar co-rotinas. Não confunda o tipo thread de Lua com processos leves do sistema operacional. Lua dá suporte a co-rotinas em todos os sistemas, até mesmo naqueles que não dão suporte a processos leves. Tipo boolean Boolean é o tipo dos valores false e true. 38 Atribuição simples e múltipla É possível atribuir diversas variáveis em um mesmo comando. Por exemplo: s, v = "Linguagem Lua", 2 Quando o número de variáveis listadas à esquerda do sinal de igualdade é diferente do número de resultados à direita da igualdade, a linguagem automaticamente ajusta as listas: ou preenchendo as últimas variáveis da esquerda com valores nils ou descartando os últimos resultados da direita. Por exemplo: a, b = 2 c, d = 2, 4, 6 O código acima atribui 2 à variável a, nil à variável b, 2 à variável c, 4 à variável d, e despreza o valor 6. 39 Atribuição simples e múltipla A possibilidade de atribuição múltipla permite a troca de valores armazenados em duas variáveis com um único comando. Portanto a, b = b, a faz com que a receba o valor anteriormente armazenado por b e que b receba o valor anteriormente armazenado por a, sem necessidade de variáveis temporárias. 40 Operadores relacionais Os operadores relacionais disponíveis em Lua são: < menor que > maior que <= menor que ou igual a >= maior que ou igual a == igual a ~= diferente de Os operadores relacionais retornam o valor nil quando o resultado é falso e o valor 1 quando o resultado é verdadeiro. Assim, as atribuições a=4<3 b=4>3 armazenam em a o valor nil e em b o valor 1. Os operadores >, <, >=, <= só são aplicáveis em dados do tipo number ou string, e têm a interpretação usual. 41 Controle de fluxo – (if) if condição then bloco end ou ou ainda if condição then bloco1... else bloco2... end if condição1 then bloco1 elseif condição2 then bloco2 ... elseif condiçãoN then bloco N else bloco N+1 end 42 Laço iterativo – (while) while condição1 do bloco end Exemplo: f=1 i=n while i > 0 do f=f*i i=i–1 end 43 Laço iterativo – (repeat) repeat bloco until condição1 Exemplo: f=1 i=n while i > 0 do f=f*i i=i–1 end 44 Laço iterativo – (for) for var = exp1, exp2, exp3 do bloco end Exemplo: for i = 10, 1, -1 do print(i) end 45 Funções A linguagem Lua trata funções como valores de primeira classe. Isto quer dizer que funções podem ser armazenadas em variáveis, podem ser passadas como parâmetros para outras funções e podem ser retornadas como resultados de funções. function nome ( [lista-de-parâmetros] ) bloco de comandos end A chamada da função segue a forma básica nome ( [lista-de-argumentos] ) Lua passa parâmetros por valor. Isto quer dizer que quando se altera o valor de um parâmetro dentro de uma função, altera-se apenas o valor da variável local correspondente ao parâmetro. O valor da variável passada como argumento na chamada da função permanece inalterado. 46 Funções Os valores retornados por uma função são ajustados para a atribuição na linha que faz a chamada. Para exemplificar, supõe-se uma função que incrementa os valores de um ponto cartesiano (x, y): function translada (x, y, dx, dy) return x+dx, y+dy end Considera-se, agora, que a chamada da função é feita por: a, b = translada(20, 30, 1, 2) Assim, a recebe o valor 21 (=20+1) e b recebe o valor 32 (=30+2). 47 Funções Seguindo o mesmo exemplo, se a chamada fosse a = translada(20, 30, 1, 2) Então o segundo valor retornado seria desprezado, e a receberia o valor 21. Por outro lado, a atribuição: a, b, c = translada(20, 30, 1, 2) Faria a= 21, b = 32 e c = nil. 48 LuaJava Uma ferramenta de scripting para Java LuaJava é uma biblioteca que permite estender a linguagem Java usando Lua como ferramenta de scripting. A grande jogada da biblioteca LuaJava é permitir interoperabilidade total entre o ambiente Java e o ambiente Lua. Você pode, por exemplo, criar classes em Lua e usar uma interface para instanceá-las em Java, ou então “importar” uma biblioteca escrita em Java (seja ela criada por você ou do pacote padrão) e usar em seus scripts Lua. 49 LuaState O principal objeto da LuaJava é o LuaState. O LuaState guarda uma referencia para a máquina virtual Lua, e é a partir dele que você vai carregar arquivos de script, registrar classes, chamar funções, etc. public static void main(String[] args){ LuaState luaState; luaState = LuaStateFactory.newLuaState(); luaState.openLibs(); luaState.LdoFile("helloworld.lua"); luaState.close(); } No arquivo .lua print("Hello World") 50 99 Bottles of Beer function PrintBottleNumber(n) local bs if n == 0 then bs = "No more bottles" elseif n == 1 then bs = "One bottle" else bs = n .. " bottles" end return bs .. " of beer" end for bn = 99, 1, -1 do write(PrintBottleNumber(bn), " on the wall, \n") write(PrintBottleNumber(bn), "\n") write("Take one down and pass it around,\n") write(PrintBottleNumber(bn-1), " on the wall, \n\n") end write("No more bottles of beer on the wall,\nNo more bottles of beer\n") write("Go to the store, buy some more!\n") 51 Obrigado! 52