Instructions p-code W
Toutes les instructions p-code ont une mnémonique de 4 caractères. D'éventuels paramètres peuvent se trouver à la suite.
Les paramètres possibles sont :
- d1 : nombre non signé sur 8 bits, de 0 à 255
- d3 : nombre non signé sur 24 bits, de 0 à 16777215 (en big-endian)
- d8 : nombre non signé sur 64 bits (en big-endian)
- string : chaîne de caractères (mono-octet), précédée de sa longueur, soit sur 1 octet (d1), soit sur 3 octets (d3)
Concernant la syntaxe assembleur, les paramètres ont la signification suivante :
- <num3> : numérique non signé sur 3 chiffres
- <num8> : numérique non signé sur 8 chiffres
- <number> : nombre positif ou négatif sur 19 chiffres
- <string> : chaîne de 1 à 255 caractères
- <strmod> : chaîne de 3 à 45 caractères
- <dquote> : chaîne de 0 à 255 caractères, entourée de double quote
“ - <oper> : chaîne valant
EQNELTGTLEGEANDORNOT - <operdyn> : chaîne valant
EQNELTGTLEGE - <varsys> : chaîne de caractères contenant le nom d'une variable système
Gestion des adresses et sauts : en construction.
Dans l'ordre de la traduction numérique de chaque instruction. La taille donne le nombre d'octets pris par chaque instruction.
| Code | Instruction | Paramètres | Taille | Libellé | Syntaxe assembleur |
|---|---|---|---|---|---|
| 000 | VERS | d1 | 2 | Ne fait rien, donne la version du compilé qui s'exécute | VERS <num3> |
| 001 | JUMP | d3 | 4 | Saut a l'adresse d3, en relatif par rapport au début du bloc en cours : programme ou sub | |
| 002 | DECL | d1 string | 2+d1 | Déclare une variable dont le nom est <string> et de longueur <d1>. La longueur <d1> du nom de la variable est [1 , 24] | DECL <string> |
| 003 | SRCL | d3 | 4 | Indique le début du code correspondant à la ligne <d3> du code source W, pour le fichier en cours (principal / include). Sert de point d'arrêt en mode debug. N° de ligne pris en compte dans le calcul de la couverture de code | SRCL <num8> |
| 004 | BEXC | d3 | 4 | Donne l'adresse du bloc exception, juste après instruction EXCE, en relatif a partir de BEXC | BEXC |
| 005 | EXCE | 1 | Marque la fin du bloc de traitement et le début du bloc exception, du programme ou sous-programme en cours. Si l'exécuteur de code arrive à cette instruction sans exception, cela force le retour à l'appelant | EXCE |
|
| 006 | CATC | 1 | Efface l'exception en cours, dans le bloc exception uniquement, et force le retour à l'appelant | CATC |
|
| 007 | THRW | d3 | 4 | Lève une exception de n° <d3>. Dans le bloc traitement, provoque le saut au début du bloc exception. Dans le bloc exception, remplace l'exception courante et force le retour à l'appelant | THRW <num8> |
| 008 | PART | d1 | 2 | Définit le numéro de la portion de code en cours | PART <num3> |
| 009 | RETN | 1 | Force le retour à l'appelant, valide dans le bloc de traitement et le bloc exception | RETN |
|
| 010 | CALL | d1 string | 2+d1 | Appelle la sub <string> | CALL _CALL <string> |
| 011 | PARM | d1 string | 2+d1 | Dépile dans la call stack un pointeur et créé la variable PARAM correspondante dans la hash locale sur ce nom pour ce pointeur. A utiliser avec l'instruction de déclaration d'une sub SUBR | PARM <string> |
| 012 | SUBR | d1 string d3 | 5+d1 | Déclaration d'une sub de nom <string> (remplace DECL pour les sub) et force un saut dans le code après le ENDS, en relatif par rapport à l'instruction SUBR | SUBR <string> |
| 013 | COMP | d1 | 2 | Compare les 2 éléments de la pile, les dépile puis empile 1 si le résultat de la comparaison est vrai, 0 si faux. Les opérateurs de comparaisons sont, de 1 à 9 ⇒ = # < > <= >= and or not | COMP <oper> |
| 014 | JMPF | d3 | 4 | Force un saut dans le code si la dernière comparaison était fausse ⇒ l'élément de la pile = 0. La valeur est dépilée. Le saut (d3) est en relatif par rapport au début du programme ou sous-programme en cours | |
| 015 | JMPT | d3 | 4 | Force un saut dans le code si la dernière comparaison était vraie ⇒ même comportement sinon que JMPF | |
| 016 | ADDN | 1 | Additionne les 2 éléments de la pile, dépile les 2 éléments et empile le résultat. Si une valeur Dynamic est empilée, un conversion numérique est essayée, avec levée d'exception si la conversion n'est pas possible (valeur non numérique) | ADDN |
|
| 017 | SBCN | 1 | Soustrait les 2 éléments de la pile, comportement identique à ADDN | SBCN |
|
| 018 | MULN | 1 | Multiplie les 2 éléments de la pile, comportement identique à ADDN | MULN |
|
| 019 | DIVN | 1 | Divise les 2 éléments de la pile, comportement identique à ADDN, exception si diviseur nul | DIVN |
|
| 020 | INTE | 1 | Prend la valeur entière de la pile, dépile et empile le résultat, conversion essayée si la valeur est un Dynamic | INTE |
|
| 021 | FRAC | 1 | Prend la valeur fractionnaire de la pile, comportement identique à INTE | FRAC |
|
| 022 | NEGN | 1 | Prend la valeur entière de la pile, comportement identique à INTE | NEGN |
|
| 023 | ABSN | 1 | Prend la valeur entière de la pile, comportement identique à INTE | ABSN |
|
| 024 | MODL | d1 string | 2+d1 | Appel d'un module externe (dlfcn.h module.o ayant un seul point d'entrée), les paramètres sont pris de la call stack (maximum 3) ; la chaine doit être de la forme ⇒ module@fonction | MODL <strmod> |
| 025 | PSHC | d8 | 9 | Pousse sur la pile la constante sur 64 bits d8 (en big endian) | PSHC <number> |
| 026 | PSHV | 1 | Empile la variable en cours ad_var | PSHV |
|
| 027 | POPV | 1 | Dépile dans la variable en cours ad_var | POPV |
|
| 028 | PVAR | d1 string | 2+d1 | Met dans ad_var l'adresse de la variable, soit de la hash locale soit de la hash globale (+ gestion mode “typeof”) | PVAR <string> |
| 029 | PVAH | d1 string | 2+d1 | Met dans ad_var l'adresse de la variable lue de la hashtable pointée elle aussi par ad_var (+ gestion mode “typeof”) | PVAH <string> |
| 030 | WRIT | 1 | Ecrit dans la console (sortie standard) le contenu de la variable pointée par ad_var (Number ou Dynamic), ne fait rien si programme demon | WRIT |
|
| 031 | WRLN | 1 | Identique à WRIT avec de plus un saut de ligne écrit à la fin | WRLN |
|
| 032 | DSET | d1 string | 2+d1 | Affecte la chaine <string> à la variable pointée par ad_var (maxi. 255 caractères) | DSET <dquote> |
| 033 | DEXT | d1 string | 2+d1 | Correspond à <ad_var>{pile,pile} : extrait de la chaine pointée par ad_var l'attribut issu de la pile, valeur issue de la pile. Si une valeur de pile vaut 0, le contenu complet calculé précédemment est gardé. Si <d1> = 0, le résultat est mis dans int_dynamic sinon dans la variable de nom <string> | DEXT _DEXT <string> |
| 034 | DCMP | op d1 string | 3+d1 | Compare la chaine de la variable pointée par ad_var avec le contenu de la variable de nom <string> (op: = # < > <= >=, 1 a 6). Le résultat est empilé, 1 si condition vraie, 0 si fausse | DCMP <operdyn> <string> |
| 035 | DSTO | d1 string | 2+d1 | Correspond à <ad_var>{pile,pile} = variable <nom>. Si <d1> = 0, le contenu est lu de int_dynamic. Si une valeur de pile vaut 0, le contenu complet calculé précédemment est gardé. | DSTO _DSTO <string> |
| 036 | VLET | d1 string | 2+d1 | Affectation simple de variable. La variable de nom <string> reçoit la valeur de celle pointée par ad_var. Si <d1> = 0, l'affectation va dans int_dynamic. | VLET _VLET <string> |
| 037 | DCAT | d1 string | 2+d1 | Concaténation : à la variable de nom <string> est concaténée la valeur de celle pointée par ad_var. Si <d1> = 0, la concaténation se fait dans int_dynamic. | DCAT _DCAT <string> |
| 038 | DTON | 1 | Convertit la variable pointée par ad_var en numérique et l'empile | DTON |
|
| 039 | NTOD | 1 | Dépile et convertit le nombre en chaine, mis dans ad_var. | NTOD |
|
| 040 | DELE | d1 string | 2+d1 | Supprime la variable de nom <string> de la hash locale/globale et effectue les libérations associées (sauf si objet/sub) | DELE <string> |
| 041 | HLET | 1 | Affecte à la variable pointée par ad_var une hashtable vierge. Le modulo et séparateur sont dans la pile, si 0 une valeur par défaut est utilisée. | HLET |
|
| 042 | CLAS | d1 string | 2+d1 | Créé une classe globale de nom <string> héritée de la classe trouvée sur la pile (avec dépilage). | CLAS <string> |
| 043 | NLET | d1 string | 2+d1 | Instancie un objet, global, de la classe de nom <string>. La variable pointée par ad_var prend le type VAR_PARAM et pointe sur l'objet créé. | NLET <string> |
| 044 | INCL | d1 string | 2+d1 | Include dans le source W : indique un changement de fichier source en cours (utile au debugger). Si <d1> = 0, correspond à un retour d'include. | INCL <string>INCL |
| 045 | PNAM | d1 string | 2+d1 | Nom du programme principal (PROG ou BACK). | PNAM <string>PNAM |
| 046 | PSH0 | 1 | Empile la constante 0 | PSH0 |
|
| 047 | PSH1 | 1 | Empile la constante 1 | PSH1 |
|
| 048 | PSH2 | 1 | Empile la constante 2 | PSH2 |
|
| 049 | PSH3 | 1 | Empile la constante 3 | PSH3 |
|
| 050 | PSH4 | 1 | Empile la constante 4 | PSH4 |
|
| 051 | PSH5 | 1 | Empile la constante 5 | PSH5 |
|
| 052 | PSH6 | 1 | Empile la constante 6 | PSH6 |
|
| 053 | PSH7 | 1 | Empile la constante 7 | PSH7 |
|
| 054 | PSH8 | 1 | Empile la constante 8 | PSH8 |
|
| 055 | PSH9 | 1 | Empile la constante 9 | PSH9 |
|
| 056 | PSHA | d1 | 2 | Empile la @VARSYS de code d1 | PSHA <varsys> |
| 057 | PROG | 1 | Indique que le binaire est un programme, première instruction du binaire | PROG |
|
| 058 | BACK | 1 | Indique un binaire exécutable en mode demon, première instruction en alternative à PROG | BACK |
|
| 059 | CLIB | d1 string | 2+d1 | Appel de la library de nom <string>. Les paramètres sont pris de la call stack. <string>.wp est le nom du fichier binaire qui est chargé en mémoire (binaire W) | CLIB <string> |
| 060 | PVAI | d1 string | 2+d1 | Met dans ad_var l'adresse de la variable lue de la hashtable pointée elle aussi par ad_var, mais via une indirection : la variable de nom <string> donne le vrai nom de la variable à chercher (+ gestion mode “typeof”) | PVAI <string> |
| 061 | DIVE | 1 | Divise les 2 éléments de la pile en gardant la partie entière uniquement, comportement identique à ADDN, exception si diviseur nul | DIVE |
|
| 062 | MODN | 1 | Divise les 2 éléments de la pile en gardant le reste uniquement (modulo), comportement identique à ADDN, exception si diviseur nul | MODN |
|
| 063 | INPT | 1 | Réalise une saisie au clavier (entrée standard) et met le résultat dans la variable pointée par ad_var, convertie en chaine | INPT |
|
| 064 | PVAT | 1 | Met dans le pointeur de variable ad_var l'adresse d'une variable temporaire _tmp999 automatique, pour accès immédiat dans l'instruction suivante | PVAT |
|
| 065 | TYPO | 1 | Fait passer le programme en cours en mode typeof, pour ne pas générer d'exception si une variable est inconnue dans les syntaxes du type ?var.var2!var3. etc.. Renvoie le typeof. Attention : entre les instructions TYPO et PSHT ne doivent se trouver que des instructions PVAR et n fois PVAH/PVAI | TYPO |
|
| 066 | PSHT | 1 | Empile le type de la variable pointée par ad_var (typeof), -1 si inconnu. Cette instruction annule le mode typeof (annulation a faire aussi quand exception autre que var inconnue) | PSHT |
|
| 067 | CRAZ | 1 | Vide la call stack servant au passage des paramètres avant les instruction CALL CLIB MODL | CRAZ |
|
| 068 | CPSH | d1 string | 2+d1 | Empile dans la call stack la variable de nom <string>. A utiliser avant les instructions CALL CLIB MODL | CPSH <string> |
| 069 | RETT | 1 | Dépile et si la valeur est # 0 (vrai), force le retour à l'appelant, valide dans le bloc de traitement et le bloc exception | RETT |
|
| 070 | SELE | 1 | initialise la var de ad_var pour foreach dynamic/hashtable | SELE |
|
| 071 | RNXT | 1 | lit l'item suivant de ad_var et met le résultat dans la var empilée dans la call stak (dépilage au passage) | RNXT |
|
| 072 | CPHA | 1 | empile dans la call stack la var ad_var en param | CPHA |
|
| 073 | PHDE | d1 string | 2+d1 | enchainement PVAH/PVAI, en dernier crée/remplace dans la hash la var <string> avec le contenu de la pile (number/dynamic) - let | PHDE <string> |
| 074 | PIDE | d1 string | 2+d1 | enchainement PVAH/PVAI, en dernier crée/remplace dans la hash (avec indirection) la var <string> avec le contenu de la pile (number/dynamic) - let | PIDE <string> |
| 075 | PHDH | d1 string | 2+d1 | enchainement PVAH/PVAI, en dernier crée/remplace dans la hash la var hash <string> (la pile contient modulo/séparateur) - let | PHDH <string> |
| 076 | PIDH | d1 string | 2+d1 | enchainement PVAH/PVAI, en dernier crée/remplace dans la hash (avec indirection) la var hash <string> (la pile contient modulo/séparateur) - let | PIDH <string> |
| 077 | PHDO | d1 string | 2+d1 | enchainement PVAH/PVAI, en dernier cherche la sub <string> dans la classe, si pas trouve dans les classes mères | PJDO <string> |
| 078 | PIDO | d1 string | 2+d1 | enchainement PVAH/PVAI, en dernier cherche la sub <string> (avec indirection) dans la classe, si pas trouve dans les classes mères | PIDO <string> |
| 079 | PHDS | d1 string d3 | 5+d1 | enchainement PVAH/PVAI, en dernier crée/remplace dans la hash la sub <string> | PHDS <string> <d3> |
| 080 | PIDS | d1 string d3 | 5+d1 | enchainement PVAH/PVAI, en dernier crée/remplace dans la hash (avec indirection) la sub <string> | PIDS <string> <d3> |
| 081 | TYPE | 1 | trouve le type de l'élément de la pile num/str/vide, dépile + met le résultat | TYPE |
|
| 082 | ROUN | 1 | arrondi l'élément pile2 sur le nombre de décimales pile1, dépile et arrondi l'élément de la pile si nb décimales n'est pas 0 1 2 3 4 5, utilise la précision courante | ROUN |
|
| 083 | LENG | 1 | calcule la longueur de l'élément de la pile (comme si chaine), dépile + met le résultat | LENG |
|
| 084 | COUN | 1 | compte le nombre de caractère (1er de pile2) trouve dans pile1, dépile + met le résultat | COUN |
|
| 085 | DCOF | 1 | dcount(var), comme le nombre de champs, en prenant le séparateur courant | DCOF |
|
| 086 | FIEL | 1 | “fonction ”“field”” : chercher dans la chaine pile1, avec le caractère pile2 (1er car), le champ no pile3, dépile + met le résultat | FIEL |
|
| 087 | INDX | 1 | index(var, search, occ) | INDX |
|
| 088 | SRCH | 1 | search(var) search string in field | SRCH |
|
| 089 | CHNG | 1 | change(var, cherche, remplace) | CHNG |
|
| 090 | FMTA | 1 | format - alignment (left right center) | FMTA |
|
| 091 | INSE | 1 | insert(var, chaine, field) | INSE |
|
| 092 | REMV | 1 | remove(var, field) | REMV |
|
| 093 | TONU | 1 | tonum : force la conversion de l'élément de la pile en numérique, exception si non numérique | TONU |
|
| 094 | TOST | 1 | tostring : force la conversion de l'élément de la pile en chaine | TOST |
|
| 095 | CCAT | 1 | concat : : concatène pile1 et pile2, dépile 2 fois + met le résultat“ | CCAT |
|
| 096 | SSTR | 1 | substring ou notation [9,9] : prend la substring de la pile + met le résultat (base 0 pour début, longueur ; si 1 seul param : part de la fin (que longueur)) | SSTR |
|
| 097 | SSEP | 1 | set sep : prend les séparateur de la pile + dépile les 2 + maj séparateur | SSEP |
|
| 098 | FLDF | 1 | idem FIEL mais utilise le séparateur @currfm (pour faire x{1}) | FLDF |
|
| 099 | FLDS | 1 | idem FIEL mais utilise le séparateur @currfm et @currvm (pour faire x{1,2}) | FLDS |
|
| 100 | DCOS | 1 | dcount(var, numchamp) | DCOS |
|
| 101 | FMTT | 1 | “format ”“trim””“ | FMTT |
|
| 102 | FMTS | 1 | “format ”“surround””“ | FMTS |
|
| 103 | SCHS | 1 | search(var, numField) search string in subfield of the field given | SCHS |
|
| 104 | INSS | 1 | insert(var, chaine, field, subfield) | INSS |
|
| 105 | REMS | 1 | remove(var, field, subfield) | REMS |
|
| 106 | DEXH | d1 string | 2+lg | ad_var_hash.string<pile1, pile2> = pile3 (suite PHDE) | DEXH |
| 107 | DEXI | d1 string | 2+lg | ad_var_hash!string<pile1, pile2> = pile3 (suite PIDE) | DEXI |
| 108 | PREC | d1 | 2 | force la précision a <d1> décimales (de 0 a 5) | PREC <d1> |
| 109 | DESV | 1 | ad_var[pile1, pile2] = pile3 (suite PVAR) | DESV |
|
| 110 | DESH | d1 string | 2+lg | ad_var_hash.string[pile1, pile2] = pile3 (suite PHDE/PIDE) | DESH |
| 111 | DESI | d1 string | 2+lg | ad_var_hash!string[pile1, pile2] = pile3 (suite PHDE/PIDE) | DESI |
| 112 | DEZV | 1 | ad_var<pile1, pile2>[pile3, pile4] = pile5 (suite PVAR) | DEZV |
|
| 113 | DEZH | d1 string | 2+lg | ad_var_hash.string<pile1, pile2>[pile3, pile4] = pile5 (suite PHDE/PIDE) | DEZH |
| 114 | DEZI | d1 string | 2+lg | ad_var_hash!string<pile1, pile2>[pile3, pile4] = pile5 (suite PHDE/PIDE) | DEZI |
| 115 | SDBG | d3 string | 4+d3 | liste des fichiers sources + num lignes (pour debugger) | SDBG <string> |
| 116 | PHDN | d1 string | 2+lg | enchainement PVAH/PVAI, en dernier cree/remplace dans la hash <ad_var_hash> la var <string > qui sera utilisée ensuite par NLET (mis dans <ad_var>) | PHDN <string> |
| 117 | PIDN | d1 string | 2+lg | enchainement PVAH/PVAI, en dernier cree/remplace dans la hash <ad_var_hash> (avec indirection) la var <string > qui sera utilisée ensuite par NLET (mis dans <ad_var>) | PIDN <string> |
| 118 | SADV | 1 | sauvegarde ad_var dans ad_var_sav (suite enchainement PVAR/PVAH/PVAI) | SADV |
|
| 119 | VLET | 1 | affectation de variable sans expression, traite tous les types. Correspond a : ad_var = ad_var_sav (copie) | VLET |
|
| 120 | PHDV | d1 string | 2+lg | idem VLET mais en fin de chaine de vars hash pour la var <string> | PHDV <string> |
| 121 | PIDV | d1 string | 2+lg | idem VLET mais en fin de chaine de vars hash pour la var <string>, avec indirection | PIDV <string> |
| 122 | HCOU | 1 | idem PVAH/PVAI mais renvoi le nombre d'élément de la hash/objet en cours (dans ad_var = e→int_number) | HCOU |
|
| 251 | LIBR | 1 | Indique que le binaire est une library, pas un programme exécutable directement. Première instruction du binaire. | LIBR |
|
| 252 | ENDL | 1 | Fin de library, avec libération des éléments locaux à la library uniquement | ENDL |
|
| 253 | TEST | 1 | Instruction permettant d'exécuter du code, utilisé dans le cadre du développement de W. Ne fait rien en fonctionnement normal | TEST |
|
| 254 | ENDS | 1 | Fin du sous-programme en cours, avec libération des éléments locaux à la sub uniquement | ENDS |
|
| 255 | ENDP | 1 | Fin du programme principale en cours, en effectuant toutes les libérations mémoires. Instruction appelée de manière forcée en cas d'erreur non gérable par une exception | ENDP |