	FORTH: le type ENSEMBLE et les MENUS
	************************************

	En moins d'un mois, aprs la parution du ST Mag 121, vous avez t
une trentaine  me demander par courrier l'interprteur/compilateur FORTH
et ce, jusqu'en Belgique. Je continue donc avec entrain cette srie sur ce
langage  part.

CAHIER DES CHARGES
******************

	Le petit programme que je vais vous proposer a pour but de montrer
la mise en place et l'utilisation d'un menu et de montrer l'extrme
facilit d'utilisation du type ENSEMBLE en FORTH (une facilit existant
dans le Pascal par exemple).
	Le programme permet, dans l'intervalle [0,1000] d'ajouter ou
d'enlever les multiples d'un nombre donn puis de compter les lments de
cet ensemble.
	Il permettrait par exemple de rpondre  "Combien y-a-t-il
d'entiers multiples de 5 ou de 17 et impairs  la fois entre 0 et 1000?".

	Pour taper le programme, faire "edit" suivi de [RETURN]. A la fin
de l'dition, un [Esc] permet de revenir  l'interprteur et saveb
permettra de sauver le source.

LES VARIABLES
*************

	Elles sont peu nombreuses comme toujours en FORTH. D'ailleurs, la
pile aurait-pu facilement tre utilise pour viter "x" et la fin du dicco
pour viter "BUFFER". Mais je les ai laisses par souci de clart. "x"
sert d'incrment lors de l'ajout/suppression des multiples d'un nombre.
"BUFFER" est la zone de 16 octets utilise par le GEM pour les messages.
"ENTIERS" est mon ensemble de 0  1000. "MENU" est un tableau des chaines
reprsentant le menu.

variable x
16 allot constant BUFFER
1000 0 &segment ENTIERS
30 12 array$ MENU

>comp

LA CREATION DU MENU
*******************

	Pour crer le menu, on donne d'abord les noms des titres puis,
menu par menu, les noms des options. Tous ces blocs sont spars par une
chaine vide. Les chaines ncessaires aux accessoires sont automatiquement
ajoutes par le FORTH.

"  Bureau "                      0 MENU $!
"  Fichier "                     1 MENU $!
" "                              2 MENU $!
"  A propos de... "              3 MENU $!
" "                              4 MENU $!
"  Remise  zro "               5 MENU $!
"  Ajouter les multiples de... " 6 MENU $!
"  Enlever les multiples de... " 7 MENU $!
"  Compter les lments "        8 MENU $!
" -----------------------------" 9 MENU $!
"  Quitter                     " 10 MENU $!
" "                              11 MENU $!

	Ensuite, la fonction "menu" reoit comme paramtre l'adresse de la
premire chaine (0 MENU) et renvoit l'adresse de l'arbre GEM correspondant
qu'on stocke immdiatement dans une constante MON_MENU:

0 MENU menu constant MON_MENU

	La chaine 9 correspond  une entre non selectionnable, c'est un
sparateur. "gemindex" me permet de connaitre l'index GEM de la chaine 9
que je transmet  "menu_ienable" pour la rendre "non slectionnable":

9 gemindex 0 MON_MENU menu_ienable

>comp

LE TRAITEMENT DES ENSEMBLES
***************************

	Voil finalement la liste des mots, ou sous-programmes, qui vont
ragir  chaque entre du menu. Le mot "info" se contente d'afficher une
bote d'alerte:

: info
   1 v_show_c
   1 " [1][ Dmo FORTH | Ensembles et Menus | G.Tello ][Confirmer]"
   form_alert
   v_hide_c
;

	Le mot "init" vide notre ensemble de tous ses lments. Grce 
"initset" l'ensemble par dfaut (pads) prend la structure de ENTIERS,
ensuite "set!" copie cette structure vide dans ENTIERS:

: init
   ENTIERS initset
   pads ENTIERS set!
;

	Le mot "ajouter" attend un nombre entre 1 et 1000 et le range dans
la variable "x". Si il n'est pas dans l'intervalle voulu, <seg> sera faux
et la demande sera ritre. Ensuite,  partir de 0 et sans atteindre
1001, les multiples de "x" sont ajouts  l'ensemble, ceci est assur par
"+loop" qui utilise x comme incrment:

