Пример #1
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
Пример #2
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
Пример #3
0
def compileLetStar(comp, form):
    if len(form) < 2:
        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)
    bindings = RT.seq(form.first())
    args = []
    code = []
    if bindings and len(bindings) % 2:
        raise CompilerException("let* takes a even number of bindings", form)
    while bindings:
        local, bindings = bindings.first(), bindings.next()
        body, bindings = bindings.first(), bindings.next()
        if not isinstance(local, Symbol) or local.ns is not None:
            raise CompilerException("bindings must be non-namespaced symbols",
                                    form)
        code.extend(comp.compile(body))
        alias = RenamedLocal(
            Symbol("{0}_{1}".format(local, RT.nextID())) if comp.
            getAlias(local) else local)
        comp.pushAlias(local, alias)
        args.append(local)
        code.extend(alias.compileSet(comp))
    form = form.next()
    code.extend(compileImplcitDo(comp, form))
    comp.popAliases(args)
    return code
Пример #4
0
def findNS(name, fromns=None):
    """Finds a namespace, possibly as an defined as an alias in another one.
    """
    symbol_name = Symbol(name)
    if symbol_name in getattr(fromns, "__aliases__", {}):
        return fromns.__aliases__[symbol_name]
    return sys.modules.get(str(name))
Пример #5
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.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
Пример #6
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
Пример #7
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)
Пример #8
0
 def read_number(self, reader):
     chars = []
     while self.is_number(reader.current()) or \
           reader.current() == '.' or \
           reader.current() == '-':
           chars.append(reader.current())
           reader.next()
     str = "".join(chars)
     if str == "-":
         return Symbol.from_string(str)
     if '.' in str:
         return FloatObj(float(str))
     return IntObj(int(str))
Пример #9
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
Пример #10
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: RT.name(x.sym), 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 = types.FunctionType(c.to_code(), comp.ns.__dict__, name.name)

    return [(LOAD_CONST, c)], c
