			La cr‚ation de nouveaux mots
			****************************

1 Les mots et le dictionnaire
*****************************

	Un programme FORTH peut ˆtre d‚compos‚ en plusieurs sous-tƒches,
chacune recevant un nom. Lorsque ce nouveau mot est cr‚‚ il est utilis‚
comme un mot standard, il prend ses paramŠtres sur la pile et y renvoit les
r‚sultats. Il peut aussi se servir de variables, c'est au choix, ou n'avoir aucun
paramŠtre.
	La d‚finition de chaque mot est rang‚e dans le dictionnaire, comme
une variable. Le dictionnaire est une pile de type LIFO (dernier arriv‚,
premier sorti) au fonctionnement primaire. C'est … dire qu'un mot cr‚‚ ne
peut utiliser que ceux d‚j… cr‚‚s avant lui (ou lui mˆme, le FORTH est
r‚cursif). DeuxiŠme effet, lorsqu'un mot est effac‚, le FORTH est oblig‚
d'effacer tous les mots cr‚‚s aprŠs lui ‚galement.
	Il existe n‚anmoins une maniŠre (peu jolie, mais … quoi bon?) de faire
des appels "en avant" vers des mots pas encore cr‚‚s.
	Lorsqu'il est cr‚‚, un mot re‡oit un code FORTH (c'est son num‚ro
d'ordre dans la suite des mots cr‚‚s), ce code sera utile … certaines fonctions
mais est surtout indipensable … l'interpr‚teur.

:  ...  ;
---------
	: XXX ... ;	ceci cr‚‚ un nouveau mot XXX, sa d‚finition correspond
… tout ce qui se trouve entre XXX et ;. Par exemple, voici un mot qui
additionne 65 au sommet de la pile:
	: plus65
		65 +
	;
	Donc:
	15 plus65 .		\ affiche 80 (65+15)

::  .... ;
----------
	:: XXX ... ;	Mˆme principe que la paire pr‚c‚dente, sauf qu'…
l'ex‚cution ce mot sera plus rapide.

	Lorsque le texte d'une d‚finition est envoy‚ … l'interpr‚teur, celui-ci
