Example #1
0
def compileFn(comp, name, form, orgform):
    locals, args, lastisargs, argsname = unpackArgs(form.first())

    for x in locals:
        comp.pushAlias(x, FnArgument(x))

    if orgform.meta() is not None:
        line = orgform.meta()[LINE_KEY]
    else:
        line = 0
    code = [(SetLineno,line if line is not None else 0)]
    if lastisargs:
        code.extend(cleanRest(argsname.name))

    recurlabel = Label("recurLabel")

    recur = {"label": recurlabel,
    "args": map(lambda x: comp.getAlias(symbol(x)).compileSet(comp), args)}

    code.append((recurlabel, None))
    comp.pushRecur(recur)
    code.extend(compileImplcitDo(comp, form.next()))
    comp.popRecur()
    code.append((RETURN_VALUE,None))
    comp.popAliases(locals)

    clist = map(lambda x: x.sym.name, comp.closureList())
    code = expandMetas(code, comp)
    c = Code(code, clist, args, lastisargs, False, True, str(symbol(comp.getNS().__name__, name.name)), comp.filename, 0, None)
    if not clist:
        c = new.function(c.to_code(), comp.ns.__dict__, name.name)

    return [(LOAD_CONST, c)], c
Example #2
0
    def getAccessCode(self, sym):
        if (sym.ns is not None and sym.ns == self.getNS().__name__) \
           or sym.ns is None:
            if self.getNS() is None:
                raise CompilerException("no namespace has been defined", None)
            if not hasattr(self.getNS(), sym.name):
                raise CompilerException("could not resolve '" + str(sym) + "', '" \
                                        + sym.name + "' not found in " + self.getNS().__name__ +
                                        " reference " + str(self.getNamesString(False)), None)
            var = getattr(self.getNS(), sym.name)
            return [GlobalPtr(self.getNS(), sym.name)]

        if hasattr(self.getNS(), "__aliases__") and \
            symbol(sym.ns) in self.getNS().__aliases__:
            sym = symbol(self.getNS().__aliases__[symbol(sym.ns)].__name__, sym.name)

        splt = []
        if sym.ns is not None:
            module = findNamespace(sym.ns)
            if not hasattr(module, sym.name):
                raise CompilerException(str(module) + " does not define " + sym.name, None)
            return [GlobalPtr(module, sym.name)]

        code = LOAD_ATTR if sym.ns else LOAD_GLOBAL
        #if not sym.ns and sym.name.find(".") != -1 and sym.name != "..":
        raise CompilerException("unqualified dotted forms not supported: " + str(sym), sym)

        if len(sym.name.replace(".", "")):
            splt.extend((code, attr) for attr in sym.name.split("."))
        else:
            splt.append((code, sym.name))
        return splt
Example #3
0
    def getAccessCode(self, sym):
        if (sym.ns is not None and sym.ns == self.getNS().__name__) \
           or sym.ns is None:
            if self.getNS() is None:
                raise CompilerException("no namespace has been defined", None)
            if not hasattr(self.getNS(), RT.name(sym)):
                raise CompilerException("could not resolve '" + str(sym) + "', '" \
                                        + RT.name(sym) + "' not found in " + self.getNS().__name__ +
                                        " reference " + str(self.getNamesString(False)), None)
            var = getattr(self.getNS(), RT.name(sym))
            return [GlobalPtr(self.getNS(), RT.name(sym))]

        if hasattr(self.getNS(), "__aliases__") and \
            symbol(sym.ns) in self.getNS().__aliases__:
            sym = symbol(self.getNS().__aliases__[symbol(sym.ns)].__name__,
                         RT.name(sym))

        splt = []
        if sym.ns is not None:
            module = findNamespace(sym.ns)
            if not hasattr(module, RT.name(sym)):
                raise CompilerException(
                    str(module) + " does not define " + RT.name(sym), None)
            return [GlobalPtr(module, RT.name(sym))]

        code = LOAD_ATTR if sym.ns else LOAD_GLOBAL
        #if not sym.ns and RT.name(sym).find(".") != -1 and RT.name(sym) != "..":
        raise CompilerException(
            "unqualified dotted forms not supported: " + str(sym), sym)

        if len(RT.name(sym).replace(".", "")):
            splt.extend((code, attr) for attr in RT.name(sym).split("."))
        else:
            splt.append((code, RT.name(sym)))
        return splt
Example #4
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 #5
0
def find(sym):
    from clojure.lang.namespace import find as findNamespace
    if sym.ns is None:
        raise InvalidArgumentException("Symbol must be namespace-qualified")
    ns = findNamespace(symbol(sym.ns))
    if ns is None:
        raise InvalidArgumentException("No such namespace " + str(sym.ns))
    return ns.findInternedVar(symbol(sym.name))
Example #6
0
def find(self, *args):
    if len(args) == 1:
        if isinstance(args[0], Symbol):
            return interned.val()[args[0]]()
        if isinstance(args[0], str):
            return Keyword.find(symbol(args[0]))
    if len(args) == 2:
        return Keyword.find(symbol(*args))
    raise ArityException()
Example #7
0
def find(self, *args):
    if len(args) == 1:
        if isinstance(args[0], Symbol):
            return interned.val()[args[0]]()
        if isinstance(args[0], str):
            return Keyword.find(symbol(args[0]))
    if len(args) == 2:
        return Keyword.find(symbol(*args))
    raise ArityException()
