unit - Vuzi/vuziks GitHub Wiki
Chaque unité de code possède ses propres sous unitées, variables et instructions. En vuziks tout code entre accolades est une unité de code. Ainsi, les conditions ou même les accolades seules sont des unités de code.
Le langage utilise par défaut une unité implicite, permettant d'écrire directement des instructions (La première ligne étant le point d'entré).
Portée des variables et fonctions
La portée d'une variable en vuziks est son unité de code. Il n'est donc pas possible d'accéder à une variable d'une fonction depuis l'extérieur.
L’interpréteur regarde donc en premier si la variable est dans son unité courante. Si ce n'est pas le cas, alors l’interpréteur remonte d'un cran et relance la recherche. Le cheminement des fonctions est le même. Si une variable à le même nom qu'une variable plus haute dans les unité, celle-ci empêchera alors d'y accéder (De même pour les fonctions).
Ainsi, une variable déclarée dans l'unité implicite de base peut être considéré comme une variable globale de par sa portée.
Exemple :
var a = 0.5;
var b = 12;
unit foo(b,c) {
print(a);
print(b+c);
}
print(a); # Affiche 0.5
{
var a = 42;
print(a); # Affiche 42
foo(1,2); # Affiche 42 puis 3
}
foo(1,2); # Affiche 0.5 puis 3
Si utilisé comme une fonction en C, alors une unité se comportera comme une fonction et ne sauvegardera ni ses variables ni autres unités internes, alors qu'associé au mot-clef new et si stocké en mémoire, alors ces variables et sous-unités restent en mémoire et sont utilisables.
Les différents types de blocs
Conditions
Les conditions, ou bloc conditionnel, sont des instructions de code qui ne sont exécutée que si la condition présente est validée (Que son résultat, une fois casté en booléen, vaut vrai).
if (si)
La condition la plus simple est sans doute le if. Si la condition est vraie, alors le bloc est exécuté :
var val = 12;
# Affiche 42 uniquement si foo renvoi 23 avec 12 comme argument
if(foo(val) == 23) {
print(42);
}
elif (sinon si)
Cette condition ne peut prendre place qu'après un premier if et teste une condition après que celle précédente ait été fausse. Plusieurs elif peuvent être situé à la suite :
var val = 12;
# Affiche 42 uniquement si foo renvoi 23 avec 12 comme argument
# ou alors affiche 12 si foo ne renvoi pas 23 mais que boo renvoi 12
if(foo(val) == 23) {
print(42);
} elif (boo(val) == 12) {
print(12);
}
Une suite de condition ne peut pas commencer par un elif.
else (sinon)
Il s'agit d'un elif qui serait toujours vrai. La place de ce bloc est donc généralement après une suite de elif ou un if. Une suite de condition ne peut pas commencer par un else.
Boucles itératives
Une boucle itérative contient une condition d'arrêt, ainsi que parfois des opérations à effectuer à chaque tour de boucle (En plus des opérations du bloc).
while (tant que)
La boucle while permet d’exécuter un bloc de code tant que la condition testée est vraie :
# Programme qui va afficher 5 fois la lettre a
var a = 5;
while(a > 0) {
a = a - 5;
print('a');
}
for (pour x tant que)
La boucle for agit comme la boucle while à la différence que celle-ci effectue une opération au lancement et à chaque fin de tour.
# Programme qui va afficher 5 fois la lettre a
for(a = 5; a > 0; a = a - 1) {
print(a);
}
Unités
Une unité est un bloc d'instruction qui n'est pas directement appelé (Contrairement aux blocs conditionnels et itératifs) mais gardé en mémoire pour être appelé plus tard avec des variables spécifiques (Arguments).
Une déclaration de ce type de bloc se fait avec le mot clef unit suivit du nom des arguments entre parenthèses :
# Fonction foo qui prend en argument deux variables a et b
unit foo(a,b) {
return(a+b);
}
L'appel à return coupe la traitement et renvoi le résultat
Un appel de fonction en vuziks se fait avec le nom de la fonction suivit de parenthèses avec les arguments du programme.
print(foo(12,42));
Fonctionnement des objets & du bloc unit
Un bloc unit désigne en fait d'une manière générique un bloc contenant des instructions, quelque soit leurs sortes. Il existe deux manières d'utiliser un bloc unit.
La première est comme une fonction, alors le bloc retournera comme valeur ce qui est passé au premier return rencontré, ou null par défaut. Il s'agit du fonctionnement le plus simple.
# Fonction foo qui prend en argument deux variables a et b
unit foo(a,b) {
return(a+b);
}
L'autre est comme un objet, en lui signifiant avec l'aide du mot clef new qu'on ne souhaite pas attendre un résultat mais sauvegarder le contexte d’exécution à la fin de celui-ci. Si un return retourne une valeur quelconque, celle-ci sera ignorée (Mais le return arrêtera bien l’exécution). Il devient alors possible d’accéder aux valeurs et autres unit internes avec l'opérateur . :
# On crée notre unité
unit test(a) {
attr b = a * 2;
unit foo() {
a = a + 1;
return 12;
}
}
var v = new test(1); # On souhaite conserver le contexte
print(test.foo()); # Affiche 12
print(test.b); # Affiche 2 (valeur de b)
print(test.a); # Affiche valeur de type non-existence
Si on tente d’accéder à une valeur inexistante, la même erreur sera générée que lorsqu'on tente d’accéder à une variable locale qui n'existe pas. De même pour les unités internes.