LES CHAINES DE CARACTERES

 

A. Définition d'une chaîne de caractère

Une chaîne de caractères est un espace mémoire pointé par une adresse et une valeur indiquant le nombre de caractères pris en compte à partir de cette adresse.

Les caractères contenus dans une chaîne de caractères sont des valeurs codées sur 7 ou 8 bits selon le système utilisé:

-sur 7 bits, les codes des caractères sont compris entre 0 et 127. La norme la plus utilisée est celle définie dans le standard ASCII.
-sur 8 bits, les codes des caractères sont compris entre 0 et 255. Sur les systèmes IBM PC/XT/AT et compatibles, les codes compris entre 128 et 255 correspondent aux caractères accentués de divers pays, symboles monétaires et mathématiques, caractères semi-graphiques.

Le mot EMIT affiche un caractère à partir de son codeASCII. Exemple:

65 EMIT affiche A

Certains codes n'affichent pas directement un caractère à l'écran, mais déclenchent une action:

7 EMIT provoque l'émission d'un bip sonore

Pour visualiser tous les codes disponibles, vous pouvez essayer la définition suivante:

: AFFICHE-CARS ( ---)
  256 32 DO I EMIT LOOP ;

Pour connaître le code d'un caractère associé à une touche, essayez cette définition:

: .TOUCHE ( ---)
  CR ." Appuyez sur une touche: " KEY
  CR ." Vous avez appuyé sur : " EMIT CR ;

B. Représentation en mémoire d'une chaîne de caractères.

Le premier mot permettant de définir une chaîne de caractères est le mot " (quote ou guillemet). Le texte compris dans la chaîne est délimité par un guillemet. Ce mot est utilisable en interprétation ou à l'intérieur d'une définition:

  : TITRE ( --- str) " MENU GENERAL " ;

L'exécution de titre dépose sur la pile de données les paramètres symbolisés par str correspondant à deux valeurs 16 bits, la première indiquant l'adresse mémoire où est rangé le contenu de la chaîne, la seconde indiquant le nombre de caractères à prendre en compte à partir de cette adresse. Dans notre exemple, l'adresse déposée sur la pile correspond à l'emplacement mémoire contenant la lettre M de la chaîne "MENU GENERAL", la longueur étant celle de la chaîne en question:

Le mot " et le texte de la chaîne doivent être séparés par au moins un caractère espace:

"MENU GENERAL"

provoque une erreur en interprétation ou en compilation, FORTH ne reconnaissant pas le mot "MENU à moins que vous ne l'ayez préalablement défini.

Le contenu de la chaîne est affiché en exécutant le mot TYPE précédé des paramètres adresse et longueur de la chaîne:

TITRE TYPE    affiche    MENU GENERAL

Attention, TYPE affiche le contenu d'une zone mémoire de taille quelconque à partir de n'importe quelle adresse de base sans faire de discernement entre caractères affichables et caractères exécutables. Une plaisanterie du genre 0 25000 TYPE risque d'avoir un effet assez psychédélique sur votre écran vidéo.

Les chaînes de caractères peuvent être définies de plusieurs façons:

-en tant que constantes alphanumériques, par l'utilisation du mot ".

-traitement de variables alphanumériques définies dans le dictionnaire par exécution du mot de définition STRING.

-par traitement de chaînes du type concaténation, fractionnement, de constantes ou variables alphanumériques, extraction de zones mémoires contenant du texte ASCII, lecture de fichier, etc...

C. Traitement élémentaires de chaînes.

Le mot STRING définit une variable de type chaîne alphanumérique. Le mot STRING est précédé d'un paramètre indiquant la taille maximale de la variable chaîne à définir:

10 STRING A$

définit une variable alphanumérique pouvant recevoir dix caractères ou moins. Ensuite, l'exécution d'un mot défini par STRING dépose sur la pile l'adresse et la longueur de la chaîne contenue dans sa zone mémoire. Si la variable chaîne n'a pas encore été affectée, cette longueur sera nulle:

A$    dépose son adresse et la valeur 0 sur la pile de données.

