def setEnv(self, env): # noinspection PyAttributeOutsideInit self.env = Environment(env) if not hasattr(self.env.parent, 'parent'): self.env.parent = Environment(scheme.Globals.Globals, env) # self.env.parent = env.parent if env is not None and hasattr(env, 'parent') else scheme.Globals.Globals return self
def __call__(self, processer, params): e = processer.cenv syntax_object = params[0] syntax_object = processer.process([syntax_object], e) syntax_list = syntax_object.toObject(e) while isinstance(syntax_list, SyntaxSymbol): syntax_list = syntax_list.toObject(e) literals = params[1] patterns = params[2:] for pattern in patterns: if len(pattern) == 2: template = pattern[1:] pattern = pattern[0] guard = True else: template = pattern[2:] guard = pattern[1] pattern = pattern[0] bindings = PatternMatcher(pattern, literals).match(syntax_list) if bindings is None: continue processer.pushStack([guard]) icd = processer.callDepth r = processer.process([guard], processer.cenv) while processer.callDepth > icd: processer.popStackN() processer.popStack(r) if not r: continue env = Environment(processer.cenv) transformedCode = transformCode(template, bindings, env, bindings) return transformedCode[0] raise SyntaxError("syntax-case no case matching %r" % (syntax_list))
def __call__(self, processer, params): params=params[0].toObject(processer.cenv) for pattern in self.patterns: template = pattern[1:] pattern = pattern[0] bindings = PatternMatcher(pattern, self.literals).match(params) if bindings is None: continue env = Environment(self.env) l = {} l.update(globals()) l.update(locals()) #import code #code.InteractiveConsole(locals=l).interact() transformedCode = transformCode(template, bindings, env, self) #osp = processer.stackPointer #processer.popStack(transformedCode) ##processer.ast = transformedCode #processer.stackPointer = osp if scheme.debug.getDebug('syntax'): print 56, transformedCode if len(transformedCode)==1: return transformedCode[0] return transformedCode raise SyntaxError("syntax-rules no case matching %r for %s" % (params, self.name))
def __call__(self, processer, args): retval = None env = Environment(self.env) if (isinstance(self.ast[0], list)): if '.' in self.ast[0]: iter_args = iter(args) for idx, item in enumerate(self.ast[0][:-2]): i = iter_args.next() env[item] = i env[self.ast[0][-1]] = list(iter_args) else: if (len(args) != len(self.ast[0])): raise TypeError("%r expected exactly %i arguments, got %i" % (self, len(self.ast[0]), len(args))) for idx, item in enumerate(self.ast[0]): i = args[idx] env[item] = i else: env[self.ast[0]] = args for i in self.ast[1:]: c = deepcopy([i]) processer.pushStack(c) icd = processer.callDepth retval = processer.process(c, env) while icd < processer.callDepth: processer.popStackN() processer.popStack(retval) if (isinstance(retval, Symbol)) and retval.isBound(env): return retval.toObject(env) return retval
def pushStack(self, ast): if debug.getDebug('pushStack'): import traceback traceback.print_stack() print 'push', self.ast, self.stackPointer self.callStack.put((self.ast, self.cenv, self.stackPointer, 1)) self.ast = ast self.cenv = Environment(self.cenv) self.stackPointer = 0 self.callDepth += 1
def __call__(self, processer, params): env = processer.cenv print 18, env if isinstance(params[0], list): bindings = params[0] e = Environment(env) for binding in bindings: if len(binding[1:]) != 1: raise SyntaxError("let requires a list of pairs for its first argument") if isinstance(binding[1], list): b = binding[1] else: b = binding[1] processer.pushStack(b) r = processer.process(b, Environment(env), processer.initialCallDepth) processer.popStack(r) e[binding[0]] = r # processer.popStack(r) r = processer.process(params[1:], e, processer.callDepth) processer.popStack(r) processer.popStack(r) # processer.stackPointer+=1 return name = params[0] bindings = params[1] vars_ = [i[0] for i in bindings] vals = [processer.process(i[1], Environment(env)) for i in bindings] proc = SimpleProcedure([vars_] + params[2:], env).setName(name) env[name] = proc LOG('LET', 32, [proc] + vals) ret = processer.process([[proc] + vals]) processer.popStack(ret) processer.stackPointer += 1 return
def __call__(self, processer, args): if self.wrapped: if Procedure in providedBy(self.wrapped): return self.wrapped(processer, args) return self.wrapped(args) retval = None env = Environment(self.env) if (isinstance(self.ast[0], list)): # if len(self.ast[0])==1: # env[self.ast[0][0]] = [Symbol('quote'), args] if '.' in self.ast[0]: idx = -1 item = None for idx, item in enumerate(self.ast[0][:-2]): i = args[idx] env[item] = i env[self.ast[0][-1]] = args[idx + 1:] else: if len(self.ast[0]) != len(args): raise SyntaxError( "Macro %r requires exactly %i args, %i given" % (self, len(self.ast[0]), len(args))) for idx, item in enumerate(self.ast[0]): i = args[idx] env[item] = i else: env[self.ast[0]] = [Symbol('quote'), args] o = [] retval = copy_with_quasiquote(processer, env, deepcopy(self.ast[1:]), o_stack=o)[0] LOG("macro", retval) retval = processer.process(retval, processer.cenv) processer.popStack(retval) return
def process(self, _ast, env=None, callDepth=None, quotesExpanded=True): global current_processer current_processer = self if _ast == [[]]: raise SyntaxError() """ :rtype : object :param _ast: :param env: Environment :return: """ try: if callDepth is not None: self.initialCallDepth = callDepth else: self.initialCallDepth = self.callDepth if env is None: self.cenv = self.env else: self.cenv = env self.ast = _ast if not quotesExpanded: self.ast = expand_quotes(self.ast) self.stackPointer = 0 if not isinstance(self.ast, list): if isinstance(self.ast, Symbol): this = self.ast.toObject(self.cenv) else: this = self.ast if self.callDepth: self.popStack(this) else: return this if len(self.ast) == 1 and not isinstance(self.ast[0], list): if isinstance(self.ast[0], Symbol): this = self.ast[0].toObject(self.cenv) else: this = self.ast[0] if self.callDepth > self.initialCallDepth: self.popStack(this) else: return this while True: if self.shouldAbort: raise self.shouldAbort if self.stackPointer >= len( self.ast) and self.callDepth <= self.initialCallDepth: return self.ast[-1] if self.stackPointer >= len(self.ast): for idx, i in enumerate(self.ast): if isinstance(i, Symbol) and i.isBound(self.cenv): self.ast[idx] = i.toObject(self.cenv) initial_call_depth = self.initialCallDepth if isinstance(self.ast[0], Symbol): self.ast[0] = self.ast[0].toObject(self.cenv) if isinstance(self.ast[0], SimpleProcedure): this = self.ast[0] args = self.ast[1:] params = deepcopy(this.ast[0]) e = Environment(this.env) if isinstance(params, list): if '.' in params: iter_args = iter(args) for idx, item in enumerate(params[:-2]): e[item] = iter_args.next() e[params[-1]] = list(iter_args) else: if (isinstance(args, list) and len(args) != len(params)): raise TypeError( "%r expected exactly %i arguments, got %i" % (self.ast[0], len(params), len(args))) if (not isinstance(args, list) and 1 != len(params)): raise TypeError( "%r expected exactly %i arguments, got %i" % (self.ast[0], len(params), len(args))) iter_args = iter(args) for idx, item in enumerate(params): e[item] = iter_args.next() else: e[params] = args self.popStackN() self.pushStack( deepcopy([ Symbol('last'), [Symbol('list')] + this.ast[1:] ])) self.cenv = Environment(e) continue elif Procedure in providedBy(self.ast[0]): r = self.ast[0](self, self.ast[1:]) self.popStack(r) elif Macro in providedBy(self.ast[0]): r = self.ast[0](self, self.ast[1:]) if r is None: continue self.popStack(r) else: r = self.ast[0](*self.ast[1:]) self.popStack(r) self.initialCallDepth = initial_call_depth self.stackPointer += 1 continue this = self.ast[self.stackPointer] if isinstance(this, SyntaxSymbol): this = this.toObject(self.cenv) if isinstance(this, list): self.pushStack(this) continue if isinstance(this, Symbol) and this.isBound(self.cenv): t = this.toObject(self.cenv) while isinstance(t, Symbol) and t.isBound(self.cenv): t = t.toObject(self.cenv) else: t = this if self.stackPointer == 0 and Macro in providedBy(t): initial_call_depth = self.initialCallDepth r = t(self, self.ast[1:]) self.initialCallDepth = initial_call_depth if r is None: continue if isinstance(r, SyntaxSymbol): self.popStack(r) elif not isinstance(r, list): r1 = [lambda *x: r] # self.ast[:] = r1 self.popStack(r1) else: self.ast[:] = r continue if isinstance(this, Symbol) and this.isBound(self.cenv): self.ast[self.stackPointer] = this.toObject(self.cenv) self.stackPointer += 1 except Empty as e: if hasattr(e, 'ret'): return e.ret return self.ast[-1]
def write_nested_code(statement): if not isinstance(statement, list): if isinstance(statement, Symbol): bytecode.nextLine(statement.line) stackptr + 1 loader.loadItem(statement) return True func = statement[0] while isinstance(func, Symbol): bytecode.nextLine(func.line) if func.isBound(obj.env): func = func.toObject(obj.env) else: break if func in basic_ops.keys(): isp = stackptr.ptr for l in statement[1:]: if isinstance(l, list): if not write_nested_code(l): return False continue stackptr + 1 loader.loadItem(l) while stackptr > isp + 1: stackptr - 1 bytecode.append(basic_ops[func]) return True elif func in compare_ops: isp = stackptr.ptr istatement = iter(statement[1:]) lidx = labelidx.next() for l in istatement: if isinstance(l, list): if not write_nested_code(l): return False else: stackptr + 1 loader.loadItem(l) if stackptr > isp + 1: stackptr + 1 if istatement.__length_hint__(): bytecode.append(DUP_TOP) bytecode.append(ROT_THREE) bytecode.append(COMPARE_OP) stackptr - 1 bytecode.append(compare_ops.index(func)) bytecode.append(0) if istatement.__length_hint__(): bytecode.append(JUMP_IF_FALSE_OR_POP) bytecode.append(goto('false%i'%lidx)) stackptr - 1 else: bytecode.append(JUMP_ABSOLUTE) bytecode.append(goto('false%i'%lidx)) bytecode.append(label('false%i'%lidx)) bytecode.append(ROT_TWO) bytecode.append(POP_TOP) stackptr - 1 bytecode.append(label('false%i'%lidx)) return True elif isinstance(func, (BuiltinFunctionType, function, type)): isp = stackptr.ptr istatement = iter(statement[1:]) loader.loadItem(statement[0]) for l in statement[1:]: if isinstance(l, list): if not write_nested_code(l): return False continue stackptr + 1 loader.loadItem(l) bytecode.add(CALL_FUNCTION, len(statement[1:]), 0) return True elif isinstance(func, scheme.define.define): var = statement[1] if isinstance(var, list): return False val = statement[2] if isinstance(val, list): if not write_nested_code(val): return False else: loader.loadItem(val) stackptr +1 bytecode.add(DUP_TOP) bytecode.add(DUP_TOP) loader.storeItem(var) loader.loadItem(obj.env) loader.loadExtraConstant(var) bytecode.add(ROT_THREE,ROT_THREE,ROT_TWO) bytecode.add(STORE_MAP) bytecode.add(POP_TOP) return True elif isinstance(func, scheme.IF.IF): lidx = labelidx.next() if not write_nested_code(statement[1]): return False bytecode.add(JUMP_IF_FALSE_OR_POP, goto('iffalse%i'%lidx)) if not write_nested_code(statement[2]): return False bytecode.add(JUMP_ABSOLUTE, goto('end%i'%lidx)) bytecode.add(label('iffalse%i'%lidx)) if len(statement)==4: bytecode.add(POP_TOP) if not write_nested_code(statement[3]): return False bytecode.add(label('end%i'%lidx)) return True elif isinstance(func, scheme.begin.begin): c = iter(statement[1:]) isp = stackptr.ptr for statement in c: while stackptr > isp: bytecode.append(POP_TOP) stackptr-1 if not isinstance(statement, list): if isinstance(statement, Symbol): bytecode.nextLine(statement.line) stackptr + 1 loader.loadItem(statement) if c.__length_hint__() > 0: bytecode.append(POP_TOP) stackptr - 1 continue if not write_nested_code(statement): return False return True elif isaProcedure(func): ls = len(statement)-1 loader.loadItem(func) if func is not obj: loader.loadItem(scheme.processer.processer) bytecode.add(DUP_TOP) bytecode.add(LOAD_ATTR,names.index("pushStack")%256,names.index("pushStack")//256) loader.loadItem([None]) bytecode.add(CALL_FUNCTION,1,0) bytecode.add(POP_TOP) for arg in statement[1:]: if not write_nested_code(arg): return False if func is not obj: bytecode.add(BUILD_LIST, ls%256,ls//256) bytecode.add(CALL_FUNCTION, 2, 0) else: bytecode.add(CALL_FUNCTION, ls, 0) stackptr-(ls-1) return True elif isinstance(func, Symbol): #not currently resolvable, so we calculate it's value at runtime. If it's a Procedure or special form, we'll apply it. Only use these if unstable optimizations enabled gidx=labelidx.next() if unstable_enabled: ls = len(statement)-1 loader.loadItem(isaProcedure) stackptr+1 loader.loadItem(func) stackptr+1 bytecode.add(DUP_TOP,ROT_THREE,CALL_FUNCTION,1,0) bytecode.add(POP_JUMP_IF_TRUE) bytecode.add(goto("applyProcedure%i"%gidx)) #it's a function for arg in statement[1:]: if not write_nested_code(arg): return False bytecode.add(CALL_FUNCTION, ls, 0) stackptr-(ls-1) bytecode.add(JUMP_ABSOLUTE, goto("end%i"%gidx)) bytecode.add(label("applyProcedure%i"%gidx)) loader.loadItem(scheme.processer.processer) for arg in statement[1:]: if not write_nested_code(arg): return False bytecode.add(BUILD_LIST,ls%256,ls//256) stackptr-(ls-1) bytecode.add(CALL_FUNCTION,2,0) stackptr-3 bytecode.add(label('end%i'%gidx)) return True else: return False elif isinstance(func, list): if not write_nested_code(func): return False for arg in statement[1:]: if not write_nested_code(arg): return False bytecode.add(CALL_FUNCTION, len(statement)-1, 0) stackptr - (len(statement)-2) return True elif isinstance(func, scheme.Lambda.Lambda): if unstable_enabled and lambdas_enabled: p = scheme.processer.processer p.pushStackN() p.cenv=Environment(p.cenv) print 470, 'statically compiling and linking lambda' f = func(p, statement[1:]).toObject({}) try: if isinstance(f, SimpleProcedure): f = makeFunction(f) finally: p.popStackN() loader.loadExtraConstant(f) return True return False else: print type(func) return False