Bienvenue

Présentation

SBASIC est un interpréteur très rapide et très complet. Il s’utilise comme la plupart des BASIC interprétés :

  • En mode immédiat, il exécute directement les ordres entrés au clavier, ce qui permet de l’utiliser interactivement comme un calculateur.
  • En mode programme, les lignes, entrées au clavier, permettent de construire le programme qui sera par la suite lancé au moyen de la commande RUN.

Nous recommandons à l’utilisateur de lire l’ensemble du présent manuel avant de travailler sous SBASIC. Nous y avons inclus de nombreux exemples afin de le rendre plus accessible à la majorité des lecteurs.

SBASIC diffère d’un BASIC ordinaire par l’adjonction d’un certain nombre de mots-clés et de commandes qui en font un outil puissant de programmation. Citons par exemple, l’usage des procédures, du mode trace, de la renumérotation partielle, de l’édition de la table des variables, etc.

SBASIC apporte ainsi une dimension et un confort nouveaux à la programmation en BASIC.

Concepts généraux

SBASIC autorise la manipulation de trois types d’objets différents. Des entiers, des réels et des chaînes de caractères. Les deux premiers types permettent de représenter des nombres alors que le troisième permet de travailler sur du texte. Tous ces objets sont stockés en mémoire à l’aide d’octets (groupes de 8 bits), chacun d’entre eux pouvant représenter un nombre compris entre 0 et 255 inclus.

Types

Type entier

Le type Entier permet de stocker des nombres entiers signés pouvant être codés sur quatre octets, c’est à dire des nombres entiers compris entre -2147483648 et 2147483647. Ils sont représentés en complément à deux, sur 4 octets consécutifs de la mémoire centrale, mais il faut prendre garde au fait que l’ordre dans lequel ces derniers sont utilisés dépend de la machine et même du système utilisé.

Type réel

Le type Réel permet de stocker toutes les autres valeurs numériques. Cette méthode de codage est aussi appelée représentation en virgule flottante. Elle utilise 8 octets par valeur (6,5 pour la mantisse et 1,5 pour l’exposant) et permet de représenter des nombres approximativement compris entre 10-300 et 10300.

Type chaîne de caractères

Le type Chaîne de caractères permet de stocker du texte dont l’utilisateur aura besoin pour documenter les résultats d’un programme de calcul ou sur lequel il aura envie de travailler avant de l’éditer. Chaque caractère de texte est alors codé sur un octet (codage ASCII international).

Ce type est souvent appelé type Chaîne, ou encore type Alphanumérique.

Constantes, Variables, Tableaux

Constantes

Une valeur utilisée sous forme de Constante doit être décrite lors de chacune de ses utilisations. Cette description doit respecter les règles suivantes :

Constantes de type entier

Pour une constante de type Entier la valeur doit être écrite en décimal et représenter un nombre entier compris entre -2147483648 et 2147483647. Les seuls symboles permis sont donc les chiffres de 0 à 9, l’espace et le signe + ou le signe - (placés en tête).

L’utilisation du point décimal provoque un codage en virgule flottante, même s’il n’est suivi d’aucun chiffre.

Les descriptions suivantes de constantes entières sont correctes :

12
+15
31000
-57
-2545

Les descriptions suivantes sont incorrectes :

12. # codage en virgule flottante à cause du point décimal
10000000000 # entier supérieur à 2147483647
Constante de type réel

Pour une constante de type Réel la valeur peut, au gré de l’utilisateur, être décrite sous forme décimale ou sous forme scientifique.

Sous forme décimale on utilisera donc les chiffres de 0 à 9, l’espace, le signe + ou le signe - et le point décimal exactement comme dans la vie courante (anglo-saxonne !).

L’écriture sous forme scientifique est recommandée pour des nombres très grands ou très petits en valeur absolue, mais elle peut être utilisée pour toute valeur numérique. En plus des symboles précédents elle tolère la lettre E (majuscule ou minuscule) qui permet de séparer la mantisse de l’exposant. Une constante de type réel doit être comprise entre 10-127 et 10+127.

Les descriptions suivantes de constantes réelles sont correctes :

3.14159
-6.25
+12.
6.02E 23
1 E 27

Les deux dernières valeurs sont respectivement égales à : 6.02 x 10^23 et 10^27

Les descriptions suivantes sont incorrectes :

12,5 # utilisation de la virgule
5.23E10+2 # utilisation du signe + dans l’exposant
Constantes de type chaîne de caractères

La description d’une constante de type Chaîne de caractères peut utiliser tous les caractères obtenus à partir du clavier, mais elle doit débuter et se terminer par des guillemets (ou des apostrophes) ; ces signes ne font pas partie de la chaîne, ils permettent simplement de la délimiter.

Dans une constante chaîne on peut trouver une ou plusieurs occurrences de guillemets ; une telle constante doit alors être délimitée par des apostrophes et ne peut contenir aucune apostrophe. De même il est possible d’y placer des apostrophes, à condition de la délimiter par des guillemets, mais on ne peut alors y trouver aucun guillemet.

Les descriptions suivantes de constantes chaînes sont correctes :

"Vive le SBASIC"
"La lettre 'E' "
'Dites "Bonjour"'

Les descriptions suivantes sont incorrectes :

"A bas le SBASIC
'lettre"
'la lettre "A" et l'apostrophe'

Variables

On utilise une variable pour manipuler des valeurs qu’on ne veut pas ou qu’on ne peut pas décrire lors de chacune de ses utilisations. Ce peut être parce que la valeur est longue et donc fastidieuse à décrire, ou parce qu’elle dépend du cheminement suivi lors de l’exécution du programme et que le programmeur n’est pas capable de la décrire lors de l’écriture de ce dernier.

Dans ce cas la valeur en cause est manipulée par l’intermédiaire d’un identificateur appelé « nom de variable ». Le programmeur se trouve dans la situation d’un manutentionnaire qui travaille sur des boîtes dont il ne connaît pas vraiment le contenu, mais qu’il repère par un nom ou un numéro écrit sur cette dernière (nom de variable) et qui seul lui permet de distinguer une boîte d’une autre. Ce qui se trouve dans la boîte y a été mis par quelqu’un d’autre à un autre moment (affectation de la variable).

Pour pouvoir utiliser des variables, il faut connaître les règles qui régissent la formation de leurs noms et la façon de leur affecter une valeur.

Noms de variables

Un nom de variable se construit en respectant les règles suivantes :

  • Un nom de variable doit être une suite d’au plus 255 caractères pris parmi les lettres de l’alphabet, le caractère souligné « _ », les chiffres et les symboles réservés « % » et « $ ».
  • Le premier caractère doit être une lettre de l’alphabet, les suivants peuvent être des lettres, « _ » ou des chiffres, seul le dernier peut être « % » ou « $ ».
  • Deux suites différentes permettent de gérer des variables différentes. Tous les caractères sont discriminatoires. Si des lettres minuscules sont utilisées lors de la saisie, elles sont automatiquement converties en majuscules. La chasse des lettres n’est donc pas discriminatoire.
  • Un nom de variable ne doit pas commencer par un mot réservé du SBASIC. Voir la liste des mots réservés se trouvant en « Annexe 2 : Liste des codes d’erreurs réservés ».
  • Les variables dont le nom se termine par le symbole « % » ne pourront être utilisées que pour contenir des valeurs de type entier.
  • Celles dont le nom se termine par « $ » devront avoir un contenu de type chaîne de caractères.
  • Les autres variables permettent de manipuler les valeurs réelles.

Exemples de noms de variables syntaxiquement corrects :

  • Variables de type entier :

    KILO% N% NOMBRE_PAR_KILO%

  • Variables de type réel :

    VITESSE X POIDS_AU_LITRE

  • Variables de type chaîne :

    TXT$ A$ LIGNE_COURANTE$

Exemples de noms de variables incorrects :

1AB, $, événement # ne commence pas par une lettre majuscule
A%B$, A/B # comporte des symboles interdits
TOTAL%, TABLEAU # commence par un mot réservé, « TAB » ou « TO »
Affectation

La première chose à faire lorsque l’on utilise une variable est de lui Affecter une valeur, c’est à dire, en poursuivant la comparaison entre variables et boîtes, de mettre quelque chose dans la boîte sur laquelle est inscrit le nom de la variable.

Une telle opération se fait à l’aide d’une instruction d’affectation qui peut être effectuée par l’un des mots réservés LET, INPUT ou READ entièrement décrits dans la suite de ce manuel. Toutefois, on peut dès à présent brièvement décrire l’utilisation de LET et de INPUT.

LET var = exp

permet d’affecter à la variable de nom-var la valeur de l’expression exp qui doit être de même type.

Par exemple :

LET A=1 # affecte à la variable A la valeur 1
LET NOM$="toto" # affecte à la variable A$ la valeur "toto"
LET VI=12.5 # affecte à la variable réelle VI la valeur 12,5

Nous rencontrons ici le premier exemple de la syntaxe que nous utiliserons tout au long de cet ouvrage pour décrire les différentes instructions de SBASIC. La mise en avant permet de représenter un objet SBASIC que l’utilisateur devra remplacer lors de l’écriture d’un programme par un objet correspondant à cette description.

Ici, nous avons utilisé var qui doit être remplacé par un nom de variable SBASIC syntaxiquement correct. De même exp devra, lui, être remplacé par une expression quelconque dont l’exemple le plus simple est une constante.

Il est possible, dans les instructions précédentes, d’omettre le mot réservé LET et d’écrire respectivement pour chacune des trois affectations précédentes :

A=1
NOM$="toto"
VI=12.5

Nous verrons ultérieurement que l’on peut, à droite du signe « = » utiliser des expressions plus complexes que de simples constantes, mais à gauche de ce signe on doit uniquement trouver un nom de variable.

Par exemple, l’instruction :

LET A+1 = 10

est tout à fait incorrecte et ne permet pas d’affecter à la variable A la valeur 9 comme inciterait à le penser toute allusion à l’équation algébrique « x +1= 10 ».

Autre exemple :

num-ligne INPUT var

Cette instruction arrête l’exécution du programme, affiche dans la fenêtre SBASIC un point d’interrogation et attend que l’utilisateur frappe une entrée au clavier. La ligne entrée par l’utilisateur est alors interprétée par SBASIC et la valeur correspondante affectée à la variable var.

Si la variable var est de type numérique (entier ou réel) et que l’utilisateur frappe des caractères qui ne peuvent intervenir dans la définition d’une constante de ce type, le programme signale une erreur.

Par exemple le programme :

10 PRINT "Quel est votre nom ? ";
20 INPUT NOM$
30 PRINT "Bonjour ";NOM$

permet à l’utilisateur de cette machine de se faire saluer très poliment par son ordinateur préféré ; il lui suffit d’entrer ces quelques lignes, puis de les exécuter en frappant au clavier la commande RUN.

Signalons que l’entrée au clavier doit se terminer par la frappe d’un caractère Retour-Chariot.

Tableaux

Lorsqu’un programme nécessite l’utilisation d’une liste de variables de même type et que chacune d’entre elles peut être repérée par son rang dans la liste, il est pratique et souvent indispensable de se servir d’un Tableau, encore appelé variable indicée.

Notion de tableau à une dimension

Par exemple un enseignant qui désire travailler sur les notes obtenues par ses élèves lors d’une composition utilisera une liste, un tableau, dont chacun des éléments contiendra la note d’un élève. La liste de classe étant supposée, ce qui est fréquent, écrite dans l’ordre alphabétique, chaque élève sera simplement repéré par son rang dans cette liste.

En supposant avoir une classe de 5 élèves ayant les noms suivants :

ANDRE
JACQUES
JEAN
PAUL
PIERRE

