1. OPERATEURS ARITHMETIQUES, LOGIQUES ET MANIPULATION DE PILE


A. Opérateurs arithmétiques 16 bits signés.

+ n1 n2 --- n3 F83

Additionne deux nombres entiers, n1 et n2, et dépose le résultat n3 sur la pile de données. Les valeurs n1 et n2 sont perdues. Exemple: 22 3 + . affiche 25
65535 1 + . affiche 0 (.. entiers sur 16 bits !!!)

 
- n1 n2 --- n3 F83

Le nombre entier signé n3 est le résultat de la soustraction de n2 à n1, équivalant à l'opération algébrique n1-n2. Exemple:

7 5 - . affiche 2
5 7 - . affiche -2

 
* n1 n2 --- n3 F83

Effectue la multiplication signée de n1 par n2 et laisse le résultat n3 sur la pile de données. Attention aux effets de débordement de capacité risquant d'entraîner des erreurs en cas de multiplication de deux nombres entiers trop importants. Pour être valideé le résultat doit rester dans l'intervalle -32768..32767. Exemple:

45 3 * . affiche '135' ce qui est exact
450 1000 * . affichera un résultat faux.

Le signe du résultat dépend du signe des nombres n1 et n2:

 
/ n1 n2 --- n3 F83

Opérateur division entière signée. n3 est le quotient plancher (entier inférieur) de n1 et n2. Exemple:

Note: le standard prévoit qu'un message d'erreur soit généré en cas de division par zéro.

 
MOD n1 n2 --- n3 F83

Délivre le reste n3 de la division de n1 par n2.

 
/MOD n1 n2 --- n3 n4 F83

Opérateur division entière signée avec reste. n4 est le quotient plancher et n3 le reste de la division de n1 par n2. Le reste a le même signe que le diviseur. Exemple:

 22 7 /MOD . .  affiche 3 1
 22 -7 /MOD . . affiche -4 -6
-22 7 /MOD . .  affiche -4 6
-22 -7 /MOD . . affiche 3 -1

 
*/ n1 n2 n3 --- q F83

Effectue le produit des nombres entiers n1 et n2 et divise le résultat par n3. Le résultat final correspond au quotient signé q de l'opération (n1*n2)/n3. Exemple, soit à calculer 7 pour 100 d'un nombre:

: 7% 7 100 */ ;
100 7% . affiche 7
300 7% . affiche 21

Attention, 302 7% affiche aussi 21, car le mot */ ne calcule le quotient q qu'en nombre entier signé. Notez que le résultat intermédiaire est sur 32 bits, ce qui donne tout son intérêt à ce mot pour éviter des débordements. Le signe du résultat dépend des signes de n1, n2 et n3:

 
*/MOD n1 n2 n3 --- r q F83

 

Effectue le produit des nombres entiers n1 et n2 et divise le résultat par n3. Le résultat final correspond au quotient q et au reste r de l'opération (n1*n2)/n3. L'exécution de ce mot en remplacement des opérations de multiplication et de division simultanées permet de supprimer l'erreur apparaissant lors du dépassement de capacité pendant la multiplication. Exemple:

302 7 100 */MOD . . affiche 21 14

Les signes de r et de q dépendent des signes de n1 n2 et n3:

 
1+ n --- n+1 F83

Ajoute 1 à la valeur située au sommet de la pile de données.

 
1- n --- n-1 F83

Soustrait 1 à la valeur située au sommet de la pile de données.

 
2+ n --- n+2 F83

Ajoute 2 au nombre situé au sommet de la pile de données.

 
2- n --- n-2 F83

Soustrait 2 au nombre situé au sommet de la pile de données.

 
2* n --- n*2  

Multiplie le nombre n par deux. Cette opération est beaucoup plus rapide que la séquence 2 *, car 2* exécute un décalage logique d'un bit vers la gauche sur le contenu d'un registre 16 bits.

 
2/ n --- n/2 F83

