Documentation and report.

This commit is contained in:
etc404
2026-04-27 01:44:38 -06:00
parent b04f9945ea
commit c65b29485b
6 changed files with 102 additions and 39 deletions
+18 -17
View File
@@ -1,20 +1,11 @@
import math
import string
from functools import reduce
def prettyprint(expression) -> str:
if type(expression) is list:
retvalue = "("
for x in expression:
retvalue += prettyprint(x) + " "
return retvalue.rstrip() + ")"
elif type(expression) is bool:
return "T" if expression else "NIL"
elif str():
return expression.upper()
else:
return str(expression)
### LISP.PY
### Autumn Wolf
### 04/26/26
### CSE3024
# This file (and contained class) handles lisp interpreter details, environment management, and expression evaluation.
class Function:
def __init__(self, parameters, expression):
@@ -28,11 +19,15 @@ class Lisp:
else:
self.env = env
# Recursively evaluate an expression
def evaluate(self, expression):
# Handle literals
if type(expression) is not list:
if expression in self.env.keys():
return self.env[expression]
return expression
# Handling of some special operations
operation = expression[0]
if type(operation) is list:
operation = self.evaluate(operation)
@@ -41,7 +36,7 @@ class Lisp:
if operation == "QUOTE":
return expression[1:][0]
if operation != "DEFUN":
arguments = [self.evaluate(x) for x in expression[1:]]
arguments = [self.evaluate(x) for x in expression[1:]] # Don't evaluate for defun or quote!
else:
arguments = expression[1:]
match operation:
@@ -53,6 +48,7 @@ class Lisp:
return reduce(lambda x,y: x*y, arguments)
case "/":
return reduce(lambda x,y: x/y, arguments)
case "CAR":
if len(arguments) != 1:
raise ValueError("Expected 1 argument")
@@ -68,6 +64,7 @@ class Lisp:
return [arguments[0]]+arguments[1]
else:
return [arguments[0]]+arguments[1]
case "SQRT":
if len(arguments) != 1:
raise ValueError("Expected 1 argument")
@@ -76,6 +73,7 @@ class Lisp:
if len(arguments) != 2:
raise ValueError("Expected 2 arguments")
return pow(arguments[0], arguments[1])
case "IF":
if len(arguments) != 3:
raise ValueError("Expected 3 arguments")
@@ -111,9 +109,11 @@ class Lisp:
if len(arguments) != 1:
raise ValueError("Expected 1 argument")
return not arguments[0]
case "QUIT":
print(">> bye")
raise SystemExit
case "DEFINE":
if len(arguments) != 2:
raise ValueError("Expected 2 arguments")
@@ -132,6 +132,7 @@ class Lisp:
else:
raise ValueError("Undefined variable: " + str(arguments[0]))
return arguments[0]
case "MAPCAR":
if len(arguments) != 3:
raise ValueError("Expected 3 arguments")
@@ -140,14 +141,14 @@ class Lisp:
result.append(self.evaluate([arguments[0], arguments[1][i], arguments[2][i]]))
return result
case _:
if operation in self.env.keys():
if operation in self.env.keys(): # Check for user-defined functions
if type(self.env[operation]) == Function:
func = self.env[operation]
functionrunner = Lisp(self.env)
if len(arguments) != len(func.parameters):
raise ValueError("Expected " + str(len(func.parameters)) + " arguments")
for i in range(0, len(arguments)):
functionrunner.env[func.parameters[i]] = arguments[i]
functionrunner.env[func.parameters[i]] = arguments[i] # Populate sub-interpreter environment
return functionrunner.evaluate(self.env[operation].expression)
else:
raise TypeError("This value is not a valid function: " + operation)