Example #1
0
    def syntaxQuote(self, form):
        from 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 = self.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()))#FIXME: _WITH_META_ undefined
        return ret
Example #2
0
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)
Example #3
0
 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()
Example #4
0
 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()
Example #5
0
def unquoteReader(rdr, tilde):
    """Return one of:
    * (unquote-splicing next-object-read)
    * (unquote next-object-read)"""
    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)
Example #6
0
 def __init__(self):
     self.recurPoint = RT.list()
     self.names = None
     self.ns = None
     self.lastlineno = -1
     self.aliases = {}
     self.filename = "<unknown>"
Example #7
0
def fnReader(rdr, lparen):
    """Read an anonymous function #() from reader

    rdr -- a read/unread-able object
    lparen -- ignored

    Return an IPersistentList"""
    if ARG_ENV.deref() is not None:
        raise IllegalStateException("Nested #()s are not allowed")
    with threadBindings(RT.map(ARG_ENV, EMPTY_MAP)):
        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(1, int(str(sargs[-1])) + 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)
    return RT.list(_FN_, vargs, form)
Example #8
0
 def __init__(self):
     self.recurPoint = RT.list()
     self.names = None
     self.ns = None
     self.lastlineno = -1
     self.aliases = {}
     self.filename = "<unknown>"
Example #9
0
def fnReader(rdr, lparen):
    from clojure.lang.persistenthashmap import EMPTY
    from clojure.lang.var import popThreadBindings, pushThreadBindings

    if ARG_ENV.deref() is not None:
        raise IllegalStateException("Nested #()s are not allowed")
    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(1, int(str(sargs[-1])) + 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)
Example #10
0
 def __init__(self):
     self.recurPoint = RT.list()
     self.names = None
     self.ns = clojure_core = Namespace("clojure.core")
     self.lastlineno = -1
     self.aliases = {}
     self.filename = "<unknown>"
     self._NS_ = findItem(clojure_core, _NS_)
Example #11
0
def varQuoteReader(rdr, singlequote):
    """Return the list (var next-object-read)

    rdr -- read/unread-able object
    singlequote -- ignored"""
    line = rdr.lineCol()[0]
    form = read(rdr, True, None, True)
    return RT.list(_VAR_, form).withMeta(RT.map(LINE_KEY, line))
Example #12
0
 def __init__(self):
     self.recurPoint = RT.list()
     self.names = None
     self.ns = clojure_core = Namespace("clojure.core")
     self.lastlineno = -1
     self.aliases = {}
     self.filename = "<unknown>"
     self._NS_ = findItem(clojure_core, _NS_)
Example #13
0
def compileFNStar(comp, form):
    with ResolutionContext(comp):
        if len(comp.aliases) > 0: # we might have closures to deal with
            for x in comp.aliases:
                comp.pushAlias(x, tr.Closure(comp.getAlias(x).name, comp.getAlias(x)))

        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):
            name = comp.getNamesString() + "_auto_"
        else:
            comp.pushName(name.name)
            pushed = True
            form = form.next()

        name = symbol(name)

        # This is fun stuff here. The idea is that we want closures to be able
        # to call themselves. But we can't get a pointer to a closure until after
        # it's created, which is when we actually run this code. So, we're going to
        # create a tmp local that is None at first, then pass that in as a possible
        # closure cell. Then after we create the closure with MAKE_CLOSURE we'll
        # populate this var with the correct value


        # form = ([x] x)
        if isinstance(form.first(), IPersistentVector):
            expr = compileFn(comp, name, form, orgform)
        # form = (([x] x))
        elif len(form) == 1:
            expr = compileFn(comp, name, RT.list(*form.first()), orgform)
        # form = (([x] x) ([x y] x))
        else:
            expr = compileMultiFn(comp, name, form)

        if pushed:
            comp.popName()

        return expr
Example #14
0
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 " +
                                    " got " + str(form) + " instead", form)
        locals[x] = RT.list(x)
        args.append(x.name)
    return locals, args, lastisargs, argsname
Example #15
0
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 " + " got " +
                str(form) + " instead", form)
        locals[x] = RT.list(x)
        args.append(x.name)
    return locals, args, lastisargs, argsname
