Proposition d'article
============
Les directives et le préprocesseur
==================================
Introduction
------------
Parmi les mots-clés de Panoramic, certains jouent un rôle particulier.
Il s'agit des directives, dont le nom commence par un dièse (#). Pour
le moment, il n'y en a qu'une seule : la directive #include, mais il
est prévu d'en ajouter d'autres par la suite.
Les directives s'adressent à un composant particulier de Panoramic
appelé le préprocesseur. Ce dernier fonctionne comme un traitement
de texte, transformant le code source original en un autre code
source qui sera interprété par Panoramic. On a donc la chaîne :
- Code:
-
Préprocesseur Panoramic
Source original ------------> Source modifié ---------> Exécution
Les directives sont placées dans le source original. Leur rôle est de
dire au préprocesseur ce qu'il doit faire. Le nom de "directive" est
donc parfaitement justifié.
Le problème, c'est que l'utilisateur ne voit pas le source modifié !
Il croit que Panoramic interprète le source original, ce qui n'est pas
le cas ! Il s'ensuit que les directives sont une source fréquente
d'erreurs et de confusions.
Les directives ne sont pas une spécificité de Panoramic. Certains
langages comme le FreeBASIC ou le C disposent d'un préprocesseur
beaucoup plus développé, au prix d'un risque de confusion encore
plus grand.
Il est donc très important de bien comprendre le fonctionnement du
préprocesseur si l'on veut pouvoir utiliser efficacement les directives.
La directive #include
---------------------
Cette directive ordonne au préprocesseur d'inclure le contenu d'un
fichier texte dans le code source, à l'endroit de la directive.
Par exemple si l'on a un fichier variables.inc contenant des
déclarations de variables :
- Code:
-
dim a%, b, c$
Le source original pourrait se présenter ainsi :
- Code:
-
#include "variables.inc"
a% = 10
b = 3.14
c$ = "Bonjour"
Le préprocesseur va alors transformer ce code pour créer le source
suivant :
- Code:
-
dim a%, b, c$
a% = 10
b = 3.14
c$ = "Bonjour"
C'est donc ce dernier code qui sera interprété.
Remarquons que :
1) La position de la directive est très importante. Si on l'avait placée
en fin de programme on n'aurait pas pu initialiser les variables puisqu'elles
n'auraient pas été déclarées auparavant.
2) La directive a disparu dans le source modifié. Ce n'est donc pas une
instruction.
Rôle des fichiers à inclure
---------------------------
En théorie, on peut mettre tout ce qu'on veut dans les fichiers à
inclure. En pratique, la principale utilisation est constituée par les
bibliothèques de procédures (SUBs). On écrit toutes les procédures dans
un seul fichier, que l'on inclut dans tous les programmes utilisant ces
procédures. En cas de modification des procédures, seul le fichier à
inclure aura besoin d'être modifié.
Un exemple de bibliothèque sera présenté dans un prochain article.
D'ici là, nous conseillons de lire le tutoriel de papydall sur les procédures.
Une future directive #const ?
-----------------------------
Beaucoup d'utilisateurs de Panoramic souhaiteraient avoir une telle directive
pour définir des constantes. On pourrait ainsi écrire :
- Code:
-
#const QUATRE 4
#const CINQ 5
print "4 * 5 = ", QUATRE * CINQ
Et on obtiendrait le bon résultat :
4 * 5 = 20
Tout cela semble évident... Mais supposez que l'on écrive :
- Code:
-
#const QUATRE 3 + 1
#const CINQ 4 + 1
print "4 * 5 = ", QUATRE * CINQ
On obtient alors :
4 * 5 = 8
Etonnant, non ? (comme aurait dit le regretté Pierre Desproges...)
Pour comprendre ce qui s'est passé, il faut se rappeler que le
préprocesseur travaille comme un traitement de texte. En l'occurrence,
il va remplacer les symboles "QUATRE" et "CINQ" par les chaînes de caractères
qui leur sont associées par les directives #const.
Dans le premier exemple, "QUATRE" devient "4" et "CINQ" devient "5", de sorte
que le code source est transformé en :
print "4 * 5 = ", 4 * 5
Ce qui donne le bon résultat... Mais dans le deuxième exemple,
"QUATRE" devient "3 + 1" et "CINQ" devient "4 + 1", ce qui donne :
print "4 * 5 = ", 3 + 1 * 4 + 1
que Panoramic évalue comme 3 + (1 * 4) + 1, soit 8, puisque la multiplication
est prioritaire par rapport à l'addition.
Pour obtenir le bon résultat, il faut ajouter des parenthèses :
- Code:
-
#const QUATRE (3 + 1)
#const CINQ (4 + 1)
print "4 * 5 = ", QUATRE * CINQ
ce qui devient, par l'action du préprocesseur :
print "4 * 5 = ", (3 + 1) * (4 + 1)
Ce petit exemple, pour caricatural qu'il soit, montre les inconvénients
que peut entraîner l'utilisation naïve des directives.
Notes :
1) L'exemple est purement virtuel, puique la directive #const n'est pas
encore implémentée dans Panoramic, et peut-être ne le sera-t-elle pas,
ou bien sous une autre forme moins dangereuse...
2) Les programmes précédents peuvent être testés en FreeBASIC, à condition
de remplacer #const par #define, car tel est le nom de la directive dans
ce langage (ainsi que dans le langage C)
3) Le tant attendu "compilateur" Panoramic devrait pouvoir générer du
code FreeBASIC, donnant ainsi accès à un éventail beaucoup plus grand
de directives, à manipuler donc avec beaucoup de précautions. Nous
espérons que ce petit article aura permis de prendre conscience des
risques encourus !