: ajouter

   begin
      cr ." Nombre (1-1000):" input
      x !
      x @ 1 1000 <seg>
   until

   1001 0 do
      i ENTIERS elmt+
      x @
   +loop
;

	Le mot "enlever" est identique  "ajouter" sauf que la fonction
"elmt-" se substitue  "elmt+":

: enlever
   begin
      cr ." Nombre (1-1000):" input
      x !
      x @ 1 1000 <seg>
   until

   1001 0 do
      i ENTIERS elmt-
      x @
   +loop
;

	Le mot "compter" est des plus simples puisqu'il fait appel  la
fonction "card" qui renvoit le nombre d'lements d'un ensemble:

: compter
   cr
   ." L'ensemble contient "
   ENTIERS card .
   ."  lments."
;

LA BOUCLE GEM PRINCIPALE
************************

	Le mot principal s'appelle "main", ce n'est en aucun cas une
obligation, c'est juste une habitude. On commence par ouvrir la fentre
FORTH avec "fastopen" puis on vide l'ensemble avec "init", enfin "setmenu"
fixe MON_MENU comme menu courant. Cette dernire opration est inutile
dans le cas o un seul menu est utilis.
	La boucle "evnt_mesag" attend l'vnement "10", c'est  dire la
slection d'une entre du menu. Dans ce cas on rcupre en BUFFER+6
l'index GEM du titre que je remets en vido normale avec "menu_tnormal".
Puis en BUFFER+8 je rcupre l'index GEM de l'entre du menu que je
convertis tout de suite en index de chaine avec "strindex". En effet, il
m'est plus facile d'utiliser l'ordre de mon tableau de chaines plutt que
de prvoir les indexs internes des objets GEM.
	La structure "case/endcase" me permet de ragir  chaque option
possible par l'appel du mot qui convient. Avant chaque "endof" je dpose
sur la pile un 0 ou un 1: "0" si le programme doit continuer, 1 si il doit
s'arrter: en effet, la prsence du "until" final force le bouclage tant
qu'il y a zro sur la pile.

: main
   fastopen drop
   init
   MON_MENU setmenu
   begin
      1 MON_MENU menu_bar
      1 v_show_c
      begin
         BUFFER evnt_mesag
         BUFFER w@ 10 =
      until
      v_hide_c
      BUFFER 6 + w@
      1 MON_MENU menu_tnormal
      BUFFER 8 + w@
      strindex
      case
         3 of info 0 endof
         5 of init 0 endof
         6 of ajouter 0 endof
         7 of enlever 0 endof
         8 of compter 0 endof
         10 of 1 endof
         drop 0
      endcase
   until
   0 MON_MENU menu_bar
;

	(Bien valider cette dernire ligne par [RETURN] pour qu'elle soit
prise en compte lors de la compilation).

UTILISATION
***********

	Nous pouvons maintenant rpondre  la question du dpart. Aprs la
sauvegarde du source, tapez "compilb" suivi de [RETURN] et vrifiez avec
"vlist" que tous les mots sont bien crs (x BUFFER ..... main).

	Lancer le programme avec "main" et choisissez "Ajouter..." avec le
nombre 5. Demandez de compter, il y a 201 lments. Allez encore dans
"Ajouter..." avec 17 et puis "Compter" vous donne 248 lements. Pour finir
allez dans "Enlever..." avec 2. Nous avons maintenant tous les nombres
multiples de 5 ou de 17 mais qui ne sont pas pairs. Demandez de compter,
le rsultat devrait tre: 123.

CONCLUSION
**********

	J'espre vous avoir montr:
	- l'conomie de variables (4 en tout!)
	- la concision des programmes
	- la facilit de mise en oeuvre des fentres et menus
	- la puissance du type ENSEMBLE

	Vous pouvez encore me demander cette version du FORTH, je vous
l'envoie avec plaisir contre une disquette et une enveloppe timbre 
4F50.

	Guillaume TELLO
	gtello@wanadoo.fr
	http://perso.wanadoo.fr/gtello/