La note de l’élève n° 1 (ANDRE) correspondra à l’élément 1 du tableau,

la note de l’élève n° 2 (JACQUES) correspondra à l’élément 2 du tableau,

la note de l’élève n° 3 (JEAN) correspondra à l’élément 2 du tableau

et ainsi de suite

Dimensionnement d’un tableau à une dimension

Avant toute utilisation d’un tableau à une dimension permettant de gérer une liste de variables de même type, il faut déclarer ce tableau en indiquant son nom et en le dimensionnant. Cette opération permet à SBASIC de se préparer à la gestion d’une telle liste.

Pour dimensionner un tableau on utilise l’instruction DIM, décrite complètement dans la suite de ce manuel, mais dont on peut donner ici brièvement la syntaxe.

DIM var(exp-num)

var est le nom du tableau. La construction de ce nom obéit aux mêmes règles que celles régissant la construction d’un nom de variable.

Si chaque élément du tableau est destiné à contenir une valeur de type entier, le nom var doit de terminer par le symbole réservé %.

Si chaque élément du tableau est destiné à contenir du texte, le nom var doit se terminer par le symbole réservé $.

exp-num est un entier indiquant le nombre maximum d’éléments que l’on désire ranger dans le tableau.

Aucune opération globale d’affectation ou d’édition ne peut être faite en utilisant le nom du tableau. Mais chacun de ses éléments peut être manipulé exactement comme une variable de type correspondant.

Utilisation d’un tableau a une dimension

En reprenant l’exemple de la classe de 5 élèves, il est possible d’utiliser deux tableaux parallèles, l’un permettant de ranger les noms des élèves, l’autre contenant leurs notes.

Ces tableaux sont dimensionnés de la façon suivante :

10 N%=5
20 DIM NOM$(N%)
30 DIM NOTE(N%)

Pour entrer les noms et les notes des différents élèves de la classe il suffit d’exécuter les lignes suivantes :

100 FOR I%=1 TO N%
110 REM
120 REM Affectation d’un contenu à la variable NOM$(l%)
130 PRINT "Nom de l'élève ";I% ;
140 INPUT NOM$(I%)
150 REM
160 REM Affectation d'une note à l'élève de rang I%
170 PRINT "Note de l'élève ";NOM$(I%);
180 INPUT NOTE(I%)
190 NEXT I%

Pour obtenir maintenant une édition de ces notes dans l’ordre alphabétique il suffit d’exécuter les instructions suivantes :

200 FOR I%=1 TO N%
210 PRINT NOM$(I%); " a pour note "; NOTE(I%)
220 NEXT I%

Pour ce petit programme on aurait évidemment pu utiliser 5 variables de type chaîne de caractères destinées à contenir les noms N1$, N2$, N3$, N4$, N5$ ainsi que 5 variables de type réel destinées à contenir les notes, N1, N2, N3, N4, N5.

Toutefois la méthode utilisée présente deux avantages. Tout d’abord elle évite d’écrire 5 fois chacune des lignes mettant en jeu les éléments NOM$(I%) et NOTE(I%), à savoir les lignes 110, 120, 130, 210. Ensuite elle donne un programme aisément modifiable et adaptable à une classe plus conforme à la réalité. Il suffit par exemple de modifier l’affectation de la ligne 10, en la remplaçant par :

10 N%=25

on obtient alors un programme valable pour une classe de 25 élèves.

Notion de tableau à deux dimensions

Si le même enseignant désire travailler sur l’ensemble des notes de ses élèves pour un mois donné, il devra disposer, pour chacune des quatre interrogations du mois, de la liste des notes de ses élèves.

Il pourrait évidemment utiliser un tableau pour chacune des listes de notes :

NOTE1(*) contenant les notes de tous les élèves pour la première interrogation,

NOTE2(*) contenant les notes de tous les élèves pour la deuxième interrogation,

et ainsi de suite.

Mais on retombe alors dans le double travers signalé à la fin du paragraphe précédent concernant la concision d’écriture du programme et les possibilités d’adaptation à d’autres cas de figure semblables.

Il est préférable d’utiliser un tableau à deux dimensions, qui permettra, comme la page d’un cahier de notes, de stocker l’ensemble des notes du mois. L’un des indices permettra de repérer le nom de l’élève concerné (la ligne du cahier) et l’autre d’indiquer de quelle interrogation il s’agit (la colonne du cahier).

Dimensionnement et utilisation d’un tableau double

Un tableau double se déclare par une instruction de dimensionnement semblable à celle utilisée pour un tableau à une dimension :

DIM var(exp-num-1,exp-num-2)

var est le nom du tableau qui doit être construit comme celui d’un tableau à une dimension en fonction du type de valeurs que l’on désire y stocker.

exp-num-1 est le nombre maximum de lignes du tableau.

exp-num-2 est le nombre maximum de colonnes du tableau.

L’utilisation du tableau nécessaire à la gestion de l’ensemble des notes de l’exemple précédemment décrit imposera la déclaration d’un tableau de notes doublement indicé grâce à l’instruction :

50 DIM NOTE_MOIS(5,4)

Dans ce tableau :

NOTE_MOIS(2,3) est la note obtenue par JACQUES à l’interrogation 3,

NOTE_MOIS(4,1) est la note obtenue par PAUL à l’interrogation 1.

Il faudra utiliser une double boucle pour entrer tous les éléments du tableau, mais l’utilisateur aura ensuite la possibilité de d’établir, pour chaque élève, la moyenne des notes du mois et de calculer pour chacune des interrogations la moyenne des notes de la classe.

De même que pour les tableaux à une dimension, aucune opération (affectation, édition, …) ne peut être faite globalement en invoquant seulement le nom du tableau, mais chacun de ses éléments peut être utilisé dans les mêmes conditions qu’une variable de type correspondant.

SBASIC supporte un nombre quelconque de dimensions à condition que le nombre total d’éléments ne dépasse pas 536870911.

Operateurs et expressions

Ayant défini précédemment les objets élémentaires (constantes et variables) sur lesquels travaillait SBASIC, nous allons maintenant définir les opérateurs qui permettent de construire d’autres objets plus complexes, les expressions dont la valeur peut être un nombre ou une chaîne de caractères, ainsi que des relations entre ces objets.

Par exemple :

A désignant une variable numérique et A$ une variable chaîne, on pourra être amené dans le cours d’un programme à utiliser les expressions :

12 + EXP(A)
PI + LEN(A$)

que l’on pourra désigner respectivement par exp-num-1 et exp-num-2. En appliquant à ces mêmes expressions les règles de remplacement que nous avons vues au sujet des variables, nous voyons que la première, par exemple, est obtenue à partir de l’expression formelle :

const-num + EXP(var-num)

en y remplaçant respectivement :

const-num par 12

var-num par A

De même, les expressions prenant des valeurs de type chaîne de caractères seront désignées par exp chaîne éventuellement suivie d’un chiffre, ce qui pourra donner exp chaîne 1 ou exp chaîne 2 lorsque l’on désirera utiliser deux éléments de ce type.

On parlera, par exemple, de l’expression formelle :

var-chaîne = MID$(const-chaîne,var-num-1,const-num)

qui pourra devenir pour une utilisation particulière :

EXTRAIT$ = MID$("SIROS SBASIC",I%,3)

Opérateurs

Trois catégories d’opérateurs sont disponibles.

Les premiers opèrent sur des objets (expressions numériques ou alphanumériques) et permettent de construire d’autres objets plus complexes, c’est-à-dire d’autres expressions plus complexes. Ce sont les Opérateurs arithmétiques et l’Opérateur de concaténation de chaînes.

Les seconds opèrent sur des objets et permettent de former des relations entre ces objets. Ce sont les Opérateurs de relations.

Enfin, la dernière catégorie est celle des Opérateurs logiques qui peuvent opérer sur des relations pour donner d’autres relations, et qui peuvent opérer sur des valeurs numériques pour donner d’autres valeurs numériques.

Operateurs arithmétiques

La première catégorie d’opérateurs, avec laquelle nous sommes le plus familiarisés, est celle des opérateurs arithmétiques. Ces opérateurs permettent de relier deux expressions numériques, pour former des expressions numériques de plus en plus complexes.

Ce sont :

Nom Symbole Exemple Explication
Addition + X+Y Ajoute X à Y
Soustraction - X-Y Soustrait Y de X
Multiplication * X*Y Multiplie X par Y
Division / X/Y Divise X par Y
Exponentiation ** X**Y Elève X à la puissance Y
Modulo MOD X MOD Y Calcule X modulo Y

Dans chacune des phrases précédentes il faut évidemment lire contenu de X et contenu de Y au lieu de X et de Y. Ce n’est que pour des questions de présentation que nous nous sommes permis ce raccourci.

De plus on pourra évidemment remplacer chacune des variables X et Y par une variable entière ou même par une expression numérique quelconque exp-num-1 ou exp-num-2.

Lorsque deux valeurs de type différent sont concernées, un entier et un flottant (nombre réel) par exemple, l’entier est d’abord converti en flottant et l’opération est effectuée. Seul l’opérateur d’exponentiation fait exception à cette règle.

Operateur de concaténation de chaînes

De même que les opérateurs précédents permettent de construire des expressions dont la valeur est de type numérique, il existe un opérateur permettant de construire des expressions alphanumériques plus complexes.

Cet opérateur, représenté par le signe +, permet de relier deux expressions de type chaîne de caractères pour en obtenir une troisième du même type. L’expression suivante :

exp-chaîne-1 + exp-chaîne-2

aura pour valeur la chaîne obtenue en concaténant (mettant bout à bout) les deux chaînes dans l’ordre donné.

Attention : contrairement à l’opération que ce symbole +, représente lorsqu’il agit sur des expressions numériques, la concaténation de chaînes n’est pas commutative. Les valeurs de exp-chaîne-1 + exp-chaîne-2 et de exp-chaîne-2 + exp-chaîne-1 ne sont en général pas égales.

Par exemple si A$ et B$ contiennent respectivement "Sbasic " et "SIROS ", la valeur de A$+B$ est "Sbasic SIROS ", alors que celle de B$+A$ est "SIROS Sbasic ".

Operateurs de relation

Les opérateurs de relation permettent de construire des expressions logiques élémentaires qui pourront être utilisées par exemple dans un test introduit par le mot réservé IF.

Les expressions logiques élémentaires se construisent en comparant, à l’aide de ces opérateurs, des expressions de même type, numérique ou alphanumérique. Les six symboles de relation reconnus par SBASIC sont :

Symbole Exemple Signification
= exp 1 = exp 2 exp 1 égal à exp 2
<> exp 1 <> exp 2 exp 1 différent de exp 2
< exp 1 < exp 2 exp 1 inférieur à exp 2
> exp 1 > exp 2 exp 1 supérieur à exp 2
<= exp 1 <= exp 2 exp 1 supérieur ou égal à exp 2
>= exp 1 >= exp 2 exp 1 inférieur ou égal à exp 2

Lorsqu’il s’agit d’expressions numériques, l’interprétation ne pose aucun problème. Pour les expressions de type alphanumérique, la relation d’ordre utilisée est l’ordre alphabétique des chaînes de caractères. La valeur de l’expression alphanumérique exp-chaîne-1 est supérieure à celle de l’expression alphanumérique exp-chaîne-2 si la chaîne correspondant à la première s’écrit après la chaîne correspondant à la seconde dans le grand dictionnaire des chaînes alphanumériques.

Par exemple, si A$ contient « SIROS », la relation A$ <= "SBASIC" est une relation fausse, car dans l’ordre alphabétique « SIROS » vient après « SBASIC ».

