Display of numbers and character strings
published: 21 November 2024 / updated 21 November 2024
Affichage des nombres et chaînes de caractères
article: 24 mai 2019 / mis à jour 25 mai 2019
Changement de base numérique
Applicable également sur Flash Forth pour Arduino
FORTH ne traite pas n'importe quels nombres. Ceux que vous avez utilisés en essayant les précédents exemples sont des entiers signés simple précision. Le domaine de définition des entiers simple précision est compris entre moins 32768 et plus 32767. Exemple:
32767 . \ affiche 32767 -32768 . \ affiche -32768 65535 . \ affiche -1 ( sur systèmes FORTH avec pile 16 bits)
Ces nombres peuvent être traités dans n'importe quelle base numérique, toutes les bases numériques situées entre 2 et 36 étant valides:
255 HEX . DECIMAL \ affiche FF
On peut choisir une base numérique encore plus grande, mais les symboles disponibles sortiront de l'ensemble alpha-numérique [0..9,A..Z] et risquent de devenir incohérents. Exemple:
DECIMAL 255 BASE ! ò 2 + .
fonctionnera, mais n'est guère concevable sur un plan sémantique.
La base numérique courante est controlée par une variable nommée BASE
et dont le
contenu peut être modifié. Ainsi, pour passer en binaire, il suffit de stocker
la valeur 2 dans BASE
. Exemple:
2 BASE !
et de taper DECIMAL
pour revenir à la base numérique décimale.
Forth dispose de deux mots pré-définis permettant de sélectionner différentes bases numériques:
DECIMAL
pour sélectionnner la base numérique décimale. C'est la base numérique prise par défaut au démarrage de Forth.HEX
pour sélectionner la base numérique hexadécimale.
Dès sélection d'une de ces bases numériques, les nombres litéraux seront interprétés, affichés ou traités dans cette base. Tout nombre entré précédemment dans une base numérique différente de la base numérique courante est automatiquement converti dans la base numérique actuelle. Exemple:
DECIMAL \ base en décimal 255 \ empile 255 HEX \ sélectionne base hexadécimale 1+ \ incrémente 255 devient 256 . \ affiche 100
On peut définir sa propre base numérique en définissant le mot approprié ou
en stockant cette base dans BASE
. Exemple:
: BINARY ( ---) \ sélectionne la base numérique binaire 2 BASE ! ; DECIMAL 255 BINARY . \ affiche 11111111
Le contenu de BASE
peut être empilé comme le contenu de n'importe
quelle autre variable:
VARIABLE RANGE_BASE \ définition de variable RANGE-BASE BASE @ RANGE_BASE ! \ stockage contenu BASE dans RANGE-BASE HEX FF 10 + . \ affiche 10F RANGE_BASE @ BASE ! \ restaure BASE avec contenu de RANGE-BASE
Dans une définition "deux-points", le contenu de BASE
peut transiter
par la pile de retour:
: OPERATION ( ---) BASE @ >R \ stocke BASE sur pile de retour HEX FF 10 + . \ opération du précédent exemple R> BASE ! ; \ restaure valeur initiale de BASE
ATTENTION: les mots >R
et R>
ne sont pas exploitables en mode interprété.
Vous ne pouvez utiliser ces mots que dans une définition qui sera compilée.
Définition de nouveaux formats d'affichage
Applicable également sur Flash Forth pour Arduino
Forth dispose de primitives permettant d'adapter l'affichage d'un nombre à un format quelconque. Ces primitives ne traitent que des nombres double précision:
<#
débute une séquence de définition de format#
insère un digit dans une séquence de définition de format#S
équivaut à une succession de #HOLD
insère un caractère dans une définition de format#>
achève une définition de format et laisse sur la pile l'adresse et la longueur de la chaîne contenant le nombre à afficher
Ces mots ne sont utilisables qu'au sein d'une définition. Exemple, soit à afficher un nombre exprimant un montant libellé en francs avec la virgule comme séparateur décimal:
: EUROS ( ud ---)
<# # # ASCII , HOLD #S #>
TYPE ." EUR " ;
Exemples d'exécution:
0.35 EUROS \ affiche 0,35 EUR 35.75 EUROS \ affiche 35,75 EUR 10.15 35.75 D+ EUROS \ affiche 45,90 EUR
La définition de EUROS
ne prend pas en compte le signe du résultat, ni la
position de la virgule. Si vous tapez:
35. EUROS \ vous aurez à l'affichage 0,35 EUR
Dans la définition de EUROS
, le mot <#
débute la séquence de définition de format
d'affichage; les deux mots #
placent les chiffres des unités et des dizaines
dans la chaîne de caractère; ASCII , HOLD
placent le caractère , (virgule)
à la suite des deux chiffres de droite, le mot #S
complète le format
d'affichage avec les chiffres non nuls à la suite de "," le mot #>
ferme la
définition de format et dépose sur la pile l'adresse et la longueur de la chaîne
contenant les digits du nombre à afficher; le mot TYPE
affiche cette
chaîne de caractères.
En exécution, une séquence de format d'affichage traite exclusivement des nombres entiers double précision signés ou non signés. La concaténation des différents éléments de la chaîne se fait de droite à gauche, c'est à dire en commençant par les chiffres les moins significatifs.
Le traitement d'un nombre par une séquence de format d'affichage est exécutée en fonction de la base numérique courante. La base numérique peut être modifiée entre deux digits.
Voici un exemple plus complexe démontrant la compacité du FORTH. Il s'agit d'écrire un programme convertissant un nombre quelconque de secondes au format HH:MM:SS:
: :00 ( ---) DECIMAL # \ insertion digit unité en décimal 6 BASE ! \ sélection base 6 # \ insertion digit dizaine ASCII : HOLD \ insertion caractère : DECIMAL ; \ retour base décimale : HMS ( ud ---) \ affiche nombre secondes format HH:MM:SS <# :00 :00 #S #> TYPE SPACE ;
Exemples d'exécution:
59. HMS \ affiche 0:00:59 60. HMS \ affiche 0:01:00 4500. HMS \ affiche 1:15:00
Explication: le système d'affichage des secondes et des minutes est
appelé système sexagésimal. Les 'unités' sont exprimées dans la base
numérique décimale, les 'dizaines' sont exprimées dans la base six.
Le mot :00
défini précédemment gère la conversion des
'unités' et des 'dizaines' dans ces deux bases pour la mise au format
des digits correspondants aux secondes et aux minutes. Pour les heures,
les digits sont tous décimaux.
Autre exemple, soit à définir un programme convertissant un nombre entier simple précision décimal en binaire et l'affichant au format bbbb bbbb bbbb bbbb:
: QUATRE-DIGITS ( ---) # # # # 32 HOLD ; : AFB ( d ---) \ mise au format 4 digits et un espace BASE @ >R \ Sauvegarde base courante 2 BASE ! \ Sélection base numérique binaire <# 4 0 DO \ Boucle de mise au format QUATRE-DIGITS LOOP #> TYPE SPACE \ Affichage en binaire R> BASE ! ; \ Restauration base numérique initiale
Exemple d'exécution:
DECIMAL 12. AFB \ affiche 0000 0000 0000 0110 HEX 3FC5. AFB \ affiche 0011 1111 1100 0101
Encore un exemple, soit à créer un agenda téléphonique où l'on associe à un patronyme un ou plusieurs numéros de téléphone. On définit un mot par patronyme:
: .## ( ---) # # ASCII . HOLD ; : .TEL ( d ---) CR <# .## .## .## .## .## #> TYPE CR BYE ; : DUGENOU ( ---) .06051254 .TEL ; \ ...ici votre agenda téléphonique...puis sous DOS:
Cet agenda, qui peut être compilé depuis un fichier source, est facilement modifiable, et bien que les noms ne soient pas classés, la recherche y est extrêmement rapide.
Affichage des caractères et chaînes de caractères
L'affichage d'un caractère est réalisé par le mot EMIT
:
65 EMIT \ affiche A
Les caractères affichables sont compris dans l'intervalle 32..255. Les codes compris entre 0 et 31 seront également affichés, sous réserve de certains caractères exécutés comme des codes de contrôle. Voici une définition affichant tout le jeu de caractères de la table ASCII:
: JEU-ASCII ( ---) DARK 256 32 DO I 3 .R SPACE \ affiche code du caractère I EMIT 2 SPACES \ affiche caractère #OUT @ 77 = IF CR THEN LOOP ;
L'exécution de JEU-ASCII
affiche les codes ASCII et les caractères
dont le code est compris entre 32 et 255. Pour afficher la table équivalente
avec les codes ASCII en hexadécimal, taper HEX JEU-ASCII
.
Les chaînes de caractères sont affichées de diverses manières. La première, utilisable en compilation seulement, affiche une chaîne de caractères délimitée par le caractère " (guillemet):
: TITRE ." MENU GENERAL" ;
TITRE \ affiche MENU GENERAL
a chaîne est séparée du mot ."
par au moins un caractère espace.
Une chaîne de caractères peut aussi être compilée par le mot S"
et délimitée par le caractère " (guillemet):
: LIGNE1 ( --- adr len)
S" E..Enregistrement de données" ;
L'exécution de LIGNE1
dépose sur la pile de données l'adresse et
la longueur de la chaîne compilée dans la définition. L'affichage est réalisé
par le mot TYPE
:
LIGNE1 TYPE \ affiche E..Enregistrement de données
En fin d'affichage d'une chaîne de caractères, le retour à la ligne doit être provoqué s'il est souhaité:
LIGNE1 TYPE \ affiche E..Enregistrement de données CR TITRE CR CR LIGNE1 TYPE CR \ affiche \ MENU GENERAL \ \ E..Enregistrement de données
Un ou plusieurs espaces peuvent être ajoutés en début ou fin d'affichage d'une chaîne alphanumérique:
SPACE \ affiche un caractère espace 10 SPACES \ affiche 10 caractères espace