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()
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
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
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)
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
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()
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 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 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)
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)
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()
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
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
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
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)
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.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 ]
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)