Example #8
0
def findItem(ns, sym):
    if sym.ns is not None and symbol(sym.ns) in getattr(ns, "__aliases__", {}):
        sym = symbol(ns.__aliases__[symbol(sym.ns)].__name__, sym.name)
       
    if isinstance(sym, Symbol):
        if ns is None:
            ns = sys.modules["clojure.core"] # we need this to boostrap files
        if sym.ns == ns.__name__:
            return getattr(ns, sym.name, None)
        if sym.ns is not None:
            mod = find(sym.ns, ns)
            return getattr(mod, sym.name, None)
        return getattr(ns, str(sym), None)
    return getattr(ns, sym)
Example #9
0
def matchSymbol(s):
    """Return a symbol or keyword.

    Return None if the string s does not define a legal symbol or keyword."""
    m = symbolPat.match(s)
    if m is not None:
        ns = m.group(1)
        name = m.group(2)

        if name.endswith(".") and not name.startswith("."):
            name = name[:-1]
        if ns is not None and (ns.endswith(":/") or name.endswith(":")\
            or s.find("::") != -1):
            return None
        ns = ns if ns is None else ns[:-1]

        if s.startswith("::"):
            return keyword(currentNSName(), s[2:])

        iskeyword = s.startswith(':')
        if iskeyword:
            return keyword(s[1:])
        else:
            return symbol(ns, name)
    return None
Example #10
0
def compileVector(comp, form):
    code = []
    code.extend(comp.compile(symbol("clojure.lang.rt", "vector")))
    for x in form:
        code.extend(comp.compile(x))
    code.append((CALL_FUNCTION, len(form)))
    return code
Example #11
0
def compileVector(comp, form):
    code = []
    code.extend(comp.compile(symbol("clojure.lang.rt", "vector")))
    for x in form:
        code.extend(comp.compile(x))
    code.append((CALL_FUNCTION, len(form)))
    return code
Example #12
0
def compileDot(comp, form):
    from clojure.lang.persistentlist import PersistentList
    from clojure.lang.iseq import ISeq

    if len(form) != 3:
        raise CompilerException(". form must have two arguments", form)
    clss = form.next().first()
    member = form.next().next().first()

    if isinstance(member, Symbol):
        attr = member.name
        args = []
    elif isinstance(member, ISeq):
        if not isinstance(member.first(), Symbol):
            raise CompilerException("Member name must be symbol")
        attr = member.first().name
        args = []
        if len(member) > 1:
            f = member.next()
            while f is not None:
                args.append(comp.compile(f.first()))
                f = f.next()

    alias = comp.getAlias(clss)
    if alias:
        code = alias.compile(comp)
        code.append((LOAD_ATTR, attr))
    else:
        code = comp.compile(symbol(clss, attr))

    for x in args:
        code.extend(x)
    code.append((CALL_FUNCTION, len(args)))

    return code
Example #13
0
def compileDot(comp, form):
    if len(form) != 3:
        raise CompilerException(". form must have two arguments", form)
    clss = form.next().first()
    member = form.next().next().first()

    if isinstance(member, Symbol):
        attr = member.name
        args = []
    elif isinstance(member, ISeq):
        if not isinstance(member.first(), Symbol):
            raise CompilerException("Member name must be symbol", form)
        attr = member.first().name
        args = []
        if len(member) > 1:
            f = member.next()
            while f is not None:
                args.append(comp.compile(f.first()))
                f = f.next()

    alias = comp.getAlias(clss)
    if alias:
        code = alias.compile(comp)
        code = tr.Attr(code, attr)
    else:
        code = comp.compile(symbol(clss, attr))

    code = tr.Call(code, *args)
    return code
Example #14
0
def matchSymbol(s):
    """Return a symbol or keyword.

    Return None if the string s does not define a legal symbol or keyword."""
    m = symbolPat.match(s)
    if m is not None:
        ns = m.group(1)
        name = m.group(2)

        if name.endswith(".") and not name.startswith("."):
            name = name[:-1]
        if ns is not None and (ns.endswith(":/") or name.endswith(":")\
            or s.find("::") != -1):
                return None
        ns = ns if ns is None else ns[:-1]
        
        if s.startswith("::"):
            return keyword(currentNSName(), s[2:])


        iskeyword = s.startswith(':')
        if iskeyword:
            return keyword(s[1:])
        else:
            return symbol(ns, name)
    return None
Example #15
0
def intern(ns, name):
    from namespace import findOrCreate, intern as nsintern
    
    if isinstance(ns, types.ModuleType):
        return nsintern(ns, name)
    ns = findOrCreate(symbol(ns))
    return nsintern(ns, name)
Example #16
0
def compileDot(comp, form):
    if len(form) != 3:
        raise CompilerException(". form must have two arguments", form)
    clss = form.next().first()
    member = form.next().next().first()

    if isinstance(member, Symbol):
        attr = member.name
        args = []
    elif isinstance(member, ISeq):
        if not isinstance(member.first(), Symbol):
            raise CompilerException("Member name must be symbol")
        attr = member.first().name
        args = []
        if len(member) > 1:
            f = member.next()
            while f is not None:
                args.append(comp.compile(f.first()))
                f = f.next()

    alias = comp.getAlias(clss)
    if alias:
        code = alias.compile(comp)
        code.append((LOAD_ATTR, attr))
    else:
        code = comp.compile(symbol(clss, attr))

    for x in args:
        code.extend(x)
    code.append((CALL_FUNCTION, len(args)))
    return code