Пример #11
0
    def getAccessCode(self, sym):
        if sym.ns is None or sym.ns == self.getNS().__name__:
            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 [GlobalPtr(self.getNS(), RT.name(sym))]

        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 = findNS(sym.ns)
            if not hasattr(module, RT.name(sym)):
                raise CompilerException(
                    "{0} does not define {1}".format(module, 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: {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
Пример #12
0
 def __new__(cls, *args):
     """Keyword constructor.
     
     Argument(s) will be passed to Symbol() first.  If the keyword was
     already interned, it will be returned.
     """
     sym = Symbol(*args).withMeta(None)
     if sym in Keyword.interned.get():
         return Keyword.interned.get()[sym]
     obj = super(Keyword, cls).__new__(cls)
     Keyword.interned.mutate(
         lambda old: old if sym in old else old.assoc(sym, obj))
     obj.sym = sym
     obj.hash = hash(sym) + 0x9e3779b9
     return obj
Пример #13
0
def intern(ns, sym):
    """Interns a non-ns-qualified Symbol in a namespace.
    """
    sym = Symbol(sym)
    if sym.ns is not None:
        raise InvalidArgumentException(
            "Can't intern namespace-qualified symbol")
    if not isinstance(ns, ModuleType):
        raise InvalidArgumentException
    v = getattr(ns, str(sym), None)
    if v is not None:
        if not isinstance(v, Var):
            raise Exception("Can't redefine {0} as {1}: is not Var".format(
                v, sym))
        if ns.__name__ == v.ns.__name__:
            return v
    v = Var(ns, sym)
    setattr(ns, sym.name, v)
    return v
Пример #14
0
 def read_term(self, reader):
     if not reader.has_more():
         return None
     
     while reader.current() in _whitespace:
         reader.next()
         if not reader.has_more():
             return None
     
     cur = reader.current()
     
     if cur == '"':
         return self.read_string(reader, '"')
     
     if self.is_number(cur) or cur == '-':
         return self.read_number(reader)
     
     if cur == '(':
         return self.read_list('(', reader, ')')
     
     if cur == ')':
         return StrObj(cur)
     
     chrs = []
     
     
     while (not reader.current() in _whitespace) \
               and (reader.current() != ')') \
               and (reader.current() != '(') \
               and reader.has_more():
         chrs.append(reader.current())
         reader.next()
     sym = "".join(chrs)
     
     #if sym.strip(_whitespace) == "":
     #    return None
     
     return Symbol.intern(StrObj(sym))
Пример #15
0
    def executeCode(self, code, ns=None):
        ns = ns or self.getNS()
        if code == []:
            return None
        newcode = expandMetas(code, self)
        newcode.append((RETURN_VALUE, None))
        c = Code(newcode, [], [], False, False, False,
                 str(Symbol(ns.__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)

        with threadBindings({self._NS_: ns}):
            retval = eval(c, ns.__dict__)
        return retval
Пример #16
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: RT.name(x.sym), 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 = types.FunctionType(c.to_code(), comp.ns.__dict__, name.name)
    return [(LOAD_CONST, c)], c
Пример #17
0
def find(*args):
    if len(args) == 1 and isinstance(args[0], Symbol):
        return Keyword.interned.val()[args[0]]()
    if len(args) == 2:
        return find(Symbol(*args))
Пример #18
0
from clojure.lang.var import Var
from clojure.lang.symbol import Symbol
from clojure.lang.primitives import Obj, IntObj
from clojure.lang.afn import AFn


class Add(AFn):
	def __init__(self):
		pass
	def evaluate(self):
		return self
	def invoke2(self, arg0, arg1):
		return IntObj(arg0.int_value() + arg1.int_value())
		
add = Var(Symbol.from_string("+"), Add())

class Sub(AFn):
	def __init__(self):
		pass
	def evaluate(self):
		return self
	def invoke2(self, arg0, arg1):
		return IntObj(arg0.int_value() - arg1.int_value())
		
sub = Var(Symbol.from_string("-"), Sub())

class Equals(AFn):
	def __init__(self):
		pass
	def evaluate(self):
		return self
Пример #19
0
def run_repl(opts, comp=None):
    """Initializes and runs the REPL. Assumes that RT.init has been called.

    Repeatedly reads well-formed forms from stdin (with an interactive prompt
    if a tty) and evaluates them (and prints the result if a tty). Exits on
    EOF.
    """
    if not opts.quiet and os.isatty(0):
        print VERSION_MSG

    if comp is None:
        curr = currentCompiler.get(lambda: None)
        if curr == None:
            comp = Compiler()
            currentCompiler.set(comp)
        else:
            comp = curr
    comp.setNS(Symbol("user"))
    core = sys.modules["clojure.core"]
    for i in dir(core):
        if not i.startswith("_"):
            setattr(comp.getNS(), i, getattr(core, i))

    line = opts.cmd
    last3 = [None, None, None]

    def firstLinePrompt():
        return comp.getNS().__name__ + "=> " if os.isatty(0) else ""

    def continuationLinePrompt():
        return "." * len(comp.getNS().__name__) + ".. " if os.isatty(0) else ""

    while True:
        # Evaluating before prompting caters for initially given forms.
        r = StringReader(line)
        while True:
            try:
                s = read(r, False, None, True)
                if s is None:
                    break
                res = comp.compile(s)
                out = comp.executeCode(res)
            except Exception:
                traceback.print_exc()
            else:
                if os.isatty(0):
                    RT.printTo(out)
                last3.pop()
                last3.insert(0, out)
                for i, value in enumerate(last3, 1):
                    v = findItem(Namespace("clojure.core"),
                                 Symbol("*{0}".format(i)))
                    if isinstance(value, Var):
                        v.bindRoot(value.deref())
                        v.setMeta(value.meta())
                    else:
                        v.bindRoot(value)
        try:
            line = raw_input(firstLinePrompt())
            while unbalanced(line):
                line += "\n" + raw_input(continuationLinePrompt())
        except BracketsException as exc:
            print exc
            continue
        except EOFError:
            print
            break
Пример #20
0
def main():
    """Main entry point to clojure-py.
    """
    def gobble(option, opt_str, value, parser):
        """Interprets all the remaining arguments as a single argument.
        """
        setattr(parser.values, option.dest, " ".join(parser.rargs))
        del parser.rargs[:]

    parser = OptionParser(
        usage="%prog [options] ... [-c cmd | file | -] [arg] ...",
        version=VERSION_MSG)
    parser.add_option(
        "-c",
        action="callback",
        dest="cmd",
        default="",
        callback=gobble,
        help="program passed in as a string (terminates option list)")
    parser.add_option("-i",
                      action="store_true",
                      dest="interactive",
                      help="inspect interactively after running script")
    parser.add_option(
        "-q",
        action="store_true",
        dest="quiet",
        help="don't print version message on interactive startup")
    # fooling OptionParser
    parser.add_option("--\b\bfile",
                      action="store_true",
                      help="    program read from script file")
    parser.add_option(
        "--\b\b-",
        action="store_true",
        help="    program read from stdin (default; interactive mode if a tty)"
    )
    parser.add_option(
        "--\b\barg ...",
        action="store_true",
        help="    arguments passed to program in *command-line-args*")
    args = sys.argv[1:]
    try:
        i = args.index("-")
    except ValueError:
        i = len(args)
    dash_and_post = args[i:]
    opts, command_line_args = parser.parse_args(args[:i])
    source = command_line_args.pop(0) if command_line_args else None
    command_line_args.extend(dash_and_post)
    opts.command_line_args = command_line_args

    RT.init()
    comp = Compiler()

    command_line_args_sym = findItem(Namespace("clojure.core"),
                                     Symbol("*command-line-args*"))
    with threadBindings({
            currentCompiler: comp,
            command_line_args_sym: command_line_args
    }):
        if source:
            requireClj(source)
        if opts.interactive or not source and not opts.cmd:
            import clojure.repl
            clojure.repl.enable_readline()
            clojure.repl.run_repl(opts, comp)
Пример #21
0
import os.path
import sys
import unittest
sys.path = [os.path.dirname(__file__) + "../"] + sys.path

from clojure.lang.cljkeyword import Keyword
from clojure.lang.namespace import Namespace, findItem
from clojure.lang.var import Var, threadBindings
from clojure.lang.symbol import Symbol
from clojure.main import requireClj

_NS_ = findItem(Namespace("clojure.core"), Symbol("*ns*"))


def mapTest(ns, var):
    class Test(unittest.TestCase):
        def testVar(self):
            with threadBindings({_NS_: var.ns}):
                var()

    name = ns + str(var)
    tst = Test
    tst.__name__ = name
    globals()[name] = tst


for x in os.listdir(os.path.dirname(__file__)):
    if x.endswith(".clj") and x.find("test") >= 0:
        print "Reading tests from", x
        requireClj(os.path.join(os.path.dirname(__file__), x))
        folder, file = os.path.split(x)
Пример #22
0
	def is_builtin(self):
		return BoolObj(True)
	def evaluate(self):
		return self
	def invoke2(self, arg0, arg1):
		val = arg1.evaluate()
		return Var(arg0, val)


class Recur(Obj):
	def __init__(self):
		pass
	def is_builtin(self):
		return BoolObj(True)
	def evaluate(self):
		return self
	def apply(self, args):
		nlist = []
		while args is not None:
			nlist.append(args.first().evaluate())
			args = args.rest()
		_RecurInfo.set_recur(List.from_list(nlist))
		return None
  
recur = Var(Symbol.from_string("recur"), Recur())  
d = Var(Symbol.from_string("def"), Def())	    	
fn = Var(Symbol.from_string("fn"), Fn())	
    	
ifsym = Var(Symbol.from_string("if"), If())	
        
Пример #23
0
from clojure.lang.ipersistentlist import IPersistentList
from clojure.lang.ipersistentvector import IPersistentVector
from clojure.lang.ipersistentmap import IPersistentMap
from clojure.lang.ipersistentset import IPersistentSet
from clojure.lang.ipersistentcollection import IPersistentCollection
from clojure.lang.iseq import ISeq
from clojure.lang.persistenthashmap import EMPTY as EMPTY_MAP
from clojure.lang.persistentvector import EMPTY as EMPTY_VECTOR
import clojure.lang.persistenthashset
from clojure.lang.persistenthashset import createWithCheck
import clojure.lang.rt as RT
from clojure.lang.symbol import Symbol
from clojure.lang.var import Var, threadBindings
import clojure.lang.namespace as namespace

_AMP_ = Symbol("&")
_FN_ = Symbol("fn")
_VAR_ = Symbol("var")
_APPLY_ = Symbol("apply")
_DEREF_ = Symbol("deref")
_HASHMAP_ = Symbol("clojure.core", "hashmap")
_CONCAT_ = Symbol("clojure.core", "concat")
_LIST_ = Symbol("clojure.core", "list")
_SEQ_ = Symbol("clojure.core", "seq")
_VECTOR_ = Symbol("clojure.core", "vector")
_QUOTE_ = Symbol("quote")
_SYNTAX_QUOTE_ = Symbol("`")
_UNQUOTE_ = Symbol("~")
_UNQUOTE_SPLICING_ = Symbol("~@")

ARG_ENV = Var(None).setDynamic()
Пример #24
0
from clojure.lang.cljexceptions import (ArityException, IllegalStateException)
from clojure.lang.cljkeyword import Keyword
from clojure.lang.ifn import IFn
from clojure.lang.iprintable import IPrintable
from clojure.lang.persistenthashmap import EMPTY
from clojure.lang.persistentarraymap import create
from clojure.lang.settable import Settable
from clojure.lang.symbol import Symbol
from clojure.lang.threadutil import ThreadLocal, currentThread

privateKey = Keyword("private")
macrokey = Keyword("macro")
STATIC_KEY = Keyword("static")
dvals = ThreadLocal()
privateMeta = create([privateKey, True])
UNKNOWN = Symbol("UNKNOWN")


class Var(ARef, Settable, IFn, IPrintable):
    def __init__(self, *args):
        """Var initializer

        Valid calls:
        - Var(namespace, symbol, root)
        - Var(namespace, symbol) -- unbound Var
        - Var(root) -- anonymous Var
        - Var() -- anonymous, unbound Var
        """
        self.ns = args[0] if len(args) >= 2 else None
        self.sym = args[1] if len(args) >= 2 else None
        root = args[-1] if len(args) % 2 else UNKNOWN
Пример #25
0
 def inner(func):
     builtins[Symbol(sym)] = func
     return func
Пример #26
0
 def __init__(self, sym, rest=None):
     AAlias.__init__(self, rest)
     self.sym = sym
     self.newsym = Symbol(RT.name(sym) + str(RT.nextID()))
Пример #27
0
from clojure.lang.ipersistentlist import IPersistentList
from clojure.lang.iseq import ISeq
from clojure.lang.lispreader import _AMP_, LINE_KEY, garg
from clojure.lang.namespace import Namespace, findNS, findItem, intern
from clojure.lang.persistentlist import PersistentList, EmptyList
from clojure.lang.persistentvector import PersistentVector
import clojure.lang.rt as RT
from clojure.lang.symbol import Symbol
from clojure.lang.var import Var, threadBindings
from clojure.util.byteplay import *
import clojure.util.byteplay as byteplay
import marshal
import types

_MACRO_ = Keyword("macro")
_NS_ = Symbol("*ns*")
version = (sys.version_info[0] * 10) + sys.version_info[1]

PTR_MODE_GLOBAL = "PTR_MODE_GLOBAL"
PTR_MODE_DEREF = "PTR_MODE_DEREF"

AUDIT_CONSTS = False


class MetaBytecode(object):
    pass


class GlobalPtr(MetaBytecode):
    def __init__(self, ns, name):
        self.ns = ns
Пример #28
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
Пример #29
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
Пример #30
0
def garg(n):
    return Symbol("rest" if n == -1 else "p{0}__{1}#".format(n, RT.nextID()))
Пример #31
0
def init_vars():
	from clojure.lang.var import Var
	conslist = Var(Symbol.from_string("cons_list*"), Cons_List())
Пример #32
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)]

    # Keep a list of compiled might-throw statements in
    # implicit-do try body
    body = comp.compile(form.first())
    form = form.next()

    if not form:
        # If there are no further body statements, or
        # catch/finally/else etc statements, just
        # compile the body
        return body

    catch = []
    els = None
    fin = None
    for subform in form:
        try:
            name = subform.first()
        except AttributeError:
            name = None
        if name in (Symbol("catch"), Symbol("except")):
            name = subform.first()
            if len(subform) != 4:
                raise CompilerException(
                    "try {0} blocks must be 4 items long".format(name), form)

            # Exception is second, val is third
            exception = subform.next().first()
            if not isinstance(exception, Symbol):
                raise CompilerException(
                    "exception passed to {0} block must be a symbol".format(
                        name), 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 {0} block must be a symbol".format(
                        name), 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:
            # Append to implicit do
            body.append((POP_TOP, None))
            body.extend(comp.compile(subform))

    if fin and not catch and not els:
        return compileTryFinally(body, comp.compile(fin))
    elif catch and not fin and not els:
        return compileTryCatch(comp, 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, body, catch, comp.compile(fin))

    if not fin and not catch and not els:
        # No other statements, return compiled body
        return body
Пример #33
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 {0} blocks must be 4 items long".format(name), form)

            # Exception is second, val is third
            exception = subform.next().first()
            if not isinstance(exception, Symbol):
                raise CompilerException(
                    "exception passed to {0} block must be a symbol".format(
                        name), 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 {0} block must be a symbol".format(
                        name), 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 {0}".format(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))