Lua, tour d’horizon

Lua

Sommaire

Présentation
Éléments de syntaxe : Écriture, Commentaires, Chaînes de caractères.
Valeurs, Types, Variables et Fonctions : Typage dynamique, Lua possède 8 types de base, Portée des variables.
Structures de contrôle : Structure conditionnelle, Structures itératives, Structures itératives for générique, Conditions, Bloc d’instructions.
Fonctions particulières, particularités : self et « : », Fonctions sur les chaînes.
Plus d’information, sources

Présentation

Flexible, réflexif, impératif, compact et léger (compilateur, interpréteur et librairies standards n’occupent qu’environ 150 kilo-octets une fois compilés), open-source (distribué sous la licence MIT), Lua est un langage de script extrêmement puissant et rapide (dix à trente fois plus rapide que d’autres langages de scripts tel que TCL, Perl, Python, Ruby ou PHP). Lua est écrit en langage C ANSI strict et donc multiplateforme.

Créé en 1993, Lua (Lune en portugais, prononcer Loua, écrire Lua et pas LUA car ce n’est pas un acronyme) a été développé par Luiz Henrique de Figueiredo, Roberto Ierusalimschy et Waldemar Celes, membres du groupe de recherche TeCGraf, de l’université pontificale catholique de Rio de Janeiro au Brésil.

Voici un programme minimaliste en Lua. En sauvant le code ci-dessous dans le fichier hello.lua, le script s’exécute de la manière suivante : $ lua hello.lua

print("Hello World")

Voici un script Lua plus évolué :

-- Définition d'une fonction factorielle
function fact (n)
  if n == 0 then
    return 1
  else
    return n * fact(n-1)
  end
end
 
print("Saisir un nombre :")
a = io.read("*number") -- read a number
print(fact(a))

Éléments de syntaxe

Écriture

Lua est un langage free-form : les espaces ne servent que de délimiteurs entre identifiants et mots-clefs. Lua tient compte de la casse. Les identifiants ne doivent pas commencer par un chiffre mais peuvent en contenir ainsi que des _. La liste des mots-clefs est :
and break do else elseif end false for function goto if in local nil not or repeat return then true until while
Les autres séquences réservées sont :
+ - * / % ^ # == ~= <= >= < > = ( ) { } [ ] :: ; : , . .. ...

Commentaires

