Postscript Deel III: De Operand Stack van PostScript: Arrays, Variabelen, Loops en Macro Definities

ArticleCategory: [Artikel Kategorie]

Software Development

AuthorImage:[Bild des Autors]

[Emre Demiralph]

TranslationInfo:[Author and translation history]

original in en Emre Demiralp

en to nl Guus Snijders

AboutTheAuthor:[Über den Autor]

Ik ben een student aan het Instanbul American Robert College en tegelijkertijd een van de beheerders van het Computer Labs in het Wetenschaps en letterkunde Faculteit van de Technische Universiteit Instanbul. Het overdominerende besturingssysteem in deze labs is LINUX. Interesses: PovRay en PostScript, animatie, CD ontwerp, programmeren, holography, enz... Linux gebruikers sinds 1994.

Abstract:[Zusammenfassung]

Iemand die teveel weet maakt ook teveel fouten
- Turks gezegde-.

De auteur gaat verder met het beschrijven van de operand stack van de PostScript taal. De definitie van arrays, de array operators, de variabele definities, de lussen en de macro definities zijn hier alle present met voldoende detail en illustratieve voorbeelden en vragen welke beantwoord zullen worden in het volgende artikel. Dit artikel sluit de bespreking van de operand stack niet af. Het verhaal gaat verder in de komende artikelen.

ArticleIllustration:[Titelbild des Artikels]

[Ilustratie]

ArticleBody:[Der eigentliche Artikel]

Introductie

Dit is de derde in een serie artikelen over PostScript. We gaan verder met vertellen over de operand stack van PostScript. We richten ons vooral op de definities van arrays, array operators, variabele definities, lussen en macro definities. We proberen verschillende punten over deze onderwerpen te geven. De presentatie is ook verrijkt met illustratieve voorbeelden. Het verhaal van de operand stack wordt vervolgt in toekomstige artikelen over andere onderwerpen, gerelateerd aan de operand stack.

Arrays en Array Operators

In de voorgaande artikelen van deze serie noemden we de structuur van de operand stack en de operators die structuur van de operand stack kunnen veranderen. Zoals je je zult herinneren, zijn alle hoeveelheden die worden opgeslagen in de operand stack integers behalve een speciaal element dat wordt gebruikt voor referentie punt(en) in de operand stack. Dit element wordt -marktype- genoemd en de operators cleartomark en counttomark werden gebruikt om de om de elementen op de operand stack van boven tot dit element op te ruimen of te tellen. Dit is, natuurlijk, een groepperings faciliteit, het is echter niet de enige. Het is mogelijk om een enkele entiteit te maken welke vele elementen bevat. Deze entiteit wordt een array genoemd en het is mogelijk om te opereren op zijn eigen elementen door de array operators van de PostScript taal te gebruiken. In de volgende regels zullen we een paar details over deze onderwerpen geven en ook een paar illustratieve voorbeelden over het sorteren van de array operators.

[  : Dit creëert een marktype element in de stack. Tenzij zijn metgezel ] wordt gegeven, speelt het dezelfde rol als het mark commando. Alle elementen die op de operand stack komen na deze operator worden als individuele elementen gezien ook al is er een gemarkeerd referentie punt voor deze in de operand stack. De volgende sessie legt de relatie tussen ] en mark uit

