-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVirtualMachine.py
More file actions
158 lines (138 loc) · 7.23 KB
/
VirtualMachine.py
File metadata and controls
158 lines (138 loc) · 7.23 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
from Memory import *
import operator
from time import sleep
global ops
#ops is used for arithmetic operation, this was a cleaner approach than making a condition for every operator
ops = {
"+" : operator.add,
"+*" : operator.add,
"-" : operator.sub,
"*" : operator.mul,
"/" : operator.truediv,
"%" : operator.mod,
"&&" : operator.and_,
"||" : operator.or_,
"==": operator.eq,
"!=": operator.ne,
"<": operator.lt,
"<=": operator.le,
">": operator.gt,
">=": operator.ge
}
def Execute(globalMemoryMap, globalTemporals, globalDirectory, quadruples, constantDirectory):
currentQuadruple = 0
returnStack = []
#Initialize global memory required
globalMemoryMap.insert(1, globalTemporals)
globalMemoryMap.insert(1, None)
programMemory = Memory(globalMemoryMap)
#Assign the constant values to the memory
programMemory.assignConstants(constantDirectory)
#Iterate through the quadruples
while quadruples[currentQuadruple][0] != 'RIP':
quadruple = quadruples[currentQuadruple]
#Funtions
#ERA: creates the memory of the function call
if (quadruple[0] == 'ERA'):
programMemory.assignFunctionMemory(globalDirectory[quadruple[3]][2])
currentQuadruple += 1
#PAR: sends parameters to new memory of function call
elif (quadruple[0] == 'PAR'):
programMemory.assignParameterToNewMemory(programMemory.getValueFromAddress(quadruple[3]), quadruple[3])
currentQuadruple += 1
#GOSUB: 'sleeps' current memory and assigns function call memory as current
elif (quadruple[0] == 'GOSUB'):
programMemory.switchToNewMemory()
returnStack.append(currentQuadruple + 1)
currentQuadruple = quadruple[3]
#RETURN: saves the value to be returned, returns to quadruple after function call and wakes up memory
elif (quadruple[0] == 'RETURN'):
programMemory.assignValueToAddress(programMemory.getValueFromAddress(quadruple[1]), quadruple[3])
currentQuadruple = returnStack.pop()
programMemory.recoverMemory()
#ENDPROC: returns to the quadruple after function call and wakes up memory
elif (quadruple[0] == 'ENDPROC'):
currentQuadruple = returnStack.pop()
programMemory.recoverMemory()
#GotoMain: After assigning any global variables, assigns main memory and goes to main quadruple
elif (quadruple[0] == 'GotoMain'):
#Initialize main function memory required to programMemory
if(globalDirectory['main'][2] is not None):
programMemory.assignMainMemory(globalDirectory['main'][2])
currentQuadruple = quadruple[3]
#Goto: goes to quadruple indicated
elif (quadruple[0] == 'Goto'):
currentQuadruple = quadruple[3]
#GotoF: if false goes to quadruple indicated
elif (quadruple[0] == 'GotoF'):
if(not programMemory.getValueFromAddress(quadruple[1])):
currentQuadruple = quadruple[3]
else:
currentQuadruple += 1
#GotoT: if true goes to quadruple indicated
elif (quadruple[0] == 'GotoT'):
if(programMemory.getValueFromAddress(quadruple[1])):
currentQuadruple = quadruple[3]
else:
currentQuadruple += 1
#input: parses the input to the specified type and saves value to address
elif (quadruple[0] == 'INPUT'):
value = input(quadruple[1])
if(quadruple[2] == 0):
try:
#Can not cast a STRING in float format directly to int, so double cast is used
value = int(float(value))
except:
print("ERROR, the input can not be cast to int")
sys.exit()
elif(quadruple[2] == 1):
try:
value = float(value)
except:
print("ERROR, the input can not be cast to float")
sys.exit()
elif(quadruple[2] == 3):
if (value == 'true' or value == 'false'):
value = value == 'true'
else:
print("ERROR, the input can not be cast to bool")
sys.exit()
programMemory.assignValueToAddress(value, quadruple[3])
currentQuadruple += 1
#Console: prints value from address
elif (quadruple[0] == 'console'):
print(programMemory.getValueFromAddress(programMemory.getValueFromAddress(quadruple[3][0]) if isinstance(quadruple[3], list) else quadruple[3]))
currentQuadruple += 1
#Arithmetic: executes operation based on the operator received, saves resultant value to address
elif (quadruple[0] in ['+', '-', '*', '/', '%']):
if(isinstance(quadruple[1], list) and isinstance(quadruple[2], list)):
quadruple[1] = programMemory.getValueFromAddress(quadruple[1][0])
quadruple[2] = programMemory.getValueFromAddress(quadruple[2][0])
programMemory.assignValueToAddress(ops[quadruple[0]](
programMemory.getValueFromAddress(
programMemory.getValueFromAddress(quadruple[1][0]) if isinstance(quadruple[1], list) else quadruple[1]),
quadruple[2][0] if isinstance(quadruple[2], list) else programMemory.getValueFromAddress(quadruple[2])),
quadruple[3])
currentQuadruple += 1
# Logic: executes operation based on the operator received, saves resultant value to address
elif(quadruple[0] in ['<', '<=', '>', '>=', '==', '!=', '&&', '||']):
programMemory.assignValueToAddress(ops[quadruple[0]](
programMemory.getValueFromAddress(
programMemory.getValueFromAddress(quadruple[1][0]) if isinstance(quadruple[1], list) else quadruple[1]),
programMemory.getValueFromAddress(
programMemory.getValueFromAddress(quadruple[2][0]) if isinstance(quadruple[2], list) else quadruple[2])),
quadruple[3])
currentQuadruple += 1
#Assignation: assigns value to address
elif(quadruple[0] == '='):
programMemory.assignValueToAddress(
programMemory.getValueFromAddress(
programMemory.getValueFromAddress(quadruple[1][0])) if isinstance(quadruple[1], list) else programMemory.getValueFromAddress(quadruple[1]),
programMemory.getValueFromAddress(quadruple[3][0]) if isinstance(quadruple[3], list) else quadruple[3])
currentQuadruple += 1
elif(quadruple[0] == 'VER'):
if((programMemory.getValueFromAddress(quadruple[1]) >= 0) and (programMemory.getValueFromAddress(quadruple[1]) < quadruple[3])):
currentQuadruple+=1
else:
print("Array out of bounds: ", programMemory.getValueFromAddress(quadruple[1]), quadruple[3])
sys.exit()