-
Notifications
You must be signed in to change notification settings - Fork 7
/
operators_stack.go
98 lines (84 loc) · 2.8 KB
/
operators_stack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright 2010 The postscript-go Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff
//Operand Stack Manipulation Operators
package ps
//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))
}