GS>[ pstack
-marktype
GS<1>2 3 mark pstack
-marktype-
3
2
-marktype-
GS<4>

]  :Dit is de metgezel van de bovengenoemde operator [. De stack moet een marktype element bevatten voor dit element wordt gegeven. In feite wordt dit gezien als de eind markering voor de array en completeerd de array constructie. Daar ieder einde een begin nodig heeft, zoekt PostScript zijn metgezel, de begin markering [ als dit element op de stack wordt geplaatst. Als [ ontbreekt zal PostScript een foutmelding geven en wordt de actie niet uitgevoerd. Als dit element onmiddelijk na [ op de stack wordt geplaatst, wordt er een lege array gecreëerd en opgeslagen als een enkele entiteit in de operand stack (het bestaande marktype element duikt op als een deel van de array, dus niet als een ander element) zoals de volgende sessie laat zien:

GS>[ pstack
-marktype-
GS<1>] pstack
[]
GS<1>

Na dit alles bevat de operand stack alleen een enkele element, een lege array. Een niet-lege array kan direct worden gecreëerd door [ en ] samen met de array elementen op hetzelfde moment aan de interpreter aan te bieden zoals de volgende sessie laat zien.

GS>[ 1 2 3 ] pstack
[1 2 3]
GS<1>

Zoals we kunnen zien wordt de array als een enkele entiteit beschouwd.

We kunnen ook een array maken met een bepaald aantal elementen, zelfs als we niet ieder element willen specificeren. Dit kan gedaan worden met een null element, wat niets betekend:.

GS>[ null null ] pstack
[null null]
GS<1>

array: Dit commando neemt een integer als parameter. Als de parameter n is, dan wordt het commando opgegeven als n array. Dit commando creëert een array die exact n null elementen bevat. Hetzelde geldt voor de begin en einde markeringen voor het maken van de array. Zo doet bijvoorbeeld 3 array hetzelfde als [ null null null ] . Het zoekt de parameter als het bovenste element van de operand stack. Als het gegeven is voor het commando, wordt het op de operand stack geplaatst en wordt het bovenste element dat wordt gebruikt voor het commando. Als de parameter niet gegeven wordt voor het commando, bepaald het bovenste element van de operand stack wat er gaat gebeuren. Als het een integer is, wordt de waarde ervan gebruikt voor het commando, anders zal er een foutmelding worden weergegeven door incompatibiliteiten.

length: Deze operator evalueert het aantal elementen in een array. De null elementen worden ook in de evaluatie meegenomen. De operator neemt een parameter die ook een array moet zijn. De parameter verdwijnt van de operand stack na het uitvoeren van de operatie. Dus, als er een parameter voor een commando is gegeven en het is een array dan gaat alles goed en wordt een nummer bovenop de stack geplaatst. Bijvoorbeeld:

GS>[ 1 2 3 4 5 ] length pstack
5
GS<1>

Als we de parameter niet geven voor length operator dan wordt of het bovenste element gebruikt door het commando en verwijderd van de operand stack en het aantal elementen in de array wordt bovenop de stack geplaatst.

GS<1>pstack
[1 2 3 6 7]
GS<1>length pstack
5
GS<1>

of het bovenste element van de operand stack is geen array en er wordt een foutmelding gegenereerd.

get:D eze operator neemt twee parameters. Deze zijn een array en een integer respectievelijk. De operator krijgt een gespecificeerd element van de array. De positie van het element is de tweede parameter. De posities zijn geïndexeerd met natuurlijke nummers, dat wil zeggen, er wordt begonnen te tellen bij nul. In feite gelden deze regels voor alle operator parameters. De parameters worden gebruikt door het commando en worden van de operand stack verwijderd. Hun types moeten compatibel zijn met de gegeven waarden. We zullen dit punt verder niet meer benadrukken. Het gebruik van get gaat als volgt.

GS[1 6 3 0 9] 0 get pstack
1
GS<1>

put: Dit commando neemt drie parameters. Dit zijn respectievelijk een array, een index en het element om in de array te plaatsen. Wanneer gebruikt, krijgt het commando de array welke is aangegeven met het de eerste parameter, zoekt de locatie van het index nummer dat is opgegeven met de tweede parameter en vervangt het array element op die positie met hetgeen gegeven is als derde parameter. De resulterende array wordt echter niet opgeslagen in de operand stack. Vandaar dat voor expliciet gebruik van de put operator we een array variabele (of sleutel in PostScript terminology). De bewerking vindt plaats op deze variabele en het resultaat wordt dan op de operand stack geplaatst en van daar weergegeven. Kijk naar het volgende

GS>[1 2 3] 0 8 put
GS>

Er gebeurd hier niets, in de operand stack. Maar er treedt ook geen foutmelding op. In feite doet put wat het moet doen, maar het resultaat is niet opgeslagen op de operand stack. Om het resultaat van dezelfde actie op de operand stack te krijgen, kunnen we onderstaande sessie volgen.

GS>/ar [ 1 2 3 ] def
GS>ar 0 8 put
GS>ar pstack
[8 2 3]
GS<1>

Hier wordt eerst een array variabele (in plat 'Nederlands') of een sleutel (PostScript terminology) gedefinieerd. De naam van de variabele is ar. De tweede stap is naar het veranderen van het eerste element (met index nul) naar 8 met behulp van de put operator (commando). Daarna plaatst ar pstack de waarde van de array variabele ar op de operand stack en geeft de inhoud ervan weer. De variabele definitie zullen we later in dit artikel bekijken. Ook zullen de dictionaries (woordenboeken) en dictionary stack in toekomstige artikelen van deze serie worden besproken.

getinterval: Deze operator creëert een subarray van een opgegeven array. Er zijn drie parameters nodig. Dit zijn respectievelijk de array, waarvan de subarray word gecreëerd, de index die het eerste element van de subarray aangeeft en ten slotte een integer die het aantal elementen van de subarray aangeeft. Wanneer gebruikt neemt het commando een aantal elementen (opgegeven met de derde parameter) van de array (gegeven als eerste parameter), te beginnen met de locatie (gegeven met de tweede parameter) en kopieerd deze in een nieuwe array. De nieuwe array wordt op de operand stack gezet. Bij voorbeeld,

GS>[1 2 3 4 5 6 7 8 9] 2 3 getinterval pstack
[3 4 5]
GS<1>

putinterval: Dit vervangt een subarray van een opgeven array met een andere array. Er zijn drie parameters nodig: Eerst de array waarvan de subarray wordt veranderd, ten tweede de integer die de positie van de subarray aangeeft en ten derde de subarray om vervangen te worden met de subarray van de opgegeven array. Het commando komt sterk overeen met put. Het resultaat wordt niet op de operand stack geplaatst. In het volgende sessie is te zien hoe het resultaat wordt weergegeven.

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: Dit neemt een array als parameter en kopieerd de elementen als losse entiteiten naar de operand stack. Het bovenste element van de operand stack na de uitvoering is de array. Dat is,

[1 2 3] aload pstack
[1 2 3]
3
2
1
GS<4>

astore: Dit commando vervangt alle elementen van een array gegeven als de tweede parameter met een serie elementen waarvan het aantal gelijk is aan de lengte van de array van de operand stack. Het resultaat is een nieuwe array met die vervangen elementen.

GS>1 2 3 [null null null] astore pstack
[1 2 3]
GS<1>

copy: Dit kopieerd de eerste parameter, welke een array moet zijn, in de eerste subarray van de tweede parameter, welke dus ook een array moet zijn. Het weergegeven resultaat is de gekopieerde subarray, niet de tweede array. Om de laatste vorm van de tweede array te zien kan de variabele definitie als volgt worden gebruikt.

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>

De array elementen hoeven geen integers te zijn. Het kunnen strings en ook arrays zijn. Dit betekend dat de geneste structuur voor arrays is toegestaan in PostScript. Dit voordeel maakt het mogelijk om matrix operaties en macro definities op matrices te gebruiken. Het is zelfs mogelijk tensors of multidimensionale series in principes te gebruiken. Voor het moment is dit voldoende informatie.

Sleutels en Variabelen

Het is in alle programmeertalen mogelijk om variabelen te definiëren. Het gebruik van variabelen maakt het mogelijk om met hoeveelheden te werken, zonder je zorgen te maken over waar ze zich in het geheugen bevinden. Je kunt de waarde die opgeslagen is in een segment van het geheugen krijgen door ofwel zijn adres aan te geven of de sleutel voor zijn inhoud. De eerste benadering is vergelijkbaar met het gebruik van pointers in C... Als je je niet bezig wilt houden met de adressen is het gebruik van sleutels voldoende voor je. Echter, de compiler of de interpreter van de taal moet dan de geheugen toegang en andere operaties voor zijn rekening nemen. Hiervoor definieer je een woord of een string, een naam in plat Engels (of Nederlands ;), en dan geef je een waarde op voor deze entiteit. Al deze acties vertellen in feite de programmeertaal wat de variabele is en wat de waarde ervan is vanuit jouw oogpunt. De compiler of interpreter specificeerd een geheugen segment voor jouw variabele en alle toewijzingen gaan naar dit segment als data. Een vergelijkbare structuur is ook beschikbaar in PostScript. PostScript heeft dictionaries (woordenboeken) die de namen of sleutels en gerelateerde definities bevatten. In PostScript terminologie bestaat een dictionary uit paren waarvan het eerste element een key (sleutel) wordt genoemd en de tweede is de waarde. Bijvoorbeeld add is een naam (sleutel) welke een rekenkundige toevoeging maakt (waarde). PostScript kent de betekenis van add omdat deze is opgeslagen in een dictionary met de naam systemdict. Als je commando 1 2 add pstack geeft, zie je het resultaat 3 omdat PostScript deze 3 namen opzoekt en het volgende doet; het vind 1 en 2 en daarna add. De eerste twee objecten zijn integers en worden dus opgeslagen op de operand stack. Het derde object is een string die een naam (sleutel zou kunnen zijn. PostScript kijkt in zijn dictionary(ies) om deze naam te zoeken. Als deze wordt gevonden, wordt de bijbehorende actie uitgevoerd. Daar add bestaat in de systeem dictionary, systemdict is er een actie (waarde) voor deze naam (sleutel). Dit is respectievelijk het ophalen van de bovenste twee waarden van de operand stack om de wiskundige som te berekenen en de uitkomst weer op de stack te plaatsen. Het overblijvende deel van het commando is de string pstack welke voorkomt in de system dictionary en betekend "haal de huidige inhoud van de operand stack op en plaats deze op de standaard uitvoer", de actie vind dus plaats. Aan de andere kant zouden we per ongeluk of opzettelijk de volgende regel aan de interpreter kunnen geven: 1 2 dad pstack. Als dit gebeurt, geeft de interpreter een foutmelding doordat er geen sleutel of naam dad in de PostScript dictionaries voorkomt.

We zijn niet beperkt tot de bestaande definities van de systeem dictionary van PostScript. Het is mogelijk om procedures of identificaties als acties van gebruiker-gedefinieerde commando's te definiëren. Als de definitie een identificatie is, roepen we de naam of sleutel als variabele aan ook al is het niet gebruikt in PostScript terminologie. Ons doel is om vergelijkingen te maken met andere programmeertalen. Voor de definitie van variabelen gebruiken we /x waarde def waar waarde een object van PostScript is zoals integer, array, string ... Neem bijvoorbeeld als invoer /x 12 def op de integer prompt. Wanneer opgegeven neemt de PostScript interpreter drie objecten, /x, 12 en def. De objecten die beginnen met een slash worden herkend als de sleutels of namen. Deze kunnen op de operand stack worden geplaatst zonder te controleren of ze voorkomen in een dictionary. Het def commando bestaat als een sleutel-waarde paar in de system dictionary van PostScript en neemt twee parameters, eerst de sleutel of naam die gedefinieerd wordt, en als tweede de waarde die zal worden toegewezen aan deze sleutel. Zo creëert PostScript een sleutel-waarde paar na dit commando, /x 12 def wordt opgegeven en geplaatst in een specifieke standaard dictionary welke de current dictionary wordt genoemd. Het is het bovenste element van de dictionary stack, deze we later in deze serie in detail zullen bekijken. Vanaf dit punt zal x worden herkend door PostScript als 12 gedurende de hele sessie.

In principe kan iedere string die begint met een slash worden gebruikt als een sleutel waarde. Het is echter beter om karakters anders dan letters en nummers te vermijden. Karakters als interpunctie tekens, slash, enz. kunnen ongewilde effecten acties tot gevolg hebben in het gebruik van de resulterende sleutel omdat ze speciale rollen hebben in PostScript zoals het slash karakter. De limitaties op het aantal karakters in de string gegeven als sleutelnaam komt van de capaciteiten en limitaties van de interpreter die je gebruikt. In feite is het niet prettig te werken met een honderd karakters lange sleutelnaam hoewel het mogelijk is te gebruiken. PostScript is case sensitive (maakt onderscheid tussen hoofd- en kleine letters) en is dus erg flexibel. De namen moeten niet gekozen worden uit de systeem sleutels van PostScript. Anders overschrijft jouw sleutel definitie het systeem commando wat niet erg prettig is. Bijvoorbeeld als je /add 13 def dan blijkt add een constante te zijn en de toevoegingsmogelijkheid van PostScript bevriest tijdens de rest van de sessie. Er kunnen nog meer dingen over dit onderwerp worden gezegd, maar we zullen het bij deze paragrafen houden om de rest aan toekomstige artikelen over te laten.

Lussen

PostScript kent constructies voor herhaaldelijke acties, namelijk lussen (loops). Het aantal herhalingen kan duizenden, miljoenen, miljarden zijn. Het maakt niet uit. In de volgende regels zullen we lussen en lus commando's bespreken.

repeat: Dit commando neemt twee parameters, waarvan de eerste een integer is en het aantal herhalingen aangeeft, terwijl de tweede meestal een procedure is met een blok acties. In PostScript wordt een blok aangegeven met de begrenzers { en }. De instructies of commando's kunnen achtereenvolgend geplaatst worden tussen deze begrenzers. De syntax van het commando is n { ... } repeat. Waneer gebruikt, neemt PostScript de eerste parameter en plaatst deze op de operand stack. Vervolgens wordt de procedure in het blok { ... } genomen en besloten hoe de actie plaats vindt. Tenslotte wordt repeat opgezocht en gevonden in de system dictionary en zijn actie vindt plaats. Daar de gedefinieerde actie een herhaling is wordt de actie die als tweede parameter is opgegeven n keer uitgevoerd. Om meer specifiek te zijn geven we het volgende voorbeeld.

GS>3 {1} repeat
1
1
1
GS<3>

Drie integer waardes van 1 worden op de operand stack geplaatst met dit commando. In feite is de procedure hier erg eenvoudig. Het is gewoon het opgeven van 1. Hieronder een voorbeeld dat een iets gecompliceerdere procedure als volgt gebruikt.

GS>1 5 {1 add} repeat pstack
6
GS<1>

In dit voorbeeld wordt 1 eerst op de operand stack geplaatst en vervolgens wordt de procedure ({1 add}) 5 keer uitgevoerd. Deze 5 stappen worden als volgt uitgevoerd. In de eerste stap wordt 1 add uitgevoerd. add neemt twee parameters, de tweede is gegeven in de procedure. De eerste parameter (of operand in PostScript terminology) wordt van de operand stack gehaald. Daarom wordt in de eerste stap van repeat 1 1 add uitgevoerd. Het enige element op de operand stack 1 wordt na uitvoering verwijderd en het resultaat, 2, geplaatst als bovenste element. Dan gaat de volgende stap verder met 2 1 add en resulteerd in een enkel-element operand stack waarvan het enige element 3 is. Dit leidt tot de uitvoering van de derde stap 3 1 add. De overblijvende twee stappen omvatten de uitvoering van 4 1 add en 5 1 add. Daarom bevat de operand stack maar een element 6 als alles klaar is.

for: Dit commando neemt een integer controle variabele voor het herhaald uitvoeren van de gegeven procedure. De controle variabele start op een gegeven initiële waarde en verhoogd zijn waarde na iedere inidividuele uitvoering van de procedure. Deze actie gaat door tot een voorgeschreven limiet waarde wordt overschreden. Daardoor neemt het commando 4 argumenten, de eerste drie zijn respectievelijk Initial (begin), Increment (verhoog) en Limit (limiet). Deze parameters worden verwacht als nummerieke waarden, integers of decimale nummers. Het vierde argument is de procedure die zowel een enkel commando als een blok commando's, omgeven door { en } kan zijn. De volledige syntax van het commando is Initial Increment Limit Procedure for. Als het commando wordt uitgevoerd, creëert PostScript een tijdelijke teller variabele (control variabele in PostScript Terminology) en geeft deze de waarde van Initial. Deze waarde wordt op de operand stack geplaatst. Deze kan al dan niet gebruikt worden door de procedure als een parameter. Als deze wordt gebruikt, kan hij verwijderd worden van de operand stack, anders wordt hij opgeslagen op de operand stack. Nadat de teller variabele is gezet op Initial wordt de procedure uitgevoerd. Dit wordt gevolgd doorhet verhogen van de teller variabele met de waarde van Increment. Dan gaat de lus weer verder tot de verhoogde waarde van de teller de waarde van Limit overschrijdt. Als Increment positief is, is de uitvoering van for compleet als de waarde van de teller-variabele groter wordt dan Limit. Anders stopt de uitvoering van for als de teller variabele kleiner wordt dan Limit. Het bereik of de interval van de teller variabele moet niet-leeg zijn. Dit betekend dat Initial kleiner moet zijn als Limit als Increment positief is en vice versa. Om een en ander duidelijk te maken, geven we de volgende sessie als voorbeeld.

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>

Het eerste commando doet hier niets omdat er geen procedure is om uit te voeren, hij is null. Daarom worden alle waarden van de teller variabele opgeslagen op de operand stack en blijft daar omdat er geen procedure is om deze waarden te gebruiken. Het tweede commando bevat echter de add procedure welke twee argumenten nodig heeft. Het eerste argument is altijd het bovenste element op de operand stack en de tweede variabele is de waarde van de teller variabele van de loop, welke op de operand stack wordt geplaatst tijdens die stap. Het tweede commando evalueert de som van de eerste 23 positieve integers. Het heeft een externe initiële waarde nodig voor de voor de toevoegingsprocedure. Deze is gegeven als 0 voor het commmando. In andere woorden, 0 maakt geen deel uit van het for commando.

forall: Dit commando voert een procedure uit voor ieder element van een gegeven array. Voor dit doel, somt het ieder element op van de gegeven array, te beginnen bij nul. Er wordt een tijdelijke teller variabele gebruikt om de lus te beheren. De initiële waarde van deze teller is 0, wordt verhoogd met 1 en de limiet is de lengte van de gegeven array. Het lus schema is bijna hetzelfde als die van het for commando. Het enige verschil is het gebruik van de array elementen in plaats van de teller variabele in de procedure van dit commando. Het commando heeft twee argumenten nodig, de eerste is de array waarvan de elementen zullen worden gebruikt door de procedure. De tweede is de procedure. De complete syntax van dit commando is Array Procedure forall. De volgende PostScript sessie illustreerd het gebruik van het commando, hierin wordt geprobeerd de som van array te berekenen en alle elementen in een andere array te plaatsen op de operand stack.

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: Dit commando zoekt slechts een argument, de procedure om uit te voeren. Wanneer gebruikt, wordt de procedure zonder te stoppen herhaald. In andere woorden, het is een oneindige circel die alleen onderbroken kan worden door een externe interrupt als Ctrl-C, als de procedure niet over een speciale structuur beschikt. Als ergens in de procedure exit of stop commando's voorkomen, wordt de lus gestopt zodra het deze commando's tegenkomt en de controle gaat terug naar het volgende object van de interpretatie. De syntax van het commando is procedure loop.

Procedure of Macro Definities

In PostScript betekend Procedure of Macro een geordende set objecten. Deze objecten moeten worden opgenomen binnen een paar block begrenzers { en }. Ze kunnen benoemd worden met een sleutel definitie als /Macro1 {1 add 2 mul} def. Wanneer gebruikt, wordt de sleutel /Macro en de waarde {1 add 2 mul} wordt toegevoegd aan de huidige dictionary, welke zich als bovenste element op de dictionary stack bevindt als sleutel-waarde paar. Dan, als het object Macro1 wordt gegegeven op de interpreter prompt, vindt de bijbehorende actie plaats. De procedure, gedefinieerd in het block, kan zo gecompliceerd of eenvoudig zijn als je wilt. In toekomstige artikelen zullen we verder kijken naar macros. Voor het moment voldoet deze introductie informatie voor ons doel.

Oefeningen

Te beginnen bij dit artikel zullen we een paar oefeningen geven voor de lezer. De antwoorden van de vragen hier zullen in het volgende artikel worden gegeven.

  • 1)  Schrijf een procedure die een integer argument neemt en de som van de kwadraten van de integers tussen 1 en dit argument berekend.

  • 2)  Schrijf een procedure die twee integer argumenten neemt en de cubussen van de integers tussen de eerste en tweede argumenten uitrekend. De procedure moet een array maken en deze cubussen in de array plaatsen als elemente.

  • 3)  Schrijf een procedure die een array argument neemt en het gemiddelde van de elementen in de array berekend. Ook de vierkantswortel van de som van de kwadraten van de array worden berekend.

  • 4)  Neem aan dat PostScript niet over de exp procedure beschikt en schrijf een procedure die twee nummerieke waarden als argument neemt en beschouw het eerste argument als basis en het tweede argument als de exponent. De procedure zal de exponent-te macht van de basis berekenen. De argumenten moeten behouden worden in de operand stack na de operatie.

  • 5)  Het mathematische object matrix, kan beschouwd worden als een array van arrays. Een N rij vierkante matrix kan gerepresenteerd worden met een N-elementen array waarvan de elementen eveneens N-element arrays zijn. Noem dit type array van arrays "Square Matrix". Schrijf een procedure die een vierkantsmatrix argument neemt en bereken zijn spoor (de som van de diagonale elementen). Het resultaat en de originele vierkantsmatrix moet behouden blijven na de operatie.

  • 6)  Schrijf een procedure die een vierkantsmatrix argument neemt en zijn "transpose" (de rijen worden verwisseld door de kolommen) berekend. Het resultaat en de originele vierkantsmatrix moeten behouden blijven na de operatie.

  • 7)  Schrijf een procedure die twee vierkantsmatrix argumenten neemt en bereken de matrix som van beide. De resultaten en de originele vierkants matrix moeten behouden blijven na de operatie.

  • 8)  Schrijf een procedure die twee vierkants matrix argumenten neemt en bereken het matrix product ervan. De resultaten en de originele vierkants matrices moeten behouden blijven na de operatie.