-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathqueue.py
155 lines (109 loc) · 3.66 KB
/
queue.py
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from collections import deque
import datatypes
import exceptions
import pprint
from command import Command
class RQueue(Command):
def __init__(self, size):
self.q = deque([])
self.size = size
def push(self, val):
assert val is not None
assert self.size >= len(self.q)
if self.size == len(self.q):
raise exceptions.QQError("Register queue is full.")
self.q.append(val)
def pop(self):
return self.q.popleft()
class RQAlloc(Command):
def execute(self, env):
if env.rqueue is not None:
raise exceptions.QQError("Register queue is already allocated")
size = env.qframe.popleft()
env.rqueue = RQueue(size.value)
class QueueFrameBase:
def get_queue(self, env):
pass
def return_queue(self, env):
pass
def pop(self, env):
return env.qframe.popleft()
def push(self, env, val):
env.qframe.append(val)
class RegisterQueueBase:
def get_queue(self, env):
pass
def return_queue(self, env):
pass
def pop(self, env):
if env.rqueue is None:
raise exceptions.QQError("Register queue is not allocated")
return env.rqueue.pop()
def push(self, env, val):
if env.rqueue is None:
raise exceptions.QQError("Register queue is not allocated")
env.rqueue.push(val)
class QQueueBase:
def get_queue(self, env):
if type(env.qframe[0]) != datatypes.Queue:
raise exceptions.QQError("Element at front of queue is not a Queue")
self.queue = env.qframe.popleft()
def return_queue(self, env):
env.qframe.append(self.queue)
def pop(self, env):
return self.queue.pop()
def push(self, env, val):
self.queue.push(val)
class RotBase:
def execute(self, env):
self.get_queue(env)
self.push(env, self.pop(env))
self.return_queue(env)
class Rot(Command, RotBase, QueueFrameBase): pass
class RRot(Command, RotBase, RegisterQueueBase): pass
class QRot(Command, RotBase, QQueueBase): pass
class PopBase:
def execute(self, env):
self.get_queue(env)
env.qframe.append(self.pop(env))
self.return_queue(env)
class Pop(Command):
def execute(self, env):
env.qframe.popleft()
class RPop(Command, PopBase, RegisterQueueBase): pass
class QPop(Command, PopBase, QQueueBase): pass
class PushBase:
def execute(self, env):
self.get_queue(env)
self.push(env, env.qframe.popleft())
self.return_queue(env)
class Push(Command, PushBase, QueueFrameBase): pass # This is the same as Rot, but left it for funsies
class RPush(Command, PushBase, RegisterQueueBase): pass
class QPush(Command, PushBase, QQueueBase): pass
class DrainBase:
def execute(self, env):
self.get_queue(env)
try:
while True:
self.pop(env)
except IndexError:
pass
self.return_queue(env)
class Drain(Command, DrainBase, QueueFrameBase): pass
class RDrain(Command, DrainBase, RegisterQueueBase): pass
class QDrain(Command, DrainBase, QQueueBase): pass
class DupBase:
def execute(self, env):
self.get_queue(env)
elm = self.pop(env)
self.push(env, elm)
self.push(env, elm.copy())
self.return_queue(env)
class Dup(Command, DupBase, QueueFrameBase): pass
class RDup(Command, DupBase, RegisterQueueBase): pass
class QDup(Command, DupBase, QQueueBase): pass
class Pack(Command):
def execute(self, env):
size = env.qframe.popleft()
new_q = datatypes.Queue([env.qframe.popleft() for _ in range(int(size.value))])
env.qframe.append(new_q)