Example #17
0
def intern(ns, name):
    from namespace import findOrCreate, intern as nsintern

    if isinstance(ns, types.ModuleType):
        return nsintern(ns, name)
    ns = findOrCreate(symbol(ns))
    return nsintern(ns, name)
Example #18
0
def compileMultiFn(comp, name, form):
    s = form
    argdefs = []

    while s is not None:
        argdefs.append(MultiFn(comp, s.first()))
        s = s.next()
    argdefs = sorted(argdefs, lambda x, y: len(x.args) < len(y.args))
    if len(filter(lambda x: x.lastisargs, argdefs)) > 1:
        raise CompilerException("Only one function overload may have variable number of arguments", form)

    code = []
    if len(argdefs) == 1 and not argdefs[0].lastisargs:
        hasvararg = False
        argslist = argdefs[0].args
        code.extend(argdefs[0].bodycode)
    else:
        hasvararg = True
        argslist = ["__argsv__"]
        for x in argdefs:
            code.extend(x.argcode)
            code.extend(x.bodycode)

        code.append((LOAD_CONST, Exception))
        code.append((CALL_FUNCTION, 0))
        code.append((RAISE_VARARGS, 1))

    clist = map(lambda x: x.sym.name, comp.closureList())
    code = expandMetas(code, comp)
    c = Code(code, clist, argslist, hasvararg, False, True, str(symbol(comp.getNS().__name__, name.name)), comp.filename, 0, None)
    if not clist:
        c = new.function(c.to_code(), comp.ns.__dict__, name.name)
    return [(LOAD_CONST, c)], c
Example #19
0
def intern(ns, name):
    from namespace import findOrCreate, intern as nsintern
    import new 
    
    if isinstance(ns, new.module):
        return nsintern(ns, name)
    ns = findOrCreate(symbol(ns))
    return nsintern(ns, name)
Example #20
0
def find(sym):
    from clojure.lang.namespace import find as findNamespace
    if sym.ns is None:
        raise InvalidArgumentException("Symbol must be namespace-qualified")
    ns = findNamespace(symbol(sym.ns))
    if ns is None:
        raise InvalidArgumentException("No such namespace {0}".format(sym.ns))
    return getattr(ns, sym.name)
Example #21
0
def intern(ns, name):
    from namespace import findOrCreate, intern as nsintern
    import new 
    
    if isinstance(ns, new.module):
        return nsintern(ns, name)
    ns = findOrCreate(symbol(ns))
    return nsintern(ns, name)
Example #22
0
 def executeCode(self, code):
     if code == []:
         return None
     newcode = expandMetas(code, self)
     newcode.append((RETURN_VALUE, None))
     c = Code(newcode, [], [], False, False, False, str(symbol(self.getNS().__name__, "<string>")), self.filename, 0, None)
     retval = eval(c.to_code(), self.getNS().__dict__)
     self.getNS().__file__ = self.filename
     return retval
Example #23
0
 def executeCode(self, code):
     import sys
     if code == []:
         return None
     newcode = code[:]
     newcode.append((RETURN_VALUE, None))
     c = Code(newcode, [], [], False, False, False, str(symbol(self.getNS().__name__, "<string>")), self.filename, 0, None)
     retval = eval(c.to_code(), self.getNS().__dict__)
     return retval
Example #24
0
def keyword(*args):
    if len(args) == 1:
        if isinstance(args[0], Symbol):
            sym = args[0]
            if sym.meta() is not None:
                sym = sym.withMeta(None)
            k = Keyword(sym)

            interned.mutate(lambda old: old if sym in old else old.assoc(sym,k))

            return interned.get()[sym]
        elif isinstance(args[0], (str, unicode)):
            return keyword(symbol(args[0]))
        else:
            raise InvalidArgumentException()
    elif len(args) == 2:
        return keyword(symbol(*args))
    else:
        raise ArityException()
Example #25
0
def keyword(*args):
    if len(args) == 1:
        if isinstance(args[0], Symbol):
            sym = args[0]
            if sym.meta() is not None:
                sym = sym.withMeta(None)
            k = Keyword(sym)

            interned.mutate(lambda old: old
                            if sym in old else old.assoc(sym, k))

            return interned.get()[sym]
        elif isinstance(args[0], (str, unicode)):
            return keyword(symbol(args[0]))
        else:
            raise InvalidArgumentException()
    elif len(args) == 2:
        return keyword(symbol(*args))
    else:
        raise ArityException()
Example #26
0
    def executeModule(self, code):
        code.append((RETURN_VALUE, None))
        c = Code(code, [], [], False, False, False, str(symbol(self.getNS().__name__, "<string>")), self.filename, 0, None)

        dis.dis(c)
        codeobject = c.to_code()

        with open('output.pyc', 'wb') as fc:
            fc.write(py_compile.MAGIC)
            py_compile.wr_long(fc, long(time.time()))
            marshal.dump(c, fc)
