|
`TML PASCAL II
une traduction de B. Capslock
`INTRODUCTION
Bienvenue dans TML II, la deuxième génération du fameux langage
de développement Pascal sur Apple //GS. TML II implémente certaines
nouvelles fonctions rendant la programmation plus facile et assurant
une totale compatibilité avec le système d'exploitation 5.0. En
particulier, TML II accepte l'édition et la création de ressources.
Cette version est destinée à être employée sur un seul
ordinateur; pour une utilisation sur un réseau AppleShare vous devez
vous procurer la version TML spéciale fonctionnant en réseau.
Le langage de programmation TML Pascal est destiné à satisfaire
le plus grand nombre de programmeurs sur Apple IIGS. Il est basé sur
le langage Pascal ANS avec de nombreuses extensions pour les
programmeurs familiarisés avec les suppléments des autres Pascal.
Le TML Pascal reconnait les Modules, entrées/sorties en accès
direct sur disque, et les sous-programmes standard comme Moveleft,
Fillchar, etc. que l'on trouve dans les extensions de Pascal UCSD
comme celui de Apple. Et bien entendu les possibilités du TML Pascal
sur Macintosh comme le type 'casting' opérations sur un bit, les
déclarations CYCLE et LEAVE, les Modules et davantage encore, existent
sur le TML Pascal de l'Apple II GS.
Le TML Pascal pour l'Apple II GS a été conçu pour tirer avantage
et accéder aux nouvelles possibilités de la machine. Il tourne en vrai
16 bits mode natif GS/OS. L'accès sous Pascal à chacune des routines
du Toolbox de l'Apple II GS est possible de mème qu'à celles de Prodos
16, de GS/OS et des ressources.
Avec le Pascal TML, vous serez capable de développer des
applications autonomes GS/OS, des accessoires de bureau NDA et CDA,
des aplications en mode texte ou graphique.
En plus du développement d'applications qui exploitent les
avantages du Toolbox du II GS, le Pascal TML vous permet de développer
ce que nous appelons des applications "plain vanilla" ou "textbox".
Cette possibilité vous permet d'entrer dans les programmes directement
à partir des exemples texte et de les compiler. Dans cet
environnement, Pascal TML fourni une fenêtre console de 20 lignes sur
80 colonnes en mode super-haute résolution 640.
Le guide d'utilisateur et manuel de référence du Pascal TML a été
écrit pour vous guider dans l'emploi du Pascal TML, cependant ce ne
sont pas des livres d'apprentissage.
Afin d'utiliser Pascal TML, il vous faudra un Apple II GS avec
moniteur, un lecteur 3"1/2 800 Ko et une carte d'extension mémoire
avec au moins 512 KO soit un total de 768 K de mémoire vive. Pour le
développement d'applications importantes, deux lecteurs 800 Ko ou un
disque dur sont recommandés. Une imprimante pour conserver le listing
de vos sources sera également la bienvenue.
Si vous avez des questions relatives à TML ou à la programmation
Pascal, vous pouvez nous contacter à notre service Clients, du Lundi
au Vendredi entre 8h30 et 17h30 (heure locale) au 904 636 8592. En ce
qui concerne les problèmes plus techniques, nous vous conseilons
d'appeler notre service Technique entre 14h et 17h au 904 636 0118.
Et puis si vous préférez nous envoyer une lettre, vous pouvez
nous écrire à:
TML SYSTEMS, Inc
8837-B Goodbys Executive Drive
Jacksonville, Florida 32217
```A PROPOS DU MANUEL:
Ce manuel a été conçu pour vous aider à débuter rapidement avec
TML Pascal II et aussi servir de manuel de référence quand votre
niveau de programmation devient plus élevé. Ce manuel est divisé en
quatre parties:
1- le Guide de l'Utilisateur
2- la programmation
3- la Référence du langage
4- les appendices
Le guide de l'utilisateur vous introduit dans TML Pascal II et
vous enseignera comment configurer votre système pour l'utiliser et
comment tirer le maximum de l'utilisation de TML Pascal. Le Guide de
l'utilisateur a pour but de vous fournir une vue générale de
l'environnement de travail TML Pascal II.
La Programmation vous introduit dans les bases de TML Pascal II
en vous enseignant comment écrire chacun des cinq différents types de
programmes utilisant TML Pascal II.
La Référence du langage est une référence complète des
possibilités fournies par TML Pascal II. Notez que cette section est
une référence et non un guide du langage Pascal. Si vous n'êtes pas
familiarisé avec le langage Pascal, vous aurez besoin d'un manuel
supplémentaire qui vous enseignera le langage Pascal.
Les Appendices résument les messages d'erreur et les résultats
d'entrées/sorties du TML Pascal II, les directives de compilation et
les fonctions de la boite à outil de l'Apple //GS. De plus, un regard
sur les possibilités les plus avancées de TML Pascal II est donné avec
une comparaison de TML Pascal II avec TML Pascal original.
``CHAPITRE 1: PREMIER CONTACT
Avant d'utiliser le Pascal TML vous devrez prendre des
précautions pour protéger votre logiciel. Comme il est impossible
d'utiliser directement la disquette fournie avec le Pascal TML (elle
ne contient pas GS/OS) il peut être suffisant de la protèger contre
l'écriture lorsque vous l'utiliserez pour installer le Pascal TML sur
votre disque dur. Cependant, il est préférable de faire une sauvegarde
de la disquette livrée et de ranger l'originale en lieu s|r.
Rappelez-vous que la philosophie des systèmes TML étant de vendre
des produits de qualité à un prix abordable sans protection contre la
copie, cela ne peut fonctionner que si vous jouez le jeu. Avec la
licence vous pouvez faire des sauvegardes du logiciel pour vos besoins
personnels mais celles-ci ne doivent pas être données ou utilisées par
quelqun d'autre.
Pour formater une nouvelle disquette et faire une sauvegarde vous
pouvez utiliser votre programme habituel de copie (mais permettant la
duplication des fichiers resources) ou mieux, en utilisant les
fonctionalités du Finder. Si vous n'êtes pas habitué à ces outils
alors consultez leurs manuels respectifs.
```CONFIGURATION DU SYSTEME:
La disquette de distribution Pascal TML contient tous les
fichiers nécessaires à l'installation du Pascal TML. Un système de
développement sur Apple II GS utilisant le Pascal TML peut être
configuré de nombreuses façons, cependant dans les sections suivantes
nous vous indiquons les configurations les plus courantes: 1 lecteur,
2 lecteurs, un disque dur.
Pour construire un environnement de développement Pascal TML vous
aurez besoin de deux ensembles différents de logiciels :
- logiciels Pascal TML
- logiciels système Apple II GS
````Un lecteur 800k:
Un seul lecteur 800 Ko est la configuration minimum possible.
Bien que cette configuration réduise l'espace disponible sur la
disquette, elle permet un système de développement complet et puissant
utilisant le Pascal TML.
Un système de développement sur une seule unité 800K contient le
minimum de logiciels cités plus haut. Avec cette configuration vous
disposez d'environ 100 Ko pour développer vos applications, cependant
il sera nécessaire de faire un peu de 'ménage' sur la copie de votre
disquette TML en enlevant, notamment, les fichiers SAMPLES. Ceci vous
permettra de disposer de plus de place pour sauver vos sources.
````Deux lecteurs 800k:
Avec deux lecteurs 800 Ko il est tout à fait raisonnable
d'utiliser le second lecteur pour stocker le code source de
l'applications que vous développez. Néanmoins, les fichiers librairies
doivent impérativement se trouver sur la disquette TML.
````Un disque dur:
Un système de développement sur disque dur offre bien s|r la plus
grande souplesse. Dans ce cas nous vous recommendons d'installer toute
la disquette système de l'Apple II GS et celle de TML sur le disque
dur. Cependant assurez-vous que vous utilisez bien la dernière version
du système d'exploitation de la disquette Apple II GS et non une
ancienne version. La dernière version GS/OS est minimum 5.0. Vous ne
pourrez pas faire fonctionner ni TML ni vos applications développées à
partir de TML sur une version du système GS/OS antérieure à 5.0.
```LANGAGES INTERPRETES OU COMPILES:
TML II est un langage compilé. A cet égard, il diffère
notablement des langages interprétés, tel le Basic Apple.
Un langage de programmation est constitué d'une collection
d'instructions, expressions et autres, plus connus sous la
dénomination de syntaxe ou structure du langage. Alors que les
langages écrits en langage machine sont généralement incompréhensibles
pour un humain, ils sont pourtant totalement compris par le
microprocesseur de l'ordinateur. Dans notre cas, le microprocesseur
65816.
Avant qu'une instruction écrite en langage évolué ne s'exécute,
elle doit d'abord être traduite en langage compris par l'ordinateur:
le langage machine. Le langage machine est constitué de suites de
nombres binaires (0 et 1) compris par l'ordinateur comme étant une
série d'états OUI-NON caractérisant les opérations que la machine est
capable d'exécuter. Bien s|r, une succession de 0 et 1 n'est pas
facilement compréhensible par un homme.
La plus grande partie de chaque langage de programmation est
constituée de la translation des programmes en langage machine. Dans
un langage interprété, cette translation se fait lorsque le programme
s'exécute. Cette méthode est parfois dénommée 'à la volée'. Si une
instruction du programme est exécutée 100 fois par exemple, la
translation en langage machine est excutée 100 fois également par
l'interpréteur. Généralement, les langages interprétés s'exécutent
plus lentement que les langages compilés du fait de la translation qui
se produit durant l'exécution du programme.
D'un autre coté, un langage compilé traduit un programme en
langage machine avant son exécution. Ainsi, chaque ligne du programme
est traduite une seule fois (lors de la compilation). De plus, la
compilation traque toutes les erreurs de syntaxe du programme avant
son exécution. Bien entendu, le compilateur ne peut déceler les
erreurs de logique (par exemple les boucles infinies).
Généralement, les langages compilés s'exécutent bien plus
rapidement que les langages interprétés. De plus, les langages
compilés peuvent être exécutés indépendamment de tout langage
processeur. Ainsi, les programmes compilés TML peuvent être exécutés
sous GS OS sans que TML soit utilisé. Au contraire du Basic Applesoft,
dont les programmes ne peuvent être exécutés que si le langage Basic
est préalablement chargé en mémoire.
```ET MAINTENANT ?:
Si vous êtes débutant en programmation, lisez entièrement le
manuel TML et procurez-vous un bon livre d'initiation à la
programmation Pascal (par exemple TOPIQUES PASCAL de J Colibri aux
éditions Mnemodyne).
Si vous connaissez la programmation du GS avec un langage autre
que Pascal, il vous suffit de lire les chapitres 4 à 10 afin de
connaitre les spécificités du TML et les programmes que l'on peut
développer dans un tel environnement.
Si vous connaissez déja bien le Pascal, l'appendix E sera votre
seul livre de référence pour connaitre les différentes fonctions de la
boite à outils.
``CHAPITRE 2: UTILISATION DE TML
```LANCER TML:
Mettez une copie de votre disquette TML dans un lecteur 3'1/2 et
allumez votre ordinateur. Lorsque le boot est terminé, le bureau du
finder est affiché avec l'icone de la disquette TML dessiné dans la
partie droite de l'écran.
Cliquez sur cet icone, et ensuite sélectionnez l'option OPEN du
menu FILE (ou alors double-cliquez sur l'icone TML). Une fenêtre
s'ouvre: double-cliquez sur l'icone TML II afin de charger en mémoire
le langage TML.
```L'ENVIRONNEMENT DE PROGRAMMATION:
TML II est conçu pour tirer plein avantage des possibilités du
GS: interface souris, menus déroulants, multi-fenètrage.... Avec un
tel outil, la programmation est simplifiée: l'éditeur et le
compilateur fonctionnent dans le mème environnement de travail.
Le menu principal de TML permet uniquement l'édition d'un fichier
Source ou Resource. Dans ce chapitre et le suivant, nous verrons
comment éditer un fichier source; dans le chapitre 4 nous traiterons
de la spécificité des fichiers Resources.
```EDITION DES FICHIERS SOURCE:
Les fenêtres d'éditions sont des outils de TML permettant la
création/modificaion aisée de vos sources. TML vous autorise à avoir
autant de fichiers sources ouverts simultanément que le permet la
mémoire disponible de votre système. Bien évidemment, plus la RAM
disponible dans votre GS sera importante, plus vous disposerez de
place pour créer des programmes et ouvrir des fenêtres d'édition.
Au fur et à mesure que vous ouvrez de nouveaux fichiers source,
TML les place dans des nouvelles fenêtres d'édition indépendantes les
unes des autres. Mais une seule fenêtre d'édition ne peut être active
à la fois. La fenêtre active est toujours celle située au premier
plan, celle o| les commandes seront actives.
TML utilise également des dialogues pour communiquer avec
l'utilisateur. Ces dialogues servent généralement à informer le
programmeur qu'il doit fournir certains éléments afin de continuer son
travail (ou corriger certains éléments erronés). Les dialogues
utilisent également des boutons OK/CANCEL ou YES/NO pour confirmer ou
infirmer vos décisions.
````Menu d'édition des fichiers source:
Choisissez l'option OPEN du menu FILE. Un dialogue standard de
chargement de fichier apparait à l'écran. Cliquez sur le bouton radio
SOURCE TEXT FILE puis double-cliquez sur le fichier HELLOWORLD dans le
dossier HELLOWORLD. Presque instantanément, le listing s'affiche dans
une fenêtre d'édition. Vous remarquerez qu'alors la barre de menus
comprend de nouvelles options: les outils d'édition. Ces outils seront
étudiés en détail au cours du chapitre 5.
````Conventions de dénominations:
Lorsque vous avez ouvert le dossier HelloWorld, vous avez
surement noté la présence de différents fichiers aux noms très
voisins. Ces similitudes sont justement la résultante des conventions
de dénomination des différents fichiers. Tout ceci afin de
différencier les fichiers Source, Resource et Application.
Voici les convention que nous avons adoptées pour nommer les
fichiers générés à partir de TML:
fichier Source : utiliser le suffixe .P à la fin des noms
fichier Resource: utiliser le suffixe .R à la fin des noms
application : TML ote automatiquement les suffixes pour créer le
nom de l'application
Attention, TML ne crée pas automatiquement les noms en respectant
ces règles: c'est à vous de suivre ces règles lors de la création de
nouveaux fichiers.
````Règles de base pour l'édition:
L'éditeur TML est très similaire aux traitements de textes
traditionnels. Ainsi l'utilisateur averti du GS ne sera pas dépaysé
pour éditer ses fichiers sources avec TML. Vous disposez des
fonctionnalités suivantes:
- couper, copier, coller et annuler sur des blocs de texte
- recherche et remplacement de texte
- indentations (tabulations)
- choix de la fonte et de sa taille
- défilement par ascenseurs
- impression sur Imagewriter ou Laserwriter
D'un autre coté, TML dispose de commandes sépcifiques:
- vérifier la syntaxe d'un fichier source
- exécuter un programme
- créer une application
- utiliser certaines commandes GS OS (renommer, copier)
- indiquer les erreurs de programmation
Avec le fichier source de HelloWorld, familiarisez-vous avec les
différentes commandes d'édition. Par exemple, copiez-collez une zone
de texte, changez de fonte et de taille dans la fenêtre d'édition,
annulez vos modifications....
Avec les chapitres 3 et 5 nous étudierons en détail les
différents options disponibles avec TML.
``CHAPITRE 3: CREER UN PROGRAMME:
```LES COMPILATIONS:
TML dispose de trois options de compilation: TO MEMORY, TO DISK
et CHECK SYNTAX. Ces commandes de compilation se trouvent dans le menu
COMPILE.
La compilation TO MEMORY est certainement celle que vous
utiliserez le plus souvent. Cette commande effectue une compilation du
source se trouvant dans la fenêtre active. En cas de réussite, la
compilation se poursuit par l'exécution du programme compilé en
mémoire.
La commande de compilation TO DISK est similaire à la précédente,
mais le programme compilé n'est pas exécuté, il est sauvé sur disque.
Cette commande est utilisée lorsque votre programme est terminé et
testé: cette commande produit alors l'application exécutable à partir
d'un launcher.
Enfin, CHECK SYNTAX permet de vérifier rapidement la syntaxe du
source se trouvant dans la fenêtre active. Il n'y a ni exécution du
programme compilé ni sauvegarde sur disque dans ce cas.
Lorsqu'une option de compilation est utilisée, une fenêtre est
affichée indiquant la progression du processus. Lorsque le
'thermomêtre' a atteint le bord droit, la compilation est terminée.
```TESTER UN SOURCE:
La commande Check Syntax est l'option de compilation la plus
rapide: il n'y a pas de code généré, mais vérification de la bonne
orthographe des mots clés, des instructions, des fonctions...
Cependant, cela ne teste pas la logique du programme. Par exemple, une
boucle infinie ne pourra être détectée par Check Syntax.
Ouvrez le fichier exemple TextBook.p et lancez l'option de
compilation Check Syntax. Lorsque le 'thermomêtre' est en bout de
course, la vérification est terminée. Ceci n'a pris que quelques
secondes, grace aux performances du compilateur TML et à la compacité
du code source testé.
Si le test indique qu'aucune erreur n'a été détectée, cela ne
signifie pas que le programme est parfait. Cela garantie juste qu'il
n'y a pas d'erreur de syntaxe.
Il est important de procéder à une vérification de syntaxe pour
détecter les erreurs qui provoqueraient un 'plantage' du programme
lors de son excution après Compile to Memory.
Si une erreur est détectée, la compilation est interrompue et TML
affiche une fenêtre indiquant le type d'erreur. Dans la fenêtre
active, la zone responsable de l'erreur est affichée en mode inverse.
```EXECUTION D'UN PROGRAMME:
Lorsque vous êtes certain que votre programme ne comporte aucune
erreur de syntaxe, il est temps de le faire fonctionner. Pour cela, la
commande de compiltion To Memory sera adéquate. Lors de la
compilation, TML génère un code qui sera exécuté à partir de la
mémoire du GS. L'environnement de programmation sera fermé (fenêtres,
menus) et votre application lancée. Lorsque vous quitterez votre
programme, vous reviendrez dans TML automatiquement, avec le bureau
dans l'état o| vous l'aviez quitté (fenêtres ouvertes, sources
affichés...).
Comme il est possible que votre source contienne des erreurs de
logique provoquant un plantage los de l'exécution, TML permet de
sauver le bureau juste avant le lancement de votre code compilé. Cette
possibilité s'appelle AUTOSAVE. Si cette option est connectée, TML
effectue une sauvegarde de tous les fichierss ouverts modifiés depuis
la dernière compilation. Cette option vous permet de ne pas risquer de
perdre votre travail si le GS est bloqué par une erreur lors de
l'excution du programme en mémoire. L'option AUTOSAVE est commentée au
chapitre 5.
```CREER UNE APPLICATION:
Comme on l'a vu précédemment, la compilation en mémoire est très
rapide et très pratique. Cependant elle oblige chaque fois à lancer
TML et à compiler le source de l'application pour l'exécuter.
Heureusement, il existe un moyen plus facile pour lancer une
application. Pour cela, il faut effectuer une compiltion To Disk. Cela
va créer un programme exécutable à partir des launchers traditionnels.
Dès lors, il n'y aura plus besoin de TML pour lancer votre applicaion:
elle sera auto-lançable.
La compilation sur disque est légèrement plus longue que les
autres modes de compilation du fait de la sauvegarde du code sur
disquette.
Le nom du programme compilé est le mème que celui du source, le
suffixe '.p' en moins.
```COMPILATION DES UNITS:
De la mème manière que TML compile un programme, il peut compiler
une Unit. Cette compilation ne peut générer un programme exécutable,
mais elle sert à produire un code contenant des informations relatives
à votre application. Les Units sont utilisées pour fractionner un
programme très volumineux en unités logiques. Une Unit peut comprendre
des constantes, des types, des variables, des procédures et des
fonctions.
Comme une Unit ne peut être exécutée, le compilateur TML agit
différemment avec un tel source. Si on compile en mémoire une unit,
TML effectue la compiltion puis rend la main à l'éditeur au lieu
d'exécuter le code. Lors de cette compilation, le code de l'Unit est
sauvé en mémoire et peut donc être utilisé ultérieurement par un
programme.
Si on compile sur disque une Unit, TML ne vas pas créer une
application exécutable, mais un fichier objet contenant la table des
symboles et les librairies compilées. Le code ainsi produit sera sauvé
avec le suffixe '.p.o'. Si un autre programme ou Unit faisant appel à
cette Unit est compilé, le fichier code '.p.o' de l'unit utilisée sera
recherché par TML.
Le nom du fichier de l'Unit compilée est le nom du fichier source
suivi du suffixe '.o'. ainsi, le code objet d'une unit se termine par
'.p.o'.
La commande Check Syntax fonctionne comme pour un programme
normal. De ce fait, Check Syntax va seulement vérifier si l'Unit ne
contient pas d'erreur de syntaxe dans ses instructions.
```DETECTION DES ERREURS:
Jusqu'à présent, nous avons parlé des processus de compilation se
produisant sans erreur. Voyons un peu comment TML détecte et gère les
erreurs.
TML est constitué de trois parties: l'éditeur, le compilateur et
le linker. Ces trois parties fonctionnent en inter-relation et donnent
l'illusion de n'être qu'une seule et mème entité. Mais en comprenant
comment ces trois parties fonctionnent, vous saurez mieux comment TML
détecte les erreurs de vos programmes sources.
L'éditeur, bien entendu, est ce que vous utilisez la plupart du
temps. Il permet d'ouvrir les fenêtres contenant vos programmes et la
majorité des commandes des menus sont applicables à l'éditeur. Le
compilateur est utilisé lorsque vous choisissez une des trois
commandes de compilation. Il permet de détecter les erreurs de syntaxe
et de produire un code objet. Enfin, le linker est employé uniquement
lors de la compilation sur disque ou en mémoire. Il va combiner les
différents programmes objets (les units) et allouer la mémoire interne
nécesssaire à votre application.
L'éditeur va seulement indiquer les erreurs se produisant dans
l'environnement d'édition. Par exemple, il va indiquer une erreur si
vous sauvez un fichier sur disquette protégée en écriture, ou si vous
ouvrez un fichier sans disposer de suffissamment de mémoire. Le
compilateur indique les erreurs relatives à un code incorrect. Enfin
le linker détecte les erreurs survenant lors de la création du fichier
GS OS: par exemple si la disquette est verrouillée, o| si le directory
est plein...
Lorsqu'une erreur est détectée, TML va mettre en oeuvre une série
d'actions afin de ne pas perdre vos données et afin d'afficher une
fenêtre de dialogue indiquant la cause présumée de l'erreur. A coté du
message, un icone vous indique le type de l'erreur. Enfin, si l'erreur
est relative à une partie de votre source, la partie concernée est
affichée en mode inverse dans sa fenêtre d'édition.
Les erreurs d'édition sont indiquées par un triangle enfermant un
point d'exclamation; les erreurs de compiltion sont signalées par une
sorte de coccinelle verte et les erreurs de linkage sont signalées par
une chaine. Si dans le message décrivant l'erreur est indiqué un
numéro d'erreur, celui-ci est un code d'erreur standard GS OS tel que
décrit dans les manuels GS OS. L'appendix A comprend la liste des
messages d'erreurs retournés par TML.
``CHAPITRE 4: LES RESSOURCES
```INTRODUCTION:
L'ajout le plus intéressant du système 5.0 est le Resource
Manager (Gestionnaire de Ressources). Le Resource Manager est un outil
spécial qui manipule les ressources stockées dans la Composante de
Ressource des fichiers GS OS. Rappelez-vous qu'un fichier stocké sous
GS OS peut avoir deux composantes: la composante donnée et la
composante de ressources. Un fichier n'a encore qu'un seul nom, mais
chaque composante peut-être ouverte et consultée séparément de
l'autre.
fichier GS OS
La composante de données est typiquement manipulée en utilisant
les appels du système GS OS: ouvrir, lire, écrire et fermer le
fichier. Le fichier est simplement traité comme une collection
d'octets sur un disque ou un autre périphérique de stockage.
L'organisation des données dans la composante de données n'est pas
bien définie et est typiquement très différente pour chaque type de
fichier. Voir GS OS REFERENCE pour une documentation complète
concernant les routines fournies par GS OS pour manipuler une
composante de données.
Une composante de ressource, d'autre part, est manipulée en
utilisant le Resource Manager. Le Resource Manager définit la
structure précise pour la composante de ressources et fournit
plusieurs routines pour accéder et manipuler les informations stockées
dans la composante de ressource. TML Pascal II ajoute un éditeur de
Resources pour créer et éditer graphiquement des ressources, et c'est
le sujet de ce chapitre. Pour une documentation complète sur la
composante de ressources contenu par le Resource Manager, voir le
manuel Apple //GS Toolbox Référence Update.
```LES RESSOURCES:
Une ressource est une collection de données formatées, organisées
d'une certaine manière, qui représente un menu ou une barre de menu,
une fenêtre, une chaine d'alerte, ou tout autre nombre ou type de
données définis par le système ou par l'utilisateur. La structure
exacte de chaque type de ressource n'est pas définie par le Resource
Manager. Le Resource MAnager définit seulement comment les ressources
sont stockées sur le disque, non leur contenu.
Un programme identifie une ressource par son Resource Type et son
Resource ID. Le Resource Type définit une classe ou un groupe de
ressources qui partagent un format commun. Le Resource ID identifie
uniquement un cas (exemple) de ressource d'un ressource type donné.
Réunis, le Resource Type et le Resource ID identifient complètement la
ressource et son format. Notez qu'un Resource ID est seulement unique
parmi un Resource Type. Deux ressources de différents Resources Types
peuvent avoir le mème Resource ID.
Le Resource Type est un nombre entier de deux octets. La table
suivante montre les champs de types de ressources:
Types de ressources définis par Apple
suite Resource Type
$0000 numéro de resource type non valable
(ne pas utiliser)
$0001-$7FFF valable pour l'utilisation des applications
$8000-$FFFF réservé pour l'utilisation du système
Parmi les types de ressources réservés pour l'utilisation du
système, Apple a prédéfini plusieurs types de ressources. Ces types de
ressources prédéfinis sont utilisés pour stocker les représentations
des éléments de la boite à outils du //GS. Par exemple, une ressource
pèut être utilisée pour définir la structure et les contenus d'un menu
ou d'une fenêtre. Ces ressources prédéfinies sont montrées dans le
tableau suivant:
TML Nom du Resource Type Numéro (hex) du Resource Type
rIcon $8001
rPicture $8002
oui rControlList $8003
oui rControlTemplate $8004
oui rPString $8006
rStringList $8007
oui rMenuBar $8008
oui rMenu $8009
oui rMenuItem $800A
rTextForLETextBox2 $800B
rCtlDefProc $800C
oui rWindParam1 $800E
rWindParam2 $800F
rWindColor $8010
oui rTextBlock $8011
rStyleBlock $8012
oui rToolStartup $8013
rResName $8014
oui rAlertString $8015
oui rText $8016
rCodeResource $8017
rCDEVCode $8018
rCDEVFlags $8019
rTwoRects $801A
rListRef $801C
oui rCString $801D
oui rErrorString $8020
Le nom de Resource Type dans la table ci-dessus est donné dans un
but de description. En plus, l'unité d'interface Resource.p de la
Boite à outils Apple //GS utilise les mèmes noms comme constantes dont
les valeurs sont celles indiquées dans la table. La colonne TML
indique si l'éditeur de ressource TML fournit l'édition des ressources
données.
Comme mentionné au-dessus, chaque ressource a un Resource Type et
un Resource ID. Un Resource ID est un entier long de quatre octets. La
table ci-dessous montre les champs de Resource ID:
Champ Resource ID
$00000000 numéro de Resource ID non valable
(ne pas utiliser)
$00000001-$07FEFFFF pour l'utilisation des applications
$07FF0000-$07FFFFFF réservé au système
$08000000-$FFFFFFFF valeurs a ne pas utiliser
Lorsqu'on crée de nouvelles ressources, un Resource ID unique
peut-être obtenu pour le Resource Type auquel la ressource appartient.
Le Resource Manager fournit la routine UniqueResourceID dans ce but.
Les Resource IDs sont importants à retenir, parcequ'ils sont réclamés
comme paramêtres pour plusieurs routines de la boite à outils qui
chargent et créent des menus, fenêtres etc...
```L'EDITEUR DE RESSOURCES:
````Introduction:
Comme mentionné précédemment, TML Pascal contient un éditeur de
ressources. L'Editeur de Ressources de TML est utilisé pour créer
graphiquement et éditer plusieurs des types de ressources prédéfinis
par Apple. En utilisant l'éditeur de ressources, vous pourrez créer
des menus, fenêtres, alertes, chaines etc.. uniquement en cliquant la
souris. Les ressources que vous créez peuvent être incorporés à
l'intérieur d'un programme dans le but de créer rapidement et
facilement des applications de bureau (desktop) complexes.
````Resource Document Window:
Quand TML ouvre un fichier ressource, il affiche une fenêtre.
Cette fenêtre contient deux listes déroulantes. La liste de gauche
affiche chaque Resource Type pour lequel une ressource existe dans le
fichier ressource. L'affichage donne le numéro du Resource Type et
optionnellement un nom de Resource Type. Seules les ressources que
l'Editeur de Ressources fournit sont montrées avec un nom de Resource
Type. Cela permet de distinguer quelles ressources peuvent être
éditées ou non.
La liste de droite affiche chaque ressource existant pour le type
sélectionné dans la liste de gauche. La liste affiche le numéro de
Resource ID. Par exemple, le Resource Type fenêtre est sélectionné et
le fichier contient deux ressources fenêtres (1001 et 1002). Pour
éditer une ressource particulière, double cliquez simplement sur son
Resource ID.
En plus de ces deux listes, la fenêtre du document Resource
contient un pop-up menu et un bouton. La Nouvelle Ressource bouton est
utilisée pour créer de nouvelles ressources du type actuellement
sélectionné. Le pop-up menu est utilisé pour créer une nouvelle
ressource quand le Resource Type n'existe pas encore dans le fichier.
Chaque ressource a son jeu d'attributs qui définit comment la
ressource peut être utilisée. Les attributs sont stockés par le
Resource Manager pour chaque ressource dans l'attribute flag word. En
plus, le Resource Manager fournit deux routines: GetResourceAttr et
SetResourceAttr pour lire et écrire des attributs de ressource.
L'éditeur de ressource TML fournit un bouton "Attr..." dans
chaque fenêtre d'édition de ressource. En cliquant ce bouton on
affiche la fenêtre de dialogue d'Attributs de ressource avec les
attributs actuels de ces attributs de ressource. Cliquer sur le bouton
OK dans le dialogue va mettre à jour la nouvelle configuration des
attributs de ressource.
Voici la signification de chacun des attributs de ressource:
Locked (verrouilé) si cet attribut est mis, alors le Resource
Manager appelera NewHandle pour créer un
handle verrouillé quand il allouera la
mémoire pour la ressource.
Fixed (fixé) si cet attribut est mis, le Resource Manager
appellera NewHandle pour créer un Handle Fixé
quand il allouera la mémoire pour le
ressource.
Resource Converter cet attribut indique si la représentation de
la ressource comme elle est stockée dans la
composante de ressource du fichier doit être
convertie en une représentation différente
quand elle est lue à l'intérieur de la
mémoire. Si l'attribut est mis, la ressource
doit être convertie.
Write-protection si cet attribut est mis, la ressource est
protégée en écriture. Ce qui signifie qu'une
application ne peut remettre à jour les
contenus de ressource de la composante de
ressource d'un fichier.
Preload si cet attribut est mis, le Resource Manager
chargera automatiquement la ressource en
mémoire avec son fichier ressource si le
fichier est ouvert. Si une ressource n'est
pas configurée pour être pré-chargée alors
elle doit être chargée en mémoire de manière
explicite avec la routine LoadResource du
Resource Manager.
Do not cross bank si cet attribut est mis, le Resource Manager
demandera a NewHandle de créer un handle qui
ne sortira pas d'un banc mémoire lors de
l'attribution de Stockage pour la ressource.
Do not use special si cet attribut est mis, le Resource Manager
demandera à NewHandle de créer un handle qui
n'occupera pas de mémoire spéciale lors de
l'attribution de mémoire pour la ressource.
Page aligned si cet attribut est mis, le Resource Manager
demandera à NewHandle de créer un handle
d'alignement de page lors de l'attribution de
mémoire pour la ressource.
Purge level le Resource Manager donne la valeur du niveau
de purge à NewHandle quand il alloue la
mémoire pour la ressource.
*NOTE: la valeur par défaut de tous les attributs de ressource est NOT
et chacun des niveaux de purge de zézo (0).
```PASCAL STRING RESOURCE:
La chaine Pascal (rPString) stocke une chaine jusqu'à 255
caractères ASCII. La chaine commence avec un octet entier qui est un
compte indiquant le nombre de caractères qui suivent dans la
ressource. Les ressources Pascal String sont largement utilisées par
les autres types de ressources. Par exemple, les types de ressources
rMenuItem, rMenu, rWindParam1 et plusieurs des différents
rControlTemplate référencent une ressource rPString pour stocker leurs
titres.
```C STRING RESOURCE:
La chaine C (rCString) stocke une chaine qui se termine par un
octet mis à 0. Il n'y a pas de restriction sur le nombre de caractères
contenus dans une ressource chaine C. Les ressources rCString ne sont
pas souvent utilisées dans les programmes en TML PAscal, parceque le
Pascal ne fournit pas le mécanisme naturel pour utiliser ces types de
chaines. Cependant l'Editeur de Ressource de TML supporte ce Resource
Type.
```ALERT STRING RESOURCE:
La chaine Alerte (rAlertString) stocke une chaine de caractères
qui est terminée par un octet zéro (nul). La chaine est utilisée avec
la fonction AlertWindow du Window Manager pour afficher de simples
fenêtres d'alerte. La ressource chaine d'alerte stocke le message
devant appraitre dans une fenêtre d'alerte avec les codes spéciaux qui
définissent la taille de la fenêtre, si un icone apparait ou non, et
les boutons.
Pour une descriptiion complète du format et de la structure de la
chaine d'alerte, voir le chapitre Window Manager de l'Apple //GS
Toolbox Reference Update.
L'éditeur de ressources du TML Pascal II permet l'édition et la
création de chaines d'alerte pour utiliser avec la procédure
AlertWindow du Window Manager. Cependant les chaines d'alerte ont un
formatage très spécial:
- une chaine d'alerte (AlertString) doit commencer par un
caractère de séparation (le caractère / est recommandé)
- le caractère de séparation est utilisé pour séparer un texte de
chaine d'alerte (AlertTextString) des boutons chaine d'alerte
(AlertStringButtons). Pour créer un bouton dans une alerte,
entrer simplement le caractère de séparation suivi par le caret
(accent circonflexe), un symbole pound (#) et finalement un
chiffre entre 0 et 6 correspondant aux titres des boutons
suivants:
#0 OK
#1 Cancel
#2 Yes
#3 No
#4 Try again
#5 Quit
#6 Continue
- les codes de formatage de LETextBox2 sont permis à l'intérieur
d'un texte de chaine d'alerte. Ces codes sont entrés en
utilisant le bouton "Insert LETextBox2" dans le dialogue
AlertStringResource de TML Pascal II. Les options de formatage
doivent être entrées après que tous les AlertStringText l'aient
été, car les codes sont des caractères invisibles ce qui rend
leur édition difficile. Les codes de LETextBox2 sont
complètement documentés dans le chapitre LineEdit du manuel de
référence de la Toolbox Apple IIGS.
```TOOL STARTUP RESOURCE:
La ressource rToolStartup est utilisée par une application pour
spécifier à la boite à outils du IIGS quels outils sont requis par
l'application et si l'application utilise le mode écran 320 ou 640.
La ressource rToolStartup est utilisée avec une nouvellle
fonction StartupTools et la fonction ShutDownTools fournies par les
outils du ToolLocator. Ces deux routines utilisées ensembles avec
rToolStartup implémente le travail nécessaire pour commencer à
utiliser la boite à outil du IIGS. Ces opérations comprennent:
- démarrer le Resource Manager
- ouvrir une ressource fourche d'application
- allouer le montant approprié de page directe pour les outils
qu'il utilise
- démarrer chaque outil utilisé par l'application
```MENU BAR RESOURCE:
La ressource barre de menu (rMenuBar) est une suite ordonnée de
ressources Menu qui définit une barre de menu. La ressource est
utilisée par la procédure NewMenuBar2 du Menu Manager pour créer une
barre de menu de l'application.
Le long rectangle en haut du dialogue représente la barre de menu
actuellement définie par la ressource. La liste déroulable dans le
coin en bas à gauche est une liste complète de chaque ressource Menu
dans le fichier ressource ouvert. Les boutons Insert Menu et Delete
Menu sont utilisés pour ajouter des menus ou en effacer de la barre de
menu. Pour ajouter un nouveau Menu dans la barre de menu, premièrement
sélectionner le menu dans la barre de menu o| le menu nouvellement
ajouté devra être placé après. Puis sélectionner le menu à ajouter
depuis la liste des menus valables, et finalement cliquer le bouton
Insert Menu. Pour effacer un menu de la barre de menu, sélectionner le
menu à effacer dans la barre de menu puis cliquer sur le bouton Delete
Item.
```MENU RESOURCE:
La ressource Menu (rMenu) est une suite ordonnée de ressources
MenuItem qui définit un menu. Les ressources Menu sont typiquement
référencées par les ressources Menu Bar, mais peuvent être utilisées
directement par la routine NewMenu2 de l'outil Menu Manager.
La ressource Menu est une des deux super Ressources que l'Editeur
de Ressources TML permet (l'autre est la ressource Fenêtre). Une
ressource Menu comme définie par Apple stocke simplement les
références vers les autres ressources. En particulier une ressource
chaine Pascal pour le titre du menu et ensuite une suite ordonnée de
références pour les ressources MenuItem (rMenuItem). Chaque ressource
MenuItem a ses propres références une autre chaine pascal pour son
titre. Par exemple, un menu avec seulement 6 menus items (éléments de
menus) consiste actuellemnt en 14 différentes ressources. Une pour la
ressource Menu, une pour la ressource chaine pascal pour le titre du
menu et six ressources Menu Items qui référencent six chaines pascal
pour leurs titres. En clair, créer les nombreux menus qu'une
application requiert serait une tache très fastidieuse si chaque
ressource devait être crée et référencée individuellement. En
conséquence, l'Editeur de Ressource TML groupe toutes ces taches
d'édition de ressources en de simples dialogues pour créer et éditer
facilement des Ressources Menu. L'Editeur de Ressource TML ne fournit
pas de signification directe d'édition de ressource Menu Item.
L'édition de l'élément en haut à gauche du dialogue est le titre
du menu. La liste déroulable dans la partie gauche du dialogue est la
liste actuelle d'éléments menu (Menu Item) contenus dans le menu. Pour
éditer un élément de menu particulier cliquer simplement sur son nom
dans la liste. Quand un élément menu est sélectionné, son nom et ses
caractéristiques sont affichés dans plusieurs éléments de la partie
droite de l'affichage du dialogue.
L'Editeur de Ressource vous permet de spécifier un des cinq types
de style pour dessiner les éléments du menu titre, et si l'élément du
menu a une ligne de séparation et/ou est validé. En plus vous pouvez
spécifier un équivalent touche de commandes pour l'élément du menu et
un caractère de marquage. L'item ID est la valeur retournée par
TaskMaster ou MenuSelect dans une application quand l'utilisateur
sélectionne un élément du menu. L'Editeur de Ressource utilise aussi
ce nombre comme le ressource ID de la ressource Menu Item et sa
ressource chaine pascal de titre.
```WINDOW RESOURCE:
La ressource fenêtre (rWindParam1) stocke les informations
nécessaires pour créer une fenêtre sur le bureau Apple //GS (Desktop)
en utilisant la fonction NewWindow2 du Window Manager. La ressource
fenêtre définit l'emplacement de la fenêtre, la taille zoom, le titre,
la définition de l'encadrement (frame) et les autres attributs. En
plus, la ressource peut référencer une liste de controles intégrés.
Les controles intégrés peuvent être des boutons, des boites test
(check box), des boutons radio, une édition de texte, des ascenseurs,
des pop-up menus... qui apparaissent dans le contenu de la fenêtre.
La ressource fenêtre est la deuxième des deux super ressources
que l'Editeur de Ressource TML supporte (l'autre est la ressource
Menu). Comme la ressource Menu, la ressource fenêtre peut référencer
de nombreuses autres ressources. Une fenêtre peut référencer une
ressource chaine pascal pour son titre, et si la fenêtre a des
controle sintégrés, il référencie une ressource Control List
(rControlList). Une ressource ControlList référencie ensuite plusieurs
ressources Control Template (rControlTemplate) pour chaque bouton,
boite test, bouton radio, élément d'édition de texte, ascenseurs, menu
po-up etc... qui apparait dans la fenêtre. Et plus loin, chaque
Control Template peut référencer uen ressource chaine pascal pour son
titre. En clair, créer une ressource fenêtre serait une tache très
pénible si chacun de ces éléments devait être créé individuellement
puis référencé de manière appropriée. L'Editeur de Ressource TML ne
fournit pas de signification directe d'édition de ressources Control
List ou Control Template.
La grande zone bleue au centre du dialogue est utilisée pour
représenter une échelle à 50% du bureau du GS avec une fenêtre. La
fenêtre représente l'emplacement et la taille de la fenêtre telle
qu'elle est définie par la ressource fenêtre. Pour changer
l'emplacement de la fenêtre, cliquer simplement dans le contenu de la
surface de la fenêtre et déplacez-la. Pour changer la taille de la
fenêtre cliquer dans la case de taille du coin inférieur droit de la
fenêtre et déplacez-la. Le bouton Center peut être utilisé pour
centrer rapidement la fenêtre sur le bureau. Les boutons radios des
modes 640 et 320 sont utilisés pour informer l'Editeur de Ressource
sur l'écran graphique à utiliser quand la fenêtre sera créée.
L'Editeur de Ressource utilise ces informations pour calculer
correctement l'échelle de la taille de la fenêtre dans le dialogue. Le
bouton frame (structure) est utilisé pour afficher le dialogue de
définition de la structure de la fenêtre et ses informations. Le
bouton Controls est utilisé pour demander le dialogue Content Controls
(controles intégrés) et créer les controles intégrés qui appartiennent
à la fenêtre.
````Window Frame Definition:
Le dialogue de définition de la structure est utilisé pour
définir les attributs de la strucutre de la fenêtre, taille zoom,
taille des données contenues et les informations de la hauteur de la
barre.
La signification de chacun des attributs ressource est expliqué
dans la table suivante:
Attribut Signification
Title bar mis si la fenêtre a une barre de titre
Close box " " " une case de fermeture
Alert frame type " " " devra être dessinée avec un
style d'alerte au lieu de la strucure d'un
document standard. Une strucure d'alerte est
typiquement utilisée pour les modals dialogs.
Vertical scroll bar mis si la fenêtre a une barre de défilement
verticale
Horizontal scroll bar " " " " " " horizontale
Grow box mis si la fenêtre a une case de taille
Zoom box " " " une case de zoom
Moveable doit être traitée comme une
région déplaçable pour déplacer la fenêtre sur le
bureau
Quick in content mis si un clic dans une région contenue dans la
fenêtre (pas en avant) sélectionnera la fenêtre
comme serait traité un clic dans le contenu.
Visible mis si la fenêtre est visible quand elle est créée
Information bar mis si la fenêtre a une barre d'information
Zoomed " " " est initialement agrandie
Zoom rect définit les coordonnées haut, gauche, bas et
droite de la fenêtre quand elle est agrandie
Data height/width définit la taille en pixels de la hauteur et
largeur de la fenêtre
Info height définit la hauteur de la barre d'information si la
fenêtre en possède une
````Window Controls Definition:
Le dialogue de controle de fenêtre est utilisé pour définir les
controles contenus dans la fenêtre. Les controles intégrés sont un
simple bouton, une case de test, un bouton radio, une édition de
ligne, une édition de texte, une case de taille, un texte statique,
une image, un bouton icone, des ascenseurs, un menu pop-up, une liste.
Pour créer un nouveau controle, cliquer simplement sur la palette de
controle dans la partie gauche de la case de dialogue pour le type de
controle désiré puis cliquer à l'intérieur de la fenêtre à l'endroit
o| le controle devra être placé.
``CHAPITRE 5: MODE D'EMPLOI DE TML II
```LE MENU POMME:
Contient une rubrique ABOUT donnant les références et copyright
de TML Pascal II.
En dessous, se trouvent les NDA disponibles dans votre disquette
de lancement.
Ensuite, on trouve OPEN NDA si on vient de compiler en mémoire un
accessoire de bureau. Cela permet de tester le programme NDA que vous
venez de compiler.
Si un accessoire de bureau vient d'être compilé, l'option
REMOVENDA est également présente. Elle permet de libérer la mémoire du
code compilé de l'accessoire de bureau. De plus, après usage de cette
option OPEN et REMOVE NDA disparaissent de ce menu.
```LE MENU FILE:
Ce menu contient les options habituelles:
NEW : créer une nouvelle fenêtre d'édition Source ou Resource. On
peut ouvrir autant de fenêtre que la mémoire disponible le
permet.
OPEN : ouvrir un fichier Source ou Resource existant.
CLOSE : fermer la fenêtre d'édition active. Si le fichier n'a pas
été sauvé, une alerte vous demande de confirmer.
SAVE : sauver la fenêtre active avec son nom courant SAVE AS :
sauver la fenêtre active en la renommant
REVERT : remplacer les modifications apportées à la fenêtre d'édition
active, par la dernière version sauvée.
PRINT OPTIONS: permet de configurer le Haut de Page pour l'impresion:
présence facultative du nom, de la date et du numéro de page
PAGE SETUP: permet de définir les commandes d'impression.
Soit papier continu (listing) ou feuille à feuille (cut
sheet). Avec l'option Continuous, l'en-tète est imprimé
uniquement sur la première page et aucune ligne n'est sautée
en bas de page. Avec Cut Sheet, l'en-tète estimprimé en haut
de chaque page, en bas de page il y a saut de lignes et il
faut spécifier le nombre de lignes à imprimer (défaut: 8'1/2
x 11'). Les commandes d'impression éditables permettent
d'envoyer une commande AVANT l'impression (changement de
fonte, style...). Les caractères de controle sont
représentés par * (attention: cette * est un accent
circonflexe) suivi de la lettre représentant le caractère
controle à envoyer. Par exemple, * [ va envoyer ASCII 27
(caractère Escape). (attention: cette * est un accent
circonflexe)
PRINT : impression du fichier se trouvant dans la fenêtre active.
Entapant OPTION lors du choix de cette commande, seul le
texte sélectionné sera imprimé (texte en mode inverse).
QUIT : quitter TML et revenir au Launcher. Une alerte vous demande
de confirmer pour la sauvegarde des fichiers en cours
d'édition.
```LE MENU EDIT:
Les commandes traditionnelles:
UNDO : annule la dernière opération d'édition effectuée.
CUT : transférer une zone sélectionnée, dans le Presse-Papier
COPY : dupliquer une zone sélectionnée, dans le Presse-Papier
PASTE : coller le contenu du Presse-Papier à partir de la position
du curseur
CLEAR : effacer la zone sélectionnée
SELECT ALL: sélectionne tout le contenu de la fenêtre d'édition
SET FONT-SIZE: permet de définir la forme et la taille de la fonte de
la fenêtre d'édition ainsi que la largeur des tabulations.
```LE MENU SEARCH:
FIND : affiche une fenêtre de dialogue o| l'on indique la chaine à
rechercher à partir de la position actuelle du curseur (et
non depuis le début du fichier).
FIND NEXT: poursuit la recherche à partir de la position du curseur de
la chaine spécifiée dans le dialogue 'Find'.
FIND SELECTION: recherche à partir du curseur la position de la chaine
sélectionnée dans la fenêtre d'édition.
REPLACE: affiche le menu de Remplacement permettant d'indiquer la
chaine à chercher (à partir du curseur) et celle qui la
remplacera.
REPLACE SAME: poursuit le remplacement de la chaine indiquée dans la
dialogue 'Remplacement'.
GOTO SELECTION: fait défiler le texte de manière à afficher la zone
contenant le curseur
```LE MENU WINDOW:
NEXT WINDOW: fait passer la fenêtre active en toute dernière position.
Ainsi la fenêtre suivante est alors placée en première
position et devient active.
GET INFO: affiche le préfixe d'accès du fichier actif, sa taille en
octets et le nombre de lignes.
LAST ERROR: affiche la fenêtre d'alerte contenant le dernier message
d'erreur détecté par TML.
```LE MENU COMPILE:
TO MEMORY: compile en mémoire le source de la fenêtre active. Si ce
source est un programme, celui-ci est exécuté. Si le source
est un NDA, l'option OPEN et REMOVE NDA est activée dans le
menu POMME. Si le source est une UNIT, celle-ci est
simplement compilée en mémoire.
TO DISK : compile sur disque le source présent dans la fenêtre active.
Si le fichier est un programme, TML génère un fichier compilé de type
$B3, si le fichier est une unit, le code objt compilé à son
nom se terminant par '.p.o'.
CHECK SYNTAX: vérifie si le source de la fenêtre active contient des
erreurs de syntaxe.
ADD RESOURCES: permet de lier le fichier principal avec un fichier
resource présent sur la disquette. Cette liaison permettra
d'effectuer le collage des resources avec le programme lors
des compilations.
PREFERENCES: permet d'indiquer un certain nombre de paramêtres en
standard.
K-bytes symbol table: taille allouée pour la table des ymboles.
Une telle table est une zone de données servant au
compilateur pour y stocker les déclarations de labels,
variables, tableaux, procédures et fonctions. Dans la
majorité des cas, la taille standard de 12k est
suffisante. Cependant si une erreur de type ERROR
SYMBOL TABLE SPACE EXHAUSTED se produit, il faudra
augmenter ce paramêtre (maxi 32K, mini 2K).
K-byte Stack: les programmes TML ont besoin d'une pile
d'exécution. Valeur par défaut: 8K; valeur mini: 1K et
maxi: 32K. Cette option peut également être changée par
la directive $StackSize.
Keyboard break: permet d'implémenter le CTRL-C. Si cette option
est cochée, TML génère un code entre chaque instruction
afin de détecter si CTRL-C a été tapé. On peut aussi
utiliser la directive $KeyboardBreak pour activer
l'option.
Unit search path: permet d'indiquer à TML le préfixe d'accès des
UNITS indiquées dans les clausess USES. La valeur par
défaut est 1:TOOLINTERFACES: qui indique le dossier
ToolInterface situé dans le dossier contenant le
compilateur pascal.
Auto save text: indique si on veut sauver automatiquement les
sources lors de la compilation en mémoire. Ceci permet
de conserver son source sur disque au cas o| un
'incident' se produiraait lors de l'exécution du code
compilé.
Total system memory: indique la taille RAM maxi
Free memory: indique la taille RAM disponible
Largest memory block: la taille du plus large bloc disponible en
mémoire
OK : on accepte les paramêtres du menu préférences (ou taper
RETURN).
CANCEL : on efface les paramêtres entrés et on récupère les
anciens.
RELEASE MEMORY: purge les zones mémoires occupées par des codes
compilés.
```LE MENU GS OS:
RENAME : permet de renommer un fichier se trouvant sur disquette.
DELETE : permet d'effacer définitivemeent un fichier présent sur
disquette TRANSFER: permet de lancer une application sans
revenir au Launcher.
``CHAPITRE 6: LES APPLICATIONS TEXTBOOK
La programmation de l'Apple II GS peut parfois apparaitre
dissuasive, intimidante. Pour cette raison, non seulement le
compilateur Pascal TML a été réalisé pour développer des applications
sur Apple II GS avec des accessoires de bureau qui utilisent
l'interface "desktop" mais aussi pour fournir un environnement de
programmation en Pascal plus traditionnel. C'est à dire la possibilité
d'écrire des applications utiles sans avoir à s'occuper des fenêtres,
Menus, controles, etc...
Ce type d'application est appelé une application "textbook". Les
applications "plain vanilla" sont encore des applications autonomes
GS/OS mais elles représentent le programme Pascal Standard le plus
représentatif que l'on puisse trouver dans un ouvrage ou dans
l'environnement informatique traditionnel. Ces programmes n'utilisent
que peu ou prou la boite à outil du II GS et assurent donc la
portabilité des programmes pour l'Apple II GS.
Un programme "textbook" s'exécute sur l'Apple II GS en mode
super-haute définition 640. Le compilateur génère le code qui
initialise les outils de l'Apple II GS et crée une fenêtre unique sur
l'écran qui permettra l'affichage standard en 20 lignes et 80
colonnes. A l'intérieur de cette fenêtre vous pourrez utiliser les
procedures Pascal standard READLN et WRITELN, et parce qu'il s'agit
d'une fenêtre Apple II GS vous pourrez également utiliser le graphisme
QUICKDRAW.
La programmation "textbook" est particulièrement utile aux
programmeurs débutants du langage Pascal qui par conséquent sont à la
découverte des possibilités fascinantes de l'Apple II GS. Les
programmeurs expérimentés apprécieront aussi cette possibilité du
Pascal TML aussi bien pour la construction "vite faite" d'outils ou
pour tester une nouvelle portion de code sans avoir à rentrer dans les
détails de l'utilisation des outils de l'Apple II GS.
La structure d'un programme "textbook" est trés simple et
rigoureuse.
Le premier programme exemple FIRSTPROG est un programme
"textbook".
PROGRAM FirstProg;
BEGIN
Writeln('Hello World');
Readln;
End.
``CHAPITRE 7: LES APPLICATIONS GRAPHIQUES TEXTBOOK
Parceque les programmes 'textbook' tournent actuellement dans le
mode super-haute-résolution de l'Apple II GS en utilisant QUICKDRAW,
il est possible d'utiliser les fonctions graphiques de QUICKDRAW dans
vos programmes 'textbook'.
La définition de tels programme se fait au moyen de la procédure
Graphics qui initialise le bureau du GS à l'aide de Quickdraw et
spécifie le mode de résolution 320 ou 640. Le bureau ainsi préparé n'a
ni barre de menu ni fenêtre. Par exemple:
PROCEDURE Graphics(screenMode: Integer);
Voici la transformation de notre précédent exemple en application
graphique:
PROGRAM HelloWorld;
BEGIN
Graphics(640);
WriteLn('Hello world');
ReadLn;
END.
Pour utiliser QuickDraw il faut bien entendu inclure le nom de ce
module dans la clause USES de votre programme. Quand votre programme
se lance, QuickDraw a déjà été initialisé et il est pret à l'emploi.
De plus, l'Event Manager est également disponible et la souris
activée.
Par exemple:
PROGRAM GraphicHelloWold;
USES Types,
QuickDraw;
VAR aRect: Rect;
BEGIN
Graphics(320);
SetRect(aRect,10,10,30,40);
FrameRect(aRect);
OffsetRect(aRect,25,30);
FrameOval(aRect);
OffsetRect(aRect,25,30);
FrameRRect(aRect,20,20);
MoveTo(50,30);
DrawString('HelloWorld');
END.
Sur la disquette TML se trouve un exemple d'application graphique
textbook nommée Graphics.p.
``CHAPITRE 8: LES APPLICATIONS DESKTOP
Ce chapitre donne les grandes lignes de l'accés au Pascal TML et
à l'emploi du 'Toolbox' (boite à outils) de l'Apple II GS ce qui
naturellement est la base pour la gestion des évènements, les
applications basées sur le presse-papier et les accessoires de bureau.
La boite à outils est un ensemble important de logiciels organisés en
plusieurs sous-ensembles selon leur fonction appelés 'Tool Set'
(outils) ou 'Managers' (gestionnaires). A l'intérieur de chaque outil
se trouve un ensemble de routines nécessaires à la fonction de
l'outil. A chacun des outils est attribué un numéro d'outil qui lui
est propre et à chacune de ses routines est attribué un numéro de
fonction particulier.
Le Pascal TML permet l'accés à la Boite à outils de l'Apple II GS
grace à un ensemble de modules Pascal. Dans un module on trouve des
Constantes, des Types, des Procédures et des Fonctions qui
correspondent à une ou plusieurs des routines 'outil' de l'Apple II
GS. Ainsi, chaque fois qu'une application nécessite l'accés à une
partie de la boite à outils, elle doit préciser le nom du module
Pascal dans la clause USES qui défini le lien avec les routines de la
boite à outils. Ces modules Pascal se trouvent dans le répertoire
TOOLINTF/ de la disquette de distribution Pascal. Par exemple, la
clause USES suivante rend l'outil 'QuickDraw II' disponible :
USES QuickDraw;
```LES OUTILS DE L'APPLE II GS
Avec la version Système 5.0 minimum du II GS, 30 outils
différents ont été définis en tant que sous-ensembles de la boite à
outils. Chacun d'entre eux est listé dans la table ci-dessous avec le
module Pascal qui défini son interfaçage. Il est précisé en outre si
celui-ci réside en ROM dans le II GS ou sur disquette comme un fichier
outil et qui doit alors être chargé en RAM avant d'être utilisé. Si un
outil doit résider en RAM alors son fichier outil correspondant doit
être disponible dans le répertoire SYSTEM/TOOLS/ de la disquette
d'amorçage. Le nom d'un fichier outil est TOOLxxx o| xxx représente un
nombre de trois chiffres correspondant au numéro d'outil attribué. Par
exemple, le fichier outil du gestionnaire d'écran a le nom : TOOL014.
N[ Outil Nom d'outil Module Pascal RAM ROM
1 Tool locator Locator.p X
2 Memory Manager Memory.p X
3 Miscellaneous Tools MiscTool.p X
4 QuickDraw II QuickDraw.p X
5 Desk Manager Desk.p X
6 Event Manager Event.p X
7 Scheduler Scheduler.p X
8 Sound Manager Sound.p X
9 Apple Desktop Bus ADB.p X
10 SANE SANE.p X
11 Integer Math IntMath.p X
12 Text Tools TextTool.p X
13 réservé au système
14 Window Manager Windows.p X
15 Menu Manager Menus.p X
16 Control Manager Controls.p X
17 System Loader Loader.p X
18 QuickDraw Aux Rout QDAux.p X
19 Print Manager Print.p X
20 Line Edit LineEdit.p X
21 Dialog Manager Dialogs.p X
22 Scrap Manager Scrap.p X
23 Standard File StdFile.p X
24 Disk Utilities n/a X
25 Note Synthesizer NoteSyn.p X
26 Note Sequencer NoteSeq.p X
27 Font Manager Fonts.p X
28 List Manager Lists.p X
29 Audio Comp-Expan. ACE.p X
30 Resource Manager Resources.p X
32 MIDI MIDI.p X
34 TextEdit Manager TextEdit.p X
```QUE FONT CES OUTILS ?
Le paragraphe suivant expose bièvement la fonctionnalité de
chacun des outils de l'Apple II GS. Ce synoptique se veut une brève
introduction à chacun des outils et vous devrez consulter les volumes
1,2 et 3 de Apple II GS ToolBox Reference pour en savoir davantage.
````Les 7 outils de base:
TOOL LOCATOR
Le localisateur d'outil est le plus important. Sans cet outil il
serait impossible d'accéder aux autres outils. Le localisateur d'outil
vous permet de charger en RAM les outils à partir de la disquette et
de les solliciter comme nous l'avons vu sans savoir en quel
emplacement de la mémoire ils sont rangés.
MEMORY MANAGER
C'est le plus important après le Tool Locator. Cet outil est
entièrement responsable de l'allocation, désallocation et
repositionnement des blocs mémoires de l'Apple II GS. Il garde en
mémoire le volume mémoire disponible et quelle partie est allouée et à
qui.
MISCELLANEOUS-TOOLS
Il est essentiellement constitué de routines systèmes qui doivent
être disponibles pour la plupart des autres outils.
QUICKDRAW
C'est l'outil qui controle l'environnement graphique de l'Apple
II GS et trace des objets simples et du texte. Tous les autres outils
qui créent des objets graphiques comme le gestionnaire de fenêtre,
font appel à lui.
QUICKDRAW AUXILIAIRE
Cet outil contient des routines supplémentaires qui complètent
l'outil QuickDraw de la ROM.
EVENT MANAGER
Le gestionnaire d'évènements permet aux applications de controler
et de réagir à une action de l'utilisateur comme les actions sur la
souris ou le clavier.
RESOURCE MANAGER
Il est responsable de la manipulation des données resources d'un
fichier GS/OS.
````Les outils d'interfaçage Desktop
CONTROL MANAGER
Il est constitué de toutes les routines nécessaires à la
manipulation des controles. Les controles étant ces choses comme les
barres déroulantes, les ascenseurs, les boites de vérifications,
etc...
DESK MANAGER
Cet outil rend une application capable de supporter les
accessoires de bureau, à la fois les accessoires de bureau classiques
et les nouveaux accessoires de bureau.
DIALOG MANAGER
Il fournit les routines qui permettent à une application de créer
et d'utiliser des boites de dialogue et d'alerte pour assurer une
communication entre un utilisateur et votre programme.
FONT MANAGER
C'est l'outil qui permet à votre application d'utiliser
différentes polices de caractères ou des styles différents.
LINE EDIT
Il permet à un programme de présenter du texte à l'écran et à
l'utilisateur d'éditer ce texte.
LIST MANAGER
Il est utilisé pour créer les listes qui sont utilisées à
l'affichage résultant de la sélection sur un montant ou sur une donnée
du mème genre.
MENU MANAGER
Il controle et permet l'utilisation des menus déroulant et
exploite les choix d'une application.
SCRAP MANAGER
Complète le 'brouillon' du bureau en ajoutant le couper, copie et
coller à une application.
TEXTEDIT MANAGER
Il implémente un éditeur de texte acceptant les changements de
fontes et de style.
WINDOW MANAGER
Il crée l'environnement Bureau et il est responsable de la
création et de la manipulation des fenêtres.
````Les outils de gestion de périphériques
APPLE DESKTOP BUS
Cet outil est une méthode et un protocole pour connecter des
équipements en entrée, comme des claviers et des souris, avec l'Apple
II GS. Les routines de cet outil sont utilisées pour émettre des
commandes et des données entre le microcontrolleur de Apple Desktop
Bus et le reste du système.
PRINT MANAGER
Il permet à une application d'utiliser les routines QuickDraw
pour imprimer du texte et du graphique sur l'imagewriter ou la
Laserwriter.
STANDARD FILE
Complète l'interface utilisateur pour spécifier un fichier à
ouvrir ou à sauvegarder.
TEXT TOOLS
Cet outil assure le lien entre les drivers d'équipement en
matière de caractères, qui doivent être exécutés en mode émulation, et
les applications tournant en mode natif.
````Les outils gérant le système
SCHEDULER
Le planificateur retarde l'activation d'un accessoire de bureau
ou d'une autre tache jusqu'à ce que les ressources nécessaires soient
devenues disponibles.
SYSTEM LOADER
Il est responsable du chargement et du relogement du code, commme
celui des applications ou des accessoires de bureau, en mémoire.
````Les outils sonores
SOUND MANAGER
Cet outil permet d'accéder à l'électronique du son de l'Apple II
GS pour créer des sons de base.
NOTE SYNTHESIZER
Utilisé pour créer des sons musicaux complexes en utilisant
l'électronique musicale de l'Apple II GS.
NOTE SEQUENCER
Sert à lier des notes du Note Synthetizer en séquences, motifs et
phrases constituant un son.
ACE
Permet de compresser/décompresser les sons digitalisés afin de
réduire leur encombrement sur disque.
MIDI
Permet de lier le GS avec un instrument à la norme MIDI via un
des ports série.
````Les outils mathématiques
INTEGER MATH
Cet outil est constitué de l'ensemble des opérations utilisées
sur des entiers. Ceci inclus multiplication, division, conversions,
etc...
SANE
Cet outil complète l'environnement numérique standard Apple. Il
donne une précision étendue IEEE 754 et 854 constituant un plus à
l'arithmétique en virgule flottante.
```COMMENT S'OPERE L'APPEL D'UNE ROUTINE OUTIL
Cette section est destinée aux programmeurs expérimentés qui
veulent comprendre comment une routine outil est actuellement appelée
à partir de Pascal. Si vous vous contentez du fait que tout fonctionne
et que les routines sont des sous-programmes supplémentaires internes
vous pouvez sauter cette section.
Comme précisé plus haut, le Pascal TML permet l'accés à la boite
à outils de l'Apple II GS grace à un ensemble de modules Pascal qui
définissent en Pascal le lien approprié à chacune des routines d'un
outil particulier. Chaque routine outil est définie comme une
procédure ou une fonction selon qu'elle retourne ou non une valeur
dans la pile et peut avoir zéro ou davantage de paramêtres.
Finallement, la déclaration de procédure ou de fonction est complétée
avec l'instruction Tool (Tool Directive à voir dans le chapitre 7 du
manuel de référence). L'instruction Tool est une extension
particulière au Pascal TML pour l'Apple II GS dans le but de définir
les liens avec la boite à outils. La déclaration de procédure suivante
est extraite du module QUICKDRAW.P et c'est le lien avec la procédure
MoveTo de l'outil QuickDraw.
PROCEDURE MoveTo(h,v:integer); Tool 4,58;
Comme vous pouvez le voir, la déclaration de procedure est
complétée d'une instruction Tool 4,58. Le premier entier de
l'instruction tool spécifie l'outil (toolset) auquel appartient la
routine. Dans ce cas c'est l'outil numéro 4 qui est Quickdraw. Le
second entier est le numéro de fonction de la routine de l'outil.
Chaque routine d'un outil a son numéro de fonction particulier. La
routine MoveTo s'est vu attribuer le numéro 58. Ensemble, ces deux
entiers permettent d'identifier une unique procedure dans la boite à
outils complète.
L'Apple II GS définit un processus pour activer une routine du
ToolBox. Pour appeler une routine, de l'espace pour les résultats de
fonctions doit d'abord être réservé sur la pile suivi de l'entassement
des valeurs des paramêtres. Alors le registre X du 65816 doit être
chargé avec le numéro de fonction de la routine outil et le numéro de
l'outil de telle sorte que le registre X contienne : 256 * numéro de
fonction + numéro d'outil. Finallement un grand saut à un
sous-programme est fait à l'adresse $E10000 qui contient alors un saut
dans le 'tool locator' (localisateur d'outil) qui trouve le code
associé à la routine outil désirée et lui passe le controle. Au retour
de la routine outil tous les paramêtres ont été enlevés de la pile
laissant éventuellement la valeur résultat au dessus de la pile. De
plus le drapeau de report du 65816 est vraie et si une erreur se
produit pendant l'exécution de la routine outil alors l'accumulateur
du 65816 contiendra un code d'erreur.
En utilisant l'instruction Tool avec une déclaration de procédure
ou de fonction et si les conventions précédentes sont réalisées alors
le Pascal TML génére une instruction de stockage de l'accumulateur
dans la variable globale ToolErrorNum (voir chapitre 10 du manuel de
référence) ainsi le code d'erreur potentielle retourné par une routine
outil peut être examiné. Ainsi l'instruction MoveTo(16,20) générera
les instructions 65816 suivantes :
pea $0010
pea $0014
ldx $3A04 ; 58 * 256+4
jsl $E10000
sta _ToolErr
Afin de permettre aux programmes écrits en TML Pascal d'effectuer
des controles d'erreur à l'appel des routines outil, le Pascal TML a
défini une fonction spéciale ISTOOLERROR qui examine l'état du drapeau
de report du microprocesseur. La fonction IsToolError ne doit être
utilisée qu'IMMEDIATEMENT aprés un appel à une routine outil pour être
sur que l'état du drapeau de report n'a pas été altéré par une autre
opération. Ainsi, un programme écrit en Pascal TML pourrait utiliser
le code suivant pour détecter une erreur se produisant dans la routine
MoveTo :
MoveTo(16,20);
if IsToolError then
Temp:= _ToolErr;
Writeln('Erreur survenu en MoveTo, #',Temp);
end;
Remarquez que la valeur de _ToolErr a été sauvegardée dans la
variable temporaire Temp avant l'appel à Writeln. Ceci parceque
Writeln lui-mème fait appel aux outils ce qui detruirait la valeur de
_ToolErr associée avec la condition d'erreur retournée par MoveTo.
Il y a au moins trois cas o| le compilateur n'a pas besoin
d'effectuer le stockage STA _ToolErr. Ce sont les suivants :
(1) Beaucoup de routines outils ne renvoie pas d'erreur (ceci est le
cas de l'exemple ci-dessus).
(2) Une application qui a d'autres garanties que toutes les conditions
possibles d'erreur n'existent pas.
(3) Une application qui ne serait pas affectée si une erreur
survenait.
Si ces raisons apparaissent souvent dans une application, alors
la génération de STA _ToolErr peut augmenter la dimension d'une
application inutilement. Pour éviter cela le Pascal TML dispose d'une
instruction $ToolErrorChk pour éviter ou réactiver la génération du
STA. (voir l'annexe B du manuel de référence).
Par exemple, l'appel suivant à la routine MoveTo ne générera pas
l'instruction STA ToolErrorNum :
(*$ToolErrorChk-*)
MoveTo(16,20);
Alors que l'utilisation de l'instruction $ToolErrorChk peut
économiser une grande quantité de code, le programmeur doit être trés
prudent dans son emploie afin d'éviter de tester la valeur du _ToolErr
alors qu'aucun code d'erreur ne sera affecté à cette variable.
```GESTION DES INTERRUPTIONS (EVENEMENTS)
Le concept de gestion des interruptions est un peu différent de
ce que vous avez l'habitude de faire en programmation. La statégie
habituelle et conventionnelle de la programmation d'une application
consiste à élaborer en séquence des actions qui sont exécutées l'une
aprés l'autre. L'action 1 est exécutée d'abord, suivie par l'action2,
puis l'action3 etc...
La gestion d'évènements utilise une approche opposée. Toutes les
actions sont possibles à un instant donné et l'action suivante dépend
d'un événement, générallement en réponse à une interaction de
l'utilisateur dans le programme.
La statégie étant donnée, la structure de base de toutes les
applications sur l'Apple II GS est presque toujours identique. Le
programme principal est générallement constitué des déclarations
suivantes :
BEGIN
StartUpGSTools;
(* routines pour initialiser menus, fenêtres, etc... *)
MainEventLoop;
ShutDownGSTools;
END.
Les procédures StartUpGSTools et ShutDownGSTools sont
responsables du chargement et de l'initialisation des outils de la
boite à outils devant être utilisés dans l'application et ensuite de
les 'fermer' avant la fin du programme (voir Utilisation de la boite à
outil de l'Apple II GS plus bas). La procédure MainEventLoop est
responsable de la détection des évènements et ensuite de la réponse
aux évènements. La structure typique de cette procédure est la
suivante :
procedure MainEventLoop;
var Event: EventRecord;
code: integer;
begin
gMainEvent.wmTaskMask := $001FFFFF; (*permet à tache princ.
de tout faire*)
gDone := false;
repeat
code:=TaskMaster($FFFF, gMainEvent);
case code of
wInGoAway: DoClose;
wInSpecial,
wInMenuBar: HandleMenu;
wInControl: DoControlHit;
end;
until gDone;
end;
````Les évènements GetNextEvent possibles:
nullEvent lorsqu'aucun évènement n'a eu lieu
mouseDownEvt généré lors d'un clic
mouseUpEvt généré lors de la fin de clic
keydownEvt généré lors de la frappe d'une touche
autoKeyEvt généré lors de l'enfoncement long d'une touche
updateEvt évènement interne spécifiant que le contenu d'une
fenêtre doit être redessiné (rafraichi).
activateEvt évènement interne spécifiant qu'une fenêtre
devient active ou inactive
switchEvt généré lorsqu'un controle switch est pressé
deskAccEvt généré lors de l'appel aux CDA
driverEvt généré lorsqu'un PostEvent est envoyé par un
périphérique (en général début ou arrèt de
transmission)
app1Evt-app4Evt il peut y avoir 4 évènements définis par
l'utilisateur et passés dans la queue d'évènements
grace à PostEvent.
````Les évènements TaskMaster possibles:
wInDesk évènement souris dans le bureau, hors de toute
fenêtre
wInMenuBar
wInSpecial évènement souris dans la barre de menu avec
relachement au dessus d'un item menu autre que NDA
wInContent évènement souris dans la région Contenu d'une
fenêtre
wInDrag évènement souris dans la région Drag d'une fenêtre
wInGrow évènement souris dans la case Grow d'une fenêtre
wInGoAway évènement souris dans la case de fermeture d'une
fenêtre
wInZoom évènement souris dans la case Zoom d'une fenêtre
wInInfo évènement souris dans la barre d'information d'une
fenêtre
wInFrame évènement souris dans le corps d'une fenêtre
wInactMenu sélection d'un item menu inactif
wClosedNDA fermeture d'un NDA
wCalledSysEdit appel de System Edit
wTrackZoom évènement souris dans la case Zoom d'une fenêtre,
mais la souris n'a pas été relachée dans la case
wHitFrame évènement souris dans le corps de la fenêtre
active
wInControl évènement souris dans une fenêtre et à l'intérieur
d'un controle
```STRUCTURE D'UN PROGRAMME
Le code source d'un programme peut, bien sur, être organisé en
fonction des désirs du programmeur. Cependant, les applications
Desktop doivent respecter certaines contraintes. En effet, toute
application Desktop doit commencer par initialiser ses outils, puis
les variables globales, créer les menus et fenêtres, gérer les
évènements et finalement fermer les outils avant de quitter
l'application.
Voici un extrait du programme SKELETON.p faisant appel aux
resources. Dans ce cas, la fonction StartupTools fais référence à la
resource StartStop définissant les outils utilisés par l'application.
Voir le chapitre 4 pour plus d'informations sur les resources.
gMyMemoryID := MMStartUp;
gStartStopRef :=
StartupTools(gMyMemoryID,
refIsResource,
ref(kStartStopRefID));
if _ToolErr = NoError then begin
InitializeGlobals;
SetUpMenus;
SetUpWindows;
InitCursor;
MainEventLoop;
end;
ShutDownTools(refIsHandle,gStartStopRef);
````Ajout de resources:
Comme on le voit dans l'exemple ci-dessus, les programmes TML
peuvent utiliser les resources définies à l'aide de l'éditeur
approprié (voir chapitre 4). Lors de la compilation du programme, les
resources doievent être copiées à la suite de l'application GS/OS. Le
linker se charge de cette besogne en copiant le fichier resource
spécifié dans le menu Add Resources, dans l'application compilée.
````Procédures définies (DefProcs)
Souvent, les routines de la boite à outils de l'Apple II GS
doivent appeler une procédure qui fait partie de votre application.
Ces types de procédures et parfois de fonctions se sont vues donner le
nom de Procédures définies en abrégé DefProcs. La raison de ce nom
vient de ce que ces routines sont générallement utilisées pour
permettre à l'application de produire une définition courante pour la
génération de quelques opérations. Par exemple, il y a les procédures
de définition de menu qui permettent à une application de fournir des
procedures de tracés pour représenter des menus, peut-être un menu
qui contiendrait une palette de couleurs à la place des rubriques
habituelles. Comme vous pouviez vous y attendre, la boite à outils
permet aussi les procédures définies de fenêtres, controles, listes,
etc...
Un autre composant de la boite à outils o| une application doit
utiliser une procédure définie est la routine outil 'NewWindow' du
gestionnaire de fenêtre. La routine 'NewWindow' n'a qu'un paramêtre
d'enregistrement qui est : 'NewWindowParamBlk'. Cet enregistrement
défini toute l'information dont a besoin le gestionnaire de fenêtre
pour tracer et entretenir la nouvelle fenêtre. Trois des champs de
l'enregistrement nécessitent des procédures définies. L'enregistrement
Pascal suivant montre les champs de l'enregistrement
'NewWindowParamBlk' qui exigent des procédures définies.
NewWindowParamBlk =
record
...
wFrameDefProc : ProcPtr;
wInfoDefProc : ProcPtr;
wContDefProc : ProcPtr;
...
end;
La routine wContDefProc, par exemple, est appelée par le
gestionnaire de fenêtre si jamais il détecte que l'affichage du
contenu de la fenêtre doit être mis à jour du fait qu'une partie de la
fenêtre, qui était précédemment cachée, devient visible.
Lorsqu'on utilise également NewWindow2, il y a lieu de faire
appel à des procédures définies puisque l'un des paramêtres de la
fonction s'appelle WINDOW'S CONTENT DEFINITION PROCEDURE.
La routine Content defProc est appelée par le Window Manager
lorsqu'il détermine que le contenu d'une fenêtre doit être mis à jour
(redessiné) du fait de la visibilité d'une région de la fenêtre
préalablement masquée.
Comme vous pouviez le deviner, les conventions d'appel de
procédure de la boite à outils pour une procédure définie ne sont pas
les mèmes que pour les procédures Pascal normales. Par conséquent, il
est nécessaire pour une application de signaler au compilateur du
Pascal TML qu'une procédure particulière est en fait une procédure
définie et qu'il doit utiliser les conventions d'appel des routines de
la boite à outils. Pour accomplir ceci, l'instruction de compilation
suivante est utilisée : $DefProc. L'instruction doit apparaitre
immédiatement avant chacune des procédures qui sont des procédures
définies.
Il y a une observation qui doit encore être faite concernant les
procédures définies : l'adressage des variables globales. Typiquement,
les variables globales sont adressées en utilisant le mode d'adressage
absolu du 65816 plutot que le mode d'adressage absolu long moins
efficace car le Pascal TML s'assure que le registre de la banque de
données pointe sur la banque de mémoire contenant les variables
globales du programme. Cependant, dans le cas de procédures définies,
la convention du Pascal TML peut ne pas obéir à une routine
particulière de la boite à outils (par exemple la routine de la boite
à outil a changé la valeur du registre de la banque de données). Aussi
il est nécessaire de forcer le Pascal TML à utiliser le mode
d'adressage absolu long pour les variables globales dans une procédure
définie pour s'assurer qu'elles sont correctement référencées.
exemple:
(*$DefProc*)
PROCEDURE WindowContentDraw;
BEGIN
....
END.
````Les grands programmes et la segmentation
L'Apple II GS limite la dimension du code d'un programme et des
segments de données à 64 Ko. Les segments de code contiennent le code
de l'application, tandis que le segment de données contient l'espace
nécessaire aux variables globales de l'application. La raison de cette
restriction est qu'un segment ne doit pas franchir la limite d'une
banque de mémoire. Sur l'Apple II GS, une banque de mémoire est de
64ko. Aussi, pour développer des applications ayant plus de 64 Ko de
code ou de données, le programme doit-il être segmenté. Normallement,
Le Pascal TML crée un segment code et un segment données pour une
application. Pour obtenir plus d'un segment, les instructions de
compilation $CSeg et $DSeg doivent être utilisées.
`````Segmentation du code:
Les segments de code sont baptisés pour que l'éditeur de liens
puisse organiser les différentes parties du code ensemble en se basant
sur leur nom de segment. Le nom de segment code par défaut est MAIN.
Pour changer le nom du segment code en cours, l'instruction de
compilation du Pascal TML (*$CSeg segname *) est utilisée. Quand cette
instruction apparait dans un programme ou dans un module, le code de
toutes les procedures et fonctions qui suivent est placé dans le
nouveau segment code. Pour ramener le code de la segmentation au
segment par défaut mettez l'instruction (*$CSeg Main *) dans votre
programme.
Pour plus de détails concernant l'emploi de l'instruction de
compilation (*$CSeg segname*) voir annexes B et C du manuel de
référence.
`````Segmentation des données:
Les segments de données sont baptisés comme les segments de code
pour que l'éditeur de liens puisse organiser les données ensembles en
se basant sur leur nom. Le nom de segment de données par défaut est
-global. Pour changer le nom on utilise l'instruction de compilation
(*$DSeg segname*). A moins qu'un programme ait absolument besoin d'une
grande place de mémoire pour ses variables globales l'instruction de
compilation précitée ne devrait pas être utilisée car l'accés est
moins efficace.
Voir les annexes B et C du manuel de référence pour plus de détails
sur (*$Dseg segname*).
``CHAPITRE 9: LES NDA
Les accessoires de bureau NDA sont des 'mini-applications' qui
peuvent tourner à l'intérieur des applications Apple II GS. Il y a
actuellement deux sortes d'accessoires de bureau : le type
d'accessoires de bureau classique et les nouveaux accessoires de
bureau.
Les accessoires du nouveau bureau (NDA) sont destinés à
s'exécuter en environnement bureau et gestion d'évènements. Un NDA
tourne dans une fenêtre et prend le controle quand cette fenêtre est
la plus frontale du bureau. Les accessoires du nouveau bureau sont
rendus disponibles, par les applications qui travaillent avec, par
l'intermédiaire du menu Pomme. Le Pascal TML fournit les outils pour
compléter les nouveaux accessoires de bureau en Pascal et c'est
l'objet de ce chapitre.
```DEMARRONS
Puisque les NDA opèrent en environnement bureau vous devez vous
assurer que les outils suivants ont bien été chargés et initialisés :
QuickDraw
Event Manager
Window Manager
Menu Manager
Control Manager
Scrap Manager
LineEdit
Dialog Manager
D'autres outils peuvent aussi être disponibles, mais vous ne
pouvez pas savoir s'ils ont été chargés et initialisés. Si un nouvel
accessoire de bureau a besoin d'autres outils il doit en assurer le
chargement et l'initialisation lui-mème.
```LE FICHIER SOURCE
Le code source d'un nouvel accessoire de bureau est tout à fait
différent de celui d'un programme normal. En particulier, un NDA n'a
pas de partie principale mais contient par contre quatre procédures
particulières:
DAOpen, DAClose, DAAction et DAInit.
En plus de ces quatres procédures nécessaires, trois élèments
d'informations supplémentaires sont exigés : la périodicité, le masque
d'événement et son nom de menu. Ces informations sont précisées en
Pascal TML avec l'instruction de compilation $DeskAcc.
(*$NDA period eventmask menuName *)
La périodicité précise la fréquence d'appel du NDA par DARun pour
rendre le NDA fonctionnel. Une période de 1 représente 1/60 ème de
seconde, une période de 2 représente 1/30 ème de seconde, etc. . ..
Une période de $FFFF est jamais. Si un NDA affiche l'heure alors il
faut une période de 60 pour faire une mise à jour par seconde.
Le masque d'évènement précise quels évènements sont manipulés
par l'accessoire de bureau. Ces valeurs sont un sous-ensemble de
celles là qui sont utilisées par les applications de l'Apple II GS qui
utilise GetNextEvent ou TaskMaster et qui sont listées ci-dessous en
faisant référence au module Events.p. Des 6 listés ci-dessous, la mise
à jour et l'activation des évènements sont toujours transmis à
l'accessoire de bureau sans s'occuper du masque d'évènement,
cependant, les quatre types d'évènements restant doivent être précisés
explicitement. Si tous les évènements doivent être manipulés par
l'accessoire de bureau alors un masque d'évènement de -1 (ou $FFFF)
doit être précisé.
CONST MDownMask = 2;
MUpMask = 4;
KeyDownMask = 8;
AutoKeyMask = 32;
UpdateMask = 64;
ActivMask =256;
EveryEvent = -1; (* $FFFF*)
Enfin, le nom de menu est le nom de l'accessoire qui devra
apparaitre dans le menu Pomme d'une application travaillant avec des
accessoires de bureau.
Comme nous l'avons dit plus haut, cette information est spécifiée
avec l'instruction de compilation $NDA. Cette instruction doit être la
première ligne du programme avant mème le mot PROGRAM. Par exemple,
l'instruction suivante spécifie une période de 1 seconde et que tous
les évènements seront manipulés par l'accessoire de bureau et que le
nom de menu de cet accessoire est "Horloge".
(*$NDA 60 -1 Horloge *)
Les accessoires de bureau fonctionnent différemment des
applications normales en ce qui concerne l'adressage des variables
globales. Le Pascal TML alloue l'emplacement mémoire nécessaire aux
variables globales dans un segment de données. Un segment de données
est chargé en mémoire tout comme le code d'un accessoire de bureau est
chargé en mémoire. Cependant le registre banque de données du 65816
n'est pas pret pour pointer sur la banque de mémoire qui contient le
segment de données des variables globales de notre accessoire de
bureau. Comme le compilateur ne peut être s|r de l'endroit o| les
variables globales seront rangées, il doit toujours utiliser le mode
d'adressage absolu long du 65816 pour faire référence aux variables
globales. Comme ce n'est pas le cas habituel pour les programmes en
Pascal TML, il faut le préciser au compilateur avec l'instruction
$LongGlobals+
A présent nous en arrivons à la structure de base d'un nouvel
accessoire de bureau écrit en Pascal TML.
(*$NDA 60 -1 Horloge *)
UNIT MonHorlogeNDA;
FUNCTION DAOpen:WindowPtr;
PROCEDURE DAClose;
PROCEDURE DAAction(Code: Integer; Param: LongInt);
PROCEDURE DAInit(Code: Integer);
IMPLEMENTATION
FUNCTION DAOpen: windowPtr;
BEGIN
(* code pour DAOpen *)
END;
PROCEDURE DAClose;
BEGIN
(* code pour DAClose *)
END;
PROCEDURE DAAction(Code:integer; Param: Longint);
BEGIN
(* code pour DAAction *)
END;
PROCEDURE DAInit(Code:integer);
BEGIN
(* code pour DAInit *)
END;
END.
````La procédure DAInit
La procédure DAInit est appelée quand les routines DeskStartUp et
DeskShutDown de l'outil Desk Manager sont appelées par l'application
pour initialiser ou fermer tous les accessoires du nouveau bureau. La
valeur du paramêtre code indique dans quelles circonstances la routine
a été appelée. Si le code=0 DAInit a été appelée pour une fermeture
sinon pour une ouverture. Dans tous les cas, cette routine devra
contenir le code nécessaire à l'initialisation et à la fermeture de
l'accessoire de bureau.
PROCEDURE DAInit(code:integer);
(* la variable myWindOpen est globale *)
BEGIN
if code=0 then begin
(* demande de fermeture, vérifier que la fenêtre DA est fermée *)
end
else begin
(* initialisation *)
myWindOpen:=false
end
END;
La plupart des NDA sont ouvert en mème temps qu'une fenêtre est
affichée 'fenêtre de l'application en cours). Le NDA doit vérifier si
la fenêtre est ouverte ou non. La meilleure façon de procéder consiste
à employer une variable globale windOpen qui sera VRAIE lorsque la
fenêtre est ouvert et FAUSSE autrment. Ainsi, lorsque DAInit est
appelé lors du DeskStartUp, il devra mettre la variable globale
windOpen à FAUX.
Il est possible que DAInit soit appellée pour se fermer à cause
d'un DeskShutDown, alors que sa fenêtre est encore ouverte. Ceci peut
se produire si un utilisateur quitte une applicatrion avec un NDA
encore ouvert sur le bureau. Il est impératif que la procédure DAInit
vérifie que la fenêtre est fermée avant de permettre la fin.
````La fonction DAOpen
Cette fonction est appelée comme le résultat d'une application en
appelant la routine OpenNDA de l'outil Desk Manager. Cette routine
doit vérifier si l'accessoire de bureau a déja été ouvert et si oui
sort sans rien faire. Sinon, la fonction devra créer la fenêtre de
l'accessoire de bureau, lui faire un système de fenêtre et renvoyer le
pointeur de fenêtre à la fenêtre crée comme un résultat de fonction.
Voici une partie de code qui montre la structure de base de
DAOpen.
FUNCTION DAOpen: windowPtr;
(* les variables myWindOpen, myWindPtr, et myWind sont globales *)
BEGIN
if myWindOpen then SelectWindow(mywindPtr)
else begin
myWindOpen:=true;
myWindPtr := NewWindow2(...);
SetSysWindow(myWindPtr);
end;
DAOpen:=myWindPtr;
END;
````La procédure DAClose
La procédure DAClose devra fermer l'accessoire de bureau si
celui-ci est ouvert. Il doit aussi travailler sans créer de situation
d'erreur s'il est appelé alors que l'accessoire de bureau n'est pas
ouvert.
PROCEDURE DAClose
(* les variables myWindPtr et myWindOpen sont globales *)
BEGIN
if myWindOpen then begin
CloseWindow(myWindPtr);
myWindOpen:=false;
end;
END;
````La procédure DAAction
La procédure DAAction est la routine qui fait tout le travail
associé à l'accessoire de bureau depuis l'ouverture de celui-ci et
jusqu'à sa fermeture. La procédure DAAction a deux paramêtres : un
code qui indique quel genre d'action faire et un paramêtre param dont
la signification dépend en fait du paramêtre code. Il y a neuf valeurs
possibles pour le code, chacune devant pouvoir être reconnue de la
procédure DAAction. Ces actions sont énumérées dans la table suivante
avec la signification du paramêtre param dans chaque cas.
ACTION DESCRIPTION
DAEvent Un évènement relevant de l'accessoire de bureau s'est
produit, param pointe sur l'enregistrement le
décrivant.
DARun La durée de la période précisée a expirée. Param non
significatif
DACursor Ce code est transmis à l'accessoire de bureau, si
celui-ci est sur le devant de l'écran, chaque fois que
SystemTask est appelé. Le but est de permettre à
l'accessoire de bureau de changer le curseur quand il
est sur la fenêtre du NDA. Param non significatif
DAMenu Ceci est transmis à un accessoire de bureau si une
rubrique d'un menu est sélectionnée. LoWrd(param) est
l'identifiant du menu et HiWrd(param) est l'identifiant
de la rubrique.
DAUndo Chacun des 5 codes suivants sont transmis à un
DACut accessoire de bureau si l'application détermine que
DACopy l'utilisateur a sélectionné l'une de ces commandes
DAPaste d'édition dans le menu Edition. La pro-
DAClear cédure DAAction attribuera la valeur 1 au paramêtre
code si l'action a eu lieu, sinon la valeur 0 sera
attribuée.
La partie de code suivant montre la structure de base de DAAction
PROCEDURE DAAction(Code : integer; Param: Longint);
(* la variable myWindPtr est globale *)
VAR currPort: GrafPtr;
BEGIN
case code of
DAEvent:begin
case EventRecordPtr(param)".what of éle " est un accent circonflexeè
mousedownEvt:;
mousUpEvt: ;
keyDownEvt: ;
autoKeyEvt: ;
updateEvt: ;
activateEvt: ;
end;
end;
DARun: begin
currPort := GetPort;
SetPort(myWindPtr);
SetPort(currPort);
end;
DACursor: begin
(* code pour m.a.j. du curseur *)
end;
DAMenu : begin
(* code pour répondre à une sélection dans un menu *)
end;
DAUndo : begin
(* code pour produire un 'annuler' pour le DA *)
code := 1;
end;
DACut : begin
(* code pour un 'couper' pour le DA *)
code := 1;
end;
DACopy : begin
(* code pour un 'copier' pour le DA *)
code := 1;
end;
DAPaste : begin
(* code pour un 'coller' pour le DA *)
code := 1;
end;
DAClear: begin
(* code pour un 'effacer' pour le DA *)
code := 1;
end;
end;
END;
```LA COMPILATION D'UN NDA:
Lors de la mise au point du NDA, la compilation en mémoire permet
d'installer le NDA artificiellement dans le menu Pomme et de tester
son fonctionnement. Lorsque le NDA est au point, procédez à une
compilation sur disque.
A présent que vous avez créé avec succés un accessoire de bureau
il doit être convenablement installé dans le répertoire
SYSTEM/DESK.ACCS/ de la disquette d'amorçage pour que les applications
puissent y accéder. L'installation d'un nouvel accessoire de bureau se
fait selon les trois étapes décrites ci-dessous :
(1) Les nouveaux accessoires de bureau sont des programmes (fichiers
à charger pour GS/OS) ayant pour type de fichier $B8.
(2) L'outil Desk Manager de l'Apple II GS exige que tous les
accessoires de bureau soient placés dans le répertoire
SYSTEM/DESK.ACCS/. Par conséquent il est nécessaire de copier le
fichier à charger de l'accessoire de bureau dans le répertoire.
(3) Enfin l'Apple II GS doit être redémarré. Pendant ce redémarrage
le répertoire SYSTEM/DESK.ACCS/ est exploré pour voir les
accessoires actuellement installés. Comme cette exploration ne se
fait qu'une fois lors du démarrage il faut donc redémarrer pour
que notre nouvel accessoire soit reconnu.
``CHAPITRE 10: LES CDA
Les accessoires de bureau CDA sont des 'mini-applications' qui
peuvent tourner à l'intérieur des applications Apple II GS. Les
accessoires classiques de bureau (CDA) sont destinés à s'exécuter en
environnement non-bureau et sans gestion d'évènements. Un CDA s'active
à partir du Control Panel (Pomme-Ctrl-Esc).
```STRUCTURE DU PROGRAMME
La structure d'un CDA est assez proche d'une application Texte
normale, excepté qu'il n'y a pas de programme MAIN et qu'il y a deux
routines spéciales: starUpCDA et ShutDownCDA appelées directement par
le DeskManager en temps opportun.
De plus, le source doit commencer par la directive $CDA qui
indique au compilateur que le source implémente un CDA. A la suite de
la directive, on place le nom du CDA tel qu'il apparaitra dans le menu
Ctrl-Panel.
(*$CDA menuName*)
Cette directive doit se situer AVANT le mot réservé UNIT.
Voici la strucutre complète d'un CDA:
(*$CDA SHRDump*)
UNIT MySHRDump;
INTERFACE
PROCEDURE StartUpCDA;
PROCEDURE ShutDownCDA;
IMPLEMENTATION
PROCEDURE StratUpCDA;
BEGIN
(* code pour la routine *)
END;
PROCEDURE ShutDownCDA;
BEGIN
(* code pour la routine *)
END;
END.
````La procédure StartUpCDA:
Cette procédure n'a aucun paramêtre et n'a aucune tache
spécifique à accomplir. Le DeskManager appelle cette procédure lorsque
le nom du CDA est sélectionné dans le menu Ctrl-Panel. Au contraire
des NDA, les CDA ne génèrent pas d'évènements, aussi c'est à vous de
gérer entièrement votre CDA.
````La fonction ShutDownCDA:
Cette procédure n'a aucun paramêtre et n'a aucune tache
spécifique à accomplir. Le DeskManager appelle cette procédure lorsque
DeskShutDown est invoqué par une application ou si on passe de P8 à
GS/OS.
Cette fonction permet de conclure les évènements mis en route par
la procédure StartUpCDA; mais comme en principe les CDA se quittent
pour revenir dans une application, vous n'aurez pas à appeler cette
fonction.
```COMPILER UN CDA:
Lors de la mise au point du CDA, la compilation sur disque permet
de compiler CDA. Au contraire de sNDA, on ne peut le compiler en
mémoire pour le tester.
A présent que vous avez créé avec succés un accessoire de bureau
il doit être convenablement installé dans le répertoire
SYSTEM/DESK.ACCS/ de la disquette d'amorçage pour que les applications
puissent y accéder. L'installation d'un accessoire de bureau classique
se fait selon les trois étapes décrites ci-dessous :
(1) Les ccessoires de bureau classiques sont des programmes (fichiers
à charger pour GS/OS) ayant pour type de fichier $B9.
(2) L'outil Desk Manager de l'Apple II GS exige que tous les
accessoires de bureau soient placés dans le répertoire
SYSTEM/DESK.ACCS/. Par conséquent il est nécessaire de copier le
fichier à charger de l'accessoire de bureau dans le répertoire.
(3) Enfin l'Apple II GS doit être redémarré. Pendant ce redémarrage
le répertoire SYSTEM/DESK.ACCS/ est exploré pour voir les
accessoires actuellement installés. Comme cette exploration ne se
fait qu'une fois lors du démarrage il faut donc redémarrer pour
que notre accessoire soit reconnu.
``CHAPITRE 11: MOTS RESERVES
```ELEMENTS DE BASE
Les éléments de base que nous allons voir se classent en
"symboles spéciaux", "identifiants", "instructions", "nombres non
signés", "étiquettes" et "chaines de caractères". En dehors des
chaines de caractères la représentation de n'importe quelle lettre
(majuscule, miniature, police, etc...) n'est pas significative pour le
programme.
Le texte d'un programme Pascal est constitué d'éléments de base
et de séparateurs, lequel est soit un blanc (caractère espace ou
tabulation) ou un commentaire. Deux éléments de base adjacents doivent
être séparés par un ou plusieurs séparateurs si chacun des éléments
est un identifiant, un nombre ou un mot-symbole.
```SYMBOLES SPECIAUX:
Les symboles spéciaux sont des éléments qui ont une signification
particulière et qui sont utilisés pour délimiter les modules
syntaxique du langage.
Les caractères simples suivants sont des symboles spéciaux:
+ - * / = < > . , ( ) : ; ! à [ ] é è
!- accent circonflexe
Les paires de caractères suivantes sont des symboles spéciaux:
<> <= >= := .. (* *)
Les mots-symboles suivants (mots réservés) sont des symboles spéciaux:
and array begin body
case const div do
downto else end file
for function goto if
implementation in interface label
mod nil not of
or otherwise packed procedure
program record repeat set
string then to type
unit until uses var
while with
```LES IDENTIFIANTS:
Les identifiants servent à repérer les constantes, types,
variables, procédures, fonctions, programmes, modules et champs dans
les enregistrements. Un identifiant peut être de n'importe quelle
longueur s'il tient sur une seule ligne, cependant, seuls les 255
premiers caractères sont significatifs. Majuscules et minuscules sont
équivalants dans les identifiants. Aucun identifiant ne peut prendre
le nom d'un mot réservé.
identifiant !
! !
! ! ! !
! !
!----! SOULIGNE !-! ! !
!
! !
!
! !
! !
! !
!
!
Exemples d'identifiants standards du Pascal TML:
Exit Maxint Writeln _DataInit A_very_long_identifiant
```LES DIRECTIVES:
Les directives sont des identifiants qui ont une signification
particulière dans le contexte d'une déclaration de procédure ou de
fonction. Ils peuvent sinon être utilisés comme identifiants dans tous
les autres contextes. Ce sont :
EXTERNAL FORWARD INLINE TOOL
(voir chapitre 17)
```LES NOMBRES:
Les entiers non-signés en décimal ou hexadécimal (en héxadécimal
le caractère $ est utilisé en préfixe) la notation représente des
constantes de type de données "entier" ou "entier long". Les réels
non-signés en notation décimale représentent les constantes des
données de type étendue. La lettre "E" ou "e" précédant un facteur
représente la puissance de dix.
suite de chiffres
!
!
suite de chiffres Hex
!
!
signe
!
!
!---! - !--!
Nombre non signé
!
!
!----! $ !-->! séquence de chiffres Hex !
Réel non signé
-->! séquence de chiffres !-->! . !-->! séquence de chiffres !
!
!facteur !
!d'échelle!
!-->! inf !---->
!
Nombre de type Réel !
! ! !
!
!---->! signe !---! ! !-! séquence !--! !
!
! !
!
!->! séquence !
! ! chiffres ! !
!
! !
! !
!
Exemples de nombres :
1 +100 -0.1 $A05D 5.329E4 NaN(1) Inf
```LES LABELS:
Une étiquette est une suite de caractères dont la valeur est
celle de n'importe quel entier entre 0 et 9999. Mettre des zéros en
tète d'étiquette ne modifie pas sa signification. 1 et 0001 sont
équivalents. Les étiquettes sont utilisées avec l'instruction GOTO qui
sera décrite au chapitre 16.
```LES CHAINES DE CARACTERES:
Une chaine de caractères est une suite de zéro ou plusieurs
caractères d'impression, tous sur la mème ligne d'un programme et
encadrés d'apostrophes. Le nombre maximum de caractères dans une
chaine est de 255. Une chaine de caractères n'ayant pas de caractère
entre les apostrophes est appelée une chaine vide.
Une chaine de caractères représente une valeur de type chaine. En
tant que type chaine, une chaine de caractères n'est pas seulement
compatible avec d'autres types chaine mais aussi avec les types
caractère et chaine compactée.
Toutes les valeurs de type chaine ont un attribut longueur
"length". Dans le cas d'une chaine de caractères, la longueur est
fixée; elle est égale au nombre actuel de caractères de la chaine à
l'intérieur des apostrophes. Une paire d'apostrophes adjacents à
l'intérieur d'une chaine de caractères est considérée comme une simple
apostrophe et donc comptée comme un caractère simple dans la longueur
de la chaine.
Exemples de chaines caractères
'A' ';' 'Pascal' 'Ceci est une chaine' 'L''image' '''' ''
```DECLARATIONS DE CONSTANTES:
Une déclaration de constante définie un identifiant pour
représenter une constante à l'intérieur du bloc qui contient la
déclaration.
déclaration de constante
!
!
constante
!
! ! ! !
! ! !
! !-! SIGNE !
! !
! !
! !
!-> ! NOMBRE SIGNE !
! !
! !
! !
!-> ! CHAINE CARACTERES !
!
Un nombre signé peut être un entier ou un réel.
```COMMENTAIRES ET DIRECTIVES DE COMPILATION:
les constructions:
( n'importe quel texte ne contenant pas de e accent grave )
(* texte sans le couple astérisque et parenthése fermante *)
sont appelées commentaires.
Le remplacement d'un blanc par un commentaire ou un commentaire
par un blanc ne modifie pas le sens d'un programme. Ceci étant, un
commentaire, comme un séparateur, peut apparaitre n'importe o| dans un
programme là ou un blanc peut apparaitre.
Les commentaires de la forme é...è peuvent être emboités avec les
commentaires de la forme (*...*), et vice versa, cependant aucun autre
emboitement de commentaire n'est disponible. L'arrivée d'un è dans un
commentaire é..è ou un *) dans un commentaire (*...*) termine toujours
le commentaire.
Une directive de compilation est un commentaire qui contient le
signe $ immédiatement aprés le é ou le (* qui commence le commentaire.
Le caractère $ est ensuite suivi par une ou plusieurs lettres qui
représente une instruction de compilation précise. Les directives de
compilation servent à modifier le comportement du compilateur. Chacune
des instructions de compilation et leur effets sont décrits en annexe
B.
Exemple d'instructions de compilation:
é$DefProcè é$LongGlobalstè (*StackSize 10240*)
``CHAPITRE 12: BLOCS, VISIBILITE ET ACTIVATION
```DEFINITION D'UN BLOC:
Le BLOC est le module de base d'un source Pascal. Il est
constitué d'une partie déclaration et d'une partie instruction. La
partie déclaration contient zéro, une ou plusieurs déclarations qui
peuvent apparaitrent dans n'importe quel ordre. La partie instruction
est un arrangement d'instructions et elle suit la partie déclaration.
Chaque bloc est une partie d'une procédure, d'une fonction, d'un
programme ou d'un module (unit). Tous les identifiants et étiquettes
qui sont déclarés dans la partie déclaration d'un bloc sont dits
locaux. Le bloc programme contient tous les autres blocs; par
conséquent, les déclarations dans le bloc programme sont dites
globales.
Bloc
!
! ! !
! !
!--! DECLARATION !<-!
!
Déclaration
!
! !
! !
! !
!
! !
! !
! !
!
! !
! !
! !
!
! !
! !
! !
!
!
La partie déclaration d'étiquette déclare les étiquettes qui
marquent des instructions dans la partie instruction correspondante.
Chaque étiquette doit marquer exactement une instruction dans la
partie instruction.
! --- !
!
---
La partie déclaration de constantes contient les déclarations de
constantes locales à ce bloc. (voir "déclarations de constantes" au
chapitre 11).
! !
!
La partie déclaration de type contient les déclarations de type
locales à ce bloc. (voir chapitre 13)
! !
!
La partie déclaration de variables contient les déclarations de
variables locales à ce bloc. (voir chapitre 10)
! !
!
La partie déclaration des procédures et fonctions contient les
déclarations des procédures et fonctions locales à ce bloc.(voir
chapitre 17)
partie déclaration des procédures et fonctions
!
! ! !
! ! ! !
! ! !
! !
! !
!
```REGLES DE VISIBILITE:
````Visibilité d'une déclaration:
L'apparition d'un identifiant ou d'une étiquette dans une
déclaration définie l'identifiant ou l'étiquette, ceci étant,
l'identifiant ou l'étiquette est associé à sa signification au point
de déclaration. Toutes les autres occurences de cet identifiant ou
étiquette doivent apparaitre dans la "visibilité" de cette
déclaration. La "visibilité" d'une déclaration est le bloc qui
contient la déclaration et tous les blocs qui lui sont inclus avec les
exceptions décrites dans les paragraphes suivants.
````Redéclaration dans un bloc inclus:
Supposons que EXTERIEUR soit un bloc et que INTERIEUR soit un
autre bloc déclaré à l'intérieur de EXTERIEUR. Si un identifiant
déclaré dans le bloc EXTERIEUR a le mème nom qu'un identifiant déclaré
dans le bloc INTERIEUR, alors le bloc INTERIEUR et tous ses blocs
inclus sont exclus de la visibilité de la déclaration du bloc
EXTERIEUR.
````Position des déclarations dans un bloc:
La déclaration d'un identifiant ou d'une étiquette doit précéder
les occurences de cet identifiant ou étiquette dans le texte du
programme. C'est à dire que les identifiants et étiquettes ne peuvent
pas être utilisés tant qu'ils ne sont pas déclarés. Il y a une
exception à cette règle: dans une déclaration de type, le type de
domaine d'un type pointeur peut être un identifiant qui n'a pas encore
été déclaré. Dans ce cas, l'identifiant doit être déclaré quelque part
dans la mème déclaration que le type pointeur.
````Redéclaration à l'intérieur d'un bloc:
Un identifiant ou étiquette ne peuvent être déclaré plus d'une
fois dans un bloc, à moins qu'il ne soit déclaré à l'intérieur d'un
bloc inclus ou encore s'il apparait dans la liste des champs d'une
déclaration d'enregistrement.
Un identifiant de champs d'enregistrement est déclaré dans un
type record (enregistrement). Il n'a de signification qu'en référence
à une variable de ce type enregistrement. Par conséquent, un
identifiant de champs peut être déclaré à l'intérieur d'un mème bloc
contenant un autre identifiant de mème nom dans la mesure o| il n'a
pas été précédemment déclaré dans la mème liste de champs. Un
identifiant qui a été déclaré peut être réutilisé comme identifiant de
champs dans un mème bloc.
````Identifiants d'objets standards:
Le Pascal TML fourni un ensemble de constantes standards
(prédéclarées), de types, procédures et fonctions qui se conduisent
comme s'ils avaient été déclarés dans un bloc qui contiendrait le
programme entier. Leurs visibilités est le programme entier ou le
module (voir chapitre 9 et 10, o| vous trouverez chacun des
identifiants standards du Pascal TML).
````Visibilité des interfaces modules et identifiants de modules:
Les programmes, Modules, spécifications de module, et corps de
module contenant une clause USES se voient enrichis des identifiants
appartenant à chacun des modules de la clause USES. Ces identifiants
agissent comme s'ils avaient été déclarés dans le mème bloc o| est
apparue la clause USES.
```ACTIVATIONS:
L'éxécution d'un bloc fait dire de lui qu'il est en activation. A
un moment donné, un bloc peut avoir zéro, une ou plusieurs
activations. Si un bloc n'est pas en train de s'éxécuter il a alors
zéro activation. Si un bloc est en train de s'éxécuter il a au moins
une activation. Quand un bloc a plus d'une activation on dit qu'il est
récursif.
``CHAPITRE 13: LES TYPES DES VARIABLES
Quand vous déclarez une variable vous devez indiquez son type. Le
type d'une variable détermine l'ensemble des valeurs que la variable
peut prendre et les opérations qui peuvent lui être appliquées. Une
déclaration de type introduit un identifiant pour repérer un type.
!
!
type
!
! !
! !
! !
!
! !
! !
! !
!
! !
! !
! !
!
! !
! !
! !
!
!
Quand un identifiant apparait à la gauche d'une déclaration de
type, il est déclaré comme un identifiant de type pour le bloc dans
lequel la déclaration de type a lieu. La visibilité d'un identifiant
de type ne s'inclus pas d'elle mème, excepté pour les types pointeurs.
```Les TYPES simples:
Tous les types simples définissent un ensemble ordonné de
valeurs.
type simple
!
! !
! !
! !
!
!
Un identifiant de type entier est un des identifiants standards
Integer ou LongInt. Un identifiant de type réel est un des
identifiants standards Real, Single, Double, Comp ou Extended. Voir
"Nombres" dans le chapitre 1 1ou comment repérer des constantes
entières et les valeurs de type réel.
````Les TYPES ordinaux
Les types ordinaux sont un sous-ensemble des types simples qui
ont les caractéristiques particulières suivantes :
- les valeurs possibles d'un type ordinal sont un ensemble ordonné et
chacune des valeurs a un numéro d'ordre qui est une valeur entière.
A l'exception des types entiers, la première valeur de tous les
types ordinaux est zéro, la suivante a 1, etc.... Pour les types
entiers, le numéro d'ordre d'une valeur est la valeur elle-mème.
Toutes les valeurs d'un type ordinal, à l'exception de la première,
ont un prédécesseur basé sur le numéro d'ordre du type, et toutes
les valeurs d'un type ordinal, à l'exception de la dernière, ont un
successeur basé sur le numéro d'ordre du type.
- les fonctions standard ORD et ORD4 peuvent être appliquées à
n'importe quelle valeur de type ordinal et elles renvoient le numéro
d'ordre de la valeur.
- la fonction standard PRED peut être appliquée à n'importe quelle
valeur de type ordinal et elle renvoie le numéro d'ordre de la
valeur.
- la fonction standard SUCC peut être appliquée à n'importe quelle
valeur de type ordinal et elle renvoie le numéro d'ordre de la
valeur.
type nombre ordinal
!
! !
! !
! !
!
! !
! !
! !
!
!
Le pascal TML a quatre types ordinaux prédéfinis: Integer,
LongInt, Boolean, et Char. De plus il y a deux classes pour la
définition de types ordinaux par l'utilisateur: les types Enumérés et
les types Intervals.
````Les TYPES ordinaux standards:
Integer les valeurs du type entier sont un sous-ensemble de tous les
nombres. Une variable de type entier peut avoir une valeur
comprise dans l'interval -maxint-1 . . maxint, c'est à dire
-32768 à 32767. La constante standard entière maxint est
définie à 32767.
Longint les valeurs du type entier long sont aussi un sous-ensemble
de tous les nombres. Une variable de type entier long peut
avoir une valeur comprise dans l'interval -maxlongint-1 . .
maxlongint. La constante standard maxlongint est définie à 2
147 483 647.
Les opérations arithmétiques avec des opérandes de type
entier utilisent une précision entière (16 bits) ou entier
long (32 bits) selon les règles suivantes :
- les constantes entières dans l'interval du type entier sont
considérées de type entier. Les autres constantes entières
sont considérées de type entier long.
- si opérateur et opérande sont de type entier le résultat sera
de type entier (éventuellement tronqué à 16 bits). De mème si
les deux opérandes sont de type longint la précision sur 32
bits sera utilisée et le résultat sera de type longint.
- Quand un opérande est de type longint et l'autre de type
entier, l'opérande de type entier est d'abord converti en
entier long et le résultat est de type entier long.
- l'expression située du coté droit d'une instruction
d'attribution est évaluée indépendamment de la partie gauche.
Une valeur entière peut être explicitement convertie en
entier long en utilisant la fonction stantard ORD4 décrite au
chapitre 20.
Boolean Les valeurs du type booléen sont précisées par les
identifiants de constantes prédéfinies FALSE et TRUE, o|
ord(false)=0 et ord(true)=1. Les valeurs de type booléen sont
sollicitées par les instructions pascal IF, REPEAT et WHILE.
Char Le type caractère a un ensemble de valeurs qui est celui des
caractères ASCII. L'appel de la fonction ord(ch), o| ch est
une valeur caractère, retourne le numéro d'ordre de ch. Une
constante chaine de longueur 1 peut être utilisée pour
préciser la valeur d'une constante de type caractère,
n'importe quelle valeur de type caractère peut être générée
par l'intermédiaire de la fonction CHR.
````TYPES énumérés:
Un type énuméré défini un ensemble ordonné de valeurs par
l'énumération de la collection des identifiants qui repèrent ces
valeurs. L'ordre de ces valeurs est déterminé par la suite dans
laquelle les identifiants sont listés. Par conséquent pour deux
identifiants énumérés x et y, si x précède y alors le numéro d'ordre
de x est inférieur à celui de y.
type énuméré
--- !
--- !
Quand un identifiant apparait à l'intérieur d'une liste
d'identifiants d'un type énuméré, il est déclaré comme constante pour
le bloc dans lequel le type énuméré est déclaré. Le type de cette
constante est le type énuméré dans lequel il est déclaré. Le numéro
d'ordre d'une constante énumérée est sa position dans la liste des
identifiants sachant que le numéro d'ordre de la première constante
énumérée est toujours 0.
Exemples de types énumérés:
jour_ouvrable = (lundi,mardi,mercredi,jeudi,vendredi)
couleur = (rouge,jaune,vert,bleue)
Ici jaune est une constante énumérée de type couleur avec numéro
d'ordre 1, vendredi est une constante énumérée de type jour_ouvrable
avec numéro d'ordre 4, et ainsi de suite... et on a donc:
ORD(lundi) < ORD(mardi)
ORD(jeudi) > ORD(mardi)
PRED(vert) = jaune
SUCC(rouge)= jaune
````TYPES intervals:
Un type interval défini un sous-ensemble de valeurs d'un type
ordinal appelé le type hote. La définition d'un type interval spécifie
la valeur la plus petite et la plus grande de l'interval.
type interval
!
!
Les deux constantes d'un type interval doivent être du mème type
ordinal. Les types intervals de la forme a . . b exigent que a soit
inférieur ou égal à b. Une variable de type interval possède toutes
les propriétés des variables de type hote, avec la restriction que sa
valeur doit toujours être l'une de celle de l'interval défini par le
type interval.
Exemples de types intervals:
1 . . 100
-128 . . 127
lundi . . jeudi
````Les TYPES réels
Les types réels ont des ensembles de valeurs qui sont des
sous-ensembles des nombres réels, lesquels peuvent être représentés en
notation virgule flottante en utilisant un nombre de digits déterminé.
En général, une notation virgule flottante d'une valeur n comprend un
ensemble de trois valeurs m, b et e tel que m * (b à la puissance e)=n
, o| b est toujours 2 et m et e sont des valeurs entières dans
l'interval des réels. Ces valeurs m et e détermineront par la suite
l'interval et la précision des types réels.
Il y a quatre types réels standards en Pascal TML: single,
double, comp et extended. De plus l'identifiant standard real est
définie comme étant équivalent au type extended. Les types réels se
différencient par leur interval et la précision des valeurs qu'ils
représentent.
Les types réels:
Identifiant de type Occup. mémoire Interval
Single 4 octets 1.4E-45 à 3.4E38
Double 8 octets 5.0E-324 à 1.7E308
Real, Extended 10 octets 1.9E-4951 à 1.1E4932
Comp 8 octets -9.2E18 à 9.2E18
Les valeurs possibles des réels sont:
- des valeurs finies (un sous-ensemble des nombres réels). La
valeur 0 a un signe associé (elle peut être négative ou
positive)
- des valeurs infinies, +INF et -INF résultant de dépassement de
capacité ou d'une division par zéro.
- NaN (Not a Number) représente le résultat d'une opération
n'ayant pas de représentation mathématique (multiplier +- par 0
par exemple). NaN est représenté par NaN(x) o| x est un Integer
définissant la source de NaN.
Les réels sont implémentés dans TML II par l'outil SANE. Les
opérations sur les réels sont également possibles par l'emploi de
l'interface SANE.P.
Toutes les valeurs de type real sont converties en "extended"
avant qu'une opération n'agisse sur elles, et le résultat de ces
opérations et toujours de type étendue. Une valeur étendue peut
toujours être utilisée là o| une valeur "single, double ou comp" est
demandée, à condition que la valeur tombe dans l'interval
correspondant.
Toutes les valeurs de type réel sont converties en type étendue
par le compilateur avant que les calculs ne soient éffectués afin
d'obtenir une précision maximum. En conséquence, les calculs sur des
données stockées selon le type étendue fourniront plus rapidement un
code plus compact que les calculs sur des données stockées dans
d'autres représentations. Les plus petites représentations devront
être utilisées quand l'espace de stockage des données est plus
critique que la vitesse d'exécution.
```LES TYPES STRUCTURES:
Un type structuré est caractérisé par sa structure et par le(s)
type(s) de ses composants. Le type d'un composant pouvant être
lui-mème structuré. Il n'y a pas de limite inhérente au nombre de
niveaux dans la structure.
type structuré
!
! ! ! !
!
!->! COMPACTE !--! ! !
!
! ! !
! ! !
! ! !
! !---> ! TYPE FICHIER !
! ! !
! ! !
! ! !
! !---> ! TYPE ENREGISTREMENT !
! !
! !
!
!
L'utilisation du mot PACKED dans la déclaration d'un type
structuré indique que l'organisation du stockage de toutes les valeurs
de ce type sera la compression pour économiser de la mémoire, mème si
l'accés à un composant d'une variable de ce type est moins efficace.
Notez que vous ne pouvez pas utiliser de composants de variables
compactées comme variable actuelles paramétrant des procédures ou
fonctions. Le compactage ne se fait qu'au niveau de l'octet, pas au
niveau des bits. Voir également l'appendix D.
````TYPES Tableaux:
Un type tableau définie un type structuré qui a un nombre de
composants déterminés et qui sont tous du mème type.
type tableau
-->! ARRAY !-->! ( !-->! INDEX DE TYPE !-->! ) !-->! OF !-->! TYPE !->
! !
! --- !
!
---
index de type
!
!
Le type qui suit le mot OF est le type des composants du tableau.
Le nombre des éléments est déterminé par un ou plusieurs types index,
un par dimension du tableau. Le type index doit être un type ordinal.
Il n'y a pas de limite au nombre de dimensions d'un tableau. Cependant
le pascal TML limite le tableau à 32 767 octets.
Un tableau de la forme
packed array(1 . . n) of char
est considéré comme un type chaine compacté. Un type chaine compacté a
certaines propriétés que ne partagent pas d'autres types de tableaux
(voir les types identiques et compatibles plus loin dans ce chapitre)
Exemples de types tableaux:
array(1 . . 100) of real
packed array (color) of boolean
array (Boolean) of integer
array(low..high) of boolean
Si le type du composant d'un tableau est également un tableau, le
type résultant est soit un tableau de tableaux soit un tableau
multi-dimentionné. Par exemple:
array(boolean) of array(0..maxsize) of real
est équivalent à
array(boolean, 0..maxsize) of real
Le composant d'un tableau peut être récupéré par l'emploi des
index du composant à l'intérieur des crochets immédiatement après
l'identifiant du tableau. On peut utiliser plusieurs ensembles de
crochets. Par exemple:
var anArray: array(1..maxlength,1..maxwidth) of real
permet l'emploi de
anAray(1,1) ou anArray(1)(1) pour accéder au premier
élément du premier sous-tableau.
Remarquez que anArray(2) accède à la totalité du
deuxième sous-tableau.
````Les TYPES "Enregistrement"
Un type enregistrement est constitué d'une collection déterminée
de composants appelés champs, chacun d'eux pouvant être de type
différent. Pour chaque composant le type enregistrement précise le
type du champs et le nom de son identifiant.
type enregistrement
liste de champs
!
! !
!
----> ! PARTIE FIXE ! --> ! ; ! --> ! PARTIE VARIABLE ! -- ! ; ! -->
! !
! ! ! !
!
partie fixe
!
! !
! --- !
!
---
déclaration de champs
!
!
La partie fixe d'un type enregistrement donne la liste des champs
qui sont toujours accessible par une variable de type enregistrement
en donnant un identifiant et un type pour chaque champs. Chacun de ces
champs contient des données qui sont toujours accessibles de la mème
manière.
Exemple de type enregistrement:
record
année : integer;
mois : 1 . . 12;
jour : 1 . . 31;
end
Une partie variable constituée de listes de champs "alternative"
qui se voient allouer le mème espace mémoire qu'une variable
enregistrement, ainsi les données situées dans cet emplacement seront
accessibles de diverses manières. Chacune des listes est appelée une
variante. Les variantes se remplacent en mémoire et tous les champs de
toutes les variantes sont accessibles à tout moment.
partie variante
!
! !
--->! CASE !--->! IDENTIFIANT !-->! : !-->! ETIQ DU CHAMP TYPE !---!
!
!
!
! ---- !
!--->! OF !---->! VARIANTE !
--- ! !
! !
! --- !
!
---
variante
!
---> ! CONSTANTE !--> ! : !---> ! ( !--> ! LIST CHAMPS !--> ! ) !-->
!
étiquette de champs type
!
!
Chaque variante est introduite par une ou plusieurs constantes.
Les constantes doivent être distinctes et être d'un type ordinal qui
soit compatible avec l'étiquette champ du type. La partie variante
permet un identifiant optionel qui annonce une étiquette de champs. Si
une étiquette champs est présente, elle est considérée comme un champs
de la précédente partie fixe.
Exemple de type enregistrement avec variantes:
record
nom, prénom : string(80);
age : 0 . . 99;
case married: boolean of
true : (nom_de_jeune_fille:string(80));
false:()
end
record
x,y:real;
case sorte: figure of
rectangle:(hauteur,largeur:real);
triangle: (coté1,coté2,angle:real);
cercle : (rayon:real);
end
````Les TYPES Ensembles:
Un type ensemble a une gamme de valeurs qui peut atteindre celle
d'un type ordinal appelé alors type de base. Chacune des valeurs
possibles d'un type ensemble est un sous-ensemble des valeurs
possibles du type de base.
type ensemble
Le pascal TML limite le type de base à 256 valeurs possibles. Si
le type de base est un sous-ensemble d'entier il doit se limiter à
0 .. 255. Pour plus d'informations concernant l'allocation mémoire et
la représentation des données voir l'annexe C.
Chaque type ensemble peut avoir la valeur () appelée ensemble
vide.
Exemples d'ensembles:
Set of Char
Set of 0..31
set of (rouge, vert, bleu)
````TYPES Fichier:
Un type fichier est un type structuré comportant une suite
linéaire de composants d'un mème type. Le type du composant peut être
de n'importe quel type qui ne soit pas un type fichier ou un type
structuré contenant un composant de type fichier. Le nombre de
composants n'est pas précisé par la déclaration de type fichier.
type fichier
Le type fichier standard "text" est un fichier compacté
particulier de caractères, organisé en lignes. Les fichiers de type
texte sont manipulés par des procédures d'entrées/sorties
particulières expliquées au chapitre 19.
A cause de la représentation des types en TML Pascal, un fichier
de caractères accède aux éléments de fichier qui sont des mots de 16
bits tandis que dans un fichier compacté de caractères (ou texte) on
accède à des éléments de 8 bits. Pour plus de détail voir l'annexe D.
Exemples de types fichiers:
IntFile = file of integer
Le TML ne permet le passage de variables files dans les
procedures ou fonctions que si elles sont des paramêtres.
```TYPES CHAINE:
Une valeur d'un type chaine est une suite de caractères ayant un
attribut longueur dynamique et un attribut 'constante' de dimension de
1 à 255. La constante de dimension est une limite maximum sur la
longueur des valeurs de ce type. Si un attribut de dimension n'est pas
explicité celui-ci aura par défaut la valeur 255.
La valeur courante de l'attribut longueur d'une valeur de type
chaine est retournée par la fonction standard 'length'. Une chaine
vide est une valeur de type chaine ayant une longueur dynamique de
zéro.
type chaine
!
! ! !
! !
! !
! !
!
!
dimension
!
!
La relation d'ordre entre deux valeurs de chaine est déterminée
par la comparaison des caractères dans les positions correspondantes.
Quand les deux chaines sont de longueurs inégales, chaque caractère de
la chaine la plus longue ne peuvent correspondre à un caractère de la
plus courte et à caractères communs égaux la plus longue sera
considérée de plus haute valeur. Ainsi 'attribut' est plus grand que
'at'. Deux chaines doivent donc avoir la mème longueur pour pouvoir
être égales.
Une chaine est stockée sous la forme un octet de longueur suivi
des caractères de la chaine. On peut modifier la longueur d'une chaine
en modifiant directment son prmier octet:
aString(0) := chr(5);
Les opérateurs applicables aux chaines sont étudiés au chapitre
15; et les procédures et fonctions standard de manipulation de chaines
sont décrites au chapitre 20.
exemples:
string(50)
string(255)
string
```TYPES POINTEUR:
Un type pointeur défini un ensemble de valeurs qui pointent sur
des variables dynamiques d'un type spécial appelé type de base. Une
variable de type pointeur contient l'adresse en mémoire d'une variable
dynamique.
type pointeur
--- !
--- !
(attention cette * est un accent circonflexe )
Si le type de base est un identifiant non déclaré, il doit être
déclaré dans la mème partie de déclaration de type que le type
pointeur.
Vous pouvez affecter une valeur à une variable pointeur avec la
procédure 'NEW', l'opérateur 'à' ou la fonction 'POINTER'. La
procédure 'NEW' alloue une nouvelle zone de mémoire sur la pile pour
la variable dynamique et range l'adresse de cet espace mémoire dans la
valeur du pointeur. L'opérateur 'à' dirige la variable pointeur sur la
zone mémoire contenant des variables. La fonction 'POINTER' pointe la
variable pointeur sur une adresse mémoire particulière.
L'identifiant de constante prédéclarée 'NIL' représente une
valeur pointeur constante qui est une valeur possible pour chacun des
types pointeur. Par conception, nil est un pointeur qui ne pointe sur
rien.
Exemples de types pointeurs:
* LongInt
* Char
* String(32)
(attention: les * sont des accents circonflexes)
```TYPES IDENTIQUES ET TYPES COMPATIBLES:
Deux types peuvent être ou ne pas être "identiques". Dans
certains contextes il est nécessaire qu'ils soient identiques.
D'autres fois mème s'ils ne sont pas identiques il peut être
nécessaire qu'ils soient compatibles et d'autres fois encore
l'assignation de compatibilité est demandée.
````TYPE identiques:
Les types identiques sont nécessaires dans les contextes
suivants:
- entre les paramêtres de la variable formelle et actuelle
- entre les types des résultats formel et actuel des paramêtres de
fonction
- entre les valeurs et variables paramêtres formelles et actuelles
dans les listes de paramêtres de fonctions ou procédures.
- lorsqu'un tableau PACKED ARRAY OF CHAR unidimensionné est comparé
avec un autre à l'aide d'un opérateur.
Deux types, t1 et t2 sont identiques si l'une des propositions est
vraie :
- t1 et t2 sont le mème identifiant de type
- t1 est déclaré comme étant équivalent à un type identique à t2
````TYPES compatibles:
L'assignation de compatibilité est exigée quand une valeur est
affectée à quelquechose, soit explicitement (comme dans une
instruction d'assignation) soit implicitement (comme le passage de
paramêtres de valeurs).
Une valeur de type t2 est assignée compatible avec un type t1 si
l'une des propositions suivantes est vraie :
- t1 et t2 sont de types identiques et ils ne sont ni de type fichier
ni de type structuré qui contiendrait un élément de type fichier.
- t1 est un type réel et t2 est un type entier
- t1 et t2 sont de types ordinal et la valeur de t2 est dans la gamme
des valeurs possibles de t1
- t1 et t2 sont compatibles de type ensemble et tous les éléments des
valeurs de type t2 sont dans la gamme des valeurs possibles du type
de base de t1
- t1 est un type chaine ou un type caractère et t2 est un type chaine
ou une constante caractère entre apostrophes.
- t1 est un type chaine compactée de n éléments et la valeur de type
t2 est un type chaine d'une constante caractère entre apostrophes
ayant une longueur de n.
Il y a erreur si l'assignation de compatibilité est exigée et
qu'aucune des propositions ci-dessus n'est vraie.
``CHAPITRE 14: LES VARIABLES
```DECLARATION DES VARIABLES:
Une déclaration de variable est utilisée pour allouer et associer
un emplacement de mémoire avec un type particulier. Une variable est
une entité dans la quelle une valeur est rangée. Chaque identifiant de
la liste d'identifiants d'une déclaration de variable montre que
chaque variable a le type précisé dans la déclaration.
déclaration de variables
!
--> ! LISTE D'IDENTIFIANTS ! ----> ! : ! ---> ! TYPE ! ---> ! ; ! --->
!
La présence d'un identifiant à l'intérieur de la liste des
identifiants d'une déclaration de variables annonce qu'il y a un
identifiant de variable pour le bloc dans lequel la déclaration
apparait. On peut donc faire référence à la variable tout au long du
bloc à moins que l'identifiant ne soit redéclaré dans un sous-bloc. La
redéclaration crée une nouvelle variable utilisant le mème identifiant
sans affecter la valeur de la variable originale.
Exemples de déclaration de variables:
x,y,z: real;
c: couleur;
p1,p2: personne;
aujourdhui: date;
operateur: (plus,moins);
digit: 0..9;
coord: polaire;
fait,errer: boolean;
```REFERENCES AUX VARIABLES:
La référence à une variable se rapporte soit à une variable
complète, un composant d'un type structuré ou d'une chaine, une
variable dynamique pointant par une variable de type pointeur, soit à
une variable que l'on atteint par un appel à une fonction.
référence à une variable
! !
! ! ! !
! !
!---> ! APPEL A FONCTION ! ---! !--- ! QUALIFIANT ! <---!
!
````LES QUALIFIANTS:
La référence à une variable est composée d'un identifiant de
variable suivi de zéro, un ou plusieurs éléments qui modifient le sens
de la variable ainsi référencée.
qualifiant
!
! !
! !
! !
!
! !
! !
! --- !
!
---
(attention: cette * est un accent circonflexe)
Par exemple avec:
var aMultiDimArray: array(1..100) of array(1..100) of integer
on peut écrire:
aMultDimArray accéder à tout le tableau
aMultDimArray(1) accéder au premier sous-tableau
aMultDimArray(1,1) accéder au premier élément du prmier
sous-tableau
````Tableaux, chaines et index:
Un composant déterminé d'une variable tableau est noté par une
référence à une variable de type tableau suivi d'une élément
d'indexation qui précise l'élément concerné. Un caractère particulier
dans une variable chaine est spécifié par la référence à la variable
suivi d'un index qui précise la position du caractère.
index
--- !
--- ! !
! !
! --- !
!
---
Exemples de tableaux indexés :
m(i,j)
a(i+j)
Chaque expression dans l'index sélecte un élément dans le tableau
de la dimension correspondante. Le nombre d'expressions ne doit pas
dépasser le nombre de types indexés dans la déclaration de tableau.
L'expression d'index doit être d'assignation compatible avec le type
index correspondant.
Quand on indexe un tableau multidimensionnel, multi-indexé ou
avec des expressions multiples on peut faire l'interchangeabilité. Par
exemple:
MaMatrice (i)(j) à la mème sens que MaMatrice (i,j)
Une variable chaine peut être indexée avec une expression simple,
dont la valeur doit se situer dans la gamme 0..n, o| n est la
dimension déclarée de la chaine. Indexer une chaine permet l'accès à
un caractère de la chane. Le premier caractère d'une variable chaine
(index 0) contient la longueur dynamique de la chaine.
En général, on ne peut assigner une valeur à une position d'un
caractère seul dans une chaine à moins que le caractère occupait cette
place auparavant. C'est à dire si la longueur dynamique de la chaine
est inférieure à la position du caractère manipulé, l'opération
laissera la chaine inchangée.
Voir aussi chapitre 20.
````Enregistrements et désignateurs de champs:
Un champ déterminé d'une variable enregistrement est précisé par
une référence à la variable enregistrement suivi par un désignateur de
champs qui spécifie celui-ci.
désignateur de champs
--- !
--- !
Exemples de désignateurs de champs
today.year
p2*.pregnant (attention: cet * est un accent circonflexe)
C'est une erreur d'accéder à un composant variant d'un
enregistrment non actif. Voir le chapitre 13.
Dans une instruction située dans une instruction WITH un
désignateur de champs n'a pas a être précédé par la référence à la
variable enregistrement qui le contient.
````Pointeurs et variables dynamiques:
La valeur d'une variable pointeur est soit nil soit une valeur
qui pointe vers une variable dynamique.
La variable dynamique pointée par la variable pointeur est
référencée en écrivant la variable pointeur immédiatement suivi de
l'accent circonflexe.
Les variables dynamiques et les valeurs des pointeurs qui
pointent dessus sont créées par la procédure standard NEW. De plus
l'opérateur 'aroba' (à) et la procédure standard POINTER peuvent être
utilisés pour créer des valeurs de pointeurs qui en fait ne pointent
pas sur des variables dynamiques mais qui sont traités comme tel.
La constante nil ne pointe sur aucune variable. Il y a erreur si
vous accédez à une variable dynamique quand la valeur du pointeur est
nil ou indéfinie.
Exemples de références à des variables dynamiques :
p1*
p1*.sibling*
(attention: les * sont des accents circonflexes)
````Modification du type d'une variable 'variable type casts':
La référence à une variable d'un type donné peut être changée en
une référence à une variable d'un autre type grace à un mécanisme
appelé en anglais 'variable type casts'
variable de type casts
!
-->! IDENTIFIANT DE TYPE !->! ( !->! VARIABLE REFERENCE !--->! ) !-->
!
Quand une modification de type est appliquée à la référence à une
variable, celle-ci est traitée provisoirement comme étant du type
spécifié par l'identifiant de type. La dimension de la variable (c'est
à dire le nombre d'octets qu'elle occupe en mémoire) doit être le mème
que la dimension du type représenté par l'identifiant de type. Une
variable de type cast peut être suivie par un ou plusieurs qualifiants
comme pour la référence à une variable classique.
Exemples de variable type casts:
type point=record
v,h:integer;
end;
var p:point;
l:longint;
begin
p:=point(l);
l:=longint(p);
longint(p):=longint(p)+$00020002;
end;
``CHAPITRE 15: LES EXPRESSIONS
Les expressions indiquent des valeurs. L'expression la plus
simple est par exemple la référence à une variable, cependant la
plupart des expressions sont composées d'opérateurs et d'opérandes. La
plupart des opérateurs pascal sont binaires, ceci étant ils ont alors
deux opérandes. Les autres opérateurs sont unaire et n'ont qu'un seul
opérande. Quand plus d'un opérateur apparait dans une expression, les
règles de priorité sont appliquées pour déterminer quels opérandes
sont associés avec quels opérateurs. Par exemple, l'expression :
a + b * c
peut être interprétée soit comme (a+b)*c soit comme a + (b*c). Les
règles de priorité lèvent l'ambiguité de l'interprétation:
* quand un opérande apparait entre deux opérateurs de priorité
différente, il est associé à l'opérateur ayant la plus grande
priorité.
* quand un opérande est écrit entre deux opérateurs de mème priorité
il est associé à l'opérateur de gauche.
* une expression entre parenthèses est toujours évaluée avant de lui
appliquer un opérateur.
Priorité des opérateurs:
Opérateurs unaires à , not
opérateurs multiplicateurs *, /, div, mod, and
opérateurs d'addition +, -, or
opérateurs de relation =, <>, <, >, <=, >=, in
Ainsi, l'expression a+b*c est interprétée comme a+(b*c) car * a
une plus grande priorité que +. Notez que a+b-c est interprété comme
(a+b)-c car + et - ont la mème priorité.
Les règles de priorité suivent la syntaxe des expressions, qui
sont construitent à partir de facteurs, termes et expressions simples.
La syntaxe d'une expression est réalisée à partir d'opérateurs de
relation appliqués aux expressions simples :
expression
! !
! ! ! ! ! ! ! !
V V V V V V V !
= < > <= >= <> in !
! ! ! ! ! ! !
exemple d'expressions:
x=1.5
c in teinte1
fait <>error
p<=q
La syntaxe d'une expression simple est le résultat d'un ajout
d'opérateurs et de signes appliqués à des termes:
expression simple
! ! !
!
!---->! signe !---! ! ----! ----!
!
!
exemples d'expressions simples:
x+y
-x
teinte1 + teinte2
b or c
La syntaxe d'un terme est faite de l'utilisation des opérateurs
de multiplication appliqués à des facteurs:
terme
!
! -V- -V- -V-- --V-- --V-- --V--
! !*! !/! !**! !div! !mod! !and!
! --- --- ----
!
exemples de termes:
x*y
e/(1-e)
fait and error
La syntaxe d'un facteur est le résultat des constructions
suivantes:
facteur
! !
! !->! à !
!
!
!
!
!->! constante non signée !
!
!->! appel de fonction !
!
!->! construction d'ensemble !
!
!->! ( !-->! expression !
!
!->!not !---->! facteur !
Une constante non signée a la syntaxe suivante :
constante non signée
!
!
!
!
!
!
exemple de facteurs:
x (référence à variable)
àx (pointeur vers une variable)
15 (constante non signée)
'Bonjour' (constante non signée)
(x+y+z) (sous-expression)
sin (x/2) (appel à fonction)
not q (négation d'un booléen)
('A'..'F','a'..'f') (construction d'ensemble)
```LES OPERATEURS:
Les opérateurs sont classés en opérateurs arithmétiques,
opérateurs booléens, opérateurs d'ensembles, opérateurs de relation et
l'opérateur 'à'.
````Les opérateurs arithmétiques
Les deux tableaux suivants montrent les types des opérandes et
des résultats avec des opérateurs respectivement binaires et unaires.
Opérations arithmétiques binaires (sur deux éléments)
opérateur opération type de l'opérande type du résultat
+ addition entier ou réel idem (entier ou réel) (1)
- soustraction " " " "
* multiplication " " " "
/ division " " réel (2)
div division entière entier entier
mod modulo entier entier
(1) si mélange entier et réel l'opérande entier est converti en réel
et le résultat est de type réel.
(2) les opérandes entiers sont toujours convertis en réels mème si les
deux opérandes sont de type entier.
Opérations arithmétiques unaires
Opérateur opération type de l'opérande type du résultat
+ identité entier ou réel idem (entier ou réel)
- signe de négation entier ou réel idem (entier ou réel)
Si deux opérandes des opérateurs +,-,*,div, ou mod sont du mème
type d'entier (integer ou longint) les résultats sont toujours du mème
type d'entier. Si l'un des opérandes est de type longint et l'autre de
type entier alors l'opérande entier est d'abord converti en longint et
le résultat est de type longint. Dans les autres cas la valeur du
résultat est déterminée par les règles normales des mathématiques sur
les entiers. Il y a erreur si la valeur du résultat sort de la plage
-maxint-1..maxint pour les entiers et de la plage
-maxlongint-1..maxlongint pour les entiers longs.
Si l'un des opérandes des opérateurs +,-, ou * est d'un type
réel, le résultat est toujours de type étendue et a une valeur qui est
une approximation du résultat mathématique normal. Le résultat de
l'opération avec l'opérateur / est toujours de type étendue.
Si l'opérande de l'identité ou de négation est de type entier, le
résultat est toujours du mème type d'entier et la valeur absolue du
résultat est toujours identique à la valeur absolue de l'opérande.
Si l'opérande de l'identité ou de négation est de type réel, le
résultat est toujours de type réel et la valeur absolue du résultat
est toujours identique à la valeur absolue de l'opérande.
````Opérateurs Booléens:
Les types des opérandes et des résultats pour les opérations
booléennes sont montrés dans la table suivante :
Opérateur opération type de l'opérande type du résultat
or disjonction booléen booléen
and intersection " "
not négation " "
Le résultat d'une opération booléenne est déterminée par les
règles de l'algèbre de Boole, par exemple a and b est évalué vraie si
et seulement si a et b sont vraies.
````Opérateurs sur les ensembles
Les types des opérandes et des résultats figurent dans le tableau
suivant:
Opérateur Opération type de l'opérande type du résultat
+ union type ensemble compatible Si types des opérandes
- différence " " identiques alors mème
* intersection " " que opérandes sinon
Les résultats des opérations sur ensembles sont déterminés par
les règles normales sur les ensembles.
* une valeur ordinale c est dans l'ensemble a+b si et seulement si c
est en a ou en b.
* une valeur ordinale c est dans l'ensemble a-b si et seulement si c
est en a et non en b.
* une valeur ordinale c est dans l'ensemble a*b si et seulement si c
est en a et en b.
````Opérateurs de relation
Les types des opérandes et des résultats des opérations de relation
sont montrés dans le tableau suivant:
Opérateur Type de l'opérande type du résultat
= <> compatible simple, pointeur, booléen
ensemble, chaines ou chaines
compactées
< > compatible simple, chaines booléen
ou chaines compactées
<= => compatible simple, ensemble, booléen
chaine ou chaine compactée
in op de gauche:ordinal T booléen
op de droite:ensemble de T
````Comparaison entre types ordinaux
Quand les opérandes des opérateurs =, <>, <, >, >= ou <= sont
de type ordinal ils doivent être de types compatibles à moins que l'un
des opérandes ne soit de type réel l'autre étant alors considéré comme
étant de type entier. Le résultat est la relation mathématique des
ordinaux. Quand on compare des types réels, les résultats peuvent être
différents de ce l'on attend car la représentation d'une valeur réelle
est seulement une approximation.
````Comparaison entre chaines
Quand les opérateurs relationnels =, <>, <, >, <=, et >= sont
utilisés pour comparer des chaines, celles-ci sont comparées selon
leur ordre lexicographique. Notez que n'importe qu'elle paire de
chaines peuvent faire l'objet d'une comparaison car toutes les valeurs
des chaines sont compatibles. De plus une valeur char est compatible
avec une valeur de type chaine et quand on fait la comparaison la
valeur de type char est traitée comme une chaine de longueur égale à
1. Quand une valeur de type chaine compactée qui a n éléments est
comparée avec une valeur de type chaine, elle est traitée comme une
valeur de type chaine qui aurait une longueur égale à n.
````Comparaison entre chaines compactées
Les opérateurs de relation =, <>,<,>,<= et >= peuvent aussi être
utilisés pour comparer deux valeurs de type chaine compactée si toutes
les deux ont le mème nombre d'éléments. Si ce nombre est n alors le
résultat est le mème que si les deux chaines étaient de type chaine et
de longueur n. Voir aussi le chapitre 13 sur les Packed Array of Char.
````Comparaison d'ensembles
Si a et b sont des opérandes d'ensemble alors :
* a=b est vrai si et seulement si chaque membre de a est membre de b
et chque membre de b est membre de a, sinon a<>b.
* a<=b est vrai si et seulement si chaque membre de a est aussi membre
de b.
* a>=b est vrai si et seulement si chaque membre de b est aussi membre
de a.
Ainsi a=b et a<>b indiquent respectivement l'équivalence ou la
non-équivalence des ensembles a et b, et a<=b et a>=b indiquent
respectivement l'inclusion de a dans b et l'inclusion de b dans a.
````Comparaisons de pointeurs
Les opérateurs de relation = et <> peuvent être appliqués à des
opérandes de type pointeur compatible. Deux pointeurs sont égaux si et
seulement s'ils indiquent le mème objet.
````Test d'appartenance à un ensemble
L'opérateur in retourne la valeur vraie si la valeur de
l'opérande de type ordinal est membre de l'opérande de type ensemble;
sinon il fournit la valeur false. Le type de l'opérateur de gauche
doit être compatible avec le type de base de l'opérateur de droite.
````L'opérateur aroba "à"
Une valeur pointeur qui pointe sur une variable, procédure ou
fonction peut-être créée avec l'opérateur aroba. L'opérande et les
types du résultat sont montrés dans le tableau qui suit.
à est un opérateur unaire qui prend la référence d'un identifiant
de variable, de procédure ou de fonction pour en faire son opérande et
calcul la valeur de son pointeur. Si l'opérande de l'opérateur aroba
est une référence à une variable, alors la valeur de pointeur est
l'adresse en mémoire o| la variable est rangée. Si l'opérande de
l'opérateur aroba est un identifiant de procédure ou de fonction alors
la valeur du pointeur est le point d'entrée de la procédure ou de la
fonction. Le type de la valeur est équivalent au type du pointeur
anonyme de la constante pointeur nil, par exemple il peut être
attribué à n'importe quelle variable pointeur.
Opérations avec les pointeur
Opérateur Opération Type de l'opérande Type du résultat
à création de pointeur référence à variable, type pointeur
identifiant de procé-
dure ou de fonction.
L'opérateur aroba devra être utilisé seulement avec des
procédures et fonctions déclarées dans la partie déclaration du
programme ou du module (déclarations globales) quand la valeur
résultante du pointeur est transmise à une routine de l'Apple II GS en
ROM. Les procédures et fonctions déclarées dans la partie déclaration
d'une autre procédure ou fonction (déclarations emboitées) ont une
convention d'appel différente qui n'est pas compatible avec les
routines ROM de l'Apple II GS. En outre l'option de compilation pascal
TML 'DefProc' devra être utilisée quand la valeur résultante du
pointeur est transmise à une routine ROM de l'Apple II GS. Voir
l'annexe "A l'intérieur du Pascal TML" pour des détails sur les
conventions d'appel Pascal et l'emploi de l'option de compilation
"DefProc".
`````à avec les Variables:
L'utilisation de l'opérateur 'à' avec des variables ordinaires
(pas des paramêtres) est évidente. Par exemple, si on a:
type twochar = packed array (0..1) of Char;
var int: integer;
twocharptr: *twochar;
(attention: cet * est un accent circonflexe)
alors on peut écrire:
twocharptr := àint
ceci va forcer TWOCHARPTR à pointer sur la variable INT. Puisque les
types Integer et Twochar ont le mème type de stockage, la valeur de
Int récupérée via Twocharptr, est ré-interprétée en type Twochar.
`````à et les Valeurs paramêtres:
Si 'à' s'applique à une valeur paramêtre formel, le résultat est
un pointeur sur l'adresse de la pile contenant la valeur actuelle. Si
aParam est une variable formelle dans une procédure, et que actParam
est la variable passée à la procédure comme étant la variable actuelle
aParam, et si aPtr est un pointeur; alors si on exécute:
aPtr := àaParam;
alors aPtr est un pointeur sur actParam dans la pile et aPtr* donne la
valeur de actParam. (attention: cette * est un accent circonflexe)
`````à avec une variable paramêtre:
Si 'à' s'applique à une variable paramêtre formel, le résultat
est un pointeur sur le paramêtre actuel. Dans ce cas, le pointeur est
pris à partir de la pile. Si aParam est une variable paramêtre formel
dans une procédure, et que actParam est une variable passée à la
procédure en tant que paramêtre aParam actuel, et si aPtr est un
pointeur; alors si on exécute:
aPtr := àaParam
alors aPtr est un pointeur sur actParam et aPtr* donne le contenu de
actParam. (attention: cette * est un accent circonflexe)
`````à avec une procédure ou une fonction:
Lorsque 'à' est employé avec une procédure ou une fonction, le
résultat sera un pointeur sur son point d'entée. Il n'y a aucune
possibilité d'utiliser cela avec le Pascal. Le seul emploi possible
d'un pointeur sur une procédure est de le passer à une procédure
ToolBox que la boite à outil utilise pour appeler la fonction désignée
par une instruction ASM de type JSL. Les pointeurs sur procédure
servent généralement à implémenter la définition de procédures et les
procédures de filtrage.
L'opérateur 'à' doit être uniquement employé avec des procédures
ou fonctions déclarées dans la partie déclarative du programme ou de
l'unit (déclarations globales) lorsque la valeur du pointeur résultant
est passée à une routine de la boite à outils. Les procédures et
fonctions déclarées dans une autyre procédure ou fonction
(déclarations imbriquées) on des conventions d'appel différentes les
rendant incompatibles avec les routines de la boite à outils.
```APPLE DE FONCTION:
Un appel à une fonction précise l'activation du bloc associé à
l'identifiant de la fonction. Le résultat renvoyé par l'activation de
la fonction est utilisé comme une valeur expression. Si la fonction a
des paramêtres formels alors le désignateur de fonction doit contenir
la liste correspondante des paramêtres actuels. A chaque paramêtre
actuel est substitué le paramêtre formel correspondant.
Exemples d'appels à des fonctions:
sum(a,63)
sin(x+y)
eof(f)
ord(f*) (attention: cet * est un accent circonflexe)
Voir le chapitre 17 pour la description des appels de procédures.
```LES CONSTRUCTIONS D'ENSEMBLE:
La création d'un ensemble précise une valeur d'un type ensemble
et elle est réalisée en écrivant des expressions encadrées par des
crochets rectangulaires. Chaque expressions précise une valeur de
l'ensemble.
S'il n'y a rien dans une paire de crochets rectangulaires
l'ensemble est vide, c'est une affectation compatible à tous les types
'ensemble'. Tout groupe d'éléments x..y signifie que toutes les
valeurs des éléments de l'ensemble sont situées dans la plage de x à y
bornes comprises. Si la valeur de x est plus grande que la valeur de y
alors x..y signifie aucun élément et (x..y) est un ensemble vide.
Toutes les valeurs d'une expression dans les éléments groupés
d'une création d'ensemble doivent être de type ordinal compatible. Si
a est la valeur ordinal la plus petite dans l'ensemble résultant, et
si b est la valeur ordinal la plus grande de l'ensemble résultant
alors le type de base de l'ensemble résultant est a..b
Exemples d'ensembles:
(rouge, c, vert)
(1, 5, 10..k MOD 12, 23)
('A'..'Z','a'..'z', CHR(13))
```VALEUR D'UN TYPE MODIFIE:
Le type d'une expression peut être changé en un autre type par
une valeur de type modifié.
L'argument de l'expression doit être d'un type ordinal ou de type
pointeur. Le résultat d'un type modifié est du type spécifié et sa
valeur ordinale est obtenue par la conversion de l'expression. La
syntaxe d'une valeur d'un type modifié est presque identique à celle
de la valeur de variable modifiée. Cependant les valeurs de type
modifié opèrent sur des valeurs et non sur des variables et ne peuvent
donc pas constituer des références à variables. Ceci étant, une valeur
de type modifié peut ne pas avoir de qualifiant dans la partie gauche
d'une déclaration d'affectation ou avoir un paramêtre actuel o| le
paramêtre formel est déclaré comme paramêtre VAR.
Exemples de valeurs de type modifié:
integer('c')
ptr($89F2)
boolean(0)
``CHAPITRE 16: LES INSTRUCTIONS
Les instructions décrivent les actions algorithmiques pouvant
être excutées. Il y a deux classes d'instructions: les instructions
simples et les instrucctions structurées. Les instructions peuvent
être préfixées par un label et les labels sont référencés par les
instructions GOTO.
instruction
!
!-->! label !->! : !-! !
Un label est une constante entière non négative, déclarée en
premier dans la déclaration des labels (voir chapitre 11).
label
```LES INSTRUCTIONS SIMPLES:
Une instruction simple est une instruction ne contenant aucune
autre instruction. L'instruction vide est une instruction simple ne
contenant aucun symbole et ne spécifiant aucune action.
instruction simple
!
!
!
!
!
!
instruction vide
````Instruction d'assignation:
L'instruction d'assignation permet d'effectuer une de ces deux
actions:
- remplacer la valeur courante d'une variable par une nouvelle
valeur spcifiée dans une expresion.
- spécifier une expresion dont la valeur sera retournée par une
fonction.
instruction d'assignation
!
---->! identifiant foncction !
Le symbole := peut se lire 'donner la valeur'. L'expression doit
être compatible, en terme d'assignation, avec le type de la variable
ou avec le type du résultat de la fonction. L'identifiant de la
fonction doit être celui de la fonction en cours.
La référence à la variable à gauche identifie une variable de
n'importe quel type sauf FILE. Avec la plupart des variables, la
référence à la variable est juste un nom d'identifiction, mais dans
certains cas la variable est suivie d'une qualification:
- chaine: le nom de la variable est suivi par un indexage entre
crochets.
- tabelau: la varibalee est identifiée par le nom du tableau
suivi par un index entre crochets pour chaque dimension du
tableau.
- champ d'enregistrement: le nom de la variable doit être précédé
parle nom de la structure et un point. La seule exception est
l'emploi de l'instruction dans une boucle WITH associée à
l'enregistremnt correspondant.
- variable dynamique: la référence à la variable est définie par
le nom de son pointeur suivi du *. (attention: cette * est un
accent circonflexe)
De plus, une référence à une variable située à gauche peut être
une définition de type. Voir le chapitre 13 pour plus d'informations
et la compatibilité des types et la syntaxe de ces variables.
Exemples d'assignations:
x := y+z
p := (1<=i) and (i<100)
i := sqr(k) - (i*j)
coul := ébleu, succ(c)è
Il n'est pas spécifié si l'évaluation de la référence à la
variable est effectuée avant ou après l'évaluation de l'expression.
Cependant, lorsque la référence à la variable est établie, elle n'est
pas altérée par les effets de débordement d|s à l'exécution du restant
de l'instruction d'assignation. Ainsi:
Aéiè := Une_Fonction(i);
est lié à la modification de i par la fonction, et si c'est le cas,
selon que la fonction est évaluée avant ou après Aéiè.
````Instruction Procédure:
Une instruction procédure définit un bloc spécifié par les
identifiants de procédure. Si la procédure à des paramêtres formels,
alors l'instruction de procédure doit contenir la liste correspondante
des paramêtres actuels. Chaque paramêtre actuel est remplacé par le
paramêtre formel correspondant dans la liste, lors de l'appel à la
procédure.
instruction procédure
+-->! liste param. acts. !-+
L'identifiant utilisé pour définir une procédure doit être
identique à celui utilisé dans la déclaration. Les paramêtres dans la
déclaration de fonction ou de procédure sont appelés 'paramêtres
formels'; ceux dans l'instruction d'appel sont appelés 'paramêtres
actuels'. Les valeurs dans la liste des paramêtres actuels seront
passées aux paramêtres formels lors de l'appel. Le nombre de
paramêtres dans la liste formelle doit être équivalent et compatible
avec les paramêtres actuels. Il y a 3 exceptions à cette compatibilit:
- les sous-types sont équivalents à leurs types de
base.
- un paramêtre formel de type LongInt accepte un
paramêtre actuel de type Integer.
- les paramêtres formels précédés par UNIV acceptent
tout paramêtre actuel occupant le mème espacement
mémoire. Voir le chapitre 19 au sujet de UNIV.
Les paramêtres actuels spécifiés dans un appel à une fonction ou
à une procédure doivent respecter les règles suivantes:
- les variables paramêtres actuels, à l'opposé des
valeurs paramêtres, doivent être des variables. Les
variables paramêtres actuels ne peuvent être des
constantes, expressions, éléments ou variables
compactées.
- la valeur d'une chaine variable paramêtre peut être
passée à toute chaine variable paramêtre, sans soucis
de la longueur des chaines.
- si la valeur d'un paramêtre actuel excède
l'intervalle de définition d'un paramêtre formel, un
erreur d'exécution se produit.
```LES INSTRUCTIONS STRUCTUREES:
Les instructions structurées sont constituées d'autres
instructions s'exécutant conditionnellement, répétitivement ou
séquentiellement.
````Les instructions à-la-suite:
Ce type d'instruction définit l'exécution d'une séquence
d'instructions, dans l'ordre de leur écriture.
instructions en séquence
--->! begin !
+
Le corps de toute procédure, fonction ou programme MAIN en Pascal
est une suite d'instructions. Une trelle séquence commence par BEGIN
et se conclut par END, chaque instruction élémentaire située entre ces
bornes se termine par ;. Les suites d'instructions peuvent être
imbriquées dans d'autres suites. Dans ce cas, chaque END est apparié
avec le BEGIN précédent le plus proche.
Exemple:
begin
z:= x;
x:= y;
y:= z;
end
````Les instructions conditionnelles:
Une telle instruction détermine si certains (ou aucun) de ses
constituants seront exécutés.
instruction conditionnelle
!
+
````L'instruction IF:
Cette instruction exécute une instruction (qui peut être une
séquence d'instructions) si une expression Boolenne est TRUE. Une
clause optionnelle ELSE peut être ajoutée afin de faire exécuter une
autre instrution au cas ou l'expression Booléenne serait FALSE.
L'instruction associée avec la clause ELSE, peut également être une
séquence d'instructions.
instruction IF
---->! IF !--->! expression !-->! THEN !-->! instruction !--+---+->
+
!
+--->! ELSE !-->! instruction !
L'expression entre IF et THEN est ordinairement constituée
d'opérateurs logiques et relationnels et son type doit être booléen.
On peut avoir des instructions IF imbriquées. Dans ce cas, chaque
ELSE est toujours associé avec le IF le plus proche non associé
lui-mème avec un autre ELSE.
Exemples:
if x < 1.5 then
z := x+y
else
z := 1.5
if p1 <> nil then
p1 := p1*.pere; (* est un accent circonflexe)
````Les instructions CASE:
Cette instruction est constituée d'une expression (le sélecteur)
et d'une liste d'instructions. Chaque instruction est préfixée par une
ou plusieurs constantes (les constantes CASE), ou par le mot réservé
OTHERWISE. Toutes les constantes case doivent être distinctes et
doivent être d'un type ordinal compatible avec le type de l'expression
sélectionnante.
instruction case
+
!
+-+->! CASE !--+--+
!
+----! ; !<--+ +-->! OTHERWISE !---+
case
---+->!expression!-+
! !constante ! ! ----
!
!
+
clause otherwise
L'instruction CASE exécute l'instruction préfixée par la
constante CASE égale à la valeur du sélecteur. Si aucune constante
CASE ne répond à ce critère, et que la clause OTHERWISE soit présente,
l'instruction suivant OTHERWISE est exécutée; si OTHERWISE n'est pas
présent, alors l'exécution se poursuit avec l'instruction suivant
l'instruction CASE.
Chaque instruction dans la clause CASE ou OTHERWISE peut être une
séquence d'instructions.
Exemples:
case operateur of
plus : x := x+y;
moins : x := x-y;
fois : x := x*y
end;
case i of
1 : x := sin(x);
2 : x := cos(x);
3,4,5 : x := exp(x);
otherwise x := ln(x);
end;
````Instruction de répétition:
Ceci indique qu'un groupe d'instructions doit être répété un
certain nombre de fois.
instruction de répétition
!
+
!
+
Si le nombre de répétitions est connu à priori, l'instruction FOR
est la plus appropriée; sinon REPEAT et WHILE sont employés.
````L'instruction REPEAT:
Cette instruction contient une expression controlant l'exécution
répétitive d'une séquence d'instructions contenues dans cette
instruction REPEAT.
instruction repeat
+
L'expression doit générer un résultat de type booléen. Les
instructions entre les symboles REPAT et UNTIL sont exécutées
répétitivement jusqu'à ce que l'expression contienne la valeur TRUE.
La séquence d'instructions est exécutée au moins une fois, car
l'expression est évaluée APRES l'exécution de la séquence.
REPEAT et UNTIL n'ont nul besoin de l'emploi de Begin et End pour
délimiter la séquence.
Exemples:
repeat
k := i mod j;
i := j;
j := k
until j=0
repeat
process(f*); (attention: * est un accent circonflexe)
read(f)
until eof(f)
````L'instruction WHILE:
L'instruction While comprend une expression controlant
l'exécution répétitive d'une instruction.
instruction while
L'expression doit générer un résultat de type booléen.
L'expression est évaluée AVANT chaque exécution de la boucle.
L'instruction est exécutée répétitivement tant que l'expression
contient la valeur TRUE. Si l'expression contient FALSE dès le départ,
l'instruction n'est pas exécutée.
L'instruction controlée par une instruction While peut être soit
une instruction simple, soit une séquence d'instructions.
Exemples:
while aéiè <> x do
i := i+1
while i>0 do begin
if oddéiè then
z := z*x;
i := i div 2;
x := x*x
end
Attention à ce que l'expression booléenne change bien de valeur
dans les instructions REPEAT et WHILE, autrement on bouclerait sans
fin. Sinon, on peut quitter la boucle par GOTO, EXIT ou LEAVE (voir
plus loin).
````L'instruction FOR:
Cette instruction provoque l'exécution répétitive d'une
instruction aussi longtemps qu'un index reste dans un intervalle
défini. Cet index progresse séquentiellement à chaque exécution de la
boucle.
instruction for
---->! FOR !-->! variable !-->! := !-->! expression !--+
+
!
+--+-->! to !----+->! expression !-->! do !-->! instruction !->
!
!
+->!downto !--+
La première expresion suivant le := est appelée VALEUR INITIALE.
La seconde expression après le := est appelée VALEUR FINALE. La
variable de controle, valeur initiale, et la valeur finale doivent
être compatibles. Voir le chapitre 13 au sujet de la compatibilité des
types.
La variable de controle est de type scalaire (Integer, Char,
boolean, subrange ou défini par l'utilisateur). Cependant, ce ne peut
être un tableau ou une chaine, un champ d'enregistrement ou une
variable dynamique. Cette variable de controle doit être déclarée dans
le bloc contenant l'instrucion FOR. Une nouvelle valeur lui est
assignée par l'instruction FOR avant chaque exécution de la boucle. La
valeur de la variable de controle est accessible dans l'instruction
gérée par FOR.
Si le mot réservé après la première expression est TO, la
variable de controle sera incrémentée avant chaque exécution de la
boucle. L'excution de l'instruction FOR se poursuit jusqu'à ce que la
variable de controle ait une valeur plus grande que la valeur finale
autorisée. Si le mot réservé après la premère expression est DOWNTO,
la variable est alors décrémentée avant chaque exécution de la boucle,
et l'exécution du procesus se poursuit jusqu'à ce que la variable ait
une valeur inférieure à la valeur finale autorise.
Voici quelques règles à respecter pour définir une instruction
FOR:
- la variable de controle doit être une variable simple déclarée
dans la zone locale.
- si la variable de controle est de type subrange ou un scalaire
définit par l'utilisateur, elle doit accepter toutes les
valeurs comprises entre la valeur initiale et la valeur
finales, bornes comprises.
- la variable de controle ne doit pas être modifée dans la boucle
gérée par l'instruction FOR.
- la variable de controle peut ne pas être inclue dans les
expressions définissant les valeurs finales ou initiales.
- la variable de controle peut ne pas être spécifiée à la fin de
l'instruction FOR.
- les valeurs initiales et finales ne sont évaluée qu'une fois,
avant l'exécution du premier passage. Ensuite, toute
modification de l'une ou l'autre des valeurs sera sans effet
sur le déroulement de la boucle.
- si les valeurs initiales et finales sont identiques, la boucle
n'est exécutée qu'une fois.
Exemples:
for i:= 2 to 63 do
if aéiè > max then
max := aéiè
for c := red to blue do check(c);
```INSTRUCTIONS DE CONTROLE:
Les instructions de répétition, conditionnelles, d'assignation
ainsi que les appels aux procédures ou fonctions servent à assurer la
plupart des taches en Pascal. Mais dans certains cas, on peut avoir
des situations demandant l'arrèt immédiat du programme. Dans ces cas,
TMLII dispose de certains outils:
- l'instruction GOTO pour passer le controle à une autre partie
du programme située dans le mème bloc.
- l'instruction CYCLE forçant le passage à la prochaine itération
d'une instruction de répétition.
- l'instruction LEAVE pour quitter la boucle d'une instruction de
répétition.
- l'instruction HALT pour stopper immédiatement l'exécution du
programme.
````L'instruction GOTO:
L'instruction GOTO passe le controle du programme à l'instruction
suivant le label.
instruction goto
Voici les règles à respecter pour employer cette instruction:
- le lable référencé par une instruction GOTO doit être dans le
mème bloc que l'instruction GOTO, ou dans un bloc contenant
l'instruction GOTO.
- le saut dans une instruction structurée à partir d'un endroit
extérieur à cette instruction va produire des effets non
prévisibles. Toutefois, TML Pascal ne détecte pas ce genre de
situation.
Voir aussi le chapitre 13.
````L'instruction CYCLE:
L'instruction CYCLE passe le controle du programme à la fin de
l'instruction gérée par le WHILE, REPEAT ou FOR. L'emploi de CYCLE
hors d'une boucle WHILE, REPEAT ou FOR génère une erreur.
Exemples:
for i:=1 to 100 do begin
if aéiè <=0 then cycle;
f(aéiè);
end;
CYCLE n'est pas un mot réservé, il peut donc être redéfini et
dans ce cas, il ne peut être employé dans le bloc o| il est redéfini.
````L'instruction LEAVE:
L'instruction LEAVE conclue la boucle WHILE, REPEAT ou FOR et
passe le controle à l'insruction suivant immédiatement la boucle.
L'emploi de LEAVE en dehors d'une boucle génère une erreur.
Exemples:
while i<63 do begin
if aéiè = x then leave;
i := i+1;
end;
LEAVE n'est pas un mot réservé, il peut donc être redéfini et
dans ce cas, il ne peut être employé dans le bloc o| il est redéfini.
````L'instruction WITH:
L'instruction WITH est une méthode simple pour désigner des
champs d'un enregistrement. Avec une instruction WITH, les champs
d'une ou plusieurs variables d'un enregistrement peuvent être
référencés en utilisant uniquement les identifiants des champs. Voici
la syntaxe de cette instruction:
with
!
+
L'emploi d'une variable dans une instruction WITH caractérise
l'utilisation d'un enregistrement. Dans une instruction WITH, chaque
référence par variable est tout d'abord interprétée comme un champ
d'enregistrement. Mème si une variable de mème nom est accessible,
c'est toujours la référence au champ de l'enregistrement qui est
traitée dans cette instruction.
Voici les règles à respecter dans l'emploi de with:
- lorsqu'on liste un enregistreement qui est le champ d'un autre
enregistrement, il faut d'abord lister l'enregistrement
contenant ou lister ce champ dans sa forme explicite.
- les instructions WITH peuvent être imbriquées. Dans ce cas, le
WITH contenant les autres WITH imbriqués reste valide mème dans
les boucles imbriquées.
- lorsque plusieurs enregistrements ont des champs de mème nom,
WITH fera référence au champ du dernier enregistrement nommé
dans la liste du WITH.
- lorsque l'identifiant d'un champ d'enregistrement est le mème
qu'une variable ou qu'un autre identifiant déclaré hors de
l'enregistrement, le WITH accéde au champ.
Exmples:
with date do
if month = 12 then begin
month:= 1;
year := year +1;
end
else month := month +1
ceci est équivalent à:
if date.month then begin
date.month := 1;
date.year := date.year +1
end
else date.month := date.month +1
Lorsque plus d'une référence de variable à un enregistrement se
trouve dans une instruction WITH comme:
with var1, var2, ... varN do instruction
alors cela est traité comme une suite imbriquée:
with var1 do
with var2 do
...
with varN do
instruction
Si varN est un champ de var1 et var2, il est interprété sous la
forme var2.varN et non comme var1.varN.
````L'instruction NULL:
Les instructions NULL sont des instructions ne contenant rien.
Les point-virgules non indispensables sont traités sous forme
d'instructions nulles par TML. Le résultat produit par une instruction
nulle est la présence de deux instructions au lieu d'une.
Généralement, cela n'est pas génant, mais toutefois cela peut produire
des erreurs.
``CHAPITRE 17: PROCEDURES ET FONCTIONS
Les procédures et fonctions vous permettent d'imbriquer des blocs
dans le bloc principal ou de définir des UNITS. Les procédures et
fonctions sont aussi appelées 'sous-programmes'. Chaque procédure et
fonction à un en-tète suivi par un bloc ou une directive spéciale. Une
procédure est activée par une instruction de procédure, et une
fonction est active par l'évaluation d'une expression contenant un
appel à une fonction.
```DECLARATION DES PROCEDURES:
Une déclaration de procédure asssocie un identifiant avec un
bloc; celui-ci pouvant être activé par une instruction de procédure.
déclaration de procédure
---->! en-tète de proc. !->! ; !->! corps de proc. !->! ; !->
corps de procédure
---+--->! bloc !
!
+--->!forward !
!
+--->! external !
!
+--->! inline !---+>! entier non-signé !-+
!
! +
!
+--->! tool !-->! entier non !--! , !-! entier non !-+-->
L'en-tète de procédure spécifie l'identifiant de la procéduree et
les paramêtres formels éventuels.
en-tète de procédure
---->! procédure !
+
+
!
+
La syntaxe des paramêtres formels est décrite plus loin dans ce
chapitre.
Une procédure est activée par une instruction de procédure qui
indique l'identifiant de la procédure et les paramêtres actuels requis
par elle. Les instructions à exécuter par la procédure sont spécifiées
par la partie 'instructions' du bloc de la procédure. Si l'identifiant
de la procédure est utilisé dans une une instruction de procédure dans
le bloc de procédure, la procédure est exécutée récurcivment. C'est à
dire que la procédure s'appelle elle mème en cours d'exécution.
Exemple de déclaration de procédure:
procedure Num2String (N: integer; var S: string);
var V: integer;
begin
V := Abs(N);
S:='';
repeat
S:= concat(Chr(V mod 10 + ord('0')),S);
V:= V div 10;
until V = 0;
if V<0 then S := Concat(('-',S);
end;
Au lieu du bloc dans une déclaration de procédure ou de fonction,
on peut trouver une directive FORWARD, EXTERNAL, INLINE ou TOOL. Voir
le paragraphes traitant des directives, dans ce chapitre.
```DECLARATION DES FONCTIONS:
Une déclaration de fonction associe un identifiant avec un bloc,
sous forme d'une fonction pouvant être activé par un appel de fonction
afin de calculer et retourner une valeur d'un type quelconque.
déclaration de fonction
---->! en-tète de fonc. !->! ; !->! corps de fonc. !->! ; !->
corps de fonction
---+--->! bloc !
!
+--->!forward !
!
+--->! external !
!
+--->! inline !---+>! entier non-signé !-+
!
! +
!
+--->! tool !-->! entier non !--! , !-! entier non !-+-->
L'en-tète de fonction spécifie l'identifiant de la fonction et
les paramêtres formels éventuels, ainsi que le type du résultat.
en-tète de fonction
---->! fonction !
+
!
+
!
+
! paramêtres!
! formels !
Une fonction est activée par l'évaluation d'un appel de fonction,
qui donne l'identifiant de la fonction ainsi que les paramêtres
formels requis. L'appel à la fonction est sous la forme d'un opérande
dans une expression. L'expression est évaluée en exécutant la
fonction, et en fait en remplaçant l'appel à la fonction par la valeur
retournée par la fonction.
Les instructions à exécuter sous controle de la fonction sont
spécifiés par la partie instruction du bloc de la fonction. Le bloc
devrait normalement contenir au moins une instruction d'assignation
assignant une valeur à l'identifiant de la fonction. Le résultat d'une
fonction est la dernière valeur assignée. Si aucune instruction
d'assignation n'existe, ou si elle existe mais n'est pas exécutée, la
valeur retournée par la fonction est indéfinie.
Si l'identifiant de la fonction est utilisé dans une appel de
fonction à l'intérieur du bloc de la fonction, la fonction est
exécutée récursivement.
Exemple de déclaration de fonction:
function Num2String(N: integer;): string;
var V: integer;
S: string;
begin
V := Abs(N):
S := '';
repeat
S:= concat(Chr(V mod 10 + ord('0')),S);
V := V div 10;
until V = 0;
if V<0 then S:= concat('-',S);
Num2String:=S;
end;
Une fonction peut être déclarée FORWARD, EXTERNAL, INLINE ou
TOOLde la mème manière que pour les procédures.
Si la valeur de retour d'une fonction est un type enregistrement
ou un pointeur sur un type enregistement, on ne peut l'utiliser dans
la liste d'une instruction WITH afin d'assigner des valeurs aux champs
de cet enregistrement. Le compilateur interprétera l'emploi de
l'identifiant de la fonction dans l'instruction WITH comme étant un
appel à la fonction.
```DIRECTIVES DE FONCTIONS ET PROCEDURES:
A la suite d'une procédure ou fonction, la partie constituée des
instructions peut être remplacée par une de ces quatre directives:
- FORWARD: permet à la procédure ou à la fonction
d'être déclarée immédiatement tout en ne déclarant le
bloc des instructions qu'ultérieurement.
- EXTERNAL: permet aux procédures ou fonctions d'être
écrites dans unautre langage que TML et d'être
ensuite linkées avec votre programe TML.
- INLINE: permet de remplacer les instructions Pascal
par un code en langage machine 65816.
- TOOL: désigne une procédure ou fonction implémentant
une routine de la boite à outils de l'Apple // GS.
````Directive FORWARD:
Une déclaration procédure ayant la directive FORWARD au lieu du
bloc d'instructions, est appelée une déclaration ultérieure. Quelque
part après la déclaration FORWARD, la procédure sera définie par une
déclaration de définition (procédure utilisant le mème identifiant de
procédure et contenant cette fois un bloc d'instructions). La
déclaration de définition peut contenir à nouveau la liste des
paramêtres formels, et dans ce cas, cette liste doit être identique à
la déclaration FORWARD. La déclartion FORWARD et la déclaration de
définition doivent être dans la mème partie de déclaration, mais n'ont
pas besoins d'être contigues. Ainsi, d'autres procédures, fonctions,
types ou variables peuvent être déclarées entre elles et peuvent faire
appel à la procédure en question. La déclaration FORWARD permet la
récursivité mutuelle.
La déclaration FORWARD et la déclaration de définition
constituent la déclaration complète de la procédure. La procédure est
considrée comme déclarée en lieu et place de la déclaration FORWARD.
Les procédures et fonctions FORWARD ne peuvent être déclarées dans la
partie INTERFACE d'une UNIT.
Exemples:
procedure Proc2 (m,n: integer); forward;
procedure Proc1 (x,y: real);
begin
...
Proc2(4,5);
end;
procedure Proc2 (m,n: integer);
begin
...
Proc1(8.3 , 2.4);
end;
````Les directives EXTERNAL:
Une déclaration de procédure dont le corps est constitué de la
directive EXETERNAL définit l'interface Pascal pour une routine
assemblée ou compilée dans un langage autre que TML. Le code externe
pour la routine doit être disponible pour le linkage.
Exemple:
procdure GotoXY (x,y: integer); External;
Dans cet exmple, GotoXY est une procédure externe devant être
linkée au programme principal avant exécution.
C'est au programmeur de s'assurer que les fonctions et procédures
externes sont compatibles avec leurs déclarations dans le programme
Pascal. Le linker n'effectue aucun test de compatibilité.
````Les directives INLINE:
Les directives INLINE permettent d'écrire du code en langage
machine à la place du bloc des instructions. Le code machine ne peut
être constitué que par une séquence de constantes entières repésentant
un seul octet de langage machine. Lorsque la procédure est appelée, le
compilateur génère le code machine spécifié par la directive INLINE.
Si une procédure a des paramêtres, ils sont empilés sur la pile avant
que le code ne soit généré.
La directive INLINE a pour but d'écrire de petites routines. Par
exemple, la procédure suivante va effacer le drapeau d'inhibition des
interruptions en générant l'instruction CLI:
procedure GenCli; inline $58;
````Les directives TOOL:
La directive TOOL sert à définir le corps d'une procédure par une
des routines de la boite à outils du GS. La boite à outils du GS est
divisée en plusieurs outils, chacun contenant des routines. Chaque
outil est identifié par un numéro unique, et chaque routine est
désignée par une numéro unique de fonction. Cette méthode de
désignation des routines de la boite à outils permet au TML de générer
le code adéquat pour faire appel à une fonction ToolBox. Par exemple,
la procédure MoveTo de l'outil QuickDraw (outil n[ 4) est désignée par
la fonction 58. Ainsi la déclaration TOOL se fera par:
procedure MoveTo (h,v: integer); Tool 4,58;
```LES PARAMETRES:
La déclaration d'une procédure ou d'une fonction spécifie une
liste de paramêtres formels. Les paramêtres déclarés dans une liste de
paramêtres formels sont locaux à la procédure ou fonction déclarée, et
peuvent être adressés par leurs identifiants dans le bloc associé à la
procédure ou fonction.
liste de paramêtres formels
--->! ( !----+-->! déclaration des paramêtres !---+--! ) !-->
!
+
déclaration des paramêtres
-+
!
+->! var !---+
!
+->! static !+ !I!
---
Les déclarations de procédures et fonctions peuvent avoir jusqu'à
trois sortes de paramêtres formels:
- variable: groupe de paramêtres précédés par le mot
VAR
- valeur : groupe de paramêtres non précédés par VAR
- statique: groupe de paramêtres précédés du mot STATIC
````Les paramêtres VALEURS:
Un paramêtre formel valeur se comporte comme une variable locale
à la procédure ou fonction, sauf que sa valeur initiale est donnée par
le paramêtre actuel correspondant lors de l'activation de la procédure
ou fonction. Les modifications de la valeur du paramêtre n'affectent
pas la valeur du paramêtre actuel.
Un paramêtre valeur correspondant à un paramêtre actuel dans un
appel de procédure ou de fonction doit être une expression, et sa
valeur ne peut être un type File ou tout autre type structuré conteant
un type File.
Le paramêtre actuel doit être compatible en assignation avec le
type du paramêtre valeur formel. Si le type du paramêtre est String,
le paramêtre formel doit avoir une taille statique de 255.
Si la taille du paramêtre formel (en octets) est supérieure à 4
octets, alors le paramêtre actuel est passé par son adresse et la
valeur actuelle est copiée dans la zone des variables locales.
Cependant, les assignations au paramêtre formel n'affectent pas la
valeur du paramêtre actuel.
Les paramêtres formels et actuels doivent compatibles en
assignation. Cette restriction peut être contournée en déclarant le
paramêtre sous la forme UNIV (voir l'avant dernier paragraphe de ce
chapitre).
````Les paramêtres VARIABLE:
Un paramêtre Variable est employé lorsque la valeur du paramêtre
doit être passée en retour de la procédure ou fonction. Le paramêtre
actuel correspondant dans une instruction d'appel de procédure ou de
fonction doit être une référence à une variable. Le paramêtre formel
Variable représente la variable acuelle durant l'activation de la
procédure ou de la fonction, aussi toute modification de la valeur du
paramêtre formel est immédiatement transférée au paramêtre actuel.
Dans une procédure ou fonction, toute référence à un paramêtre
formel Variable concerne le paramêtre actuel. Les paramêtres actuels
et formels doivent être compatibles en assignation. Cette restriction
peutêtre contournée en déclarant le paramêtre sous la forme UNIV (voir
l'avant dernier paragraphe de ce chapitre). Si le type du paramêtre
est String, le paramêtre formel doit avoir une taille statique de 255,
et le paramêtre actuel Variable doit être de type String avec une
longueur255.
Les types File ne peuvent être passés en paramêtre Variable.
Les composants des variables des types structurés compactés ne
peuvent être utilisés en tant que paramêtres actuels Variable.
Si on accède à une variable actuelle par l'indexation à un
tableau, la recherche de la variable identifiée par un pointeur, ou la
recherche du champ d'un enregistrement, l'action est exécutée avant
l'activation de la procédure ou de la fonction. Il faut faire
attention lors de la recherche de variables relogées dans le segment
principal. Le compactage de ce segment peut faire déplacer la source
ce qui produirait des effets surprenants.
````Les paramêtres STATIC:
Les paramêtres statiques sont des extensions spécifiques de TML
pour le //GS. Ils ont été ajoutés dans le seul but de permettre la
production d'un code objet performant. Les paramêtres statiques sont
traités de la mème manière que les paramêtres Valeur avec la
restriction suivante: une nouvelle valeur ne peut être assignée à un
paramêtre formel statique au sein de la procédure ou fonction.
Les paramêtres valeur dont le type formel nécessite plus de 4
octets de stockage sont passés par leurs adresses puis copiés dans la
zone locale de stockage des variables. Ainsi l'assignation de
nouvelles valeurs au paramêtre formel valeur ne modifie pas le
paramêtre actuel (voir appendix D). Cependant, dans certains cas si le
paramêtre formel est uniquement lu (et non écrit), il n'y a pas besoin
de copier le paramêtre actuel dans la zone local de stockage en vue de
son utilisation par le paramêtre formel puisque celui ci peut
l'adresser directement.
Les paramêtres statiques réduisent la taille de la pile requise
par une application et réduisent également le temps d'exécution
pusiqu'il n'y a pas besoin de copier la valeur du paramêtre actuel
dans la zone locale.
Attention, TML ne vérifie pas si un paramêtre statique sera ou
non ré-écrit. C'est au programmeur de s'assurer de l'usage correct des
paramêtres statiques.
````Les paramêtres UNIV:
Lorsque le mot UNIV apparait avant l'identifiant de type dans la
liste des paramêtres formels, la restriction selon laquelle les
paramêtres actuel et formel doivent être compatibles en assignation
pour les paramêtres Valeur, ou identiques si les paramêtres sont
Variables, n'a plus lieu. Lorsqu'on utilise UNIV, le paramêtre actuel
peut être de n'importe quel type pourvu que le nombre d'octets
nécessaires au stockage de la valeur du paramêtre actuel soit le mème
que celui du paramêtre formel.
Voici un exemple de paramêtre UNIV:
TYPE ptr = *Char; (* est un accent circonflexe)
VAR aLong: LongInt;
aPtr : Ptr;
procedure aProc(p: univ Ptr);
begin
end;
begin
aProc(aLong);
aProc(aPtr);
end.
````Compatibilité des listes de paramêtres:
La compatibilité des listes de paramêtres est indispensable pour
la concordance des listes formelles et actuelles.
Deux listes de paramêtres formels sont compatibles si elles
contiennent le mème nombre de paramêtres et si les paramêtres sont en
concordance dans la liste. Deux paramêtres concordent si une de ces
conditions est vraie:
- ce sont des paramêtres Valeur de type identique.
- ce sont des paramêtres variables de ype identique.
- le paramêtre formel à UNIV avant son type, et le
paramêtre actuel est une valeur ou une variable de
mème taille. Les paramêtres doivent être tous deux
des valeurs ou des variables.
``CHAPITRE 18: PROGRAMMES ET UNITS
```INTRODUCTION:
Le TML offre deux sortes de définition du source de vos
applications: les Programmes et les Unit. La différence entre les deux
est que le programme correspond à une application complète et peut
donc être compilé et exécuté. Une Unit ne peut être exécutée; c'est
plutot un assemblage dans lequel des parties de programmes peuvent
être définies et compilées indépendamment du programme. Les Programmes
et les Units sont compilés séparément. Leurs fichiers objets sont liés
par le Linker du TML afin de constituer un seul fichier exécutable.
```LES PROGRAMMES:
Un Programme Pascal ressemble à une déclaration de procédure si
ce n'est l'en-tète et la présence optionnelle de la clause USES.
programme
--->! en-tete de !->! ; !-+
! programme !
! USES ! ---
L'identifiant immédiatement après le mot PROGRAM dans l'en-tète
du programme est un identifiant de programme. Les paramêtres de
programme décrits par Jensen et Wirth et la norme ANS n'ont rien à
voir avec le TML.
NOTE: les versions 1.x de TML utilisaient la présence des mots
réservés Input et Output dans l'en-tète. Ces mots servaient à indiquer
au compilateur qu'il devait créer un environnement Plain Vanilla. Avec
TML II, il n'y a plus besoin d'employer ces mots réservés. Afin de
créer une environnement Plain Vanilla (désormais appelé textbook
Graphic), il suffit de faire appel à la procédure Graphics.
en-tète de programme
-->! PROGRAM !->! identifiant !-+
+-!(!->! paramêtres prog. !->!)!-+
---
paramêtres de programme
```LA CLAUSE USES:
La clause USES sert à identifier les Units requises par un
programme ou une Unit afin de pouvoir procéder à la compilation.
clause Uses
Lorsque TML rencontre un identifiant (le nom d'une UNIT) dans une
clause USES, il doit trouver le code compilé correspondant contenant
la table des symboles et le code objet de l'unit. Pour cela, la chaine
'.p.o' est ajoutée à la fin du nom de l'unit. Par exemple:
uses Globals, fileStuff;
fera utiliser les fichiers Globals.p.o et fileStuff.p.o
La clause USES dans le programme principal répertorie les Units
nécessaires au programme. Ces units sont celles utilisées directement
par le programme principal et celles utilisées par les Units
elle-mèmes.
Il se peut que le nom du fichier code-objet d'une unit ne
corresponde pas au nom de l'unit. Dans ce cas, la directive de
compilation $U permet de spécifier un nom d'unit particulière. La
directive $U doit se trouver immédiatement avant le nom de l'unit dans
la clause USES. Par exemple, on aurait pu écrire:
uses globals,
é$U :MyDisk:MyFolder:fileStuff.p.oè fileStuff;
Comme illustré dans cet exemple, la directive $U sert à indiquer
le préfixe complet d'accès à une unit non située dans le mème
directory que le source entrain d'être compilé. La directive $U est
documentée dans l'appendix B.
Lorsqu'une Unit nommée dans une clause USES utilise d'autres
Unit, les noms de ces units doivent également apparaitre dans la
clause USES et leurs noms doivent précéder celui de l'unit en
question. Par exemple:
UNIT UnitA; UNIT UnitB;
INTERFACE USES UnitA;
type colors=(red,white,blue); INTERFACE
IMPLEMENTATION type Rec = record
END. i : Integer;
c : colors;
end;
IMPLEMENTATION
END.
PROGRAM MyProgram;
USES UnitA, UnitB;
VAR aRec: Rec;
BEGIN
END.
Dans cet exemple, le programme MyProgram déclare une variable
aRec de type Rec, qui est déclaré dans UnitB. Cependant, une clause
USES sert à nommer UnitB et cette unit utilise également une clause
USES afin de nommer UnitA. Donc, la clause Uses du programme MyProgram
doit nommer UnitA avant UnitB.
Si une Unit est recompilée, toutes les Units qui l'utilisent
doivent être également recompilées. Ceci afin que les units
interdépendantes n'essaient pas de référencer des déclarations
devenues inexistantes ou modifiées. Par exemple, si UnitB est
recompilé dans notre exemple précédent, alors MyProgram doit être
recompilé mais pas UnitA. toutefois, si on modifie UnitA, il faudra
recompiler UnitB et MyProgram.
```LES UNITS:
Les Units sont la pierre angulaire de la programmation modulaire.
Les Units sont compilées séparément les unes des autres et sont
utilisées pour organiser les programmes importants en tronçons
logiques. En divisant un programme en plusieurs parties, on réduit
également le temps de compilation de chaque partie.
Voici quelques bonnes raisons d'employer des Units:
- permettent de rendre modulaire les programmes
importants
- permettent de définir des déclarations et des blocs
d'instructions utilisables par différents programmes
- peuvent être utilisées pour faire des parties non
listables par tout un chacun
Voici la syntaxe des Units:
Unit
+
!
+->! partie !-->! partie !->! END !->! . !->
! interface ! ! implémentation !
L'identifiant suivant le mot réservé UNIT est l'identifiant
d'unit. C'est le nom que les autres units et le programme principal
devront utiliser dans leurs clauses USES
partie interface
!-+
+->! clause !-+ +-! déclaration !<-+
! USES !
La partie Interface d'une Unit déclare les constantes, les types,
les variables, les procédures et les fonctions publiques. C'est à dire
que les déclarations faites dans la partie Interface sont disponibles
pour les autres Units ou Programmes utilisant le nom de l'unit dans
leur clause USES. En d'autres termes, le champ de validité des
déclarations publiques est le programme entier ou les units utilisant
cette unit. Le programme ou l'unit utilisant une unit peut accéder aux
déclarations publiques comme si elles avaient été déclarées dans ses
propres blocs.
Les déclarations de labels ne sont pas permises dans la partie
interface d'une Unit. Les procédures et fonctions de la partie
interface sont déclarées uniquement en indiquant le nom des procédures
ou fonctions, les paramêtres formels éventuels, et le type de résultat
(pour les fonctions). On ne peut mettre de bloc d'instruction pour les
procédures et fonctions dans la partie interface. A la place,
l'en-tète de la procédure ou fonction est répétée dans la partie
IMPLEMENTATION, là o| le code des blocs sont déclarés. Les
déclarations de procédures et fonctions dans la partie INTERFACE se
comportent comme si la directive FORWARD avait été spécifiée.
Cependant, les déclarations de procédures et fonctions peuvent avoir
les directives EXTERNAL, INLINE et TOOL dans la partie interface
puisqu'elles n'ont pas de bloc dans la partie implémentation.
Les variables, procédures et fonctions apparaissant dans la
partie interface sont dites GLOBALES. L'unit entière est sous la
gestion du bloc dans lequel une clause USES référence l'unit.
La partie interface peut contenir une clause USES, et ainsi une
Unit peut utiliser une autre Unit.
partie implémentation
+-!déclaration!<-+
La partie implémentation qui suit la dernière déclaration de la
partie interface, déclare chaque constante, type, varaiable, procédure
et fonction privées, c'est à dire non disponibles pour le programme ou
l'unit l'utilisant. Les procédures et fonctions privées sont déclarées
comme des procédures ou fonctions dans les programmes (avec un en-tète
et un corps).
Les procédures e fonctions publiques déclarées dans la partie
interface sont redéclarées dans la partie implémentation. La seule
exception concerne les procédures et fonctions déclarées en utilisant
les directives EXTERNAL, INLINE et TOOL. Les paramêtres formels et les
types de résulat peuvent être omis, mais s'ils sont indiqués, ils
doivent l'être de manière identique à leur déclaration précédente.
``CHAPITRE 19: LES ENTREES-SORTIES
```LES ACCES AUX FICHIERS
Le TML Pascal II gère les accès aux fichiers de deux manières:
- les routines E/S de la boite à outils du GS
- les procédures et fonctions propres au TML.
QuickDraw et l'Event Manager restent les méthodes les plus
directes pour gérer l'écran, le clavier et la souris. Les appels au
Système d'Exploitation GS/OS 5.0 permettent également de manipuler
aisément les fichiers. L'appendix C contient la liste des fichiers
interfaces de la boite à outils.
Les routines internes au TML permettent aussi de manipuler
facilement les accès aux fichiers. Ce chapitre traite exclusivement de
cette méthode.
```LES FICHIERS EN PASCAL
Avec le TML Pascal II, les fichiers sont gérés à l'aide de
'variables de fichier'. Une variable de fichier est tout simplement
une variable déclarée pour un type de fichier (voir ch. 13). Le TML
Pascal II accepte deux types de fichiers:
- les fichiers texte.
- les fichiers à structure.
Les fichiers textes sont déclarés avec le type prédéfini TEXT.
Les fichiers textes archivent les données sous forme de séquences de
caractères organisés en lignes. Le TML Pascal II dispose de plusieurs
fonctions et procédures spéciales pour gérer les lignes de texte.
TML Pascal II pré-défini deux fichiers textes pour chaque
programme: Input et Output. Le fichier Input est pré-défini en lecture
à partir du clavier uniquement, et le fichier Output est pré-défini en
écriture écran (écran texte ou graphique).
Les fichiers à structure sont constitués d'une séquence de
composants. Dans un fichier texte, un composant est un caractère; dans
un fichier à structure, le composant peut être de tout type autre
qu'un type de fichier ou qu'un type structuré contenant un type de
fichier. Un seul composant est appelé un 'enregistrement logique'.
Exemples de fichiers:
var aFile: text; é exemple de fichier texte è
var aFile: file of integer; é exemple de fichier structure
è
Les variables fichier se réfèrent à des fichiers composés de
séquences de composants. Pour les fichiers texte, ces composants sont
toujours de type 'Char'. Pour les fichiers à structure, le composant
peut être n'importe quel type Pascal, sauf un type de fichier ou un
type structuré contenant un fichier. Dans chaque cas, le composant est
considéré comme étant un enregistrement logique. Les fichiers peuvent
avoir n'importe quel nombre d'enregistrements logiques, mais on ne
peut accéder qu'à un seul à la fois avec une variable fichier. La
position, par rapport au début du fichier, de l'enregistrement logique
accessible, s'appelle 'position courante dans le fichier'.
Avant d'utiliser une variable fichier, il faut l'associer à un
fichier: c'est ce qu'on appelle 'ouvrir' le fichier. Il y a trois
procédures d'ouverture de fichier: Reset, Rewrite et Open.
Note: les variables fichier Input et Output sont pré-définies et
ouvertes automatiquement au lancement du programme.
Pour ouvrir un fichier, on doit spécifier son nom externe. Ce nom
peut être un chemin d'accès GS/OS ou un nom de périphérique.
```PROCEDURES ET FONCTIONS STANDARDS POUR TOUS LES FICHIERS
````La procédure RESET
syntaxe: Reset (f [, titre ])
Reset ouvre en lecture un fichier existant ou 'repositionne' un
fichier ouvert en remettant la position courante sur le composant 0.
Le fichier est ouvert uniquement pour des lectures séquentielles.
Lorsqu'un fichier déja ouvert est 'repositionné', son contenu n'est
pas effacé. 'f' est une variable fichier de n'importe quel type de
fichier; 'titre' est une chaine optionnelle.
Si 'TITRE' est spécifié dans la liste des paramêtres, alors RESET
va ouvrir un fichier existant nommé 'TITRE' puis la variable fichier
'f' sera associée à ce fichier externe. Si 'TITRE' n'est pas un nom
compatible GS/OS, ni un nom de périphérique, ou si le fichier ne peut
être ouvert, une erreur est retournée dans IOResult.
Si 'TITRE' n'est pas spécifié dans la liste des paramêtres, alors
'f' devra déja être associé à un fichier ouvert. Dans ce cas, RESET
replace la position courante sur le composaant 0 du fichier. Si 'f'
n'est pas déja associé à un fichier, alors une erreur est retournée
dans IOResult.
````La procedure REWRITE
syntaxe: Rewrite (f [, titre])
Rewrite ouvre en écriture un fichier existant, ou crée un nouveau
fichier, ou 'repositionne' un fichier ouvert en remettant la position
courante sur le composant 0. Le fichier est ouvert uniquement pour des
écritures séquentielles. Lorsqu'un fichier déja ouvert est
'repositionné' avec REWRITE, son contenu est effacé. 'f' est une
variable fichier de n'importe quel type de fichier; 'titre' est une
chaine optionnelle.
Si 'TITRE' est spécifié dans la liste des paramêtres, alors
REWRITE va créer et ouvrir un nouveau fichier externe nommé 'TITRE'
puis la variable fichier 'f' sera associée à ce fichier externe. Si le
fichier existe dja, il est ouvert et son contenu est effacé.
Si 'TITRE' n'est pas spécifié dans la liste des paramêtres, alors
'f' devra déja être associé à un fichier ouvert. Dans ce cas, REWRITE
replace la position courante sur le composaant 0 du fichier. Si 'f'
n'est pas déja associé à un fichier, alors une erreur est retournée
dans IOResult.
````La procédure OPEN
syntaxe: Open (f, titre)
OPEN va ouvrir un fichier existant ou va créer un nouveau
fichier. Le fichier est ouvert pour des lectures/écritures en accès
aléatoire. Lorsqu'un fichier existant est ouvert, son contenu n'est
pas effacé. 'f' est une variable fichier de n'importe quel type de
fichier; 'titre' est une chaine optionnelle.
Si 'TITRE' n'est pas un nom compatible GS/OS ni un nom de
périphérique, ou si le fichier ne peut être ouvert, une erreur est
retournée dans IOResult.
````La procédure CLOSE
syntaxe: Close (f)
CLOSE va fermer le fichier ouvert. 'f' est une variable fichier
de n'importe quel type de fichier. L'association entre 'f' et le
fichier externe est supprimée, et le système marque le fichier
'fermé'.
````La procédure EOF
syntaxe: EOF (f)
résultat: Boolean
Cela retourne l'état de fin de fichier. 'f' est une variable
fichier. EOF(f) retourne VRAI si la position courante est après le
dernier composant du fichier; sinon elle retourne FAUX.
````La procédure SEEK
syntaxe: Seek(f, n)
Change la position courante sur le composant 'n' et lis le nouvel
enregistrement logique. 'f' est une variable fichier, ',' est une
expression de type 'LongInt'. Pour les fichiers textes, la taille d'un
enregistrement logique est 1. Le numéro du premier enregistrement
logique est 0. Si la valeur de 'n' est plus grande que le nombre de
composants du fichier, alors la position courante est positionnée en
fin de fichier et EOF(f) est VRAI.
````La procédure ERASE
syntaxe: Erase (titre)
Permet d'effacer un fichier externe. 'titre' est une expression
de type chaine. Le fichier externe avec le nom 'TITRE' est effacé du
périphérique externe o| il se trouvait.
````La procédure IORESULT
syntaxe: IOResult
résultat: Integer
Cela retourne une valeur entière correspondant à l'état de la
dernière opération E/S effectuée. La valeur 0 indique une opération
correctement effectuée; une valeur non nulle indique qu'une erreur
s'est produite.
Vous remarquerez que IOResult retourne l'état de la DERNIERE
operation E/S. Aussi, les deux instructions suivantes ne donnent pas
les résultats qu'on pourrait croire:
Reset(f, 'monFichier');
Writeln('IOResult pour Reset = ',IOResult);
L'appel à la fonction IOResult dans la liste de paramêtre de
Writeln retourne l'état de l'opération WRITELN de la chaine 'IOresult
pour Reset =' puisque c'est la dernière opération E/S effectuée. Si on
avait voulu retourner l'état de 'Reset', on aurait du écrire:
Reset(f, 'monFichier');
svIOResult := IOresult;
Writeln('IOResult pour Reset = ', svIOResult);
````La fonction FILEPOS
syntaxe: FilePos(f)
résultat: LongInt
Cela retourne la position courante du fichier ouvert 'f'. Le
premier enregistrement logique dans un fichier est à la position 0.
Avec les fichiers à structure, un enregistrement logique est une
occurence du type de composant. Pour les fichiers textes, le type de
composant est un octet.
'f' est une variable fichier associée à un fichier devant être
ouvert.
````La procédure RENAME
syntaxe: Rename(AncNom, NouvNom)
Permet de renommer un fichier. 'AncNom' et 'NouvNom' sont des
expressions de type chaine. Le fichier externe nommé 'AncNom' va être
renommé en 'NouvNom'. Si aucun fichier ne porte le nom 'AncNom', une
erreur est retournée dans IOResult.
```PROCEDURES STANDARD POUR LES FICHIERS A STRUCTURE
Les procédures indiquées dans ce paragraphe sont utilisées pour
des accès aléatoires à des enregistrements logiques de fichiers à
structure. Le type de composant de ces fichiers peut être de tout type
autre qu'un type de fichier ou qu'un type structuré contenant un type
de fichier.
````La procédure READ pour les fichiers à structure
syntaxe: Read (f, v1 [, v2, ..., vn])
Permet de lire un composant de fichier dans une variable. 'f' est
une variable fichier, et chaque paramêtre 'v' est une variable du mème
type que le type du composant du fichier 'f'. Pour chaque paramêtre
'v', le composant de fichier à la position courante est lu dans 'v' et
la position courante est avancée au prochain composant. Si on essaie
de lire après la fin de fichier, une erreur est retournée dans
IOResult.
La procédure READ est aussi utilisée pour les fichiers textes
(voir plus loin). Avec les fichiers textes, la variable fichier 'f'
est un paramêtre optionnel, car si elle est omise, l'instruction READ
effectuera une lecture à partir de l'entrée standard (donc le clavier)
définie en type texte. Pour les fichiers à structure, la variable
fichier est indispensable.
````La procédure WRITE pour les fichiers à structure
syntaxe: Write (f, v1 [, v2, ..., vn])
Permet d'écrire chaque variable 'v' dans un composant de fichier.
'f' est une variable fichier, et chaque paramêtre 'v' est une variable
du mème type que le type du composant du fichier 'f'. Pour chaque
paramêtre 'v', la valeur de 'v' est écrite sur le composant de fichier
à la position courante, et la position courante est avancée au
prochain composant. Si on essaie d'écrire après la fin de fichier, un
nouveau composant est ajouté en fin de fichier.
La procédure WRITE est aussi utilisée pour les fichiers textes
(voir plus loin). Avec les fichiers textes, la variable fichier 'f'
est un paramêtre optionnel, car si elle est omise, l'instruction WRITE
effectuera une écriture sur la sortie standard (donc l'écran) définie
en type texte. Pour les fichiers à structure, la variable fichier est
indispensable.
```LES PROCEDURES ET FONCTIONS STANDARD POUR LES FICHIERS TEXTES
Les fichiers textes se distinguent des autres types de fichier du
fait qu'ils sont organisés en collections de lignes se terminant
toutes par un retour chariot. Les fichiers texte sont uniques parmi
les fichiers définis comme 'file of char' car le $#former est organisé
en lignes, tandis que le dernier ne l'est pas forcément.
Aucune procédure ou fonction définie dans ce paragraphe ne
requiert de variable fichier comme paramêtre explicite. Si on
n'indique pas de paramêtre variable fichier, le fichier pré-défini
Input ou Output est pris par défaut (si on fait une lecture, c'est
INPUT qui sera pris par défaut; autrement ce sera OUTPUt).
````La procédure READ pour les fichiers textes
syntaxe: Read ([f, ] v1 [, v2, ..., vn])
Lis une ou plusieurs valeurs d'un fichier texte dans les
paramêtres V1,... correspondants. Si la variable 'f' est indiquée,
elle doit être de type texte. Si on ne spécifié pas 'f', le fichier
standard Input est pris par défaut, qui est le clavier. Chaque
variable 'v' est de type Integer, Longint, Real, Char ou String.
lire une variable Char: pour les variables de type Char, la
procédure Read lit un caractère du fichier et l'assigne à la
variable. Si Eof(f) était VRAI avant la lecture, alors la
valeur Chr(0) est retournée. Si Eoln(f) était VRAI avant la
lecture, alors la valeur Chr(13) est retournée. La prochaine
lecture aura lieu à partir du prochain caractère dans le
fichier.
lire une variable LongInt ou Integer: avec une variable Integer
ou LongInt, on lit des séquences de caractères formant un
nombre signé. Les espaces, tabulations et fin de lignes sont
sautées jusqu'à ce qu'on tombe sur le début d'une chaine
numérique. Dès lors, tous les caractères autres que
'espace', 'tabulation' ou 'fin de ligne' sont considérés
comme faisant partie de la chaine numérique. La chaine est
alors interprétée sous forme de valeur numérique. Si aucun
caractère de la chaine ne représente un nombre signé, alors
une erreur est retournée par IOResult. La prochaine lecture
se fera ensuite à partir du caractère terminant la chaine
numérique.
lire une variable Real: avec les variables Real, on lit une
séquence de caractères formant un nombre signé en virgule
flottante. Tous les espaces, tabulations ou fin de ligne
sont sautés jusqu'à ce qu'on tombe sur le début d'une chaine
numérique. Dès lors, tous les caractères autres que
'espace', 'tabulation' ou 'fin de ligne' sont considérés
comme faisant partie de la chaine numérique. La chaine est
alors interprétée sous forme de valeur numérique. Si aucun
caractère de la chaine ne représente un nombre réel, alors
une erreur est retournée par IOResult. La prochaine lecture
se fera ensuite à partir du caractère terminant la chaine
numérique.
lire une variable String: avec une variable String, on lit tous
les caractères dans la variable chaine jusqu'au prochain
caractère 'fin de ligne' (celui-ci n'étant pas lu). La
prochaine lecture commencera à partir de ce caractère 'fin
de ligne'. Remarquez que des lectures successives de type
String, ne vont pas effectuer des lectures succesives de
lignes puisque une lecture de type String ne passe JAMAIS
après le caractère 'fin de ligne'.
````La procédure READLN
syntaxe: Readln([f,] v1 [,v2,...,vn])
Cette procédure est une extension de la procédure READ. Après
avoir effectué le mème travail que READ, alors READLN passe au début
de la prochaine ligne du fichier en sautant tous les caractères
jusqu'à ce qu'un 'fin de fichier' soit effectivement lu. S'il n'y a
pas d'autre ligne, EOF(f) devient VRAI. Bien entendu, si on ne
spécifie pas 'f', c'est le fichier standard Input qui est pris par
défaut.
````La procédure WRITE avec les fichiers textes:
syntaxe: Write ([f,] v1 [,v2,...,vn])
Ecris une ou plusieurs valeurs dans un fichier de type texte. Si
F n'est pas indiqué, le fichier standard Output est utilisé, qui est
généralement l'écran du moniteur //GS. Chaque valeur v peut être une
expression de type entier, entier long, réel, caractère, booléen ou
chaine.
Les paramêtres v sont appelés paramêtres d'écriture. Chaque
paramêtre d'écriture est de la forme:
OutExpr [: MinWidth [: DecPlaces]]
OutExpr: est une expression d'un type autorisé.
MinWidth et DecPlaces sont des expressions avec des valeurs de
type entier. MinWidth indique la largeur minimum du champ; il doit
être plus grand ou égal à 0. Il y aura exactement MinWidth caractères
écris (avec des espaces en en-tète si nécessaire), sauf si OutExpr a
une valeur ne pouvant être représentée qu'avec plus de caractères que
MinWidth; dans ce cas, le nombre nécessaire de caractères pour
représenter OutExpr est écrit. De la mème manière, si MinWidth n'est
pas spécifié, chaque OutExpr sera écrite avec le nombre nécessaire de
caractères pour la représenter.
DecPlaces indique le nombre de décimales dans la représentation
des réels. On ne peut l'employer que si OutExpr est de type réel, et
si MinWidth est également indiqué. Si on l'utilise, il doit être
supérieur à 0. Si on n'indique pas DecPlaces, OutExpr est écrit en
représentation virgule flottante.
````La procédure WRITELN:
syntaxe: Writeln ([f,] v1 [,v2,...,vn])
Cette procédure est une extension de la procédure Write. Après
avoir effectué la mème opération que Write, la procédure Writeln envoi
un caratère Fin-de-ligne (retour chariot) vers le fichier.
````La fonction EOLN:
syntaxe: Eoln [(f`]
résultat: boolean
Retourne l'indicateur Fin-de-ligne pour un fichier. F doit être
déclaré comme fichier de type Text. Eoln(f) retourne TRUE si le
caractère actuellement lu est un caractère Fin-de-ligne, ou si Eof (f)
est TRUE; autrement le résultat est FALSE.
````La procédure PAGE:
syntaxe: Page [(f)]
Ecrit un caractère de saut de page dans un fichier texte. F doit
être déclaré comme fichier de type texte. Si on ne le spécifie pas, le
fichier standard Output est utilisé.
```LES FICHIERS DISQUES ET LE TML PASCAL:
Lorsqu'on indique un fichier externe dans une procédure TML
Pascal, le nom d'accès complet doit être spécifié comme nom de
fichier. Un nom d'accès complet est constitué du nom de fichier
éventuellement précédé par le nom de volume et un ou plusieurs nom de
dossiers. Les noms de volumes, de dossiers et du fichier sont séparés
alors par des (:). Exemple:
MyVolume:MyDir1: ...:MyDirN:MyFile
Cependant, on peut également utiliser l'ancienne syntaxe
ProDos16, et mettre un (/) à la place des (:). Exemple:
MyVolume/MyDir1/ .../MyDirN/MyFile
(Voir le manuel GS/OS reference pour plus amples informations).
```LES PERIPHERIQUES ET TML PASCAL:
En plus des fichiers disques externes, TML Pascal accepte des
périphériques comme port d'entrée/sortie. Ces périphériques doivent
être des périphériques reconnus par GS/OS: clavier, écran,
imprimante... Lors du lancement du programme, Clavier et Ecran sont,
respectivement, les fichiers standard Entrée et Sortie.
L'imprimante est aussi disponible comme périphérique texte, mais
elle doit être explicitement ouverte avec la procedure REWRITE
utilisant le nom de device ".PRINTER". Exemple:
PROGRAM TestPrinter;
var f: Text;
begin
Rewrite(f,'.PRINTER');
for i:=1 to 10 do
Writeln(f,'bonjour l''imprimante');
Close(f);
end;
``CHAPITRE 20: PROCEDURES STANDARDS ET FONCTIONS
Ce chapitre décrit les procédures standard pré-définies ainsi que
les fonctions du TML II, à l'exception des procédures et fonctions
d'entrée/sortie décrites au chapitre 19.
Les procédures et fonctions standards sont pré-définies. Cela
signifie qu'elles fonctionnent comme si elles étaient déclarées dans
une Unit annexe. Il n'y a aucun conflit dans une déclaration
redéfinissant le mème identifiant dans un programme, mais dans ce cas
la procédure ou fonction pré-définie est masquée. A noter que les les
procédures et fonctions pré-définies ne peuvent être employées comme
paramêtres de procédures ou fonctions.
```La procedure GRAPHICS:
syntaxe: Graphics(screenMode: integer);
La procédure Graphics sert à initialiser l'environnement //GS.
Cette procédure doit être appelée au tout début du corps du programme.
Cette procédure initialise les outils QuickDraw et EventManager et
commute l'écran en mode SHGR 640 ou 320, selon la valeur de
ScreenMode. L'écran peut être utilisé comme Entrée/Sortie standard
pour les procédures Readln, Writeln et autres routines I/O. Des
graphismes QuickDraw peuvent également être dessinés sur cet écran.
La procédure Graphics est fournie dans TML II afin de simplifier
l'accès au dessin. La programmation dans le mode graphique est
explicitée au chapitre 7.
```Le déroulement des Procédures de Controle:
Les procédures décrites dans ce chapitre permettent un
branchement immédiat à une partie de programme.
````La procédure EXIT:
syntaxe: Exit (id)
La procédure Exit interrompt l'exécution d'un bloc de programme:
un bloc étant une fonction, une procédure ou le programme entier. De
manière générale, elle est équivalente à un GOTO vers un label situé à
la fin du bloc identifié par ID.
````La procédure HALT:
syntaxe: Halt
La procédure Halt interrompt l'exécution du programme.
````La procédure CYCLE:
syntaxe: Cycle
La procédure Cycle fait passer immédiatement à la fin de la
boucle en cours et l'exécution se poursuit ensuite avec la prochaine
valeur de la boucle. Cette procédure n'a de sens que dans des boucles
WHILE, FOR ou REPEAT; dans les autres cas, elle est sans effet. Voir
le chapitre 16 pour plus de renseignements.
````La procédure LEAVE:
syntaxe: Leave
La procédure Leave permet de passer immédiatement à l'instruction
immédiatement après la boucle en cours. Cette procédure n'a de sens
que dans des boucles WHILE, FOR ou REPEAT; dans les autres cas, elle
est sans effet. Voir le chapitre 16 pour plus de renseignements.
```Procédures et fonctions d'ALLOCATION DYNAMIQUE:
Ces procédures servent à gérer une zone mémoire non allouée lors
de l'exécution du programme. Cette procédure utilise les
fonctionnalités du MemoryManager afin de récupérer de la mémoire
libre.
````La procédure NEW:
syntaxe: New(p)
New(p) crée une variable de type P et lui fait référencer P. P
peut être un pointeur de tout type. La valeur de P est référencée par
p*. (attention: cette * est un accent circonflexe)
New utilise la fonction NewHandle pour trouver une zone mémoire
libre et elle retourne un pointeur sur le bloc mémoire alloué.
On obtient un code d'erreur si la zone réservée est insuffisante
pour contenir la nouvelle variable. Dans ce cas, p contient nil et la
fonction HeapResult contient un code d'erreur.
````La procédure DISPOSE:
syntaxe: Dispose(p)
Dispose(p) détruit une variable dynamique référencée par p et
libère la zone mémoire qu'elle occupait. P doit être une variable
précédemment crée par New(p) ou assignée à une valeur par une
instruction d'assignation. Désormais, la valeur de P devient indéfinie
et on a une erreur si on se réfère à une valeur précédemment associée
à p.
```LES FONCTIONS DE TRANSFERT:
Ces fonctions sont utilisées pour transférer une valeur d'un type
à un autre. Remarquez que les procédures standard Pack et Unpack du
Pascal ne sont pas implémentées dans le TML.
````La fonction TRUNC:
syntaxe: Trunc(x)
résultat: LongInt
Trunc(x) retourne une valeur LongInt de la variable réelle x,
tronquée à la valeur entière la plus proche comprise entre 0 et x
inclus.
On a une erreur si le résultat de cet arrondissement est hors des
limites -maxlongint-1..maxlongint.
````La fonction ROUND:
syntaxe: Round(x)
résultat: LongInt
round(x) retourne une valeur LongInt de la variable réelle x
arrondie à l'entier le plus proche. Si x est exactement à mi-chemin de
deux entiers, le résultat est l'entier ayant la plus grande valeur
absolue.
On a une erreur si le résultat de cet arrondissement est hors des
limites -maxlongint-1..maxlongint.
````La fonction ORD4:
syntaxe: Ord4(x)
résultat: LongInt
Ord4(x) retourne le nombre ordinal d'une valeur de type pointeur
ou ordinal. Ord4 correspond à Ord, sauf que le type du résultat est
LongInt.
````La fonction POINTER:
syntaxe: Pointer(x)
résultat: pointeur de type anonyme
Pointer convertis une valeur Integer ou LongInt en un type
pointeur. La valeur retournée par Pointer(x) est un pointeur sur
l'adresse physique o| se trouve la valeur de x. Ce pointeur est du
mème type que nil en ce sens qu'il est compatible avec tout type de
pointeur. La valeur de Pointer(0) est nil.
```LES FONCTIONS ET PROCEDURES ARITHMETIQUES:
Les fonctions et procédures arithmétiques effectuent des
opérations sur des valeurs de type entier ou réel. L'implémentation de
ces routines peut se faire avec le compilateur TML ou avec les
fonctions de l'outil SANE.
````La procédure INC:
syntaxe: Inc(x)
Incrémente de 1 la variable x de type Integer ou LongInt.
````La procédure DEC:
syntaxe: Dec(x)
Décrémente de 1 la variable x de type Integer ou LongInt.
````La fonction ABS:
syntaxe: Abs(x)
résultat: du mème type que le paramêtre
Retourne la valeur absolue de x; c'est à dire que si x est
négatif, on récupère -x; autrement on récupère x. x est un argument de
type Integer ou Real.
````La fonction SQRT:
syntaxe: Sqrt(x)
résultat: étendu
Si x n'est pas négatif, la valeur retournée est de type étendu et
correspond à la racine carrée de x. Si x est négatif, un diagnostic
NaN (Not a Number) est généré et un indicateur d'opération illégale
est positionné (voir Apple Numérics Manual).
````La fonction ODD:
syntaxe: Odd(x)
résultat: boolean
Retourne TRUE si x est impaire (non divisible par 2 sans reste).
Si x est paire, la fonction retourne FALSE. x est une expression de
type ordinal.
````La fonction SIN:
syntaxe: Sin(x)
résultat: étendu
Retourne le sinus trigonométrique de x. X est une expression de
type réel et doit représenter un angle en radians. Si x est infini, un
diagnostic NaN est produit et l'indicateur d'opération invalide est
positionné.
````La fonction COS:
syntaxe: Cos(x)
résultat: étendu
Retourne le cosinus trigonométrique de x. X est une expression de
type réel et doit représenter un angle en radians. Si x est infini, un
diagnostic NaN est produit et l'indicateur d'opération invalide est
positionné.
```La fonction EXP:
syntaxe: Exp(x)
résultat: étendu
Retourne la valeur de e puissance x (e étant la base des
logarithmes naturels). Si un dépassement de virgule flottante se
produit, le résultat est +inf. X est une expression de type réel.
````La fonction LN:
syntaxe: Ln(x)
résultat: étendu
Ln(x) retourne le logarithme naturel de x. X est une expression
de type réel. Si x est négatif, un diagnostic NaN est généré et
l'indicateur d'opération invalide est positionné.
````La fonction ARCTAN:
syntaxe: Arctan(x)
résultat: étendu
Retourne la valeur Arctangente de x. X est une expression de type
réel. Toutes valeurs numériques entre + et - inf sont valables.
```LES FONCTIONS ORDINALES:
Les fonctions ordinales décrites dans ce chapitre se rapportent à
des valeurs ordinales de types scalaires ou pointeurs. Voir le
chapitre 13 pour les informations sur les types scalaires et
pointeurs.
````La fonction ORD:
syntaxe: Ord(x)
résultat: Integer ou LongInt
Ord retourne la valeur ordinale d'un scalaire ou d'un pointeur.
Si x est de type entier ou long, le type du résultat sera identique à
celui de x. Si x est de type pointeur, le résultat est l'adresse
correspondante de la variable dynamique pointée par x, de type
LongInt. Si x est de type ordinal, le résultat est de type entier et
la valeur est l'ordinal de x. La procédure standard Ord4 doit être
utilisée si on veut un résultat de type LongInt, quelquesoit le type
de x.
````La fonction CHR:
syntaxe: Chr(x)
résultat: Char
Retourne la valeur Char dont l'ordinal est x. Pour toute valeur
char ch, on a toujours: chr(ord(ch))= ch.
````La fonction SUCC:
syntaxe: Succ(x)
résultat: le mème que le paramêtre
Retourne le successeur de x. Une erreur se produit si x est la
dernière valeur autorisée dans le type (c'est à dire qu'il n'a pas de
successeur).
````La fonction PRED:
syntaxe: Pred(x)
résultat: le mème que le paramêtre
Retourne le prédecesseur de x. Une erreur se produit si x est la
première valeur autorisée dans le type (c'est à dire qu'il n'a pas de
prédecesseur).
```LES FONCTIONS ET PROCEDURES DE CHAINES:
Les fonctions et procédures chaines n'acceptent pas de paramêtres
de type Packed Array of Char, mais uniquement des types String.
````La fonction LENGTH:
syntaxe: Length(str)
résultat: Integer
Retourne la longueur dynamique d'une chaine.
````La fonction POS:
syntaxe: Pos(substr, str)
résultat: Integer
Pos(substr, str) recherche la sous-chaine Substr dans la chaine
Str, et retourne une valeur entière correspondant à l'index du premier
caractère de Substr dans Str. Si Substr n'est pas trouvé dans Str, la
fonction retourne 0.
````La fonction CONCAT:
syntaxe: Concat(str1 [, str2,...strn])
résultat: type String anonyme
La fonction Concat permet de concaténer les paramêtres dans
l'ordre de leur passage et de retourner une chaine unique. La chaine
résultante ne peut excéder 255 caractères de long.
````La fonction COPY:
syntaxe: Copy(source, index, count)
résultat: type String
La fonction Copy retourne une chaine contenant Count caractères
de la chaine Source à partir de source[index].
````La procédure DELETE:
syntaxe: Delete( dest, index, count)
La procédure Delete ote Count caractèrees de la chaine Dest à
partir de Dest[index].
````La procédure INSERT:
syntaxe: Insert (source, dest, index)
La procédure Insert insère la chaine Source dans la chaine Dest,
le premier caractère de Source devenant dest[index].
```FONCTIONS ET PROCEDURES LOGIQUES:
Ce chapitre décrit les manipulations sur les bit; ces routines
correspondent à certaines instructions équivalentes du 65816.
````La fonction BAND:
syntaxe: BAnd(arg1, arg2)
résultat: Integer ou LongInt
BAnd retourne le ET logique de ses deux arguments. Arg1 et Arg2
sont deux expresions de type scalaire.
````La fonction BOR:
syntaxe: BOr(arg1, arg2)
résultat: Integer ou LongInt
BOr retourne le OU logique de ses deux arguments. Arg1 et Arg2
sont deux expresions de type scalaire.
````La fonction BXOR:
syntaxe: BXor(arg1, arg2)
résultat: Integer ou LongInt
BXor retourne le OU EXCLUSIF logique de ses deux arguments. Arg1
et Arg2 sont deux expresions de type scalaire.
````La fonction BNOT:
syntaxe: BNot(arg)
résultat: Integer ou LongInt
BNot retourne la négation logique de son argument (son complément
à 1). Arg est une expresion de type scalaire.
````La fonction BSL:
syntaxe: BSL(arg)
résultat: Integer ou LongInt
BSL décale à gauche les bits de Arg. Arg est une expresion de
type scalaire. Un zéro est introduit dans le bit faible.
````La fonction BSR:
syntaxe: BSR(arg)
résultat: Integer ou LongInt
BSR décale à droite les bits de Arg. Arg est une expresion de
type scalaire. Un zéro est introduit dans le bit fort.
````La fonction BROTL:
syntaxe: BRotL(arg)
résultat: Integer ou LongInt
BRotL effectue une rotation à gauche des bits de Arg. Arg est une
expresion de type scalaire. Le bit de poids fort est ré-introduit à la
place du bit de poids faible.
````La fonction BROTR:
syntaxe: BRotR(arg)
résultat: Integer ou LongInt
BRotR effectue une rotation à droite des bits de Arg. Arg est une
expresion de type scalaire. Le bit de poids faible est ré-introduit à
la place du bit de poids fort.
````La fonction HIWRD:
syntaxe: HiWrd(arg)
résultat: Integer
HiWrd retourne le mot de poids fort du scalaire ou du pointeur
Arg, c'est à dire les bits 31-16 d'un LongInt. Si Arg n'est pas une
valeur sur 32 bits, HiWrd retourne 0. Lorsque cet argument est une
variable simple ou un tableau, aucun code n'est généré par la fonction
car l'argument est seulement adressé et utilisé comme Integer.
````La fonction LOWRD:
syntaxe: LoWrd(arg)
résultat: Integer
LoWrd retourne le mot de poids faible du scalaire ou du pointeur
Arg, c'est à dire les bits 15-0 d'un LongInt. Lorsque cet argument est
une variable simple ou un tableau, aucun code n'est généré par la
fonction car l'argument est seulement adressé et utilisé comme
Integer.
```FONCTIONS ET PROCEDURES DIVERSES:
Ce chapitre décrit les fonctions et procédures manipulant les
octets ainsi que les routines travaillant sur des Packed Array of
Char.
Les routines manipulant les octets permettent à un programme de
considérer une variable comme une séquence d'octets, sans se soucier
des types de données. Les routines manipulant les octets sont:
MoveLeft, MoveRight et SizeOf.
Les routines travaillant avec des Packed Array of Char sont:
ScanEq, ScanNE et FillChar. Les paramêtres de ces routines ne peuvent
êtres indicés et les routines commencent toujours au premier caractère
du tableau.
````La fonction SIZEOF:
syntaxe: SizeOf(id)
résultat: LongInt
Retourne le nombre d'octets occupés par la variable ou le type
ID. La valeur de SizeOf est déterminée par le compilateur Pascal qui
la traite comme une constante lors de la compilation.
````La fonction CARD:
syntaxe: Card(s)
résultat: Integer
Décompte le nombre d'éléments dans s et retourne une valeur
entière représentant la cardinalité de s, c'est à dire le nombre
d'éléments.
````La procédure MOVELEFT:
syntaxe: MoveLeft (source, dest, count)
MoveLeft copie un bloc de Count octets consécutifs à partir de
Source et vers Dest, en commençant par l'adresse la plus basse (c'est
à dire le premier octet de Source et Dest). Source et Dest sont des
variables de tout type autre que File ou qu'une structure contenant un
type File. Count est une expression entière dont la valeur n'est pas
vérifiée. Si Source et Dest se chevauchent, vous ne pouvez utiliser
cette procédure que si Source est à l'adresse la plus haute.
````La procédure MOVERIGHT:
syntaxe: MoveRight (source, dest, count)
MoveRight copie un bloc de Count octets consécutifs à partir de
SOurce et vers Dest, en commençant par l'adresse la plus haute (c'est
à dire le dernier octet de Source et Dest). Source et Dest sont des
variables de tout type autre que File ou qu'une structure contenant un
type File. Count est une expression entière dont la valeur n'est pas
vérifiée. Si Source et Dest se chevauchent, vous ne pouvez utiliser
cette procédure que si Source est à l'adresse la plus basse.
````La procédure FILLCHAR:
syntaxe: FillChar(dest, count, ch)
FillChar remplit un bloc de Count caractères consécutifs avec le
caractère CH, en commençant à l'adresse de début de Dest. Dest est une
variable de type Packed Array of Char. Count est une expression
entière dont la valeur n'est pas vérifiée. CH est une valeur de type
Char.
````La fonction SCANEQ:
syntaxe: ScanEq( limit, ch, source)
résultat: Integer
ScanEq scrute un bloc de mémoire en commençant à Source et
recherche la première occurence de CH. La fonction est active jusqu'à
ce que CH soit trouvé, o| que l'on a analysé Limit octets. Si CH n'est
pas trouvé dans la limite indiquée, la valeur retournée est égale à
Limit. Autrment, la valeur retournée correspond au nombre d'octets
analysés avant que CH n'ait été trouvé.
Limit est une expression entière coupée à 16 bits et non
vérifiée. Ch est de type Char; Source est une variable avec une valeur
de type Packed Array of Char.
````La fonction SCNANE:
syntaxe: ScanNe( limit, ch, source)
résultat: Integer
ScanNe fonctionne de la mème manière que ScanEq, à la différence
qu'elle recherche le premier caractère DIFFERENT de ch.
```LA GESTION DES ERREURS D'APPEL A LA BOITE A OUTILS:
La boite à outils de L'Apple //Gs obéit à une convention de
traitement des erreurs survenant lors de l'appel à une fonction
ToolBox. Si une erreur est détectée lors de l'exécution d'une routine
ToolBox, le 65816 met la carry à 1 et l'accumulateur contient le code
d'erreur correspondant. Le Pascal TML permet de récupérer ces
informations dans vos programmes.
````La fonction ISTOOLERROR:
syntaxe: IsToolError
résultat: Boolean
Retourne TRUE si la dernière fonction ToolBox appelée à provoqué
une erreur; sinon elle retourne FALSE. Cette fonction teste le bit de
carry du 65816 pour savoir si une erreur s'est produite. La fonction
doit être appelée IMMEDIATEMENT après l'appel à la fonction avant
qu'une autre opération n'affecte le bit de carry du micro-processeur.
Si l'appel à la ToolBox est une fonction se trouvant dans une
expression, le résultat de IsToolError peut être incorrect puisque
l'évaluation de l'expression peut modifier la carry. Dans ce cas, le
programme doit tester la variable _ToolErr.
````La variable _TOOLERR:
syntaxe: _ToolErr
type: Integer
La variable _ToolErr contient le code d'erreur retourné par le
dernier appel à une fonction ToolBox. Une valeur différent de 0
indique une erreur. Le compilateur génère un code stockant le contenu
de l'accumulateur dans la variable _ToolErr immédiatement après
l'appel à la boite à outils, et avant qu'une autre opération n'altère
cette valeur.
Exemple d'emploi de IsToolError et de _ToolErr:
h := NewHandle(100,myMemoryID,0,Ptr(0));
if IsToolError then begin
theErr:=_ToolErr;
Writeln('Erreur d'allocation mémoire:',theErr);
end;
Remarquez que _ToolErr a été sauvé dans une variable temporaire
avant l'appel à la procédure Writeln. Ceci est nécessaire car la
procédure Writeln fait appel à plusieurs fonctions ToolBox qui
altéreraient le contenu de _ToolErr et donneraient donc un résultat
erroné.
Plusieurs fonctions ToolBox sont conçues pour ne pas générer
d'erreur, mais TML ne le sait pas et il génère donc le code
correspondant à la sauvegarde du code d'erreur. Si une application ne
veut pas que ce code de gestion d'erreur soit généré, il faut mettre
la directive é$ToolErrorCheck-è. Voir l'appendix B pour plus de
renseignements.
Note: les verions 1.x de TML utilisaient la variable ToolErrorNum pour
retourner les erreurs produites lors des appels à la boite à outils.
Cette variable est également disponible dans TML II, mais il est
préférable d'utiliser _ToolErr dans un souci de standardisation.
``APPENDIX A: LES MESSAGES D'ERREUR
Cet appendix répertorie les erreurs possibles en TML Pascal que
ce soit dans l'éditeur, le compilateur ou le linker; ainsi que pour
les erreurs GS/OS et I/O. Certaines explications sont parfois fournies
afin de mieux expliquer pourquoi et comment le message est généré; et
quelquefois il est indiqué comment corriger l'erreur.
Certains messages contiennnet le caractère "*" qui signifie que
dans le message que vous verrez à l'écran, TML utilisera un
identifiant, un label ou une valeur.
```LES ERREURS D'EDITION:
- Memory is getting low. Close a document window:
TML détecte que la mémoire est pleine et avant que certaines de
vos données ne soient perdues, il vous conseille de faire une
purge de la mémoire en fermant un document. On peut aussi choisir
RELEASE MEMORY dans le menu Preferences.
- Can't open that file. The file already open in another window:
On ne peut avoir deux fois le mème document à l'écran.
- Error reading file:
Une rreur s'est produite lors de la lecture du document sur
disquette. Cela se produit si le fichier est endommagé ou si la
disquette a été otée du lecteur.
- error saving file:
Cette erreur survient si TML ne peut sauver le document sur
disque. Ceci se produit si la disquette est verrouillée, otée du
lecteur ou si elle est pleine.
- Error deleting file:
Cette erreur survient si vous choisissez DELETE dans le menu
GS/OS et que la disquette a été otée du lecteur ou si elle est
verrouillée.
- Error renaming file:
Cette erreur survient si vous avez choisi de renommer un fichier
avec la commande RENAME du menu GS/OS, et que soit vous avez
donné un nom illégal, soit la disquette a été otée ou soit le
disque est verrouillé.
- Insufficient memory to complete that operation:
Lorsqu'une opération n'a pu se faire du fait d'un manque de
mémoire libre.
```LES ERREURS DE COMPILATION:
````Les erreurs lexicales:
- String constant must not exceed source line:
Une constante chaine ne se termine pas par les guillemets de
cloture.
- Error in numeric litteral:
La syntaxe d'une valeur littérale numérique est incorrecte.
- Illegal character in input:
Un caractère illégal a été lu dans le fichier source.
- Incomplete program:
La fin de fichier est atteinte avant que le Programme ou l'Unit
ne soit terminé normalement par un point.
- End of file encountered while reading a comment:
Le compilateur TML est arrivé à la fin du fichier sans avoir
trouvé la fin de commentaire. Tout commentaire doit commencer par
é ou (* et se teminer par è ou *). Voir le chapitre 11.
````Les erreurs de syntaxe:
Ces messages d'erreur signifient que votre programme contient des
syntaxes interdites. Bien que le message d'erreur vous suggère le
symbole manquant dans l'expression illégale, il est possible que
l'erreur soit due à autre chose. Pour cela, voir les chapitres 11 à 20
pour vous familiariser avec la syntaxe du Pascal.
- Identifier expected: il faut un identifiant.
- Unexpected symbol: symbole non placé correctement.
- Integer constant expected: il faut mettre une constante entière.
- Error in statement: instruction incorrecte.
- Error in expression: expression incorrecte.
- BEGIN expected: il manque l'instruction BEGIN.
- DO expected: il manque l'instruction DO.
- END expected: il manque l'instruction END.
- IMPLEMENTATION expected: il manque la directive IMPLEMENTATION dans
l'Unit.
- INTERFACE expected: il manque la directive INTERFACE dans l'Unit.
- OF expected: il manque l'instruction OF.
- PROGRAM or UNIT expected: il manque la directive PROGRAM ou UNIT en
début de document.
- THEN expected: il manque l'instruction THEN dans une condition IF.
- TO or DOWNTO expected: il manque l'instruction TO ou DOWNTO dans une
boucle FOR.
- UNTIL expected: il manque l'expression UNTIL dans une boucle REPEAT.
- ) : [ ] ; = , .. . := expected.
````Les erreurs sémantiques:
- Duplicate identifier:
Lorsque le mème identifiant est déclaré plusieurs fois dans le
mème bloc.
- Low bound exceeds high bound:
Dans une déclaration de tableau, l'indice est infrieur est
déclaré plus élevé que l'indice supérieur.
- Identifier is not of appropriate class:
- Identifier not declared:
- Sign not allowed:
- Incompatible subrange types:
- File not allowed here:
- Tagfield must be scalar or subrange:
- Index type muste be scalar or subrange:
- Base type must be scalar or subrange:
Le type spécifié doit être un scalaire ou un type tel que
Integer, Char, Boolean ... Le type ne peut pas être Real.
- Error in type of standard subprogram parameter:
Lorsque le type d'une expression passée en paramêtre à une
procédure ou fonction pré-définie de TML, est incorect. Voir les
chapitres 19 et 20.
- Repetition of parameter list is not identical to previous
declaration:
Lorsqu'une liste de paramêtres pour une fonction ou une procédure
déclarée FORWARD est répétée, ou lorsque dans une interface Unit
elle ne correpond pas à la déclaration.
- File value parameter not allowed:
Les paramêtres de fichiers doivent toujours être spécifiés par
VAR.
- LongInt case/control variable/index expression are not implemented:
TML ne permet pas l'utilisation d'expressions dont le type est
LongInt dans des expressions Case, des variables de controle de
boucle ou des tableaux indexés.
- Missing result type in function declaration: le type du résultat de
la fonction n'est pas déclaré.
- Fixed point formatting allowed only for real types: point décimal
uniquement pour les réels.
- Number of parameters does not agree with declaration: le nombre de
paramêtres ne correspond pas avec la déclaration.
- Actual parameter may not be PACKED for VAR formal parameter: le
parmêtre ne doit pas être compacté pour la déclaration VAR.
- Operands are not assignement compatible: les opérandes ne sont pas
compatibles.
- Tests on equality allowed only: on ne peut que tester l'égalité.
- Strict inclusion not allowed: l'inclusion stricte n'est pas permise.
- File comparison not allowed: on ne peut comparer les fichiers.
- Illegal type of operand(s): opérande de type interdit.
- Type of operand muste be boolean: il faut un opérande de type
booléen.
- set element type must be scalar or subrange: le type de
l'énumération doit être scalaire ou sous-type.
- Set element types not compatible: les types de l'énumération ne sont
pas compatibles.
- Type of varibale is not array: la variable n'est pas un tableau.
- Index type is not compatible with declaration: le type de l'index ne
correspond pas à sa déclaration.
- Type of varaiable is not record: la variable n'est pas un
enregistrement.
- Type of variable must be pointer: la variable doit être de type
pointeur.
- Illegal parameter substitution: changement de paramêtre interdit.
- Illegal type of loop control variable: type interdit pour la
variable controlant la boucle.
- Boolean expression expected: il faut une expression de type
booléenne.
- Assignment of files not allowed: l'assignation de fichers n'est pas
autorisée.
- Label type incompatible with selecting expression: le type de label
est incompatible avec l'expression.
- Subrange bounds must be scalar: les valeurs limites doivent être
scalaires.
- No such field in this record: l'enregistrement n'a pas de ce champ.
- Actual parameter must be variable: le paramêtre doit être une
variable.
- Control variable must not be declared on intermediate level: on ne
peut déclarer la variable de controle à un niveau intermédiaire.
- Multidefined case label: instruction CASE déclarée plusieurs fois.
- Again forward declared: directive FORWARD a nouveau déclarée.
- Multidefined label: label définit plusieurs fois.
- Multideclared label: label déclaré plusieurs fois.
- Undeclared label: label non déclaré.
- Error in base set: erreur dans l'énumération.
- Illegal function result assignment: assignation incorrecte du
résultat de la fonction.
- Must EXIT to an enclosing subprogramm: on doit quitter vers une
borne du sous-programme.
- Control variable must not be format: on ne doit pas formater la
variable de controle.
- Assignment to control variable is not allowed: on ne peut pas
assigner une variable de controle.
- Forward referenced type "*" not completed in previous: le type de la
référence FORWARD pour "*" n'a pas été indiqué.
- Forward declared subprogram "*" not completed in previous: le
sous-programme déclaré en forward n'a pas été défini.
- Label "*" was declared but not defined in previous block: le label
"*" a été déclaré mais non défini au préalable.
- Size of string must be between 1 and 255: la taille de la chaine
doit être entre 1 et 255.
- à is not allowed for expressions or INLINE and TOOL subprogramms: on
ne peut utiliser l'assignation à dans les sous-programmes INLINE ou
TOOL.
- Type cast to a different size is not allowed: on ne peut modifier la
taille de ce type .
- Too many nested scopes of identifiers: trop d'identifiants
imbriqués.
- Too many nestded procedures and/or functions: trop de procédures ou
fonctions imbriquées.
- Index expression out of bounds: index hors limite.
- Implementation restriction: limite de l'implémentation.
````Les erreurs d'Unit:
- The Unit "*" require is required to USE this unit:
Lorsque une Unit nommée dans une déclaration USES utilise une
autre Unit non indiquée dans cette déclaration.
- Repetition of unit not allowed:
On ne peut répéter l'unit.
- This unit must be recompiled:
Lorsqu'une Unit nommée dans la déclaration USES a été recompilée.
Pour corriger l'erreur, il faut recompiler l'Unit indiquée dans
la déclaration Uses.
- Unable to find/open unit's symbol file:
Lorsque le fichier ".p.o" pour l'unit indiquée ne se trouve pas
dans le préfixe courant ou dans le chemin d'accès aux units
indiqué dans Preferences.
- Unable to write unit symbol file for this unit:
Lorsque le compilateur ne peut créer le fichier ".p.o". La
disquette est peut être verrouillée, absente ou pleine.
- Unit must be recompiled with current version of compiler:
Lorsque vous utilisez une nouvelle version TML, il faut
recompiler vos Units.
- Symbol table space exhausted:
Lorsque le nombre de déclarations dans cette unit a rempli la
mémoire disponible allouée pour la table des symboles des units.
Il vous faut modifier cette taille de table des symboles dans le
menu Preferences.
````Les erreurs du Linker:
- Out of Memory:
- Segment "*" specified as both CODE and DATA:
Ces erreurs se produisent lorsque vous spécifiez le mème nom de
segment dans une directive de compilation é$DSeg segnameè et
é$CSeg segnameè.
- Segment "*" too large:
Un segment CODE ou DATA est plus grand que 64K. Vous devez
re-segmenter votre programme pour qu'aucun segment ne dépasse
cette limite. Voir chapitre 16.
- Unresolved linker reference to symbol "*":
Un label définit extérieurement ne peut être trouvé par le
linker. Vous devez revérifier l'orthographe du symbole pour vous
assurrer qu'il est correct.
- Unable to create/open application file:
Après une compilation sur disque, le linker essaie d'écrire le
fichier de chargement. Cette erreur se produit si ce fichier ne
peut être créé et/ou ouvert: disque verrouillé ou absent.
- Error in writing to application file:
Cette erreur survient si TML a pu créer et/ou ouvrir le fichier
d'application de sortie mais qu'une erreur s'est produite lors de
l'écriture. Ceci se produit avec un disque verouillé ou plein.
````Les codes d'erreur GS/OS:
Ce chapitre répertorie les erreurs GS/OS produite lors des
entrées/sorties, à l'exclusion des codes d'erreurs -1, -2 et -3
générés par les routines TML pour des erreurs spécifiques à Pascal.
Pour de plus amples informations sur cette liste d'erreurs, consultez
le manuel GS/OS Reference.
- Erreurs générales:
$00 aucune erreur.
$01 numéro d'appel GS/OS non valide.
$04 nombre de paramêtres hors limite.
$07 GS/OS actif.
- Les erreurs d'appel aux périphériques:
$10 périphérique absent.
$11 n[ de périphérique non valide.
$20 request invalide.
$21 code d'état ou de controle invalide.
$22 mauvais paramêtre d'appel.
$23 périphérique caractère non ouvert.
$24 périphérique caractère déja ouvert.
$25 table des interruptions remplie.
$26 resources non disponibles.
$27 I/O errreur.
$28 aucun périphérique connecté.
$29 driver actif.
$2B périphérique protégé en écriture.
$2C décompte d'octets invalid.
$2D mauvais adressage de bloc.
$2E le disque a été permuté.
$2F périphérique éteint ou support absent.
- Les erreurs d'appel aux fichiers:
$40 syntaxe du chemin d'accès incorrecte.
$43 n[ de référence incorrect.
$44 sous-dossier inexistant.
$45 volume absent.
$46 fichier absent.
$47 création ou renommer avec un nom existant.
$48 volume plein.
$49 directory plein.
$4A erreur de version.
$4B type de stockage non accepté.
$4C fin-de-fichier rencontré.
$4D position hors limite.
$4E accès non autorisé.
$4F buffer insuffisant.
$50 fichier déja ouvert.
$51 erreur dans le directory.
$52 type de volume inconnu.
$53 paramêtre hors limite.
$54 mémoire saturée.
$57 noms de volumes identiques.
$58 périphériques de type autre que bloc.
$59 niveau hors limite.
$5A n[ de bloc trop grand.
$5B chemin d'accès non valide pour Change Path.
$5C fichier non exécutable.
$5D système non accepté.
$5F trop d'applications sur la pile.
$60 donnée non disponible.
$61 fin de directory atteinte.
$62 classe d'appel FST non valide.
$63 le fichier ne contient pas la resource spécifiée.
- Les erreurs spécifiques à TML:
-1 fichier Txt non ouvert en lecture.
-2 fichier Txt non ouvert en écriture.
-3 erreur de conversion de chaine dans un fichier Txt.
``APPENDIX B: LES DIRECTIVES DE COMPILATION
Le TML offre un certain nombre de directives (ou options)
affectant la compilation et/ou le code généré par le compilateur. Ces
directives de compilation sont à écrire entre les délimiteurs de
commentaires é..è ou (*..*). Une directive commence toujours avec le
symbole $ et doit se trouver immédiatement après le délimiteur
d'ouverture, et elle doit être suivie d'une lettre indiquant la
directive.
Il y a deux types de directives: les directives de commutation et
les directives de paramêtres. Une directive de commutation donne ou
enlève une possibilité en spécifiant + ou - juste après la directive.
Une directive de paramêtre comprend une ou plusieurs chaines arguments
(noms de fichiers, noms de segments...). Une chaine argument se
termine par un espace, une astérisque ou un crochet fermé. Si une
chaine argument contient un de ces caractères, la chaine doit être
mise entre guillemets.
Exemples:
(*$LongGlobals+ *)
é$CSeg NewSegè
```LES CDA:
(*$CDA menuName*)
La directive CDA sert à informer le compilateur que le programme
implémente un CDA au lieu d'une application clasique GS/OS. La
structure d'un CDA est différente d'une application clasique. En
particulier, TML doit générer un en-tète spécial contenant le nom du
CDA tel qu'il apparaitra dans le menu Pomme.
Voir le chapitre 10 pour écrire son propre CDA.
Comme le compilateur doit générer un code spécial pour les CDA
avant tout autre chose, l'option DOIT se trouver avant le mot UNIT
dans votre source. Exemple:
(*$CDA SHRDump*)
UNIT MySHRDump;
...
end.
```CODE SEGMENT:
(*$CSeg segname*)
valeur par défaut: (*CSeg main*)
L'option CSeg informe le compilateur dans quel segment les sous
programmes suivants devront être alloués. Le segment par défaut à le
nom réservé MAIN. Pour les autres noms de segments, toute chaine de
caractères ne contenant pas d'espace est permise. Voir le chapitre 8
pour plus d'informations sur l'utilisation des segments.
```DEFINITION DE PROCEDURE:
(*$DefProc*)
La directive (*$DefProc*) informe le compilateur que la prochaine
procédure ou fonction dans le source va implémenter une définition de
procédure Tool Box. On implémente une définition de procédure de la
mème manière que pour toute autre procédure ou fonction, sauf que dans
ce cas le compilateur génère un code particulier. Plus précisément, le
compilateur génère un code forçant le DBR (registre de banc de
données) à être égal au banc mémoire contenant les variables globales
Pascal du programme. Lorsqu'on quitte la procédure, un code
particulier restaure les valeurs originelles du DBR.
```SEGMENT DE DONNEES:
(*$DSeg segname*) valeur par défaut: (*$DSeg _global*)
!
(ceci est en fait un trema ----+ )
L'option (*$DSeg*) informe le compilateur que les variables
globales suivantes seront allouées dans un segment particulier. Le nom
du segment par défaut est le nom réservé _GLOBAL (_ est un trema);
pour les autres segments, on peut utiliser toute chaine de caractères
ne contenant pas d'espace, et précédée du caractère 'trema'. Le
segment de données _global est le segment particulier o| le
compilateur utilise un adressage absolu, plus performant que
l'adressage long absolu (_ est un trema). Voir le chapitre 8 pour plus
de renseignements sur l'emploi des segments de données.
```LES REFERENCES DE VARIABLES EXTERNES:
(*$J+*) ou (*$J-*) valeur par défaut: (*$J-*)
La directive de référence de variable externe informe TML que les
variables globales suivantes n'auront pas de zone de stockage allouée.
A la place, la déclaration de ces variables globales est traitée comme
une référence externe à une variable globale déclarée ailleurs.
Cette directive sert à TML pour utiliser des variables globales
définies dans des modules ASM ou C.
Exemple:
VAR GlobVar1: integer;
(*+J*)
GlobVar2: integer;
(*-J*)
GlobVar3: integer;
```LONG GLOBALS:
(*$LongGlobals+*) ou (*$LongGlobals-*)
valeur par défaut: (*$LongGlobals-*)
Cette option informe le compilateur de commuter (+) ou de
désactiver (-) la génération d'adressage absolu long pour les
variables globales dans le segment de données _global (_ est un
trema). Normalement, le compilateur génère un code qui force le DBR
(banc de registre données) à être le mème que le banc mémoire
contenant les varibales globales allouées dans le segment de données
_global (_ est un trea). Cependant, dans certaines occasions, le
programme exige que ces bancs soient différents. Dans ces cas, il faut
indiquer au compilateur que l'on veut accéder aux variables globales
du segment de données _global par un adressage absolu long. (_ est un
trema)
```LES NDA:
(*$NDA period event Mask menuName*)
La directive NDA informe le compilateur que le programme est un
NDA et non une application GS/OS standard. La structure d'un NDA est
différente de celle d'une application normale. En particulier, TML
doit générer un code spécial en en-tète indiquant la période (en
1/60ème de secondes), intervalle d'accès périodique au NDA; un
EventMask décrivant le type d'évènements gérés par le NDA; et le Nom
qui apparaitra dans la liste des NDA (menu Pomme).
Voir le chapitre 9 pour de plus amples informations sur la
structure des NDA.
Comme le compilateur doit générer un code spécial en en-tète pour
les NDA, cette option DOIT se trouver avant le mot réservé UNIT dans
votre source. Exemple:
(*$NDA 60 -1 TMLClock*)
UNIT TMLClock;
...
END.
```TAILLE DE LA PILE:
(*$StackSize numbytes*) valeur par défaut: (*$StackSize 8096*)
La directive StackSize informe TML de la taille (en octets)
allouée pour la pile d'exécution de l'application. Cette pile
d'exécution sert à conserver l'adresse de retour des sous-programmes
ainsi que les variables locales. L'usage intensif de variables locales
va donc décider de la taille de la pile.
La valeur par défaut de cette pile est 8K (8096 octets). Si un
programme nécessite plus ou moins de place, il faut alors spécifier la
taille. Cependant, au moins 1K (1024 octets) et au plus 40K (40960)
peuvent être aloués (bien que TML ne vérifie pas la taille spécifiée
dans la directive). Voir l'appendix D pour plus d'information sur
l'emploi des piles d'exécutions.
Notez que cette option DOIT se trouver avant le mot réservé
PROGRAM dans votre code. Exemple:
(*StackSize 10240*)
PROGRAM MyProgram;
begin
...
end.
```LE PREFIXE DE RECHERCHE DES UNITS:
(*$U GSOS prefix*) valeur par dfaut: (*$U 0:*)
Cette option permet d'utiliser un préfixe particulier pour
rechercher le suffixe des units (.P.O). Le TML ne recompile pas les
interfaces des units indiquées dans USES, mais il charge une table
pré-compilée des déclarations à partir d'un fichier '.P.O'. Afin de
rechercher ces fichiers, TML utilise un préfixe d'accès aux units; ce
préfixe est :0 par défaut (préfixe en cours). On peut donc spécifier
un préfixe particulier de recherche avec cette directive: exemple:
USES TYPES,
(*$U :TML:MYSTUFF:*) HandyRoutines;
Notez que si les fichiers '.P.O' ne peuvent être trouvés avec la
direcive de compilation ($U*), TML essaira de les trouver en utilisant
le préfixe de recherche indiqué dans le menu Preferences (voir le
chapitre 5). Si un fichier '.P.O' ne peut être trouvé avec aucun des
préfixes, une erreur est retournée.
```LES ERREURS DE FONCTION TOOLBOX:
(*$ToolErrorChk+*) ou (*$ToolErrorChk-*)
valeur par défaut: (*$ToolErrorChk+*)
Cette directive permet à une application de gérer les erreurs
d'appels aux fonctions de la boite à outils. Comme nous l'avons vu au
chapitre 20, TML génère un STA _ToolErr après chaque appel à une
fonction ToolBox. Ainsi, la variable globale _ToolErr contient
toujours le code d'erreur retourné par la dernière fonction appelée.
Une valeur de _ToolErr différente de 0 indique qu'une erreur s'est
produite lors de l'exécution de la dernière fonction ToolBox, et la
valeur de _ToolErr sert à déterminer quel est le type d'erreur
survenue.
Dans la plupart des cas, une application n'a pas besoin de
ramener systématiquement l'erreur après chaque appel à une fonction
ToolBox. Aussi on peut déconnecter cette option afin de produire un
code moins volumineux.
``APPENDIX C: LES UNITS TOOLBOX:
La boite à outils du //GS est constituée d'une importante
collection de routines facilitant la programmation. La boite à outils
implémente la gestion du graphisme via QuickDraw ainsi que la gestion
du bureau (y compris les fenêtres, menus, dialogues, controles...).
Comme on l'a vu au chapitre 8, TML permet d'accéder à la boite à
outils à l'aide de différentes Units. Cet appendix liste de manière
exhaustive les units pré-définies mises à votre disposition.
Vu l'ampleur des fichiers, ceux-ci ne seront pas listés dans la
présente documentation, nous renvoyons le lecteur à son traitement de
texte préféré pour éditer et imprimer les fichier '.P' se trouvant
dans le dossier LIBRARIES de la disquette SOURCE CODE LIBRARY.
``APPENDIX D: AU COEUR DU TML
```LA GESTION MEMOIRE ET LE TML:
L'environnement dans lequel une application va fonctionner peut
être divisée en 4 parties: le code de l'application, les variables
globales, la pile d'exécution et la mémoire disponible. Ces 4
composants de l'application doivent co-exister dans la RAM du GS. La
mémoire du GS est partitionnée en bancs de 64K, et est gérée par le
Memory Manager. Un Apple //GS standard comprend 4 bancs de 64K de RAM
numérotés $00, $01, $E0 et $E1. On peut ajouter des cartes d'extension
RAM entre les bancs $02 et $7F: les autres bancs sont soient réservés
soient non disponibles.
````Le code de l'application:
Une application peut être constituée de un ou plusieurs segments.
Les petits programmes sont souvent constitués d'un seul segment, mais
les très grosses applications sont divisées en plusieurs segments car
chaque segment ne peut excéder 64K. En effet, un segment ne peut
chevaucher deux bancs mémoires.
TML génère un module indépendant pour chaque procédure et
fonction déclarée daans le programme. Chacun de ces modules est
associé à un nom de segment à charger servant à organiser entre eux
les segments lors du linkage. Le nom du segment par défaut est MAIN.
Lorsqu'une application est suffisamment volumineuse pour nécessiter
plusieurs segments, on doit utiliser la directive (*$CSeg segname*)
afin de déclarer le nom du segment associé aux procédures suivantes.
On redéclare le segment par défaut au compilateur avec la directive
(*$CSeg main*).
````Les variables globales:
TML stocke les variables globales dans un segment de données. Par
défaut, les segments de données ont le nom "_global" (_ est un trema).
Le linker utilise les noms des segments de chargement associé avec
chaque segment de données afin de les grouper en segment de
chargement. Les programmes sont en principe constitués d'un seul
segment de données, mais les applications nécessitant une grande
quantité de variables globales sont fractionnés en plusieurs segments
de données. En effet, chaque segment de données ne peut excéder la
taille d'un banc mémoire: soit 64K.
Lorsqu'une application nécessite plusieurs bancs de données, on
doit utiliser la directive (*$DSeg segname*) afin d'indiquer au
compilateur qu'on souhaite allouer un autre segment pour les variables
suivantes. On peut redonner le nom du segment principal au compilateur
avec la directive ($DSeg _global*). (_ est un trema)
Lors de l'exécution du code d'initialisation généré par TML, le
registre du banc de données du 65816 (le DBR) est positionné pour
pointer sur sur le banc de mémoire contenant les variables globales
déclarées dans le segment _global (_ est un trema). Pour cela, les
références aux variables globales du segment _global peuvent utiliser
un adressage absolu (_ est un trema). Les variables globales dans les
autres segments de données sont adressés en mode long absolu (moins
rapide et plus gourmand en mémoire).
````La pile d'exécution:
La pile d'exécution est un bloc mémoire spécial que l'application
utilise pour stocker l'adresse de retour des procédures et fonctions
et pour conserver les paramêtres et les variables locales. Lors de
l'exécution du code d'initialisation de l'application, un bloc de
mémoire est alloué dans le banc $0 (car c'est le seul banc mémoire
dans lequel le registre de pile du 65816 peut fonctionner).
Par défaut, le TML définit une pile de 8K (8096 octets). Si une
application à besoin de plus ou moins de place pour sa pile, vous
devez l'indiquer avec la directive (*$StackSize numbytes*).
La directive (*$StackSize numbytes*) doit se trouver avant le mot
réservé PROGRAM. Par exemple, le code suivant va générer une pile de
10K pour l'application:
(*StackSize 10240*)
PROGRAM MyApp;
...
Les accessoires de bureu n'ont pas de code d'initialisation
allouant et initialisant la pile d'exécution puisqu'ils fonctionnent
dans l'environnement d'une application. Donc, en écrivant vos
applications, asssurez-vous que vous laissez une place mémoire
suffisante dans la pile pour l'utilisation de NDA ou CDA. Et bien sur,
en écrivant un accessoire de bureau, faites en sorte d'utiliser le
moins possible de place dans la pile. Souvenez-vous toujours que la
taille de la pile par défaut est de seulment 8K.
Ni le GS ni TML ne peuvent déterminer la taille de la pile
utilisée par l'application. Si vous avez réservé une place
insuffisante pour la pile d'exécution, des zones mémoires seront
détruites lors de l'exécution de votre application.
````La mémoire disponible:
La mémoire disponible est la mémoire non utilisée par le code de
l'application, ses segments de données et sa pile d'exécution. Cette
mémoire libre est mise à disposition de l'application par le Memory
Manager, à l'aide des routines se trouvant dans l'unit GSIntf.Pas. On
peut également réserver et libérer de la mémoire dans cette zone
disponible avec les procédures New et Dispose.
Chaque application va avoir besoin de réserver au moins un bloc
mémoire dans le banc 0 pour initialiser les outils. Et la plupart des
applications auront besoin de plusieurs pages réservées dans le banc
0. Ces pages sont appelées PAGES ZERO.
```REPRESENTATION DES DONNEES:
Ce chapitre va vous montrer comment chaque type de donnée est
stocké dans la mémoire du GS. Vous noterez que le 65816 stocke chaque
octet d'un mot selon la représentation poids faible-poids fort; ce qui
signifie que les bits les plus signifiants sont dans la zone mémoire
la plus haute. Par exemple:
type essai = packed record
case integer of
0: (int: integer);
1: (highbyte: 0..255;
lowbyte : 0..255);
end;
Cet enregistrement ne donne pas le résultat que l'on pense. Avec
le 65816, en référençant highbyte, on retourne l'octet de poids faible
de l'entier int, et non l'octet de poids fort. Les paragraphes
suivants vont vous expliquer comment Pascal stocke ses types de
données.
Integer: le complément à 2 d'un entier signé dans
l'intervalle -32768/32767 et nécessitant 2 octets de
stockage. Le bit 15 est le bit de signe.
7 0 15 8
I ISI I (S est le bit de signe)
LongInt: le complément à deux d'un entier dans l'intervalle
-2147483648/2147483647 et nécessitant 4 octets de
stockage. Le bit 31 est le bit de signe.
!7 0!15 8!23 16! 24!
Boolean: un type énuméré de (False,True) nécessitant un octet
de stockage, la valeur booléenne étant dans le bit
0. Un octet de stockage est utilisé dans un packed
array ou un record.
!7 0!15 8!
Char: type énuméré de caractères ASCII ayant 256 valeurs
possibles. La valeur du caractère nécessite é octets
de stockage, la valeur étant dans l'octet de poids
fort (bits 7-0). Un octet de stockage est utilisé
dans les packed array ou les record.
!7 0!15 8!
Enumeration: un octet non signé ou un entier sur deux octets. Si
le type d'énumération contient moins de 128
constantes, la première valeur du type occupe un
seul octet de stockage si elle est employée dans un
packed array ou un record; autrement elle occupe
deux octets.
!7 0!
<= 128 énumérations
!7 0!15 8! > 128 énumérations
Subrange: un octet signé, un mot ou un mot long. si
l'intervalle est dans -128/127, un mot est employé
dans les structures non packées ou les variables
simples; mais dans un packed array ou un record, un
seul octet est utilisé pour représenter le subrange.
Si l'intervalle est dans -32768/32767, on utilise un
mot; autrement un mot long est employé pour la
représentation.
!7 0! -128..127
!7 0!15 8!
-32768..32767
!7 0!15 8!23 16!31 24! les autres
Single: un nombre réel sur 32 bits représenté en format
simple précision IEE, implémenté en type SANE
Single.
31 30 23!22 0
!S! exposant ! signifiant !
Double: un nombre réel sur 64 bits représenté en format
double précision IEE, implémenté en type SANE
Double.
63 62 52 51 0
!S! exposant ! signifiant !
Real/Extended: un nombre réel sur 80 bits représenté en format
étendu standard IEE. Tous deux sont implémentés en
type SANE Extended.
79 78 64 63 0
!S! exposant ! signifiant !
String[n]: une chaine pascal de n+1 octets de long. Cette
chaine est constituée d'un octet de longueur
(longueur de la chine, non compris cet octet) suivi
des octets contenant les caractères ASCII.
octet 1 2 3 ... n+1
!long ! ! ! ... ! !
Pointers: une adresse mémoire sur 24 bits, occupant 4 octets
de stockage. Seuls 3 octets servent à stocker une
adresse sur 24 bits, aussi les bits 31-24 sont
toujours à 0. Le pointeur NIL est représenté par la
valeur zéro sur 32 bits.
!7 0!15 8!23 16!31 24!
Sets: Séquence d'octets jusqu'à un maximum de 32 octets ou
256 bits représentant la grandeur du type de base.
Le nombre d'octets utilisés est le nombre minimum
utilisé pour représenter cette grandeur. La valeur
ordinale du type de base est représentée par un seul
bit. Si la valeur ordinale fait partie d'un
ensemble, alors son bit est à 1, autrement il est à
0. Si les valeurs ordinales du type de base sont
dans l'intervalle 0..15, alors deux octets
représentent l'ensemble. Si les valeurs ordinales du
type de base sont dans l'intervalle 0..31,alors 4
octets le représentent, etc...
Files: une structure de données sur 22 octets, utilisée de
manière interne par TML. En plus de la variable
fichier, le fichier ouvert associé avec un disque
externe a un buffer d'accès alloué dans la mémoire
libre pour la gestion GS/OS; de plus un fichier
texte a un buffer de 256 octets.
Arrays-Records: les composants d'un tableau non compacté et de
records sont alloués consécutivement comme défini
plus haut. Les tableaux sont stockés ligne par
ligne. C'est à dire que le dernier indice est celui
qui augmente le premier. Les composants des
enregistrements sont alloués dans l'ordre de leur
apparition dans la déclaration.
L'implémentation de TML effectue un compactage des
données uniquement au niveau de l'octet, le
compactage au niveau des bits n'est pas possible. Un
type de données est représenté par un octet dans les
enregistrements compactés si et seulement si le
nombre de bits nécessaires pour stocker toutes les
valeurs du type est inférieur ou égal à 8 bits. Par
exemple, le type standard Char ou boolean nécessite
moins de 8 bits pour représenter toutes leurs
valeurs, cependant dans un enregistrement compacté,
char ou boolean sont représentés sur un octet;
autrement ils utilisent un mot.
```LES CONVENTIONS D'APPEL:
````Appeler un sous programme:
TML passe ses paramêtres en utilisant la pile lors des appels à
des sous-programmes. Avant d'appeler une procédure ou une fonction,
les paramêtres sont poussés sur la pile dans le mème ordre que leur
déclaration. Si une fonction est appelée, le stockage du résultat est
alloué sur la pile avant d'empiler les paramêtres. Lorsque l'appel est
terminé, le controle est repassé au programme principal avec les
paramêtres éventuels dépilés, mais le résultat de la fonction (si
c'est une fonction) est laissé sur la pile. Le programme doit dépiler
ce résultat lorsqu'il l'a utilisé.
Voici un exemple d'appel à une procédure:
lda pppp ; empiler le 1er paramêtre
pha
...
lda pppp ; empiler dernier paramêtre
pha
jsl >Aproc ; appel de la procédure
; paramêtres otés de la pile
Voici un exemple d'appel à une fonction:
pha ; réserver de la place pour
résultat
lda pppp ; empiler le 1er paramêtre
pha
...
lda pppp ; empiler dernier paramêtre
pha
jsl >Afunc ; appel de la fonction
; paramêtres otés de la pile
pla ; dépiler le résultat et
; le mettre dans l'accumulateur
Les sous-programmes sont toujours appelés en mode natif 65816
(accumulateur et registres d'index sur 16 bits). Cependant, si le
processeur n'est pas en mode natif avant l'appel, il est forcé au mode
natif avant que l'appel ne soit effectué. Par exemple, si
l'accumulateur est en 8 bits et les registres d'index en 16 bits, le
code suivant est généré:
; accumulateur en 8 bits
rep #$20 ; accumulateur en 16 bits
LONGA ON
jsl >ASubprog
Si le sous-programme appelé est déclaré à un niveau autre que le
niveau global (c'est à dire ailleurs que dans le bloc principal ou
dans une unit), alors un lien statique est poussé sur la pile après
que les paramêtres aient été empilés. Ce lien statique sert à adresser
les variables locales dans les piles imbriquées. Du fait de ce lien
statique, l'adresse d'un sous-programme imbriqué ne doit jamais être
passée à une routine de la boite à outils comme définition de
procédure puisque ce n'est pas la convention utilisée par les outils.
````Les variables paramêtres:
Les variables paramêtres (VAR) sont toujours passées par
référence au paramêtre de format, c'est à dire comme une pointeur sur
la zone de stockage occupée par le paramêtre actuel. Le pointeur est
passé sous forme de valeur sur 32 bits (4 octets)). Le mot de poids
fort est empilé avant le mot de poids faible.
Dans l'exemple suivant, le passage de la variable globale GlobVar
en tant que paramêtre VAR se fait par l'adressage absolu:
pea GlobVar|-16 ; empiler le mot de poids fort
pea GlobVar ; empiler ensuite mot de poids
faible
````Les valeurs paramêtres:
Les valeurs paramêtres sont passées avec leurs valeurs sur la
pile ou par référence, selon la taille de la valeur. Si la taille de
la valeur du paramêtre occupe 4 octets ou moins, alors la valeur est
passée par la pile. Si la taille de cette valeur est supérieur à 4
octets, alors un pointeur 32 bits sur la valeur est empilé. La
procédure ou fonction appelée copie alors la valeur en stockage local
de manière à ce que toute modification de la valeur du paramêtre
formel n'affecte pas la valeur du paramêtre actuel.
````Les paramêtres statiques:
Les paramêtres statiques sont empilés de la mème manière que les
valeurs paramêtres. La différence entre les paramêtres par valeur et
les paramêtres statiques est que si la taille du paramêtre actuel est
plus grande que 4 octets, la procédure ou fonction appelée NE RECOPIE
PAS la valeur dans un stockage local pour le paramêtre formel. Ainsi,
il est illégal de donner une nouvelle valeur au paramêtre statique
formel puisqu'il changera la valeur du paramêtre actuel.
Les paramêtres statiques ont été introduits dans TML 2 afin de
conserver la taille de la pile d'exécution pour le stockage des
paramêtres formels ainsi que pour accélérer le traitement des
informations.
Attention, TML ne vérifie pas si une nouvelle valeur a été
assignée à un paramêtre statique. C'est au programmeur de s'assurer de
l'emploi correct des paramêtres statiques.
````Les résultats de fonctions:
Le stockage des résultats de fonctions est réservé sur la pile
par le sous-programme appelant avant l'empilage des paramêtres. Si le
résultat de la fonction est de type Integer, LongInt, char, boolean,
subrange, énumération, pointeur ou single real, alors 2 ou 4 octets de
stockage sont alloués. Si le type du résultat ne nécessite qu'un
octet, 2 octets sont alloués et la valeur est stockée dans l'adresse
la plus basse.
Si le type du résultat est double, Comp, Extended, tableau,
chaine ou record, alors le sous-programme appelant alloue un espace
temporaire dans ses piles pour le résultat, et il empile un pointeur
de 4 octets sur la zone temporaire. Le sous-programme appelant dépile
le pointeur lorsque la fonction retourne le résultat et la zone
temporaire de stockage est libérée s'il n'y a aucune référence à la
valeur.
````Code d'entrée-sortie:
Chaque procédure et fonction Pascal commence et finit par un code
d'entrée et de sortie standards.
Voici le code standard d'entrée:
phd ; sauver précédent pointeur de pile
tsc
sec
sbc #xx
tcd ; créer nouveau pointeur de pile
clc
adc #yy
tcs ; allouer stockage local
D'abord, le registre de page directe en cours est sauvé. Le
registre de page directe est utilisé comme pointeur. Le pointeur sauvé
est appelé lien dynamique et sert à remettre les choses telles
quelles.
Après avoir sauvé le pointeur de pile, xx octets sont otés du
pointeur de pile courant afin de créer le nouveau pointeur. XX est
calculé de manière que le premier mot de stockage dans la pile (c'est
à dire le résultat de la fonction ou le premier paramêtre) est à un
multiple de 254 dans la page directe. Grace à ce choix, les paramêtres
et la plupart des variables locales sont adressées par l'adressage en
page directe.
Lorsque le pointeur de pile est défini, yy octets sont ajoutés à
cette valeur pour allouer l'espace nécessaire au stockage des
variables locales, des valeurs des paramêtres copiés localement et
pour les besoins du compilateur.
Aucun registre n'est sauvé et on suppose que le processeur est en
mode natif.
Voici le code de sortie standard:
tdc
clc
adc #xx
tcs ; désallouer le stockage local
pld ; récupérer pointeur de pile
lda 2,S
sta mm,S
lda 1,S ; adresse de retour mise sous
sta mm-1,S ; les paramêtres
tsc
clc
adc #mm-2 ; désallouer les paramêtres
tcs
rtl
Le stockage local est d'abord désalloué en ajoutant la valeur xx
au pointeur de pile. Puis on récupère le pointeur de pile précédent
grace à l'instruction pld. Ensuite les paramêtres sont "otés" en
déplaçant l'adresse de retour juste au dessus du premier paramêtre et
en repositionnant le pointeur de pile sur cette nouvelle adresse.
Finalement, RTL est exécuté pour revenir au sous-programme d'appel.
Remarquez que si une procédure ou fonction n'a pas de paramêtres,
le code de sortie est alors:
tdc
clc
adc #xx
tcs ; désallouer le stockage local
pld ; récupérer le pointeur de pile
rtl
``APPENDIX E: COMPARAISON DE TML 2 ET TML 1
TML Pascal II implémente de nouvelles fonctions par rapport à
l'ancienne version TML I. Dans ce chapitre nous allons voir les
différences entre les deux versions afin que les anciens utilisateurs
de TML I puissent facilement s'adapter à ce nouveau produit.
Dans ce qui suit, les différences entre les version sont
présentées chapitre par chapitre.
```CHAPITRE 1: DECOUVRIR TML
La différence la plus importante entre TML I et TML II est la
spécificité de TML II pour le GS/OS 5.0. Les applications développées
avec TML II ne peuvent pas fonctionner avec un système antérieur à la
version 5.0 ni avec les versions de Prodos 16.
Cette limitation est due en grande partie à l'implémentation du
Resource Manager dans TML II, outil non disponible dans les versions
antérieures à 5.0 du système.
```CHAPITRE 2: UTILISER L'ENVIRONNEMENT DESKTOP
L'éditeur du TML II permet l'ouverture d'un nombre illimité de
fenêtres à l'écran. De plus, dans chaque fenêtre, on peut utiliser une
fonte et un style particulier ainsi qu'une tabulation personnalisée.
Enfin, l'éditeur acccepte désormais la commande UNDO.
Enfin, l'environnement d'édition permet de créer une fenêtre
d'édition pour les fichiers resources.
```CHAPITRE 3: CREER DES PROGRAMMES
La convention de dénomination des fichiers a changé avec TML II.
Les fichiers sources doivent se terminer par le suffixe '.p' au lieu
de '.pas'.
Le nom des fichiers compilés Units est également modifié: au lieu
de '.usym', le suffixe est désormais '.o' ajouté par le compilateur,
ce qui donne un suffixe total de '.p.o'. Ces conventions permettent au
compilateur de retrouver aisément les modules dont il a besoin.
L'item menu RESOURCES a été ajouté dans le menu COMPILE afin de
pouvoir spécifier quelles sont les resources à compiler dans
l'application finale.
```CHAPITRE 4: LES RESOURCES
Les resources sont une nouvelle fonction du TML II. Les
programmes écrits avec TML I devraient être convertis sans trop tarder
en TML IIafin de tirer partie des fonctionnalités du Resource Manager.
```CHAPITRE 7: APPLICATIONS GRAPHIQUES
Le TML I implémentait les applications 'plain vanilla'. Ceci a
été remplacé par les applications 'textbook graphics'. A l'origine, un
programme pouvait spécifier les paramêtres (Input, Output) en en-tète
pour indiquer que l'on voulait travailler en environnement Plain
Vanilla. Exemple:
Program Test(Input, Output);
Plain Vanilla connecte l'écran graphique en mode 640 et crée une
fenêtre intitulée 'TML PASCAL'. Ceci permet de développer facilement
des applications graphiques.
TML Pascal II possède une nouvelle procédure appelée 'Graphics'.
Cette procédure accepte un paramêtre de définition du mode graphique:
320 ou 640; et au lieu d'ouvrir une fenêtre à l'écran, elle permet de
travailler sur l'écran total.
```CHAPITRE 8: APPLICATIONS DESKTOP
Les applications peuvent désormais utiliser les resources pour
créer des menus, fenêtres, dialogues... Les resources sont crées à
partir du TML Resource Editor. On spécifie les resources à compiler
avec le programme principal avec la fonction Resources du menu
Compile.
```CHAPITRE 9: LES NDA
Le code source d'un NDA peut désormais être écrit sous forme de
Unit. Les NDA n'ayant pas de programme MAIN, il n'est pas nécessaire
d'employer la structure des programmes.
```CHAPITRE 10: LES CDA
Le code source d'un CDA peut désormais être écrit sous forme de
Unit. Les CDA n'ayant pas de programme MAIN, il n'est pas nécessaire
d'employer la structure des programmes.
```CHAPITRE 11: LES MOTS RESERVES
Le TML II définit 3 constantes réelles afin de faciliter
l'écriture d'applications numériques. Ces nombres sont Inf (infini),
NaN (not a number) et PI.
```CHAPITRE 19: ENTREES-SORTIES
Le TML II implémente désormais la procédure OPEN pour ouvrir un
fichier en écriture/lecture aléatoire.
Le TML II est compatible GS/OS. Ainsi les noms de fichiers
doivent respecter la syntaxe Prodos 16 ou GS/OS. De plus, les noms de
devices peuvent être utilisés. Par exemple, le nom du device
imprimante est'.PRINTER' au lieu de 'PRINTER'. A noter que le nom
'.PRINTER' doit être écrit en majuscules.
```CHAPITRE 20: PROCEDURES ET FONCTIONS STANDARDS
La procédure GRAPHICS est nouvelle dans TML II.
Les fonctions et procédures standard suivantes ont été renommées
dans TML II afin de se conformer aux spécifications Apple:
nom en TML I nom en TML II
BitAnd BAND
BitOr BOR
BitXor BXOR
BitNot BNOT
BitSL BSL
BitSR BSR
BitRotl BROTL
BitRotr BROTR
HiWord HiWrd
LoWord LoWrd
Dans TML II, HiWord et LoWord sont réservés pour les fonctions de
IntMath.p.
La variable globale prédéfinie retournant un code d'erreur
s'appelle désormais '_ToolErr', mais l'ancien nom '_ToolErrorNum' est
également accepté.
```ANNEXE B: DIRECTIVES DE COMPILATION
Les directives suivantes ont été renommées:
$DeskAcces renommé en $NDA
$P $U
$XrefVar $J
Les directives suivantes ont été ajoutées depuis la version 1 (et
étaient donc déja disponibles dans la version 1.5).
$CDA
$DefProc
```ANNEXE C: LES INTERFACES
Les interfaces de la boite à outil ont été largement modifiées
afin d'être compatible avec le système 5.0. Certaines interfaces ont
été rajoutées.
```ANNEXE D: AU COEUR DU TML
Le type Boolean, Enumeration et les petits ensembles d'entiers
sont représentés sur 2 octets au lieu d'un. Cependant, lorsque ces
types sont des Packed Record ou Array, ils n'utilisent plus qu'un
octet en mémoire.
| |