def macroexpand(form, comp, one=False): if isinstance(form.first(), Symbol): if form.first().ns == 'py' or form.first().ns == "py.bytecode": return form, False itm = findItem(comp.getNS(), form.first()) dreffed = itm if isinstance(dreffed, Var): dreffed = itm.deref() # Handle macros here # TODO: Break this out into a seperate function if ismacro(itm) or ismacro(dreffed): macro = dreffed args = RT.seqToTuple(form.next()) macroform = getattr(macro, "_macro-form", macro) mresult = macro(macroform, None, *args) if hasattr(mresult, "withMeta") and hasattr(form, "meta"): mresult = mresult.withMeta(form.meta()) if not one: mresult = comp.compile(mresult) return mresult, True return form, False
def macroexpand(form, comp, one = False): if isinstance(form.first(), Symbol): if form.first().ns == 'py' or form.first().ns == "py.bytecode": return form, False itm = findItem(comp.getNS(), form.first()) dreffed = itm if isinstance(dreffed, Var): dreffed = itm.deref() # Handle macros here # TODO: Break this out into a seperate function if ismacro(itm) or ismacro(dreffed): macro = dreffed args = RT.seqToTuple(form.next()) macroform = macro if hasattr(macro, "_macro-form"): macroform = getattr(macro, "_macro-form") mresult = macro(macroform, None, *args) if hasattr(mresult, "withMeta") \ and hasattr(form, "meta"): mresult = mresult.withMeta(form.meta()) mresult = comp.compile(mresult) return mresult, True return form, False
def __init__(self): self.recurPoint = RT.list() self.names = None self.ns = clojure_core = Namespace("clojure.core") self.lastlineno = -1 self.aliases = {} self.filename = "<unknown>" self._NS_ = findItem(clojure_core, _NS_)
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)
def executeCode(self, code): ns = self.getNS() if code == []: return None print(code) pushThreadBindings( {findItem(findOrCreateNamespace("clojure.core"), _NS_): ns}) retval = code.toFunc(ns.__dict__, filename = self.filename)() self.getNS().__file__ = self.filename popThreadBindings() return retval
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
import os.path import sys sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) import unittest 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))
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)
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 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)