Dans le texte, nous voulons introduire le "gras" sous la forme :
acolade ouvrant texte gras acolade fermant.
Cela suppose que l'on sait rechercher et remplacer un
caractère.
Dans l'ordre :
- Définition de la longueur de la chaine à l'aide
d'une variable
- création de la variable, appelée ici boite, par
analogie avec le fait qu'on va la remplir d'un contenu.
Remarque : On a simplement réservé un espace de
256 caractères et associé une adresse au mot
boite.
256 Constant max-line
create boite max-line allot
Rappel :
Dans Gforth, le transfert du contenu d'une chaine se fait par
l'utilisation du mot s" ".
Exemple :
s" blablabla"
- place le texte blablabla dans une zone tampon provisoire
- retourne sur la pile : l'adresse de ce tampon et la longueur de la
chaine. Cela se traduit par la représentation
conventionnelle :
s" " ( -- adresse-tampon-provisoire longueur )
Quand on appelle une variable, son adresse est empilée
(placée au sommet de la pile. Il s'agit en fait d'un
pointeur.
Exemple :
boite ( -- adresse-de-la-variable )
Le mot Gforth est cmove.
La syntaxe est la suivante :
Adresse-initiale Adresse-de-destination longueur cmove
Le mot cmove détruit les trois valeurs du sommet de la pile.
Exemple :
s" Il est revenu, {le} temps du muguet" boite cmove
Le mot Gforth est type.
La syntaxe est la suivante :
Adresse longueur type
Exemple :
boite type ne marchera pas : il manque la longueur à
afficher.
Remarquons que celle-ci a été "mangée"
par cmove.
Il faut donc la conserver dans une variable numérique.
Le seul moyen provisoire est de faire par exemple
boite 10 type
... qui fonctionne. Mais boite 100 type donnera des choses curieuse...
Ces deux adjectifs permettent de caractériser le fait que la
chaîne de caractère "transporte avec elle" (ou
non) sa longueur.
Dans le Pascal, la longueur d'une chaîne (de type String) est
stockée dans le premier octet de celle-ci. A cause de cela,
elle ne peut pas dépasser la longueur de 255
caractères.
Dans le C, la fin d'une chaîne est marquée par le
caractère 0 et, si l'on veut conserver la longueur il faut
la stocker dans une variable numérique.
Dans Gforth, on fait comme on veut...
Dans les exemples donnés ici la longueur de la
chaîne est stockée dans une variable
numérique annexe.
Pour la suite du travail, nous allons <éer deux
variables numériques :
variable lg 0 ( longueur de la boite lue dans le fichier )
variable n2 0 ( position dans la boite )
Il s'agit en fait de pointeurs.
Pour affecter une valeur à une variable numérique
on fait :
adresse-de-la-variable nombre !
Exemple :
lg 12 ! ( affecte la variable 12 à la variable lg )
Pour empiler la valeur d'une variable numérique on fait :
adresse-de-la-variable @
Exemple :
lg @ . (le . permet de "voir" la valeur empilée )
Ce mot s'appelle affecte (idée d'affectation).
Il est appelé ainsi :
s" contenu" variable affecte
: affecte ( adr1 u adr2 -- )
swap dup lg ! cmove ;
Seul point obscur : swap.
Ce mot échange u et adr2 au sommet de la pile de
façon à respecter la syntaxe de cmove.
dup permet de dupliquer la longueur avant qu'elle ne soit
"mangée" par l'affectation à lg (par le mot !).
s" Il est revenu, {le} temps du muguet" boite affecte
Le mot s'appelle incr.
Il est appelé ainsi :
variable-numérique incr
: incr ( adr -- ) dup @ 1 +
swap ! ;
Logique de codage :
Au moment de l'appel du mot, l'adresse de la variable
numérique a été emplilée.
dup duplique cette adresse
@ charge le contenu de cette adresse sur la pile (et la "mange", ce qui
explique le recours à dup)
1 + augmente de 1 le nombre contenu sur la pile
swap met dans le bon ordre adresse et valeur
! charge le nombre dans la variable située à
l'adresse empilée.
Pour cette expérimentation, le résultat s'affiche
à l'écran, ce qui explique l'usage du mot "type".
: si{ ( adr --) dup 1 s" {"
compare 0 =
if s" <b>" type
else si}
endif ;
s" {" compare 0 = le caractère pointé par "adr"
est-il { ?
if s" <b>" type si oui, affiche <b>
sinon exécute le mot si}
Le programme s'appelle "parcours.fs".
Se souvenir qu'on lui a fait
chmod +x parcours.fs
et que le s<ipt se lance par ./parcours.fs
#! /usr/local/bin/gforth
256 Constant max-line
<eate boite max-line allot
variable lg 0 ( longueur de la boite lue dans le fichier )
variable n2 0 ( position dans la boite )
: affecte ( adr1 u adr2 -- )
swap dup lg ! cmove ;
s" Il est revenu, {le} temps du muguet" boite affecte
: incr ( adr -- ) dup @ 1 + swap ! ;
: si} ( adr --) dup 1 s" }" compare 0 =
if s" </b>" type
else 1 type
endif ;
: si{ ( adr --) dup 1 s" {" compare 0 =
if s" <b>" type
else si}
endif ;
: boucle begin
boite n2 @ + si{
n2 incr
lg @ n2 @ =
until ;
boucle
bye
Haut de page