Sommaire
- 1. Bases du langage
- 2. Types de base (8)
- 3. Opérateurs
- 4. Contrôle du flux
- 5. Fonctions
- 6. Gestion des exceptions et multifichiers
- 7. Bibliothèque de base
- 8. Recettes
- 9. Liens web
1. Bases du langage
1.1 Description
Lua, lune en portugais, est un langage de script, gratuit, concis et simple :
- Concis car le langage est assez petit aussi bien dans son nombre de mots-clés que les concepts qu'il met en jeu. Il n'y a par exemple qu'un type de données structurées, les tables, alors que de Python utilisent des tuples, des sets, des listes, des dictionnaires. L'orientation objet n'est pas supportée par des mots-clés dans le langage, il faut la reprogrammer à la main mais Lua offre des facilités pour développer les capacités du langage.
- Simple car Lua a une syntaxe assez standard et très permissive : on peut appeler une fonction sans respecter le nombre de paramètres demandés, on peut simplement concaténer deux expressions à la suite, il n'y pas de système de typage des variables.
La version actuelle (janvier 2022) est la version 5.4 disponible selon les termes de la licence MIT. Ses fichiers portent l'extension .lua
.
1.2 Historique et influences
Lua a été développé au Brésil à partir de 1993 par Roberto Ierusalimschy, Waldemar Celes et Luiz Henrique de Figueiredo au sein du groupe de recherche Computer Graphics Technology Group (TeCGraf [pt, en]), de l'université pontificale catholique de Rio de Janeiro avec l'aide du géant industriel Petrobras [en].
Sa syntaxe emprunte au langage Modula, un langage développé dans les années 70 en Suisse par Niklaus Wirth, le créateur de Pascal. Elle présente également des similarités avec le langage de script Ruby mais sans sa partie orientée objet.
1.3 Désavantages
- Absence de mécanisme d'orientation objet de base,
- Danger de pouvoir concaténer deux expressions à la suite, car il n'y a ni séparateur, ni terminateur :
3+5 2
est valide en Lua ! - Une bibliothèque standard minimaliste où il manque beaucoup de choses mais de taille réduite
- Il n'y a pas de mot clé
continue
pour avancer une boucle d'une itération in
ne s'utilise qu'avec les fonctionspairs
ouipairs
dans unfor
- Opérateur de différence est
~=
au lieu du standard de facto!=
- Opérateur de puissance est
^
au lieu de**
- Pas d'opérateurs combinés :
+= -= *= /=
- Aucune vérification du nombre de paramètres des fonctions
- Aucune déclaration de type possible
- Fusion des types int et float en number
- Fusion du concept de liste et de dictionnaire en celui de table
- Difficulté à connaître la longueur d'une liste et à s'assurer de la continuité de ses index
- On ne peut pas différencier une clé existante avec sa valeur à nil d'une clé qui n'existe pas
- Les clés de type string doivent être entourées de crochets
{ ['key'] = val }
Aucun moyen de déclarer des constantes: Depuis Lua ⩾ 5.4 on peut avec une syntaxe horrible :local stone <const> = 42
- Toute variable sans
local
est globale même dans les fonctions - Conversion automatique des chaînes en nombres
1.4 Utilisations
Lua peut être utilisé de deux façons :
- Via l'interpréteur en tant qu'API C embarqué dans une application hôte. il permet de piloter celle-ci via des scripts en utilisant les fonctions supplémentaires qu'elle met à leur disposition et les bibliothèques Lua. Sa concision fait qu'il ne prend pas trop de place dans l'application hôte. On parle alors de langage d'extension (extension language) ou embarqué (embedded).
- Via l'interpréteur en tant qu'application, appelé lua, on ne peut alors utiliser que les bibliothèques en Lua mais celles-ci sont nombreuses. On parle alors d'utilisation en tant que langage principal (stand alone). On peut utiliser ce dernier pour exécuter d'un coup des scripts Lua ou en mode interactif via une boucle REPL (read-eval-print-loop) en entrant au fur et à mesure des instructions qui sont exécutées au fur et à mesure qu'elles sont entrées dans l'interpréteur. L'interpréteur est programmé en C.
L'interpréteur n'interprète pas directement le script mais le compile en bytecode et envoi celui-ci à la machine virtuelle Lua.
Lua est utilisée de façon embarquée dans de nombreux applications, en particulier des jeux vidéo. On peut citer le lecteur multimédia VLC et le jeu vidéo World of Warcraft.
1.5 Premiers pas
La tradition veut que l'on commence par écrire "Bonjour le monde !" sur la sortie standard (console) lorsque l'on découvre un nouveau langage de programmation.
-- Ceci est un commentaire jusqu'à la fin de la ligne print("Bonjour le monde !")
1.6 Mots réservés (22)
and break do else elseif end false for function goto if in local nil not or repeat return then true until while
1.7 Commentaires
Commentaires en Lua :
-- mon commentaire jusqu'à la fin de la ligne
Commentaires sur plusieurs lignes :
--[[
vos lignes
--]]
1.8 Variables
Une variable est une référence vers une valeur. Une valeur a un type, pas la variable. L'exemple suivant établie une référence entre la variable a et la valeur 5 de type number.
a = 5
Il n'y a pas de constantes en Lua : une variable peut référencer ensuite une autre valeur, du même type ou d'un autre.
Une variable peut être déclarée constante avec l'attribut const :
local stone <const> = 42
2. Types de base (8)
En Lua, il y a 8 types de base.
2.1 nil
Le type nil n'a qu'une seule valeur, nil
.
2.2 Booléens : boolean
Le type boolean a deux valeurs, true
et false
.
Les valeurs nil
et false
sont les deux seules valeurs qui sont considérées comme fausse par les tests. Toutes les autres valeurs, y compris 0
et la chaîne vide ""
sont vraies.
2.3 Nombres : number
Le type number a pour valeurs les entiers et les réels (ou flottants). Les conversions de l'un vers l'autre type sont automatiques. Par défaut, entiers et réels sont stockés sur 64 bits et selon la norme IEEE 754 pour les réels.
2.4 Chaînes de caractères : string
Le type string unifie les caractères et les chaînes de caractères. Lua peut stocker les chaînes en UTF-8 mais ne sait pas comment les gérer.
Les chaînes sont immutables en Lua.
2.5 Fonctions : function
Le type function sera plus étudié dans le chapitre suivant. Il s'agit de bloc de code écrit en Lua ou en C.
2.6 Données utilisateurs : userdata
Le type userdata permet de stocker des données binaires venant du code C avec lequel lua s'interface.
2.7 Processus légers : thread
Lua utilise le type thread pour ses coroutines. Ce type est indépendant des threads du système d'exploitation.
2.8 Tables : table
Lua a fusionné les listes et les tables associatives (ou dictionnaires) dans le type table : une clé désigne une valeur.
Une clé ne peut avoir pour valeur nil
ou NaN
.
t = { ["k1"] = 5, ["k2"] = "v", [4] = 6 } -- Définition print(t["k1"]) -- Accès print(t.k1) -- Accès avec sucre syntaxique
3. Opérateurs
3.1 Liste des opérateurs
Opérateurs arithmétiques
+
addition-
binaire soustraction*
multiplication/
division (converti en float)//
division entière%
modulo^
puissance (converti en float)-
unaire signe négatif
Opérateurs de comparaisons
==
égalité~=
inégalité<
inférieur à>
supérieur à<=
inférieur ou égal à>=
supérieur ou égal à
Si les types sont différents, l'égalité renverra toujours false
.
Opérateurs booléens
&
et|
ou~
binaire ou exclusif>>
décalage à droite (rempli avec des zéros)<<
décalage à gauche (rempli avec des zéros)~
unaire non
Opérateurs logiques
or
ouand
etnot
unaire non
Tout est faux en Lua sauf false
et nil
.
Opérateur | Opé 1 | Opé 2 | Retour |
---|---|---|---|
and | false, nil | non évaluée | opé 1 |
and | autre | évaluée | opé 2 |
or | autre | non évaluée | opé 1 |
or | false, nil | évaluée | opé 2 |
Les opérateurs n'évaluent la deuxième opérande que si nécessaire.
Autres opérateurs
..
concaténation avec conversion#
longueur des chaînes ou bordure des tables
Attention : une table peut avoir des trous, dans ce cas la bordure n'indique pas la longueur de la table.
3.2 Précédence des opérateurs
Niveau | Opérateur |
---|---|
1 | ^ |
2 | unaires : not # - ~ |
3 | * / // % |
4 | + - |
5 | .. |
6 | << >> |
7 | & |
8 | ~ |
9 | | |
10 | < > <= >= ~= == |
11 | and |
12 | or |
4. Contrôle du flux
4.1 Séquence
En Lua, le symbole pour terminer les instructions est ;
mais il est totalement optionnel. Ce code est donc valide : a = 5 b = 6
4.2 Conditions
Pour qu'une partie du code ne soit exécutée que si une condition est vrai, on utilisera if
:
if condition then actions [ elseif condition then actions ] * [ else actions ] ? end
Sont considérées fausses les valeurs false
et nil
. Toutes les autres valeurs sont vraies (dont {} "" 0
).
4.3 Répétitions
Boucle qui s'exécute tant que la condition est vraie avec while
:
while condition do actions end
Le corps de la boucle (ses actions) sera exécuté entre 0 et n fois.
Avec repeat
, le corps de la boucle sera exécuté au moins une fois car la condition est testée après :
repeat actions until condition
Autre grand classique des boucles, for
qui peut-être utilisé avec un intervalle numérique :
for identifiant = debut, fin [ , pas ] do actions end
Par défaut le pas est égal à 1 (si fin < début, la boucle ne s'exécutera pas une seule fois).
Ou avec une table indexée par des nombres :
for indice, valeur in ipairs(table) do actions end
Ou avec une table indexée par des chaînes :
for cle, valeur in pairs(table) do actions end
Dans les trois cas, on peut utiliser le mot-clé break
pour sortir de la boucle.
Il n'y a pas de mot-clé continue ou next en Lua pour passer à l'itération suivante.
5. Fonctions
5.1 Définition
function id ( parametres ) corps end
Il s'agit d'un sucre syntaxique pour :
id = function ( parametres ) corps end
Les paramètres sont séparés par des virgules.
Le paramètre spécial ...
indique qu'il y a des paramètres supplémentaires. Ils seront accessibles dans la variable ...
.
Le mot-clé return
permet de retourner une expression.
5.2 Appel
Pour appeler une fonction on utilise f(p1, p2, p3)
.
On peut omettre les parenthèses si il y a un argument de type string ou table.
5.3 Closure
6. Gestion des exceptions et multifichiers
Il n'y a pas à proprement parler d'exception en Lua. On peut toutefois faire des appels protégés pour gérer les erreurs.
6.1 Appels protégés
6.2 Multifichiers
Pour appeler du code lua écrit dans un autre fichier, il faut faire dans le fichier appelant :
local id = require(string)
La string doit correspondr au nom du fichier sans le .lua.
7. Bibliothèque de base
7.1 Sortie et entrée console
print("Hello World!")
7.2 Nombres
7.3 Chaînes de caractères
Avoir le premier caractère d'une chaîne s : string.sub(s, 1, 1)
Pour tester si une chaîne est un nombre, on essaye de le convertir avec : tonumber(n)
. Si on veut tester si une chaine est un entier, on essaye de la convertir avec : tonumber(n ,base)
(lua ⩾5.2). Dans les deux cas, la fonction renverra nil si elle ne peut pas.
print(tonumber("2.4")) -- retourne 2.4 print(tonumber("2.4", 10)) -- retourne nil print(tonumber("2", 10)) --retourne 2
7.4 Tables
Pour savoir si une table contient une valeur, il faut la parcourir (!) avec un for
:
a = {1,2,3,4,5,6} searched = 3 for index, value in ipairs(a) do if value == searched then print("found", searched, "at", index) break end end
Contient : il faut parcourir avec un for index, value in ipairs(tab) et faire value ⩵ searched
7.5 Fichiers
8. Recettes
8.1 Programmation orientée objet (POO)
8.1.1 Définir un type
local Type = {} function Type:new() return setmetatable({}, {__index = Type}) end function Type:method(params) cod end
8.1.2 Instancier et appeler une méthode
local t = Type.new() t.method(t, param) t:method(param)
Le double point :
est un sucre syntaxique pour éviter de passer en premier paramètre l'instance.
8.2 Recettes pour LÖVE
8.2.1 Afficher la console
- Faire un fichier conf.lua dans le répertoire du jeu
- Faire une fonction love.conf(t)
- Faire dans le corps de la fonction t.console = true
8.2.2 Faire une fonction principale
- Faire un fichier main.lua dans le répertoire du jeu. Love ne lance qu’un répertoire ou un fichier packagé .love
- Faire une fonction love.load()
- Mettre le code dedans dont love.window.setTitle(string)
9. Liens web
9.1 Généraux
- Site officiel du langage, avec la distribution standard (interpréteur officiel + bibliothèque standard)
- La première édition, un peu datée, du livre électronique Programming in Lua (ou PIL) introduit Lua avec de nombreux exemples.
- Le wiki des utilisateurs de Lua
- Lua binaries, distributions de Lua pour différents systèmes d'exploitation
- Page de Wikipédia sur Lua
- Boutique officielle Zazzle pour supporter Lua via l'achat de goodies
9.2 Bibliothèques
9.3 Interpréteurs
- Intepréteur en ligne One Compiler
- Löve, VM Lua mettant à disposition une bibliothèque pour faire des jeux
- REPL.it interpréteur en ligne
- MoonSharp interpréteur en C# pour .Net, Mono et Unity
- Moonshine interpréteur et VM en JavaScript
9.4 Langages liés
- Teal surlangage avec des types.
- MoonScript un langage qui transpile en Lua.
- Titan un langage statically-typed, ahead-of-time compiled mais surtout abandonné
- Pallene un langage statically typed and ahead-of-time compiled, fork de Titan
- Terra statically-typed, compiled language with manual memory management and low-level system programming language that is embedded in and meta-programmed by the Lua programming language
9.5 Outils
- ZeroBrane Studio un IDE léger, gratuit, simple et efficace
Damien Gouteux Aide-mémoire Lua v0.1 2017-2024