L'interpréteur en ligne de commande (yes.exe)
yes.exe est l'interpréteur YScript autonome — un
exécutable qu'on lance directement depuis un terminal, sans écrire de code C#. C'est l'équivalent du
lua.exe/« standalone interpreter » du manuel Lua. Cette page s'adresse à quelqu'un qui exécute
des scripts YScript en ligne de commande ; pour embarquer le moteur dans une application .NET, voir
Moteur.
yes.exe monscript.yes arg1 arg2
yes.exe -i
yes.exe -e "print(1+1)"
yes.exe construit un ScriptEngine sur un hôte console (ConsoleHost) et ouvre toutes les
bibliothèques standard, sans exception : OpenLibs() (base, coroutine, package, table,
math, string, regex, debug), plus OpenIOLib() (io.*), OpenOSLib() (os.*) et
OpenDotnetLib() (dotnet.*, interop .NET complète). Contrairement à un hôte embarqué, qui choisit
d'ouvrir un sous-ensemble précis selon ses besoins (voir Démarrage),
l'interpréteur standalone n'a pas de raison de restreindre quoi que ce soit : un script lancé depuis
la ligne de commande a par construction accès au système de fichiers, à l'horloge/au process et à la
réflexion .NET du process qui l'exécute.
Syntaxe d'invocation
yes.exe [options] [script [args]]
script: le fichier à exécuter (ou un nom de paquet, voir Résolution paquet/commande plus bas). Absent, l'interpréteur passe en mode interactif (sauf si-e/-la déjà fourni du code à exécuter).args: tout ce qui suitscriptsur la ligne de commande est transmis tel quel au script via la table globaleargs(voir plus bas) — ce ne sont pas des options deyes.exe, même si elles commencent par-.
Options
| Option | Effet |
|---|---|
-e stat |
Exécute la chaîne stat comme un chunk de code YScript. |
-l name |
Équivalent à name = require("name") : charge la bibliothèque/le module name et l'assigne à la variable globale du même nom. |
-i, --interactive |
Passe en mode interactif (REPL) une fois le script (et les -e/-l) exécuté(s). |
-p file, --profile file |
Charge file comme fichier de profil au lieu du profil par défaut. file doit exister. |
--no-profile |
Désactive le chargement d'un profil, par défaut ou explicite. |
-c, --command |
Force la résolution de script comme commande d'un paquet plutôt que comme fichier littéral (voir plus bas). |
-v, --version |
Affiche l'en-tête (version du moteur, copyright) avant de continuer — n'arrête pas l'exécution. |
-d, -D, --debug |
Active l'affichage d'informations de déboguage (y compris dans le REPL). |
Les options courtes se combinent (-vi = -v -i) sauf -e, -l et -p, qui consomment le reste
de leur propre argument (-emonstat) ou, s'il n'en reste pas, l'argument suivant sur la ligne de
commande (-e monstat) — placez-les en dernier dans un groupe combiné, ou seules. -e et -l
peuvent apparaître plusieurs fois ; ils sont alors exécutés dans l'ordre où ils apparaissent sur la
ligne de commande.
Une option longue inconnue (--truc), une option courte inconnue, ou -e/-l/-p/--profile sans
argument, arrête l'analyse et affiche l'en-tête, le message d'erreur, l'usage puis l'aide, avant de
quitter en erreur.
Ordre d'exécution réel
- L'en-tête (version, copyright) s'affiche si
-v/--versionest présent, ou si l'interpréteur va de toute façon entrer en mode interactif (voir plus bas) — dans ce dernier cas même sans-v. - Le profil est chargé (sauf
--no-profile), avant que la tableargsn'existe encore — un script de profil n'a donc pas accès àargs. - La table globale
argsest construite. - Chaque
-e/-lfourni est exécuté, dans l'ordre où il apparaît sur la ligne de commande. Si l'un d'eux échoue, l'interpréteur s'arrête immédiatement (le reste, y comprisscript, n'est pas exécuté). - Si un
scripta été fourni, il est chargé et exécuté (ou résolu comme commande de paquet — voir plus bas). - Si le mode interactif doit s'enclencher (voir plus bas), le REPL démarre.
Le mode interactif s'enclenche si -i/--interactive est passé explicitement, ou si aucun
script n'a été fourni et qu'aucun -e n'a été utilisé (un -l seul, sans -e ni script, entraîne
donc aussi le REPL).
La table globale args
À l'image de la table arg du Lua standalone, yes.exe construit une table globale args avant
d'exécuter -e/-l/le script :
args[0]— le nom du script en cours d'exécution (ouyes.exelui-même si aucun script n'est fourni).args[-1],args[-2], ... — les arguments de la ligne de commande qui précèdent le nom du script (typiquement, le chemin de l'exécutable et les options deyes.exe), dans l'ordre où ils apparaissent, indexés négativement à partir du script.args[1],args[2], ... — les arguments qui suivent le nom du script sur la ligne de commande, c'est-à-dire ceux destinés au script lui-même.
Exemple : yes.exe monscript.yes arg1 arg2 produit args[-1] = "yes.exe", args[0] = "monscript.yes", args[1] = "arg1", args[2] = "arg2".
Quand script est résolu comme commande d'un paquet plutôt que comme fichier littéral (voir plus
bas), args est reconstruite une seconde fois une fois la commande localisée : args[0] devient
alors le chemin réel de command.yes exécuté, à la place du nom du paquet tapé sur la ligne de
commande.
Le profil
Avant tout autre code (-e, -l, script), yes.exe charge un fichier de profil, dans l'esprit d'un
.bashrc : utile pour définir des alias, des fonctions utilitaires ou pré-charger des bibliothèques
qu'on veut disponibles à chaque session.
- Par défaut,
%APPDATA%/yeg/yscript/profile.yes(le même fichier que celui utilisé parYScript.Editor). S'il n'existe pas, il est silencieusement ignoré — ce n'est pas une erreur. -p file/--profile filechargefileà la place ; contrairement au profil par défaut, ce fichier doit exister (son absence est une erreur qui arrête l'interpréteur).--no-profiledésactive complètement cette étape, qu'un profil par défaut existe ou qu'un profil explicite ait été demandé.
Résolution paquet/commande (yes.exe nom)
Quand un script est fourni et n'est pas --command/-c, yes.exe tente d'abord de l'ouvrir comme
un fichier littéral. Si ce fichier n'existe pas (ou si -c/--command a forcé l'autre chemin), il
tente de résoudre nom comme un paquet YScript :
- Recherche de
nomviapackage.path, puispackage.dotnetpath(la même résolution querequireutilise en interne, viapackage.searchpath) — s'il n'est trouvé dans aucun des deux, l'échec final se comporte comme un fichier introuvable ordinaire (même message qu'unscriptinexistant). - Si un module
nomest trouvé,yes.execherche un fichiercommand.yesà la racine du même dossier. S'il n'y en a pas, l'erreur « le paquet 'nom' n'expose pas de commande. » est affichée et l'interpréteur s'arrête. - Sinon, le paquet est chargé normalement (
require("nom"), comme-l nom—package.loaded["nom"]est donc disponible àcommand.yes), la tableargsest reconstruite (voir plus haut), puiscommand.yesest exécuté comme s'il s'agissait du script littéral fourni.
-c/--command force ce chemin de résolution d'entrée, sans même essayer d'ouvrir script comme
fichier littéral au préalable — utile si un fichier et un paquet portent le même nom, ou pour être
explicite dans un script/alias.
Le détail de la résolution package.path/package.dotnetpath est documenté dans
la bibliothèque package ; cette page ne couvre que l'usage côté ligne de
commande. Pour installer/publier des paquets (au sens ypack.json, distinct d'un simple module
require-able), voir la documentation du module ypack (require("ypack") ou
yes.exe ypack doc ypack).
Le mode interactif (REPL)
Le comportement du moteur REPL (ScriptReplEngine, saisie multi-ligne, invite prompt/_PROMPT/
_PROMPT2, ...) est documenté côté embarqueur dans Démarrage ;
yes.exe en est simplement un client, avec l'édition de ligne, l'historique et l'affichage propres à
un terminal.
Du point de vue utilisateur :
- Ctrl+C n'arrête jamais le process. Pendant la saisie d'une ligne, il annule la ligne en cours.
Pendant l'exécution d'un script (lancé depuis le REPL ou comme
scriptinitial), il interrompt ce script en cours — l'interpréteur se retrouve alors de retour à l'invite, prêt à continuer, comme si une erreur s'était produite dans le script. - Fin de fichier (EOF) — Ctrl+D sous un terminal Unix, Ctrl+Z puis Entrée sous Windows, ou une entrée standard redirigée qui se termine — met fin proprement à la session et quitte l'interpréteur.
Débogage
-d, -D ou --debug active l'affichage d'informations de déboguage, aussi bien pour l'exécution
d'un script que dans le REPL. Une build DEBUG de l'exécutable lui-même active ce mode d'office.
debug.debug()
Contrairement au reste de la bibliothèque debug, debug.debug() n'est pas
définie par le moteur cœur — stdin/stdout interactifs sont propres à l'hôte — mais ajoutée par
yes.exe lui-même, qui a un vrai terminal.
Appelée, elle suspend le script à l'endroit de l'appel et ouvre une invite imbriquée (debug>), qui
lit et exécute des lignes comme le REPL top-level (mêmes règles de saisie multi-ligne, historique,
Ctrl+C annule la ligne en cours) :
local function f(x)
local y = x * 2
debug.debug() -- suspend ici
return y
end
print(f(21))
debug> print("bonjour depuis l'invite imbriquée")
bonjour depuis l'invite imbriquée
debug> cont
42
Taper cont (seul sur la ligne) ou atteindre la fin de l'entrée (EOF) reprend l'exécution normale du
script à partir d'où elle avait été suspendue.
Comme en Lua, cette invite n'a pas de résolution automatique vers les variables locales de la
fonction interrompue — une ligne tapée y est un chunk indépendant, exécuté dans l'environnement
global. Pour inspecter/modifier l'état de l'appelant, passez explicitement par debug.getlocal/
debug.setlocal (voir debug) avec le niveau de pile approprié
— celui-ci dépend de l'empilement interne (l'invite elle-même, plus l'appel natif de debug.debug,
ajoutent chacun un niveau) et se détermine au besoin avec debug.getinfo :
debug> for lvl = 0, 5 do local i = debug.getinfo(lvl, "nSl"); if i then print(lvl, i.what, i.name) end end
debug> print(debug.getlocal(3, 2)) -- le niveau qui correspond à 'f' dans l'exemple ci-dessus
y 42