Ces relations logiques élémentaires sont souvent combinées entre elles grâce aux opérateurs logiques (Voir le paragraphe « Operateurs logiques ») pour donner des expressions logiques plus complexes qui seront désignées génériquement dans la suite par exp logique.

Operateurs logiques

La dernière classe d’opérateurs est celle des opérateurs logiques (AND, OR, NOT). Ils permettent de relier des valeurs de type entier ou des expressions logiques.

Operateurs logiques entre valeurs de type entier

Lorsqu’ils relient des valeurs de type entier, les opérateurs logiques permettent de réaliser des opérations bit à bit, afin de former des expressions de type numérique.

Si, par exemple, A% et B% contiennent respectivement les quantités binaires suivantes :

A% contient 11001011111101101100101111110110 (soit -873018378 en décimal)
B% contient 01110101111001000111010111100100 (soit 1977906660 en décimal)

Alors :

A% AND B% a pour valeur 01000001111001000100000111100100 (1105478116) 
A% OR B% a pour valeur 11111111111101101111111111110110 (-589834)
NOT A% a pour valeur 00110100000010010011010000001001 (873018377)

De façon plus générale, les effets des opérateurs logiques sont décrits ci-dessous :

Opérateur Exemple Action
NOT NOT X% Cet opérateur transforme la valeur de chaque bit en son complément (les 1 sont remplacés par des 0 et les 0 par des 1).
AND X% AND Y% Le résultat de cette opération est d’affecter, à chaque bit du résultat, un 1 si chacun des bits de même rang vaut 1 dans X% et Y%.
OR X% OR Y% L’opération met à 1 chaque bit du résultat si l’un ou l’autre des bits de même rang dans X% ou Y% vaut 1.

On peut évidemment, dans chacun des trois exemples précédents, remplacer l’une ou l’autres des variables X% et Y% par une expression numérique.

Dans la mesure où ces opérateurs sont définis par leur effet sur des quantités entières, la représentation interne en virgule flottante de certaines variables et constantes doit d’abord être convertie en entiers. Cette conversion est réalisée automatiquement par l’interpréteur SBASIC.

Ces opérateurs peuvent s’utiliser conjointement aux opérateurs arithmétiques dans des expressions numériques.

Si l’on veut par exemple, pour le contenu d’une variable A% faire la somme de son quotient par 16 et de son reste modulo 16, puis affecter la valeur correspondante à la variable B%, on pourra écrire :

 B% = (A%/16) + (A% AND 15)

Remarque : Pour l’extraction d’un modulo, on ne peut utiliser la formule var-num AND exp-num que si la valeur de exp-num est de 2n -1, n étant un entier compris entre 1 et 31.

Operateurs logiques entre expressions

Les opérateurs logiques AND, OR, NOT peuvent aussi, et c’est en fait leur utilisation la plus fréquente, opérer sur des expressions logiques. Ils permettent alors de former des expressions logiques plus complexes, qui seront le plus souvent testées grâce à l’instruction IF.

Si exp-logique-1 et exp-logique-2 représentent des expressions logiques, on peut former :

Opération | Résultat NOT exp-logique-1 | Vrai si et seulement si exp-logique-1 est fausse. exp-logique-1 AND exp-logique-2 | Vrai si et seulement si exp-logique-1 et exp-logique-2 sont simultanément vraies. exp-logique-1 OR exp-logique-2 | Vrai dès que l’une au moins des deux expressions exp-logique-1 ou exp-logique-2 est vraie.

Dans l’exemple :

40 IF (A$="FIN" AND I%=10) THEN GOTO 100

le programme se branchera à la ligne 100 si la variable A$ contient la valeur « FIN » et si I% contient la valeur 10. Les parenthèses ne sont pas obligatoires, elles ont simplement été placées pour mieux mettre en évidence l’expression logique testée.

Toutefois les deux utilisations des opérateurs logiques peuvent être combinées, car à chaque expression logique on peut, à un instant donné, associer une valeur numérique entière qui vaut 0 si sa valeur logique est FAUX et -1 si elle est VRAI.

On pourra donc par exemple écrire :

var-num = exp-logique-1 AND exp-logique-2

ce qui permettra d’affecter à var-num la valeurs -1 si exp-logique-1 et exp-logique-2 sont toutes deux vraies. L’expression précédente permet évidemment de remplacer avantageusement :

IF exp-logique-1=exp-logique-2 THEN var-num=-1 ELSE var-num=0,

mais exp-logique-1 AND exp-logique-2 peut aussi s’utiliser de la même façon que n’importe quelle autre expression de type numérique.

Priorité entre les operateurs

Quand SBASIC évalue une expression contenant un mélange d’opérateurs mathématiques, il effectue d’abord l’exponentiation, prend en compte ensuite tous les signes moins unaires (comme -3.4 ou -A). Il effectue ensuite les multiplications et divisions, et enfin les additions et soustractions. Lorsque des opérateurs de priorité égale sont rencontrés, c’est celui situé le plus à gauche qui est d’abord exécuté, car SBASIC évalue les expressions de gauche à droite.

L’ordre peut toutefois être modifié par l’utilisation de parenthèses. SBASIC évalue d’abord les quantités entre les parenthèses les plus internes. Les parenthèses doivent être utilisées à chaque fois qu’il y a un doute au sujet de l’évaluation de l’expression.

Lorsque deux valeurs de même type sont concernées, l’opérateur approprié est appelé. Par exemple, lorsque l’on multiplie deux entiers, la routine de multiplication d’entiers est appelée. Si deux nombres en virgule flottante doivent être soustraits, la routine de soustraction en virgule flottante est appelée.

Les priorités entre opérateurs sont indiquées dans le tableau ci-dessous. Les opérateurs sont listés par ordre de priorité décroissante. Les opérateurs de même priorité sont évalués de gauche à droite.

Opérateur Priorité
( ) Expressions placées entre parenthèses
** Exponentiation
- Signe moins (unaire)
* / Multiplication et division
MOD Modulo
+- Addition et soustraction
<> = >= <= Opérateurs de relation
NOT Opérateur NOT
AND Opérateur AND
OR Opérateur OR

Il faut toutefois se rappeler que si, en plus de ces opérateurs, des fonctions interviennent dans l’expression à évaluer, ces dernières ont une priorité encore plus élevée que les parenthèses.

Utilisation de SBASIC en mode direct et en mode programme

Instructions

L’interpréteur SBASIC permet d’analyser et d’exécuter des instructions qui sont construites à partir des mots réservés dont le mode d’emploi détaillé est donné dans la deuxième partie de ce manuel.

A titre d’exemple on peut donner des instructions d’affectation :

LET A = 12 * PI
B = (A + 5) * 12.5
TITRES = "Documentation SBASIC"

ou des instructions d’impression :

PRINT "Dernier chapitre"
PRINT "Page numéro "; NP%

Mode direct

Ces instructions peuvent s’utiliser en MODE DIRECT, c’est à dire telles que nous les avons écrites ci-dessus ; elles sont alors directement analysées et exécutées par SBASIC. On dit alors qu’il s’agit de Commandes.

Si l’on tape au clavier l’avant dernier exemple donné plus haut, suivi d’un Retour-Chariot indiquant à SBASIC que l’on a terminé d’entrer une commande, ce dernier l’exécutera immédiatement : il affichera la chaîne de caractères « Dernier chapitre » dans la fenêtre SBASIC.

Il est possible d’entrer en une seule fois plusieurs commandes que SBASIC exécutera les unes après les autres, il suffit de les séparer par le signe deux points :. Il faut évidemment finir par un Retour-Chariot indiquant à SBASIC que l’utilisateur a terminé sa ligne de commandes. Par exemple on peut taper :

NP%=10 : PRINT "Page "; NP%

ce qui affecte la valeur 10 à la variable entière NP%, puis affiche dans la fenêtre SBASIC le libellé « Page 10 ».

Mode programme

On peut également entrer des instructions que SBASIC n’exécute pas immédiatement, mais qu’il mémorise sous forme de lignes de programme qui seront exécutées ultérieurement. C’est ce que l’on appelle le mode programme.

Avant tout travail dans ce mode, il est conseillé d’exécuter la commande NEW (ne pas oublier le Retour-Chariot final) qui efface toute ligne de programme qui aurait pu être entrée accidentellement par l’utilisateur courant de la machine, ou sciemment par un utilisateur antérieur.

Il est par exemple possible d’entrer le programme suivant :

10 PRINT "Quel est votre nom "
20 INPUT NOM$
30 PRINT "Bonjour "; NOM$

Pour ce faire il suffit à l’utilisateur de frapper au clavier les lignes telles qu’elles sont écrites, en les terminant toujours par un Retour-Chariot. S’il commet une erreur lors de l’entrée de l’une d’entre elles, il lui suffit de la frapper à nouveau.

Contrairement à ce qui s’est passé dans l’exemple précédent, aucun message ne s’affiche lorsque l’utilisateur frappe le Retour-Chariot terminant la première et la dernière ligne. C’est que l’on vient de créer 3 lignes de programme. Pour Exécuter ce programme, l’utilisateur doit frapper au clavier la commande RUN (suivi d’un Retour-Chariot) qui débutera l’exécution du programme.

Ce dernier commencera par demander le nom de l’utilisateur puis le saluera poliment. Si l’utilisateur ne se lasse pas de cette politesse et qu’il désire un nouveau salut, il lui sera inutile de réécrire les lignes de programmes, il lui suffira de frapper à nouveau la commande RUN, c’est ce qui fait tout l’intérêt du mode programme.

Sauvegarde et chargement d’un programme

Malheureusement ce programme phénoménal se trouve dans la mémoire centrale de la machine qui est constituée de mémoire vive (RAM) dans laquelle on peut écrire facilement, mais qui s’efface tout aussi facilement à la moindre coupure de courant. Si l’utilisateur veut conserver son programme, il lui suffit de l’enregistrer sur disque en utilisant la commande :

SAVE "PREMIER"

qui lui permettra de le sauvegarder sur disque dans un fichier nommé « PREMIER ». En fait le nom complet du fichier, tel qu’il pourra apparaître dans un répertoire de fichiers, sera « PREMIER.BAS », mais l’extension .BAS est gérée automatiquement par le système et l’utilisateur n’a pas à s’en préoccuper pour l’instant.

Après une interruption du courant ou même l’utilisation de la commande NEW, l’utilisateur pourra recharger les trois lignes du programme précédent en tapant la commande :

LOAD "PREMIER"

S’il utilise alors la commande :

LIST

qui permet de LISTer le programme se trouvant en mémoire centrale, il pourra vérifier qu’il a effectivement retrouvé le programme initial.

Utilisation conjointe du mode programme et du mode direct

Il est possible de panacher les deux modes d’utilisation de l’interpréteur SBASIC. Même après l’exécution du programme précédent la variable NOM$ n’a pas « perdu » son contenu et l’utilisateur peut taper l’ordre :

PRINT NOM$

qui permettra de vérifier son contenu. Cette dernière possibilité, dans laquelle réside une grande partie de l’intérêt des langages interprétés, offre de grandes facilités lors de la mise au point et le dépannage des programmes écrits en SBASIC. Elle est aussi utilisable lorsque le programme a été interrompu par une instruction STOP, l’appui simultané sur les touches Ctrl et C (notée Ctrl-C dans la suite de ce manuel) ou la survenue d’une erreur.

Description d’une ligne de programme SBASIC

Chaque ligne de programme BASIC commence par un numéro de ligne. La ligne peut contenir une ou plusieurs instructions séparées par le caractère « : » et s’achève par un Retour-Chariot.

La longueur d’une ligne ne peut dépasser 255 caractères. Les lignes peuvent être numérotées de 1 à 2147483647 et chacune d’entre elles a un numéro unique. Lorsque SBASIC exécute un programme, il interprète les lignes dans l’ordre croissant de leurs numéros.

