Manuel de référence complet pour la version
3 de Scriptol.
Ce manuel s'utilise pour le compilateur de Scriptol en C++ (solc) ou en JavaScript (solj).
Le compilateur Scriptol PHP (solp) utilise Scriptol 2.
Pour les anciennes versions des compilateurs reportez vous au langage Scriptol 1.
Le langage est entièrement implémenté dans le compilateur de Scriptol en JavaScript mais quelques extensions (promises, async/await) ne le sont pas dans la version C++.
Page d'accueil: https://www.scriptol.fr/
Le nouveau langage de programmation Scriptol peut être utilisé avec un interpréteur et des compilateurs.
Une version Windows et Unix existe pour chaque compilateur.
L'objectif du langage est d'être simple, naturel et donc de réduire le risque d'erreurs. Scriptol signifie: "Scriptwriter Oriented Language" ou "langage de scénariste" en français. C'est un langage universel conçu pour produire des pages web dynamiques, des scripts et des applications
avec interface graphique. Ce peut être aussi un langage de script pour les applications traitant ou produisant des documents XML. Scriptol peut être imbriqué dans une page HTML et est converti en la même page avec du code PHP, prêt pour le Net et totalement portable. Le langage a été défini selon sept règles décrites sur le site.
Veuillez noter que les symboles [] inclus dans la syntaxe des instructions ne font pas partie de la syntaxe du langage et indiquent un élément optionel, sauf pour les indices et intervalles qui utilisent précisément ces caractères.
Vous devez installer Node.js pour faire fonctionner le programme en ligne de commande. Cela s'installe automatiquement après téléchargement sous Windows. Sous Linux il faut taper cette commande:
sudo apt-get install nodejs
Ou équivalent, selon la distribution.
Pour compiler le programme en JavaScript, la commande est:
solj [options] nomfichier
Si
le source est déja compilé, le programme JS est
interprété, sinon il est compilé avant d'être
interprété s'il n'y a pas d'erreur.
Tant que le
source a des erreurs une nouvelle commande "solp nomfichier"
va le compiler. Si le source est une page HTML, il n'est pas exécuté
après compilation.
Options du compilateur:
aucune: compile un script en PHP/JavaScript ou le lance si déja compilé. -w compile du code inclus dans une page et crée un fichier HTML. -j génère un fichier JavaScript à inclure dans une page HTML. -r force l'exécution. Compile si besoin seulement. -c recompile le fichier et fichiers inclus. Le programme n'est pas lancé. -v affiche plus d'informations lors de la compilation. -q pas de message de compilation.
Ces lettres peuvent être combinées en une seule option. Ainsi -be est équivalent à -b -e.
Fonctionne aussi dans les versions récentes de Powershell sur Windows.
Le fichier solj.ini peut indiquer le chemin du fichier scriptol.js et l'extension du fichier HTML généré. Par exemple:
lib="c:/scriptolj/scriptol.js htmlext=".php"
Un source Scriptol est juste un fichier de texte contenant
des commandes inside, une par ligne.
Exemples:
print x * 2 print x + (y / 2)
Avec un éditeur de texte, comme Advanced Editor, taper cette ligne:
print "Bonjour le monde"
Sauver dans le fichier bonjour.sol.
Si vous travaillez dans une fenêtre de ligne de commande (MS-DOS sous Windows, console sous Unix), tapez simplement:
solj bonjour ...ou solp bonjour
Vous pouvez aussi construire un exécutable avec la commande:
solc -bre bonjour
et lancez le programme bonjour.exe généré.
Il est possible de travailler à la fois avec l'éditeur et une fenêtre de console.
Aucun fichier projet n'est nécessaire.
En Java ou PHP, un programme est un source qui inclut d'autres sources. Scriptol conserve cette structure.
Un source scriptol doit avoir une instruction "include" pour chaque fichier dont le contenu est utilisé. Le compilateur calcule les dépendances sur plusieurs niveaux d'inclusions, et parmi les inclusions mutuelles.
Un fichier Scriptol doit avoir l'extension "sol", et sera converti en un fichier d'extension php, ou cpp et hpp, ou un exécutable.
Cela la forme du source, on aura un script ou une application.
Script
Le source d'un script est une séquence d'instructions et de définitions de fonctions ou de classes. Il peut inclure d'autre fichiers contenant des déclarations de fonctions, de variables, de classes.
Application
Un fichier d'application contient seulement des déclarations de fonctions, variables et classes. Le source principal est celui que l'on passe en ligne de commande du compilateur, il doit contenir une fonction "main", et une commande d'appel de cette fonction (void plus loin),
return 0
main() // lancement du programme.
Scriptol peut être défini comme:
Sensibilité à la casse:
Identifieurs:
Nombres:
Cela depend du langage cible.
Conversion (cast):
Orienté-objet:
Orienté-XML:
Orienté programmation réactive
Pour que le code Scriptol puisse être compilé en PHP dans une page HTML, il doit être inclus dans les balises suivantes:
<?sol ... code scriptol ... ?>
La dernière ligne d'un script Scriptol doit être terminée par un point-virgule ou un saut de ligne, avant le symbole ?>
Tester les pages HTML Si vous avez installé un serveur comme Apache ou Xitami ou Windows Server sur votre ordinateur, et l'avez configuré pour reconnaitre l'extension php, votre code sera traité comme sur le web, une fois compilé en PHP. Autrement, il vous rediriger dans un fichier test.HTML la page dynamique, et ensuite exécuter le code PHP:
solp -w mapage
php mapage.php > test.HTML
Pour compiler to code Scriptol en JavaScript dans une page HTML, placez le dans ces marqueurs:
<scriptol> ... code scriptol ... </scriptol>
Une instruction est terminée par un point virgule ou par la fin de la ligne. Quand une instruction dépasse la largeur d'une ligne, elle est concaténée avec la suivante pourvu qu'elle soit terminée par une virgule, un opérateur ou tout autre symbole qui ne peut terminer une instruction. Aucun symbole n'est requis pour continuer une instruction sur la ligne suivante. Plusieurs instructions sur une même ligne sont séparés par un point virgule. Cela peut être utile si vous placez du code Scriptol dans une page HTML et si l'éditeur concatène les lignes!
Copyright : Le symbole # se place en début de ligne et est suivi d'un commentaire sur la même ligne. Ce type de commentaire reste présent dans le code cible.
Commentaires de code source suivants ne sont pas conservés dans le langage cible :
// le commentaire va du symbole jusqu'à la fin de la ligne.
/* et */ enclosent un commentaire sur plusieurs lignes.
Le langage Scriptol n'utilise jamais le même symbole pour des usages conceptuellement différents.
+ addition - sousctraction * multiplication / division = opérateur d'assignement. < moins que. > supérieur à. <= inférieur ou égal. >= supérieur ou égal. ; est un terminateur d'instruction. , sépare les éléments d'un initialiseur ou d'un tuple. : attache un corps à une en-tête, une valeur à une clé... . associe la référence d'une méthode à un objet. () regroupe des sous-expressions, les paramètres d'une fonction. .. sépare les limites d'un intervalle. -- intervalle avec la limite supérieure non incluse. [] contiennent un index ou un intervalle. ? sépare condition et action dans une structure d'une seule ligne. != opérateur de différence. <> autre opérateur de différence. & et binaire ou intersection de tableaux. | ou binaire ou union de tableaux. << décalage à gauche. >> décalage à droite. and et logique (sur valeurs booléennes). or ou logique. not négation logique. mod modulo (C utilise %). ^ xor. # commentaire de copyright. // commentaire de code source sur une ligne. /* */ commentaire sur plusieurs lignes. ~~ début et fin d'un bloc de code cible à insérer. ` début et fin d'un template, chaîne sur plusieurs lignes. @ suivi par un identifieur externe à insère dans le code.
Les identifieurs sont les noms de variables, fonctions et objets. Ils commencent par une lettre, suivie de lettres, chiffres ou caractères de soulignement. On ne peut les différencier par la casse: on ne peut donner le même nom à deux objets différents, l'un en majuscules, l'autre en minuscules. Les mot-clés sont les mots réservés du langage, ils sont en minuscules.
Les primitives sont des objets de base. Quand elles sont les arguments d'une fonction, la fonction utilise une copie de leur contenu, de leur valeur, et ne modifie par l'original, tandis qu'elle utilise un alias pour les autres objets.
Les primitives de Scriptol sont celles-ci:
var élément générique de array ou valeur de dict. number toute sorte de nombre (jusqu'au double du C++). int un nombre arrondi à la partie entière sur 32 bits. integer identique. natural entier non signed de 64 bits sauf 0. real un nombre avec des décimales. bool la valeur vrai ou faux. text une chaîne de caractères. array une liste dynamique indexée d'objets. dict une liste associative formée de couples clé:valeur. react une variable reactive. file un fichier.
D'autres types speciaux sont utilisés avec les imports de C:
byte type externe de C. cstring utilisé dans les déclarations externes en langage C (traduit par char *).
Les nombres littéraux s'écrivent:
123 entier (int) 123n naturel (natural) 123.0 réel (real) 0.123 réel (real) 1.2e10 réel (real) 0xf8 hexadécimal 0b011 binaire true/false booléen (bool)
Un texte litéral s'écrit: "untexte" ou 'untexte'.
Example:
print "abc$xyz" print 'abc$xyz'
dans les deux cas affiche abc$xyz.
Codes d'échappement
Pour les caractères qui ne peuvent être placés directement dans un texte, on utilise le code spécial: \ Par exemple pour afficher un guillement, on écrira: "abc\"def"
\" insère un guillemet double. \' insère un guillemet simple. \n insère a retour à la ligne. \t insère une tabulation. \\ insère l'anti-slash lui-même.
Supposons que vous voulez assigner la variable a avec exactement ce texte: ma "jolie" voiture. Vous ne pouvez le mettre entre guillements: a = "ma "jolie" voiture" Le compilateur ne saura comment le traiter! Un code special est utilisé pour dire que les guillemet sont dans le texte plutôt qu'ils ne le délimitent, c'est \ a = "ma \"jolie\" voiture" Vous pouvez aussi alterner les types de guillemets: a = "ma 'jolie' voiture" ou a = 'ma "jolie" voiture'
Multi-lignes
Vous pouvez aussi avoir un texte répartis sur plusieurs lignes enclos dans les symboles `comme en ECMAScript 6.
Example:
x = ` ligne 1 ligne 2 `
Le retour à la ligne peut être direct ou introduit par un code d'échappement.
x = "un\ndeux" ...valide x = "un deux" ... non valide x = `un deux` ... valide
Si une chaîne est entre double guillemets, les séquences de caractères commençant pas $ sont des noms de variables.
text xyz = "def" text t = "abc$xyz"
On assign à t la chaîne "abc" suivie du contenu de la variable abc. C'est ce qu'on appelle l'interpolation de chaîne.
Les symboles {} peuvent avoir une signification particulière dans le langage cible et ils doivent être échappé dans une chaîne en double guillement avec le caractère \.
Les textes entre guillemets simples, et précédés de $ ne sont pas interprétés du tout.
text t = 'av$er\n'
affichera: av$er\n
La déclaration d'une variable a la forme:
type nom [ = valeur ]
Exemples:
int x text t = "demo"
Pourvu qu'elles aient toutes le même type, il est possible de déclarer et initialiser plusieurs variables à la fois.
La syntaxe est alors:
type nom [= value], name [= value], etc... int x = 1, y, z = 2
On ne peut mêler plusieurs types dans une seule déclaration. On ne peut faire d'assignements multiples, comme il est décrit plus loin, dans une déclaration.
La forme suivante n'est
pas valide:
int x, y = 0, 0 // non valide
Alors que la suivante est reconnue:
text a = "a"
text b = "b"
text c, d
c, d = [a, b]
Le modifieur const dénote une primitive dont la valeur ne peut changer. Une valeur doit être assignée lors de la déclaration.
Syntaxe et exemples de déclarations de constantes:
const type nom = valeur const int X = 1 const bool B = true const text T = "texte quelconque"
Les constantes sont usuellement en majuscules.
Il y a des constantes prédéfinies qui sont des mot-clés du langage:
true correspond à une expression vraie. false le contraire. zero la valeur 0. nil objet non trouvé dans une séquence (Not In List)ou symbole de suppression. null assigné à un objet quand il n'est pas encore initialisé.
PI est une constante prédéfinie pour représenter le symbole mathématique.
Nil signifie "pas dans la liste" tandis que null signifie "sans valeur", ou "déclaré mais non défini".
Nil n'est pas une vraie valeur mais plutôt une construction du langage. En lecture, il dénote le fait qu'un objet ne soit pas trouvé lors d'une recherche dans une liste. En écriture il a pour effet de supprimer un élément ou un intervalle dans une liste. On ne peut pas initialiser une variable avec nil.
Exemples d'usage:
array a = [1,2,3,4,5] a[1..3] = nil
Maintenant le contenu du tableau est [1,5].
int i = "démo".find("x") if i = nil print "Non trouvé"
Puisque "x" n'est pas dans le texte "démo", le message "Non trouvé" sera affiché.
Voici les valeurs de nil en différents contextes...
Quand du code C++ est généré, nil est remplacé par ces valeurs:
bool false int -1 natural -1 real -1 text "" array [] dict {} file null objet null var selon le type du contenu.
Quand du code PHP est généré, nil est remplacé par false pour un nombre, par "" pour un texte.
Quand du code JavaScript est généré, nil vaut -1 pour un nombre, "" pour un texte.
Le mot-clé null est converti en "null" en PHP, "NULL" en C++ et "undefined" en JavaScript;
Si null est assigné à un identifieur, il ne peut être référencé ou donc utilisé jusqu'à ce qu'on lui assigne une valeur. On peut seulement le comparer dans une condition avec le mot-clé null.
Exemple d'usage:
text a = null
La variable "a" peut être assignée mais reférencée seulement pour être comparée à la valeur null, sinon un message d'erreur s'affiche.
La syntaxe d'un assignement simple est:
identifieur = expression
La valeur assignée doit avoir le type de la variable:
int i = 10 int j = "343" ... incorrect
Cependant, les constructeurs de primitives permettent de faire des conversions.
Lorsque une opération est effectuée sur une variable, et le résultat assigné à la même variable, il est possible de simplifier l'instruction, en assignement augmenté (d'une opération) .
La syntaxe d'un assignement augmenté est:
identifieur opérateur expression
Par exemple, ajouter 10 à x et mettre le résultat dans x. Au lieu d'écrire x = x + 10, on écrira plus simplement: x + 10
Les opérateurs possibles sont: + - * / mod << >>
& | ^ #
Examples:
a = 1 ... donne à a la valeur 1. a + 1 ... ajoute 1 à a. x * y ... remplace le contenu de x par le résultat x * y. a * (x + 2) ... multiplie a par l'expression. a = a * (x + 2) ... comme ci-dessus. a & b ... remplace le tableau a par l'intersection des tableaux a et b.
Noter que dans un test de condition, x + 10 retourne simplement le résultat de l'addition de 10 au contenu de x, sans modifier x. Dans une instruction augmentée, ce résultat est affecté à x.
if x + 1 : ... ici x n'est pas modifié.
Un tuple de valeurs peut être assigné à un groupe de variable. Syntaxe et exemple:
nom [, nom]* = expression [, expression]* x, y, z = 1, x2, 8
Le nombre d'expressions à droite doit correspondre au nombre
d'expressions à gauche.
Sauf dans le cas ou une seule
expression figure à droite, elle sera assignée à
chaque variable du groupe.
Noter qu'une fonction peut retourner
plusieurs valeurs et sera assignée à un groupe de
variables.
Exemples:
x, y, z = 0 a, b = mafonction()
Au contraire de la déclaration multiple, un assignement
multiple peut se faire avec des variables de types
différents.
Exemple:
int x text t x, t = 1000, "abc"
L'assignement multiple peut s'utiliser avec les éléments
d'un tableau. Les tableaux ont une taille dynamique et donc, le
nombre de cible n'a pas besoin de correspondre au nombre d'éléments,
et si le tableau n'a qu'un seul élément, seule la
première variable sera assignée.
Exemple:
x, y, z = [1, 2, 3, 4]
Est équivalent à: x = 1, y = 2, z = 3.
x, y, z = [1]
Est équivalent à: x = 1.
Vous pouvez assigner plusieurs variables à la fois avec:
Dans le cas d'array ou dict, de tuple, de fonction
retournant plusieurs valeurs, on affecte aux variables 1 à n
les éléments 1 à n, dans le même ordre. Si
le nombre ne correspond pas, c'est une erreur.
Si la fonction ne
retourne qu'une seule valeur, la même valeur est assignée
à toutes les variables à gauche.
Echange du contenu de deux variables:
var a = "alpha" var b = "beta" a,b = [b, a] print a, b
Ce qui affichera: beta, alpha.
Les opérateurs de comparaison sont:
= égal < inférieur à > supérieur à <= inférieur ou égal >= supérieur ou égal != différent <> différent
L'opérateur "in" teste la présence d'un élément dans une séquence: texte dans un texte, objet dans un tableau, valeur dans un intervalle.
if "a" in line print "dans le texte" if x in 1..10 print "dans l'intervalle"
Les opérateurs binaires sont:
& (et) | (ou) ^ (ou exclusif) ~ (non) << (décalage à gauche) >> (décalage à droite).
Les opérateurs de tableaux sont:
& (intersection) | (union) ^ (complément d'intersection).
Précédence
Les opérateurs unaires ont la précédence sur les opérateurs binaires. Entre opérateurs de même arité, la précédence est donnée par les parenthèses.
Une expression est une combinaison de valeurs et d'opérateurs.
Expressions arithmétiques
Ce sont des valeurs arithmétiques ou des appels de fonctions combinés avec ces opérateurs:
+ - * / ^ puissance mod modulo, retourne le reste d'une division...
Example:
print 100 mod 3 ... affiche 1 le rester de 100 divisé par 3.
Expressions relationnelles
Les expressions arithmétiques peuvent être comparées grâce aux opérateurs de comparaison vus précédemment.
La comparaison retourne une valeur booléenne: true ou false (vrai ou faux). Cette valeur booléenne peut être assignée à une variable booléenne ou utilisée comme condition d'une structure de contrôle, telle que "if" notamment.
Expressions logiques
Une expression logique est une combinaison de valeurs booléennes
ou d'expressions (relationnelles ou logiques) et d'opérateurs
logiques.
Les opérateurs logiques sont:
and et or ou not non
L'expression "and" retourne vrai si les deux termes sont
vrais, faux sinon.
L'expression "or" retourne vrai si un
des deux termes est vrai, faux si les deux sont faux.
Example:
bool x = true bool y = false if x and y print "vrai"; else print "faux" ... doit afficher faux not(x or y) ... est faux x and not y ... est vrai
Expressions binaires
Les opérateurs binaires sont ceux que la plupart des langages utilisent:
& et binaire | ou binaire ^ ou exclusif ~ négation binaire << rotation à gauche qui équivaud à multiplier par 2 >> rotation à droite qui équivaud à diviser par 2
Expressions textuelles
Les opérateurs de texte sont:
=, <, >, <=, >= comparaison de deux textes. + concaténation de deux textes. [] indexation, slicing ou splicing (voir chapitre Text). in teste si un text fait partie d'un autre.
Exemple:
text t = "préfixe" print t + "suffixe" ...affichera: préfixesuffixe
Expressions de listes dynamiques
Les opérateurs de listes (array, dict) sont:
= < > <= >= <> compare les valeurs de deux listes. + concatène deux listes (des doubles peuvent en résulter). - enlève d'une liste les éléments d'une autre (sauf doubles). [] indexation, slicing or splicing (voir Array et Dict). in teste si un élément est dans la liste. & intersection. | union. ^ complément d'intersection.
L'intersection de deux listes retourne les éléments communs aux deux. L'union de deux listes retourne l'ensemble de leurs éléments. Les éléments appartenant aux deux ne sont gardés qu'une fois. Si une des listes a déja un élément en double, seule la première occurence est conservée.
Quelques langages de programmation on institué des règles de précédence, ainsi, quand les parenthèses sont omises, on sait quel terme est concerné par chaque opérateur. Bien que le précédence ait été construite dans le parseur Scriptol, des erreurs de messages seront envoyés si les parenthèses sont omises, car elles sont nécessaires à la lisibilité.
Le seul cas ou la précédence
est admise sans parenthèse est pour les opérateurs unaires: not, ~ Un opérateur unaire s'applique toujours au terme qui le suit, donc pour l'appliquer à une expression il faut la mettre entre parenthèses. Exemple:
if not a and b if not (a and b)
L'opérateur not est associé à l'objet "a" dans le premier, dans le second on a la négation de l'expression.
Dans les assignements composé (voir plus loin) le premier opérateur concerne la variable à assigner avec l'expression à sa droite.
Une fonction est définie avec une interface qui indique comment l'appeler, un ensemble d'instrucitons, et se termine avec le mot-clé "return".
Le type de retour est requis et
le type des arguments aussi. On utilise "void" si la fonction ne retourne rien.
Syntaxe:
type [,type]* nom ( argument [, argument]* ) [:] ... instructions ... return [expression [, expression]*]
Example:
int multiply(int x, int y) int z z = x * y return z
Cela peut être écrit plus simplement:
int multiply(int x, int y) return x * y
Le corps de la fonction est une liste d'instructions, incluant des instructions "return" si besoin.
La fin de définition est un return avec zéro, une, ou plusieurs valeurs.
return return x return x, y, 5
Si la fonction retourne plusieurs valeurs, elle doit avoir plusieurs types de retour et l'instruction de retour à plusieurs paramètres (dans le même ordre que les types de retour).
Exemple:
text, int, int coordonnees(int num) int x = matable[num].x int y = matable[num].y return "coordonnées=", x, y
Appel de fonction
L'appel d'une fonction peut assigner zéro, une, ou plusieurs variables.
mafonc() a = mafonc() a,b,c = mafonc()
Quand une fonction a des objects comme paramètres, les noms des paramètres sont des alias des objects, et toute modification dans la fonction sont effectués en fait sur les objets originaux. Par défaut, les primitives sont des copies et les objets des alias. On peut le changer avec un modifieur: "alias": le nom de la primitive devient un alias de l'original.
void mafonc(number x) x + 1 print x return void foncalias(alias number x) x + 1 print x return number y = 5 mafonc(y) print y ... doit afficher 6 puis 5 foncalias(y) print y ... doit afficher 6 puis 6.
Assigner une valeur par défaut permet d'ommettre un argument à l'appel d'une fonction. La syntaxe complète de l'interface est:
type [,type]* nom(type nom [= expression] [, type nom [= expression]]* )
Exemple:
int increment(int x, int y = 1) x + y return x print increment(10, 5) ...affichera: 15 print increment(10) ...affichera: 11
La valeur par défaut 1 a été utilisée pour remplacer le paramètre manquant.
Si l'interface d'une fonction a plusieurs paramètres avec une valeur par défaut, vous ne pouvez en omettre un lors de l'appel sans omettre tous les suivants. Les paramètres ne peuvent être reconnus par leur type.
Si ce que vous voulez, c'est écrire une fonction ayant un nombre et des types de paramètres variables, vous devez plutôt utiliser un tableau ou dictionnaire.
Example:
void param(dict parlist) taille = parlist["taille"] nom = parlist["nom"] valeur = parlist["valeur"] return
Dans cet exemple, les variables "taille", "nom", "valeur" sont globales, et elle sont assignée par le contenu du dict en argument.
Le scope est un niveau de l'espace de visibilité des objets déclarés. Une fonction ouvre un nouveau scope pour toutes les variables déclarées à l'intérieur.
Si la fonction est dans le scope global, toutes les variables globales compilées avant la fonction sont visibles dans la fonction.
On ne peut redéclarer dans la fonction une variable avec le même nom qu'une variable globale.
Si la fonction est une méthode d'une classe, toutes les variables déclarées dans la classe avant la fonction sont visibles dans la fonction.
Les objets déclarés dans la fonction sont visibles dans les structures de contrôle à
l'intérieur de la fonction.
Il est utile de pouvoir passer des arguments à un programme à partir de la ligne de commande.
Un script Scriptol (comme PHP) utilise la variable PHP $argv". Pour imiter la façon dont C++ passe des arguments à un programme, créer une fonction "main" et appelez-la avec $argv en argument (et $argc si besoin):
int main(int argnum, array arglist) print argnum, "arguments" for arg in arglist print arg /for return 0 main($argv, $argc) // $argv and $argc sont des variables système. Elles sont assignés automatiquement.
Le type de retour int est obligatoire si le source est compilé en binaire.
Quand le programme est compilé en C++, l'appel à main est inutile.
Echo
Affiche une expression, ou une liste d'expressions séparées par des virgules, sans espaces entre elles et sans retour à la ligne à la fin (comme le fait print).
Syntaxe: echo expression [, expression]
Exemple:
x = 5 y = 20 z = 1 echo "values", x, y / 2 echo z
Ce sera affiché à l'écran comme ceci:
values5101
Exemple:
echo "demo", 5 echo "next"
affiche: demo5next
Un affichage plus élaboré est obtenu avec l'instruction print. Les expressions sont séparées et on va à la ligne en fin d'instruction.
Syntaxe: print expression [, expression]
Exemple:
print "demo", 5
affiche: demo 5
Une instruction print simple, sans expression, envoie un retour à la ligne.
Exemple:
Pour entrer du texte à partir du clavier, utiliser la commande input.
Un texte peut être affiché avant la saisie du texte.
Exemple:
text name input name print name
Example:
input "who are you? ", name
La variable a assigner doit être déclarée avant la commande input, ce peut être un text ou un nombre de type quelconque.
Les structures de contrôle sont:
if if else /if. if une instruction. if composite. for for /for. for une instruction. while while let. while une instruction. while forever do while do until. do /do while. do case. switch case enum enum simple. enum dictionnaire.
Pour JavaScript seulement:
to for /to to while /to to une instruction
break et continue sont utilisables dans les boucles.
Une structure de contrôle d'une seule instruction a la forme:
mot-clé-de-structure expression let instruction ou mot-clé-de-structure expression ? instruction ou mot-clé-de-structure expression instruction commençant par un mot-clé.
Il n'y a pas d'autre marqueur de fin que la fin de ligne. L'instruction est basique et ne peut être un autre construct.
L'instruction "let" est toujours la dernière partie d'une structure de contrôle et peut être la seule. Le symbole "?" est simplement une abbréviation de "let". Let est requis si l'instruction est un assignement ou un appel de fonction, mais optionel si un mot-clé le suit. Si "else" ou "let" complète la structure
de contrôle sur la même ligne, l'instruction doit être terminée par un point-virgule.
Une structure de contrôle multi-lignes a la forme:
nom-structure expression [:] ... instructions ... /nom-structure
Le symbole deux-points est optionnel (sauf si une instruction est mise sur la même ligne).
Une structure de contrôle conditionnelle d'une ligne à la forme:
if condition ? instruction : instruction
Cela se lit ainsi: condition vraie ? action : sinon action
Examples:
if a = 5 ? break if a = 1 ? print "un" : print "plusieurs"
Multi-lignes
Syntaxe:
if condition-booléenne [:] ... instruction ... else ...optionnel ... instructions ... /if
N.B.: Le symbole deux-points est optionnel après la condition, comme le point-virgule après une instruction, mais il est requis quand on concatène les lignes.
Exemple:
if (x + y) > 8 print "> 8" print x else print "<= 8" /if if (x + y) > 8 : print "> 8" ; print x ; else print "<= 8"; /if
La syntaxe est:
if expression non-booléenne [:] operateur expression : instructions operateur expression : instructions ... else ... instructions ... /if
Une expression non-booléenne est une variable, un littéral, ou toute expression qui ne retourne pas la valeur booléenne vrai ou faux.
On ne place pas le mot-clé "break"
à la fin d'un groupe case comme en C. Un break produirait une sortie de la structure de contrôle qui contient le construct if.
Les opérateurs valides sont: =, <, >, <=, >=,
!=, <>, in, else.
Le "else" ici est équivalent au "default" du switch case.
Exemple:
if a = 1: print 1 = 2: print 2 > 2: print ">2" else print "<1" /if if x in [1,2,3]: print "premier" in [4,5,6]: print "second" in [7,8] : print "troisième" else print "autre" /if
Cettre structure de contrôle parcourt soit un intervalle d'entiers, soit une tableau et assigne tour à tour chaque élément à une variable.
Syntaxe de for sur un intervalle:
for variable in début..fin [step s] [:] ... instructions ... /for
Début, fin, et le pas (step) sont des identifieurs ou des littéraux.
Le pas est optionnel, la valeur par défaut est 1.
La limite fin est incluse dans l'intervalle, si le symbole
d'intervalle est ".." et pas si le symbole est "-".
La fin peut avoir une valeur inférieure au début, si "step" est présent et contient un pas négatif.
La variable conteneur peut être déclarée dans l'en-tête. Dans ce cas elle est locale à la structure de contrôle.
Syntaxe de for sur une liste:
for variable in expression-tableau [:] ... instructions ... /for
Dans ce cas, le contenu de l'expression est parcouru et chaque élément assigné à la variable. Cette expression doit être un tableau ou une combinaison produisant un tableau.
Exemples:
for i in 1..10 print i /for for w in montableau print w /for for w in arr1 + (arr2 & arr3[0..5]) print w /for
La syntaxe courte, d'une instruction est:
for variable in liste let instruction-basique
Exemples:
for w in maliste let print w for x in 10..1 step -1 let print w + 10
La boucle for scanne un tableau associatif valeur par valeur. C'est équivalent au for .. of de JavaScript alors que for .. in en JavaScript scanne les clés.
for var v in d let print v // affiche les valeurs
Mais vous pouvez obtenir la clé et la valeur:
for text k, var v in d let print k, ":", v // affiche clés et valeurs
Cela fonctionne aussi sur un tableau simple:
array a = (10,20,30) for int indice, int val in a print indice, ")", val /for
Cela affichera:
1) 10 2) 20 3) 30
La structure de contrôle while est une boucle conditionnelle.
Syntaxe à instruction unique:
while expression let instruction
Syntaxe standard:
while expression [:] ... instructions ... /while
Exemple:
int x = 10 while x < 20 print x x + 1 /while
Une instruction "break" sort de la boucle.
Une instruction "continue" ignore tout ce qui suit et commence une nouvelle boucle.
Cette syntaxe est recommandée pour éviter le risque de boucles infinies.
L'instruction qui fait évoluer la valeur de l'expression testée comme condition de l'itération
est déplacée après le marqueur /while grâce à l'instruction "let".
while condition ...instructions... let incrementation
Exemple:
while x < 10 if (x mod 2) = 0 continue print x let x + 1
L'instruction continue saute sur l'instruction let.
Il n'y a pas d'équivalent en C ou PHP parceque l'instruction continue saute le code qui suit, y compris l'incrémentation de x, d'ou une
boucle infinie.
Exemples sur une instruction:
while x < 10 let x + 1 while x < 10 : print x; let x + 1
Le bloc d'instructions entre les marqueurs do /do est un nouvel espace de visibilité, et les instructions encloses sont excécutée selon une condition éventuelle.
Syntaxe générale:
do ... instructions ... until [ condition ]
Le bloc d'instruction est exécuté tant que la condition est fausse, et laissé quand la condition devient vraie.
Syntaxe de do until:
do print x x + 1 until x = 10
C'est un puissant construct de "pattern-matching". Il contient un ou plusieurs groupes case suivis par un "default" optionnel, et un "always" optionnel. Un seul groupe case est exécuté, le premier dont la condition est satisfaite. Always est toujours exécuté, default quand aucune condition n'est satisfaite.
Syntaxe de do case:
do case condition : instructions [ case condition : instructions ] [ default instructions ] [ always instructions ] /do [while expression]
Exemples:
do case nom = "pussycat": print "c'est un chat" case nom = "flipper": print "c'est un dauphin" case nom = "mobby dick": print "c'est une baleine" default print "un autre animal" /do int state = ON do case state = ON: counter + 1 case state = OFF: break always state = getState() ` une fonction quelconque /do while forever
L'automate qui lit son état à partir d'une et continue de tourner jusqu'a ce que l'état OFF soit rencontré, produit par la fonction appelée.
Le marqueur de fin do peut être complété d'une condition, while ou forever.
Le bloc d'instruction sera exécuté au moins une fois et tant que la condtion est vraie.
Syntaxe:
do ... instructions ... /do while expression do print x x + 1 /do while x < 3
Options:
Syntax:
swith nom-variable case int/real/text : bloc d'instruction ... séris de cases ... default: bloc d'instruction /switch
Une variable peut être comparée:
Exemple:
real x = 0.8 switch x case 0 : print "0" case 0 .. 1 : print "dans l'intervalle" case 1,0.5, 0.8, 1 : print "dans l'intervalle" defaut: print "pas trouvé" /switch
Ce n'est pas une erreur de comparer une variable d'un type avec une valeur d'un type différent, au contraire d'un assignement. Par exemple un entier et un réel. Le langage cible décidera du résultat de la comparaison.
Commande pour sortir d'une boucle.
Exemple utilisant le mot-clé "forever" (pour toujours) qui crée délibérément une boucle infinie.
int x = 0 while forever print x if x > 100 break /if x + 1 /while
Quand x atteint la valeur 100, l'instruction break fait que le programme saute au-dela de /while, sur l'instuction après la structure while.
Continue
Cette seconde commande permet de sauter toutes les instructions de la position actuelle, jusqu'en fin de structure, donc de démarrer une nouvelle boucle.
int x = -1 while x < 20 x + 1 if (x mod 2) = 0 continue print x /while
Cet exemple affiche seulement les valeurs paires de x, car lorsque l'on rencontre une valeur impaire, la condition x mod 2 est vérifié et une commande continue est exécutée.
Dans cet
exemple, j'ai inséré l'incrémentation de x sur la première ligne. Si cela avait été placé après la commande continue, il en résulterait une boucle sans fin puisque l'incrémentation aurait été passée. La syntaxe while .. let évite ceci.
Enum permet d'assigner séquentiellement des valeurs à des identifieur, et en Scriptol, il permet d'assigner des valeurs non entière: des réels ou des textes.
Par défaut un nombre entier est assigné, à partir de zéro, et incrémenté pour chaque identifieur de la liste.
On utilise un double point pour assigner une valeur donnée à
un identifieur et le signe égal pour redémarrer la une valeur donnée.
Syntaxe:
enum identifieur [ : value | = value ] [ identifieur ...]* /enum enum: Z, UN, DEUX, TROIS /enum
Cela assigne 0 à Z, 1 à UN, et ainsi de suite. C'est équivalent à:
const int Z = 0 const int UN = 1 etc... ou: enum: Z:0, UN:1, DEUX:2 /enum
Exemple plus complexe assignant des valeur hétérogènes et démarrant une séquence:
enum Z : "a0", ... assigne a0 UN : "a1", ... assigne a1 TROIS, ... assigne 0 QUATRE : 3.15, ... assigne 3.15 CINQ = 5, ... assigne 5 et redémarre la séquence SIX ... assigne 6 /enum
Exemple de syntaxe simplifiée en une instruction:
enum ZERO, UN, DEUX, TROIS
La syntaxe d'un indice dans un texte ou un tableau est: [indice]. L'indice doit être une expression simple sans crochets imbriqués. Une expression simple est un nombre littéral, un identifieur, un appel de fonction, ou une expression arithmétique et doit être évaluée comme un nombre entier.
La syntaxe d'un intervalle est:
début..fin
Pour indicer une liste, is est enclos entre crochets:
nom-liste[début..fin]
Début et fin sont des expressions entières. Le dernier élément est inclus dans l'intervalle à moins que l'on utilise l'opérateur: "-"
a[0 -- 100] équivaud à [0..99] a[x -- y] équivaud à a[x..y-1]
Exemples d'intervalles:
0..10 x..y x * 2 / 4 .. y + 10
Vous pouvez utiliser un intervalle pour:
- tester si une valeur est dans un intervalle: if x in 10..100
- scanner un intervalle: for x in 1..100
- extraire une partie de liste: array b = a[x..y]
- changer une partie de liste: a[x..y] = autre-liste
Quand on indice une liste, la limite inférieure ou la limite supérieure de l'intervalle peut être omise.
Il y a trois moyens pour découper une liste: array a = [x0, x1, x2, x3, x4, x5, x6, x7, x8] array b = a[..2] array c = a[3..5] array d = a[6..] On obtient trois tableaux avec ces contenus: b: (x0, x1, x2) c: (x3, x4, x5) d: (x6, x7, x8) On les affiche: b.display() c.display() d.display() On doit voir: array ( [0] => x0 [1] => x1 [2] => x2 ) et ainsi de suite...
Pour remplacer un intervalle par une autre liste, il suffit d'un assignement:
a[3..5] = ["a", "b", "c"]
Le contenu devient:
(x0, x1, x2, "a", "b", "c", x6, x7, x8)
Avec la même syntaxe, on remplace une sous-liste par une liste ou un élément:
a[3..5] = "xyz"
The original liste become:
(x0, x1, x2, "xyz", x6, x7, x8)
Pour supprimer une sous-liste, on la déclare nil, "not in liste" (pas dans la liste):
a[3..5] = nil
On a supprimé la sous-liste 3..5 qui est (x3, x4, x5), on obtient:
(x0, x1, x2,
x6, x7, x8)
On peut tester si une valeur appartient à une sous-liste.
Example:
array a = ["un, "deux", "trois"] if "deux" in a[2..5] print "dedans"
Un texte est un objet basique avec des méthodes et qui contient une chaîne de caractères.
Quand un texte est paramètres d'une fonction, la fonction utilise une copie et non un alias sur le texte original.
Un indice peut être négatif dans un intervalle, pas dans l'indexation.
Syntaxe:
text s crée un texte. s = "str" initialise. s = s[i] prend un caractère. s[i] = s2 remplace un caractère, s2 a un seul caractère. s = s[i..j] prend une sous-chaîne, de i jusqu'à j inclus. s[i..j] = s remplace une sous-chaîne. s[i..j] = "" supprime une sous-chaîne.
Un texte litéral est une chaîne de caractères enclose par des guillemets simples ou doubles.
Le symbole + peut être utilisé avec les textes, et il représente la
concaténation de deux chaînes.
Exemple:
text b = "préfixe" text a = b + "suffixe"
Le contenu de a sera: "préfixesuffixe".
Retour Méthode Fonction text capitalize() met la première lettre en majuscule. int compare(text) compare lexicographiquement deux textes (ignore maj). retourne -1, 0, 1. text dup(int) retourne un texte dupliqué n fois. Ex: "*".dup(10). void fill(text, int) remplit avec le texte en paramètre dupliqué n fois. int find(text s2) retourne la position du texte s2 dans le texte, retourne "nil" si non trouvé. (tester si = nil car <> nil ne va pas en PHP) int identical(text) compare, différencie maj/min. Retourne -1, 0, 1 void insert(int, text) insère in text à la position donnée. bool isNumber() retourne true si le texte contient un nombre. int length() retourne la longueur. text lower() met en minuscules. text ltrim() supprime blancs et codes de contrôle au début. text replace(ft, rt) remplace chaque occurence de ft par rt. void reserve(int) alloue la taille donnée pour utiliser comme buffer. array split(sep) découpe le texte en éléments séparés par sep. void toFile(text) sauve le texte dans un fichier dont le nom est en paramètre. int toInt() convertit en entier natural toNatural() convertit en naturel. real toReal() convertit en réel. text toText() cast une chaîne littérale en text (pour C++). text trim() supprime blancs et codes de contrôle en début et fin. text rtrim() supprime blancs et codes de contrôle en fin. text upper() met en majuscules. text wrap(int size) mots non coupés.
Sont déclarées avec le type: var.
Les variables dynamiques ont les méthodes de tous les autres types de variables mais pas les méthodes de classes déclarées (voir extern). Quand une variable est assigned a un var, un cast est requis pour assigner le contenu à une variable typée.
Méthodes de var :
Une séquence est une liste soit statique (text) ou dynamique (array ou dict).
Listes et séquences ont les mêmes opérateurs, sauf & et | propres aux listes. Les
opérations sur les listes sont:
[] : indice, lecture ou modification de sous-liste. + : fusion de deux séquences. Ou ajoute un élément à une liste. - : supprime une séquence d'une autre, ou un élément d'une liste. = : comparaison de deux séquences. in : teste si un objet est dans une séquence. & : intersection de deux listes (donne les éléments communs). | : union sans doublons de deux listes.
Il y a deux sortes de listes dynamiques en Scriptol:
array: (tableau) indicé par des nombres entiers. dict: (dictionnaire) les clés sont des textes.
Un tableau est une liste dynamique d'objets ou litéraux indexée.
Un tableau vide est représenté par [].
Un tableau litéral est une liste d'expressions séparées par une virgule et enclose entre [].
Une variable peut être
un élément de tableau.
Le constructeur débute par le mot-clé "array".
Pour afficher le contenu du tableau a, on type a.display(), et on obtient quelque chose de la forme:
array( 0 : un 1 : deux 2 : trois )
Le constructeur d'un tableau a la forme: array()
Un tableau litéral s'écrit:
[ ... valeurs ... ] On peut définir un tableau en assignant le constructeur, ou un tableau litéral, ou une valeur unique.
Syntaxe:
array a crée un tableau. array a = [] crée un tableau vide. array a = [x, y, ...] crée et initialise un tableau. array a = [3] crée un tableau d'un élement.
Les éléments d'un array peuvent être toute expression, *** sauf une expression booléenne ***. Si vous placez la valeur vrai dans un tableau PHP retournera vrai chaque fois que vous utilisez l'opérateur "in", avec toute valeur cherchée.
Un tableau peut être déclaré sans assignement de contenu, et rempli par la suite:
array a a.push("un") a.push("deux") a.push("trois")
Les éléments sont retrouvés par leur position dans le tableau.
Exemples:
a[1] = "a" a[2] = "b" for x in a : print x ... doit afficher: a b
Les éléments d'un tableau sont accédés par un numéro entier.
Syntaxe:
a[n] lit l'élément ayant le numéro n. a[n] = x remplace l'élément à la position n. a[n] = nil efface un élément. a = [] efface le tableau entier. a[n].upper() appel d'une méthode sur l'élément n du tableau.
Un index vide désigne l'élément courant:
a[] élément à la position courante.
L'indice peut être toute expression qui s'évalue en un nombre entier. L'expression ne peut contenir un élément de tableau.
a[10 + x / 2] valide. a[10 + b[5]] n'est pas valide.
Puisqu'un tableau peut contenir tout type d'objet, ou même d'autres tableaux, il faudra une variable dynamique pour lire un élément, à moins de connâitre le type de l'élément à lire.
array a = [ x, "two", 3 ] var x = a[1] utilisation de var pour lire l'élément de type inconnu. text t = a[2] int i = a[3]
Quand un élément est ajouté hors de la limite, il est placé en dernière position dans le tableau.
Si vous assignez un élement avec l'instruction suivante, le contenu changera selon le langage cible:
a[1000] = "x" En PHP et JavaScript: array( 0 : un 1 : deux 2 : le dernier 1000: x ) En C++: array( 0 : un 1 : deux 2 : le dernier 3: x )
En PHP, l'indice 1000 est seulement temporaire, et changera dès qu'une instruction change le tableau.
Une instruction de la forme a[n] = x sert à modifier la valeur à l'indice donné, il ne faut pas assigner un tableau de cette façon qui ne convient qu'aux dictionnaires (dict), comme on verra plus loin.
Le contenu d'un tableau peut être parcouru par un iterateur.
On pointe sur le premier élément avec la méthode begin(), ou sur le dernier avec end(), l'élément courant est obtenu par un index vide de la forme [].
begin() pointe sur le premier élement et retourne sa valeur. end() pointe sur le dernier élement et retourne sa valeur. inc() déplace sur l'élément suivant. Retourne la valeur pointée avant, ou nil au-delà du dernier élément. dec() déplace sur l'élément précédant. Retourne la valeur ou nil. index() retourne l'index de l'élément pointé. value() retourne la valeur de l'élément pointé. [] indice de l'élément courant. nil signifie "not in liste" et est retourné par différentes fonctions quand aucune valeur ne peut être retournée.
Exemple d'utilisation avec le tableau a:
a.begin() ` déplace sur le premier élément while a[] <> nil ` teste si la fin de liste est atteinte print a[] ` affiche l'élément actuellement pointé a.inc() ` déplace sur l'élément suivant /while
En ordre descendant:
a.end() while a[] <> nil print a[] a.dec() /while
Une fois le tableau créé, vous pouvez appliquer différentes fonctions de liste, ou de pile...
a.push("item") ...ajoute un élément à la fin de la liste a.unshift("item") ...ajoute un élément au début de la liste a.pop() ...lit et enlève le dernier élement a.shift() ...lit et enlève le premier élement
Vous pouvez ainsi lire et éliminer les éléments
d'un tableau par des instructions successives telles que:
print
a.shift()
Un intervalle est délimité par un intervalle de positions.
a[pos..fin] la rangée entre "pos" et "fin" inclus. a[..fin] du début jusqu'à la position "fin". a[pos..] de la position "pos" à la fin du tableau. a[..] prend le tableau entier (peu utile). a[pos..fin] = nil supprime une rangée d'éléments. a[pos..fin] = b remplace une rangée par un tableau/élément (id).
Un élément, ou un groupe d'éléments, peut être ajouté ou supprimé avec les opérateurs + et -.
Exemple:
array a = ["un", "deux"] array b b = a + ["trois", "quatre"] maintenant le contenu de b est de quatre éléments. a = b - ["un", "quatre"] maintenant le contenu de a est: ("deux", "trois").
Seuls les opérateurs arithmétiques + et - sont utilisables sur les tableaux, avec l'opérateur d'appartenance "in".
Cet opérateur peut être utilisé pour tester si une valeur est contenue dans une liste (array, dict ou même un text), et pour parcourir le contenu également.
Syntaxe et exemples:
if variable in array for variable in array if x in a : print "dedans"; /if if x in [1,2,3] : print "dedans"; /if for x in a print x for t in ["un", "deux", "trois"] print t
Opérateurs binaires de listes dynamiques
Vous pouvez utilisez sur des listes dynamiques (array ou dict) les opérateurs binaires d'intersection et union. L'intersection de deux listes retourne seulement les éléments qui font partie à la fois des deux listes. L'union de deux listes est une nouvelle liste composée des éléments de la première, plus ceux de la seconde moins ceux qui font déja partie de la première.
& intersection | union ^ complément d'intersection a = [1, 2, 3, 4] & [3, 4, 5, 6] fait que a contient (3, 4).. a = [1, 2, 3, 4] | [3, 4, 5, 6] fait que a contient (1, 2, 3, 4, 5, 6).
La méthode map, qui est implémentée en JavaScript et PHP permet d'appliquer successivement une fonction à chaque élément d'un tableau et éventuellement retourner un nouveau tableau. Exemple:
int mapfun(int x) return x * 25
b = [1,2,3,4,5]
print b.map(mapfun)
Si l'on veut appliquer une fonction à plusieurs tableaux à la fois, ou à des dict, on utilise l'indice. Exemple:
for text k, var v in d1 d1[k] + d2[k] /for
On ajoute, élément par élément, le contenu du tableau associatif d2 à d1.
En utilisant une fonction, à deux paramètres:
array d1 = [1,2,3,4,5]
array d2 = [10, 20, 30, 40, 50]
int mapfun(int x, int y) return x + y
for int i, var x in b print mapfun(d1[i], d2[i])
Le nombre de dimensions n'est pas limité. Pour un tableau à deux dimensions, la syntax pour...
- accéder à un élément est: x = nomarray[i][j]
- changer un élément est: nomarray[i][j] = x
Pour créer un élément, la syntaxe est:
nomarray[i] = [] nomarray[i][j] = x ou nomarray[i] = [x]
On ne peut créer directement un élément dans un sous-tableau inexistant. L'index i et j supposent qu'il existe déja i et j éléments.
Le langage peut faire des comparaisons entre des tableaux de nombres avec tous les opérateurs relationnels. Deux tableaux de tailles différentes sont considérés différents.
Entre deux tableaux de texte ou autres objets, il peut tester s'ils sont identiques ou s'ils sont différents. Pour d'autres comparaisons, on doit définir son propre algorithme.
Nous devons savoir comment les clés entières d'un tableau en PHP changent selon les opérations que l'on peut accomplir. C'est important pour comprendre les tableaux associatifs et éviter pas mal de bogues.
Après chaque opération le contenu est affiché.
array a = [] array () a.push("un") array ( [0]=> un ) a + [ "deux", "trois", "quatre" ] array ( [0]=> un [1]=> deux [2]=> trois [3]=> quatre ) a.shift() ... le premier élément est supprimé et les clés sont renumérotées. array ( [0]=> deux [1]=> trois [2]=> quatre ) a[1000] = "mille" array ( [0]=> deux [1]=> trois [2]=> quatre [1000]=> mille ) a.unshift("x") ... toutes les clés sont renumérotées, même la clé 1000. array ( [0]=> x [1]=> deux [2]=> trois [3]=> quatre [4]=> mille ) Créons deux nouveaux tableaux: array a = [ "un","deux" ] array b = [] b[1000] = "mille" a + b Les clés sont renumérotées. array ( [0]=> un [1]=> deux [2]=> mille )
Si on remplace a + b par a.push("mille") le résultat sera le même.
Les itérateurs ne sont pas encore implémentés par le compilateur JavaScript, aussi les méthodes begin, dec etc. ne sont pas reconnues.
Retour Nom Action var begin() pointe sur le premier élément. var dec() retourne un élément et décrémente le pointeur. void display() affiche le tableau. var end() pointe sur le dernier élément. bool empty() return true si le tableau est vide. int find(var) recherche un élément, retourne l'index ou nil. int findLast(var) recherche un élément à partir de la fin. var inc() retourne un élément et incrémente le pointeur. int index() retourne l'index de l'élément pointé. void insert(int, var) insère un élément à un index entier (pas un text). text join(text sep) convertit en text avec le séparateur donné. text key() retourne la clé de l'élément pointé. bool load(text nom) charge un fichier dans un tableau ("file" de PHP). var min() retourne la valeur la plus faible. var max() retourne la plus forte valeur.
array map(fonction) applique une fonction à chaque élément et retourne un nouveau tableau. void pack() rend les éléments du tableau consécutifs. var pop() lit et supprime le dernier élément. var pop(int) lit et supprime l'élément à la position donnée. void push(val) ajoute un élément à la fin. var rand() retourne un élément à une position aléatoire. array reverse() retourne la liste en ordre inversé. var shift() lit et supprime le premier élément. int size() retourne le nombre d'éléments. void sort(int) trie les valeurs en ordre ascendant. void rsort(int) trie les valeurs en ordre descendant. void store(text nom) sauve le tableau dans un fichier. Ajouter false en argument pour ne pas ajouter de code eol. number sum() calcule la somme des éléments. text toText([text]) convertit le tableau en chaîne avec code de séparation en option. array unique() retourne le tableau sans valeur en double, la première est gardée. void unshift(var) insère un élément en première position.
La méthode sort de tableau a un paramètre optionnel: 0 pour un classement alphanumérique (par défaut en JavaScript et PHP), 1 pour un classement numérique.
Un dict est une liste dymamique de couples clé et valeur. Les clés sont toujours des textes. Les valeurs peuvent être tout objet.
La clé et la valeur peuvent être des
variables. Le format pour un couple clé et valeur est:
clé:valeur
Un dict vide est représenté par {}. Un dict litéral est une liste de couples separés par une virgule, et enclos entre {}.
Au contraire du tableau, le dict est créé par des assignements:
d[k] = "b" d["un"] = "element 1"
Même si JavaScript supporte les clés numériques placées entre guillemets, donc considérées comme des textes, cela produit des résultats imprévisibles quand on les mêle à des clés alphabétiques. Il faut donc éviter des mêler les types.
Un dict peut être créé à partir d'un litéral ou un constructeur.
Syntaxe:
dict d // crée un dict. dict d = {x:v, y:w,...} // crée et initialise un dict. dict d = {} // crée un dict vide.
Les valeurs peuvent être tout type d'objet.
La clé
peut être une variable et la valeur une expression.
Exemple:
text k = "a" text v = "b" dict d = {k : v} dict d = {k : v + "x".dup(4) + 20.toText()}
Cet exemple enregistre "bxxxx20" dans le dict d, avec la clé "a".
Les valeurs dans un dict sont accédées par une clé textuelle.
Syntaxe:
d["clé"] prend le premier élément avec la clé "clé". d[clé] = valeur remplace une valeur ou ajoute un couple clé-valeur si la clé n'est pas déja dans le dict. d[clé] = nil supprime un élément. d = {} efface le dict. Exemple: dict d d["program"] = "ce que l'on veut accélerer" print d["program"] affiche le texte ci-dessus.
La façon normale d'utiliser un dictionnaire est par le moyen des clés ou itérateurs. En quelques occasions il peut être utile d'accéder à un intervalle de valeurs directement.
- Quand on ajoute un élément ou un autre dict à un dict, au moyen d'intervalle, de push, unshift, PHP génère une nouvelle clé pour cet élément. La nouvelle clé est un nombre.
- Si vous remplacez un intervalle par un autre dict, certains éléments peuvent être perdus. Cela se passe aussi lors de la fusion.
- Les clés du dict qui replace un intervalle ne sont pas conservées.
Exemples d'affichage:
Il doivent présenter toutes les clés et valeurs dans le dict.
dict d = {"a":"alia", "b":"beatrix", "c":"claudia"} d.display() for k,v in d : print k, v; /for
Retour Nom Action void display([flat]) affiche le dict indenté. Si l'argument est false, il n'est pas indenté. bool empty() retourne true si le tableau est vide. int hasKey(text) retourne true si la clé existe. int find(var) recherche un élément, retourne l'index ou nil. dict getById(text) retourne un dictionnaire assigné à la propriété en paramètre. array getByName(text) retourne la liste des éléments dont l'attribut name a l'argument pour valeur. array getByTag(text) retourne la liste des objets donc l'attribut tag à l'argument pour valeur. array keys() retourne la liste des clés. void kSort() réordonne les index en préservant les associations. void load(text nom, [xml]) charge un fichier dans le dict. var pop() lit et supprime le dernier élément. var shift() lit et supprime le premier élément. int size() retourne le nombre d'éléments. void sort(int, bool) trie les valeurs en ordre ascendant. void store(text nom) sauve le dict dans un fichier. text toXML() convertit le dict en fichier XML dans une chaîne. void unshift(text,var) insère une paire clé valeur première position. array values() retourne la liste des valeurs.
Méthode load: Le fichier est converti de XML en dict s'il a l'extension xml, rss, svg ou si l'argument optionnel vaut 1.
Un tableau typé contient un type d'objets unique. Il est beaucoup plus efficient que le tableau commun parcequ'il est indexé, et non associatif, et contient directement des objets de 32 ou 64
bits ou des pointeurs, plutôt que des objets dynamiques (var).
Un tableau d'entiers est 100 fois plus rapide qu'un tableau standard pour les exécutables binaires, mais il n'y a pas de différence en PHP.
Les tableaux typés sont aussi dynamiques, la taille n'est ni prédéfinie, ni limitée.
Le constucteur d'un tableau typé a la forme:
type(...éléments...) Exemple: int(1, 2, 3)
Le nombre d'élément va de 0 à n.
Quand il y a un seul élément, il n'y a pas de différence entre une constructeur de tableau typé et un constructeur scalaire:
int(1) real(10r)
Ce n'est pas un problème lors de l'assignement, puisque l'on peut créer un tableau à un seul élément à partir d'un scalaire,.
La syntaxe pour déclarer un tableau d'entiers est:
int[] i = int(x, y, ....)
Une fois qu'il est déclaré, il est utilisé comme un tableau mixte, mais seuls les nombres entiers peuvent être ajoutés au tableau.
Lors de la création on peut assigner un constructeur ou un litéral.
Un constructeur à un seul élément équivaud à un constructeur d'entier. Dans une expression il faudra utiliser un litéral.
Exemples:
int[] x = int(5) int[] x = int(1,2) int[] x = y + int{5}
Les déclarations sont:
real[] r = real(1.0, 2.0, etc...) natural[] n = natural(1, 2, etc...) number[] n = number(1, 2.0, ...)
La déclaration à la forme:
text[] t = text("un", "deux", etc...)
Vous pouvez ne assigner un tableau typé à un tableau mixte sauf en utilisant la fonction arrayval:
Exemple:
int[] i = int(...) array a = arrayval(i)
Mais vous ne pouvez créer un tableau mixte avec un constructeur typé:
Exemples:
[1,2,3] ... c'est un tableau mixte, avec des éléments entiers int[] i = [1,2,3] ... NON VALIDE, il faut plutôt écrire: int[] i = int(1,2,3) ... valide.
Exemples:
array a = int(1,2) ... NON valide array a = [ int(1,2) ] ... NON valide
On peut assigner un tableau typé à un var.
int[] i = int(1,2) var d = var(i)
Deux méthodes sont fournies pour utiliser ce var:
arrayType() retourne le type de tableau contenu dans le var.
toList(int = 0) retourne le tableau typé contenu.
Le paramètre est
le type, et est requis quand le var se contient tableau mixte, que l'on veut convertir en tableau typé.
Types reconnus:
$TYPE_INT tableau d'entiers $TYPE_REAL $TYPE_NATURAL $TYPE_NUMBER
Exemple:
d = var(int(1,2)) if d.arrayType() = $TYPE_INT: int[] i = d.toList() = $TYPE_REAL: real[] r = d.toList() /if
Pour la compatibilité avec PHP, ajouter un élément à un tableau au-dela de la taille actuelle, a le même effet qu'ajouter cet élément, quelque soit l'index donné.
Par exemple:
int[] i = nil i[10] = 10 équivaut à: i.push(10)
Empiler des valeurs est le moyen correct pour remplier un tableau.
Si on veut réellement placer un élément à une position donnée, on doit remplier le tableau avec des valeurs nulles...
for int k in 0 .. 10 let i.push(0)
Vous pouvez maintenant placer un élément en position10.
- On ne peut appliquer une méthode directement à un élément indicé.
i[10].toText() .. non valide int x = i[10] x.toText() .. valide
- La fonction "array_diff" de PHP ne fonctionne pas quand le tableau contient des objets, on ne peut donc soustraire de tels tableaux.
File est un objet virtuel, pour traiter des fichiers locaux ou distant.
Pour une explication complète du système de fichier, voir "fopen" dans le manuel C ou PHP.
Un objet file est créé par la déclaration d'une instance de type file. Le fichier sur le disque est créé par la commande open. Elle permet d'accéder à un fichier en différents modes, selon le second paramètre de la méthode.
La structure de contrôle error permet de tester si le fichier a été ouvert correctement ou non.
Syntaxe pour créer ou ouvrir un fichier:
file nomfic declare un file. nomfic.open(path, mode) ouvre un fichier selon un chemin et un mode. Types de chemins: http://path fichier distant http. ftp://path fichier distant ftp. path fichier local. Modes: "r" lecture seulement, à partir du début. "w" écriture seulement à partir du début. "r+" lecture ou écriture au début du fichier. "a" ajout en fin de fichier en écriture seule. "a+" lecture à la position courante, ou écriture à la fin.
Les méthodes de fichier sont:
retour méthode action int eof() retourne true quand la fin de fichier est atteinte. int open(text, text) crée ou ouvre un fichier. Positionne le drapeau "error". int close() ferme le fichier. text read(int) lit un bloc selon la taille en argument, retourne un text. text readLine() lit et retourne la ligne suivante dans un fichier de texte. int seek(int) va à la position donnée en argument, retourne 1 si ok. int size() retourne la taille du fichier. int time() retourne la date de dernière modification. int write(text) écrit le texte donné en argument, retourne la taille écrite. void writeLine(text) écrit le texte en argument.
Exemples:
file nomfic crée un objet file. nomfic.open("monfichier", "r") ouvre un fichier physique. nomfic.close() ferme le file. bool b = nomfic.eof() assigne vrai à b si la fin de fichier est atteint. nomfic.seek(250) lecture ou écriture en sautant 250 octets.
Les fichiers distants ne sont pas gérés par Scriptol C++ et l'interpréteur pour l'instant.
Un fichier peut être lu ligne par ligne, ou par blocks binaires.
Dans le premier cas, la méthode readLine() est utilisée, sinon, on utilise la méthode read avec la taille du bloc en argument.
Le code de fin de ligne dans le fichier est inclus, et peut être supprimé par la méthode rTrim().
Exemples:
text t = nomfic.readLine() lecture d'une ligne de texte. text t = nomfic.read(1000) lecture de 1000 octets.
La méthode write place le contenu d'une variable de texte dans un fichier. Une fois le fichier ouvert soit avec le mode "w" ou "a", et donc enregistré soit à partir de zéro ou à la fin de son contenu actuel, chaque nouvel appel à write ajoute un nouveau texte à la fin.
Exemple simple:
text nomfic = "monfic" // nom du fichier file sortie // nom de l'objet virtuel sortie.open(nomfic, "w") // ouvert en écriture error? die("impossible d'ouvrir " + nomfic) for text ligne in maliste // un tableau quelconque sortie.write(ligne) // enregistrer un élément /for sortie.close() // fermer le fichier
Du code XML standard peut être inséré dans un programme scriptol. Il sera convertit en tableau associatif. Une balise contenue dans une autre balise est convertir en dict comme élément d'un autre dict.
Le contenu textuel d'une balise est associé à la clé data dans le tableau associatif généré.
Exemple:
<xml id="car" speed=150 name="Spitfire">
<engine id="engine1" power=100 />
<passengers id="pass1" num=4 >
"Clara, Dana, Elisa, Farah"
</passengers>
</xml>
Ce code JavaScript est généré par le compilateur:
var car={ "_00" : "car", "tag" : "xml", "speed":150, "name":"Spitfire", "engine1":{ "tag": "engine", "power":100 }, "pass1":{ "tag": "passengers", "num":4, "data":"Clara, Dana, Elisa, Farah" } };
Ou ce code PHP:
$car=[ "speed"=>150, "name"=>"Spitfire",
"engine"=>[ "power"=>100 ],
"passengers"=>[ "num"=>4,
"data"=>"Clara, Dana, Elisa, Farah" ] ];
Le tableau associatif peut aussi être transformé en document XML dans une variable de type text, que l'on peut sauver dans un fichier:
car.toXML().store("fichier.xml")
Après une instruction open, le construct error ... /error devrait être exécuté en cas d'erreur d'accès. Mais l'interpréteur peut stopper le programme avant d'atteindre le construct. Sinon le contenu du bloc sera exécuté en cas d'erreur.
La syntaxe est:
xxx.open("nom fichier") error ...instructions... /error ou: xxx.open("nom fichier"); error ? action ou: xxx.open("nom fichier"); error action
Exemple:
file monfic monfic.open("nom", "r") error? exit()
Si le fichier n'est pas trouvé ou ne peut être ouvert, le programme s'arrête.
Les règles de visibilités sont celles des principaux langages procéduraux, non celles des langages de scripts.
Scriptol ajoute des règles de sureté, il ne permet pas de donner le même nom à deux objets dans les scopes imbriqués (par exemple, dans le scope global et celui d'une fonction). Mais les mêmes noms peuvent se réutiliser dans des scopes successifs.
Il y a quatre niveaux de visibilité: - global, - classe, - corps d'une fonction, - et le corps d'une structure de contrôle.
La visibilité d'une variable est le niveau dans lequel elle est déclarée: global, classe, fonction ou bloc délimité (if, do, for, etc.), ainsi que les niveaux contenus.
On ne peut redéclarer une variable là ou elle reste visible. On ne peut la redéclarer que quand son scope est clos, dans des fonctions successives ou des structures de contrôles successives.
L'en-tête du construct for fait partie du scope du bloc.
for text t in a // t est visible seulement dans la boucle for. t = a.inc() /for
La partie let qui termine une boucle while est dans le scope de la boucle.
Les arguments d'une fonction sont dans le scope de la fonction.
A l'intérieur d'une fonction, si une variable est référencée avant tout assignement, elle reférence une variable globale si elle existe, sinon c'est une erreur.
A l'intérieur d'une méthode d'une classe, si elle est référencée avant tout assignement, elle référence un attribut s'il existe, sinon c'est une erreur.
Les variables globales ne sont pas visibles dans une classe, sauf les variables externes.
Les variables externes (celles de PHP, Apache, etc...) sont toujours dans le scope, puisqu'il n'y a pas de contrôle sur elles. Donc vous devez connaître leur nom pour ne pas le réutiliser, car les variables Scriptol sont transformée en variable PHP avec $ devant.
Si vous utilisez des variables externes dans une fonction, il faut les déclarer "global",
car le compilateur ne les gère pas.
Les variables et constantes de PHP peuvent être utilisées comme celles de Scriptol dès lors qu'elle sont déclarées avec le mot-clé "extern".
Les déclarations externes comme les includes sont placées en tête de fichier.
La syntaxe pour une variable externe est:
extern type identifieur extern const type identifieur
Aucun test de contrôle sur le type ou le scope d'un objet externe. Dans une fonction il faut une déclaration "global".
Exemple:
global argv array a = $argv
Une constante PHP est déclarée comme une variable avec le mot-clé const:
extern const text PHP_VERSION ... print PHP_VERSION
Il est possible aussi d'utiliser une variable PHP ou C++ sans déclaration avec le préfixe $ suivie d'un identifieur.
Celui-ci peut commencer par un caractère de soulignement.
$var_name $(constant_name) in PHP $constant_name. in C++
Les fonctions PHP peuvent être utilisées sans déclaration, ce qui n'est pas le cas des fonctions C++.
On peut aussi les déclarer avec le mot-clé extern. Une valeur par défaut est spécifiée par un assignement. Cette valeur est utilisée en C++, elle est ignorée par PHP.
Syntaxe et exemple:
extern type identifieur(... arguments...) extern text substr(text, int, int = 0)
Pour utiliser les méthodes de classes PHP ou C++, vous devez déclarer ces classes et les membres que vous voulez utiliser.
Exemple:
extern class phpClass int phpAttribute void phpMethod(int argument) ... déclaration ... /class /extern
C++ permet de définir des types avec les directives "typedef" and "#define". Il est possible d'intégrer ces nouveaux types avec l'instruction Scriptol define.
Exemple: define uint
Cela correspond à "#define uint unsigned int" en C++.
Aucun code n'est généré par l'instruction define: le code C++ doit se trouver dans un fichier C++ à inclure. Voir "L'instruction define" pour plus de détails.
Si vous vouler insérer directement du code cible dans votre programme, utilisez les symboles ~~ pour définir le début et la fin du code à inclure.
Le compilateur ignore le contenu, comme s'il s'agissait de commentaires mais l'inclut dans le code généré, PHP, JavaScript ou C++.
Pour un simple identifieur ou mot réservé, on utilise le code @. Exemple:
@await
Vous pouvez insérer du code spécifique PHP ou C++ dans un même programme. Pour insérer du code PHP, utilisez:
require_once("lecode.php")
Cette instruction n'a d'effet que pour l'interpréteur PHP, compilée en C++ elle est ignorée.
Pour insérer du code C++ ou JavaScript, utiliser:
include "lecode.hpp" include "lecode.js"
Une classe est une structure qui contient des variables (attributs) et a des fonctions (méthodes).
Une fois qu'une classe est définie, elle devient un nouveau type complexe du langage avec lequel on déclare des objets, instances de la classe. On utilise les attributs et méthodes de l'objet avec une commande de la forme:
x = objet.attribut objet.methode()
La description d'une classe débute avec le mot-clé "class" et se termine par "/class".
Les attributs (variables) doivent être placés avant les fonctions. Une classe ouvre un espace de visibilité. Les variables globales et les fonctions définies ne sont pas visibles à l'intérieur d'une classe. Les attributs et méthodes de la classe ou d'une instance d'une autre classe sont visibles dans toutes les méthodes de la classe avec le nom de l'instance en préfixe.
Exemple d'une déclaration de classe:
class voiture ...membres... /class
Exemple de classe avec attributes et méthodes:
class voiture int lavitesse = 50 int passagers = 4 void voiture.vitesse(int i) int x = lavitesse * 2 return x /class
Exemple d'instance avec référence aux méthodes:
voiture mavoiture print mavoiture.passagers print mavoiture.vitesse()
Un constructeur est une méthode dont le nom est celui de la classe et qui est appelée lors de la création d'une instance de la classe.
Il a toujours le type de retour "void", qui signifie: rien.
Exemple de constructeur:
class Voiture int vitesse void Voiture(int p) // cette méthode est un constructeur vitesse = 0 //vitesse est initialisée lors de la déclaration d'une instance return /class
La syntaxe pour créer une instance est:
Nomclasse nominstance = Nomclasse(argument [, arguments])
ou:
Nomclasse nominstance pour un constructeur sans arguments
Example:
Voiture mavoiture = Voiture(60) ... crée une voiture avec une vitesse de 60 Camion moncamion ... equivalent à ci-dessous Camion moncamion = Camion()
Il peut être pratique de rassembler toutes les fonctions concernant une tâche dans une classe et les déclarer "static". Ces fonctions peuvent alors être appelées directement avec le nom de la classe, sans avoir à créer d'instance.
Exemple:
node, ext = Dir.splitExt(chemin)
Les attributs peuvent également être statiques. Un attribut statique est commun à toutes les instances et celles qui sont héritées. Une méthode statique ne peut
référencer des attributs, puisqu'ils n'existent que dans les instances de la classe sauf s'ils sont statiques aussi.
On ne peut appeler une autre méthode dans le corps d'une méthode
statique..
Le mot-clé "static" doit précéder le type de l'objet.
Un message d'erreur est émis quand une fonction statique utilise un attribut non statique ou qu'elle appelle une autre méthode.
Exemple d'attributs et méthodes statiques:
class Voiture static usine = "Xxx" static void denomme(text x) usine = x return /class Voiture.denomme("nom") Voiture.usine = "nom"
Attributes et méthodes statiques peuvent être associés à une instance également:
Voiture maVoiture maVoiture.denomme("nom") maVoiture.usine = "nom"
L'effet sera le même.
Une classe peut hériter des attributs et méthodes d'une autre classe, si elle est déclarée sous-classe de celle-ci.
La classe "nom" hérite des attributs et
méthodes de "autrenom". Cela fonctionne aussi avec les attributes et méthodes statiques.
La syntaxe de la déclaration d'héritage est:
class nom is autrenom
Exemple:
class Vehicule int fuel void Vehicule() fuel = 100 return /class class Voiture is Vehicule int passagers void Voiture() passagers = 3 fuel = 50 return /class class Camion is Vehicule int charge void Camion() fuel = 200 charge = 1000 return /class Camion bibendum Voiture daisy print bibendum.charge attribut de la classe Camion print bibendum.fuel attribut de la superclasse Vehicule print bibendum.passagers mauvais! passagers non accessible à Camion! print daisy.passagers bon, passagers est attribut de Voiture
Une méthode peut être redéfinie avec des arguments différents, à la fois dans la même classe et dans les classes dérivées. Le type de retour de toutes les versions de la méthode doit être le même.
Exemple:
void ajoute(int x, int y) void ajoute(real x, natural y)
Vous avez juste à appeler la méthode "ajoute" avec le type d'arguments voulus, le compilateur associe la définition correspondante...
Le langage cible C++ requiert que les méthodes surchargées aient le même type de retour, cela est conservé en Scriptol.
Syntaxe:
async type nomfonction(paramètres) var x = await autrefonction(arguments) ... instructions suivantes... return
Exemple:
int fibo(int n) if (n < 2) return n return fibo(n-2) + fibo(n-1) async void getFibo(int n) int f = await fibo(n) print "fibo=",f return getFibo(20)
Dans la fonction déclarée async, les instructions qui suivent l'appel déclaré await, ne sont exécutées qu'après que cette dernière ait retourné une valeur, même si elle est asynchrone.
Par contre les instructions qui suivent l'appel de la fonction async, sont exécutées immédiatement sans attendre.
Dans le but d'éviter des confusions il est préférable que la fonction async ne retourne pas de valeur, même si cela serait néanmoins correct et accepté par le compilateur.
Le compilateur encapsule l'appel de la fonction qui suit await dans un objet Promise. Si la fonction appelée retourne déjà un objet Promise, alors on utilisera plutôt:
@await
La syntaxe pour inclure un fichier Scriptol externe est:
include "nomfichier.sol"
Les parenthèses sont optionnelles. Les guillemets simples ou doubles sont requis. Si vous voulez utiliser directement un fichier PHP, et que le compilateur ne le traite pas, utilisez l'extension PHP.
Seuls les fichiers avec l'extension ".sol" seront traités par les compilateur, si elle est différente:
Exemples:
include "exemple.php" include "exemple.js
Le fichier PHP sera ignoré par le code JavaScript et le fichier JS sera ignoré par le code PHP.
Quand du code scriptol est inséré dans une page HTML, le contenu d'un fichier à inclure doit être placé à l'intérieur des balises <scriptol> et </scriptol>, même si le fichier ne contient que du code scriptol. Le code généré pour une page HTML peut être différent.
Les modules externes inclus par npm peuvent être déclaré comme dictionnaire ou comme objet.
Dans le premier cas on déclare le module ainsi:
const net = require("net")
Dans le second cas, le module doit être importé avec la commande import:
import MyModule = require("MyModule")
Et dans le second cas, cela doit être utilise par une instance:
MyModule module1
Dans tous les cas le compilateur Scriptol n'effectue aucun contrôle sur les attributs, méthodes et arguments. Cela est délégué à la machine virtuelle JavaScript.
Vous pouvez utiliser une fonction comme argument d'une autre fonction en la définissant en tant que type. Cela ne fonctionne qu'au niveau global et pas dans une classe. Une fois un type défini, on ne peut le redéfinir.
1) définir une fonction:
Exemple:
int compare(int a, int b) bool b = (a < b) return b
2) Utiliser le type function comme argument:
void mafonc(function a, int x, int y) print a(x,y) return
3) utiliser la fonction générique:
L'argument peut être la fonction originelle ou une autre fonction avec mêmes arguments et même types de retour.
mafonc(compare, 10, 8)
La syntaxe:
define NOUVEAUTYPE
define NOUVEAUTYPE as
crée un nouveau type que l'on peut utiliser en argument de fonctions externes.
Le modificateur "as" fait que le nouveau type ne peut être un pointeur. Donc on l'utilise comme une primitive, comme uint ou gint par exemple.
Ces fonctions sont communes à PHP, C, C++ et Scriptol. Si le nom PHP diffère, il est donné dans la liste.
La liste complète est dans le fichier fun.hpp.
void die(text message) Affiche un message en quittant le programme. void exit() Quitte le programme. Peut afficher un message. number min(number, number) Retourne le plus petit de deux scalaires. number max(number, number) Retourne le plus grand de deux scalaires. const cstring plural(int x) Retourne le pluriel "s" si le nombre x > 0. array range(int x, int y) Génère un tableau des entiers compris entre x et y. cstring str(number) Convertit un nombre en chaîne de charactères. void swap(var, var) Echange le contenu de deux variables. text pad(text t, len l , text c [, int o]]) Complète un texte avec des espaces ou la chaîne de caractères donnée. t: text à compléter. l: longueur à atteindre. c: texte à ajouter, des espaces par défaut. o: option STR_PAD_LEFT, STR_PAD_BOTH, par défaut à droite. (Voir: str_pad)
Casting
text chr(integer) Retourne le charactère pour une valeur ASCII. Ex: chr(32) retourne un espace blanc. int ord(text) Retourne la valeur ASCII d'un charactère. int intval(any) int realval(any) natural naturalval(any) text strval(any) Convertit un nombre en text. char *str(any) Convertit un nombre en chaîne de charactères C. bool boolval(int) array arrayval(tarray) Convertit un tableau typé en tableau d'objets dynamiques.
Fonctions de fichiers (voir aussi les méthodes du type File):
void exec(text) Passe une commande au système d'exploitation. bool file_exists(text) Teste si le fichier dont le nom est en argument existe. number filesize(text) Retourne la taille. number filetime(text) Retourne la taille (utiliser la fonction date pour afficher). text filetype(text) Retourne "dir" ou "file". text fileToText(text) Charge un fichier et retourne un texte. bool rename(text, text) Renomme un fichier. Retourne faux en cas d'échec. void system(text commande) Passe une commande au système d'exploitation. bool unlink(text) Efface un fichier. Retourne true si effacé. var require(text) Déclare un module externe (JavaScript seulement).
Fonctions de répertoire:
bool chdir(text) Change le répertoire courant. Retourne false si échec. bool mkdir(text) Crée un sous-répertoire. Retourne true si créé. bool rmdir(text) Efface un sous-répertoire. Retourne true si éffacé. text getcwd() Retourne le chemin répertoire courant.
Fonctions mathématiques:
number abs(number) Retourne la valeur absolue d'un nombre. real acos(real) real asin(real) real atan(real) number ceil(number) Retourne le nombre arrondi à l'entier supérieur. real cos(real) real exp(real) number floor(number) Retourne le nombre arrondit à l'entier inférieur. number fmod(number, number) Return le modulo de deux nombres. real log(real) number pow(number, number) Retourne la puissance n d'un nombre. int rand() Retourne un nombre aléatoire. void randomize() Démarre une séquence de nombres aléatoires. real round(real) Arrondi au plus proche, plancher ou plafond. real sin(real) number sqrt(number) Retourne la racine d'un nombre. real tan(real)
Fonctions de temps:
int time() Temps en millisecondes depuis le 1 Janvier 1970. dict localtime() Temps et date courant lors de l'appel, dans un dictionaire, voir ci-dessous.
Clé du dict retourné par localtime:
tm_sec Secondes après la minute [0,61] tm_min Minutes après l'heure [0,59] tm_hour Heures après minuit [0,23] tm_mday Jour du mois [1,31] tm_mon Mois à partir de Janvier [0,11] tm_year Année depuis 1900 tm_wday Jour à partir de Dimanche [0,6] tm_yday Jour depuis le 1 Janvier [0,365] tm_isdst Indicateur d'heure d'hivers
Le traitement des exceptions requiert une définition externe. Syntaxe:
extern class exception string what() /class /extern try ... quelques instructions ... catch(exception e) print e.what() /try
Lorsqu'il est compilé en JavaScript, le langage Scriptol offre des fonctions supplémentaires. Elle sont décrite sur le site du langage.
Des mots peuvent être réservés pour le langage cible mais ne font pas partie de Scriptol.
alias
always
and
array
await as async
bool bool
break
byte
case
catch char class
const
continue
define
dict
do
echo
else
enum
error
exception
false
file
finally float
for
forever
from function
global
if
import
in
include
int
integer
is
let
long
mod
nan natural
new nil
not
null
number
or
print
private protected public
react real
require return
script scriptol
sol
static
step
super switch
text
this
to true
try
undefined until
var
void
while
yield
zero