Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Amiga E - structure d'une source
(Article écrit par Yann Armand et extrait d'Amiga News - juin 1995)
|
|
A l'instar des autres langages procéduraux, comme le Pascal ou le C, le E possède une structure de source en quatre parties :
1)
MODULE <path/module>, .....
|
2)
DEF <variable>:<type>, ......
|
3)
PROC main()
DEF <variable locale>
...
<corps du programme>
...
ENDPROC
|
4)
PROC <nom de procédure>(<variables>:<type>)
DEF <variable locale>
...
<corps de la procédure>
...
ENDPROC
|
Examinons chacune de ces parties :
1) Appel des MODULES, grâce auxquels, entre autres, nous aurons accès aux fonctions et variables des bibliothèques du système.
Une particularité du compilateur E est que les fonctions des bibliothèques exec, intuition, dos et graphics, sont directement
accessibles sans que nous ayons à appeler leurs modules.
2) DEFinition des variables globales, accessibles par n'importe quelle procédure. Nous pouvons en préciser le type, c'est-à-dire
ce qu'elle représente : INT pour les entiers, CHAR pour les caractères, LONG pour les mots long, STRING pour les chaînes de
caractères -qui sont en fait des ARRAY OF CHAR-, OBJECT pour les structures et PTR pour les pointeurs qui peuvent leur être associés
comme nous le verrons plus loin.
3) La procédure main(), en fait la procédure maîtresse de notre programme, qui sera exécutée en premier.
4) La déclaration des procédures annexes utilisées par la procédure main() soit de façon répétitive, soit pour faciliter
la lecture de la procédure main().
Les procédures
Nous auront souvent à créer nos propres fonctions, auxquelles nous passerons des arguments et qui nous renverrons un ou plusieurs
résultats.
Les procédures peuvent agir sur les variables globales définies en début de sources, mais aussi sur toutes les variables dites
locales, qui sont déclarées à l'intérieur même de la procédure.
Les arguments d'une procédure sont aussi des variables locales. Celles-ci sont exclusivement attachées à la procédure et elle
seule peut y accéder. La seule façon de faire sortir d'une procédure la valeur d'une variable locale est de la renvoyer en résultat.
Prenons un exemple. Réécrivons de deux façons différentes la procédure STRLEN() qui renvoie la longueur d'une chaîne de caractères :
Dans les deux cas nous utilisons l'argument chaine -un pointeur sur une chaîne de caractères- et nous définissons une variable
locale i qui va compter les caractères. La fin de la chaîne sera détectée par la présence d'un caractère nul.
Dans le premier cas, tant que le caractère observé n'est pas nul nous incrémentons i. Une fois trouvé ce caractère, nous finissons la
procédure par ENDPROC i, qui renvoie la valeur de i.
Dans le second cas, nous créons une boucle infinie qui teste le caractère courant et qui incrémente i. Lors du test, si la valeur du
caractère est 0, alors on sort de la procédure sans la finir par RETURN i, qui renvoie lui aussi la valeur de i.
Nous découvrons ici un des points forts des procédures : nous n'avons pas à nous soucier de la façon de traiter le problème tant
qu'on connaît l'utilisation. En effet, si nous écrivons :
longueur:=strlen('bonjour')
|
Dans les deux cas longueur recevra 7.
Pour en finir avec les arguments, il faut savoir qu'ils peuvent recevoir une valeur par défaut. Ainsi, lors d'un appel à la
procédure, si l'argument n'est pas précisé, il reçoit sa valeur par défaut. Ces arguments doivent néanmoins être déclarés en dernier :
Un appel toto(2,5) sera équivalent à toto(2,5,3).
Une déclaration PROC toto(a,b=1,c) est illégale.
Une particularité des procédures en E est de pouvoir retourner plusieurs valeurs (3 au maximum). Rien n'est plus simple, il suffit
d'enchaîner les variables de résultats avec :
ENDPROC a,b ou RETURN a,b,c
|
L'appel à de telles procédures se fera ainsi :
"a" reçoit la première valeur de retour et "b" la seconde. S'il en existe une troisième, elle est ignorée.
Dans les traitements imbriqués comme :
"a" recevra le cosinus de la première valeur de retour de toto(5,3).
Les Objets
Examinons maintenant un élément primordial du langage pour la programmation du système, j'ai nommé les Objets. Ces derniers sont
assimilables aux Structures du C ou aux Records du Pascal.
Un objet rassemble plusieurs variables -elles peuvent être de types différents-, que l'on regroupe sous un seul nom pour les
manipuler facilement.
Par exemple :
OBJECT cd
nom[50]:STRING /*nom du CD*/
durée:INT /*durée en min*/
plages:INT /*nb de plages*/
positin:INT /*position de rangement*/
ENDOBJECT
|
Nous avons créé un nouveau type cd, il ne nous reste plus qu'à l'affecter à une variable :
"metallica" est une variable de type cd. Nous pouvons lui assigner des valeurs...
-globalement:
metallica:=['Master of puppets',
54,8,38]:cd
- individuellement:
metallica.nom:='Master of puppets'
metallica.plages:=8
|
On lit les variables de l'objet de la même façon :
IF metallica.durée<60 THEN
WriteF('ce cd rentre sur
une cassette')
title:=metallica.nom
|
Le système pullule d'objets, par exemple un écran sera décrit par un OBJECT screen, une fenêtre par un OBJECT window et bien
d'autres encore... Pour y accéder nous utilisons des pointeurs (PTR) qui sont en fait des LONG dans lesquels sont stockées des
adresses. Définissons hetfield un pointeur sur un objet de type cd :
Assignons lui une valeur :
Et nous l'utilisons comme un objet :
Nous obtenons "Master of puppets" dans la variable title.
L'exemple
Voici pour finir un petit programme donnant la liste des écrans ouverts, qui résume ce que nous venons de voir. L'algorithme est
simple : on trouve le premier écran (intbase.firstscreen), tant que le pointeur scr n'est pas nul, on écrit son nom et on cherche
le suivant.
Pour finir
Pour mieux comprendre, jetez un oeil au module "intuition:screen.m" grâce à bin/ShowModule.
Et pour ne pas rester inactif, dévorez les articles sur le C et l'assembleur,
traitant du système dans les précédents numéros. Vous trouverez des mines d'informations sur les OBJECTS (structures) du système.
/* 1re version */
PROC strlen(chaine)
DEF i=0
WHILE chaine[i]<>0
i:=i+1
ENDWHILE
ENDPROC i
/* 2nde version */
PROC strlen(chaine)
DEF i=0
LOOP
IF chaine[i]=0 THEN RETURN i
i:=i+1
ENDLOOP
ENDPROC
/* exemple donnant la liste des */
/* ecrans ouverts */
MODULE 'intuition/intuitionbase'
MODULE 'intuition/screens'
DEF scr:PTR TO screen
DEF intbase:PTR TO intuitionbase
PROC main()
intbase:=intuitionbase
scr:=intbase.firstscreen
WHILE scr<>0
WriteF('\s\n',scr.title)
scr:=findnextscreen(scr)
ENDWHILE
ENDPROC
PROC findnextscreen(sc:PTR TO screen)
sc:=sc.nextscreen
ENDPROC sc
|
|