par Emre Demiralp L´auteur: Je suis �tudiant au coll�ge am�ricain Robert d'Istanbul,et en m�me temps,un des administrateurs du d�partement informatique de la facult� des arts et sciences de l'Universit� des Techniques d'Istanbul. Le syst�me d'exploitation dominant dans ces d�partements est LINUX. Centres d'int�rets: PovRay et PostScript,animation,conception de CD,programmation,holographie etc... Utilisateur Linux depuis 1994. Sommaire: |
Résumé:
Celui qui en sait beaucoup rate aussi beaucoup
-Proverbe Turc-.L'auteur poursuit sa description de la pile des op�randes du langage PostScript. La d�finition des tableaux,les op�rateurs de tableaux,la d�finition des variables,les boucles et les d�finitions de macros sont tous pr�sent�s ici en d�tail et accompagn�s d'exemples et de questions auxquels il sera r�pondu dans le prochain article. Cet article ne termine pas la s�rie consacr�e � la pile des op�randes. Cette histoire se continuera dans les prochains articles.
Voici le troisi�me article de la s�rie sur PostScript. Nous approfondirons ici nos connaissances sur la pile des op�randes de PostScript. Nous aborderons plus particuli�rement la d�finition des tableaux, les op�rateurs de tableaux, la d�finition des variables, les boucles et les d�finitions de macros. Cette pr�sentation est aussi illustr�e d'exemples. L'histoire de la pile des op�randes se continuera dans les prochains articles en traitant de sujets associ�s � la pile des op�randes.
Dans les articles pr�c�dents, de cette s�rie, nous avons parl� de la structure de la pile des op�randes et des op�rateurs capables d'en la changer la structure. Toutes les quantit�s stock�es dans la pile �taient des valeurs enti�res � l'exception d'un �l�ment sp�cial destin� � cr�er des rep�res dans la pile. Cet �l�ment, appel� -marktype-, et les op�rateurs cleartomark et counttomark �taient utilis�s pour effacer ou compter les �l�ments depuis ce rep�re. Il s'agit bien s�r, d'une facilit� de regroupement, mais qui n'est pas la seule. Il est possible de cr�er une entit� unique capable de regrouper plusieurs �l�ments. Cette entit� est appel�e tableau (array) et il est possible d'op�rer sur ses �l�ments en utilisant les op�rateurs de tableaux (array operators) du langage PostScript. Voici le d�tail tri� de ces op�rateurs et quelques exemples.
[ :Ceci cr�e un �l�ment rep�re (marktype) dans la pile. Sans la pr�sence de son compagnon, ] il joue le m�me r�le que la commande mark. Tous les �l�ments qui entrent dans la pile situ� apr�s cet op�rateur sont consid�r�s comme des �l�ments individuels bien qu'il y ait un rep�re avant eux dans la pile. La session suivante explique la relation entre [ et mark
GS>[ pstack -marktype GS<1>2 3 mark pstack -marktype- 3 2 -marktype- GS<4>
] :C'est le pendant de l'op�rateur ci-dessus [. La pile doit contenir un �l�ment rep�re avant que celui ci soit donn�. En fait, il est consid�r� comme cl�turant la d�finition d'un tableau et termine sa construction. Comme chaque fin n�cessite un d�but, PostScript recherche son pendant, le rep�re de d�but [, quand ] est introduit dans la pile. Si [ est manquant, alors PostScript retourne une erreur et aucune action n'est engag�e. Si cet �l�ment est introduit juste apr�s [, alors un tableau vide est cr�� et stock� dans une seule entit� de la pile (l'�l�ment rep�re existant devient alors partie int�grante du tableau et n'appara�t plus comme un �l�ment distinct) comme le montre la session suivante:
GS>[ pstack -marktype- GS<1>] pstack [] GS<1>
Apr�s tout cela, la pile des op�randes contient un unique �l�ment, un tableau vide. Un tableau non vide peut directement �tre cr�� en utilisant [ et ] avec les �l�ments du tableau lors d'une seule entr�e dans l'interpr�teur comme ci-dessous.
GS>[ 1 2 3 ] pstack [1 2 3] GS<1>
Comme nous pouvons le voir, le tableau est consid�r� comme une entit� unique.
On peut cr�er un tableau avec un nombre donn� d'�l�ments, m�me si l'on ne
souhaite pas sp�cifier chacun d'eux. Ceci est r�alis� au moyen de
l'�l�ment null qui signifie rien comme suit.
GS>[ null null ] pstack [null null] GS<1>
array:Cette commande n�cessite un param�tre entier. Si le param�tre est n alors la commande est n array. A l'ex�cution, elle cr�e un tableau qui contient exactement n �l�ments null. Le r�sultat est le m�me qu'avec les rep�res de d�but et de fin de tableau. Par exemple, 3 array est �quivalent � [ null null null ]. Elle recherche son param�tre sur le dessus de la pile. S'il est donn� avant la commande, alors il est introduit sur la pile et devient l'�l�ment sup�rieur qui sera utilis� par cette commande. Si le param�tre n'est pas donn� avant la commande, alors l'�l�ment sup�rieur de la pile sera utilis� pour dimensionner le tableau si c'est un entier. Dans le cas contraire une erreur est g�n�r�e � cause de l'incompatibilit�.
length:Cet op�rateur calcule le nombre d'�l�ments d'un tableau. Les �l�ments null sont pris en compte dans ce calcul. L'op�rateur a besoin d'un param�tre qui doit �tre un tableau. Il prend le param�tre sur le dessus de la pile. Le param�tre dispara�t de la pile apr�s ex�cution. Ainsi, si le param�tre est introduit avant la commande et qu'il s'agit d'un tableau, alors tout se passe bien et un nombre est situ� en partie sup�rieure de la pile. Par exemple
GS>[ 1 2 3 4 5 ] length pstack 5 GS<1>
Si nous ne ne donnons pas de param�tre pour l'op�rateur length, l'�l�ment sup�rieur de la pile est utilis�, puis remplac� par son nombre d'�l�ments
GS<1>pstack [1 2 3 6 7] GS<1>length pstack 5 GS<1>
si l'�l�ment sup�rieur de la pile n'est pas un tableau, un message d'erreur est �mis.
get:Cet op�rateur n�cessite deux param�tres qui sont respectivement un tableau et un entier. La position de l'�l�ment � r�cup�rer est donn�e par l'entier. Les positions sont donn�es par les nombres naturels, c'est � dire � partir de z�ro. En fait, ces r�gles s'appliquent � tous les param�tres de tous les op�rateurs. Ils sont utilis�s par la commande puis retir�s de la pile. Leur type doit �tre compatible avec les valeurs donn�es. Nous n'attirerons plus l'attention sur ce point maintenant. get s'utilise comme suit.
GS[1 6 3 0 9] 0 get pstack 1 GS<1>
put:Cet op�rateur n�cessite trois param�tres qui sont respectivement un tableau, un entier et l'�l�ment � ins�rer dans le tableau. La commande recherche le tableau donn� par le premier param�tre, se positionne � l'endroit point� par le second param�tre et remplace le l'�l�ment de cet position par celui donn� comme troisi�me param�tre. Le tableau r�sultant n'est pas stock� dans la pile. Aussi pour un usage explicite de l'op�rateur put, nous pouvons d�finir une variable tableau (une key en terminologie PostScript Ndt: Clef en fran�ais). L'op�ration est r�alis�e sur cette variable et le r�sultat introduit sur la pile d'o� il peut �tre affich�: Regardez l'exemple suivant
GS>[1 2 3] 0 8 put GS>
Rien ne se passe, dans la pile des op�randes. Mais il n'y a pas de message d'erreur non plus. En fait, put fait son travail mais le r�sultat n'est pas stock� sur la pile. Pour voir le r�sultat de cette m�me action sur la pile, voici la marche � suivre.
GS>/ar [ 1 2 3 ] def GS>ar 0 8 put GS>ar pstack [8 2 3] GS<1>
D'abord une variable de tableau ou une clef (en terminologie PostScript) est d�finie. Le nom de la variable est ar. La deuxi�me �tape change le premier �l�ment (index z�ro) avec 8 en utilisant l'op�rateur put. Apr�s cela, ar pstack ins�re la valeur de la variable ar sur la pile des op�randes et affiche son contenu. Nous reparlerons des d�finitions de variables un peu plus tard dans cet article. Nous parlerons aussi des dictionnaires et de la pile des dictionnaires dans de prochains articles de cette s�rie.
getinterval:Cet op�rateur cr�e un sous tableau. Il n�cessite trois param�tres qui sont respectivement le tableau � partir duquel le sous tableau sera cr��,l'index qui d�termine le premier �l�ment du sous tableau et un entier qui donne le nombre des �l�ments du sous tableau. Le nouveau tableau (sous tableau) est plac� sur la pile. Par exemple:
GS>[1 2 3 4 5 6 7 8 9] 2 3 getinterval pstack [3 4 5] GS<1>
putinterval:Remplace une partie d'un tableau avec un autre tableau. Trois param�tres sont n�cessaires: d'abord le tableau � changer, ensuite un index entier qui pr�cise la position de d�part, et enfin le tableau qui remplacera les �l�ments d�sign�s dans le premier tableau � partir de la position du second param�tre. La commande est similaire � put. Elle ne place pas le r�sultat sur la pile des op�randes. Pour voir comment afficher le r�sultat, m�ditez la session suivante:
GS>/ar [1 2 3 4 5 6 7 8 9] def GS>ar 3 [0 0 0] putinterval GS>ar pstack [1 2 3 0 0 0 7 8 9] GS<1>
aload:Prend un tableau comme param�tre et copie ses �l�ments comme une seule entit� sur la pile. L'�l�ment sup�rieur de la pile devient donc le tableau. Soit,
[1 2 3] aload pstack [1 2 3] 3 2 1 GS<4>
astore:Cette commande remplace tous les �l�ment d'un tableau donn� comme second param�tre avec une s�quence d'�l�ments pris sur la pile, dont le nombre est �gal � la taille du tableau. Le r�sultat est un nouveau tableau.
GS>1 2 3 [null null null] astore pstack [1 2 3] GS<1>
copy:Copie le premier param�tre qui doit �tre un tableau dans le premier sous tableau du second param�tre qui doit aussi �tre un tableau. Le r�sultat affich� est le sous tableau copi� et non le second tableau. Pour voir la forme finale du second tableau, une d�finition de variable peut �tre utilis�e comme suit.
GS>[1 2 3] [4 5 6 7 8] copy pstack [1 2 3] GS<1>/ar [4 5 6 7 8] def GS<1>[1 2 3] ar copy GS<2>ar pstack [1 2 3 7 8] [1 2 3] [1 2 3] GS<3>
Les �l�ments du tableau ne sont pas n�cessairement des entiers. Ils peuvent �tre des cha�nes qui sont aussi des tableaux. Ceci signifie que les structures imbriqu�es sont autoris�es en PostScript. Cet avantage nous permet de r�aliser des op�rations de matrices et des d�finitions de macros avec des matrices. Il est m�me possible, en principe, de traiter des tenseurs ou des s�quences multi-dimensionnelles. Nous nous contenterons de cette information pour l'instant.
Il est possible de d�finir des variables dans tous les langages de programmation. Leur utilisation permet de traiter des quantit�s sans s'occuper de leur position en m�moire. On peut obtenir une valeur stock�e dans un segment de m�moire soit en donnant son adresse, soit en nommant une clef qui r�f�rence son contenu. La premi�re approche consiste � utiliser des pointeurs comme en C... Si les adresses ne vous int�ressent pas, alors utilisez simplement les clefs. Toutefois, le compilateur doit traiter les adresses m�moire et d'autre op�rations dans ce cas. Pour cela, on d�finit juste un nom et lui assigne une valeur. Toutes ces actions servent en fait � d�finir au langage de programmation ce qu'est la variable et quelle est sa valeur de votre point de vue. Le compilateur, ou l'interpr�teur, d�finit une portion de m�moire pour cette variable et toutes les assignations iront � cet endroit. Une structure similaire est disponible en PostScript. PostScript a des dictionnaires qui contiennent des noms ou des clefs et leur d�finitions relatives. En terminologie PostScript, un dictionnaire est compos� de paires dont le premier �l�ment est appel� une clef et le second une valeur. Par exemple, add est un nom (clef)qui r�alise une addition (valeur). PostScript conna�t le sens de add car il est stock� dans un dictionnaire qui est appel� systemdict. Si l'on tape la commande 1 2 add pstack, on obtient le r�sultat 3 parce que PostScript recherche les trois noms et agit comme suit. Il trouve 1 et 2 puis add. Les deux premiers objets sont des entiers qui sont stock�s sur la pile des op�randes. Le troisi�me objet est une cha�ne qui peut �tre un nom (key) ou pas. PostScript recherche ce nom dans ses dictionnaires. S'il est trouv�, l'action d�finie est engag�e. Puisque add existe dans le dictionnaire syst�me, systemdict l'action est (value) pour ce nom (key). Cela correspond respectivement � r�cup�rer les deux �l�ments sup�rieurs de la pile, pour �valuer leur somme, puis � pousser le r�sultat sur la pile. Le reste de la commande est la cha�ne pstack qui existe dans le dictionnaire syst�me et signifie "afficher le r�sultat courant de la pile sur la sortie standard". D'un autre cot�, nous pourrions donner la ligne suivante � l'interpr�teur (intentionnellement ou non): 1 2 dad pstack. Dans ce cas, l'interpr�teur �mettra un message d'erreur car il n'existe aucune clef du nom de dad d�finie dans le dictionnaire de PostScript.
Nous ne sommes pas limit� par les d�finitions existantes du dictionnaire syst�me de PostScript. Il est possible de d�finir des proc�dures ou des identifications comme des actions de commandes d�finies par l'utilisateur. Si la d�finition est une identification alors le nom, ou clef, s'appelle une variable bien qu'il ne soit pas utilis� par la terminologie PostScript. Notre objectif est de faire des appels depuis d'autres langages de programmation bien connus. Pour d�finir des variables, tout ce que nous avons � faire est d'�mettre /x value def ou value est un objet de PostScript comme un entier, un tableau, une cha�ne... Par exemple si nous entrons /x 12 def � l'invite de l'interpr�teur PostScript voit trois objets, /x, 12 et def. Les objets qui commencent par un slash sont reconnus comme des clefs ou des noms. Il peuvent �tre pouss�s sur la pile des op�randes sans s'occuper de savoir s'ils existent dans le dictionnaire. La commande def existe en tant que paire clef-valeur dans le dictionnaire syst�me de PostScript et requiert deux param�tres, la clef ou le nom qui va �tre d�finit et la valeur qui lui sera assign�e. PostScript cr�e ainsi une paire key-value apr�s cette commande, /x 12 def, et la stocke dans un dictionnaire sp�cifique qui est appel� current dictionary. Ce sera l'�l�ment sup�rieur de la pile du dictionnaire dont nous parlerons plus tard en d�tail dans cette s�rie. Pass� ce point, x sera reconnu par PostScript comme 12 pendant toute la session.
En principe, toute cha�ne qui commence par un slash peut �tre utilis�e comme une valeur de clef. Toutefois, il est pr�f�rable d'�viter d'utiliser d'autres caract�res que les chiffres et les lettres. Les autres caract�res comme la ponctuation, les slasch, etc... pourraient avoir des effets ind�sirables car ils peuvent avoir une signification sp�ciale pour PostScript comme le slash. Les limitations en nombre de caract�res dans les cha�nes utilis�es comme clefs viennent des possibilit�s et limitations de l'interpr�teur que vous utilisez. En fait, il n'est pas tr�s pratique d'utiliser des noms d'une centaine de caract�res de long bien que cela soit possible. PostScript est sensible � la casse ce qui permet une grande flexibilit�. Les noms ne doivent pas �tre choisis parmi les clefs syst�me de PostScript, faute de quoi les commandes syst�me seront �cras�es. Ainsi, si vous �crivez /add 13 def alors add devient une constante qui paralyse les capacit�s de PostScript pour le reste de la session. Il y aurait encore beaucoup de choses � dire sur ce sujet, mais nous nous contenterons de ces paragraphes en reportant le reste � de futurs articles.
PostScript poss�de des sch�mas r�p�titifs, autrement dit des boucles. Elles fournissent un moyen de r�p�ter plusieurs fois les m�mes types d'instructions. Le nombre de r�p�tition peut atteindre des milliers, des millions, des milliards voire plus. Cela n'a aucune importance. En une simple commande, des proc�dures enti�res peuvent �tre ex�cut�es en utilisant des boucles.
repeat:Cette commande requiert deux param�tres. Le premier est un entier et d�crit le nombre de r�p�titions tandis que le second est g�n�ralement une proc�dure qui est un bloc d'actions. Dans PostScript, un bloc est d�finit par les d�limiteurs et . Les instructions ou les commandes peuvent �tre align�es entre ces d�limiteurs. La syntaxe de la commande est n ... repeat. PostScript ins�re le premier param�tre sur la pile, puis la proc�dure incluse dans le bloc ... est �valu�e. Finalement repeat est recherch� dans le dictionnaire et ex�cut�. Puisque l'action est juste une r�p�tition, la proc�dure d�finie par le second param�tre est ex�cut�e n fois. Voici un exemple.
GS>3 1 repeat 1 1 1 GS<3>
Trois valeurs enti�res 1 sont pouss�es sur la pile par cette commande. En fait, cette proc�dure est tr�s simple. Elle consiste seulement � entrer 1. Voici un exemple un peu plus compliqu�.
GS>1 5 1 add repeat pstack 6 GS<1>
Dans cet exemple, d'abord on entre 1 sur la pile des op�randes puis la proc�dure 1 add est ex�cut�e 5 fois sur la pile des op�randes. Ces 5 �tapes se passent comme suit. D'abord, 1 add est ex�cut�. add n'a pas besoin de param�tres, car le second est donn� par la proc�dure. Le premier param�tre (ou op�rande) en terminologie PostScript) est pris sur la pile des op�randes. Ainsi lors du premier pas de repeat, 1 1 add est ex�cut�. Le seul �l�ment de la pile, 1 est d�truit apr�s cette ex�cution et le r�sultat qui est 2 est pouss� sur la pile. Le second pas est alors 2 1 add ce qui donne comme unique r�sultat 3. Ceci conduit au troisi�me pas 3 1 add. Les deux pas restant font appel � 4 1 add et 5 1 add. Par cons�quent le seul �l�ment qui reste sur la pile apr�s ex�cution est 6.
for:Cette commande � besoin d'une variable de contr�le enti�re pour l'ex�cution r�p�titive d'une proc�dure. La variable de contr�le d�marre d'une valeur initiale et s'incr�mente � chaque ex�cution de la proc�dure. Cette action se poursuit jusqu'� ce que la valeur limite prescrite soit atteinte. C'est pourquoi cette commande prend quatre op�randes dont les trois premi�res sont Initial, Increment, et Limite. Ces trois param�tres doivent �tre des valeurs num�riques, enti�res ou d�cimales. La quatri�me op�rande est le corps de la proc�dure qui peut �tre une commande unique ou un bloc compris respectivement entre et . La syntaxe compl�te de la commande est Initial Increment Limit Procedure for. Quand elle est ex�cut�e, PostScript cr�e un compteur (variable de contr�le en terminologie PostScript) et lui affecte la valeur Initial. Cette valeur est ins�r�e sur la pile des op�randes. Elle peut �tre utilis�e par la Procedure en tant qu'op�rande. Dans ce cas elle est extraite de la pile, sinon elle y est stock�e. Une fois le compteur initialis� avec Initial la Procedure est ex�cut�e. La variable est ensuite incr�ment�e de la valeur Increment. Puis le cycle continue de la sorte jusqu'� ce que la variable exc�de la valeur de Limit.Si Increment est positif alors l'ex�cution de for se termine quand le compteur d�passe Limit. Sinon, l'ex�cution de for s'arr�te quand le compteur devient plus petit que Limit. L'�tendue de l'interval du compteur ne doit pas �tre vide. Cela signifie que Initial doit �tre plus petit que Limit quand Increment est positif et vice-versa. Exemple:
GS>1 -0.5 -1 for pstack -1.0 -0.5 0.0 0.5 1.0 GS<5>clear 0 1 1 23 add for pstack 276 GS<1>
Ici la premi�re commande ne fait rien car il n'y a aucune proc�dure de d�finie, elle est nulle. Par cons�quent, toutes les valeurs du compteur sont stock�es et y restent car aucune proc�dure n'utilise ces valeurs. La seconde commande inclus quant � elle la proc�dure add qui n�cessite deux op�randes. La premi�re est toujours le premier �l�ment sur la pile et la seconde est la valeur du compteur de boucle qui est pouss� sur la pile � chaque pas. La seconde commande �value la somme des 23 premiers entiers positifs. Elle n�cessite une valeur de d�part ext�rieure qui est fournie ici comme �tant 0. En d'autres termes, 0 ne fait pas partie de la commande for.
forall:Cette commande ex�cute une proc�dure pour chaque �l�ment d'un tableau. Pour cela, elle �num�re chaque �l�ment du tableau � partir de z�ro. Elle utilise un compteur temporaire pour contr�ler la boucle. La valeur initiale du compteur est 0, son incr�ment est 1 et sa limite sup�rieure la longueur du tableau. Le fonctionnement de la boucle est tr�s similaire � celui de for. La seule diff�rence concerne l'utilisation des �l�ments d'un tableau au lieu d'un compteur. La commande n�cessite deux param�tres dont le premier est le tableau et le second la proc�dure. La syntaxe compl�te de la commande est Array Procedure forall . La session PostScript suivante �value la somme d'un tableau. L'arrangement de tous les �l�ments d'un autre tableau dans la pile des op�randes est aussi pr�sent� et les explications viennent ensuite.
GS>0 [11 23 45 -89 26 12 0 -34] add forall pstack -6 GS<1>[1 22 -12 0] forall pstack 0 -12 22 1 -6 GS<5>
loop:Cette commande n'utilise qu'un param�tre qui est la proc�dure � ex�cuter. Elle s'ex�cute infiniment et ne peut �tre arr�t�e que par une interruption ext�rieure telle que Ctrl-C si la proc�dure ne poss�de pas de structure sp�ciale. Si la proc�dure contient exit ou stop quelque part dans la boucle, alors celle ci est arr�t�e quand une de ces commandes est rencontr�e. Le contr�le est alors pass� � l'objet suivant. La syntaxe de la commande estProcedure loop.
Dans PostScript, Proc�dure ou Macro r�f�re � un ensemble ordonn� d'objets qui doivent �tre regroup�s entre et . Ils peuvent �tre nomm�s en utilisant une d�finition de clef comme /Macro1 1 add 2 mul def. Dans ce cas, la clef /Macro et sa valeur 1 add 2 mul sont ajout�s au dictionnaire courant et situ�s au dessus dans la pile des dictionnaires. Quand l'objet Macro1 est tap� � l'invite de l'interpr�teur, son action est ex�cut�e. Les proc�dures d�finies dans les blocs peuvent �tre simples ou compliqu�es � volont�. Dans un prochain article nous reviendrons sur les macros.
A partir de cet article nous donnerons quelques exercices au lecteur. Les r�ponses seront donn�es dans les articles suivants.
Site Web maintenu par l´équipe d´édition LinuxFocus
© Emre Demiralp LinuxFocus 1999 |
Translation information:
|
1999-11-24, generated by lfparser version 0.7