def __apply1(self, arg): #sys.stdin.write('inside apply1') sym = self.symbol.getName() if sym == "car": return arg.getCar() elif sym == "cdr": return arg.getCdr() elif sym == "number?": return BoolLit.getInstance(arg.isNumber()) elif sym == "symbol?": return BoolLit.getInstance(arg.isSymbol()) elif sym == "null?": return BoolLit.getInstance(arg.isNull()) elif sym == "pair?": return BoolLit.getInstance(arg.isPair()) elif sym == "procedure?": return BoolLit.getInstance(arg.isProcedure()) elif sym == "write": arg.print(-1) return Nil.getInstance() elif sym == "display": StrLit.DoubleQuotes = False arg.print(-1) StrLit.DoubleQuotes = True return Nil.getInstance() elif sym == "load": #sys.stdout.write('load successful') if not arg.isString(): self._error("first argument error") return Nil.getInstance() f = arg.getStrVal() #sys.stdout.write('before try') try: scan = Scanner(open(f)) #sys.stdout.write('1') build = TreeBuilder() #sys.stdout.write('2') parse = Parser(scan, build) #sys.stdout.write('3') head = parse.parseExp() #sys.stdout.write('4') while head != None: head.eval(BuiltIn.env) #sys.stdout.write('loop1') head = parse.parseExp() #sys.stdout.write('loop2') except IOError: self._error("file not found " + f) return Nil.getInstance() else: self._error("first argument error") return Nil.getInstance()
def __evaluate(self, exp, env): if exp.isNull(): return Nil.getInstance() cnd = exp.getCar() if Special.util.length(cnd) < 1: self._error("first cond error") return Nil.getInstance() name = cnd.getCar() rest = cnd.getCdr() if name.isSymbol(): if test.getName() == "else": if not (rest.isNull() or exp.getCdr().isNull()): self._error("second cond error") return Nil.getInstance() return Special.util.begin(rest, env) val = test.eval(env) if val != BoolLit.getInstance(False): if rest.isNull(): return val t = rest.getCar() if t.isSymbol(): if t.getName() == "=>": if Special.util.length(rest) != 2: self._error("third cond error") return Nil.getInstance() func = body.getCdr().getCar().eval(env) return func.apply(val) return Special.util.begin(body, env) else: return self.__evalClauses(exp.getCdr(), env)
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, exp, env): if(Special.util.length(exp) != 2): self._error('invalid expression: incorrect number of arguments') return Nil.getInstance() expressions = exp.getCdr() while(not (expressions.isNull())): clause = expressions.getCar() if(Special.util.length(clause)<1): self._error('invalid expression: invalid cond clause') return Nil.getInstance() test = clause.getCar() body = clause.getCdr() first = body.getCar() if(first == '=>'): body = body.getCdr().getCar().eval(env) else: body = body.eval(env) if(test.isSymbol()): if(test.getName()=='else'): return body.apply(test) test = test.eval(env) if(test == BoolLit(True)): return body.apply(test) expressions = expressions.getCdr() return Nil.getInstance()
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 eval(self, exp, env): condition = exp.getCdr().getCar() if condition.eval(env) == BoolLit.getInstance(True): return exp.getCdr().getCdr().getCar().eval(env) elif not (exp.getCdr().getCdr().getCdr() == Nil.getInstance()): return exp.getCdr().getCdr().getCdr().getCar().eval(env) else: return StrLit("else expression not found")
def eval(self, exp, env): #sys.stdout.write('inside apply.eval') t = Special.util.length(exp) if t < 3 or t > 4: self._error("special if error") return Nil.getInstance() temp = exp.getCdr().getCar() temp1 = exp.getCdr().getCdr().getCar() if t == 3: eexp = Nil.getInstance() else: eexp = exp.getCdr().getCdr().getCdr().getCar() if temp.eval(env) != BoolLit.getInstance(False): return temp1.eval(env) else: return eexp.eval(env)
def eval(self, exp, env): n = Special.util.length(exp) # Test for a valid if statement if (n < 3 or n > 4): self._error( 'invalid expression, incorrect number of arguments for if statement' ) return Nil.getInstance() # extract the conditional test from the if statement testExp = exp.getCdr().getCar() # extract the expression to evaluate if the conditional evaluates to true trueExp = exp.getCdr().getCdr().getCar() # extract the expression to evaluate if the conditional evaluates to false if (n == 3): elseExp = Nil.getInstance( ) # Else expression is unspecified, return Unspecified if implemented else: elseExp = exp.getCdr().getCdr().getCdr().getCar() # evaluate the test and return the desired expression if (testExp.eval(env) == BoolLit.getInstance(True)): return trueExp.eval(env) else: return elseExp.eval(env)
def buildBoolLit(self,b): return BoolLit.getInstance(b)
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 eval(self, exp, env): cond = exp.getCdr() while(cond.getCdr() != Nil.getInstance() and cond.getCar().getCar().eval(env) == BoolLit.getInstance(False)): cond = cond.getCdr() if cond == Nil.getInstance(): return Nil.getInstance() else: return cond.getCar().getCdr().getCar().eval(env)
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(">")