Previous Next Table of Contents

14. LISTES THEMATIQUES

14.1 Opérateurs de manipulation des piles

Comme tous les langages, le FORTH utilise des piles; dans la plupart des langages les piles ne sont pas "visibles" par le programmeur: deux piles sont généralement gérées par le compilateur (comme en PASCAL ou en FORTRAN) ou par l'interpréteur (comme en BASIC ou en LISP); l'une permet de sauvegarder les adresses de retour d'appel de sous-programmes, l'autre sert à passer les arguments des sous-programmes et à stocker les résultats intermédiaires des calculs. En FORTH, le programmeur gère explicitement la pile "calcul", et peut utiliser (prudemment) la pile "retour".

-ROT ( n3 n2 n1 -- n1 n3 n2 )

.S ( -- )

2DROP ( d -- )

2DUP ( d -- d d )

2OVER ( d2 d1 -- d2 d1 d2 )

2SWAP ( d2 d1 -- d1 d2 )

3DUP ( n3 n2 n1 -- n3 n2 n1 n3 n2 n1 )

>R ( n -- | == n )

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

DEPTH ( -- n )

DROP ( n -- )

DUP ( n -- n n )

NIP ( n2 n1 -- n1 )

OVER ( n2 n1 -- n2 n1 n2 )

PICK ( nx nx-1 .. n2 n1 n -- nx nx-1 .. n2 n1 nn | 2* SP@ + @ )

R ( -- n | n == n )

R0RP! ( -- | ... n1 == )

R> ( -- n | n == )

R@ ( -- n | n == n )

ROT ( n3 n2 n1 -- n2 n1 n3 )

RP! ( adr -- )

RP@ ( -- adr )

SP! ( adr -- )

SP@ ( -- adr )

SWAP ( n2 n1 -- n1 n2 )

TUCK ( n2 n1 -- n1 n2 n1 )

14.2 Opérateurs d'accès mémoire

FORTH travaille en standard sur des octets et des mots de 16 bits; ont été rajoutées les extensions courantes en 32 bits, et des primitives d'accès au niveau du bit, moins courantes, mais souvent utiles, soit pour accéder à des ports d'entrées-sorties, soit pour gérer des structures de données compactes (bitmaps par exemple).

Rappel: le 6502 stocke les adresses 16 bits avec l'octet de poids faible à l'adresse basse et l'octet de poids fort à l'adresse haute (+1); FORTH fait de même pour les valeurs 16 bits, et stocke les valeurs 32 bits avec le mot de poids fort à l'adresse basse et le mot de poids faible à l'adresse haute (+2), afin d'avoir la même organisation en mémoire que dans la pile (qui croit vers les adresses basses, avec le mot de poids fort au sommet de la pile).

Note: sur un Z80, les adresses sont stockées en sens inverse, c'est-à-dire l'octet de poids fort à l'adresse basse et l'octet de poids faible à l'adresse haute; évitez donc les "astuces" utilisant la convention particulière au 6502, pour assurer une bonne portabilité des programmes FORTH sur d'autres machines.

! ( n adr -- )

+! ( n adr -- )

2! ( d adr -- )

2@ ( adr -- d )

@ ( adr -- n )

BLANK ( adr cnt -- )

C! ( c adr -- )

C@ ( adr -- c )

CMOVE ( srceAdr destAdr byteCnt -- )

CMOVE> ( srceAdr destAdr byteCnt -- )

COUNT ( adr -- adr+1 cnt )

CRESET ( c adr -- )

CSET ( c adr -- )

CTOGGLE ( c adr -- )

ERASE ( adr cnt -- )

FILL ( adr cnt c -- )

FLIP ( n2 -- n1 )

MOVE ( srceAdr destAdr byteCnt -- )

14.3 Opérateurs logiques

Ils travaillent bit à bit sur des entiers 16 bits, soit pour des opérations de masquage, soit pour du calcul sur des valeurs logiques retournées par les opérateurs de comparaison (le travail utile se fait alors sur le bit de poids faible).

