Пример #1
0
def requireClj(filename, stopafter=None):
    with open(filename) as fl:
        r = StringReader(fl.read())

    RT.init()
    comp = Compiler()
    comp.setFile(filename)

    pushThreadBindings({currentCompiler: comp})

    #o = open(filename+".cljc", "w")
    try:
        while True:
            EOF = object()
            s = read(r, False, EOF, True)
            if s is EOF:
                break
            #cPickle.dump(s, o)
            try:
                res = comp.compile(s)
                comp.executeCode(res)
                if stopafter is not None:
                    if hasattr(comp.getNS(), stopafter):
                        break
            except Exception as exp:
                print s, filename
                raise
    except IOError as e:
        pass
    finally:
        popThreadBindings()
Пример #2
0
def requireClj(filename, stopafter=None):
    """Compiles and executes the code in a clj file.
    
    If `stopafter` is given, then stop execution as soon as the `stopafter`
    name is defined in the current namespace of the compiler.
    """
    with open(filename) as fl:
        r = StringReader(fl.read())

    RT.init()
    comp = Compiler()
    comp.setFile(filename)

    with threadBindings({currentCompiler:
                         comp}):  #, open(filename + ".cljc", "w") as o:
        try:
            while True:
                EOF = object()
                s = read(r, False, EOF, True)
                if s is EOF:
                    break
                #cPickle.dump(s, o)
                try:
                    res = comp.compile(s)
                    comp.executeCode(res)
                    if stopafter is not None and hasattr(
                            comp.getNS(), stopafter):
                        break
                except Exception as exp:
                    print s, filename
                    raise
        except IOError as e:
            pass
Пример #3
0
def requireClj(filename, stopafter=None):
    with open(filename) as fl:
        r = StringReader(fl.read())

    RT.init()
    comp = Compiler()
    comp.setFile(filename)
    currentCompiler.set(comp)

    try:
        while True:
            s = read(r, True, None, True)
            try:
                res = comp.compile(s)
                comp.executeCode(res)
                if stopafter is not None:
                    if hasattr(comp.getNS(), stopafter):
                        break
            except IOError as exp:
                print s
                raise exp

            while True:
                ch = r.read()

                if ch == "":
                    raise IOError()

                if ch not in [" ", "\t", "\n", "\r"]:
                    r.back()
                    break
    except IOError as e:
        pass
Пример #4
0
class PyNamespaceTests(unittest.TestCase):
    def setUp(self):
        RT.init()
        self.comp = Compiler()
        currentCompiler.set(self.comp)
        self.comp.setNS(symbol('clojure.core'))

    def testBuiltinsNamespaced(self):
        self.assertEqual(self.eval('(py/str [1 2 3])'), '[1 2 3]')
        self.assertEqual(self.eval('(py/list "abc")'), ['a', 'b', 'c'])
        self.assertEqual(self.eval('((py/getattr "namespace" "__len__"))'), 9)

    def eval(self, code):
        r = StringReader(code)
        s = read(r, True, None, True)
        res = self.comp.compile(s)
        return self.comp.executeCode(res)
Пример #5
0
def requireClj(filename, stopafter=None):
    """Compiles and executes the code in a clj file.
    
    If `stopafter` is given, then stop execution as soon as the `stopafter`
    name is defined in the current namespace of the compiler.
    """
    with open(filename) as fl:
        r = StringReader(fl.read())

    RT.init()
    comp = Compiler()
    comp.setFile(filename)

    with threadBindings({currentCompiler: comp}): #, open(filename + ".cljc", "w") as o:
        try:
            while True:
                EOF = object()
                s = read(r, False, EOF, True)
                if s is EOF:
                    break
                #cPickle.dump(s, o)
                try:
                    res = comp.compile(s)
                    comp.executeCode(res)
                    if stopafter is not None and hasattr(comp.getNS(), stopafter):
                        break
                except Exception as exp:
                    print s, filename
                    raise
        except IOError as e:
            pass