Example #27
0
 def executeCode(self, code):
     import sys
     if code == []:
         return None
     newcode = code[:]
     newcode.append((RETURN_VALUE, None))
     c = Code(newcode, [], [], False, False, False,
              str(symbol(self.getNS().__name__, "<string>")), self.filename,
              0, None)
     retval = eval(c.to_code(), self.getNS().__dict__)
     return retval
Example #28
0
    def __init__(self, comp, form):
        form = RT.seq(form)
        if len(form) < 2:
            raise CompilerException("FN defs must have at least two vars",
                                    form)
        argv = form.first()
        if not isinstance(argv, PersistentVector):
            raise CompilerException("FN arg list must be a vector", form)
        body = form.next()

        self.locals, self.args, self.lastisargs, self.argsname = unpackArgs(
            argv)
        endLabel = Label("endLabel")
        argcode = [(LOAD_CONST, len), (LOAD_FAST, '__argsv__'),
                   (CALL_FUNCTION, 1),
                   (LOAD_CONST,
                    len(self.args) - (1 if self.lastisargs else 0)),
                   (COMPARE_OP, ">=" if self.lastisargs else "==")]
        argcode.extend(emitJump(endLabel))
        for x in range(len(self.args)):
            if self.lastisargs and x == len(self.args) - 1:
                offset = len(self.args) - 1
                argcode.extend([(LOAD_FAST, '__argsv__'), (LOAD_CONST, offset),
                                (SLICE_1, None),
                                (STORE_FAST, self.argsname.name)])
                argcode.extend(cleanRest(self.argsname.name))
            else:
                argcode.extend([(LOAD_FAST, '__argsv__'), (LOAD_CONST, x),
                                (BINARY_SUBSCR, None),
                                (STORE_FAST, self.args[x])])

        for x in self.locals:
            comp.pushAlias(x, FnArgument(x))

        recurlabel = Label("recurLabel")

        recur = {
            "label":
            recurlabel,
            "args":
            map(lambda x: comp.getAlias(symbol(x)).compileSet(comp), self.args)
        }

        bodycode = [(recurlabel, None)]
        comp.pushRecur(recur)
        bodycode.extend(compileImplcitDo(comp, body))
        bodycode.append((RETURN_VALUE, None))
        bodycode.extend(emitLanding(endLabel))
        comp.popRecur()
        comp.popAliases(self.locals)

        self.argcode = argcode
        self.bodycode = bodycode
Example #29
0
def findItem(ns, sym):
    from clojure.lang.symbol import Symbol, symbol
    if sym.ns is not None and  hasattr(ns, "__aliases__") and \
        symbol(sym.ns) in ns.__aliases__:
        sym = symbol(ns.__aliases__[symbol(sym.ns)].__name__, sym.name)

    if isinstance(sym, Symbol):
        if ns is None:
            ns = sys.modules["clojure.core"]  # we need this to boostrap files
        if sym.ns == ns.__name__:
            if not hasattr(ns, sym.name):
                return None
            return getattr(ns, sym.name)
        if sym.ns is not None:
            mod = find(sym.ns, ns)
            if hasattr(mod, sym.name):
                return getattr(mod, sym.name)
            return None
        if not hasattr(ns, str(sym)):
            return None
        return getattr(ns, str(sym))
    return getattr(ns, sym)
Example #30
0
    def executeModule(self, code):
        code.append((RETURN_VALUE, None))
        c = Code(code, [], [], False, False, False,
                 str(symbol(self.getNS().__name__, "<string>")), self.filename,
                 0, None)

        dis.dis(c)
        codeobject = c.to_code()

        with open('output.pyc', 'wb') as fc:
            fc.write(py_compile.MAGIC)
            py_compile.wr_long(fc, long(time.time()))
            marshal.dump(c, fc)
Example #31
0
def compileMap(comp, form):
    s = form.seq()
    c = 0
    code = []
    code.extend(comp.compile(symbol("clojure.lang.rt", "map")))
    while s is not None:
        kvp = s.first()
        code.extend(comp.compile(kvp.getKey()))
        code.extend(comp.compile(kvp.getValue()))
        c += 2
        s = s.next()
    code.append([CALL_FUNCTION, c])
    return code
Example #32
0
    def getAccessCode(self, sym):
        print sym
        if (sym.ns is not None and sym.ns == self.nsString) \
           or sym.ns is None:
            if self.getNS() is None:
                raise CompilerException("no namespace has been defined", None)
            if not hasattr(self.getNS(), RT.name(sym)):
                raise CompilerException(
                    "could not resolve '{0}', '{1}' not found in {2} reference {3}".
                    format(sym, RT.name(sym), self.getNS().__name__,
                           self.getNamesString(False)),
                    None)
            var = getattr(self.getNS(), RT.name(sym))

            return maybeDeref(self.ns, self.nsString, RT.name(sym), self.nsString)

        if symbol(sym.ns) in getattr(self.getNS(), "__aliases__", {}):
            sym = symbol(self.getNS().__aliases__[symbol(sym.ns)].__name__, RT.name(sym))

        splt = []
        if sym.ns is not None:
            module = findNamespace(sym.ns)
            if not hasattr(module, RT.name(sym)):
                raise CompilerException(
                    "{0} does not define {1}".format(module, RT.name(sym)),
                    None)

            return getAttrChain(sym.getNamespace() + "." + sym.getName())

        code = LOAD_ATTR if sym.ns else LOAD_GLOBAL
        #if not sym.ns and RT.name(sym).find(".") != -1 and RT.name(sym) != "..":
        raise CompilerException(
            "unqualified dotted forms not supported: {0}".format(sym), sym)

        if len(RT.name(sym).replace(".", "")):
            splt.extend((code, attr) for attr in RT.name(sym).split("."))
        else:
            splt.append((code, RT.name(sym)))
        return splt