Décalage à droite sur un bit de la valeur située au sommet de la pile de données. Equivaut à la division entière par 2 pour les nombres positifs.

 
8* n --- n*8  

Multiplication par huit. Réalise un décalage à gauche sur trois bits. Equivaut à l'exécution de trois fois le mot 2*.

 
?NEGATE n1 n2 --- n3  

Rend négatif le second élément si celui situé au sommet de la pile est négatif. Exemple:

5 -1 ?NEGATE . affiche -5
5 1 ?NEGATE . affiche 5

 
NEGATE n --- -n F83

Convertit le nombre n en son complément à deux, c'est à dire inverse son signe. Exemple:

5 NEGATE . affiche -5

 
ABS n --- +n  

Renvoie la valeur absolue du nombre entier déposé sur la pile de données.

B. Opérateurs logiques 16 bits.

 
AND n1 n2 --- n3  

Effectue un ET logique bit à bit entre les valeurs n1 et n2.

 
OR n1 n2 --- n3  

Effectue un OU logique bit à bit entre les valeurs n1 et n2.

 
XOR n1 n2 --- n3  

Effectue un OU Exclusif logique bit à bit entre les valeurs n1 et n2.

table de vérité des fonctions AND, OR et XOR:

 
NOT n1 --- n2  

Convertit un nombre n1 en son complément à un. Est équivalent à la séquence -1 XOR. Ce mot peut servir à définir une bascule logique pour inverser la valeur d'un flag booléen. Exemple:

TRUE NOT . affiche 0 ( équivaut à FALSE)
FALSE NOT . affiche -1 ( équivaut à TRUE)

Si vous êtes passionnés de montages électroniques, voici comment simuler une porte logique NAND:

: NAND ( fl1 fl2 --- fl3)
AND NOT ;

et la table de vérité de NAND devient:

0 0 NAND . affiche -1
0 1 NAND . affiche -1
1 0 NAND . affiche -1
1 1 NAND . affiche 0

etc,etc pour plus d'exemple envoyer un mail sur la liste de diff' qui complétera les exemples donné sur le livre.

 
OFF adr ---  

Rend faux le contenu de la variable pointée par son adresse. Ce contenu sert généralement de flag booléen au sein d'une structure de contrôle. Equivaut à la séquence 0 !. Exemple:

VARIABLE TEST
: APPUI KEY 5 =
IF TEST ON ELSE TEST OFF THEN ;
APPUI TEST ?