Пример #6
0
def requireClj(filename, stopafter="concat"):
    with open(filename) as fl:
        r = StringReader(fl.read())

    RT.init()
    comp = Compiler()
    comp.setFile(filename)

    pushThreadBindings({currentCompiler: comp})

    #o = open(filename+".cljc", "w")
    try:
        while True:
            EOF = object()
            s = read(r, False, EOF, True)
            if s is EOF:
                break
            #cPickle.dump(s, o)
            try:
                res = comp.compile(s)
                print s, res

                comp.executeCode(res)
                if stopafter is not None and hasattr(comp.getNS(), stopafter):
                    break
            except Exception as exp:
                print s, filename
                raise
    except IOError as e:
        pass
    finally:
        popThreadBindings()
Пример #7
0
class ClojureCoreTests(unittest.TestCase):
    def eval(self, code):
        r = StringReader(code)
        s = read(r, True, None, True)
        res = self.comp.compile(s)
        return self.comp.executeCode(res)

    def setUp(self):
        RT.init()
        self.comp = Compiler()
        currentCompiler.set(self.comp)
        self.comp.setNS(symbol('clojure.core'))

    def testList(self):
        self.assertEqual(self.eval('(list 1 2 3)'), [1, 2, 3])
        self.assertEqual(self.eval('(list)'), [])
        self.assertTrue(isinstance(self.eval('(list 1 2 3)'),
                                   PersistentList))

    def testVector(self):
        self.assertEqual(self.eval('(vector 1 2 3)'), [1, 2, 3])
        self.assertEqual(self.eval('(vector)'), [])
        self.assertTrue(isinstance(self.eval('(vector 1 2 3)'),
                                   PersistentVector))

    def testCons(self):
        self.assertEqual(self.eval('(cons 1 nil)'), [1])
        self.assertEqual(self.eval('(cons 1 [2])'), [1, 2])
        self.assertEqual(self.eval('(cons 1 (cons 2 (cons 3 nil)))'),
                         [1, 2, 3])

    def testSeq(self):
        self.assertEqual(self.eval('(seq [])'), None)
        self.assertEqual(self.eval('(seq nil)'), None)

    def testFirst(self):
        self.assertEqual(self.eval('(first [1 2])'), 1)
        self.assertEqual(self.eval('(first nil)'), None)

    def testNext(self):
        self.assertEqual(self.eval('(next [1 2])'), [2])
        self.assertEqual(self.eval('(next nil)'), None)
Пример #8
0
class ClojureCoreTests(unittest.TestCase):
    def eval(self, code):
        r = StringReader(code)
        s = read(r, True, None, True)
        res = self.comp.compile(s)
        return self.comp.executeCode(res)

    def setUp(self):
        RT.init()
        self.comp = Compiler()
        currentCompiler.set(self.comp)
        self.comp.setNS(symbol('clojure.core'))

    def testList(self):
        self.assertEqual(self.eval('(list 1 2 3)'), [1, 2, 3])
        self.assertEqual(self.eval('(list)'), [])
        self.assertTrue(isinstance(self.eval('(list 1 2 3)'), PersistentList))

    def testVector(self):
        self.assertEqual(self.eval('(vector 1 2 3)'), [1, 2, 3])
        self.assertEqual(self.eval('(vector)'), [])
        self.assertTrue(
            isinstance(self.eval('(vector 1 2 3)'), PersistentVector))

    def testCons(self):
        self.assertEqual(self.eval('(cons 1 nil)'), [1])
        self.assertEqual(self.eval('(cons 1 [2])'), [1, 2])
        self.assertEqual(self.eval('(cons 1 (cons 2 (cons 3 nil)))'),
                         [1, 2, 3])

    def testSeq(self):
        self.assertEqual(self.eval('(seq [])'), None)
        self.assertEqual(self.eval('(seq nil)'), None)

    def testFirst(self):
        self.assertEqual(self.eval('(first [1 2])'), 1)
        self.assertEqual(self.eval('(first nil)'), None)

    def testNext(self):
        self.assertEqual(self.eval('(next [1 2])'), [2])
        self.assertEqual(self.eval('(next nil)'), None)