Example #33
0
def findItem(ns, sym):
    from clojure.lang.symbol import Symbol, symbol

    if sym.ns is not None and hasattr(ns, "__aliases__") and symbol(sym.ns) in ns.__aliases__:
        sym = symbol(ns.__aliases__[symbol(sym.ns)].__name__, sym.name)

    if isinstance(sym, Symbol):
        if ns is None:
            ns = sys.modules["clojure.core"]  # we need this to boostrap files
        if sym.ns == ns.__name__:
            if not hasattr(ns, sym.name):
                return None
            return getattr(ns, sym.name)
        if sym.ns is not None:
            mod = find(sym.ns, ns)
            if hasattr(mod, sym.name):
                return getattr(mod, sym.name)
            return None
        if not hasattr(ns, str(sym)):
            return None
        return getattr(ns, str(sym))
    return getattr(ns, sym)
Example #34
0
def compileMap(comp, form):
    s = form.seq()
    c = 0
    code = []
    code.extend(comp.compile(symbol("clojure.lang.rt", "map")))
    while s is not None:
        kvp = s.first()
        code.extend(comp.compile(kvp.getKey()))
        code.extend(comp.compile(kvp.getValue()))
        c += 2
        s = s.next()
    code.append([CALL_FUNCTION, c])
    return code
Example #35
0
def compileFn(comp, name, form, orgform):
    locals, args, lastisargs, argsname = unpackArgs(form.first())

    for x in locals:
        comp.pushAlias(x, FnArgument(x))

    if orgform.meta() is not None:
        line = orgform.meta()[LINE_KEY]
    else:
        line = 0
    code = [(SetLineno, line if line is not None else 0)]
    if lastisargs:
        code.extend(cleanRest(argsname.name))

    recurlabel = Label("recurLabel")

    recur = {
        "label": recurlabel,
        "args": map(lambda x: comp.getAlias(symbol(x)).compileSet(comp), args)
    }

    code.append((recurlabel, None))
    comp.pushRecur(recur)
    code.extend(compileImplcitDo(comp, form.next()))
    comp.popRecur()

    code.append((RETURN_VALUE, None))

    comp.popAliases(locals)

    clist = map(lambda x: x.sym.name, comp.closureList())
    c = Code(code, clist, args, lastisargs, False, True,
             str(symbol(comp.getNS().__name__, name.name)), comp.filename, 0,
             None)
    if not clist:
        c = new.function(c.to_code(), comp.ns.__dict__, name.name)

    return [(LOAD_CONST, c)], c
Example #36
0
    def __init__(self, comp, form):
        form = RT.seq(form)
        if len(form) < 1:
            raise CompilerException("FN defs must have at least one arg", form)
        argv = form.first()
        if not isinstance(argv, PersistentVector):
            raise CompilerException("FN arg list must be a vector", form)
        body = form.next()

        self.locals, self.args, self.lastisargs, self.argsname = unpackArgs(argv)
        endLabel = Label("endLabel")
        argcode = [(LOAD_CONST, len),
            (LOAD_FAST, '__argsv__'),
            (CALL_FUNCTION, 1),
            (LOAD_CONST, len(self.args) - (1 if self.lastisargs else 0)),
            (COMPARE_OP, ">=" if self.lastisargs else "==")]
        argcode.extend(emitJump(endLabel))
        for x in range(len(self.args)):
            if self.lastisargs and x == len(self.args) - 1:
                offset = len(self.args) - 1
                argcode.extend([(LOAD_FAST, '__argsv__'),
                    (LOAD_CONST, offset),
                    (SLICE_1, None),
                    (STORE_FAST, self.argsname.name)])
                argcode.extend(cleanRest(self.argsname.name))
            else:
                argcode.extend([(LOAD_FAST, '__argsv__'),
                    (LOAD_CONST, x),
                    (BINARY_SUBSCR, None),
                    (STORE_FAST, self.args[x])])

        for x in self.locals:
            comp.pushAlias(x, FnArgument(x))

        recurlabel = Label("recurLabel")

        recur = {"label": recurlabel,
        "args": map(lambda x: comp.getAlias(symbol(x)).compileSet(comp), self.args)}

        bodycode = [(recurlabel, None)]
        comp.pushRecur(recur)
        bodycode.extend(compileImplcitDo(comp, body))
        bodycode.append((RETURN_VALUE, None))
        bodycode.extend(emitLanding(endLabel))
        comp.popRecur()
        comp.popAliases(self.locals)

        self.argcode = argcode
        self.bodycode = bodycode
