2016-06-23 24 views
2

Beispiel mit Werten 10 und 20 vor Laufzeit bekannt besseres Verständnis der eigentlichen Frage unten zu geben:
In PostScript: Wie platziere ich einige Stack-Elemente (berechnet zur Laufzeit) in eine Prozedur, die einem Namen zugewiesen werden kann?

/point1 { 10 20 } def Orte die Zahlen 10 und 20 in ein (anonymes) Verfahren und ordnet sich dann an den Name point1 (so ist es nicht mehr anonym). Dann kann der Name point verwendet werden, d. H. Wann immer der Interpreter es findet, wird { 10 20 } ausführen, d. H. 10 und 20 werden auf den Stapel geschoben.

Stack vor und nach der Ausführung def:

Stacke before:    Stack after: 
{ 10 20 }     - 
/point1 

Dict before:    Dict after: 
-       point1 --> { 10 20 } 

Nun ist die eigentliche Frage: Angenommen, die beiden Werte 10 und 20 wird zur Laufzeit berechnet werden. Wie ordnen Sie sie (oder eine beliebige Anzahl von obersten n Stack-Elementen) einem bestimmten Namen zu, um sie später zu verwenden?

Stacke before:    Stack after: 
<y>      - 
<x> 
/<name> 

Dict before:    Dict after: 
-       <name> --> { <x> <y> } 

Antwort

4

In Nachsatz enthält, sind Prozeduren Arrays nur mit dem ausführbaren Flag gesetzt. So können Sie ein Array (wie Sie wollen) konstruieren und dann cvx darauf aufrufen.

/x 3 def 
/y 4 def 
[ x y ] cvx % { 3 4 } 
x y [ 3 1 roll ] cvx 
x y 2 array astore cvx 
{ //x //y } 
({//x //y}) cvx exec 
({//x //y}) token pop exch pop 

Also, für Ihre hypothetische Verfahren, könnte es wie folgt geschehen:

/makepairproc { % x y -> { x y } 
    [ 3 1 roll ] cvx 
} def 

Eine weitere interessante Sache, die Sie tun können, ist eine ausführbare Array und eine wörtliche Array von den gleichen zugrunde liegenden Array gleichzeitig. Sie könnten eine als definierte Prozedur Name und die andere als Ziel definiert verwenden. Auf diese Weise können Sie den Inhalt aktualisieren, ohne jedes Mal neuen Speicher zuzuweisen.

/point1 { 10 20 } def 
/point1arr //point1 cvlit def 

30 40 point1arr astore %update contents 
point1 % 30 40   %execute contents 
+0

Danke! Genau das wollte ich. Ich kannte den 'cvx'-Befehl nicht. – Curd

2

Hmm, warum nicht einfach das Skript ausführen, das die Werte erzeugt? Dann sind sie auf dem Stapel wie nach dem Aufruf von "point1".

Aber Sie können

/xyz [ <call you procedure producing the numbers> ] cvx def 

so xyz ein Verfahren der Herstellung der zwei erzeugten Zahlen auf dem Stack verwenden ...

+0

Warum nicht das Skript ausführen, das die Werte erzeugt? Weil ich die Werte oft verwenden möchte, möchte ich nicht, dass sie immer wieder berechnet werden. – Curd

+0

@Curd Stefan bedeutet, dass man im Allgemeinen '' '' '' '' '' '' '' '' '' 'um jeden Code herum einbinden kann, um die Ergebnisse als Array zu erfassen. Dies könnte in einer '/ init'-Prozedur oder im Code der obersten Ebene geschehen, also schlägt er nicht vor, sie mehrmals auszuführen. Es ist eine Verallgemeinerung der ersten (Code-) Zeile meines ersten Beispiels, wobei 'x y' das ''. –

+0

@ luserdroog, ursprünglich wollte ich es eigentlich jedes Mal ausführen, aber ich hatte im Hinterkopf, dass es Gründe geben könnte (wie es "teuer" oder abhängig von einem speziellen Kontext ist), es nicht zu tun –