L'affectation d'une chaîne à une variable alphanumérique est réalisé par le mot $! précédé des paramètres de la chaîne origine et la chaîne de destination:

" TEST" A$ $!

Le mot $! peut être exploité en interprétation ou dans une définition compilée.

A$ TYPE    affiche    TEST
: SALUT ( ---)
  ." BONJOUR " A$ TYPE ;
" MONSIEUR" A$ $!
SALUT    affiche    BONJOUR MONSIEUR
" MADAME" A$ $!
SALUT    affiche    BONJOUR MADAME

Si vous tentez d'affecter une chaîne de taille supérieure à la taille maximale de la zone mémoire d'une variable chaîne définie par STRING, seuls les caractères affectables dans la limite de la zone mémoire réservée de cette variable seront pris en compte:

" MADEMOISELLE" A$ $!
SALUT    affiche    BONJOUR MADEMOISE

On peut aussi affecter depuis le clavier une chaîne alphanumérique à une variable alphanumérique en utilisant le mot INPUT$:

A$ INPUT$

attend qu'une suite de caractères soit tapée depuis le clavier et la range dans le zone mémoire réservée de la variable alphanumérique dont les paramètres adresse et longueur figurent au sommet de la pile de données.

Il est conseillé d'utiliser INPUT$ sur une zone mémoire autre que celle réservée pour une chaîne alphanumérique définie par STRING.

La concaténation de deux chaînes effectuée par exécution du mot APPEND$:

80 STRING B$
" BONJOUR" B$ $!
B$ TYPE    affiche    BONJOUR
A$ B$ APPEND$    / met la chaîne a$ dans B$
B$ TYPE    affiche    BONJOUR MADEMOISEL
" LE" B$ APPEND$
B$ TYPE    affiche    BONJOUR MADEMOISELLE

Si une chaîne de caractère se termine par un ou plusieurs caractères espaces, on peut les supprimer en exécutant le mot -TRAILING:

" CLAP,               " B$ $!
B$ 2DUP TYPE TYPE    affiche    CLAP,               CLAP,               
B$ -TRAILING 2DUP TYPE TYPE    affiche    CLAP,CLAP,

Le mot -TRAILING s'applique à tous les types de chaînes, constantes chaînes, variables chaînes, zones mémoire ASCII....

D. Affichage des chaînes alphanumériques

Si le mot TYPE est pratique pour afficher le contenu d'une variable alphanumérique, Il deviendrait rapidement fastidieux d'y faire systématiquement appel pour afficher du texte littéral. Forth dispose dans ce cas des mots ." et .( pour afficher ce type de chaîne:

- le mot ." est utilisable exclusivement dans une définition compilée. à l'éxécution il affiche le texte compris entre ce mot et le caractère " délimitant la fin de chaîne de caractères.

-le mot .( est utilisable exclusivement en interprétation. Il affiche le texte compris entre ce mot et le caractère ) délimitant la fin de la chaîne de caractères.

Exemple:

ECHO OFF
: TITRE
  ."      MENU GENERAL" CR
  ."      =============" ;
: ligne1
  ." 1.. Entrée des données" ;
: ligne2
  ." 2.. Traitement des données" ;