Example #37
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.aliases:
            newlocal = symbol(str(local) + "_" + str(RT.nextID()))
            code.extend(comp.compile(body))
            comp.pushAlias(local, RenamedLocal(newlocal))
            args.append(local)
        else:
            comp.pushAlias(local, RenamedLocal(local))
            args.append(local)
            code.extend(comp.compile(body))

        code.extend(comp.getAlias(local).compileSet(comp))

        idx += 1

    form = form.next()
    recurlabel = Label("recurLabel")
    recur = {
        "label": recurlabel,
        "args": map(lambda x: comp.getAlias(x).compileSet(comp), args)
    }
    code.append((recurlabel, None))
    comp.pushRecur(recur)
    code.extend(compileImplcitDo(comp, form))
    comp.popRecur()
    comp.popAliases(args)
    return code
Example #38
0
def compileLetStar(comp, form):
    if len(form) < 3:
        raise CompilerException("let* takes at least two args", form)
    form = form.next()
    if not isinstance(form.first(), IPersistentVector):
        raise CompilerException(
            "let* takes a vector as it's first argument", form)
    s = form.first()
    args = []
    code = []
    idx = 0

    with ResolutionContext(comp):
        code = []
        while idx < len(s):
            if len(s) - idx < 2:
                raise CompilerException(
                    "let* takes a even number of bindings", form)
            local = s[idx]
            if not isinstance(local, Symbol) or local.ns is not None:
                raise CompilerException(
                    "bindings must be non-namespaced symbols", form)

            idx += 1

            body = s[idx]

            if comp.getAlias(local) is not None:
                cb = (comp.compile(body))
                newlocal = symbol("{0}_{1}".format(local, RT.nextID()))
                comp.pushAlias(local, tr.Local(newlocal.getName()))
                args.append(local)
            else:
                cb = comp.compile(body)
                comp.pushAlias(local, tr.Local(local.getName()))
                args.append(local)

            code.append(tr.StoreLocal(comp.getAlias(local), cb))

            idx += 1

        form = form.next()
        code.append(compileImplcitDo(comp, form))
        code = tr.Do(*code)

        return code
Example #39
0
    def executeCode(self, code):

        if code == []:
            return None
        newcode = expandMetas(code, self)
        newcode.append((RETURN_VALUE, None))
        c = Code(newcode, [], [], False, False, False, str(symbol(self.getNS().__name__, "<string>")), self.filename, 0, None)
        c = c.to_code()

        # work on .cljs
        #from clojure.util.freeze import write, read
        #with open("foo.cljs", "wb") as fl:
        #    f = write(c, fl)

        retval = eval(c, self.getNS().__dict__)
        self.getNS().__file__ = self.filename
        return retval
Example #40
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.aliases:
            newlocal = symbol(str(local)+"_"+str(RT.nextID()))
            code.extend(comp.compile(body))
            comp.pushAlias(local, RenamedLocal(newlocal))
            args.append(local)
        else:
            comp.pushAlias(local, RenamedLocal(local))
            args.append(local)
            code.extend(comp.compile(body))


        code.extend(comp.getAlias(local).compileSet(comp))

        idx += 1

    form = form.next()
    recurlabel = Label("recurLabel")
    recur = {"label": recurlabel,
             "args": map(lambda x: comp.getAlias(x).compileSet(comp), args)}
    code.append((recurlabel, None))
    comp.pushRecur(recur)
    code.extend(compileImplcitDo(comp, form))
    comp.popRecur()
    comp.popAliases(args)
    return code
Example #41
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 #42
0
def intern(ns, sym):
    from clojure.lang.var import Var

    if isinstance(sym, str):
        sym = symbol(str)

    if sym.ns is not None:
        raise InvalidArgumentException("Can't intern namespace-qualified symbol")

    ns = find(ns)
    if hasattr(ns, str(sym)):
        v = getattr(ns, str(sym))
        if not isinstance(v, Var):
            raise Exception("can't redefine " + str(v) + " as " + str(sym) + ": is not Var")
        if ns.__name__ == v.ns.__name__:
            return v
    v = Var(ns, sym)
    setattr(ns, sym.name, v)
    return v
Example #43
0
def matchSymbol(s):
    from clojure.lang.symbol import Symbol
    from clojure.lang.cljkeyword import Keyword
    m = symbolPat.match(s)
    if m is not None:
        ns = m.group(1)
        name = m.group(2)
        if ns is not None and ns.endswith(":/") or name.endswith(":")\
            or s.find("::") != -1:
                return None
        if s.startswith("::"):
            return "FIX"
        ns = ns if ns is None else ns[:-1]
        iskeyword = s.find(':') == 0
        sym = symbol(ns, name[(1 if iskeyword else 0):])
        if iskeyword:
            return keyword(s)
        else:
            return sym
    return None
Example #44
0
def intern(ns, sym):
    from clojure.lang.var import Var

    if isinstance(sym, str):
        sym = symbol(str)

    if sym.ns is not None:
        raise InvalidArgumentException(
            "Can't intern namespace-qualified symbol")

    ns = find(ns)
    if hasattr(ns, str(sym)):
        v = getattr(ns, str(sym))
        if not isinstance(v, Var):
            raise Exception("can't redefine " + str(v) + " as " + str(sym) +
                            ": is not Var")
        if ns.__name__ == v.ns.__name__:
            return v
    v = Var(ns, sym)
    setattr(ns, sym.name, v)
    return v
