-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctionModule.py
304 lines (261 loc) · 9.96 KB
/
functionModule.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#
# @author: Noe Garcia
#
# @description Holds all the functionality for the python lisp interpreter.
#
# imports
import sys
import opLibrary
# GLOBAL FUNCTION STACKS
funcNames = []
funcDefs = []
# GLOBAL VARIABLE STACK
varNames = []
varDefs = []
# GLOBAL OPERATIONS
logicOps = ["<", ">", "=", "!=", "and", "or", "not"]
arithOps = ["+", "-", "*", "/"]
builtOps = ["car", "cdr", "cons", "sqrt", "pow", "defun", "!set", "define"]
# Takes in the string expression from the main function.
# @return array of expressions
def parseExpression(expStr, depth):
# store the depth
retDepth = depth
# define the empty array for the expression
expr = []
#print(expStr)
# check if end
if expStr == "(quit)":
expr.append("(quit)")
return expr
# check character by index
# if the string is not an expression, return itself
if expStr[0] != "(":
n = 0
tmp = ""
while n < len(expStr) and expStr[n] != " ":
tmp = tmp + expStr[n]
n += 1
expr.append(tmp)
return expr
# parse expression
i = 1
length = len(expStr)
tmp = ""
while i < length:
# recursively call parse for each recurring embedded expression
if expStr[i] == "(":
# add a depth
depth += 1
# push onto stack
newExpr = expStr[i:]
expr.append(parseExpression(newExpr, depth)) # i
# update the index for scope
#print(i)
i += lookForTerminatingExpr(newExpr) - 1
elif expStr[i] == ")":
# return the expression
if retDepth == depth:
# print("returned:", expr)
return expr
else:
tmp = ""
# check if the following is defined as an atom
if expStr[i] == "'" and expStr[i + 1] == "(": # IF '(abc...)
# i += 1
n = lookForTerminatingExpr(expStr[i + 1:])
end = i + n + 2
# the following until the space is an atom
while i < end and i < length:
tmp += expStr[i]
i += 1
expr.append(tmp[1:])
elif expStr[i] == "'" and i < length: # IF 'abc...
# i += 1
while expStr[i] != " " and expStr[i] != ")":
tmp += expStr[i]
i += 1
expr.append(tmp[1:])
# look to build the expression and push to the array
elif expStr[i] != " " and i < length:
while expStr[i] != " " and expStr[i] != ")" and i < length:
tmp += expStr[i]
i += 1
# END OF WHILE
expr.append(tmp)
if expStr[i] == ")":
i -= 1
# END OF IF/ELIF
# iterate through
i += 1
## END OF WHILE
return expr
#sys.exit("Error:: Parsing error, missing )")
# local function to help find the terminating parenthesis
# @return the index of terminating parentheses
def lookForTerminatingExpr(expStr):
scope = 0
n = 1
while n < len(expStr):
if expStr[n] == ")" and scope == 0:
#print(n)
return n
elif expStr[n] == "(":
scope += 1
elif expStr[n] == ")" and scope != 0:
scope -= 1
n += 1
print("Something went wrong!")
return n
# Takes the expression array that was parsed before and
# looks to execute the expressions defined by the user
# @return result of expression as a string
def evaluation(exprList, index):
# print("EVAL::", exprList)
result = exprList[0]
# CHECK FOR RECURSIVE DEPTH
# CHECK FOR BOUNDS
if (exprList[index] == "if"):
# evaluate the condition
exprList[index + 1] = evaluation(exprList[index + 1], 0)
if exprList[index + 1] == "T":
# print("eval true")
return evaluation(exprList[index + 2], 0)
else:
# print("eval false")
return evaluation(exprList[index + 3], 0)
else:
if (index + 1) < len(exprList):
if isinstance(exprList[index + 1], list):
exprList[index + 1] = evaluation(exprList[index + 1], 0)
if (index + 2) < len(exprList):
if isinstance(exprList[index + 2], list):
exprList[index + 2] = evaluation(exprList[index + 2], 0)
# END OF CHECK
# ARRAY INDEX UPDATED
# evaluate conditional
# check the first expression given is a defined keyword
if exprList[index] in logicOps: # logic operations
if exprList[index] == ">": # GREATER THAN
# print("greater than")
# call the greater than function
result = opLibrary.gthan(exprList[index + 1], exprList[index + 2])
if exprList[index] == "<": # LESS THAN
# print("less than")
# call the less than function
result = opLibrary.lthan(exprList[index + 1], exprList[index + 2])
if exprList[index] == "=": # EQUAL TO
# print("equal to")
# call the equal to function
result = opLibrary.equal(exprList[index + 1], exprList[index + 2])
if exprList[index] == "!=": # NOT EQUAL
# print("not equal to")
# call the not equal to function
result = opLibrary.notEqual(exprList[index + 1],
exprList[index + 2])
if exprList[index] == "and": # AND
# print("and op")
# call the AND function
result = opLibrary.logicAnd(exprList[index + 1],
exprList[index + 2])
if exprList[index] == "or": # OR
# print("or op")
# call the OR function
result = opLibrary.logicOr(exprList[index + 1],
exprList[index + 2])
if exprList[index] == "not": # NOT
# print("not op")
# call the NOT function
result = opLibrary.logicNot(exprList[index + 1])
elif exprList[index] in arithOps: # arithmetic operations
if exprList[index] == "+": # ADDITION
# print("addition")
# call the addition function
result = opLibrary.add(exprList[index + 1], exprList[index + 2])
if exprList[index] == "-": # SUBTRACTION
# print("subtraction")
# call the subtraction function
result = opLibrary.sub(exprList[index + 1], exprList[index + 2])
if exprList[index] == "*": # MULTIPLICATION
# print("multiplication")
# call the multiplication function
result = opLibrary.mult(exprList[index + 1], exprList[index + 2])
if exprList[index] == "/": # DIVISION
# print("division")
# call the division function
result = opLibrary.div(exprList[index + 1], exprList[index + 2])
elif exprList[index] in builtOps: # built in functions
if exprList[index] == "car": # CAR
# print("function car")
# call the car function
result = opLibrary.carFunc(exprList[index + 1])
if exprList[index] == "cdr": # CDR
# print("function cdr")
# call the cdr function
result = opLibrary.cdrFunc(exprList[index + 1])
if exprList[index] == "cons": # CONS
# print("function cons")
# call the cons function
result = opLibrary.consFunc(exprList[index + 1],
exprList[index + 2])
if exprList[index] == "sqrt": # SQRT
# print("function sqrt")
# call the square root function
result = opLibrary.exprSqrt(exprList[index + 1])
if exprList[index] == "pow": # POW
# print("function pow")
# call the power function
result = opLibrary.exprPow(exprList[index + 1],
exprList[index + 2])
if exprList[index] == "defun":
print("function defun")
if exprList[index] == "!set": # SET
# push result of expression to var names and var defs
# check if the variable already exists
if exprList[index + 1] in varNames:
# change the value of its definition
n = varNames.index(exprList[index + 1])
varDefs[n] = exprList[index + 2]
else:
# return the resulting variable name
varDefs.append(exprList[index + 2])
varNames.append(exprList[index + 1])
result = exprList[index + 2]
if exprList[index] == "define": # DEFINE
# push result of expression to var names and var defs
# return the resulting variable name
varDefs.append(exprList[index + 2])
varNames.append(exprList[index + 1])
result = exprList[index + 2]
# check if the first expression is a user defined function keyword
if exprList[index] in funcNames:
# user defined functions
print("user defined functions")
# check if the first expression is a user defined variable
if exprList[index] in varNames:
# user defined variables
n = varNames.index(exprList[index])
result = varDefs[n]
return result
# END OF EVALUATION
def swapExpression(exprList):
i = 0
for element in exprList:
# if element is a list
if isinstance(element, list):
# call the function recursively
swapExpression(element)
else:
# if the given element is a variable
if element in varNames:
# swap it for the variable
#print("swapping", element)
n = varNames.index(element)
#print(varDefs[n])
exprList[i] = varDefs[n]
i += 1
#print(exprList)
return exprList
def checkForAtom(a):
# check if the first element is an atom
return False