Pratique: la dualité entre le ET et le OU permet de simplifier certaines expressions logiques (donc d'améliorer leur lisibilité):

NON a ET NON b ( NOT SWAP NOT AND ) se simplifie en:

NON (a OU b) ( OR NOT ( a b -- f ));

NON a OU NON b ( NOT SWAP NOT OR ) se simplifie en:

NON (a ET b) ( AND NOT ( a b -- f )).

AND ( n2 n1 -- n )

FALSE ( -- 0 )

NOT ( n -- n' )

OFF ( adr -- )

ON ( adr -- )

OR ( n2 n1 -- n )

TRUE ( -- -1 )

XOR ( n2 n1 -- n )

14.4 Opérateurs de comparaison

Les valeurs logiques en FORTH sont représentées par des entiers 16 bits, de valeur nulle pour la valeur logique fausse, non nulle (normalement -1 en FORTH 83-STANDARD) pour la valeur logique vraie.

0< ( n -- b )

0<> ( n -- b )

0= ( n -- b )

0> ( n -- b )

< ( n2 n1 -- b )

<> ( n2 n1 -- b )

= ( n2 n1 -- b )

> ( n2 n1 -- b )

BETWEEN ( n3 n2 n1 -- b )

CAPS-COMP ( adr1 adr2 cnt -- n )

COMP ( adr1 adr2 cnt -- n )

COMPARE ( adr1 adr2 cnt -- n )

U< ( u2 u1 -- b )

U> ( u2 u1 -- b )

WITHIN ( n3 n2 n1 -- b )

14.5 Opérateurs arithmétiques

L'arithmétique FORTH de base se fait sur des entiers signés en complément à 2, de 16 bits avec certaines extensions en 32 bits. Cette arithmétique est largement suffisante dans la plupart des cas (calculs en entiers ou en virgule fixe), et présente l'avantage d'être simple et rapide; si des calculs plus sophistiqués sont nécessaires, on pourra avoir recours à une extension "calcul en virgule flottante".

* ( n2 n1 -- n | n = n2*n1 )

*/MOD ( n3 n2 n1 -- nR nQ | n3*n2 = n1*nQ+nR )

*D ( n2 n1 -- d | d = n2*n1 )

+ ( n2 n1 -- n | n = n2+n1 )

- ( n2 n1 -- n | n = n2-n1 )

/ ( n2 n1 -- nQ )

/* ( n3 n2 n1 -- nQ )

/MOD ( n2 n1 -- nR nQ | n2 = n1*nQ+nR )

0 ( -- 0 )

1 ( -- 1 )

1+ ( n -- n' | n' = n+1 )

1- ( n -- n' | n' = n-1 )

2 ( -- 2 )

2* ( n -- n' | n' = n*2 )

2+ ( n -- n' | n' = n+2 )

2- ( n -- n' | n' = n-2 )

2/ ( n -- n' | n' = n/2 )

3 ( -- 3 )

?DNEGATE ( d2 n -- d )

?NEGATE ( n2 n1 -- n )

ABS ( n -- n' )

BL ( -- 32 )

D+ ( d2 d1 -- d | d = d2+d1 )

DABS ( d -- d' )

DNEGATE ( d -- -d )

M/MOD ( d n -- nR nQ | d = n*nQ+nR )

MAX ( n2 n1 -- n )

MIN ( n2 n1 -- n )

MOD ( n2 n1 -- nR )

MU/MOD ( ud u -- uR udQ | ud = u*udQ+uR )

NEGATE ( n -- -n )

S>D ( n -- d )

U*D ( u2 u1 -- ud | ud = u2*u1 )

U2/ ( u -- u' | u' = u/2 )

UM* ( u2 u1 -- ud | ud = u2*u1 )

UM/MOD ( ud u -- uR uQ | ud = u*uQ+uR )

14.6 Opérateurs de chaînes

-TRAILING ( adr cnt -- adr cnt' )

/STRING ( adr1 cnt1 n -- adr2 cnt2 )

BOUNDS ( adr cnt -- adrfin adrdébut )

DELETE ( adr cnt1 cnt2 -- )

FOUND ( -- adr )

INSERT ( adr1 cnt1 adr2 cnt2 -- )

PLACE ( srceAdr cnt destAdr -- )

REPLACE ( adr1 cnt1 adr2 cnt2 -- )

SEARCH ( adr1 cnt1 adr2 cnt2 -- n b )

UPPER ( adr cnt -- )

14.7 Conversion numérique

FORTH sait lire et écrire les nombres dans n'importe quelle base numérique: il suffit de changer le contenu de la variable BASE; le signe d'invite affiche en permanence la base courante (et le nombre de valeurs dans la pile):

En lecture, un nombre peut contenir un signe négatif "-" initial, et/ou un point décimal, dont la position par rapport au dernier digit est mémorisée dans la variable DPL (par exemple 2 pour 1234.56); s'il n'y a pas de point décimal, DPL vaudra -1, et le nombre sera tronqué aux 16 bits de poids faible après conversion sur 32 bits (voir le mot INTERPRET).

En écriture, la chaîne résultat de la conversion est formée "à reculons" (pointeur HLD) dans un tampon, habituellement le "PAD" placé 80 octets après la fin du dictionnaire; les nombres 16 bits sont étendus sur 32 bits avant conversion.

# ( d -- d' )

#> ( d -- adr cnt )

#S ( d -- 0. )

(.) ( n -- adr cnt )

(D.) ( d -- adr cnt )

(NUMBER) ( adr -- d )

(U.) ( u -- adr cnt )

(UD.) ( ud -- adr cnt )

. ( n -- )

.R ( n c -- )

<# ( -- )

? ( adr -- )

D. ( d -- )

D.R ( d c -- )

DECIMAL ( -- )

DIGIT ( c base -- n b )

H. ( u -- )

HEX ( -- )

HOLD ( c -- )

NUMBER ( adr -- d )

NUMBER? ( adr -- d b )

PAD ( -- adr )

SIGN ( n -- )

U. ( u -- )

U.R ( u c -- )

UD. ( ud -- )

14.8 Conversion alphanumérique

(NUMBER?) ( adr -- d b )

CONVERT ( ud1 adr1 -- ud2 adr2 )

DOUBLE? ( -- b )

14.9 La machine virtuelle FORTH

FORTH est un des premiers langages à avoir utilisé le concept de "machine virtuelle". Une machine virtuelle, c'est un modèle de fonctionnement sans support physique immédiat; l'intérêt d'un tel concept est de pouvoir décrire le fonctionnement du langage en terme d'instructions de la machine virtuelle unique: vous pourrez constater à travers ce manuel que FORTH est en majorité défini en FORTH! Seules les "primitives" de base, proches des instructions communes à toutes les "machines réelles" (le 6502 pour l'ORIC), sont à implémenter en code machine. D'où la grande facilité de portage du FORTH et sa disponibilité sur un grand nombre de machines.

La machine virtuelle FORTH est constituée de 5 registres et d'une unité arithmétique et logique travaillant sur le sommet de la pile de données.

La machine virtuelle FORTH manipule principalement des adresses; si l'on considère les instructions de la machine réelle comme les micro-instructions de la machine virtuelle, alors chaque instruction de la machine virtuelle est traitée comme un pointeur à une structure mémoire dont le premier mot est l'adresse d'un micro-programme; pour cette raison, ce premier mot est appelé cfa ("Code Field Adress") car c'est un champ qui contient l'adresse du micro-code à exécuter; le mot suivant est appelé pfa ("Parameter Field Adress") car c'est là que sont stockés tous les paramètres de la structure.

Pratiquement, l'automate micro-programmé de la machine virtuelle (exécuté à la fin de chaque micro-programme) réalise les opérations suivantes:

  1. chargement de W avec l'instruction pointée par IP et incrémentation de IP ( W := (IP)+ );
  2. Chargement du pointeur de micro-instructions avec l'adresse pointée par W ( mip := (W) ).
Pour le 6502, IP, W et UP sont en mémoire en page 0, RP est dans le registre S (pointeur de pile 6502 en page 1), et SP est dans le registre d'index X.

EXECUTE ( cfa -- )

EXIT ( -- )

NOOP ( -- )

UNNEST ( -- )

14.10 L'interpréteur

On entend par là l'ensemble des mots qui lancent et font tourner la machine FORTH.

( -- )

(.VERSION) ( -- )

(ABORT) ( -- )

(COLD) ( -- )

(TERMINAL) ( -- )

.VERSION ( -- )

ABORT ( -- )

BOOT ( -- )

CAPS ( -- adr )

COLD ( -- )

DONE? ( n -- b )

EXPECT ( adr cnt -- )

HELLO ( -- )

INTERPRET ( -- )

OK ( -- )

PROMPT ( -- )

QUERY ( -- )

QUIT ( -- )

RUN ( -- )

STATUS ( -- )

TERMINAL ( -- )

VERSION ( -- adr cnt )

WARM ( -- )

14.11 Les variables USER

Elles sont utilisées par l'interprète; voir le mot USER.

#LINE ( -- adr )

#OUT ( -- adr )

#TIB ( -- adr )

(NTOP) ( -- adr )

(UAREA) ( -- adr )

>IN ( -- adr )

BASE ( -- adr )

BLK ( -- adr )

BNK ( -- adr )

CONTEXT ( -- adr )

CSP ( -- adr )

CURRENT ( -- adr )

DP ( -- adr )

DPL ( -- adr )

END? ( -- adr )

FENCE ( -- adr )

FLD ( -- adr )

HLD ( -- adr )

LAST ( -- adr )

OFFSET ( -- adr )

PRIOR ( -- adr )

R# ( -- adr )

R0 ( -- adr )

S0 ( -- adr )

SCR ( -- adr )

SPAN ( -- adr )

STATE ( -- adr )

VOC-LINK ( -- adr )

WARNING ( -- adr )

WIDTH ( -- adr )

14.12 La gestion du dictionnaire

La variable DP pointe à la fin du dictionnaire, où seront ajoutées les nouvelles définitions. La variable CURRENT pointe sur le vocabulaire auquel seront liées les nouvelles définitions. La variable CONTEXT pointe sur la pile des vocabulaires à partir desquels démarrera toute recherche; si la recherche échoue dans les vocabulaires pointés par CONTEXT, elle est poursuivie à partir du vocabulaire pointé par CURRENT; si la recherche échoue encore, l'interprète tente une conversion numérique dans la base courante; si la conversion échoue, l'interprète génère une erreur "inconnu dans ce contexte".

!CSP ( -- )

" <chaîne de caractères" ( -- adr cnt )

#VOCS ( -- 5 )

' <mot> ( -- cfa )

(") ( -- adr cnt )

(;CODE) ( -- )

(;USES) ( -- )

(FIND) ( adr lfa -- cfa b )

(FORGET) ( adr -- )

(IS) ( cfa -- )

, ( n -- )

," ( -- )

2CONSTANT <mot> ( d -- | -- d )

2VARIABLE <mot> ( -- | -- adr )

: <mot> ( -- )

; ( -- )

;CODE ( -- )

;USES ( -- )

>BODY ( cfa -- pfa )

>LINK ( cfa -- lfa )

>NAME ( cfa -- nfa )

?CSP ( -- )

ALLOT ( n -- )

ALSO ( -- )

ASSEMBLER ( -- )

AVOC ( -- adr )

BODY> ( pfa -- cfa )

C, ( c adr -- )

CLIT ( -- c )

CODE <mot> ( -- )

COMPILE <mot> ( -- )

CONSTANT <mot> ( n -- | -- n )

CREATE <mot> ( -- )

DEFER <mot> ( -- )

DEFINED <mot> ( -- cfa b )

DEFINITIONS ( -- )

DLITERAL ( d -- )

DOES> ( -- | -- pfa )

FIND ( adr -- cfa b )

FORBID <mot> ( -- )

FORGET <mot> ( -- )

FORTH ( -- )

HASH ( adr1 adr2 -- n )

HEADER <mot> ( -- )

HERE ( -- adr )

HIDE ( -- )

ID. ( nfa -- )

IMMEDIATE ( -- )

IS <mot> ( cfa -- )

L>NAME ( lfa -- nfa )

LARGEST ( adr1 n1 -- adr2 n2 )

LINK> ( lfa -- cfa )

LIT ( -- n )

LITERAL ( n -- )

N>LINK ( nfa -- lfa )

NAME> ( nfa -- cfa )

ONLY ( -- )

ORDER ( -- )

PREVIOUS ( -- )

REVEAL ( -- )

SEAL ( -- )

TRAVERSE ( adr direction -- adr' )

TRIM ( adr1 adr2 -- )

USER <mot> ( n -- | -- adr )

VARIABLE <mot> ( -- | -- adr )

VOCABULARY <mot> ( -- )

VOCS ( -- )

WORDS ( -- )

[ ( -- )

['] <mot> ( -- cfa )

[COMPILE] <mot> ( -- )

] ( -- )

14.13 Les structures de contrôle

FORTH est un langage structuré: le programmeur ignore les GOTO, c'est le compilateur qui les calcule à partir des structures de contrôle.

FORTH supporte en standard les structures de contrôle suivantes:

FORTH est un des rares langages qui permette au programmeur de définir ses propres structures de contrôle.

(+LOOP) ( n -- )

(?DO) ( fin+1 ini -- )

(DO) ( fin+1 ini -- )

(LOOP) ( -- )

+LOOP ( n -- )

<MARK ( -- adr )

<RESOLVE ( adr -- )

>MARK ( -- adr )

>RESOLVE ( adr -- )

?BRANCH ( b -- )

?DO ( n2 n1 -- )

?LEAVE ( b -- )

AGAIN ( -- )

BEGIN ( -- )

BRANCH ( -- )

DO ( n2 n1 -- )

ELSE ( -- )

I ( -- index )

IF ( b -- )

LEAVE ( -- )

LOOP ( -- )

REPEAT ( -- )

THEN ( -- )

UNTIL ( b -- )

WHILE ( b -- )

14.14 Gestion des erreurs

(?ERROR) ( adr cnt b -- )

(ABORT") ( b -- )

?COMP ( -- )

?ENOUGH ( n -- )

?ERROR ( adr cnt b -- )

?EXEC ( -- )

?LOADING ( -- )

?MISSING ( b -- )

?PAIRS ( n2 n1 -- )

?RANGE ( n3 n2 n1 -- )

?STACK ( -- )

ABORT" <chaîne de caractères>" ( b -- )

CRASH ( -- )

DISK-ERR? ( b -- )

14.15 Les entrées-sorties

( ( -- )

(.") ( -- )

(?KEY) ( -- b )

(CHAR) ( adr n c -- adr n+1 )

(CR) ( -- )

(EMIT) ( c -- )

(KBD) ( n -- )

(KEY) ( -- c )

(SOURCE) ( -- adr cnt )

." <chaîne de caractères>" ( -- )

.( <chaîne de caractères>) ( -- )

?KEY ( -- b )

?STOP ( -- b )

A-IN ( adr n1 -- adr n2 )

ACCENT ( -- )

ASCII <caractère> ( -- c )

AT ( Xcolonne Yligne -- )

AZERTY ( -- )

BANK ( n -- )

BASIC ( -- )

BIOS ( fun -- )

BS-IN ( -- )

BYE ( -- )

C-IN ( -- )

CALL ( adr -- )

CAP-IN ( -- )

CHAR ( adr n c -- adr n+1 )

CLCH ( ch io -- )

CLEAR ( scr -- )

CLL-IN ( -- )

CLS ( -- )

CONTROL <lettre majuscule> ( -- )

CR ( -- )

CR-IN ( n adr c -- n adr n )

CTRL ( -- adr )

CTRL1 ( -- adr )

CURSOR ( -- )

DEL-IN ( n c -- n' | n' = 0 ou n-1 )

DOWN-IN ( -- )

DUMP ( adr -- )

EMIT ( c -- )

FW-IN ( -- )

HOME ( -- )

INK ( couleur -- )

KCLK ( -- )

KEY ( -- c )

LINE ( lig -- adr cnt )

LOCK ( -- )

OPCH ( ch io -- )

PAPER ( couleur -- )

PARSE ( c -- adr cnt )

PARSE-WORD ( c -- adr cnt )

QWERTY ( -- )

RAM/ROM ( -- )

SCAN ( adr1 cnt1 c -- adr2 cnt2 )

SKIP ( adr1 cnt1 c -- adr2 cnt2 )

SOURCE ( -- adr cnt )

SPACE ( -- )

SPACES ( n -- )

STATLINE ( -- #BB80 )

TIB ( -- #100 )

TYPE ( adr cnt -- )

UP-IN ( -- )

WHERE ( adr n -- )

WORD ( c -- adr )

X-IN ( adr n -- adr 0 )

14.16 STRATSED/SEDORIC : le DOS

#BUFFERS ( -- 8 )

(.FILE) ( -- )

(COPY) ( srce dest -- )

(DEFAULT) ( -- )

(FROM) ( -- )

(LOAD) ( scr -- )

(TO) ( -- )

--> ( -- )

.DRV ( -- )

.FILE ( -- )

.NAME ( -- )

>BUFFERS ( -- adr )

>END ( -- adr )

>SIZE ( -- 74 )

?DOS ( -- )

?FILE <mot> ( -- b )

?VALID ( b -- )

?WILDCARDS ( -- b )

ABSENT? ( n -- adr b )

B/BUF ( -- 1024 )

B/FCB ( -- 20 )

BDOS ( fun -- b )

BLOCK ( n -- adr )

BUFFER ( n -- adr )

BUFFER# ( n -- adr )

C/L ( -- 64 )

CAPACITY ( -- adr )

CAT ( -- )

COPY ( srce dest -- )

CREATE-FILE <mot> ( n -- )

DEFAULT ( -- )

DIR ( -- )

DISCARD ( -- )

DOS ( -- )

DOS-FILE ( -- )

DRV ( drv -- )

DRV? ( -- drv )

EMPTY-BUFFERS ( -- )

EXT ( -- adr 3 )

EXT: <mot> ( -- )

FCB ( -- adr )

FCB1 ( -- adr )

FILE ( -- adr )

FILE! ( -- )

FILE-READ ( adr -- )

FILE-WRITE ( adr -- )

FILENAME <mot> ( -- )

FIRST ( -- #7800 )

FLUSH ( -- )

INDEX ( prem dern -- )

LATEST? ( n -- n /-- adr b )

LIMIT ( -- #9800 )

LIST ( scr -- )

LOAD ( scr -- )

MISSING ( -- )

NAME! ( adr cnt -- )

OPEN <mot> ( -- )

OPEN-FILE ( -- )

RD# ( piste secteur adr -- 8 )

RDBLOCK ( adr -- )

RDM-FILE ( -- )

READ-BLOCK ( adr -- )

RECORD# ( n -- piste secteur )

RESERVE ( -- 150 )

S/T ( -- 16 )

SAVE-BUFFERS ( -- )

SEARCH ( -- b )

SEARCH- ( -- b )

TAKE <mot> ( -- )

THRU ( scr1 scrn -- )

UPDATE ( -- )

WR# ( piste secteur adr -- b )

WRBLOCK( adr -- )

WRITE-BLOCK ( adr -- )

XLOAD ( vsalo0 -- )

XNFA ( adr1 cnt1 adr2 cnt2 -- )

XSAVE ( org fin ftype -- )

caractère backslash <chaîne de caractères> ( -- )


Previous Next Table of Contents