98 lines
2.8 KiB
Go
98 lines
2.8 KiB
Go
// Copyright 2010 The postscript-go Authors. All rights reserved.
|
||
// created: 13/12/2010 by Laurent Le Goff
|
||
|
||
//Operand Stack Manipulation Operators
|
||
package postscript
|
||
|
||
//any pop – -> Discard top element
|
||
func pop(interpreter *Interpreter) {
|
||
interpreter.Pop()
|
||
}
|
||
|
||
//any1 any2 exch any2 any1 -> Exchange top two elements
|
||
func exch(interpreter *Interpreter) {
|
||
value1 := interpreter.Pop()
|
||
value2 := interpreter.Pop()
|
||
interpreter.Push(value1)
|
||
interpreter.Push(value2)
|
||
}
|
||
|
||
//any dup any any -> Duplicate top element
|
||
func dup(interpreter *Interpreter) {
|
||
interpreter.Push(interpreter.Peek())
|
||
}
|
||
|
||
//any1 … anyn n copy any1 … anyn any1 … anyn -> Duplicate top n elements
|
||
func copystack(interpreter *Interpreter) {
|
||
n := interpreter.PopInt()
|
||
values := interpreter.GetValues(n)
|
||
for _, value := range values {
|
||
interpreter.Push(value)
|
||
}
|
||
}
|
||
|
||
//anyn … any0 n index anyn … any0 anyn -> Duplicate arbitrary element
|
||
func index(interpreter *Interpreter) {
|
||
f := interpreter.PopInt()
|
||
interpreter.Push(interpreter.Get(int(f)))
|
||
}
|
||
|
||
//anyn−1 … any0 n j roll any(j−1) mod n … any0 anyn−1 … anyj mod n -> Roll n elements up j times
|
||
func roll(interpreter *Interpreter) {
|
||
j := interpreter.PopInt()
|
||
n := interpreter.PopInt()
|
||
values := interpreter.PopValues(n)
|
||
j %= n
|
||
for i := 0; i < n; i++ {
|
||
interpreter.Push(values[(n+i-j)%n])
|
||
}
|
||
}
|
||
|
||
//any1 … anyn clear -> Discard all elements
|
||
func clear(interpreter *Interpreter) {
|
||
interpreter.ClearOperands()
|
||
}
|
||
|
||
//any1 … anyn count any1 … anyn n -> Count elements on stack
|
||
func count(interpreter *Interpreter) {
|
||
interpreter.Push(interpreter.OperandSize())
|
||
}
|
||
|
||
//Mark
|
||
type Mark struct{}
|
||
|
||
//– mark mark -> Push mark on stack
|
||
func mark(interpreter *Interpreter) {
|
||
interpreter.Push(Mark{})
|
||
}
|
||
|
||
//mark obj 1 … obj n cleartomark – -> Discard elements down through mark
|
||
func cleartomark(interpreter *Interpreter) {
|
||
value := interpreter.Pop()
|
||
for _, ok := value.(Mark); !ok; {
|
||
value = interpreter.Pop()
|
||
}
|
||
}
|
||
|
||
//mark obj 1 … obj n counttomark mark obj 1 … obj n n -> Count elements down to mark
|
||
func counttomark(interpreter *Interpreter) {
|
||
i := 0
|
||
value := interpreter.Get(i)
|
||
for _, ok := value.(Mark); !ok; i++ {
|
||
value = interpreter.Get(i)
|
||
}
|
||
interpreter.Push(float64(i))
|
||
}
|
||
|
||
func initStackOperator(interpreter *Interpreter) {
|
||
interpreter.SystemDefine("pop", NewOperator(pop))
|
||
interpreter.SystemDefine("exch", NewOperator(exch))
|
||
interpreter.SystemDefine("dup", NewOperator(dup))
|
||
interpreter.SystemDefine("index", NewOperator(index))
|
||
interpreter.SystemDefine("roll", NewOperator(roll))
|
||
interpreter.SystemDefine("clear", NewOperator(clear))
|
||
interpreter.SystemDefine("count", NewOperator(count))
|
||
interpreter.SystemDefine("mark", NewOperator(mark))
|
||
interpreter.SystemDefine("cleartomark", NewOperator(mark))
|
||
interpreter.SystemDefine("counttomark", NewOperator(mark))
|
||
}
|