Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
 def __init__(self, sym, rest = None):
     AAlias.__init__(self, rest)
     self.sym = sym
     self.newsym = symbol(sym.name + str(RT.nextID()))
Ejemplo n.º 9
0
def garg(n):
    from symbol import Symbol
    return Symbol.intern(None,  "rest" if n == -1 else  ("p" + str(n)) + "__" + str(RT.nextID()) + "#")