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 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 __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 __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 apply(self, args): params = self.fun.getCdr().getCar() body = self.fun.getCdr().getCdr() functionEnv = Environment(self.env) while(not (params.isNull())): if(args.isNull()): self._error('invalid expression: arguments do not match parameters') return Nil.getInstance() if(params.isSymbol()): functionEnv.define(params, args) elif(not (params.isPair())): self._error('invalid expression: invalid parameters') return Nil.getInstance() elif(args.isPair()): if(params.getCar().getName() == '.'): params = params.getCdr() if(not params.isSymbol()): self._error('invalid expression: invalid parameter') return Nil.getInstance() functionEnv.define(params.getCar(), args.getCar()) else: self._error('invalid expression') return Nil.getInstance() args = args.getCdr() params = params.getCdr() return Closure.util.begin(body, functionEnv)
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 assign(self, id, value): if self.lookup(id) is not Nil.getInstance(): #Implement similar to find: self.__recursiveAssign(id, value, self.frame) return Nil.getInstance() elif self.env != None: return self.env.assign(id, value) else: sys.stderr.write('ERROR: NAME NOT FOUND')
def eval(self, exp, env): length = Special.util.length(exp) if (length != 3): self._error('invalid expression: invalid number of arguments') return Nil.getInstance() varName = exp.getCdr().getCar() varValue = exp.getCdr().getCdr().getCar() env.assign(varName, varValue.eval(env)) return Nil.getInstance()
def eval(self, exp, env): #sys.stdout.write('inside set.eval') t = Special.util.length(exp) if t != 3: self._error("set error") return Nil.getInstance() else: vars = exp.getCdr().getCar() val = exp.getCdr().getCdr().getCar() env.assign(vars, val.eval(env)) return 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 __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 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 apply(self, args): env = self.getEnv() function = self.getFun() sym = function.getCar() function = function.getCdr().getCar() while (not args == Nil.getInstance() and not args.getCar() == Nil.getInstance()): env.define(sym.getCar(), args.getCar()) sym = sym.getCdr() args = args.getCdr() return function.eval(env)
def eval(self, exp, env): n = Special.util.length(exp) if n < 2: self._error("fourth cond error") return Nil.getInstance() else: return self.__evalClauses(exp.getCdr(), env)
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, 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): 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 qt.eval') t = Special.util.length(exp) if t != 2: self._error("quote error") return Nil.getInstance() else: return exp.getCdr().getCar()
def eval(self, exp, env): length = Special.util.length(exp) if (length >= 1): function = exp.getCar().eval(env) args = Special.util.mapeval(exp.getCdr(), env) return function.apply(args) else: self._error('invalid expression') return Nil.getInstance()
def eval(self, exp, env): #sys.stdout.write('inside let.eval') t = Special.util.length(exp) if t < 3: self._error("first let error") return Nil.getInstance() name = exp.getCdr().getCar() rest = exp.getCdr().getCdr() t = Special.util.length(bind) if t < 1: self._error("second let error") return Nil.getInstance() lenv = Environment(env) if Let.__define(name, env, lenv) < 0: self._error("third let error") return Nil.getInstance() else: return Special.util.begin(rest, lenv)
def __apply0(self): #sys.stdout.write('inside apply0') sym = self.symbol.getName() if sym == "read": scan = Scanner(sys.stdin) parse = Parser(scan, TreeBuilder()) rest = parse.parseExp() if rest != None: return rest return Ident("end-of-file") elif sym == "newline": sys.stdout.write('\n') sys.stdout.flush() return Nil.getInstance() elif sym == "interaction-environment": return BuiltIn.env else: self._error("argument error 0") 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): 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)
def lookup(self, id): 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.lookup(id) else: # get the value out of the list we got from find() return val.getCar()
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): if (Special.util.length(exp) < 3): self._error('invalid expression: not enough arguments') return Nil.getInstance() bindings = exp.getCdr().getCar() body = exp.getCdr().getCdr().getCar() if (Special.util.length(bindings) < 1): self._error('invalid expression: invalid bindings') return Nil.getInstance() letEnv = Environment(env) while (not (bindings.isNull())): bind = bindings.getCar() if (Special.util.length(bind) < 1): self._error('invalid expression: invalid binding') return Nil.getInstance() varName = bind.getCar() varBody = bind.getCdr().getCar() varBody = varBody.eval(env) letEnv.define(varName, varBody) bindings = bindings.getCdr() return Special.util.begin(body, letEnv)
def eval(self, t, env): if not t.getCar().isPair(): x = env.lookup(t.getCar()) if x.isProcedure(): #get parameters as a list params = self.util.mapeval(t.getCdr(), env) return x.apply(params) else: sys.stdout.write("Error: Attempt to invoke a non-procedure") return Nil.getInstance() else: res = t.getCar().eval(env) return res.apply(self.util.mapeval(t.getCdr(), env))
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): 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)