	Salut Godefroy,

	Les annotations de prsentation sont incluses entre crochets, et
il n'y a que l qu'on trouve des crochets d'ailleurs.
	[TEXTE] -> dbut d'une zone normale, tu formates au kilomtre
	[LISTING] -> dbut d'une zone de programme GFA, a afficher avec
		l'allure d'un listing.
	[DP] -> dbut de paragraphe forc, en gros, commencer une nouvelle
		ligne.

	Guillaume


	UN INTERPRTEUR FORTH EN GFA (2)
	********************************

[TEXTE]
	Voici la suite de la srie: ajourd'hui, comme prvu on s'attaque
aux tests entre deux entiers ainsi qu' la structure IF-ELSE-THEN. C'est
un minimum pour qu'un programme puisse prendre quelques dcisions...

Une modification s'impose
-------------------------

	La procdure d'interprtation doit etre lgrement remanie. En
effet, la partie s'occupant d'extraire le mot suivant va etre rutilise:
elle devient donc une procdure  part qui sera appele de divers
endroits. Il vous faut donc remplacer "interprete" par le nouveau couple
"interprete" plus "motsuivant":

[LISTING]
PROCEDURE interprete(b$)
  LOCAL strptr%
  b$=b$+" "
  strptr%=1
  finligne!=FALSE
  DO
    GOSUB motsuivant
    EXIT IF finligne!
    FOR i%=1 TO o%
      EXIT IF mot$=mot$(i%)
    NEXT i%
    IF i%<=o%
      ON i% GOSUB plus,moins,fois,divise,point,duplique,permute,jette,quitte,ndo,nloop,chrono,cr,sup,inf,egal,dif,si,sinon,ensuite
    ELSE
      INC pileptr%
      pile%(pileptr%)=VAL(mot$)
    ENDIF
    EXIT IF fin!
  LOOP
RETURN
PROCEDURE motsuivant
  encore:
  i%=INSTR(strptr%,b$," ")
  IF i%=strptr%
    INC strptr%
    IF strptr%>=LEN(b$)
      finligne!=TRUE
    ELSE
      GOTO encore
    ENDIF
  ELSE
    mot$=MID$(b$,strptr%,i%-strptr%)
    strptr%=MIN(i%+1,LEN(b$))
  ENDIF
RETURN

[TEXTE]
	Remarques:
[DP]	- la ligne du ON GOSUB s'est allonge puisque de nouvelles
fonctions sont apparues.
[DP]	- la procdure "motsuivant" met la variable "finligne!"  TRUE si
la fin de la ligne est atteinte, sinon, elle remplit simplement la
variable mot$ avec le mot suivant.

[DP]	Il vous faut galement ajouter une ligne aux DATAs:

[LISTING]
DATA +,-,*,/,.,dup,swap,drop,system,ndo,nloop,timer,cr
DATA >,<,=,<>,if,else,then
DATA "---"

[TEXTE]
Les fonctions de tests
----------------------

	Ces fonctions comparent les deux entiers au sommet de la pile et
renvoient 0 si le test est FAUX ou 1 si le test est VRAI. En fait, pour la
plupart des fonctions, 0 reprsente FAUX et toute autre valeur reprsente
VRAI, le choix de 1 est donc arbitraire.
	Voici les quatre procdures correspondantes:

[LISTING]
PROCEDURE sup
  i%=pile%(pileptr%)
  DEC pileptr%
  IF pile%(pileptr%)>i%
    i%=1
  ELSE
    i%=0
  ENDIF
  pile%(pileptr%)=i%
RETURN
PROCEDURE inf
  i%=pile%(pileptr%)
  DEC pileptr%
  IF pile%(pileptr%)<i%
    i%=1
  ELSE
    i%=0
  ENDIF
  pile%(pileptr%)=i%
RETURN
PROCEDURE egal
  i%=pile%(pileptr%)
  DEC pileptr%
  IF pile%(pileptr%)=i%
    i%=1
  ELSE
    i%=0
  ENDIF
  pile%(pileptr%)=i%
RETURN
PROCEDURE dif
  i%=pile%(pileptr%)
  DEC pileptr%
  IF pile%(pileptr%)<>i%
    i%=1
  ELSE
    i%=0
  ENDIF
  pile%(pileptr%)=i%