Example #45
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
Example #46
0
def main():
    requireClj(os.path.dirname(__file__) + "/core.clj")

    RT.init()
    comp = Compiler()
    currentCompiler.set(comp)
    comp.setNS(symbol("user"))

    if not sys.argv[1:]:
        while True:
            try:
                line = raw_input(comp.getNS().__name__ + "=> ")
            except EOFError:
                break

            if not line:
                continue

            while unbalanced(line):
                try:
                    line += raw_input('.' * len(comp.getNS().__name__) + '.. ')
                except EOFError:
                    break

            # Propogate break from above loop.
            if unbalanced(line):
                break

            r = StringReader(line)
            s = read(r, True, None, True)

            try:
                res = comp.compile(s)
                print comp.executeCode(res)
            except Exception:
                traceback.print_exc()
    else:
        for x in sys.argv[1:]:
            requireClj(x)
Example #47
0
def compileFn(comp, name, form, orgform):
    locals, args, lastisargs, argsname = unpackArgs(form.first())

    with ResolutionContext(comp):
        trargs = []
        for x in args:
            if lastisargs and x == args[-1]:
                arg = tr.RestArgument(x)
            else:
                arg = tr.Argument(x)
            comp.pushAlias(symbol(x), arg)
            trargs.append(arg)

        resolved = partial(resolveTrLocal, comp.aliases)

        if lastisargs:
            expr = tr.Do(cleanRest(comp.getAlias(argsname)),
                         compileImplcitDo(comp, form.next()))
        else:
            expr = compileImplcitDo(comp, form.next())

        return tr.Func(trargs, expr, resolved, name = str(name))
Example #48
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
Example #49
0
def compileMultiFn(comp, name, form):
    s = form
    argdefs = []

    while s is not None:
        argdefs.append(MultiFn(comp, s.first()))
        s = s.next()
    argdefs = sorted(argdefs, lambda x, y: len(x.args) < len(y.args))
    if len(filter(lambda x: x.lastisargs, argdefs)) > 1:
        raise CompilerException(
            "Only one function overload may have variable number of arguments",
            form)

    code = []
    if len(argdefs) == 1 and not argdefs[0].lastisargs:
        hasvararg = False
        argslist = argdefs[0].args
        code.extend(argdefs[0].bodycode)
    else:
        hasvararg = True
        argslist = ["__argsv__"]
        for x in argdefs:
            code.extend(x.argcode)
            code.extend(x.bodycode)

        code.append((LOAD_CONST, Exception))
        code.append((CALL_FUNCTION, 0))
        code.append((RAISE_VARARGS, 1))

    clist = map(lambda x: x.sym.name, comp.closureList())
    c = Code(code, clist, argslist, hasvararg, False, True,
             str(symbol(comp.getNS().__name__, name.name)), comp.filename, 0,
             None)

    if not clist:
        c = new.function(c.to_code(), comp.ns.__dict__, name.name)

    return [(LOAD_CONST, c)], c
Example #50
0
    def executeCode(self, code):

        if code == []:
            return None
        newcode = expandMetas(code, self)
        newcode.append((RETURN_VALUE, None))
        c = Code(newcode, [], [], False, False, False,
                 str(symbol(self.getNS().__name__, "<string>")), self.filename,
                 0, None)
        try:
            c = c.to_code()
        except:
            for x in newcode:
                print x
            raise

        # work on .cljs
        #from clojure.util.freeze import write, read
        #with open("foo.cljs", "wb") as fl:
        #    f = write(c, fl)

        retval = eval(c, self.getNS().__dict__)
        self.getNS().__file__ = self.filename
        return retval
Example #51
0
 def __init__(self, sym, rest=None):
     AAlias.__init__(self, rest)
     self.sym = sym
     self.newsym = symbol(sym.name + str(RT.nextID()))
Example #52
0
 def inner(func):
     builtins[sym if isinstance(sym, Symbol) else symbol(sym)] = func
     return func