remplace chaque mot FORTH par son code (sur 2 octets). Lors de l'ex‚cution,
l'interpr‚teur lit un … un les codes et saute … la routine assembleur (pour les mots
standards) ou … une autre d‚finition (pour les mots de l'utilisateur). Pour acc‚l‚rer
ce processus, on peut tout simplement remplacer la suite des codes par les routines
assembleur elles mˆmes ‚vitant ainsi le cycle lecture-code/recherche de
l'adresse/saut au sous-programme. C'est ce que fait :: ; am‚liorant ainsi la paire : ;.
Mais alors pourquoi utiliser encore : ;? PremiŠrement parceque tous les mots ne
sont pas utilisables dans l'autre mode, ensuite pour des questions de taille
m‚moire. Avec : ; (mode interpr‚t‚) chaque mot n'utilise que 2 octets, avec :: ;
(mode compil‚ ou assembl‚) chaque mot est une routine assembleur qui excŠde
bien souvent 2 octets, et parfois la vitesse d'un mot est sans infuence. Imaginons
par exemple un mot qui attend une frappe au clavier.

	Voici les rŠgles … retenir:
	Un mot interpr‚t‚ peut faire appel … n'importe quel autre mot.
	Un mot compil‚ (ou assembl‚) ne peut faire appel qu'… des mots standards
ou d'autres mots compil‚s (les variables sont consid‚r‚es comme compil‚es).

find
----
	find XXX : ramŠne sur la pile le code FORTH du mot XXX.

adress
------
	est un tableau de type array. Chaque ‚l‚ment contient l'adresse d'un
mot FORTH (rang‚s dans l'ordre de leurs codes). Exemples:
	122 adress ?		\ affiche l'adresse du mot de code 122 (system)
	%hE00000 122 adress !
				\ modifie l'adresse du mot system, il pointe sur le
d‚but du systŠme et lancera donc un magnifique RESET … sa prochaine
ex‚cution.
	find if adress ?	\ affiche l'adresse du mot "if".

	Pour les mots standards, l'adresse pointe directement sur une routine
assembleur. Pour un mot utilisateur, le premier code sur 2 octets peut indiquer son
type:
	140	: variable (variable, &float, &setof, &pointer, &name, &stack)
	141	: constant
	142	: array
	143	: string
	144	: array$
	145	: table
	437	: mot compil‚ (::  ...   ;), le reste est la routine assembleur
	628	: ‚l‚ment d'un ensemble ‚num‚r‚ (&)
	706	: warray
	Autre	: c'est le premier code de la d‚finition d'un mot interpr‚t‚.

forget
------
	forget XXX : efface du dictionnaire le mot XXX et tous ceux cr‚‚s aprŠs
lui. LibŠre ainsi la place pr‚c‚demment occup‚e. Utilis‚ sur un mot standard,
la stabilit‚ de l'interpr‚teur n'est plus assur‚e.
	Par exemple forget system, ne permet plus de quitter proprement
l'interpr‚teur.

vlist
-----
	affiche la liste de tous les mots cr‚‚s par l'utilisateur.

word$
-----
	c  word$  :  envoit dans pad la chaine de caractŠres correspondant au
mot de code c, l'adresse pad est laiss‚e sur la pile. Ceci s'avŠre utile en
liaison avec les ‚l‚ments d'un ensemble ‚num‚r‚.
	Autre exemple:
	500 0 do i word$ type space loop
	Affiche le nom de tous les mots FORTH jusqu'au code 499.

fast  slow
----------
	Dans le mode slow, on peut arrˆter l'ex‚cution de mots interpr‚t‚s …
l'aide de la combinaison Control+Alternate+Les deux shift. Le d‚passement
inf‚rieur de pile est aussi r‚alis‚ (interdiction de d‚piler plus qu'on avait
empil‚). Si un arrˆt est demand‚, l'interpr‚teur d‚pose sur la pile l'adresse
de son pointeur d'ex‚cution (qui pointe sur le code de l'instruction qu'il allait
ex‚cuter).
	Dans le mode fast, ces possibilit‚s n'existent pas, mais on y gagne en
rapidit‚. Le mode fast est le mode par d‚faut.

exec
----
	c  exec  :  ex‚cute le mot de code c. Deux utilisations possibles pour ce
mot, d'abord l'‚quivalent d'un ON .... GOSUB du Basic:
	table CODES
	find sub0 ,
	find sub1 ,
	find sub2 ,	\ cr‚e une table avec les codes de 3 routines

	input		\ l'utilisateur tape 0, 1 ou 2
	CODES 	\ ramŠne le code correspondant
	exec		\ ex‚cute sub1, 2 ou 3.

	DeuxiŠme utilisation, l'appel en avant d'un mot pas encore cr‚‚:
	variable CODE		\ contiendra le code

	: essai CODE @ exec ;	\ ex‚cutera le mot point‚ par CODE

	: coucou ." COUCOU!" ;	\ le deuxiŠme mot

	find coucou CODE !		\ CODE pointera sur coucou

	essai				\ ex‚cutera le mot coucou cr‚‚ aprŠs lui.

exe+
----
	n exe+  :  ex‚cute le mot dont le code est ‚gal … celui du mot courant
plus n. Par exemple si n=1, ex‚cutera le mot suivant.
	: essai 1 exe+ 2 exe+ ;	\ ex‚cutera les deux mots qui suivent.
	: coucou ." Cou" ;
	: coucou2 ." cou!" ;
	essai			\ affiche Coucou!

2 Utilisation de l'‚diteur
**************************

	Pour faciliter la mise au point d'un programme un ‚diteur est int‚gr‚ dans
l'interpr‚teur (on peut n‚anmoins taper toutes ses instructions en mode direct … la
suite de Ok>). La taille du texte ‚ditable est fix‚e par le fichier FORTH.INF, ou, …
d‚faut, au 1/6 de la m‚moire libre.