: derniere-ligne
." F.. fin de trairement" ;
: MENU( ---)
dark titre cr cr cr
ligne1 cr cr
ligne2 cr cr
derniere-ligne ;
.( mot MENU compilé) cr
.( taper MENU pour l'exécuter) cr

Dans ce très court programme, la séquence ECHO OFF supprime le défilement du programme pendant la compilation depuis le fichier source. Cependant, les deux dernieères lignes seront exécutées, informant l'ytilisateur des manoeuvres à effectuer pour exécuter son programme.

E. Extraction de sous-chaînes.

Le découpage de chaîne s'apparente assez à une activité similaire à celle pratiquée en charcuterie. Pour bien détailler un morceau de choix, il faut disposer d'une vaste gamme d'outils. Illustrons ceci avec une personne ayant eu beaucoup d'ambition en ce domaine pour disposer de matière première, il s'agit de Pierette et de son pot au lait (c.f. La Fontaine):

80 STRING POT$
" VEAU VACHE COCHON COUVEE3 POT$ $!

Maintenant que l'on dispose de notre chaîne POT$, l'extraction de sous-chaîne sera réalisée en exécutant les mots MID$, LEFT$, RIGHT$:

-MID$ délivre la sous-chaîne pointée par l'adresse et la longueur de la chaîne de référence, la position et le nombre de caractères de la sous-chaîne à extraire. si la position est hors limite, la sous-chaîne aura une longueur nulle.

-LEFT$ délivre la sous-chaîne pointée par l'adresse et la longueur de la chaîne de référence, le nombre de caractères de la sous-chaîne à extraire depuis le début de la chaîne. si le nombre de caractères est supérieur à la taille de la chaîne de référence, la sous-chaîne aura une la taille de la chaîne initiale.

-RIGHT$ délivre la sous-chaîne pointée par l'adresse et la longueur de la chaîne de référence, le nombre de caractères de la sous-chaîne à extraire depuis l'extrémité de la chaîne. si le nombre de caractères est supérieur à la taille de la chaîne de référence, la sous-chaîne aura une la taille de la chaîne initiale.

Exemple:

POT$ 5 5 MID$ TYPE    affiche    VACHE
POT$ 4 LEFT$ TYPE    affiche    VEAU
POT$ 6 RIGHT$ TYPE    affiche    COUVEE

Ces sous-chaînes peuvent être afectées ou concaténées à d'autres chaînes, affichées ou imprimées.

A ces opérateurs de découpage de chaîne plutôt conventionnels, TURBO-Forth rajoute le découpage par ITEM. Une chaîne peut être considérée comme une collection d'items (objets), chaque tiem étant séparé par un caractère "espace". Dans le cas de la chaîne POT$, on dispose de quatre items numérotés de 1 à 4. L'extraction d'un item est exécutée en empilant sa position:

POT$ 2 ITEM TYPE    affiche    VACHE
POT$ 3 ITEM TYPE    affiche    COCHON

Et si comme Pierette on essaie d'en avoir trop:

POT$ 10 ITEM TYPE    n'affiche rien.

Toute tentative d'extraction d'une sous-chaîne en dehors des limites de la chaînede référence délivre l'adresse de fin de chaîne et une longueur nulle.

F. Interprétation des chaînes de caractères.

Le langage FORTH est à la fois interpréteur et compilateur. La fonction interprétation peut être redirigée de manière à exécuter le contenu d'une chaîne de caractères. Cette caractéristique n'est pas propre au langage FORTH (des langages tels que LISP ou LOGO en dispose également) cependant, reste une exclusivité de TURBO-Forth vis à vis d'autres versions du FORTH.

Si une chaîne de caractères définie par STRING contient des mots définis dans le dictionnaire ou des nombres, ceux-ci pourront être exécutés via la mot $EXECUTE. Exemple:

80 STRING TAmPON$
" DARK WORDS" TAmPON$ $!
TAmPON$ $EXECUTE    / exécute le contenu de TAmPON$

Le mot $EXECUTE est réentrant. Si la chaîne à interpréter contione elle-même l'exécution d'une chaîne via $EXECUTE, l'exécution se poursuit dans la seconde chaîne. En fin d'exécution de la seconde chaîne, l'exécution se poursuit dans la chaîne d'origine si elle n'est pas achevée:

0 STRING ch2$
" DARK WORDS" ch2$ $!
70 STRING ch1$
" 7 EMIT ch2$ $EXECUTE 7 EMIT" ch1 $!
ch1$ $EXECUTE    / exécute succéssivement le contenu des chaînes ch1$ et ch2$

Dans le diagramme ci-dessus, chaque ellipse correspond à un niveau de contrôle de l'interpréteur TURBO-Forth. Le nombre de niveaux n'est limité que par la capacité mémoire et la profondeur de pile du système. En théorie, la nombre d'imbrications possible de la commande $EXECUTE est infini. Cependant, certaine perturbations peuvent se produire en cas d'erreur d'interprétation oi de récursivité abusive.

 

 

-- hautdepage -- page d'accueil --