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 unquoteReader(rdr, tilde): s = read1(rdr) if s == "": raise ReaderException("EOF reading unquote", rdr) if s == "@": o = read(rdr, True, None, True) return RT.list(_UNQUOTE_SPLICING_, o) else: rdr.back() o = read(rdr, True, None, True) return RT.list(_UNQUOTE_, o)
def sqExpandList(self, seq): ret = EMPTY_VECTOR while seq is not None: item = seq.first() if isUnquote(item): ret = ret.cons(RT.list(_LIST_, item.next().first())) elif isUnquoteSplicing(item): ret = ret.cons(item.next().first()) else: ret = ret.cons(RT.list(_LIST_, self.syntaxQuote(item))) seq = seq.next() return ret.seq()
def __init__(self): self.recurPoint = RT.list() self.names = None self.ns = None self.lastlineno = -1 self.aliases = {} self.filename = "<unknown>"
def fnReader(rdr, lparen): from py.clojure.lang.persistenthashmap import EMPTY from py.clojure.lang.var import popThreadBindings, pushThreadBindings if ARG_ENV.deref() is not None: raise IllegalStateException("Nested #()s are not allowed") #try: pushThreadBindings(RT.map(ARG_ENV, EMPTY)) rdr.back() form = read(rdr, True, None, True) drefed = ARG_ENV.deref() sargs = sorted(list(filter(lambda x: x != -1, drefed))) args = [] if len(sargs): for x in range(int(str(sargs[-1]))): if x in drefed: args.append(drefed[x]) else: args.append(garg(x)) retsym = drefed[-1] if retsym is not None: args.append(_AMP_) args.append(retsym) vargs = RT.vector(args) popThreadBindings() return RT.list(_FN_, vargs, form)
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 unpackArgs(form): locals = {} args = [] lastisargs = False argsname = None for x in form: if x == _AMP_: lastisargs = True continue if lastisargs and argsname is not None: raise CompilerException("variable length argument must be the last in the function") if lastisargs: argsname = x if not isinstance(x, Symbol) or x.ns is not None: raise CompilerException("fn* arguments must be non namespaced symbols", form) locals[x] = RT.list(x) args.append(x.name) return locals, args, lastisargs, argsname
def varQuoteReader(rdr, singlequote): line = rdr.lineCol()[0] form = read(rdr, True, None, True) return RT.list(_VAR_, form).withMeta(RT.map(LINE_KEY, line))
def __call__(self, rdr, quote): o = read(rdr, True, None, True) return RT.list(self.sym, o)
def pushName(self, name): if self.names is None: self.names = RT.list((name)) self.names = self.names.cons(name)
def __init__(self): self.recurPoint = RT.list() self.names = RT.list() self.ns = None self.lastlineno = -1 self.aliases = {}
def __init__(self): self.locals = {} self.recurPoint = RT.list() self.names = RT.list() self.usedClosures = RT.list() self.ns = None