Expressions et opérateurs

Littéraux et expressions primaires

nil  true  false
42  3.14  0x2A  0b101010
"chaîne"  'chaîne'  [[chaîne longue]]
...                     -- varargs (voir Variables)
{ 1, 2, x = 3 }         -- constructeur de table
function(x) return x end
(expr)                  -- expression parenthésée

Un identifiant (a, t.champ, t[clé], f(...), t:méthode(...)) est une expression « préfixée » : on peut enchaîner indexation et appel librement, dans n'importe quel ordre autorisé par la grammaire (a.b[1]:c().d).

Opérateurs arithmétiques

Opérateur Sens
+ - * addition, soustraction, multiplication
/ division
// division entière
% modulo
^ puissance (toujours flottante)
- (unaire) négation

Ces opérateurs acceptent des nombres, ou des chaînes convertibles en nombre (conversion automatique). Le résultat est un entier si les deux opérandes (après conversion) sont des entiers, sauf pour ^ qui produit toujours un flottant. Voir Différences avec Lua pour le comportement de / et // entre deux entiers, qui diffère de Lua standard.

Le préfixe unaire + est accepté par le parseur mais n'a aucun effet (il est simplement ignoré, sans même exiger un opérande numérique à la compilation).

Opérateurs relationnels

== ~= < <= > >= — voir Types et valeurs pour la sémantique d'égalité entre types différents. </<=/>/>= comparent deux chaînes par ordre lexicographique, ou deux nombres par valeur ; toute autre combinaison de types requiert une métaméthode (__lt/__le), sinon c'est une erreur.

Opérateurs logiques

and, or et not opèrent sur la « valeur fausse » définie dans Types et valeurs, pas uniquement sur les booléens :

print(nil and 1)     --> nil    (s'arrête au premier opérande faux)
print(false or "x")  --> x
print(1 and 2)        --> 2     (and retourne le second opérande si le premier est vrai)
print(not 0)           --> true (0 est une valeur fausse en YScript, voir Différences avec Lua)

and/or sont évaluées en court-circuit : le second opérande n'est évalué que si nécessaire.

Opérateurs sur bits

& (et), | (ou), ~ (ou exclusif, binaire), <<, >> (décalages), ~ (unaire, complément à un). Ces opérateurs s'appliquent :

Il n'y a pas de conversion implicite d'un flottant en entier pour ces opérateurs : 1.0 & 1 n'est pas une opération native, elle requiert une métaméthode ou lève une erreur.

Concaténation

.. concatène deux chaînes, ou convertit silencieusement ses opérandes numériques en chaîne avant de les joindre :

print("a" .. "b")     --> ab
print("n=" .. 42)     --> n=42

nil, les booléens, les tables (sans métaméthode __concat) ne sont pas concaténables et lèvent une erreur.

Opérateur de longueur

# retourne la longueur d'une chaîne (nombre de caractères), ou la longueur de la partie « tableau » d'une table (indices entiers consécutifs à partir de 1), ou invoque la métaméthode __len si elle est définie.

print(#"bonjour")    --> 7
print(#{ 1, 2, 3 })   --> 3
print(#{ 1, nil, 3 }) -- résultat non garanti au-delà du premier trou, comme en Lua

Précédence (de la plus faible à la plus forte)

or
and
<  >  <=  >=  ~=  ==
|
~ (binaire)
&
<<  >>
..                      (associatif à droite)
+  -
*  /  //  %
unaires : not  #  -  ~
^                       (associatif à droite)

Utilisez des parenthèses pour lever toute ambiguïté : 2 + 3 * 4 vaut 14, 2 ^ 2 ^ 3 vaut 256.0 (associativité à droite : 2 ^ (2 ^ 3)).

Constructeurs de table

local t = {}                        -- table vide
local t = { 1, 2, 3 }               -- indices 1, 2, 3 (partie tableau)
local t = { x = 1, y = 2 }          -- clés nommées (équivalent à ["x"] = 1)
local t = { [10] = "dix", "un" }    -- mélange : "un" prend l'indice 1, [10] est explicite
local t = { f(), g() }              -- seule la dernière expression d'appel se développe

Les champs sont séparés par , ou ; indifféremment, avec une virgule/point-virgule finale optionnelle.