Пример #9
0
class TruthinessTests(unittest.TestCase):
    def setUp(self):
        RT.init()
        self.comp = Compiler()
        currentCompiler.set(self.comp)
        self.comp.setNS(symbol('clojure.core'))

    def testTrue(self):
        self.assertTrue(self.eval('(if true true false)'))

    def testList(self):
        self.assertTrue(self.eval('(if \'() true false)'))
        self.assertTrue(self.eval('(if \'(1) true false)'))

    def testVector(self):
        self.assertTrue(self.eval('(if [] true false)'))
        self.assertTrue(self.eval('(if [1] true false)'))

    def testMap(self):
        self.assertTrue(self.eval('(if {} true false)'))
        self.assertTrue(self.eval('(if {1 2} true false)'))

    @skip  # hash sets aren't implemented yet
    def testSet(self):
        self.assertTrue(self.eval('(if #{} true false)'))
        self.assertTrue(self.eval('(if #{1} true false)'))

    def testNil(self):
        self.assertFalse(self.eval('(if nil true false)'))
        self.assertFalse(self.eval('(if nil true false)'))

    def testFalse(self):
        self.assertFalse(self.eval('(if false true false)'))

    def eval(self, code):
        r = StringReader(code)
        s = read(r, True, None, True)
        res = self.comp.compile(s)
        return self.comp.executeCode(res)
Пример #10
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)
Пример #11
0
def main():
    RT.init()
    comp = Compiler()

    pushThreadBindings({currentCompiler: comp})

    try:

        if not sys.argv[1:]:
            import clojure.repl
            clojure.repl.enable_readline()
            clojure.repl.run_repl(comp)
        else:
            for x in sys.argv[1:]:
                if x.endswith('.clj'):
                    requireClj(x)
    finally:
        popThreadBindings()
Пример #12
0
def requireClj(filename, stopafter=None):
    with open(filename) as fl:
        r = StringReader(fl.read())

    RT.init()
    comp = Compiler()
    comp.setFile(filename)
    currentCompiler.set(comp)

    # o = open(filename+".cljc", "w")
    try:
        while True:
            s = read(r, False, None, True)
            if s is None:
                break
            # cPickle.dump(s, o)
            try:
                res = comp.compile(s)
                comp.executeCode(res)
                if stopafter is not None:
                    if hasattr(comp.getNS(), stopafter):
                        break
            except Exception as exp:
                print s, filename
                raise

            while True:
                ch = r.read()

                if ch == "":
                    raise IOError()

                if ch not in [" ", "\t", "\n", "\r"]:
                    r.back()
                    break
    except IOError as e:
        pass
Пример #13
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
Пример #14
0
def run_repl(comp=None):
    """
    Starts the repl. Assumes that RT.init has allready be called.
    """
    if comp is None:
        curr = currentCompiler.get(lambda: None)
        if curr == None:
            comp = Compiler()
            currentCompiler.set(comp)
        else:
            comp = curr
    comp.setNS(symbol("user"))

    last3 = [None, None, None]

    def execute(string):
        r = StringReader(string)
        s = read(r, False, None, True)
        res = comp.compile(s)
        return comp.executeCode(res)

    while 1:
        for i, value in enumerate(last3, 1):
            sym = symbol('*%s' % i)
            v = internVar(comp.getNS(), sym)
            v.setDynamic(True)
            if isinstance(value, Var):
                v.bindRoot(value.deref())
                v.setMeta(value.meta())
            else:
                v.bindRoot(value)

        try:
            line = raw_input(comp.getNS().__name__ + "=> ")
        except EOFError:
            break

        if not line:
            continue

        invalid = False
        while 1:
            unbalance = unbalanced(line)

            if unbalance == -1:
                invalid = True
                break
            elif unbalance is False:
                break

            try:
                new_line = '\n' + raw_input('.' * len(comp.getNS().__name__) + '.. ')
            except EOFError:
                break

            if not new_line.strip().startswith(';'):
                line += new_line

        if invalid:
            print "Invalid input"
            continue

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

        try:
            out = execute(line)
        except Exception:
            traceback.print_exc()
        else:
            last3.pop()
            last3.insert(0, out)
            print out