RETURN

[TEXTE]
	A l'utilisation:
[DP]	1 2 = . affiche 0, car 1=2 est faux.
[DP]	9 -1 > . affiche 1, car 9>-1 est vrai.
[DP]	6 2 <> . affiche 1, car 6<>1 est vrai.
[DP]	-1 -2 < . affiche 0, car -1<-2 est faux.

La structure IF-ELSE-THEN
-------------------------

	Il faut etre ambitieux (enfin, un peu...): cette stucture doit
absolument pouvoir etre imbrique avec autant de niveaux que possible.
Voyons d'abord le fonctionnement en FORTH. Soit "x" la valeur sur la pile
lors de l'excution de IF, la structure connait deux formes:

[DP]	IF
[DP]	   partie a excuter si x non nul
[DP]	THEN

[DP]	ou

[DP]	IF
[DP]	   partie  excuter si x non nul
[DP]	ELSE
[DP]	   partie  excuter si x est nul
[DP]	THEN

	Vous remarquerez la place inhabituelle du mot THEN qui,
contrairement au BASIC ne veut pas dire "alors" mais "ensuite": il ferme
donc la structure.
	L'implantation de IF vient alors d'elle meme: si x est non nul, il
n'y a rien  faire puisque le programme continue en squence. Si x est
nul, il nous faut trouver le ELSE ou le THEN suivant et sauter  cet
endroit. C'est l qu'est le pige de l'imbrication: si un autre IF est
rencontr, alors il faut aller au second THEN, pas au premier!! C'est le
but de la variable "niveau%" qui compte les niveaux d'imbrication.

[LISTING]

PROCEDURE si
  LOCAL niveau%
  i%=pile%(pileptr%)
  DEC pileptr%
  IF i%=0
    niveau%=0
    REPEAT
      GOSUB motsuivant
      EXIT IF finligne!
      IF mot$="if"
        INC niveau%
      ELSE IF mot$="then"
        DEC niveau%
      ELSE IF (mot$="else") AND (niveau%=0)
        DEC niveau%
      ENDIF
    UNTIL niveau%<0
  ENDIF
RETURN

[TEXTE]
	Remarquez le double test pour "else": il nous fait descendre d'un
niveau que si il correspond au IF dont on s'occupe, c'est  dire au niveau
zro: tout autre "else" n'est pas la fin d'un structure imbrique, c'est
le "then" qui le signale.

	Passons au "else": son travail est de sauter au THEN suivant, en
effet, si on rencontre ce "else" c'est qu'on vient d'excuter la partie
entre IF et ELSE, il faut donc sauter celle entre ELSE et THEN. Meme chose
qu'avec IF, on tient compte de possibles imbrications:

[LISTING]

PROCEDURE sinon
  LOCAL niveau%
  REPEAT
    GOSUB motsuivant
    EXIT IF finligne!
    IF mot$="if"
      INC niveau%
    ELSE IF mot$="then"
      DEC niveau%
    ENDIF
  UNTIL niveau%<0
RETURN

[TEXTE]
	Le plus simple des trois est le mot THEN: si on le rencontre,
c'est qu'on a excut la partie entre ELSE et THEN, nous devons maintenant
poursuivre en squence: il n'y a alors rien  faire:

[LISTING]

PROCEDURE ensuite
RETURN

[TEXTE]
Quelques essais
---------------

	Mettons en oeuvre ces nouvelles possibilits:
[DP]	x dup 0 < if -1 * then .
[DP]	Essayez cette petite ligne pour diffrentes valeurs de x, vous
verrez que vous obtiendrez toujours la valeur absolue du nombre x.

[DP]	x dup 255 > if drop 255 else dup 0 < if drop 0 then then .
[DP]	Cette ligne limite la valeur x  l'intervalle [0,255]. Si x est
plus grand que 255, il est ramen  255. Si x est ngatif, il est ramen 
zro.

La prochaine fois
-----------------

	On s'attaquera  la cration et mise en mmoire de nos propres mots
FORTH, qu'ils soient des variables ou des procdures. D'ici l, sauriez
vous programmer une structure REPEAT-UNTIL, une structure WHILE-WEND?

	Guillaume Tello
	gtello@wanadoo.fr