Définition du langage
Cette page définit les fonctionnalités du langage d'ATARI Pascal étant communes à chaque implémentation du compilateur. Nous supposons ici que vous connaissez le «Rapport» de Jenson et Wirth et/ou le projet de norme ISO (DPS/7185). Les fonctionnalités d'ATARI Pascal différant de celles de la norme ISO et du "Rapport" de Jenson et Wirth sont décrites par section. Dans chaque section, la syntaxe BNF (Backus Normal Form) est fournie à titre de référence.
Résumé du langage ATARI Pascal
Les fonctionnalités de ISO Pascal incluent les types de données REAL, INTEGER, CHAR, BOOLEAN, multidimensionnel ARRAY, RECORD défini par l'utilisateur, POINTER, variables de fichier, TYPE et CONST définis par l'utilisateur et SET (implémenté dans la version avec un type de base de 256 éléments d'un octet), ainsi que les types énumérés et types de sous-intervalles.
ISO Pascal comprend également PROCEDURE, FUNCTION et PROGRAM. Passer des procédures et des fonctions en tant que paramètres à une routine Pascal fait partie de la norme ISO, ainsi que les tableaux conformes. Des tableaux du même type d'index et du même type d'élément mais de tailles différentes peuvent être transmis à la même procédure. Les paramètres externes avec l'instruction PROGRAM sont pris en charge au niveau de la syntaxe.
Les fichiers de types et TEXT sont pris en charge comme défini dans la norme à l'aide des routines Pascal RESET, REWRITE, GET, PUT, READ, WRITE, READLN et WRITELN. Les fichiers d'entrées/sorties par défaut INPUT et OUTPUT sont définis.
Toutes les instructions ISO sont prises en charge, y compris les boucles WITH, REPEAT...UNTIL, CASE, WHILE, FOR, IF..THEN..ELSE et GOTO.
PACK et UNPACK sont pris en charge, mais n'affectent pas le résultat du programme (les structures de données sont toujours compressées au niveau des octets). NEW et DISPOSE sont implémentés ; ils allouent et libèrent de l'espace de mémoire de tas.
La compilation modulaire est une extension du compilateur ATARI. Les variables et routines peuvent être rendues publiques et/ou privées et peuvent être appelées depuis n'importe quel autre module ou depuis le programme principal.
Les types de données étendus STRING, BYTE et WORD sont implémentés dans le compilateur ATARI Pascal. Le type STRING comprend un octet de longueur suivi du nombre maximum d'octets possibles. Des routines sont fournies pour insérer un caractère ou une chaîne de caractères (INSERT), supprimer une chaîne de caractères (DELETE), POS pour trouver la position d'un caractère dans une chaîne de caractères, COPY pour copier une partie d'une chaîne de caractères dans une autre et CONCAT concaténer deux ou plusieurs chaînes de caractères et/ou caractères ensemble. BYTE est un élément de données d'un octet pour représenter les nombres de 0 à 255. WORD est de deux octets pour un microprocesseur 8 bits.
Des procédures supplémentaires pour gérer les fichiers sur disquette sont mises en oeuvre. Un fichier sur disquette est associé à un fichier interne et peut être fermé ou supprimé.
Les bits et octets manipulés sont effectués à l'aide de routines pour faire des tests (TEST), fixé, effacé, des décalages vers la droite (SHR) et la gauche (SHL), renvoyer HI ou LOW d'une variable et échanger les octets haut et bas d'une variable (SWAP).
Diverses routines pour accéder aux éléments d'un programme consistent à renvoyer l'adresse d'une variable ou d'une routine, à renvoyer la taille d'une variable ou d'un type, à déplacer un nombre donné d'octets d'un emplacement mémoire à un autre et à remplir un élément de données avec un certain caractère. De plus, la quantité d'espace de mémoire de tas disponible à un moment donné est accessible. La collecte des déchets sur la mémoire de tas est prise en charge.
- Des opérateurs logiques pour les non-booléens sont implémentés.
- Les nombres littéraux hexadécimal peuvent être utilisés avec le signe dollar ($).
- Les fichiers d'inclusion sont pris en charge.
- Une clause ELSE sur l'instruction CASE est fournie.
Le chaînage de programmes est pris en charge. Le chaînage est tel que le code d'un programme est totalement remplacé par le code du programme suivant, mais l'espace de mémoire de tas peut être conservé sur une CHAIN.
Notation, terminologie et vocabulaire
<lettre> ::= A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | @ <chffre> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | (seulement permit avec les nombres hexadécimales) <symbole spécial> ::= (mots réservés) + | - | * | / | = | <> | < | > | <= | >= | ( | ) | [ | ] | ^ | := | . | , | ; | : | ' | (les éléments suivants sont des ajouts ou des substitutions :) ( . | . ) | \ | ? | ! | | | $ | & (. est un synonyme de [ .) est un synonyme de ] ? et \, sont synonymes |, et |, sont synonymes & |
Extensions
Le symbole «@» est une lettre légale en plus de celles listées dans le «Rapport». Ce symbole a été ajouté car les routines de la bibliothèque d'exécution sont écrites en utilisant ce caractère spécial comme première lettre de leur nom. En ajoutant "@", les conflits avec les noms d'utilisateurs sont évités, mais les utilisateurs sont autorisés à appeler ces routines.
Un commentaire commençant par "(*" doit se terminer par "*)".
<commentaire> ::= (* <n'importe quel caractères> *) |
Identificateurs, nombres et chaînes de caractères
<identificateur> ::= <lettre> {<lettre ou chiffre ou soulignement >} <lettre ou chiffre> ::= <lettre> | <chiffre> | _ <séquence de chiffre> ::= <chiffre> {<chiffre>} <entier non signée> ::= $ <séquence de chiffre> | <séquence de chiffre> <réel non-signée> ::= <entier non-signée> . <séquence de chiffre> | <entier non-signée> . <séquence de chiffre> E <facteur d'échelle> | <entier non-signée> E <facteur d'échelle> <nombre non-signée> ::= <entier non-signé> | <réel non-signée> <facteur d'échelle> ::= <entier non-signé> | <signe><entier non-signée> <signe> ::= + | - <chaîne de caractères> ::= '<caractère> {<caractère>}' | '' |
Tous les identificateurs comportent huit caractères. Les identifiants externes comportent six ou sept caractères selon l'utilisation. Le caractère de soulignement (_) est légal entre les lettres et les chiffres dans un identifiant et est ignoré par le compilateur (c'est-à-dire que A_B est équivalent à AB). Les identifiants peuvent commencer par un «@». Pour permettre la déclaration de routines d'exécution externes dans un programme Pascal. Il est généralement conseillé aux utilisateurs d'éviter le caractère «@» afin d'éliminer tout risque de conflit avec les noms de routine d'exécution.
Les nombres peuvent être hexadécimaux ou décimaux. Placer un "$" devant un nombre entier le fait être interprété comme un nombre hexadécimal par le compilateur. Le symbole <chiffre> comprend désormais : "A", "B", "C", "D", "E" et "F". Ceux-ci peuvent être en majuscules ou en minuscules.
Définitions de constante
<identificateur de constante> ::= <identificateur> <constante> ::= <nombre non-signé> | <signe><nombre signé> | <identificateur constant> | <signe><identificateur constante> | <chaîne de caractères> <définition de constante> ::= <identificateur> = <constante> |
En plus de toutes les déclarations de constantes disponibles en Pascal standard, ATARI Pascal prend en charge les déclarations d'une constante de chaîne de caractères nulle.
Exemple :
- NullStr='';
Définitions de type de données
<type> ::= <type simple> | <type structuré> | <type de pointeur> <définition de type> ::= <identificateur> = <type> |
Types simple
<type simple> ::= <type scalaire> | <type d'intervalle> | <identificateur de type> <identificateur de type> ::= <identificateur> |
Types scalaire
<type scalaire> ::= (<identificateur {,<identificateur>}) |
Types standard
Les types suivants sont standard dans ATARI Pascal :
- INTEGER
- REAL
- BOOLEAN
- CHAR
- BYTE
- WORD
- STRING
Trois types standards supplémentaires existent dans ATARI Pascal :
Nom | Description |
---|---|
STRING | Packed Array[0..n] of Char L'octet 0 est un octet de longueur dynamique Les octets de 1 à n sont les caractères |
BYTE | Sous-intervalle de 0..255 avec attribut spécial étant également compatible avec le type CHAR. |
WORD | Mot machine natif non signé |
Types de sous-intervalle
<type de sous-intervalle> ::= <constante>..<constante> |
Types structuré
<type structuré> ::= <type structuré décompacté> | PACKED <type structuré décompacté> <type structuré décompacté> ::= <type de tableau> | <type d'enregistrement> | <type d'ensemble> | <type de fichier> |
Le mot réservé PACKED est détecté et géré par le compilateur ATARI Pascal comme suit :
- Toutes les structures sont compressées au niveau BYTE même si le mot réservé PACKED n'est pas trouvé.
Types de tableau
<type de tableau> ::= <tableau normal> | <tableau de chaîne de caractères> <tableau de chaîne de caractères> ::= STRING <longueur maximal> <longueur maximal> ::= [<intconst> ] | <vide> <intconst> ::= [<entier non-signé> ] | <identificateur d'entier constant> <tableau normal> ::= ARRAY[(<type d'index> {,<type d'index})] OF <type de composante> <type d'index> ::= <type simple> <type de composante> ::= <type> |
Les variables de type STRING ont une longueur par défaut de 81 octets (80 caractères de données). Une longueur différente peut être spécifiée entre crochets après le mot STRING. La longueur doit être une constante (littérale ou déclarée, par exemple STRING[5] ou STRING[xyz]) (où xyz est une constante (xyz=10)). Il représente la longueur de la partie DATA (c'est-à-dire qu'un octet supplémentaire est effectivement alloué pour la longueur).
Types d'enregistrement
<type d'enregistrement> ::= RECORD <liste de champs> END <liste de champs> ::= <partie fixe> | <partie fixe> , <partie variant> | <partie variant> <partie fixe> ::= <section d'enregistrement> {;<section d'enregistrement>} <section d'enregistrement> ::= <identificateur de champ> {,<identificateur de champ>} : <type> | <vide> <partie variante> ::= CASE <champ de balise> <identificateur de type> OF <variant> {;<variant>} <variant> ::= <liste d'étiquette de CASE> : (<liste de champs>) | <vide> <liste d'étiquette de CASE> ::= <étiquette de CASE> {,<étiquette de CASE>} <étiquette de CASE> ::= <constante> <champ de balise> ::= <identificateur> : | <vide> |
Types d'ensemble
<type d'ensemble> ::= SET OF <type de base> <type de base> ::= <simple type> |
L'intervalle maximale d'un type de base est de 0 à 255. Par exemple, un ensemble de [0..10000] n'est pas légal. L'ensemble de CHAR ou l'ensemble de 0..255 est légal mais l'ensemble de 0..256 ne l'est pas.
Types de fichier
<type de fichier> ::= FILE {OF <type>} |
Les fichiers non typés sont autorisés. Ils sont utilisés pour chaîné (CHAIN) et sont également utilisés avec les procédures BLOCKREAD et BLOCKWRITE. Soyez extrêmement prudent lorsque vous utilisez des fichiers non typés.
Lorsque vous souhaitez lire un fichier de caractères ASCII et utiliser des conversions implicites pour des nombres entiers et réels, utilisez le type prédéfini TEXT. TEXT n'est PAS le même que FILE OF CHAR. Il a une conversion implicite dans les appels de procédure READ et WRITE et peut également être utilisé avec READLN et WRITELN. Un fichier de type TEXT se déclare de la manière suivante :
- VAR F:TEXT;
La syntaxe incorrect pour déclarer un fichier TEXT est :
- VAR F:FILE OF TEXT;
Types de pointeur
<type de pointeur> ::= ^<identificateurf de type> |
Les types de pointeurs sont identiques à la norme, sauf qu'une vérification de type faible existe lorsque la fonctionnalité de vérification de type assouplie du compilateur est activée (valeur par défaut). Dans ce cas, les pointeurs et WORD utilisés comme pointeurs sont compatibles dans tous les cas.
Compatibilité des types et des affectations
La question Pascal standard la plus courante concerne les messages d'erreur de conflit de types provenant du compilateur. Les types doivent être identiques si la variable est passée à un paramètre VAR. Les types doivent être compatibles pour les expressions et les instructions d'affectation. Pour comprendre la différence entre les types compatibles et identiques, considérez les types comme des pointeurs vers les types au moment de la compilation et les types identiques, considérez les types comme des pointeurs vers les enregistrements au moment de la compilation. Si vous déclarez un type (tel que T=ARRAY[1..10] OF INTEGER), alors tout ce qui est déclaré comme type T pointe réellement vers l'enregistrement décrivant le type T. Si, par contre, vous déclarez deux variables comme suit :
- VAR
- A1:ARRAY[1..10] OF INTEGER;
- A2:ARRAY[1..10] OF INTEGER;
ils ne sont pas identiques. Le compilateur a créé un nouvel enregistrement pour chaque type et donc A1 et A2 ne pointent pas vers le même enregistrement en mémoire au moment de la compilation. La règle générale est que si vous ne parvenez pas à revenir à une définition de type, alors les types ne sont pas identiques.
CHR, ORD et WRD sont des opérateurs de conversion de type ne générant aucun code mais indiquent au compilateur que l'élément de données de 8 bits suivant doit être considéré comme de type CHAR, INTEGER ou WORD respectivement.
Ces opérateurs peuvent être utilisés dans des expressions et avec des paramètres à l'exception des paramètres VAR.
Vous trouverez ci-dessous une section du projet de norme ISO (DPS-7185) disponible auprès de l'Americans Standards Institute. La définition standard ISO des types compatibles est la suivante :
- Les types T1 et T2 doivent être conçus de manière compatible si l'une des quatre affirmations suivantes est vraie :
- (a) T1 et T2 sont du même type.
- (b) T1 est une sous-intervalle de T2 ou T2 est une sous-intervalle de T1, ou T1 et T2 sont des sous-intervalle du même type d'hôte.
- (c) T1 et T2 sont désignés emballés ou ni T1 ni T2 ne sont désignés emballés.
- (d) T1 et T2 sont des types de chaînes de caractères* avec le même nombre de composantes.
- ... Compatibilité des missions. Une valeur de type T2 doit être désignée comme étant compatible avec une affectation de type T1 si l'une des cinq affirmations suivantes est vraie :
- (a) T1 et T2 sont du même type, c'est-à-dire ni un type fichier ni un type structuré avec une composante de fichier (cette règle doit être interprétée de manière récursive).
- (b) T1 est le type réel et T2 est le type entier.
- (c) T1 et T2 sont des types ordinaux** compatibles et la valeur du type T2 est l'intervalle fermé spécifié par le type T1.
- (d) T1 et T2 sont des types d'ensemble compatibles et tous les membres de la valeur de type T2 sont dans l'intervalle fermé spécifié par le type de base de T1.
- (e) T1 et T2 sont des types de chaîne de caractères compatibles.
- Partout où la règle de compatibilité-affectation est utilisée :
- (a) Ce sera une erreur si T1 et T2 sont des types ordinaux compatibles** et que la valeur du type T2 n'est pas dans l'intervalle fermé spécifié par le type T1.
- (b) Ce sera une erreur si T1 et T2 sont des types d'ensemble compatibles et que tout membre de la valeur du type T2 n'est pas dans l'intervalle fermé spécifié par le type de base du type T1.
- * Les types de chaînes en ISO Pascals sont des tableaux de caractères.
- ** Les types ordinaux sont nommés sous-gammes de nombres ou d'énumérations.
Déclaration et dénotation des variables
<variable> ::= <var> | <var externe> | <var absolue> | <var externe> ::= EXTERNAL <var> <var absolue> ::= ABSOLUTE [<constante>] <var> <var> ::= <variable entière> | <variable de composante> | <variable de référence> |
Les variables ABSOLUTE peuvent être déclarées si vous connaissez l'adresse au moment de la compilation. Vous déclarez les variables comme étant absolues en utilisant une syntaxe spéciale dans une déclaration VAR. Les variables ABSOLUTE ne se voient attribuer aucun espace dans votre segment de données par le compilateur et vous êtes responsable de vous assurer qu'aucune variable allouée par le compilateur n'entre en conflit avec les variables absolues. REMARQUE : les variables de chaîne de caractères peuvent ne pas exister à l'emplacement <= $100. Ceci est fait pour que les routines d'exécution puissent détecter la différence entre une adresse de chaîne de caractères et un caractère en haut de la pile. Les caractères ont l'octet de poids fort 0 lorsqu'ils sont présents sur la pile. Après les deux points (:) et avant le type de la ou des variables, vous placez le mot clef ABSOLUTE suivi de l'adresse de la variable entre parenthèses ([..]).
Exemple :
- I: ABSOLUTE [$800] INTEGER;
- SCREEN: ABSOLUTE [$C000] ARRAY[0..15] OF ARRAY[0..63] OF CHAR;
Variables entières
<variable entières> ::= <identificateur de variable> <identificateur de variable> ::= <identificateur> |
Variables de composantes
<variable de composante> ::= <variable indexé> | <désignateur de champ> | <tampon de fichier> |
Variables indexé
<variable indexé> ::= <variable de tableau> [<expression> {,<expression>}] <variable de tableau> ::= <variable> |
Les variables STRING doivent être traitées comme un tableau PACKED de CHAR à des fins d'index. L'intervalle valide est de 0..maxlength, où maxlength est 80 pour une longueur par défaut.
Désignateurs de champs
<désignateur de champ> ::= <variable d'enregistrement> . <identificateur de champ> <variable d'enregistrement> ::= <variable> <identificateur de champ> ::= <identificateur> |
Tampons de fichier
<tampon de fichier> ::= <variable de fichier>^ <variable de fichier> ::= <variable>^ |
Variables référencé
<variable référencé> ::= <variable de pointeur>^ <variable de pointeur> ::= <variable> |
Expressions
<constante non-signé> ::= <nombre non-signé> | ::= <chaîne de caractères> | ::= NIL | ::= <identificateur de constante> <facteur> ::= <variable> | ::= <constante non-signé> | ::= <désignateur de fonction> | ::= ( <expression> ) | ::= <logique NOT opérateur> <facteur> | ::= <ensemble> <ensemble> ::= [ <liste d'éléments> ] <liste d'éléments> ::=<élément> {,<élément>} | <vide> <élément> ::= <expression> | <expression>..<expression> <terme> ::= <facteur> <opérateur de multiplicateur> <facteur> <expression simple> ::= <terme> | <expression simple> <terme> <expression> ::= <expression simple> | <expression simple> <opérateur relationnel > <expression simple> |
Une catégorie supplémentaire d'opérateurs sur les variables 16 bits sont &, ! (également |), (également \ et ?) désignant respectivement AND, OR et un complément NOT. Ceux-ci ont la même priorité que leurs opérateurs booléens équivalents et acceptent tout type d'opérande d'une taille <= 2 octets.
Opérateurs
Opérateur NOT
<opérateur logique NOT> ::= NOT | \ | ? |
\ et ? ne sont pas des opérateurs pour les opérateurs non booléens.
Opérateur de multiplication
<opérateur de multiplication> ::= * | / | DIV | MOD | AND | & |
& est un opérateur AND sur les opérateurs non booléens.
Opérateur d'addition
<opérateur d'addition> ::= + | - | OR | | | ! |
! (synonyme |) est un opérateur OR sur les opérateurs non booléens.
Opérateurs relationnels
<opérateur relationnel> ::= = | <> | < | <= | >= | IN |
Désignateurs de fonction
<désignateur de fonction> ::= <identificateur de fonction> | <identificateur de fonction>(<paramètre> {<paramètre>}) <identificateur de fonction> ::= <identificateur> |
Instructions
<instruction> ::= <étiquette> | <instruction sans étiquette> | <instruction sans étiquette> <instruction sans étiquette> ::= <simple instruction > | <instruction structuré> <étiquette> ::= <entier non-signé> |
Instructions simple
<simple instruction> ::= <association d'instruction> | <instruction de procédure> | <instruction GOTO> | <instruction vide> <instruction vide> ::= <vide> | |
Affectation d'instructions
<affectation d'instruction> ::= <variable> := <expression> <identificateur de fonction> := <expression> |
À la liste des exceptions à la compatibilité des affectations, ajoutez :
- Les expressions entières peuvent être affectées à des variables de type pointeur. Par exemple :
- TYPE X=RECORD
- (* Declarations de champ *)
- END;
- VAR P : ^X;
- I : INTEGER;
- (* ................. *)
- P := I+1;
- Les expressions de type CHAR peuvent être affectées à des variables de type STRING.
- Des variables de type CHAR et des caractères littéraux peuvent être affectés à des variables de type BYTE.
- Les expressions évaluées au type WORD peuvent être affectées à des variables de pointeur.
- Les expressions évaluées au type INTEGER peuvent être affectées à des variables de type WORD.
Instructions de procédures
<instruction de procédure> ::= <identificateur de procédure>{<paramètre> {,<paramètre>}}) | <identificateur de procédures> <identificateur de procédure>::= <identificateur> <paramètre> ::= <identificateur de procédure> | <identificateur de fonction>| <expression>| <variable> |
Le nombre maximum de paramètres pour une procédure ou une fonction est de cinquante (50).
Instructions GOTO
<Instruction GOTO> ::= goto <étiquette> |
Instructions structurés
<Instruction structuré> ::= <instruction répétitive> | <instruction conditionnelle> | <instruction composé> | <instruction with> |
Instructions composé
<Instruction composé> ::= BEGIN <instruction> {,<instruction>} END |
Instructions conditionnelle
<Instruction conditionnelle> ::= <instruction case>| <instruction if> |
Instructions if
<Instruction if> ::= IF <expression> THEN <instruction> ELSE <instruction> | IF <expression> THEN <instruction> |
Instructions case
<Instruction case> ::= CASE <expression> OF <liste de case> (,<liste de case>) {ELSE <instruction>} END <liste de case> ::= <liste d'étiquette> : <instruction> | <Vide> <liste d'étiquette> ::= <étiquette case> {,<étiquette case>} <étiquette case> ::= <constante scalaire courte et non réelle> |
ATARI Pascal implémente une clause ELSE sur l'instruction CASE. De plus, si l'expression de sélection ne correspond à aucun des sélecteurs de cas, le flux du programme "passera" par l'instruction CASE. La norme indique que cette condition est une erreur.
Exemple :
- CASE CH OF
- 'A': WRITELN('A');
- 'Q': WRITELN('Q');
- ELSE WRITELN('PAS A OU Q');
- END
Instructions à répétition
<instruction répétitive> ::= <instruction repeat> | <instruction while> | <instruction for> |
Instruction While
<instruction while> ::= WHILE <expression> DO <instruction> |
Instruction Repeat
<instruction repeat> ::= REPEAT <instruction> {,<instruction>} UNTIL <expression> |
Instruction For
<instruction for> ::= FOR <ctrlvar> := <liste de for> DO <instruction> <liste de for> ::= <expression> DOWNTO <expression> | <expression> TO <expression> <ctrlvar> ::= <variable> |
Instructions With
<instruction with> ::= WITH <liste de variable d'enregistrement> DO <instruction> <liste de variable d'enregistrement> ::= <variable d'enregistrement> {,<variable d'enregistrement>} |
Notez que la norme ISO diffère du Pascal défini par Jenson et Wirth en ce sens que seules les variables LOCAL sont autorisées comme variables de contrôle de boucle FOR. Cela évite des erreurs de programmation telles que l'utilisation par inadvertance d'une variable GLOBAL comme variable de contrôle FOR lorsqu'elle est imbriquée sur cinq niveaux.
Vous êtes limité à 16 instructions FOR et/ou WITH dans une seule procédure/fonction. Cette limitation permet au compilateur d'attribuer un nombre fixe d'emplacements temporaires (16 mots) dans le segment de données pour la procédure/fonction.
Déclarations de procédure
<déclaration de procédure> ::= EXTERNAL <entête de procédure> | <entête de procédure> <bloc> <bloc> ::= <partie de déclaration d'étiquette> <partie de déclaration de constante> <partie de définition de type> <partie de déclaration de variable> <partie de déclaration de procfunc> <partie d'instruction> <entête de procédure> ::= PROCEDURE <identificateur> <paramlist> | PROCEDURE <identificateur> <paramlist> ::= ( <fparm;> {,<fparm>} ) <fparm> ::= <entête de procédure> | <entête de fonction> | VAR <groupe de paramètres> | <groupe de paramètres> <groupe de paramètres> ::= <identificateur> {,<identificateur>} : <identificateur de type> | <identificateur> {,<identificateur>} : <tableau conforme> <tableau conforme> ::= ARRAY [<indextyp> {;<indxtyp}] OF <conarray2> <conarray2> ::= <identificateur de type> | <tableau conforme> <indxtyp> ::= <identificateur>..<identificateur> : <ordtypid> <ordtypeid> ::= <identificateur de type scalaire> | <identificateur de type de sous-intervalle> <identificateur de type scalaire> ::= <identificateur> <identificateur de type de sous-intervalle> ::= <identificateur> <partie de déclaration d'étiquette> ::= <vide> | LABEL <étiquette>, <étiquette>; <partie de définition de constante> ::= <vide> CONST <définition de constante> {;<définition de constante>}; <partie de définition de type> ::= <vide> | TYPE <définition de type> {; <définition de type>}; <partie de déclaration de variable> ::= <vide> VAR <déclaration de variable> {;<déclaration de variable>}; <partie procédure ou fonction> ::= {<procédure ou fonction>;} <procédure ou fonction> ::= <déclaration de procédure> | <déclaration de fonction> <partie d'instruction> ::= <instruction composée> |
Procédure standard
Ce qui suit est une liste des procédures intégrées d'ATARI Pascal. Ces procédures sont pré-déclarées dans un périmètre entourant le programme. Par conséquent, toutes les routines utilisateur du même nom seront prioritaires.
- ADDR
- CLRBIT
- CONCAT
- COPY
- DELETE
- DISPOSE
- EXIT
- FILLCHAR
- HI
- INSERT
- LENGTH
- LO
- MAXAVAIL
- MEMAVAIL
- MOVE
- MOVELEFT
- MOVERIGHT
- NEW
- POS
- SETBIT
- SHL
- SHR
- SIZEOF
- SWAP
- TSTBIT
Procédures de traitement des fichiers
Toutes les procédures standard de traitement des fichiers sont incluses. De plus, la procédure ASSIGN(F,string) est ajoutée où "F" est un fichier et "string" est une chaîne de caractères littérale ou variable. ASSIGN attribue le nom de fichier externe contenu dans la chaîne au fichier F. Il est utilisé avant un RESET ou un REWRITE.
Vous trouverez ci-dessous les noms des procédures de traitement :
- ASSIGN
- BLOCKREAD
- BLOCKWRITE
- CHAIN
- CLOSE
- CLOSEDEL
- GET
- GNB
- IORESULT
- OPEN
- PAGE
- PURGE
- PUT
- READ
- READLN
- RESET
- REWRITE
- WNB
- WRITE
- WRITELN
Procédures d'allocation dynamique
NEW et DISPOSE
En plus de NEW et DISPOSE, MEMAVAIL et MAXAVAIL sont également inclus.
Procédures de transfert de données
- PACK(A,I,Z)
- UNPACK(A,I,Z)
FORWARD
Les déclarations de procédure FORWARD sont implémentées dans ATARI Pascal. Il est recommandé de ne pas utiliser cette fonctionnalité à moins qu'une stricte conformité Pascal ne soit requise. Le compilateur en trois passages ; rend les déclarations anticipées inutiles.
Tableaux conformes
Notez que la norme ISO a ajouté le schéma de tableau conforme pour transmettre des tableaux de structure similaire (c'est-à-dire, même nombre de dimensions, type d'index compatible et même type d'élément), des limites supérieure et inférieure différentes. Vous pouvez maintenant passer, par exemple, un tableau dimensionné comme 1..10 et un tableau 2..50 à une procédure attendant un tableau. Vous définissez le tableau en tant que paramètre VAR et, lors du processus de déclaration du tableau, vous définissez également des variables pour contenir les limites supérieure et inférieure du tableau. Ces éléments de limites supérieure et inférieure sont remplis à l'exécution (RUN-TIME) par le code généré. Pour transmettre des tableaux de cette manière, le type d'index doit être compatible avec le type des limites conformes du tableau.
Vous trouverez ci-dessous un exemple de transmission de deux tableaux à une procédure affichant le contenu des tableaux sur le fichier OUTPUT :
- PROGRAM DEMOCON;
-
- TYPE
- NATURAL = 0..MAXINT; (* A UTILISER DANS UNE DÉCLARATION DE TABLEAU CONFORME *)
-
- VAR
- A1 : ARRAY[1..10] OF INTEGER;
- A2 : ARRAY[2..20] OF INTEGER;
-
- PROCEDURE DISPLAYIT(VAR AR1:ARRAY[LOWBOUND]..HIBOUND:NATURAL] OF INTEGER);
-
- (* CETTE DECLARATRION DEFINIE TROIS VARIABLES
-
- AR1 : LE TABLEAU PASSES EN PARAMETRE
- LOWBOUND : LA LIMITE INFERIEUR DE AR1 (PASSE A L'EXECUTION)
- HIBOUND : LA LIMITE SUPERIEUR DE AR1 (PASSE A L'EXECUTION)
-
- *)
-
- VAR
- I : NATURAL;
- (* COMPATIBLE AVEC LE TYPE D'INDEX DU TABLEAU CONFORME *)
- BEGIN
- FOR I:=LOWBOUND TO HIBOUND DO WRITELN('ENTREE DE TABLEAU [',I,']=',AR1[I]);
- END;
-
- BEGIN (* PROGRAMME PRINCIPAL *)
- DISPLAYIT(A1); (* APPELEZ DISPLAYIT ET TRANSMETTEZ A1 EXPLICITEMENT ET 1 ET 10 IMPLICITEMENT *)
- DISPLAYIT(A2); (* APPELEZ DISPLAYIT ET TRANSMETTEZ A2 EXPLICITEMENT ET 2 ET 20 IMPLICITEMENT *)
- END.
Déclarations de fonctions
<déclaration de fonction> ::= EXTERNAL <entête de fonction> | <entête de fonction> <bloc> <entête de fonction> ::= FUNCTION <identificateur> <paramlist>:<type de résultat> | FUNCTION <identificateur>:<type de résultat>; <type de résultat> ::= <identificateur de type> |
Fonctions standard
Vous trouverez ci-dessous les noms des fonctions standard prises en charge :
- ABS
- ADDR
- ARCTAN
- CHR
- COS
- EOF
- EOLN
- EXP
- IORESULT
- LENGTH
- LN
- MAXAVAIL
- MEMAVAIL
- ODD
- ORD
- POS
- PRED
- ROUND
- SIN
- SIZEOF
- SQR
- SQRT
- SUCC
- TRUNC
- WRD
Fonctions arithmétiques
Prédicats
Fonctions de transfert
WRD(x) : La valeur x (une variable ou une expression) est traitée comme la valeur WORD (entier non signé) de x. Les constantes littérales entières ne sont pas de type WORD. Par conséquent, si W est de type mot, W:=3 est illégal et vous devez utiliser W:=WRD(3).
Autres fonctions standards
Gestion des fichiers : (F est une variable de fichier)
- PUT(F)
- GET(F)
- RESET(F)
- REWRITE(F)
- PAGE(F)
- EOF(F)
- EOLN(F)
Allocation dynamique : (Tn est un sélecteur d'enregistrements de variantes, P est un pointeur) :
- NEW(P)
- NEW(P,T1,T2,...,Tn)
- DISPOSE(P)
- DISPOSE(P,T1,T2,...,Tn)
Procédures de transfert de données :
- PACK(A,I,Z)
- UNPACK(Z,A,I)
Fonctions arithmétiques :
Nom | Description |
---|---|
ABS(X) ou ABS(I) | Retour de type spécifié de son paramètre |
ABS(X) ou ABS(I) | Retour de type spécifié de son paramètre |
Fonctions de transfert : (SC est un scalaire court non réel)
Implémenté au moment de la compilation et ne génère aucun code :
- ODD(SC):BOOLEAN
- ORD(SC):INTEGER
- CHR(SC):CHAR
- WRD(SC):WORD
Implémenté au moment de la compilation et ne génère aucun code :
- PRED(tout type scalaire sauf réel)
- SUCC(tout type scalaire sauf réel)
INPUT et OUTPUT
ATARI Pascal prend en charge toutes les fonctionnalités d'entrée/sortie Pascal standard.
La procédure READ
La lecture dans les sous-intervalles est implémentée mais aucune vérification d'intervalle n'est effectuée, même si la vérification d'intervalle est activée.
La procédure READLN
<Appel de lecture> ::= <Lecture ou Lecture avec ligne> {({>filevar>,}{<varlist>})} <Lecture ou Lecture avec ligne> ::= <READ ou READLN> {({>filevar>,}{<varlist>})} <filevar> ::= <variable> <varlist> ::= <variable>{,<variable>} |
La procédure WRITE
La procédure WRITELN
<Appel d'écriture> ::= <Écriture ou écriture avec ligne> {({>filevar>,}{<exprlist>})} <Écriture ou écriture avec ligne> ::= <WRITE ou WRITELN> {({>filevar>,}{<varlist>})} <exprlist> ::= <wexpr>{,<wexpr>} <wexpr> ::= <expression> {:<largeur d'expression>} {:<expression décimal}} <largeur d'expression> ::= <expression> <expression décimal> ::= <expression> |
Pour écrire des entiers avec une base autre que dix, utilisez un spécificateur de champ de décimale négative.
Par exemple :
- WRITE(I:15:-16);
- (* Ceci écrit I en HEX *)
Vous ne pouvez pas utiliser de fonctions effectuant des entrées ou des sorties en tant que paramètre d'une instruction WRITE ou WRITELN. Ceux-ci incluent des routines d'accès telles que GNB. Les pointeurs de fichier sont modifiés par les routines de lecture, provoquant la sortie vers le fichier d'entrée.
Procédures additionnel
L'entrée et la sortie de WORD ne sont pas effectuées avec les procédures standard READ et WRITE. Deux nouvelles procédures sont READHEX et WRITEHEX. Ces nouvelles procédures autorisent les entrées/sorties hexadécimales sur des variables de n'importe quel type à un, deux ou quatre octets, comme un entier, un caractère, un octet, une sous-intervalle, une énumération, un mot et un entier long.
Programmes
<programme> ::= <entête de programme> <bloc> <entête de module> <partie de déclaration d'étiquette> <partie de définition de constante> <partie de définition de type> <partie de définition de variable> <partie de définition de procédure ou fonction> <entête de programme> ::= PROGRAM <identificateur>(<paramètres de programme>); <entête de module> ::= MODULE <identificateur>; <paramètres de programme> ::= MODULE <identificateur>; |