-
Notifications
You must be signed in to change notification settings - Fork 22
/
contextops.py
118 lines (94 loc) · 2.55 KB
/
contextops.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
from ceptions import ValidationError
from ceptions import PoisonException
from opcodes import order_ops
READ_POISON = ('READ', -1)
class ContextOps:
def __init__(self):
self.__maps = [dict()]
def push_context(self, separator):
self.__maps.append(separator)
self.__maps.append(dict())
def pop_context(self, separator):
current = self.__maps[0]
if len(self.__maps) == 1:
if READ_POISON in current:
raise PoisonException("poison encountered")
raise ValidationError("write operation not synced")
self.__maps.pop(0) # pop context
expected = self.__maps.pop(0) # pop separator
if expected != separator:
raise ValidationError("write operation not synced")
def add_mapping(self, k, v):
if k in self.__maps[-1]:
w = self.__maps[-1][k]
if w != v:
print("[WARNING] overwriting entry")
self.__maps[-1][k] = v
def lookup_mapping(self, k):
if k not in self.__maps[0]:
if READ_POISON in self.__maps[0]:
raise PoisonException("poison encountered")
raise ValidationError("read operation not synced")
return self.__maps[0][k]
def debug_mapping(self):
for i, item in enumerate(self.__maps):
if i % 2 == 0:
print("")
if isinstance(item, dict):
for k, v in item.items():
print(k, v)
else:
print(item)
def check_end_mapping(self):
return READ_POISON in self.__maps[0]
class FreeOps:
def __init__(self):
self.__map = dict()
def add_mapping(self, k, v):
opcode = k[0]
if opcode in order_ops:
if k not in self.__map:
self.__map[k] = list()
# print(opcode)
self.__map[k].append(v)
else:
if k in self.__map and self.__map[k] != v:
print("[WARNING] overwriting free ops mapping")
self.__map[k] = v
def in_mapping(self, k):
return k in self.__map
def lookup_mapping(self, k):
v = self.__map[k]
if isinstance(v, list):
if len(v) == 1:
return v[0]
return v.pop(0) # still bad
else:
return v
def debug_mapping(self):
for k, v in self.__map.items():
print(k, v)
class EffectOps:
def __init__(self):
self.__map = dict()
self.__hit = set()
def add_mapping(self, k, v):
if k not in self.__map:
self.__map[k] = list()
self.__map[k].append(v)
def lookup_mapping(self, k):
if k not in self.__map:
if self.reached_end_state():
raise PoisonException("poison encountered")
else:
raise KeyError(k)
v = self.__map[k]
if len(v) == 1:
self.__hit.add(k)
return v[0]
return v.pop(0)
def debug_mapping(self):
for k, v in self.__map.items():
print(k)
def reached_end_state(self):
return len(self.__hit) == len(self.__map)