-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVirtual_Machine.py
More file actions
164 lines (147 loc) · 6.75 KB
/
Copy pathVirtual_Machine.py
File metadata and controls
164 lines (147 loc) · 6.75 KB
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
156
157
158
159
160
161
162
163
164
class Virtual_Machine:
def __init__(self, quads, var_table, cte_table):
self.quadruples = quads
self.var_table = var_table
self.cte_table = cte_table
# Define memory starts used by Parser
self.mem_cte_int = 0
self.mem_cte_float = 1000
self.mem_cte_string = 2000
self.mem_int = 3000
self.mem_float = 4000
self.mem_bool = 5000
self.mem_limit = 6000
self.start_cte_int = 0
self.start_cte_float = 0
self.start_cte_string = 0
self.start_int = len(self.cte_table)
self.start_float = self.start_int
self.start_bool = self.start_int
self.end = self.start_int
self.allocate_memory()
self.save_cte()
def allocate_memory(self):
for cte in self.cte_table:
memory_dir = self.cte_table[cte]['memory_dir']
if memory_dir < self.mem_cte_float:
self.start_cte_float += 1
elif memory_dir < self.mem_cte_string:
self.start_cte_string += 1
self.start_cte_string += self.start_cte_float
for var in self.var_table:
memory_dir = self.var_table[var]['memory_dir']
if self.mem_int <= memory_dir < self.mem_float:
self.start_float = max(self.start_float, memory_dir)
elif self.mem_float <= memory_dir < self.mem_bool:
self.start_bool = max(self.start_bool, memory_dir)
elif self.mem_bool <= memory_dir < self.mem_limit:
self.end = max(self.end, memory_dir)
for quad in self.quadruples:
operator, l_operand_mem, r_operand_mem, memory_dir = quad
if memory_dir != None:
if self.mem_int <= memory_dir < self.mem_float:
self.start_float = max(self.start_float, memory_dir)
elif self.mem_float <= memory_dir < self.mem_bool:
self.start_bool = max(self.start_bool, memory_dir)
elif self.mem_bool <= memory_dir < self.mem_limit:
self.end = max(self.end, memory_dir)
if self.start_float > self.start_int:
self.start_float = self.start_float - self.mem_int + self.start_int + 1
if self.start_bool > self.start_int:
self.start_bool = self.start_bool - self.mem_float + self.start_float + 1
else:
self.start_bool = self.start_float
if self.end > self.start_int:
self.end = self.end - self.mem_bool + self.start_bool + 1
else:
self.end = self.start_bool
self.memory = [None] * self.end
def get_memory_dir(self, memory_dir):
if memory_dir == None:
return memory_dir
m_dir = 0
if memory_dir < self.mem_cte_float:
m_dir = self.start_cte_int + (memory_dir - self.mem_cte_int)
elif memory_dir < self.mem_cte_string:
m_dir = self.start_cte_float + (memory_dir - self.mem_cte_float)
elif memory_dir < self.mem_int:
m_dir = self.start_cte_string + (memory_dir - self.mem_cte_string)
elif memory_dir < self.mem_float:
m_dir = self.start_int + (memory_dir - self.mem_int)
elif memory_dir < self.mem_bool:
m_dir = self.start_float + (memory_dir - self.mem_float)
elif memory_dir < self.mem_limit:
m_dir = self.start_bool + (memory_dir - self.mem_bool)
else:
print("ERROR: Stack Overflow")
return m_dir
def save_to_memory(self, memory_dir, value):
m_dir = self.get_memory_dir(memory_dir)
self.memory[m_dir] = value
def save_cte(self):
for cte in self.cte_table:
memory_dir = self.cte_table[cte]['memory_dir']
self.save_to_memory(memory_dir, cte)
def execute(self):
pc = 0
while pc < len(self.quadruples):
quad = self.quadruples[pc]
operator, l_operand_mem, r_operand_mem, result_mem = quad
l_operand_mem = self.get_memory_dir(l_operand_mem)
r_operand_mem = self.get_memory_dir(r_operand_mem)
if operator == '+':
value = self.memory[l_operand_mem] + self.memory[r_operand_mem]
self.save_to_memory(result_mem, value)
elif operator == '-':
if l_operand_mem == None:
value = self.memory[r_operand_mem] * -1
self.save_to_memory(result_mem, value)
else:
value = self.memory[l_operand_mem] - self.memory[r_operand_mem]
self.save_to_memory(result_mem, value)
elif operator == '*':
value = self.memory[l_operand_mem] * self.memory[r_operand_mem]
self.save_to_memory(result_mem, value)
elif operator == '/':
value = self.memory[l_operand_mem] / self.memory[r_operand_mem]
self.save_to_memory(result_mem, value)
elif operator == '>':
if self.memory[l_operand_mem] > self.memory[r_operand_mem]:
self.save_to_memory(result_mem, True)
else:
self.save_to_memory(result_mem, False)
elif operator == '<':
if self.memory[l_operand_mem] < self.memory[r_operand_mem]:
self.save_to_memory(result_mem, True)
else:
self.save_to_memory(result_mem, False)
elif operator == '!=':
if self.memory[l_operand_mem] != self.memory[r_operand_mem]:
self.save_to_memory(result_mem, True)
else:
self.save_to_memory(result_mem, False)
elif operator == '=':
value = self.memory[l_operand_mem]
self.save_to_memory(result_mem, value)
elif operator == 'Goto':
pc = result_mem
continue
elif operator == 'GotoF':
if not self.memory[l_operand_mem]:
pc = result_mem
continue
elif operator == 'GotoT':
if self.memory[l_operand_mem]:
pc = result_mem
continue
elif operator == 'print':
if l_operand_mem == None:
print()
else:
print(self.memory[l_operand_mem], end='')
else:
print("ERROR operator", operator, "not recognized")
pc += 1
def print_memory(self):
for i in range(len(self.memory)):
print(f"Memory[{i}] = {self.memory[i]}")