Example #53
0
def compileTry(comp, form):
    """
    Compiles the try macro.
    """
    assert form.first() == symbol("try")
    form = form.next()

    if not form:
        # I don't like this, but (try) == nil
        return [(LOAD_CONST, None)]

    # Extract the thing that may raise exceptions
    body = form.first()

    form = form.next()
    if not form:
        # If there are no catch/finally/else etc statements, just
        # compile the budy
        return comp.compile(body)

    catch = []
    els = None
    fin = None
    for subform in form:
        # FIXME, could also be a Cons, LazySeq, etc.
        #if not isinstance(subform, IPersistentList):
        #    raise CompilerException("try arguments must be lists", form)
        if not len(subform):
            raise CompilerException("try arguments must not be empty", form)
        name = subform.first()
        if name in (symbol("catch"), symbol("except")):
            if len(subform) != 4:
                raise CompilerException(
                    "try " + str(name) + "blocks must be 4 items long", form)

            # Exception is second, val is third
            exception = subform.next().first()
            if not isinstance(exception, Symbol):
                raise CompilerException(
                    "exception passed to " + str(name) +
                    "block must be a symbol", form)
            for ex, _, _ in catch:
                if ex == exception:
                    raise CompilerException(
                        "try cannot catch duplicate" + " exceptions", form)

            var = subform.next().next().first()
            if not isinstance(var, Symbol):
                raise CompilerException(
                    "variable name for " + str(name) +
                    "block must be a symbol", form)
            val = subform.next().next().next().first()
            catch.append((exception, var, val))
        elif name == symbol("else"):
            if len(subform) != 2:
                raise CompilerException("try else blocks must be 2 items",
                                        form)
            elif els:
                raise CompilerException("try cannot have multiple els blocks",
                                        form)
            els = subform.next().first()
        elif name == symbol("finally"):
            if len(subform) != 2:
                raise CompilerException("try finally blocks must be 2 items",
                                        form)
            elif fin:
                raise CompilerException(
                    "try cannot have multiple finally blocks", form)
            fin = subform.next().first()
        else:
            raise CompilerException(
                "try does not accept any symbols apart " +
                "from catch/except/else/finally, got" + str(form), form)

    if fin and not catch and not els:
        return compileTryFinally(comp.compile(body), comp.compile(fin))
    elif catch and not fin and not els:
        return compileTryCatch(comp, comp.compile(body), catch)
    elif not fin and not catch and els:
        raise CompilerException("Try does not accept else statements on " +\
                                    "their own", form)

    if fin and catch and not els:
        return compileTryCatchFinally(comp, comp.compile(body), catch,
                                      comp.compile(fin))
Example #54
0
 def setUp(self):
     RT.init()
     self.comp = Compiler()
     currentCompiler.set(self.comp)
     self.comp.setNS(symbol('clojure.core'))
Example #55
0
from clojure.lang.aref import ARef
from clojure.lang.cljexceptions import (ArityException,
                                        InvalidArgumentException,
                                        IllegalStateException)
from clojure.lang.persistenthashmap import EMPTY
from clojure.lang.threadutil import ThreadLocal, currentThread
from clojure.lang.symbol import symbol
from clojure.lang.cljkeyword import keyword
from clojure.lang.iprintable import IPrintable

from clojure.lang.atomicreference import AtomicReference

import persistentarraymap
import types

privateKey = keyword(symbol("private"))
macrokey = keyword(symbol("macro"))
STATIC_KEY = keyword(symbol("static"))
dvals = ThreadLocal()
privateMeta = persistentarraymap.create([privateKey, True])
UKNOWN = symbol("UNKNOWN")


def pushThreadBindings(bindings):
    f = dvals.get(lambda: Frame())
    bmap = f.bindings
    for v in bindings:
        value = bindings[v]
        if not v.dynamic:
            raise IllegalStateException("Can't dynamically bind non-dynamic "
                                        "var: " + str(v.ns) + "/" + str(v.sym))
Example #56
0
from clojure.lang.iref import IRef
from clojure.lang.ifn import IFn
from clojure.lang.settable import Settable
from clojure.lang.aref import ARef
from clojure.lang.cljexceptions import (ArityException,
                                           InvalidArgumentException,
                                           IllegalStateException)
from clojure.lang.persistenthashmap import EMPTY
from clojure.lang.threadutil import ThreadLocal, currentThread
from clojure.lang.symbol import symbol
from clojure.lang.cljkeyword import keyword
import persistentarraymap

privateKey = keyword(symbol("private"))
macrokey = keyword(symbol(":macro"))
dvals = ThreadLocal()
privateMeta = persistentarraymap.create([privateKey, True])
UKNOWN = symbol("UNKNOWN")


def pushThreadBindings(bindings):
    f = dvals.get(lambda: Frame())
    bmap = f.bindings
    bs = bindings.seq()
    while bs is not None:
        e = bs.first()
        v = e.getKey()
        if not v.dynamic:
            raise IllegalStateException("Can't dynamically bind non-dynamic "
                                        "var: " + str(v.ns) + "/"
                                        + str(v.sym))
Example #57
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()
    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)

    if isinstance(form.first(), IPersistentVector):
        code, ptr = compileFn(comp, name, form, orgform)
    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 #58
0
def internPrivate(nsName, sym):
    ns = Namespace.findOrCreate(symbol(nsName))  #FIXME: undefined Namespace
    ret = intern(ns, symbol(sym))
    ret.setMeta(Var.privateMeta)
    return ret
Example #59
0
from clojure.lang.ipersistentlist import IPersistentList
from clojure.lang.var import Var, define, intern as internVar, var as createVar
from clojure.util.byteplay import *
import clojure.util.byteplay as byteplay
from clojure.lang.cljkeyword import Keyword, keyword
from clojure.lang.namespace import find as findNamespace
import new
import clojure.lang.rt as RT
from clojure.lang.lispreader import _AMP_
from clojure.lang.namespace import findItem
from clojure.lang.lispreader import LINE_KEY, garg
import re
import new
import sys

_MACRO_ = keyword(symbol(":macro"))
version = (sys.version_info[0] * 10) + sys.version_info[1]


def emitJump(label):
    if version == 26:
        return [(JUMP_IF_FALSE, label), (POP_TOP, None)]
    else:
        return [(POP_JUMP_IF_FALSE, label)]


def emitLanding(label):
    if version == 26:
        return [(label, None), (POP_TOP, None)]
    else:
        return [(label, None)]