def eval(self, exp, env): length = Special.util.length(exp) if(length != 3): self._error('invalid number of arguments for define') return Nil.getInstance() args = exp.getCdr().getCar() body = exp.getCdr().getCdr() if(args.isPair()): funcName = args.getCar() args = args.getCdr() if(not (funcName.isSymbol)): self._error('invalid function name') return Nil.getInstance() params = args while(params.isPair()): if(not (params.getCar().isSymbol())): self._error('invalid parameter') return Nil.getInstance() params = params.getCdr() function = Cons(Ident('lambda'), Cons(args, body)) function = function.eval(env) env.define(funcName, function) return Nil.getInstance() if(args.isSymbol): env.define(args, body.getCar().eval(env)) return Nil.getInstance() self._error('invalid expression with define')
def define(self, id, value): # TODO: implement this function node = find(id, self.frame) if (node == None): self.frame = Cons(Cons(id, Cons(value, Nil())), self.frame) else: node.setCar(value)
def eval(self, t, env): #if variable definition if t.getCdr().getCar().isSymbol(): env.define( t.getCdr().getCar(), Cons(t.getCdr().getCdr().getCar().eval(env), Nil.getInstance())) #If definition is for a closure elif t.getCdr().getCar().isPair(): env.define(t.getCdr().getCar().getCar(), Cons(Closure(t.getCdr(), env), Nil.getInstance())) return Nil.getInstance()
def __apply2(self, arg1, arg2): #sys.stdout.write('inside apply2') sym = self.symbol.getName() if sym == "eq?": return BoolLit.getInstance(arg1 is arg2) elif sym == "cons": return Cons(arg1, arg2) elif sym == "set-car!": arg1.setCar(arg2) return Nil.getInstance() elif sym == "set-cdr!": arg1.setCdr(arg2) return Nil.getInstance() elif sym == "eval": if arg2.isEnvironment(): return arg1.eval(arg2) self._error("second argument error") return Nil.getInstance() elif sym == "apply": return arg1.apply(arg2) else: if sym[0] == "b": pass if len(sym) == 2: if arg1.isNumber(): if arg2.isNumber(): return self.__IntOps(arg1.getIntVal(), arg2.getIntVal()) self._error("argument error") return Nil.getInstance() self._error("argument error") return Nil.getInstance()
def eval(self, t, env): newEnv = Environment(env) bindings = t.getCdr().getCar() for i in range(self.util.length(bindings)): identifier = bindings.getCar().getCar() val = bindings.getCar().getCdr().getCar().eval(env) newEnv.define(identifier, Cons(val, Nil.getInstance())) bindings = bindings.getCdr() body = t.getCdr().getCdr() return self.util.begin(body, newEnv)
def assign(self, id, value): # TODO: implement this function node = find(id, self.frame) if node == None and self.env == None: err = "Error: undefined variable" errors.append(err) elif node == None: assign(id, self.env) else: setCar(Cons(id, value))
def __recursiveAssign(self, id, value, alist): if not alist.isPair(): sys.stderr.write( "ERROR: ENVIRONMENT IS EMPTY" ) #should never reach this, but error in place just in case else: bind = alist.getCar() if id.getName() == bind.getCar().getName(): bind.setCdr(Cons(value, Nil.getInstance())) else: self.__recursiveAssign(id, value, alist.getCdr())
def setEnv(cls, e): cls.env = e #TODO: Cleanup builtins = [ "b+", "b-", "b/", "b*", "b=", "b<", "number?", "null?", "procedure?", "pair?", "cons", "car", "cdr", "set-car!", "set-cdr!", "eq?", "interaction-environment", "load", "read", "write", "display", "eval", "apply", "newline" ] for i in builtins: cls.env.define(Ident(i), Cons(BuiltIn(StrLit(i)), Nil.getInstance()))
def eval(self, exp, env): #sys.stdout.write('inside define.eval') t = Special.util.length(exp) if t < 3: self._error("define error") return Nil.getInstance() elif exp.getCdr().getCar().isPair(): vars = exp.getCdr().getCar() parms = vars.getCdr() sym = vars.getCar() rest = exp.getCdr().getCdr() func = Cons(Ident("lambda"), Cons(parms, rest)) env.define(sym, func.eval(env)) return Nil.getInstance() else: vars = exp.getCdr().getCar() val = exp.getCdr().getCdr().getCar() if vars.isSymbol(): if t == 3: env.define(vars, val.eval(env)) return Nil.getInstance()
def eval(self, exp, env): key = exp.getCdr().getCar() val = exp.getCdr().getCdr().getCar() # if defining a variable if key.isSymbol(): env.define(key, val) # if defining a function else: func = Closure( Cons(exp.getCdr().getCar().getCdr(), exp.getCdr().getCdr()), env) env.define(key.getCar(), func) return StrLit("no values returned")
def apply(self, args): #create a new enviroment where env will be the current env then #the frame variable of the new enviroment will represent the function environment environment = Environment(self.getEnv()) parameters = self.fun.getCar() body= self.fun.getCdr() #Check that argument count is correct, if the parameters are a well-formed list if self.util.length(parameters) != -1 and self.util.length(parameters) is not self.util.length(args): sys.stdout.write("Invalid argument count\n") return Nil.getInstance() #Map all required parameters to arguments while parameters.isPair(): environment.define(parameters.getCar(), Cons(args.getCar(), Nil.getInstance())) args = args.getCdr() parameters = parameters.getCdr() #if there is a remaining list argument, define it if not parameters.isNull(): environment.define(parameters, Cons(args, Nil.getInstance())) #evaluating function return self.util.begin(body,environment)
def populateEnv(cls, env, ini_file): builtIns = [ 'symbol?', 'number?', 'b+', 'b-', 'b*', 'b/', 'b=', 'b<', 'car', 'cdr', 'cons', 'set-car!', 'set-cdr!', 'null?', 'pair?', 'eq?', 'procedure?', 'read', 'write', 'display', 'newline', 'eval', 'apply', 'interaction-environment', 'load' ] for name in builtIns: id = Ident(name) env.define(id, BuiltIn(id)) if os.path.exists(ini_file): #sys.stdout.write('path exists') path = env.lookup(Ident('load')) path.apply(Cons(StrLit(ini_file), Nil.getInstance()))
def populateEnv(env, file): # Array of builtIn names builtIns = [ 'read', 'newline', 'interaction-environment', 'load', 'car', 'cdr', 'number?', 'symbol?', 'null?', 'pair?', 'procedure?', 'write', 'display', 'eq?', 'cons', 'set-car!', 'set-cdr!', 'eval', 'apply', 'b+', 'b-', 'b*', 'b/', 'b=', 'b<' ] # for each name in the builtIns array, define it in the environment for name in builtIns: node = Ident(name) env.define(node, BuiltIn(node)) # as long as the file exists, load file into the environment using the load built-in function if os.path.exists(file): load = env.lookup(Ident('load')) load.apply(Cons(StrLit(file), Nil.getInstance()))
def define(self, id, value): # TODO: implement this function #sys.stdout.write('inside environment.define') val = Environment.__find(id, self.frame) if val is not None: val.setCar(value) else: head = Cons(Cons(id, Cons(value, Nil.getInstance())), Nil.getInstance()) head.setCdr(self.frame) self.frame = head
def frame(self, exp, env): if exp == Nil.getInstance(): return Cons(Nil.getInstance(),Nil.getInstance()) else: argument = exp.getCar().getCar() expression = exp.getCar().getCdr().getCar() rest = exp.getCdr() if argument.isSymbol(): env.define(argument, expression.eval(env)) return self.frame(rest, env) elif argument.isPair(): return argument.eval(env) elif argument == Nil.getInstance(): return Nil.getInstance() return Nil.getInstance()
def define(self, id, value): self.frame = Cons(Cons(id, Cons(value, Nil.getInstance())), self.frame)
def apply(self, args): argLength = self.util.length(args) name = self.symbol.strVal if name == "b+": #Binary Addition if argLength is not 2: return self.invalidArgCount() if not args.getCar().isNumber() or not args.getCdr().getCar( ).isNumber(): return self.invalidArgType() sum = args.getCar().intVal + args.getCdr().getCar().intVal return IntLit(sum) elif name == "b-": #Binary Subtraction if argLength is not 2: return self.invalidArgCount() if not args.getCar().isNumber() or not args.getCdr().getCar( ).isNumber(): return self.invalidArgType() diff = args.getCar().intVal - args.getCdr().getCar().intVal return IntLit(diff) elif name == "b*": #Binary Multiplication if argLength is not 2: return self.invalidArgCount() if not args.getCar().isNumber() or not args.getCdr().getCar( ).isNumber(): return self.invalidArgType() return IntLit(args.getCar().intVal * args.getCdr().getCar().intVal) elif name == "b/": #Binary Division if argLength is not 2: return self.invalidArgCount() if not args.getCar().isNumber() or not args.getCdr().getCar( ).isNumber(): return self.invalidArgType() return IntLit(args[0].intVal / args.getCdr().getCar().intVal) elif name == "number?": #Check if is a number if argLength is not 1: return self.invalidArgCount() if args.getCar().isNumber(): return BoolLit.getInstance(True) return BoolLit.getInstance(False) elif name == "b=": if argLength is not 2: return self.invalidArgCount() if not args.getCar().isNumber() or not args.getCdr().getCar( ).isNumber(): return self.invalidArgType() return BoolLit.getInstance(True) if args.getCar( ).intVal == args.getCdr().getCar().intVal else BoolLit.getInstance( False) elif name == "b<": if argLength is not 2: return self.invalidArgCount() if not args.getCar().isNumber() or not args.getCdr().getCar( ).isNumber(): return self.invalidArgType() return BoolLit.getInstance(True) if args.getCar( ).intVal < args.getCdr().getCar().intVal else BoolLit.getInstance( False) elif name == "null?": if argLength is not 1: return self.invalidArgCount() if args.getCar().isNull(): return BoolLit.getInstance(True) return BoolLit.getInstance(False) elif name == "procedure?": if argLength is not 1: return self.invalidArgCount() if args.getCar().isProcedure(): return BoolLit.getInstance(True) return BoolLit.getInstance(False) elif name == "pair?": if argLength is not 1: return self.invalidArgCount() return BoolLit.getInstance( True) if args.getCar().isPair() else BoolLit.getInstance(False) elif name == "cons": if argLength is not 2: return self.invalidArgCount() return Cons(args.getCar(), args.getCdr().getCar()) elif name == "car": if argLength is not 1: return self.invalidArgCount() if not args.getCar().isPair(): return self.invalidArgType() return args.getCar().getCar() elif name == "cdr": if argLength is not 1: return self.invalidArgCount() if not args.getCar().isPair(): return self.invalidArgType() return args.getCar().getCdr() elif name == "set-car!": if argLength is not 2: return self.invalidArgCount() if not args.getCar().isPair(): return self.invalidArgType() args.getCar().setCar(args.getCdr().getCar()) return Nil.getInstance() elif name == "set-cdr!": if argLength is not 2: return self.invalidArgCount() if not args.getCar().isPair(): return self.invalidArgType() args.getCar().setCdr(args.getCdr().getCar()) return Nil.getInstance() elif name == "eq?": if args.getCar().isSymbol() and args.getCdr().getCar().isSymbol(): arg1_name = args.getCar().getName() arg2_name = args.getCdr().getCar().getName() return BoolLit.getInstance(arg1_name == arg2_name) return BoolLit.getInstance(args.getCar() == args.getCdr().getCar()) #load elif name == "load": if not args.getCar().isString(): return self.invalidArgType() filename = args.getCar().strVal try: scanner = Scanner(open(filename)) builder = TreeBuilder() parser = Parser(scanner, builder) root = parser.parseExp() while root != None: root.eval(BuiltIn.env) root = parser.parseExp() except IOError: self._error("could not find file " + filename) return Nil.getInstance() # or Unspecific.getInstance() #read, calls parser and returns a parse tree elif name == "read": scanner = Scanner(sys.stdin) builder = TreeBuilder() parser = Parser(scanner, builder) #return parse tree here if parser != None: return parser.parseExp() return Ident('End of Parse Tree') #write, calls pretty printer elif name == "write": if argLength is not 1: return self.invalidArgCount() args.getCar().print(-1) return Nil.getInstance() #display, calls pretty printer elif name == "display": if argLength is not 1: return self.invalidArgCount() StrLit.include_quote = 0 args.getCar().print(-1) StrLit.include_quote = 1 return Nil.getInstance() #eval, calls python eval function elif name == 'eval': if argLength is not 2: return self.invalidArgCount() if args.getCdr().getCar().isEnvironment(): return args.getCar().eval(args.getCdr().getCar()) return self.invalidArgType() #apply, calls python apply function elif name == "apply": if argLength is not 2: return self.invalidArgCount() return args.getCar().apply(args.getCdr().getCar()) #interaction-environment, returns a pointer to interpreter's global environment elif name == "interaction-environment": return BuiltIn.env #newline without optional port argument elif name == "newline": sys.stdout.write('\n') sys.stdout.flush() return Nil.getInstance() return StrLit("Error: BuiltIn.apply not yet implemented for " + self.symbol)
def mapeval(self, exp, env): if exp.isNull(): return Nil.getInstance() return Cons(exp.getCar().eval(env), self.mapeval(exp.getCdr(), env))
def define(self, id, value): self.frame = Cons(Cons(id, value), self.frame)
from Tree import Environment from Tree import Closure from Special import Special from Util import Util if __name__ == "__main__": # Initialization file with Scheme definitions of built-in functions ini_file = "ini.scm" prompt = "> " # Create scanner that reads from standard input scanner = Scanner(sys.stdin) util = Util() Cons.setUtil(util) BuiltIn.setUtil(util) Closure.setUtil(util) Special.setUtil(util) if (len(sys.argv) > 2 or (len(sys.argv) == 2 and sys.argv[1] != "-d")): sys.stderr.write("Usage: python3 SPP.py [-d]\n") sys.stderr.flush() sys.exit(2) # If command line option -d is provided, debug the scanner. if len(sys.argv) == 2 and sys.argv[1] == "-d": tok = scanner.getNextToken() while tok != None: tt = tok.getType()
def apply(self, args): # Retrive the length of the argument length = BuiltIn.util.length(args) # Error check for invalid number of arguments if (length > 2): self._error('invalid expression: too many arguments') return Nil.getInstance() # Extract the name name = self.symbol.getName() # Apply for arguments of length 0 if (length == 0): if (name == "read"): scanner = Scanner(sys.stdin) builder = TreeBuilder() parser = Parser(scanner, builder) result = parser.parseExp() if (result != None): return result return Ident('end-of-file') if (name == "newline"): sys.stdout.write('\n') sys.stdout.flush() return Nil.getInstance() if (name == "interaction-environment"): return self.env self._error('unknown built-in function') return Nil.getInstance() # Apply for arguments of length 1 if (length == 1): # Retrieve the argument arg1 = args.getCar() # Apply for load if (name == "load"): if (not arg1.isString()): self._error("wrong type of argument") return Nil.getInstance() filename = arg1.getStrVal() try: scanner = Scanner(open(filename)) builder = TreeBuilder() parser = Parser(scanner, builder) root = parser.parseExp() while root != None: root.eval(BuiltIn.env) root = parser.parseExp() except IOError: self._error("could not find file " + filename) return Nil.getInstance() # or Unspecific, if implemented # Apply for car if (name == "car"): return arg1.getCar() # Apply for cdr if (name == "cdr"): return arg1.getCdr() # Apply for number? if (name == "number?"): return BoolLit.getInstance(arg1.isNumber()) # Apply for symbol? if (name == "symbol?"): return BoolLit.getInstance(arg1.isSymbol()) # Apply for null? if (name == "null?"): return BoolLit.getInstance(arg1.isNull()) # Apply for pair? if (name == "pair?"): return BoolLit.getInstance(arg1.isPair()) # Apply for procedure? if (name == "procedure?"): return BoolLit.getInstance(arg1.isProcedure()) # Apply for write if (name == "write"): arg1.print(-1) return Nil.getInstance() # Apply for display if (name == "display"): StrLit.printQuotes = False arg1.print(-1) StrLit.printQuotes = True return Nil.getInstance() self._error('unknown built-in function') return Nil.getInstance() # Apply for arguments of length 2 if (length == 2): # Retrieve the two arguments arg1 = args.getCar() arg2 = args.getCdr().getCar() if (name == "eq?"): if (arg1.isSymbol()): if (arg2.isSymbol()): name1 = arg1.getName() name2 = arg2.getName() return BoolLit.getInstance(name1 == name2) else: return BoolLit.getInstance(False) return BoolLit.getInstance(arg1 == arg2) if (name == "cons"): return Cons(arg1, arg2) if (name == "set-car!"): arg1.setCar(arg2) return Nil.getInstance() if (name == "set-cdr!"): arg1.setCdr(arg2) return Nil.getInstance() if (name == "eval"): return arg1.eval(arg2) if (name == "apply"): return arg1.apply(arg2) if (name[0] == 'b'): if (arg1.isNumber()): if (arg2.isNumber()): arg1 = arg1.getIntVal() arg2 = arg2.getIntVal() if (name == 'b+'): return IntLit(arg1 + arg2) if (name == 'b-'): return IntLit(arg1 - arg2) if (name == 'b*'): return IntLit(arg1 * arg2) if (name == 'b/'): return IntLit(arg1 / arg2) if (name == 'b='): return BoolLit.getInstance(arg1 == arg2) if (name == 'b<'): return BoolLit.getInstance(arg1 < arg2) self._error('unknown built-in function') return Nil.getInstance() else: self._error('invalid argument type') return Nil.getInstance() else: self._error('invalid argument type') return Nil.getInstance() self._error('unknown built-in function') return Nil.getInstance()
def apply(self, args): ## The easiest way to implement BuiltIn.apply is as an ## if-then-else chain testing for the different names of ## the built-in functions. E.g., here's how load could ## be implemented: # if name == "load": # if not arg1.isString(): # self._error("wrong type of argument") # return Nil.getInstance() # filename = arg1.getStrVal() # try: # scanner = Scanner(open(filename)) # builder = TreeBuilder() # parser = Parser(scanner, builder) # root = parser.parseExp() # while root != None: # root.eval(BuiltIn.env) # root = parser.parseExp() # except IOError: # self._error("could not find file " + filename) # return Nil.getInstance() # or Unspecific.getInstance() # this may or may not work # get args (arg 1 is the car, arg 2 is the car of the cdr) if args == None: return Nil.getInstance() name = self.symbol.getName() car = args.getCar() if car.isNull(): car = Nil.getInstance() cdr = args.getCdr() # if there is no arg 2, just set it to nil if cdr.isNull(): cdr = Nil.getInstance() # otherwise arg2 is the car of the cdr else: cdr = cdr.getCar() if name == "b+": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return IntLit(x + y) else: return StrLit("Invalid arguments for b+") elif name == "b-": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return IntLit(x - y) else: return StrLit("Invalid arguments for b-") elif name == "b*": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return IntLit(x * y) else: return StrLit("Invalid arguments for b*") elif name == "b/": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return IntLit(x / y) else: return StrLit("Invalid arguments for b/") elif name == "b=": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return BoolLit.getInstance(x == y) else: return StrLit("Invalid arguments for b=") elif name == "b<": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return BoolLit.getInstance(x < y) else: return StrLit("Invalid arguments for b<") elif name == "b>": if car.isNumber() and cdr.isNumber(): x = car.intVal y = cdr.intVal return BoolLit.getInstance(x > y) else: return StrLit("Invalid arguments for b>") elif name == "car": if car.isPair(): return car.getCar() return StrLit("Wrong number of arguements") elif name == "cdr": if car.isPair(): return car.getCdr() return StrLit("Wrong number of arguements") elif name == "cons": if cdr.isPair(): return Cons(car, cdr) return StrLit("Wrong number of arguements") elif name == "set-car!": #does this work?? car.setCar(cdr) return car elif name == "set-cdr!": #does this work?? car.setCdr(cdr) return car elif name == "symbol?": return BoolLit.getInstance(car.isSymbol()) elif name == "number?": return BoolLit.getInstance(car.isNumber()) elif name == "null?": return BoolLit.getInstance(car == Nil.getInstance()) elif name == "pair?": return BoolLit.getInstance(car.isPair()) elif name == "eq?": #come back to this if car.isBool() and cdr.isBool(): return BoolLit.getInstance(car.boolVal == cdr.boolVal) elif car.isNumber() and cdr.isNumber(): return BoolLit.getInstance(car.intVal == cdr.intVal) elif car.isSymbol() and cdr.isSymbol(): return BoolLit(car.getName().equals(cdr.getName())) elif car == Nil.getInstance(): return BoolLit.getInstance(True) elif (car.isPair() and cdr.isPair()): opener = Cons(car.getCar(), Cons(cdr.getCar(), Nil.getInstance())) closer = Cons(car.getCdr(), Cons(cdr.getCdr(), Nil.getInstance())) return BoolLit(apply(opener).boolVal and apply(closer).boolVal) elif name == "procedure?": return BoolLit.getInstance(car.isProcedure()) elif name == "display": return car elif name == "newline": #come back to this StrLit("") elif name == "read": parser = Parser(Scanner(sys.stdin)) #com back to this return parser.parseExp() elif name == "write": #come back to this car.print(0) return StrLit("") elif name == "eval": #come back return car elif name == "apply": #come back return car.apply(cdr) elif name == "interaction-development": #come back interaction_environment.print(0) elif name == "load": #come back if not car.isString(): self._error("wrong type of argument") return Nil.getInstance() filename = arg1.getStrVal() try: scanner = Scanner(open(filename)) builder = TreeBuilder() parser = Parser(scanner, builder) root = parser.parseExp() while root != None: root.eval(BuiltIn.env) root = parser.parseExp() except IOError: self._error("could not find file " + filename) return Nil.getInstance() # or Unspecific.getInstance() else: car.print(0) return Nil.getInstance() return StrLit(">")
def apply(self, args): if args == None: return None symbolName = self.symbol.getName() arg1 = args.getCar() if arg1 == None or arg1.isNull(): arg1 = Nil() arg2 = args.getCdr() if arg2 == None or arg2.isNull(): arg2 = Nil() if symbolName == '+': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return IntLit(x + y) else: print('bad argument for +') return StrLit("") elif symbolName == '-': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return IntLit(x - y) else: print('bad argument for -') return StrLit("") elif symbolName == '*': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return IntLit(x * y) else: print('bad argument for *') return StrLit("") elif symbolName == '/': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return IntLit(x / y) else: print('bad argument for /') return StrLit("") elif symbolName == '=': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return BoolLit(x == y) else: print('bad argument for =') elif symbolName == '<': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return BoolLit(x < y) else: print('bad argument for <') elif symbolName == '>': if arg1.isNumber() and arg2.isNumber(): x = arg1.getIntVal() y = arg2.getIntVal() return BoolLit(x > y) else: print('bad argument for >') elif symbolName == 'car': if arg1.isNull(): return arg1 return arg1.getCar() elif symbolName == 'cdr': if arg1.isNull(): return arg1 return arg1.getCdr() elif symbolName == 'cons': return Cons(arg1, arg2) elif symbolName == 'set-car!': arg1.setCar(arg2) return arg1 elif symbolName == 'set-cdr!': arg1.setCdr(arg2) return arg1 elif symbolName == 'symbol?': return BoolLit(arg1.isSymbol()) elif symbolName == 'number?': return BoolLit(arg1.isNumber()) elif symbolName == 'null?': return BoolLit(arg1.isNull()) elif symbolName == 'pair?': return BoolLit(arg1.isPair()) elif symbolName == 'eq?': if (arg1.isBool() and arg2.isBool()) or (arg1.isNumber() and arg2.isNumber()) or ( arg1.isString() and arg2.isString()): return BoolLit(arg1 == arg2) elif arg1.isSymbol() and arg2.isSymbol(): return BoolLit(arg1.getName() == arg2.getName()) elif arg1.isNull() and arg2.isNull(): return BoolLit(True) elif arg1.isPair() and arg2.isPair(): frontArgs = Cons(arg1.getCar(), Cons(arg2.getCar(), Nil)) backArgs = Cons(arg1.getCdr(), Cons(arg2.getCdr(), Nil)) return BoolLit(apply(frontArgs) and apply(backArgs)) return BoolLit(false) elif symbolName == 'procedure?': return BoolLit(arg1.isProcedure) elif symbolName == 'display': return arg1 elif symbolName == 'newline': return StrLit("", false) elif symbolName == 'exit' or symbolName == 'quit': exit() elif symbolName == 'write': arg1.print(0) elif symbolName == 'eval': return arg1 elif symbolName == 'apply': return arg1.apply(arg2) elif symbolName == 'read': parser = Parser() return parser.parseExp() elif symbolName == 'interaction-environment': self.env.print(0) else: arg1.print(0) return Nil() return StrLit('>')
def buildCons(self,a, d): return Cons(a, d)
def define(self, id, value): # create the id, value pair idValue = Cons(id, Cons(value, Nil.getInstance())) # change the frame to include the id, value pair self.frame = Cons(idValue, self.frame)