Пример #15
0
def run_repl(comp=None):
    """
    Starts the repl. Assumes that RT.init has allready be called.
    """
    print "clojure-py", VERSION
    print "Python", sys.version

    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))

    last3 = [None, None, None]

    def execute(string):
        r = StringReader(string)
        s = read(r, False, None, True)
        res = comp.compile(s)
        return comp.executeCode(res)

    while 1:
        #for i, value in enumerate(last3, 1):
        #    v = findVar(symbol("clojure.core", "*%s" % i))
        #    if isinstance(value, Var):
        #        v.bindRoot(value.deref())
        #        v.setMeta(value.meta())
        #    else:
        #        v.bindRoot(value)

        try:
            line = raw_input(comp.getNS().__name__ + "=> ")
        except EOFError:
            print
            break

        if not line:
            continue

        invalid = False
        while 1:
            unbalance = unbalanced(line)

            if unbalance == -1:
                invalid = True
                break
            elif unbalance is False:
                break

            try:
                new_line = '\n' + raw_input('.' * len(comp.getNS().__name__) + '.. ')
            except EOFError:
                break

            if not new_line.strip().startswith(';'):
                line += new_line

        if invalid:
            print "Invalid input"
            continue

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

        try:
            out = execute(line)
        except Exception:
            traceback.print_exc()
        else:
            last3.pop()
            last3.insert(0, out)
            RT.printTo(out)
Пример #16
0
 def setUp(self):
     RT.init()
     self.comp = Compiler()
     currentCompiler.set(self.comp)
     self.comp.setNS(symbol('clojure.core'))
Пример #17
0
 def setUp(self):
     RT.init()
     self.comp = Compiler()
     currentCompiler.set(self.comp)
     self.comp.setNS(symbol('clojure.core'))
Пример #18
0
class NonOverloadedFunctions(unittest.TestCase):
    def setUp(self):
        RT.init()
        self.comp = Compiler()
        currentCompiler.set(self.comp)
        self.comp.setNS(symbol('clojure.core'))

    def testZeroArguments(self):
        actual = self.compileActual('(defn abc [] 2)')
        expected = self.compileExpected('''
            def abc():
                return 2''')
        items = [(a == e, a, e)
                 for a, e in self.zipActualExpected(actual, expected)]
        try:
            assert all(item[0] for item in items)
        except AssertionError:
            pprint.pprint(items)

    def testOneArgument(self):
        actual = self.compileActual('(defn abc ([x] x))')
        expected = self.compileExpected('''
            def abc(x):
                return x''')
        items = [(a == e, a, e)
                 for a, e in self.zipActualExpected(actual, expected)]
        try:
            assert all(item[0] for item in items)
        except AssertionError:
            pprint.pprint(items)

    def testMultipleArguments(self):
        actual = self.compileActual('(defn abc ([x] x) ([x y] y))')
        expected = self.compileExpected('''
            def abc(*__argsv__):
                if __argsv__.__len__() == 1:
                    x = __argsv__[0]
                    return x
                elif __argsv__.__len__() == 2:
                    x = __argsv__[0]
                    y = __argsv__[1]
                    return y
                raise Exception()''')
        # There's a slight different between clojure-py's compiled code and
        # Python's: clojure-py produces (LOAD_CONST, <type
        # 'exceptions.Exception'>) while Python produces (LOAD_CONST,
        # 'Exception'). Just ignore it; it's not what we're testing here.

        # Also the last to two bytecodes generated by Python are to load None
        # and return it, which isn't necessary after raising an exception.
        items = [(a == e, a, e)
                 for a, e in self.zipActualExpected(actual, expected[:-2])
                 if e[1] != 'Exception']
        try:
            assert all(item[0] for item in items)
        except AssertionError:
            pprint.pprint(items)

    def zipActualExpected(self, actual, expected):
        difference = len(expected) - len(actual)
        return zip(chain(actual, repeat(None, difference)),
                   chain(expected, repeat(None, -difference)))

    def compileActual(self, code):
        r = StringReader(code)
        s = read(r, True, None, True)
        res = self.comp.compile(s)
        fn = self.comp.executeCode(res)
        return [
            c for c in Code.from_code(fn.deref().func_code).code[:]
            if c[0] is not SetLineno
        ]

    def compileExpected(self, code):
        codeobject = compile(dedent(code), 'string', 'exec')
        globs = {}
        result = eval(codeobject, {}, globs)
        return [
            c for c in Code.from_code(globs['abc'].func_code).code[:]
            if c[0] is not SetLineno
        ]
Пример #19
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)