edit
----
	passe sous l'‚diteur. La fenˆtre est coup‚e en deux parties. En haut
une ligne indique la taille m‚moire restant pour le texte du programme ainsi
que le num‚ro de la ligne sous le curseur (commence … 0). En bas, c'est le
texte du programme qui est affich‚.
	Chaque ligne peut contenir jusqu'… 80 caractŠres. Si la largeur de la
fenˆtre est insuffisante, un scrolling horizontal se fera pour acc‚der … toute
la ligne.
	Touches actives sous l'‚diteur:
	F1	: d‚but du texte
	F2	: demi ‚cran vers le haut
	F3	: marque le d‚but du bloc
	F4	: marque la fin du bloc
	F5	: annule le marquage du bloc
	F6	: aller … la ligne... (utilise la ligne d'informations)
	F7	: chercher une chaine (utilise la ligne d'informations)
	F8	: chercher encore
	F9	: demi-‚cran vers le bas
	F10	: fin du texte

	Shift F5	: effacer bloc
	Shift F6	: d‚placer bloc avant la ligne sous le curseur.
	Shift F7	: copier bloc avant la ligne sous le curseur.

	La fonction de recherche de texte ne d‚tecte qu'une occurence de la
chaine par ligne.
	Le marquage du bloc s'effectue par num‚ros de lignes. De ce fait, si
une ligne est ins‚r‚e avant le bloc, les lignes marqu‚es ne sont plus les
mˆmes. Le mieux est de marquer le bloc puis d'effectuer imm‚diatement la
fonction de bloc associ‚e. Les focntions de bloc sont irr‚m‚diables, pas de
UNDO pr‚vu.

	flŠches	: haut, bas, droite, gauche.
	Shift Gauche	: fin de ligne
	Shift Droit	: d‚but de ligne
	Enter		: fin de ligne et cr‚ation d'une nouvelle (coupure de
l'ancienne ligne au niveau du curseur)
	Undo		: annule les modifications de la ligne courante.
	Backspace	: efface en reculant
	Delete	: efface sous le curseur
	Contrl Del	: efface la ligne courante
	Tab		: avance de 3 positions vers la droite
	Shift Haut	: demi-‚cran vers le haut, ‚quivalent de F2.
	Shift Bas	: demi-‚cran vers le bas, ‚quivalent de F9.

	L'identation est automatique.

	Esc		: quitte l'‚diteur. S'affiche alors un message indiquant si
il reste un bloc marqu‚ ou non, car les fonctions saveb, writeb sont limit‚es
au bloc si il existe.


writeb
------
	imprime le bloc s‚lectionn‚ (si il existe) ou tout le texte.

saveb
-----
	sauve le bloc s‚lectionn‚ (si il existe) ou tout le texte. Le s‚lecteur de
fichier est ouvert, il suffit d'entrer le nom d‚sir‚. Si un fichier du mˆme nom
existe d‚j…, son contenu est remplac‚ par celui de l'‚diteur.

export
------
	comme saveb, sauf qu'il est envoy‚ au format ASCII simple (pourra
ˆtre retrait‚ par un autre traitement de textes). Efface pads (voir ensembles).

append
------
	mˆme principe que saveb, sauf que si le fichier existe d‚j…, le contenu
de l'‚diteur est ajout‚ … l'ancien contenu.

loadb
-----
	charge un fichier dans l'‚diteur par l'interm‚diaire du s‚lecteur de
fichier. Si un texte est d‚j… pr‚sent, alors le fichier est ajout‚ … la suite de ce
texte.

import
------
	comme loadb, sauf que le fichier est au format ASCII simple et sera
recod‚ avant sa copie dans l'‚diteur. Efface pads (voir ensembles).

select+
select-
-------
	d‚terminent le mode de fonctionnement des mots loadb, saveb et
append. En mode select+ (par d‚faut), le selecteur de fichier est ouvert. En
mode select-, une chaine contenant le chemin complet d'accŠs est attendue
sur la pile, par exemple:
	" D:\FORTH\TEST.FOR" saveb

compilb
-------
	envoit le bloc s‚lectionn‚ (si il existe) ou tout le texte … l'interpr‚teur.
Les parties ex‚cutables sont ex‚cut‚es, les d‚finitions de mots sont rang‚es
dans le dictionnaire. Si une erreur est d‚tect‚e elle est signal‚e et l'ex‚cution
de edit amŠnera le curseur sur la ligne fautive.

>comp
-----
	l'utilisation de ce mot est r‚serv‚e … l'int‚rieur de l'‚diteur. Comme
expliqu‚ pr‚c‚demment, le FORTH lit d'abord un texte, le code, puis
l'ex‚cute. De ce fait, il utilise un buffer d'ex‚cution dans lequel il entrepose
en premiŠre lecture les codes des instructions. Ce buffer est limit‚ et il arrive
qu'il se remplisse. Si le FORTH signale cette erreur, il suffit de couper la
partie ex‚cutable par un >comp qui enverra en plusieurs parties les donn‚es
… l'interpr‚teur.
	>comp ne peut pas se trouver au milieu d'une boucle ou de toute
autre structure de contr“le (if, case, etc...). De ce fait, les parties ex‚cutables
inscrites dans une boucle (ou autre) sont limit‚es en taille. Attention, ceci
n'affecte pas les d‚finitions des instructions (entre : et ;, ou :: et ;) puisque le
buffer d'ex‚cution n'est pas utilis‚, tout est directement envoy‚ dans le
dictionnaire.
	>comp est ‚galement utilis‚ en liaison avec >export (voir le
pr‚-processeur).

eval
----
	ce mot se comporte comme compilb sauf qu'au lieu d'aller chercher le
texte dans l'‚diteur, il le prend dans une chaine.
	" chaine" eval		: interprŠte la chaine comme une suite de
commandes FORTH, ex‚cute ce qui doit l'ˆtre et range les d‚finitions
rencontr‚e dans le dictionnaire. On peut ainsi r‚aliser un interpr‚teur
FORTH en FORTH:
	begin
		." Ok>" input$ eval
	again
	Cette boucle r‚alise le mˆme travail que le mode direct de
l'interpr‚teur. La chaine peut elle mˆme contenir la fonction eval. A chaque
niveau une nouvelle couche de l'interpr‚teur est cr‚‚.

lmax
----
	variable sur 2 octets contenant le num‚ro de la derniŠre ligne de
l'‚diteur. Modifier cette variable est un peu dangereux si on ne conait pas le
codage des lignes de l'‚diteur.

bstart   bsize
--------------
	Ces deux variables sur deux octets chacune contiennent
respectivement le num‚ro de la premiŠre ligne du bloc et le nombre-1 de
lignes du bloc. Si bstart=-1 (ou 65535) aucun bloc n'est d‚fini. Si le bloc est
d‚fini et que bsize=-1 (ou 65535), le bloc s'‚tend jusqu'… la fin du texte.
	10 bstart w!
	5   bsize w!		\ marque manuellement un bloc commen‡ant …
la ligne 10 et long de 6 lignes.
	writeb			\ imprime ces 6 lignes.

buf0   buf
----------
	buf0 est une constante contenant l'adresse de d‚part du texte dans
l'‚diteur. Buf est une variable (4 octets) contenant l'adresse de la fin du texte
dans l'‚diteur.
	buf @ buf0 - .	\ affiche la taille du texte dans l'‚diteur.

buf!
----
	vide le texte de l'‚diteur.

	Dans l'‚diteur les lignes sont cod‚es ainsi:
	2 octets	: offset pour la prochaine ligne ou 0 si derniŠre ligne
	1 octet		: 1+nombre d'espaces en d‚but de ligne
	ensuite vient le texte de la ligne compl‚t‚ ‚ventuellement par un espace pour
que la ligne suivante commence … une adresse paire.