affiche 0 si touche activée <> CTRL-E
affiche -1 si touche activée = CTRL-E (éviter l'appui sur CTRL-C qui provoque un retour au DOS)

 
ON adr ---  

Rend vrai le contenu de la variable pointée par son adresse. Equivaut à la séquence -1 !. Exemple:

VARIABLE DRAPEAU DRAPEAU ON
DRAPEAU ?     affiche '-1'

 
FALSE --- 0  

Constante délivrant la valeur 0. Pour des raisons de rapidité d'exécution, sa définition est en code machine. Ce mot sert essentiellement à rendre certains tests plus explicites dans leur libellé. Ainsi, la séquence 0= IF TRUE ELSE FALSE THEN est plus claire que 0= IF -1 ELSE 0 THEN.

 
TRUE --- -1  

Constante délivrant le flag booléen vrai.

 
CRESET oct adr ---  

Opérateur à l'échelle du bit. Force à 0 les bits de l'octet pointé par adr selon les bits à un du masque oct. Les autres bits sont inchangés. Exemple:

VARIABLE OCTET
6 OCTET C!           ( 00000110)
3 OCTET CRESET       ( 00000011)
OCTET C@ . affiche 4 ( 00000100)

Le mot CRESET équivaut à la séquence DUP C@ ROT NOT AND SWAP C!.

 
CSET oct adr ---  

Opérateur à l'échelle du bit. Force à 1 les bits de l'octet pointé par adr selon les bits à un du masque oct. Les autres bits sont inchangés. Exemple:

VARIABLE OCTET
6 OCTET C!           ( 00000110)
3 OCTET CSET         ( 00000011)
OCTET C@ . affiche 7 ( 00000111)

Le mot CSET équivaut à la séquence DUP C@ ROT OR SWAP C!.

 
CTOGGLE oct adr ---  

Opérateur à l'échelle du bit. Inverse les bits de l'octet pointé par adr selon les bits à un du masque oct. Les autres bits sont inchangés. Exemple:

VARIABLE OCTET
6 OCTET C!           ( 00000110)
3 OCTET CTOGGLE      ( 00000011)
OCTET C@ . affiche 5 ( 00000101)

Le mot CTOGGLE équivaut à la séquence DUP C@ ROT XOR SWAP C!.

C. Opérateurs de comparaison 16 bits.

Parmis les opérateurs de comparaison, on distinguera les opérateurs monadiques des opérateurs diadiques. Les opérateurs monadiques ne traitent qu'une seule donnée, alors que les opérateurs diadiques traitent deux données. Exemple d'opérateurs monadiques:

0 0<= 0= 0>= 0> 0<>

Exemple d'opérateurs diadiques:

< <= = >= > <>

Toutes les règles de la logique s'appliquent à ces opérateurs, notamment lorsqu'ils sont combinés avant exécution d'une action conditionnelle. Exemple, soit à exécuter une séquence si la valeur n est comprise entre 5 et 10 ou inférieure à -5:

: TEST ( n --- fl)
DUP 5 > OVER 10 < AND OVER -5 < OR ;

Une connaissance approfondie de la logique est nécessaire pour combiner sans risque d'erreur les opérateurs et les opérateurs de comparaison.

 
0< n --- f F83

Délivre un flag booléen vrai si n est négatif. Exemple:

10 0< . affiche 0
-5 0< . affiche -1

 
0<= n --- f  

Délivre un flag booléen vrai si n est négatif ou nul. Inverse de 0>. Exemple:

5 0<= . affiche 0
0 0<= . affiche -1
-5 0<= . affiche -1

 
0<> n --- f  

Délivre un flag booléen vrai si n est différent de zéro. Inverse de 0=.

 
0= n --- f F83

Délivre un flag booléen vrai si n est égal à zéro.

 
0> n --- f F83

Délivre un flag booléen vrai si n est strictement positif.

 
0>= n --- f  

Délivre un flag booléen vrai si n est positif ou nul. Inverse de 0<.

 
< n1 n2 --- f F83

Délivre un flag booléen vrai si n1 est inférieur à n2. Exemple:

10000 1 < . affiche 0 (10000 n'est pas inférieur à 1)
50000 1 < . affiche -1 (faux car nombres signés !)

 
<= n1 n2 --- f  

Délivre un flag booléen vrai si n1 est inférieur ou égal à n2. Inverse de >.

 
<> n1 n2 --- f  

Délivre un flag booléen vrai si n1 différent de n2. Inverse de =.

 
= n1 n2 --- f F83

Délivre un flag booléen vrai si n1 est égal à n2.

 
> n1 n2 --- f F83

Délivre un flag booléen vrai si n1 est supérieur à n2.

 
>= n1 n2 --- f  

Délivre un flag booléen vrai si n1 est supérieur ou égal à n2. Inverse de <.

 
U u1 u2 --- f  

Délivre un flag booléen vrai si le nombre entier non signé u1 est inférieur au nombre entier non signé u2.

 
U<= u1 u2 --- f  

Délivre un flag booléen vrai si le nombre entier non signé u1 est inférieur ou égal au nombre entier non signé u2.

 
U> u1 u2 --- f  

Délivre un flag booléen vrai si le nombre entier non signé u1 est supérieur au nombre entier non signé u2.

 
U>= u1 u2 --- f  

Délivre un flag booléen vrai si le nombre entier non signé u1 est supérieur ou égal au nombre entier non signé u2.

 
MAX n1 n2 --- n1 ou n2 F83

Délivre le plus grand de n1 ou n2. Exemple:

5 7 MAX . affiche 7
7 5 MAX . affiche 7

Ce mot, associé au mot MIN permet d'encadrer dans un domaine borné l'exécution d'une fonction. Pour exemple, si vous désirez qu'une entrée numérique soit filtrée avec deux valeurs servant de bornes dans un domaine de définition précis (en graphisme pour exemple, pour que les coordonnées d'un point ne sortent pas de l'écran vidéo), on définit:

: FILTRE-X ( x --- x')
0 MAX 319 MIN ;

et à l'exécution:
-5 FILTRE-X . affiche 0
 0 FILTRE-X . affiche 0
25 FILTRE-X . affiche 25
319 FILTRE-X . affiche 319
450 FILTRE-X . affiche 319

 
MIN n1 n2 --- n1 ou n2 F83

Laisse sur la pile le plus petit de n1 ou n2.

 
BETWEEN n1 n2 n3 --- f  

Délivre un flag booléen vrai si n1 est compris entre n2 et n3, bornes comprises, c'est à dire si n2<=n1<=n3. A noter que si n2 est supérieur à n3, BETWEEN n'a plus de sens et le flag booléen est toujours faux. Exemple:

2 3 1 BETWEEN . affiche 0

 
WITHIN n1 min max --- f  

Renvoie un flag booléen vrai (f = -1) si min <= n1 < max.

D. Manipulation de pile 16 bits.

 
DUP n --- n n  

Duplique le nombre entier situé au sommet de la pile de données. Exemple:

: E2 ( n --- nE2)
DUP * ;
5 E2 . affiche 25
10 E2 . affiche 100

 
?DUP n --- n n si n<>0  

Duplique le nombre entier situé au sommet de la pile de données si sa valeur n'est pas nulle. Ce mot peut, pour exemple, être utilisé avant IF si la valeur n est utilisée à la fois comme drapeau logique et dans la structure de contrôle de type IF..THEN ou IF..ELSE..THEN. Exemple: pour éviter la division d'un nombre par zéro, on peut définir:

: DIV ( n1 n2 --- q)
?DUP IF / THEN ( n1=dividende, n2=diviseur) ;
22 7 DIV . affiche 3
22 0 DIV . affiche 22

alors que 22 0 / délivre 0, ce qui est une erreur.

 
OVER n1 n2 --- n1 n2 n1  

Duplique le second élément de la pile de données. Exemple:

3 5 OVER . . . affiche 3 5 3

 
PICK n1 n2..nx n --- n1 n2..nx nn F83

Met sur la pile de données le nième élément contenu dans la pile de données. Exemple:

22 25 28 34 27 3 PICK . affiche 25

L'opération 0 PICK est équivalente à DUP, 1 PICK à OVER. Attention: si vous avez travaillé avec d'anciennes versions du langage FORTH, notamment en 79-Standard, le mot PICK a comme base de départ 1 et non 0. Par conséquent, si vous adaptez des programmes écrits dans ce standard, il faudra systématiquement soustraire 1 unité au paramètre de pointage de donné traité par PICK.

 
DROP n --- F83

Enlève du sommet de la pile de données le nombre entier qui s'y trouvait.

 
NIP n1 n2 --- n2  

Supprime le second élément de la pile. Equivaut à la séquence SWAP DROP. Exemple:

2 3 5 NIP . . affiche 5 2

 
SWAP n1 n2 --- n2 n1 F83

Les deux valeurs situées au sommet de la pile de données sont permutées.

 
ROT n1 n2 n3 --- n2 n3 n1 F83

Effectue une opération de rotation sur les trois premiers éléments situés au sommet de la pile de données, mettant le troisième au sommet de la pile.

 
-ROT n1 n2 n3 --- n3 n1 n2  

Réalise une rotation inverse sur les trois nombres entiers situés au sommet de la pile de données. Le fonctionnement de ce mot est équivalent à la séquence ROT ROT.

 
ROLL n --- F83

La nième valeur de la pile, n non incluse, est mise au sommet de la pile de données. Les autres valeurs sont déplacées vers le bas. 2 ROLL est équivalent à ROT.

 
FLIP n1 --- n2  

Inverse les parties poids faible et poids fort de la valeur 16 bits déposée au sommet de la pile de données. Exemple:

HEX 3FC6 U. affiche C63F

 
TUCK n1 n2 --- n2 n1 n2  

Duplique le premier élément de la pile sous le second. Equivaut à la séquence SWAP OVER.

 
>R n --- F83

Transfère la valeur n du sommet de la pile de données vers le sommet de la pile de retour. Ce mot est utilisé notamment pour ranger temporairement certaines valeurs difficiles à manipuler autrement. Il faut cependant veiller à remettre la pile de retour dans son état initial à l'aide du mot R>, ceci avant de quitter une définition ou avant la fin d'une boucle de type DO..LOOP, DO..+LOOP. Exemple:

: TEST1 5 7 3 >R + R> . . ;

L'exécution de TEST1 affiche la somme de 5 et 7, c'est à dire 12 et le nombre 3.

: TEST2 5 7 3 >R + . . ;

plantera votre système lors de son exécution. De même:

: BOUCLE 5 0 DO >R LOOP R> ;

est également peu recommandé, plantage garanti.

 
R> --- n F83

Le nombre entier n est enlevé de la pile de retour pour être déposé sur la pile de données.

 
R@ --- n F83

Copie la valeur n située au sommet de la pile de retour sur le sommet de la pile de données. Son action est équivalente à la séquence R> DUP >R.

 
RP! adr ---  

Met le pointeur de pile de retour à la valeur spécifiée par le contenu du sommet de la pile de données.

 
RP@ --- adr  

Renvoie l'adresse de la prochaine entrée dans la pile de retour.

 
SP! adr ---  

Met le pointeur de pile à la valeur spécifiée par le contenu du sommet de la pile de données. Exemple:

SP@ 6 + SP!

incrémente le pointeur de pile de trois unités.

 
SP@ --- adr  

Renvoie l'adresse de la prochaine entrée dans la pile de données.

E. Opérateurs arithmetiques 32 bits signés.

 
D+ d1 d2 --- d3  

Le nombre double précision d3 est le résultat de la somme des deux nombres double précision d1 et d2, correspondant à l'opération algébrique d3=d1+d2.

 
D- d1 d2 --- d3  

Le nombre double précision d3 est le résultat de la différence des deux nombres double précision d2 par d1, correspondant à l'opération algébrique d3=d1-d2.

 
DABS d --- ud  

Renvoie sur la pile de données la valeur absolue d'un nombre double précision signé. Exemple:

 55. DABS D. affiche 55
-55. DABS D. affiche 55

 
DNEGATE +-d --- -+d  

Inverse le signe du nombre double précision signé d. Exemple:

 3. DNEGATE D. affiche -3
-3. DNEGATE D. affiche 3

 
?DNEGATE +-d --- -d  

Rend négatif le nombre double précision situé au sommet de la pile de données s'il ne l'est pas.

 
D2*    

Multiplie par 2 le sommet de la pile en double précision.Exemple:

55000. D2* D. affiche 110000

 
D2/ d --- d/2  

Divise le nombre double précision d par deux. Le résultat est un nombre double précision représentant le quotient de d/2, reste non compris. Exemple:

34. D2/ D. affiche 17
35. D2/ D. affiche aussi 17, il n'y a pas de reste

 
S>D n --- d  

 

Transforme un nombre simple précision signé en nombre double précision signé. Exemple:

3 S>D D. affiche 3
-7 S>D D. affiche -7

F. Opérateurs de comparaison 32 bits.

 
D0= d --- f  

Délivre un flag booléen vrai si le nombre double précision d est nul.

 
D< d1 d2 --- f  

Délivre un flag booléen vrai si le nombre double précision d1 est inférieur au nombre double précision d2. Exemple:

57. 105. D< . affiche -1 ( f=vrai)
105. 57. D< . affiche 0 ( f=faux)

 
D= d1 d2 --- f  

Délivre un flag booléen vrai si le nombre double précision d1 est égal au nombre double précision d2. Exemple:

35. 35. D= . affiche -1 ( f=vrai)
35. 36. D= . affiche 0 ( f=faux)

 
D>    

Délivre un flag booléen vrai si le nombre double précision d1 est supérieur au nombre double précision d2. Exemple:

57. 105. D< . affiche 0 ( f=faux)
105. 57. D< . affiche -1 ( f=vrai)

 
DMAX d1 d2 --- d1 | d2  

Laisse sur la pile le plus grand des deux nombres double précision signés d1 ou d2.

 
DMIN d1 d2 --- d1 | d2  

Laisse sur la pile le plus petit des deux nombres double précision signés d1 ou d2.

 
DU< ud1 ud2 --- fl  

Compare deux nombres double précision non signés.

G. Manipulations de pile 32 bits.

 
2DROP d ---  

Supprime les deux dernières cellules de la pile. Les mots manipulant les nombres double précision (32 bits) sont souvent utilisés pour des paires de nombres 16 bits. Ainsi, 2DROP équivaut à DROP DROP. Exemple:

1 2 3 2DROP . affiche 1

 
2DUP d --- d d  

Copie le nombre double précision situé au sommet de la pile de données. Equivaut à n1 n2 --- n1 n2 n1 n2.

 
2OVER d1 d2 --- d1 d2 d1  

Fait une copie de l'avant-dernière paire de cellules de la pile. Equivaut à n1 n2 n3 n4 --- n1 n2 n3 n4 n1 n2.

 
2ROT d1 d2 d3 --- d2 d3 d1  

Opère une rotation des trois dernières paires de cellules de la pile. Equivaut à n1 n2 n3 n4 n5 n6 --- n3 n4 n5 n6 n1 n2.

 
2SWAP d1 d2 --- d2 d1  

Permute les deux dernières paires de cellules de la pile. Equivaut à la manipulation de la pile n1 n2 n3 n4 --- n3 n4 n1 n2.

 
3DUP n1 n2 n3 --- n1 n2 n3 n1 n2 n3  

Fait une copie des trois dernières cellules de la pile.

 
4DUP n1 n2 n3 n4 --- n1 n2 n3 n4 n1 n2 n3 n4  

Fait une copie des quatre dernières cellules de la pile. Equivaut aussi à d1 d2 --- d1 d2 d1 d2.

H. Opérateurs arithmétiques mixtes.

 
*D n1 n2 --- d  

Multiplie deux nombres entiers, n1 et n2, et dépose le résultat d, qui est un nombre double précision (32 bits) sur la pile de données. Les valeurs n1 et n2 sont perdues. Les règles des signes appliquées à n1 et n2 sont identiques à celles du mot *.

 
M/MOD d n --- q r  

Division d'un nombre entier double précision d par un nombre entier simple précision n. Le quotient q et le reste r sont des entiers simple précision signés. Exemple:

100000. 25 M/MOD . . affiche 4000 0

 
MU/MOD d n1 --- nreste dquot  

Divise un nombre double précision par un nombre entier. Délivre un quotient en double précision et un reste entier.

 
U*D n1 n2 --- d  

Synonyme de UM*.

 
UM* u1 u2 --- ud  

Réalise le produit de deux nombres entiers u1 et u2 non signés. Le résultat est un nombre double précision non signé.

 
UM/MOD ud u1 -- u2 u3  

Correspond à la division primitive en FORTH. Ce mot réalise la division d'un nombre double précision non signé avec un nombre entier non signé. Le quotient u2 et le reste u3 sont des nombres entiers non signés.

 

 

-- hautdepage -- sommaire -- page d'accueil --