Lorsque l’on écrit un programme, il est conseillé de numéroter les lignes de 10 en 10, ou de 20 en 20 afin de pouvoir, éventuellement par la suite, en insérer facilement de nouvelles.

On peut aussi laisser des espaces pour rendre plus aisée la lecture d’un programme. Dans les exemples suivants, les instructions 30 et 40 sont identiques, mais la ligne 40 est plus facile à lire. Il est recommandé de mettre un espace entre un mot clé et un nom de variable. Un espace est obligatoire entre un nom de variable de type virgule flottante et un mot clé.

Exemples d’utilisation d’espaces :

30X=32*X/3+7.3*X/2+6.54*X-.1
40 X=  32*X/3  +  7.3*X/2  +  6.54*X  -  .1

Exemple de ligne où un espace est obligatoire :

100 IF IND=0 THEN PRINT VITESSE ELSE PRINT TEMPS

le seul espace obligatoire est celui placé entre VITESSE et ELSE ; les autres sont facultatifs.

Exemple comportant plusieurs instructions par ligne :

120 INPUT "VITESSE, TEMPS"; V,T : D = V*T : PRINT "DISTANCE ="; D

Restrictions sur l’utilisation en modes direct et programme

La majeure partie des instructions du SBASIC peut s’utiliser en mode direct et en mode programme. Toutefois, certaines d’entre elles ne peuvent s’utiliser que dans l’un des deux modes.

Les commandes pures

Voici la liste des commandes ne pouvant s’utiliser qu’en mode direct. Elles ne peuvent donc figurer dans les lignes d’un programme.

Commande Action
BREAK ON Valide la possibilité d’arrêter un programme en cours de traitement au moyen de la combinaison de touches Ctrl-C. Cette option est prise par défaut au chargement du SBASIC.
BREAK OFF Invalide l’action Ctrl-C.
CONT ou CONTINUE La commande CONTinue est utilisée pour faire redémarrer un programme arrêté par une instruction STOP ou un appui sur Ctrl-C.
EDIT Pour modifier une ligne de programme, il suffit de taper EDIT suivi du numéro de la ligne à modifier.
LIST Commande permettant de donner la liste, dans la fenêtre SBASIC, de tout ou partie du programme se trouvant en mémoire centrale.
NEW Efface le programme se trouvant en mémoire centrale.
PLIST Identique a la commande LIST, mais avec édition dans le tampon d’impression.
RENUM ou RENUMBER Effectue la renumérotation totale ou partielle du programme en mémoire.
RUN La commande RUN indique à SBASIC de démarrer l’exécution du programme se trouvant en mémoire centrale.
SAVE Cette commande est utilisée pour stocker sur disque, sous forme source (sous forme texte), tout ou partie du programme SBASIC se trouvant en mémoire centrale.
STACK Affiche la pile d’exécution du programme arrêté par une instruction STOP, un appui sur Ctrl-C ou la détection d’une erreur.
STEP Relance, pour une seule ligne, l’exécution du programme arrêté par une instruction STOP ou un appui sur Ctrl-C.
SYSTEM ou EXIT La commande SYSTEM est utilisée pour quitter SBASIC.
TRACE ON Active la fonction TRACE.
TRACE OFF Désactive la fonction TRACE.
Mots réservés ne pouvant pas être utilisés en mode direct

L’instruction READ et le mot réservé DATA ne peuvent s’utiliser qu’en mode programme. Un rapide coup d’œil à leur description détaillée permettra d’en comprendre la raison.

Utilisation des fichiers

Lorsqu’un programme SBASIC doit gérer des données en nombre trop important pour pouvoir être rentrées à chaque fois depuis le clavier, on utilise des fichiers sur disque que le programme peut lire lorsqu’il a besoin de ces données ou sur lesquels il peut écrire pour les mettre à jour.

Les fichiers que l’on peut utiliser sont de 2 types :

  • Les Fichiers à accès séquentiel
  • Les Fichiers à accès direct

Les premiers doivent s’écrire et se lire séquentiellement à l’instar d’une bande de magnétophone ou de magnétoscope alors que pour les seconds il est possible d’accéder directement à un enregistrement donné et de le modifier, ce qui correspond au fonctionnement d’un disque.

Fichier séquentiel d’entrée-sortie

La forme la plus simple d’utilisation des fichiers de données est la forme séquentielle dans laquelle les données sont écrites les unes derrière les autres, séparées par des Retour-Chariot ou par des virgules.

Ouverture en écriture d’un fichier séquentiel

Avant d’écrire dans un fichier sous SBASIC, il est nécessaire de « l’ouvrir ». C’est l’ordre OPEN qui est utilisé pour cette opération. Il permet d’affecter un canal au fichier concerné et de lui réserver en mémoire centrale une zone de mémoire tampon d’entrées-sorties ou simplement tampon (ou buffer), par laquelle transiteront les échanges avec le disque.

Imaginons que l’on veuille constituer un fichier contenant les 6 premiers entiers ainsi que leurs carrés avec quelques explications, à savoir :

  • le libellé « Liste des 6 premiers entiers »,
  • puis les 6 premiers entiers « 1 », « 2 », …, « 6 »,
  • puis le libellé « leurs carrés »,
  • enfin les 6 carrés « 1 », « 4 », …, « 36 ».

On commence par ouvrir un « nouveau » fichier au moyen de l’instruction :

100 OPEN NEW "CARRE" AS 1

qui indique que l’on veut ouvrir sur le canal 1 un fichier qui aura pour nom sur le disque, « CARRE », en fait « CARRE.DAT », car, par défaut, SBASIC utilise l’extension .DAT pour les fichiers de données.

Si un fichier de ce nom existait déjà sur le disque il est détruit sans avertissement, c’est en ce sens que tout fichier séquentiel ouvert en écriture est forcément un « nouveau » fichier.

Ecriture dans un fichier séquentiel

Pour écrire dans le fichier séquentiel précédemment ouvert sur le canal 1, il suffit d’utiliser une version légèrement modifiée de l’ordre PRINT.

La ligne :

110 PRINT #1 "Liste des 5 premiers entiers"

permet d’écrire, dans le fichier ouvert sur le canal 1, le libellé « Liste des 5 premiers entiers ».

De même la ligne :

120 FOR I%=1 TO 6: PRINT #1 I%: NEXT I%

permet d’y écrire les 6 premiers entiers « 1 », « 2 », …, « 6 ». Chacun étant séparé du précédent par un Retour-Chariot.

Pour terminer il suffira d’écrire :

130 PRINT #1 "leurs carrés"
140 FOR I%=1 TO 6: PRINT #1 I%*I%: NEXT I%

Toutefois il ne faut pas oublier de fermer le fichier par l’instruction :

200 CLOSE 1

Cette instruction permet tout d’abord de libérer le canal utilisé, ici le canal 1, afin de pouvoir éventuellement le réutiliser pour la lecture ou l’écriture d’un autre fichier.

Mais elle a une autre fonction bien plus importante dans l’exemple qui nous préoccupe : elle écrit effectivement sur disque les données qui peuvent encore se trouver dans le buffer associé au fichier. En effet, dans le but d’accélérer les opérations, l’écriture sur disque ne se produit pas effectivement lors de l’exécution de chaque ordre PRINT #1. Les données sont stockées dans un buffer, une mémoire tampon, dont la taille varie en fonction du système utilisé et qui est recopié sur le disque lorsqu’il est plein. C’est la seconde fonction de l’ordre CLOSE que d’effectuer l’écriture de cette partie résiduelle.

Après l’exécution de ce petit programme on doit trouver sur disque le fichier « CARRE.DAT » qui pourra être listé.

Le programme précédent peut paraître simpliste, mais il illustre la façon d’éviter de saisir à la main les éléments à écrire dans le fichier. Un programme plus général d’écriture en fichier doit comporter 2 phases bien distinctes :

  • Une phase de saisie qui permettra à l’utilisateur, grâce à un certain nombre d’ordres INPUT, de rentrer des données en mémoire centrale en les frappant au clavier.
  • Une phase d’écriture effective dans le fichier, qui grâce à des ordres PRINT, permettra de faire passer ces données de la mémoire centrale vers le fichier se trouvant sur le disque.
Ouverture d’un fichier en lecture

Après avoir exécuté le programme précédent et l’avoir, le cas échéant, sauvegardé, il est maintenant temps de savoir comment récupérer les données que l’on a écrites dans ce fichier, en vue de leur éventuelle utilisation par un programme SBASIC.

Il faut d’abord « ouvrir » le fichier pour le relire. C’est un fichier qui existe déjà sur le disque, un ancien fichier ; on utilisera donc l’instruction :

100 OPEN OLD "CARRE" AS 2

qui indique à SBASIC que l’on veut ouvrir le fichier « CARRE », en fait « CARRE.DAT », en vue de le lire.

Lecture d’un fichier séquentiel

De même que l’écriture dans un fichier séquentiel utilisait l’ordre PRINT #, la lecture utilise l’ordre symétrique : INPUT #.

On commencera par relire la première chaîne :

110 INPUT #2 A$

puis on pourra retrouver les 6 valeurs numériques que l’on avait écrites, mais il faut, pour ce faire, préparer un tableau NOMBRE pour les stocker en mémoire centrale. On écrira donc :

120 DIM NOMBRE(6): FOR I%=1 TO 6: INPUT #2 NOMBRE(I%): NEXT I%

Pour se convaincre que l’on a bien récupéré les valeurs précédemment écrites dans le fichier, on peut insérer dans cette boucle l’instruction PRINT NOMBRE(I%) ou même réaliser une autre boucle d’impression.

On récupère ensuite les autres valeurs de manière analogue :

130 INPUT #2 B$
140 DIM CARRE(6): FOR I%=1 TO 6: INPUT #2 CARRE(I%): NEXT I%

Enfin il faut fermer le fichier au moyen de l’instruction :

200 CLOSE 2

dont le seul effet, ici, est de libérer le canal utilisé.

Une première remarque s’impose à la lecture de ce programme : il faut connaître la structure logique du fichier pour être en mesure de le relire. Ici, il fallait savoir qu’il contenait un libellé, six valeurs numériques, un autre libellé et les six dernières valeurs numériques. Si l’on avait commis une erreur, par exemple en oubliant de lire le libellé central (omission de la ligne 130), une erreur 30 se serait produite en ligne 140 puisque le programme aurait alors essayé de lire une valeur numérique et que le fichier lui aurait présenté le libellé central, constitué d’une chaîne de caractères.

Toutefois, chaque nombre étant stocké dans un fichier séquentiel sous forme de la chaîne de caractères qui permet de l’écrire, il est toujours possible de relire un fichier séquentiel en considérant tous ses éléments comme des chaînes de caractères.

Après avoir frappé et exécuté une première fois le programme précédent, l’utilisateur peut ajouter l’instruction :

150 INPUT #2 C$

et exécuter le programme ainsi modifié. Lors de l’exécution de la ligne 150, il se produit une erreur 8, (voir « Annexe 1 : Liste des commandes, instructions et fonctions ») qui indique la fin du fichier séquentiel. Cette erreur peut évidemment être gérée sous SBASIC, à condition de l’avoir prévu, en utilisant l’instruction ON ERROR GOTO.

Cette modification permet donc de se rendre compte qu’il n’est pas nécessaire de connaître le nombre exact d’éléments d’un fichier séquentiel. Il suffit dans ce cas de prévoir l’occurrence d’une erreur de fin de fichier dont la prise en compte permettra un branchement vers la suite du traitement.

Correspondance entre les ordres PRINT, PRINT #, INPUT, INPUT #