Les commentaires débutent par -- n’importe où en dehors d’une chaîne de caractères et finissent à la fin de la ligne, sauf si la séquence -- et suivie d’un [=[ (avec un nombre arbitraire de =) auquel cas le commentaire se poursuit, éventuellement sur plusieurs lignes, jusqu’à la séquence de fermeture correspondante (]=] avec le même nombre de =). Une première ligne commençant par un shebang (#!) est aussi traitée comme un commentaire.

-- Un commentaire sur une ligne
--[[ un commentaire sur 
plusieurs lignes ]]

Chaînes de caractères

Les chaînes de caractères sont délimitées par des cotes 'Une chaîne de caractères', des guillemets "Une chaîne de caractères" ou encore par la marque de chaîne littérale, construite sur le même principe que celle des commentaires, autorisant l’écriture de chaînes sur plusieurs lignes [=[Une chaîne de caractères éventuellement sur plusieurs lignes]=] (avec un nombre de = arbitraire mais identique pour la fermeture et l’ouverture). Les chaînes de caractères peuvent contenir des séquences d’échappement comme par exemple : \n (New line), \t (tabulation), \' (simple cote), \" (guillemet), \\ (antislash)…

Valeurs, Types, Variables et Fonctions

Typage dynamique

Lua est une langage à typage dynamique. Cela signifie que les variables n’ont pas de type, seules les valeurs en ont un. Le type étant porté par les valeurs, il n’y a donc aucune déclaration de type en Lua. Lua, qui est un langage réflexif, possède et une fonction type() qui retourne le type de la valeur passée en argument.

> print(type(1),type(true),type("2"))
number	boolean	string
> a=1
> print(type(a))
number
> a=true
> print(type(a))
boolean
> a='un'
> print(type(a))
string

Lua possède 8 types de base

  • string : C’est le type des chaines de caractère. La fonction print() permet d’afficher une chaine de caractères et l’opérateur .. de concaténer deux chaines de caractères.
    > print([=["Une chaine"]=], type([=["Une chaine"]=]))
    "Une chaine"	string
    > print("Une ".."chaine")
    Une chaine
    > print("1+1="..1+1)
    1+1=2
  • nil : nil est une valeur spéciale indiquant une absence de valeur. la valeur nil possède la particularité d’être différente de toute autre valeur.
    > print(nil,type(nil))
    nil	nil
  • boolean : Le type boolean possède deux valeurs, true et false.
    > print(true, not true,type(true))
    true	false	boolean
  • number : Lua n’implémente qu’un seul type de nombre, le nombres à virgule flottante de précision double (codé sur 64 bits).
    > print(1+1,2/3,type(4))
    2	0.66666666666667	number
    > print(4/3,math.ceil(4/3),5/3,math.floor(5/3))
    1.3333333333333 	2	1.6666666666667 	1
  • function : Les fonctions sont considérées comme des variables. Il est donc possible de créer une fonction locale à une autre fonction, de passer une fonction en paramètre ou comme valeur de retour, ou encore de mettre des fonctions dans des tables. Les fonctions Lua peuvent prendre un nombre indéfini de paramètres ainsi que retourner plusieurs valeurs. En fait, le langage Lua traduit l’instruction function f () body end en f = function () body end.
    > function f() return "Bonjour" end -- Définition de la fonction f
    > f=function() return "Bonjour" end -- Définition équivalente de la fonction f
    >  print(f,f(),type(f)) -- Exemple d'appel de la fonction f
    function: 0x241ea30	Bonjour	function
  • table : Une table est une structure Lua qui permet de stocker des variables indexées par des clefs (tableaux associatifs). La table est donc une structure extrêmenet flexible et puissante qui sert, par exemple, pour représenter des pseudo-classes et objets.
    > tab={un=1,"deux",f=function(x,y) return x..y end}
    > print(tab,type(tab),tab.un,type(tab.un),tab[1],type(tab[1]),tab.f(3,"quatre"),type(tab.f))
    table: 0x24220f0	table	1	number	deux	string	3quatre	function
  • userdata : Le type userdata correspond à un objet C/C++ défini par l’utilisateur.
  • thread : Le type thread est utilisé pour implémenter les coroutines qui sont une sorte de multithreading collaboratif.

Portée des variables

Toutes les variables déclarées dans Lua sont de portée globale à moins qu’elles n’aient été déclarées locales.

> x,y=1,2
> function f() x=4 ; local y=5 end
> print(x,y)
1	2
> f() 
> print(x,y)
4	2

Structures de contrôle

Structure conditionnelle

if condition then
  -- Bloc d'instructions
elseif condition then
  -- Bloc d'instructions
elseif condition then
  -- Bloc d'instructions
else
  -- Bloc d'instructions
end

Structures itératives

repeat
  -- Bloc d'instructions
until condition
 
> i=1 ; repeat print(i) ; i=i+1 until i==3
1
2
while condition do
  -- Bloc d'instructions
end
 
> i=1 ; while i<3 do print(i) ; i=i+1 end
1
2
for var = début, fin, incrément do
  -- Bloc d'instructions
end
 
> for i=1,6,2 do print(i) end
1
3
5

Structures itératives for générique

for var_1, ..., var_n in explist do
  -- Bloc d'instructions
end
 
> for key,value in pairs({10, math.pi, "banane"}) do print(key, value) end
1	10
2	3.1415926535898
3	banane

L’expression l’explist (liste d’expressions) est évaluée avant l’entrée dans la boucle. Les résultats de cette évaluation sont une fonction itérative (qui place les valeurs var_1, …, var_n), un état (d’où les valeurs peuvent être lues), et une valeur initiale (d’où part l’itération).

Conditions

Les valeurs nil et false falsifient une condition, toute autre valeur rend la condition vraie.
Les opérateurs logiques sont : and, or et not . Les opérateur and et or n’évaluent le second opérande que si nécessaire.
Les opérateurs de comparaison sont : ==, ~=, <, >, <= et >=.

> if true then print(true) else print(false) end
true
> if 1 then print(true) else print(false) end
true
> if 0 then print(true) else print(false) end
true
> if nil then print(true) else print(false) end
false
> if nil==false then print(true) else print(false) end
false
> if "1"==1 then print(true) else print(false) end
false
> if tonumber("1")==1 then print(true) else print(false) end
true

Bloc d'instructions

Un bloc d'instruction regroupe plusieurs instructions contiguës exécutées séquentiellement. Un bloc peu être implicite (ex.: ensemble des instructions entre les mots clefs then et else d'une structure conditionnelle) ou explicite (utilisation des mots clefs do et end).

do
  -- Instruction
  -- Instruction
  -- ...
end

L'instruction break permet de sortir d'une structure itérative (while, repeat, ou for) tandis que l'instruction return permet de terminer une fonction et de retourner des valeurs. Ces deux instructions, break et return, doivent impérativement être placée s à la fin d'un bloc d'instruction, donc juste avant un end, ou un else par exemple.

Fonctions particulières, particularités

self et « : »

function a:b(...) end

est un raccourci syntaxique pour

function a.b(self, ...) end

Chacune de ces deux fonctions peut être appelée indifféremment de l'une des deux manières suivantes :

a:b(...)
a.b(a, ...)

Fonctions sur les chaînes

> print(string.match('aaxbb','^(.*)x'))
aa
> print(string.match('aaxbb','^(.*)x(.*)$'))
aa	bb

Plus d'information, sources

ProgrammingInLua

Le livre de référence : Programming in Lua, Third Edition
The Programmin Language Lua : Le site de référence
Programming in Lua (first edition) : Première édition du livre de référence en ligne
Lua Tutorial : Un excellent tour d'horizon
Lua - Wikipedia : Une bonne introduction
Lua : un langage de script puissant : Une autre bonne introduction
Introduction à la programmation LUA : Un cours intéressant
Lua Editor Support : Inventaire d'éditeurs de code Lua

Sommaire Domotique sur ce blog

Cette entrée a été publiée dans Enseignement, Domotique, Tutoriels and taguée . Placez un signet sur le permalien.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *