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 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 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 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 __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, 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 buildIdent(self,n): return Ident(n)
elif s == "set!": self.form = Set() elif s == "quote": self.form = Quote() else: self.form = Regular() def print(self, n, p=False): self.form.print(self, n, p) def getCar(self): return self.car def getCdr(self): return self.cdr def setCar(self, a): self.car = a self.parseList() def setCdr(self, d): self.cdr = d def isPair(self): return True if __name__ == "__main__": c = Cons(Ident("Hello"), Ident("World")) c.print(0)
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()
sys.stdout.write(", name = " + tok.getName() + "\n") else: sys.stdout.write("\n") sys.stdout.flush() tok = scanner.getNextToken() else: # Create parser builder = TreeBuilder() parser = Parser(scanner, builder) env = Environment() BuiltIn.setEnv(env) #Environment.populateEnv(env, ini_file) id = Ident("b+") env.define(id, BuiltIn(id)) id = Ident("b-") env.define(id, BuiltIn(id)) id = Ident("b*") env.define(id, BuiltIn(id)) id = Ident("b/") env.define(id, BuiltIn(id)) id = Ident("b=") env.define(id, BuiltIn(id)) id = Ident("b<")