Pour éviter toute confusion dans l’utilisation des instructions PRINT, PRINT #, INPUT, INPUT #, il est bon de se rappeler que SBASIC opère sur des données qui doivent se trouver en mémoire centrale.

Les instructions INPUT et INPUT # permettent d’introduire ces données en mémoire centrale, qu’elles proviennent du clavier ou d’un fichier disque qui, tous deux, sont des périphériques par rapport à la mémoire centrale. Le fichier fournit des données ASCII tout à fait comme si ces dernières étaient entrées au clavier.

De même, les ordre PRINT et PRINT # permettent de diriger des données vers les périphériques externes que sont l’écran et le disque. Dans le premier cas on écrit sur l’écran dans la fenêtre SBASIC, dans le second on écrit dans un fichier.

Autres séparateurs, cas particuliers

Jusqu’à présent nous avons, dans le fichier, séparé les données par des Retour-Chariot, mais il est aussi possible de les séparer par des virgules. Il suffit de mettre ces dernières dans la chaîne écrite dans le fichier à l’aide de l’ordre PRINT #.

Lorsqu’on utilise la virgule comme séparateur, il faut se souvenir qu’elle joue un rôle de séparateur aussi bien pour l’instruction INPUT que pour l’instruction INPUT #.

De même les limitations concernant les chaînes vides sont les mêmes que celles relatives à l’instruction INPUT. Donc si certains des éléments d’un fichier sont des chaînes contenant des virgules, voire des chaînes vides, il faudra utiliser l’instruction INPUT LINE # à la place de l’instruction INPUT #.

Il est aussi possible d’utiliser l’instruction PRINT # suivie du symbole « ; », ce qui a pour effet de ne pas introduire de Retour-Chariot après la donnée concernée par cet ordre. La donnée que l’on écrira ensuite dans le fichier lui sera alors concaténée et lors de la relecture il sera impossible de les dissocier par de simples ordres INPUT. Dans ce cas il ne faut pas oublier que la dernière donnée écrite dans le fichier doit être suivie d’un Retour-Chariot.

L’utilisation de PRINT # suivie du symbole « , » est autorisée. Elle introduit dans le fichier un nombre d’espaces correspondant à celui des espaces nécessaires à la tabulation liée à la virgule.

Enfin on peut aussi signaler l’instruction INCH$ qui permet de relire un fichier séquentiel caractère par caractère. Pour un fichier ouvert sur le canal 1, l’instruction :

R$=INCH$(1)

permettra d’affecter à la variable R$ le caractère suivant du fichier.

Utilisation du canal 0
Instruction INPUT sur le canal 0

Il est parfois souhaitable de saisir des données au clavier sans voir apparaître le signe « ? » à chaque exécution de l’ordre INPUT. Ceci est possible en utilisant le canal 0.

Exemple :

10 INPUT #0 B$
20 INPUT LINE #0 A$

Les instructions INPUT de cet exemple sont utilisés comme des ordres INPUT normaux.

Instruction PRINT sur le canal 0

Il est souvent nécessaire d’effectuer des sorties SBASIC sur un fichier plutôt que dans la fenêtre SBASIC. Le canal 0 permet d’aiguiller en sortie les ordres PRINT, vers la fenêtre SBASIC ou un fichier.

L’utilisation de l’instruction PRINT #0, sans celle préalable de l’instruction OPEN permet l’affichage direct de données dans la fenêtre SBASIC comme une instruction PRINT ordinaire.

Exemple :

20 PRINT #0 "CECI EST UN TEST"

affiche dans la fenêtre SBASIC « CECI EST UN TEST », comme si « #0 » n’était pas spécifié.

En revanche, l’ouverture du canal 0 permet d’aiguiller les données vers un fichier. L’utilisation de l’instruction OPEN NEW ou OPEN APPEND avec 0 comme numéro de canal 0 demande à SBASIC d’utiliser ce fichier de sortie chaque fois que l’ordre PRINT #0 est utilisé.

Exemple :

10 OPEN NEW "OUTPUT" AS 0
20 PRINT #0 "CECI EST UN TEST"
30 CLOSE 0

Le fichier « OUTPUT.DAT » est créé et contient le texte « CECI EST UN TEST ».

Les ordres PRINT ne spécifiant pas « #0 » continueront à afficher les données dans la fenêtre SBASIC L’ordre CLOSE 0 indiquera à SBASIC d’aiguiller à nouveau, vers la fenêtre SBASIC, toutes les données relatives à des instructions PRINT #0 et ce, jusqu’à l’exécution d’un autre ordre OPEN … AS 0.

L’exemple suivant illustre l’utilisation de l’instruction PRINT # sur le canal 0. Ce programme permet de choisir la fenêtre SBASIC ou un fichier pour éditer les résultats.

10 INPUT "ECRAN OU FICHIER ? (E / F)"; R$
20 IF R$ ="F" THEN OPEN NEW "OUTPUT" AS 0
30 FOR I=1 TO 10
40 PRINT #0 I, SQR(I)
50 NEXT I
60 IF R$="F" THEN CLOSE 0
70 END

Les tableaux virtuels

Le tableau virtuel est l’exemple le plus simple de fichier à accès direct. Il permet de spécifier qu’un ensemble de données doit résider sur disque plutôt qu’en mémoire centrale. A l’intérieur d’un programme SBASIC, les données virtuelles sont référencées comme des éléments de tableau, ce qui autorise puissance et simplicité d’emploi.

Les deux avantages de ce concept sont que le tableau peut avoir jusqu’à 2147483647 éléments, quelle que soit la taille mémoire centrale disponible, et que les données, dès leur affectation, résident sur le disque. Elles sont donc permanentes et peuvent être réutilisées.

La seule restriction au regard d’un fichier accédé par enregistrement, est que tous les éléments doivent être du même type : entiers, réels ou chaînes de caractères et que, dans ce dernier cas, toutes les chaînes doivent avoir la même longueur.

Le tableau virtuel permet d’accéder directement, en lecture et en écriture, à une donnée quel que soit son emplacement dans le fichier disque.

Ouverture d’un tableau virtuel

Avant d’être référencé, un tableau virtuel doit être ouvert au moyen de l’instruction OPEN, comme dans l’exemple suivant :

100 OPEN "VIRT" AS 1

Cette instruction va permettre d’accéder aux données du fichier « VIRT.DAT ». Mais pour indiquer qu’il s’agit d’un tableau virtuel et non d’un fichier accédé par enregistrement ainsi que pour en préciser le type, il faut dimensionner le tableau qui permettra de manipuler les éléments de ce fichier. On utilise pour cela une forme spéciale de l’instruction DIM.

Imaginons que l’on désire stocker les 10 premiers carrés « 1 », « 4 », …, « 100 ». On peut écrire :

110 DIM #1 NO%(10)

qui indique à SBASIC que le fichier ouvert sur le canal 1 est un tableau virtuel d’entiers pouvant contenir jusqu’à 11 éléments.

Pour ouvrir un fichier virtuel destiné à recevoir des chaînes de caractères, on utiliserait :

500 OPEN "TEXTE" AS 3
510 DIM #3 A$(50)=63

ce qui indiquerait à SBASIC que les données du fichier « TEXTE.DAT » sont les éléments du tableau A$(*) et que toutes ces chaînes ont une longueur de 63 caractères.

On retrouve ici l’une des contraintes signalées au début de ce chapitre : toutes les chaînes utilisées doivent avoir la même longueur pour que SBASIC puisse accéder directement à l’une d’entre elles. Dans l’exemple traité, elle est de 63 caractères.

Si aucune longueur n’est spécifiée, comme dans l’instruction :

510 DIM #3 A$(50)

la longueur prise par défaut est 18.

Si l’on affecte à l’un des éléments d’un tableau virtuel de chaînes de caractères une valeur de type alphanumérique dont la longueur est inférieure à celle des éléments du tableau, SBASIC complète ces valeurs par des espaces de façon à obtenir la longueur spécifiée. Dans le cas contraire, la valeur est tronquée.

Il est aussi possible de considérer les éléments d’un tableau virtuel comme ceux d’une matrice à deux dimensions. Si l’on veut, par exemple, traiter les éléments du fichier « MATRICE » comme ceux d’une matrice de nombre réels de 10 lignes et 5 colonnes, on écrira :

700 OPEN "MATRICE" AS 5
710 DIM #5 N(9,4)

Les tableaux virtuels à deux dimensions peuvent également contenir des entiers, des réels ou des chaînes de caractères ; dans ce dernier cas, il faut aussi spécifier la longueur des chaînes si l’on veut utiliser une longueur différente de la longueur par défaut.

SBASIC supporte un nombre quelconque de dimensions à condition que le nombre total d’éléments ne dépasse pas 2147483647.

Utilisation des tableaux virtuels

Après l’ouverture du fichier et la déclaration au moyen de l’instruction DIM, le tableau virtuel peut être utilisé dans des instructions d’affectation et dans des expressions comme un tableau ordinaire, avec, toutefois, les restrictions suivantes :

  • Il ne peut apparaître comme paramètre ou comme élément de la liste d’appel d’un sous-programme (instruction SUB) ;
  • Aucun de ses éléments ne peut être modifié au moyen des instructions SET, LSET, RSET et SWAP.

Pour créer le fichier contenant les 10 premiers carrés introduit plus haut, on écrit :

100 OPEN "VIRT" AS 1
110 DIM #1 NO%(10)
120 FOR I%=1 TO 10
130 NO%(I%)= I%* I%
140 NEXT I%
150 CLOSE 1

Dans ce programme, les écritures dans le fichier sont réalisées au moyen des affectations exécutées en ligne 130 ; il ne faut pas, pour un tableau virtuel, utiliser l’instruction PRINT # ; cette dernière est réservée aux fichiers séquentiels.

Toutefois on retrouve le même mécanisme que celui mis en œuvre lors de l’utilisation de fichiers à accès séquentiel : l’écriture effective dans le fichier n’est pas vraiment réalisée lors de l’exécution de la ligne 130. Les données sont seulement stockées dans une mémoire tampon (buffer) de transit qui est périodiquement écrite sur disque. Il faut donc se souvenir que l’instruction CLOSE de la ligne 150 permettra non seulement de libérer le canal utilisé par le tableau virtuel, mais qu’elle provoquera aussi l’écriture sur le fichier de la partie résiduelle des données qui pourrait se trouver encore dans la mémoire tampon.

Pour modifier l’une des valeurs du fichier d’entiers précédemment écrit sur disque sous le nom « VIRT.DAT », il suffit d’écrire :

100 OPEN "VIRT" AS 1
110 DIM #1, NO%(10)
120 INPUT "Rang de la valeur à modifier"; I%
130 IF I%=0 THEN 200
140 PRINT "Valeur courante :"; NO%(I%)
150 INPUT "Nouvelle valeur :"; NO%(I%)
160 GOTO 120
200 CLOSE 1: END

L’utilisation de la valeur NO%(I%), en ligne 140, suffit pour forcer SBASIC à la relire dans le fichier.

L’affectation réalisée grâce à l’instruction INPUT en ligne 150, suffit pour écrire la nouvelle valeur dans le fichier.

Un programme similaire de mise à jour peut aussi être écrit pour un fichier de chaînes.

Remarques sur les tableaux virtuels

Un fichier créé et référencé comme tableau virtuel ne comporte pas d’information sur la dimension du tableau et le type des données qu’il contient.

Un secteur de 512 octets, peut être considéré comme contenant :

  • 64 réels (codés sur 8 octets chacun par la fonction CVTF$)
  • 256 entiers (codés sur 2 octets chacun par la fonction CVT%$)
  • 4 chaînes de 128 caractères
  • 16 chaînes de 32 caractères

Une matrice est rangée par lignes, c’est-à-dire en commençant par la ligne 0 au début du fichier, suivie de la ligne 1, etc. Cette disposition est importante pour deux raisons :

  • L’accès séquentiel aux éléments d’une matrice est plus rapide lorsqu’il est réalisé ligne par ligne que colonne par colonne. En effet l’accès par ligne réalisera une lecture séquentielle du fichier, secteur après secteur, alors que l’accès par colonne va multiplier le nombre de chargements en mémoire des secteurs.
  • La déclaration de dimension d’un tableau virtuel comprend un ou deux indices, alors qu’un fichier est une collection d’objets séquentiels qu’un programme peut exploiter en définissant, de façon externe au fichier, une structure plus élaborée -une matrice- qui n’est d’ailleurs pas forcément figée.

Supposons par exemple qu’un tableau virtuel ait été créé comme une matrice 50x50 par l’instruction :

DIM #1 A(49,49)

Le fichier disque correspondant contient alors 2500 éléments qui pourront par la suite être considérés comme une simple liste dont la dimension peut être inférieure à 2500, certains éléments restant ignorés du programme.

Ce même fichier pourra donc être ultérieurement ouvert en lecture et dimensionné au moyen de l’instruction

DIM #1 B(1000)

ce qui permettra d’accéder aux mille premiers éléments de ce fichier.

Extension d’un tableau virtuel

Lors de sa création, un fichier à accès direct ne contient aucun secteur accessible à l’utilisateur. La référence en lecture à un élément d’un tableau virtuel non écrit provoquera une erreur 24 semblable à une erreur fin de fichier, en lecture d’un fichier séquentiel.

Un fichier à accès direct peut être étendu à tout moment en affectant une valeur à un élément du tableau virtuel extérieur au fichier. Chaque fois qu’une extension est demandée, SBASIC ajoute au fichier, si nécessaire, les enregistrements se trouvant dans le même secteur que 1’enregistrement écrit ; mais ces derniers sont alors remplis de caractères NUL (CHR$(0)).

Exemple :

100 OPEN "DATA" AS 1
120 DIM # 1 A(250)
130 PRINT A(250)

provoquera une erreur 24, car l’élément 250 n’existe pas dans le fichier nouvellement créé. Pour contenir 250 éléments le fichier doit être étendu de la façon suivante :

100 OPEN "DATA" AS 1
120 DIM # 1 A(250)
125 A(250)=0
130 PRINT A(250)

Nous avons décrit jusqu’à présent deux méthodes d’entrée-sortie disque : la méthode séquentielle avec les instructions PRINT # et INPUT #, et la méthode d’accès direct avec les tableaux virtuels. L’accès séquentiel est simple à utiliser, mais restreint les possibilités d’accès aux données contenues dans un fichier. Les tableaux virtuels assurent un accès sélectif rapide, mais ne permettent pas de mélanger différents types de données dans un même fichier.

SBASIC propose une troisième méthode d’entrée-sortie sur disque, la méthode d’accès direct par enregistrement. Les données sont accessibles de façon aléatoire et tous les types (entier, réel, chaîne de caractères) peuvent être présents dans le même fichier. Les fichiers utilisés dans ce cas sont aussi appelés fichiers à accès direct.

Cette méthode repose sur le fait que les données écrites sur disque sont contenues dans des enregistrements physiques de longueur fixe. Chaque enregistrement d’un fichier doit pouvoir être lu ou écrit sur demande, indépendamment des données qu’il contient. Dans chacun des enregistrements on peut mettre des chaînes de caractères aussi bien que des données numériques, entières ou réelles, écrites en binaire, ce qui évite leur conversion lors des opérations d’entrée-sortie. La méthode est donc efficace et rapide pour traiter les données contenues dans un fichier disque.

Dans la suite nous envisagerons le traitement d’un fichier du personnel, contenant pour chaque employé les renseignements suivants :

  • Un nom contenant au plus 30 caractères,
  • Un prénom contenant au plus 12 caractères,
  • Un salaire, nombre réel codé sur 8 caractères par la fonction CVTF$.

On utilisera donc un fichier à accès direct dont chaque enregistrement aura pour longueur 50 octets, somme des longueurs de chacun des trois champs listés ci-dessus.

Ouverture des fichiers accessibles par enregistrement

Les fichiers auxquels on peut accéder par enregistrement sont des fichiers à accès direct semblables à ceux utilisés pour stocker les tableaux virtuels. Ils sont également ouverts au moyen l’instruction OPEN. Il faut noter que toute tentative d’accès direct sur un fichier séquentiel provoquera une erreur.

Si l’on veut créer, mettre à jour ou tout simplement utiliser le fichier à accès direct, « PERSON.DAT », décrit ci-dessus, contenant les noms, les prénoms et les salaires des employés d’une société, il suffit d’exécuter :

 100 OPEN "PERSON" AS 1 LEN 50

qui indique a SBASIC de réserver le canal 1 pour communiquer avec le fichier disque « PERSON.DAT », dont chaque enregistrement a pour longueur 50.

Communication entre le disque et la mémoire centrale

Un fichier à accès direct communique avec la mémoire centrale de l’ordinateur par l’intermédiaire d’une zone tampon – la mémoire tampon - dont la longueur est égale à la longueur d’un enregistrement et qui contient l’enregistrement en cours de traitement.

Les instructions GET et PUT, que nous verrons dans la deuxième partie, permettent le transfert des données d’un enregistrement vers la mémoire tampon et inversement, de la mémoire tampon vers un enregistrement du disque. Il faut donc affecter des valeurs aux différents éléments de cette mémoire tampon ou, inversement, lire celles provenant du fichier.

Il convient donc au préalable définir les différentes zones de cette mémoire tampon en lui associant des variables. Cela est réalisé au moyen d’une forme spéciale de l’instruction FIELD ; chaque zone du tampon est alors identifiée par une variable de type chaîne de caractères.

Dans l’exemple qui nous préoccupe, nous utiliserons les variables suivantes :

  • NOM$ d’au plus 30 octets pour le nom de l’employé
  • PRE$ d’au plus 12 octets pour le prénom de l’employé
  • SAL$ pour le salaire de l’employé, codé au moyen de la fonction CVTF$

Il faut alors associer ces variables à la mémoire tampon du fichier ouvert sur le canal 1, ce qui-est réalisé au moyen de l’instruction suivante :

110 FIELD #1, 30 AS NOM$, 12 AS PRE$, 8 AS SAL$

qui découpe le tampon d’entrée-sortie en trois zones associées respectivement aux variables NOM$, PRE$ et SAL$.

Mais on souhaite aussi désigner par NNN$ l’ensemble nom + prénom. Il suffit alors d’exécuter la ligne 115 après la ligne 110 :

115 FIELD #1, 42 AS NNN$

ce qui permettra de disposer de 4 variables de communication entre le programme et la mémoire tampon associée au fichier.

Il faut toutefois prendre garde au fait que les variables NOM$, PRE$, SAL$ et NNN$ sont d’un genre très particulier et qu’il ne faut jamais leur affecter de valeurs au moyen d’une instruction LET - implicite ou explicite -, ce qui aurait pour conséquence d’annuler leur lien avec la mémoire tampon associée au fichier. Il ne faut donc utiliser que les instructions RSET, LSET ou SET lorsque l’on désire affecter directement une valeur à l’une de ces variables.

Il faut aussi se rappeler que le contenu de chacune d’entre elles est modifié chaque fois que l’on change le contenu de la mémoire tampon associée au moyen à l’instruction GET.

De même, il ne faut pas s’étonner que la modification du contenu de PRE$ par exemple, entraîne celle de la valeur de NNN$ dont PRE$ contient en fait les 12 derniers caractères.

On peut écrire dans la mémoire tampon grâce aux instructions suivantes :

200 RSET NOM$="DUPONT"
210 RSET PRE$="Jean"

ce qui donnera, à la variable NNN$, la valeur : DUPONT_____________________Jean____________

où le caractère « _ » représente un espace, les chaînes « DUPONT » et « Jean » ayant été complétées par suffisamment d’espaces pour s’adapter aux longueurs données pour les variables NOM$ et PRE$.

Pour enregistrer, par exemple, le salaire de 8715,25 dans la zone correspondante, il faut utiliser l’instruction :

215 RSET SAL$=CVTF$(8715.25)

qui écrit dans la troisième zone de la mémoire tampon la représentation binaire du nombre réel 8715.25. Cette représentation binaire n’a rien à voir avec la chaîne permettant d’imprimer ce nombre et qui serait obtenue au moyen de la fonction STR$ ; c’est une suite des huit octets permettant de coder ce nombre en mémoire centrale ; elle est illisible pour le commun des mortels, mais présente un double avantage :

  • Elle offre un format fixe de 8 octets quelle que soit la valeur du nombre représenté,
  • Elle évite les conversions lors de la lecture ou de l’écriture d’un enregistrement.

Si l’on veut enregistrer un nombre entier dans un fichier il faut lui associer, dans la mémoire tampon, une variable de longueur 2 et le coder grâce à la fonction CVT%$, qui permet d’obtenir la chaîne des deux octets représentant ce nombre en mémoire centrale.

Les instructions GET et PUT

L’écriture des données dans la mémoire tampon comme précédemment, il faut transférer le contenu de cette dernière vers le fichier. On réalise cela grâce à l’instruction PUT. Ainsi, l’instruction :

300 PUT #1 RECORD 5

permet d’écrire le contenu la mémoire tampon dans l’enregistrement numéro 5 du fichier : DUPONT________________________Jean_________8715.25

Si l’on exécute ensuite :

400 RSET PRE$="Jacques"
410 PUT #, RECORD 8

on transfère la mémoire tampon, qui vaut alors : DUPONT________________________Jacques_____8715.25

dans l’enregistrement numéro 8 du fichier.

De même :

500 RSET NOM$="DURAND": RSET PRE$="Pierre": RSET SAL$=CVTF$(6123.20)
510 PUT #1 RECORD 12

permet d’écrire le contenu de la mémoire tampon : DURAND________________________Pierre_______6132.20

dans l’enregistrement numéro 12 du fichier ouvert sur le canal 1.

Pour relire les données figurant dans un enregistrement du fichier, il faut commencer par les transférer dans la mémoire tampon au moyen de l’instruction GET, ce qui modifie automatiquement le contenu des variables associées à ce tampon.

Dans notre exemple, pour relire l’enregistrement numéro 8, il suffit d’exécuter :

600 GET #1 RECORD 8

Si l’on exécute ensuite :

610 PRINT NOM$, PRE$, CVT$F(SAL$)

on verra s’afficher dans la fenêtre SBASIC : DUPONT________________________Jacques_____8715.25

Il ne faut veiller à utiliser la fonction CVT$F, symétrique de la fonction CVTF$, qui permet de convertir en un nombre affichable la chaîne SAL$ codée en format interne.

Dans les instructions PUT et GET, la partie RECORD… est optionnelle : si elle n’est pas spécifiée, c’est l’enregistrement suivant le dernier auquel on a accédé qui est lu ou écrit (accès séquentiel).

Tenter de lire un enregistrement du fichier qui n’a pas été préalablement écrit provoque une erreur. Ecrire un enregistrement de numéro supérieur au dernier enregistrement écrit étend automatiquement le fichier.

Dans l’exemple qui nous intéresse, essayer de lire l’enregistrement numéro 17, provoque une erreur 24.

Il en est de même pour l’accès à l’enregistrement numéro 5.

Extension des fichiers à accès direct

Le mécanisme de création et d’extension des fichiers à accès direct est le même que pour les fichiers associés aux tableaux virtuels. Lors de sa création, le fichier ne contient aucun enregistrement. Tenter de lire un enregistrement inexistant provoque une erreur 24. Le fichier peut être étendu à tout moment par l’écriture d’un enregistrement qui n’existe pas encore.

Chaque fois qu’un enregistrement est écrit, SBASIC ajoute au fichier, si nécessaire, les enregistrements se trouvant dans le même secteur et qui n’ont pas encore été écrits ; ils sont alors remplis de caractères nuls, tels que ceux obtenus au moyen de la fonction CHR$(0).

Par exemple, l’exécution du programme :

10 KlLL "TESTD"
20 OPEN "TESTD” AS 1
30 FIELD #1, 100 AS G$
40 GET #1 RECORD 20

provoque une erreur 24. Il est donc nécessaire d’étendre le fichier avant toute lecture de l’enregistrement numéro 20 :

10 KILL "TESTD"
20 OPEN "TESTD" AS 1
30 FIELD #1, 100 AS G$
34 LSET G$="ENREGISTREMENT NUMERO 20"
38 PUT #1 RECORD 20
40 GET #1 RECORD 20
Exemple d’utilisation d’un fichier à accès direct

Le programme suivant montre comment on peut accéder à un fichier à accès direct. On considère le fichier du personnel précédemment décrit, dont chaque enregistrement contient des renseignements sur un employé : son nom, son prénom, son salaire. Le numéro d’enregistrement identifie l’employé. Le programme imprime les éléments correspondant à un employé dont on a donné le numéro d’identification et en permet la modification.

Le nom de l’employé est rangé dans les 30 premiers caractères de l’enregistrement, son prénom dans les 12 suivants et son salaire dans les 8 derniers.

98 REM *** Ouverture du fichier et définition des variables ***
100 OPEN "PERSON" AS 1 LEN 50
120 FIELD #1, 30 AS NOM$, 12 AS PRE$, 8 AS SAL$
125 FIELD #1, 42 AS NNN$

198 REM *** Saisie du numéro d'enregistrement à modifier ***
199 ON ERROR GOTO 250
200 INPUT "NUMERO DE L'EMPLOYE"; I%
210 IF I%=0 THEN 500
220 GET #1 RECORD I%
230 PRINT "Employé :"; NNN$
240 PRINT "Salaire : "; CVT$F(SAL$) : GOTO 300

248 REM *** Gestion de l'erreur "Enregistrement non trouvé"***
250 PRINT "Enregistrement inexistant"
260 RESUME 200

298 REM *** Mise à jour du contenu de la mémoire tampon (buffer)***
300 PRINT "Nom " ; : INPUT LINE R$
305 IF R$ <> "" THEN LSET NOM$=R$
320 PRINT "Prénom " ; : INPUT LINE R$
325 IF R$<>"" THEN LSET PRE$=R$
330 PRINT "Salaire " ; : INPUT LINE R$
335 IF R$<>"" THEN LSET SAL$=CVTF$(VAL(R$))
398 REM *** Ecriture de l'enregistrement ***
400 PUT #1 RECORD I%: GOTO 200
498 REM *** Fin de programme
500 CLOSE 1
510 END

Le fichier « PERSON.DAT » est ouvert sur le canal 1, puis les variables NOM$, PRE$, SAL$ et NNN$ sont associées à la mémoire tampon (buffer).

La ligne 200 demande le numéro identifiant l’employé afin de pour lire l’enregistrement le concernant. La valeur 0 permet de terminer la session. En cas de demande par l’utilisateur d’un enregistrement non présent, la ligne 210 permet un branchement en ligne 250 qui affiche un message explicatif. Dans les autres cas, les caractéristiques de l’employé sont affichées.

Les lignes 300 à 399 permettent la modification des données écrites dans le fichier. L’utilisation de l’instruction INPUT LINE autorise une réponse vide et, dans ce cas, de ne pas modifier la valeur affichée.

La ligne 400 provoque la réécriture dans le fichier du contenu la mémoire tampon (buffer) puis boucle sur une nouvelle demande.

Enfin la ligne 500 permet de fermer le fichier et termine le programme.

Gestion des erreurs

Les erreurs qui peuvent être signalées au cours de l’exécution d’un programme se répartissent en deux classes :

  • Les erreurs d’entrée-sortie (disque, clavier, écran).
  • Les erreurs de syntaxe ou d’exécution.

La liste complète des numéros d’erreur et leur signification est donnée en 0 « Liste des codes d’erreurs ». Les numéros d’erreur sont compris entre 1 et 49 pour les erreurs d’entrée-sortie et sont supérieurs à 49 pour les erreurs syntaxe ou d’exécution.

En général SBASIC signale l’erreur et arrête l’exécution du programme. Il est toutefois parfois utile de pouvoir continuer l’exécution en particulier quand les erreurs sont du premier type. L’ordre ON ERROR permet de gérer les erreurs signalées par SBASIC.

Il faut noter que la gestion des erreurs est locale aux sous-programmes appelés par l’instruction CALL.

Activation d’une procédure de gestion d’erreur

L’instruction ON ERROR GO TO num-ligne, où num-ligne désigne un numéro de ligne, strictement positif, permet de gérer les erreurs détectées par SBASIC. num-ligne est le numéro de la ligne où doit se brancher le programme en cas d’erreur.

Chaque fois que SBASIC détecte une erreur, il vérifie si une instruction ON ERROR GOTO num-ligne a été préalablement exécutée. Si tel est le cas, le contrôle est transféré à la ligne num-ligne indiquée dans l’instruction ON ERROR GOTO.

La syntaxe d’une ligne de programme utilisant cette instruction est la suivante :

num-ligne-1 ON ERROR GO TO 'num-ligne-2'

Pour être efficace cette instruction doit être exécutée avant toute instruction susceptible de provoquer une erreur.

Dans sa procédure de gestion d’erreur l’utilisateur peut tester et utiliser les variables systèmes ERR et ERL qui contiennent, respectivement, le numéro de la dernière erreur rencontrée et le numéro de la ligne où elle s’est produite.

Reprise après gestion d’erreur

L’instruction RESUME permet de reprendre l’exécution du programme principal une fois le programme de gestion d’erreur exécuté. Elle permet de réactiver la procédure de gestion d’erreur associée à la dernière instruction ON ERROR GOTO num-ligne exécutée.

La syntaxe en est :

num-ligne RESUME [num-ligne]

Si un numéro de ligne est fourni après RESUME, SBASIC reprendra l’exécution du programme à cette ligne. Si aucun numéro de ligne n’est fourni (ou si ce numéro est 0) SBASIC interprète cette instruction en réexécutant toute la ligne où l’erreur s’est produite, et non pas uniquement l’instruction qui a provoqué l’erreur.

Il ne faut pas oublier que le rôle de cette instruction ne se limite pas à celui d’un branchement, que nous venons de mettre en évidence. Elle réactive aussi la procédure de gestion d’erreur. Sa substitution par une simple instruction GOTO ne permettrait pas de prendre en charge l’erreur qui pourrait se produire dans la suite du programme.

Inhibition d’une procédure de gestion d’erreur

Parfois, seules certaines sections de programmes nécessitent l’activation d’une procédure de gestion d’erreur. Il est possible d’annuler l’ordre ON ERROR GOTO num-ligne en utilisant l’une ou l’autre des lignes :

num-ligne ON ERROR GOTO

num-ligne ON ERROR GOTO 0

Ces deux lignes sont équivalentes et ont pour effet d’annuler tous les ordres ON ERROR GOTO activés.

Si l’on se trouve en situation de récupération d’erreur et que l’on n’a pas encore exécuté d’instruction RESUME, cette instruction annule la prise en charge de l’erreur et rend la main à SBASIC qui affiche l’erreur dans le format standard puis arrête l’exécution du programme.

Il faut aussi se souvenir que l’exécution d’une instruction ON ERROR GOTO à l’intérieur d’un sous-programme permet d’activer localement la procédure de gestion d’erreur référencée dans le numéro de ligne.

Si une procédure de gestion d’erreur était active lors de l’appel du sous-programme, le numéro de ligne correspondant est mémorisé. Cette procédure est réactivée lors de l’exécution de l’instruction RETURN terminant le sous-programme.

Exemples de gestion d’erreurs

Dans le programme suivant, l’utilisateur doit entrer 3 nombres dont le programme édite la somme dans la fenêtre SBASIC.

100 ON ERROR GOTO 1000
110 INPUT "ENTREZ 3 NOMBRES", A, B, C
120 PRINT "LA SOMME EST "; A+B+C
140 GOTO 110

1000 IF ERR<>30 THEN GOTO 1030
1010 PRINT " ENTREZ UNIQUEMENT DES NOMBRES"
1020 RESUME
1030 ON ERROR GOTO

Ce programme prévoit et prend en charge une possible erreur de l’utilisateur. Ce dernier pourrait en effet entrer des caractères non numériques, provoquant ainsi une erreur 30 lors de l’addition des variables correspondantes, à la ligne 120. Le programme gérant cette erreur débute en ligne 1000, mais il ne récupère que l’erreur 30. Les autres provoqueront l’arrêt du programme : c’est, entre autres, le cas de l’erreur 34, associée à l’utilisation des touches Ctrl-C, qui permet à l’utilisateur d’interrompre le programme.

Le programme suivant demande de saisir le nom d’un fichier. Si ce dernier est présent sur le disque, travail le programme liste son contenu dans la fenêtre SBASIC.

10 INPUT "TAPEZ LE NOM DU FICHIER AVEC SON EXTENSION"; F$
20 ON ERROR GOTO 1000
30 OPEN OLD F$ AS 1
40 INPUT LINE #1 L$
50 PRINT L$
60 GOTO 40
100 CLOSE 1
110 END
1000 IF ERR = 8 THEN PRINT "Fin de fichier": END
1010 IF ERR = 4 THEN PRINT "Fichier absent": END
1020 PRINT "Erreur";ERR;"à la ligne";ERL: RESUME 10

Si Le fichier n’existe pas (Erreur système numéro 4), le programme affiche le message « Fichier absent » puis s’arrête.

Si le fichier existe sur le disque, le programme le liste, puis affiche le message « Fin de fichier » lorsque la fin du fichier est rencontrée (Erreur système 8), puis il s’arrête.

Pour les autres erreurs, par exemple si le nom du fichier est incorrect (Erreur système 21), il affiche « Erreur numéro de l’erreur à la ligne numéro de ligne » et reprend l’exécution à la ligne 10.

Codes d'erreur

 2 Le fichier requis est déjà utilisé
 3 Le fichier spécifié existe déjà
 4 Le fichier spécifié n a pas été trouvé
 5 Erreur en ouverture de fichier
 6 Création fichier impossible
 7 Tout l espace disque a été utilisé
 8 Fin de fichier rencontrée en lecture
 9 Erreur de lecture sur disque 
 10 Erreur d écriture sur disque
 11 Fichier trop grand
 12 Fichier protégé
 13 Bloc de contrôle de fichier illégal
 15 Numéro d unité disque illégal
 16 Unité disque non prête
 17 Le fichier est protégé - accès refusé
 18 Format fichier compilé incompatible
 20 Type de fichier à accès direct non défini
 21 Spécification de fichier illégale
 22 Erreur en fermeture de fichier
 23 Débordement de la table d allocation - disque trop fragmenté
 24 Numéro d enregistrement inexistant
 29 Enregistrement verrouillé
 30 Type de données non concordant
 31 Hors donnée dans une instruction READ
 32 Mauvais argument dans une instruction ON
 40 Erreur de canal
 41 Fichier déjà ouvert
 42 Mode d ouverture du fichier erroné
 43 Le fichier n a pas été ouvert
 44 Erreur d état fichier
 45 Taille trop grande dans FIELD
 49 Répertoire non trouvé
 50 Instruction non reconnue
 51 Caractère illégal dans la ligne
 52 Erreur de syntaxe
 53 Fin de ligne illégale
 54 Numéro de ligne illégal (<=0)
 55 Parenthèses non balancées
 56 Référence illégale à une fonction
 58 THEN manquant dans une instruction IF
 60 Ligne non trouvée
 61 Return sans CALL ou sans GOSUB
 62 Erreur FOR NEXT
 63 Ne peut continuer
 64 Source absent
 65 Mauvais fichier - ne peut être chargé
 66 RESUME hors traitement d erreur
 67 Mauvais arguments dans DIGITS
 68 Argument valide
 69 Format fichier image invalide
 70 Erreur de type dans une instruction PRINT USING
 71 Format illégal dans une instruction PRINT USING
 72 Types de opérandes incompatibles
 73 Expression illégale
 74 Argument <0 ou >255
 75 Argument <=0
 76 Type de variable illégal
 77 Référence à un tableau hors dimension
 78 Référence à un tableau non dimensionné
 79 Mauvais argument dans une instruction SWAP
 80 Débordement mémoire
 81 Débordement tableau
 82 Débordement mémoire programme
 83 Chaîne trop longue
 84 Trop d arguments dans une instruction SUB ou LOCAL
 85 Chaîne vide dans une instruction EXECUTE
 86 Chaîne trop longue dans une instruction EXECUTE
 88 Redimensionnement d un tableau
 89 Effacement d une ligne référencée
 90 Fonction USR non définie
 92 Argument virtuel dans l instruction
 93 Instruction SUB sans CALL
 94 Mauvaise longueur de chaîne spécifiée
 95 Instruction LOCAL sans SUB
 96 Libération par CLEAR d un tableau virtuel non fermé
 97 Position curseur impossible
 98 Mauvais argument dans l instruction CLEAR
 99 Type erroné dans les arguments d un CALL
 100 Expression trop complexe
 101 Débordement virgule flottante
 102 Argument trop grand
 103 Division par zéro
 104 Réel trop grand pour une conversion en entier
 105 Argument négatif ou nul pour une fonction LOG
 106 Erreur de conversion en entier dans une instruction INPUT
 107 Racine carrée imaginaire
 108 Erreur de conversion (nombre trop grand)
 109 Débordement dans une opération entière
 110 Numéro de couleur erroné
 111 Numéro de port impossible
 114 Ligne vide dans EDIT
 115 No de ligne absent dans EDIT
 128 Erreur non récupérable

Gestion des programmes volumineux

L’instruction CHAIN

Lorsqu’un programme est trop grand pour tenir en mémoire et y être exécuté, il doit être divisé en plusieurs segments. L’instruction CHAIN permet de charger et d’exécuter successivement plusieurs programmes. Les segments de programme doivent être soit de type .BAS, soit des programmes compilés de type .BAC. Chaque segment est un fichier et n’importe quel programme résidant sur disque peut être appelé par CHAIN. La syntaxe en est :

num-ligne CHAIN nom-fich [exp-num]

Le fichier référencé par nom-fich est chargé. L’expression exp-num, optionnelle , désigne le numéro de ligne où le programme nouvellement chargé doit commencer à être exécuté. Notez l’absence de virgule entre les deux expressions.

Exemple :

1300 CHAIN "BALANCEZ" 100

Cette ligne charge le fichier BALANCEZ.BAC et lance son exécution à la ligne 100.

Chaîner un programme compilé (de type .BAC), est plus efficace que chaîner un programme écrit en langage source (.BAS). Les communications entre programmes ainsi chaînés doivent être réalisés par l’intermédiaire de fichiers disque. En effet, lorsque l’ordre CHAIN est exécuté, tous les fichiers qui étaient ouverts sont fermés, le nouveau programme est chargé, les anciennes variables sont détruites, et l’exécution du nouveau programme commence. Les fichiers utilisés conjointement par plusieurs programmes doivent être ouverts dans chacun d’entre eux et les variables réinitialisées.

L’instruction OVERLAY

Dans les versions anciennes de SBASIC, l’instruction OVERLAY permettait de réserver une zone fixe de la mémoire pour y placer les lignes de programme. Elle divisait la mémoire disponible en une zone « programme » et une zone « données ». Ainsi, l’insertion de nouvelles lignes de programme n’affectait pas les données qui étaient alors protégées.

Les zones « programme » et « données » sont maintenant disjointes. L’instruction OVERLAY est sans effet. Elle est cependant conservée pour assurer la compatibilité avec les anciens programmes.

La syntaxe en est :

num-ligne OVERLAY nbre-ligne

nbre-ligne est un nombre inférieur ou égal à 511.

Avec SBASIC, il est possible de charger des sous-programmes dans la zone « programme » en mode programme avec les instructions LOAD et BLOAD.

Par exemple, le programme suivant :

10 OVERLAY 50
99 REM *** saisie des éléments ***
100 INPUT "Nombre d'éléments "; NE% : DIM EL(NE%)
110 FOR X% = 1 TO NE%
120 PRINT "élément "; X%;
130 INPUT EL(X%)
140 NEXT X%
199 REM *** Choix de la fonction ***
200 PRINT "0 - QUITTER  1 - Autre tableau"
210 PRINT "2 - Somme    3 - Moyenne 4 - Ecart-type"
220 I%=INSTR(1,"01234",INCH$(0))
230 IF I% = 0 THEN PRINT CHR$(7);: GOTO 220
250 ON I% GOTO 300, 310, 320, 330, 340
300 END
305 REM *** Traitement de la fonction demandée ***
310 CLEAR EL(*): GOTO 100
320 BLOAD "SOMME" : CALL SOMME(NE%,EL(*)) : GOTO 200
330 BLOAD "MOYEN" : CALL MOYEN(NE%,EL(*)) : GOTO 200
340 BLOAD "ECART" : CALL ECART(NE%,EL(*)) : GOTO 200

Programme SOMME.BAC :

1000 SUB SOMME(N%, E(*))
1010 LOCAL I%,X
1020 FOR I%=1 TO N%
1030 X=X+E(I%)
1040 NEXT I%
1050 PRINT "Somme =";X
1060 RETURN

Programme MOYEN.BAC :

1000 SUB MOYEN(N%, E(*))
1010 LOCAL I%,X
1020 FOR I%=1 TO N%
1030 X=X+E(I%)
1040 NEXT I%
1050 PRINT "Moyenne =";X/N%
1060 RETURN

Programme ECART.BAC :

1000 SUB ECART(N%, E(*))
1010 LOCAL I%,X,Y
1020 FOR I%=1 TO N%
1030 X=X+E(I%)
1040 NEXT I%
1050 X=X/N%
1060 FOR I%=1 TO N%
1070 Y=Y+(E(I%)-X)**2
1080 NEXT I%
1090 PRINT "Ecart =";SQR(Y/N%)
1100 RETURN

Ce programme commence par l’instruction OVERLAY pour réserver une zone de 50 lignes. Cette instruction est ignorée et peut être supprimée. Puis l’utilisateur est invité à saisir une série de données numériques (lignes 110 à 140). Il choisit ensuite le type de calcul (somme, moyenne ou écart-type) devant être effectué sur cette série. Une même zone du programme peut donc être utilisée pour des traitements différents, en fonction des besoins.

Cet exemple simple permet de se rendre compte de toute la puissance du SBASIC.

Gestion de l’imprimante

Sous Windows, les impressions ne se font plus en direct. C’est pourquoi SBASIC gère un tampon d’impression. Les commandes du sous-menu « Imprimante » de la fenêtre SBASIC permettent de vider le tampon d’impression ou d’éditer son contenu et l’imprimer à travers NOTEPAD.

SBASIC sous Windows

Sous Windows, SBASIC est proposé en 2 formats : fenêtre ou ligne de commande.

La fenêtre SBASIC se rapproche le plus de la version originale sous MS/DOS au niveau de l’édition de ligne. Elle est complétée par un menu et une aide en ligne. Le fichier exécutable correspondant est SB32.EXE.

En ligne de commande, SBASIC tire partie des fonctionnalités de la console Windows. Le fichier exécutable est SBASIC.EXE.

SB32.EXE et SBASIC.EXE partagent le même moteur. Seule l’interface texte diffère.

Fenêtre SBASIC (SB32.EXE)

Afin de garder la compatibilité avec les applications SBASIC sous MS/DOS, la fenêtre SBASIC affiche un écran de 25 lignes de 80 caractères. La taille de l’écran SBASIC peut être modifiée par l’instruction TEXT. Lorsque la taille de la fenêtre SBASIC est réduite, des curseurs permettent de naviguer horizontalement et verticalement à l’intérieure de cet écran.

Nouveau sous Windows, le curseur vertical permet de naviguer à travers les lignes de texte précédemment affichées. L’équivalent de 10 écrans est mémorisé. La molette de la souris permet aussi de naviguer verticalement. Dès que le curseur d’affichage se déplace, la fenêtre SBASIC est automatiquement recentrée autour de celui-ci.

Edition ligne

Comme pour SBASIC sous MS/DOS, la combinaison de touches Ctrl-R, utilisée au tout début d’une édition de ligne, permet de récupérer la dernière ligne entrée.

Nouveau sous Windows, les touches ↑ (flèche en haut) et ↓ (flèche en bas), utilisées au tout début d’une édition de ligne, permettent de retrouver une ligne parmi les 100 dernières lignes entrées. Si ces lignes sont utilisées sans modification, une séquence de ligne peut être simplement ré exécutée.

Nouveau aussi sous Windows, la combinaison de touches Ctrl-V réalise un collé du texte présent dans le presse-papier.

Les commandes SBASIC de sauvegarde et de chargement des programmes sont accessibles directement à partir du menu « Fichier » de la fenêtre SBASIC. Dans le menu « Programme » se trouvent les commandes contrôlant l’exécution.

Aide

Un clic de souris sur un mot clé dans la fenêtre SBASIC ouvre une fenêtre d’aide sur celui-ci.

Photographie fenêtre graphique

Lorsque la fenêtre graphique est sélectionnée, la combinaison de touches Ctrl-P effectue une photographie de cette fenêtre. Une fenêtre de dialogue permet de sauvegarder la photographie dans un fichier BMP.

Appel fonctions DLL

L'instruction OPEN LIBRARY permet de charger une librairie à chargement dynamique (DLL). Les fonctions de la librairie peuvent être appelées par l'instruction CALL.

Installation

Sous Windows, l’interpréteur SBASIC se présente sous la forme de 2 fichiers exécutables SB32.EXE (mode fenêtre) et SBASIC.EXE (mode ligne de commande). Son installation consiste simplement en la copie d’un de ces fichiers dans un répertoire de l’ordinateur.

Les différentes méthodes de lancement d’un programme au format .EXE peuvent être utilisées. Par exemples :

  • Création, sur le bureau, d’un raccourci vers le fichier SB32.EXE ou SBASIC.EXE. Dans les propriétés du raccourci on spécifiera comme répertoire de travail, le répertoire contenant les fichiers SBASIC avec l’extension .BAS ou .BAC. L’interpréteur SBASIC se lance alors par un double-clic sur l’icône SBASIC : Icône
  • Un programme SBASIC peut être lancé directement en glissant le nom du fichier contenant le programme SBASIC sur l’icône SBASIC.
  • Définition de SB32.EXE ou SBASIC.EXE comme programme associé aux extensions .BAS et .BAC. Un programme SBASIC se lance alors en double-cliquant, dans l’explorateur de fichier, sur le nom du fichier contenant ce programme.
  • Pour que la commande SBASIC soit reconnue en ligne de commande, le fichier SBASIC.EXE doit être placé dans un répertoire spécifié dans le PATH (par exemple le répertoire C:\Windows).