def syntaxQuote(self, form): from py.clojure.lang.compiler import builtins as compilerbuiltins if form in compilerbuiltins: ret = RT.list(_QUOTE_, form) elif isinstance(form, Symbol): sym = form if sym.ns is None and sym.name.endswith("#"): gmap = GENSYM_ENV.deref() if gmap == None: raise ReaderException("Gensym literal not in syntax-quote, before", self.rdr) gs = gmap[sym] if gs is None: gs = symbol(None, sym.name[:-1] + "__" + str(RT.nextID()) + "__auto__") GENSYM_ENV.set(gmap.assoc(sym, gs)) sym = gs elif sym.ns is None and sym.name.endswith("."): ret = sym elif sym.ns is None and sym.name.startswith("."): ret = sym elif sym.ns is not None: ret = sym else: comp = currentCompiler.get(lambda: None) if comp is None: raise IllegalStateException("No Compiler found in syntax quote!") ns = comp.getNS() if ns is None: raise IllegalStateException("No ns in reader") sym = symbol(ns.__name__, sym.name) ret = RT.list(_QUOTE_, sym) else: if isUnquote(form): return form.next().first() elif isUnquoteSplicing(form): raise IllegalStateException("splice not in list") elif isinstance(form, IPersistentCollection): if isinstance(form, IPersistentMap): keyvals = flattenMap(form) ret = RT.list(_APPLY_, _HASHMAP_, RT.list(RT.cons(_CONCAT_, self.sqExpandList(keyvals.seq())))) elif isinstance(form, (IPersistentVector, IPersistentSet)): ret = RT.list(_APPLY_, _VECTOR_, RT.list(_SEQ_, RT.cons(_CONCAT_, self.sqExpandList(form.seq())))) elif isinstance(form, (ISeq, IPersistentList)): seq = form.seq() if seq is None: ret = RT.cons(_LIST_, None) else: ret = RT.list(_SEQ_, RT.cons(_CONCAT_, self.sqExpandList(seq))) else: raise IllegalStateException("Unknown collection type") elif isinstance(form, (int, float, str, Keyword)): ret = form else: ret = RT.list(_QUOTE_, form) if hasattr(form, "meta") and form.meta() is not None: newMeta = form.meta().without(LINE_KEY) if len(newMeta) > 0: return RT.list(_WITH_META_, ret, self.syntaxQuote(form.meta())) return ret
def getNamesString(self, markused=True): if self.names is None: return "fn_"+str(RT.nextID()) s = str(self.names) if markused and self.names is not None: self.names.isused = True return s
def __str__(self): v = [] r = self while r is not None: v.append(r.name) r = r.rest v.reverse() s = "_".join(v) if self.isused: s = s + str(RT.nextID()) return s
def compileFNStar(comp, form): haslocalcaptures = False aliases = [] if len(comp.aliases) > 0: # we got a closure to deal with for x in comp.aliases: comp.pushAlias(x, Closure(x)) aliases.append(x) haslocalcaptures = True orgform = form if len(form) < 2: raise CompilerException("2 or more arguments to fn* required", form) form = form.next() name = form.first() pushed = False if not isinstance(name, Symbol): comp.pushName(name) pushed = True name = Symbol.intern("fn" + str(RT.nextID())) else: form = form.next() if isinstance(form.first(), IPersistentVector): code = compileFn(comp, name, form, orgform) else: code = compileMultiFn(comp, name, form) if pushed: comp.popName() clist = comp.closureList() fcode = [] if haslocalcaptures: comp.popAliases(aliases) if clist: for x in clist: fcode.extend(comp.getAlias(x.sym).compile(comp)) # Load our local version fcode.append((STORE_DEREF, x.sym.name)) # Store it in a Closure Cell fcode.append((LOAD_CLOSURE, x.sym.name)) # Push the cell on the stack fcode.append((BUILD_TUPLE, len(clist))) fcode.extend(code) fcode.append((MAKE_CLOSURE, 0)) code = fcode return code
def compileFNStar(comp, form): haslocalcaptures = False if len(comp.locals) > 0: # we got a closure to deal with comp.pushLocalCaptures() haslocalcaptures = True orgform = form if len(form) < 2: raise CompilerException("2 or more arguments to fn* required", form) form = form.next() name = form.first() pushed = False if not isinstance(name, Symbol): comp.pushName(name) pushed = True name = Symbol.intern("fn" + str(RT.nextID())) else: form = form.next() if isinstance(form.first(), IPersistentVector): code = compileFn(comp, name, form, orgform) else: code = compileMultiFn(comp, name, form) if pushed: comp.popName() clist = comp.closureList() fcode = [] if haslocalcaptures: comp.popLocalCaptures() if clist: for x in clist: fcode.extend(comp.compile(Symbol.intern(x))) fcode.append((STORE_DEREF, x)) fcode.append((LOAD_CLOSURE, x)) fcode.append((BUILD_TUPLE, len(clist))) fcode.extend(code) fcode.append((MAKE_CLOSURE, 0)) code = fcode return code
def compileLoopStar(comp, form): if len(form) < 3: raise CompilerException("loop* takes at least two args") form = form.next() if not isinstance(form.first(), PersistentVector): raise CompilerException("loop* takes a vector as it's first argument") s = form.first() args = [] code = [] idx = 0 while idx < len(s): if len(s) - idx < 2: raise CompilerException("loop* takes a even number of bindings") local = s[idx] if not isinstance(local, Symbol) or local.ns is not None: raise CompilerException("bindings must be non-namespaced symbols") idx += 1 body = s[idx] if local in comp.locals: newlocal = Symbol.intern(str(local)+"_"+str(RT.nextID())) code.extend(comp.compile(body)) comp.locals[local] = comp.locals[local].cons(newlocal) args.append(local) local = newlocal else: comp.locals[local] = RT.list(local) args.append(local) code.extend(comp.compile(body)) code.append((STORE_FAST, str(local))) idx += 1 form = form.next() recurlabel = Label("recurLabel") recur = {"label": recurlabel, "args": map(lambda x: x.name, args)} code.append((recurlabel, None)) comp.pushRecur(recur) code.extend(compileImplcitDo(comp, form)) comp.popRecur() comp.popLocals(args) return code
def compileLetStar(comp, form): if len(form) < 3: raise CompilerException("let* takes at least two args") form = form.next() if not isinstance(form.first(), PersistentVector): raise CompilerException("let* takes a vector as it's first argument") s = form.first() args = [] code = [] idx = 0 while idx < len(s): if len(s) - idx < 2: raise CompilerException("let* takes a even number of bindings") local = s[idx] if not isinstance(local, Symbol) or local.ns is not None: raise CompilerException("bindings must be non-namespaced symbols") idx += 1 body = s[idx] if comp.getAlias(local) is not None: code.extend(comp.compile(body)) newlocal = symbol(str(local)+"_"+str(RT.nextID())) comp.pushAlias(local, RenamedLocal(newlocal)) args.append(local) else: code.extend(comp.compile(body)) comp.pushAlias(local, RenamedLocal(local)) args.append(local) code.extend(comp.getAlias(local).compileSet(comp)) idx += 1 form = form.next() code.extend(compileImplcitDo(comp, form)) comp.popAliases(args) return code
def __init__(self, sym, rest = None): AAlias.__init__(self, rest) self.sym = sym self.newsym = symbol(sym.name + str(RT.nextID()))
def garg(n): from symbol import Symbol return Symbol.intern(None, "rest" if n == -1 else ("p" + str(n)) + "__" + str(RT.nextID()) + "#")