def requireClj(filename, stopafter = None): with open(filename) as fl: r = StringReader(fl.read()) RT.init() comp = Compiler() 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
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)
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)
class PyNamespaceTests(unittest.TestCase): def setUp(self): RT.init() self.comp = Compiler() currentCompiler.set(self.comp) self.comp.setNS(Symbol.intern('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 testBuiltinsNotIncluded(self): self.assertRaises(NameError, self.eval, '(str [1 2 3])') self.assertRaises(NameError, self.eval, '(getattr [1 2 3] "pop")') def eval(self, code): r = StringReader(code) s = read(r, True, None, True) res = self.comp.compile(s) return self.comp.executeCode(res)
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 None 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)
def main(): requireClj(os.path.dirname(__file__) + "/clj/clojure/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)
def setUp(self): RT.init() self.comp = Compiler() currentCompiler.set(self.comp) self.comp.setNS(symbol("clojure.core"))
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.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]
def setUp(self): RT.init() self.comp = Compiler() currentCompiler.set(self.comp) self.comp.setNS(Symbol.intern('clojure.core'))