def __IntOps(self, arg1, arg2): sym = self.symbol.getName() if sym == "b+": return IntLit(arg1 + arg2) elif sym == "b-": return IntLit(arg1 - arg2) elif sym == "b*": return IntLit(arg1 * arg2) elif sym == "b/": return IntLit(arg1 / arg2) elif sym == "b=": return BoolLit.getInstance(arg1 == arg2) elif sym == "b<": return BoolLit.getInstance(arg1 < arg2) else: self._error("Unknown BuiltIn function") return Nil.getInstance()
def buildIntLit(self,i): return IntLit(i)
if val == None and self.env == None: self._error("undefined variable " + id.getName()) return Nil.getInstance() elif val == None: # look up the identifier in the enclosing scope return self.env.lookup(id) else: # get the value out of the list we got from find() return val.getCar() def define(self, id, value): self.frame = Cons(Cons(id, Cons(value, Nil.getInstance())), self.frame) def assign(self, id, value): val = Environment.__find(id, self.frame) if val == None and self.env == None: self._error("undefined variable " + id.getName()) return Nil.getInstance() elif val == None: # look up the identifier in the enclosing scope return self.env.assign(id, value) else: # set the value of the list we got to 'value' return val.setCar(value) if __name__ == "__main__": env = Environment() env.define(Ident("foo"), IntLit(42)) env.print(0)
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 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): 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 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(">")