Example #16
0
def compileFNStar(comp, form):
    haslocalcaptures = False
    aliases = []
    if len(comp.aliases) > 0: # we might have closures 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):
        name = comp.getNamesString() + "_auto_"
    else:
        comp.pushName(name.name)
        pushed = True
        form = form.next()

    name = symbol(name)

    # This is fun stuff here. The idea is that we want closures to be able
    # to call themselves. But we can't get a pointer to a closure until after
    # it's created, which is when we actually run this code. So, we're going to
    # create a tmp local that is None at first, then pass that in as a possible
    # closure cell. Then after we create the closure with MAKE_CLOSURE we'll
    # populate this var with the correct value

    selfalias = Closure(name)
    comp.pushAlias(name, selfalias)

    # form = ([x] x)
    if isinstance(form.first(), IPersistentVector):
        code, ptr = compileFn(comp, name, form, orgform)
    # form = (([x] x))
    elif len(form) == 1:
        code, ptr = compileFn(comp, name, RT.list(*form.first()), orgform)
    # form = (([x] x) ([x y] x))
    else:
        code, ptr = compileMultiFn(comp, name, form)

    if pushed:
        comp.popName()

    clist = comp.closureList()
    fcode = []

    if haslocalcaptures:
        comp.popAliases(aliases)

    if clist:
        for x in clist:
            if x is not selfalias:   #we'll populate selfalias later
                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

    if selfalias in clist:
        prefix = []
        prefix.append((LOAD_CONST, None))
        prefix.extend(selfalias.compileSet(comp))
        prefix.extend(code)
        code = prefix
        code.append((DUP_TOP, None))
        code.extend(selfalias.compileSet(comp))

    comp.popAlias(symbol(name)) #closure
    return code
Example #17
0
def compileFNStar(comp, form):
    haslocalcaptures = False
    aliases = []
    if len(comp.aliases) > 0:  # we might have closures 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):
        name = comp.getNamesString() + "_auto_"
    else:
        comp.pushName(name.name)
        pushed = True
        form = form.next()

    name = Symbol(name)

    # This is fun stuff here. The idea is that we want closures to be able
    # to call themselves. But we can't get a pointer to a closure until after
    # it's created, which is when we actually run this code. So, we're going to
    # create a tmp local that is None at first, then pass that in as a possible
    # closure cell. Then after we create the closure with MAKE_CLOSURE we'll
    # populate this var with the correct value

    selfalias = Closure(name)
    comp.pushAlias(name, selfalias)

    # form = ([x] x)
    if isinstance(form.first(), IPersistentVector):
        code, ptr = compileFn(comp, name, form, orgform)
    # form = (([x] x))
    elif len(form) == 1:
        code, ptr = compileFn(comp, name, RT.list(*form.first()), orgform)
    # form = (([x] x) ([x y] x))
    else:
        code, ptr = compileMultiFn(comp, name, form)

    if pushed:
        comp.popName()

    clist = comp.closureList()
    fcode = []

    if haslocalcaptures:
        comp.popAliases(aliases)

    if clist:
        for x in clist:
            if x is not selfalias:  #we'll populate selfalias later
                fcode.extend(comp.getAlias(
                    x.sym).compile(comp))  # Load our local version
                fcode.append((STORE_DEREF,
                              RT.name(x.sym)))  # Store it in a Closure Cell
            fcode.append(
                (LOAD_CLOSURE, RT.name(x.sym)))  # Push the cell on the stack
        fcode.append((BUILD_TUPLE, len(clist)))
        fcode.extend(code)
        fcode.append((MAKE_CLOSURE, 0))
        code = fcode

    if selfalias in clist:
        prefix = []
        prefix.append((LOAD_CONST, None))
        prefix.extend(selfalias.compileSet(comp))
        prefix.extend(code)
        code = prefix
        code.append((DUP_TOP, None))
        code.extend(selfalias.compileSet(comp))

    comp.popAlias(Symbol(name))  #closure
    return code
Example #18
0
 def __call__(self, rdr, quote):
     o = read(rdr, True, None, True)
     return RT.list(self.sym, o)
Example #19
0
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))
Example #20
0
 def __call__(self, rdr, quote):
     o = read(rdr, True, None, True)
     return RT.list(self.sym, o)
Example #21
0
    def syntaxQuote(self, form):
        # compiler uses this module, so import it lazily
        from 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, "{0}__{1}__auto__".format(sym.name[:-1], RT.nextID()))
                    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.deref()
                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")
                
                item = namespace.findItem(ns, sym)
                if item is None:
                    sym = Symbol(ns.__name__, sym.name)
                else:
                    sym = Symbol(item.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 = self.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 getattr(form, "meta", lambda: None)() is not None:
            newMeta = form.meta().without(LINE_KEY)
            if len(newMeta) > 0:
                return RT.list(_WITH_META_, ret, self.syntaxQuote(form.meta()))#FIXME: _WITH_META_ undefined
        return ret