def require(source_module, target_module, assignments, prefix=""): """Load macros from `source_module` in the namespace of `target_module`. `assignments` maps old names to new names, or should be the string "ALL". If `prefix` is nonempty, it is prepended to the name of each imported macro. (This means you get macros named things like "mymacromodule.mymacro", which looks like an attribute of a module, although it's actually just a symbol with a period in its name.) This function is called from the `require` special form in the compiler. """ seen_names = set() if prefix: prefix += "." if assignments != "ALL": assignments = {mangle(str_type(k)): v for k, v in assignments} for d in _hy_macros, _hy_tag: for name, macro in d[source_module].items(): seen_names.add(name) if assignments == "ALL": d[target_module][mangle(prefix + name)] = macro elif name in assignments: d[target_module][mangle(prefix + assignments[name])] = macro if assignments != "ALL": unseen = frozenset(assignments.keys()).difference(seen_names) if unseen: raise ImportError("cannot require names: " + repr(list(unseen)))
def __init__(self, spy=False, output_fn=None, locals=None, filename="<input>"): self.spy = spy if output_fn is None: self.output_fn = repr elif callable(output_fn): self.output_fn = output_fn else: if "." in output_fn: parts = [mangle(x) for x in output_fn.split(".")] module, f = '.'.join(parts[:-1]), parts[-1] self.output_fn = getattr(importlib.import_module(module), f) else: self.output_fn = __builtins__[mangle(output_fn)] code.InteractiveConsole.__init__(self, locals=locals, filename=filename) # Pre-mangle symbols for repl recent results: *1, *2, *3 self._repl_results_symbols = [ mangle("*{}".format(i + 1)) for i in range(3) ] self.locals.update({sym: None for sym in self._repl_results_symbols})
def _(fn): _name = mangle('#{}'.format(name)) if not PY3: _name = _name.encode('UTF-8') fn.__name__ = _name module_name = fn.__module__ if module_name.startswith("hy.core"): module_name = None _hy_tag[module_name][mangle(name)] = fn return fn
def macro(name): """Decorator to define a macro called `name`. This stores the macro `name` in the namespace for the module where it is defined. If the module where it is defined is in `hy.core`, then the macro is stored in the default `None` namespace. This function is called from the `defmacro` special form in the compiler. """ name = mangle(name) def _(fn): fn.__name__ = '({})'.format(name) try: fn._hy_macro_pass_compiler = hy.inspect.has_kwargs(fn) except Exception: # An exception might be raised if fn has arguments with # names that are invalid in Python. fn._hy_macro_pass_compiler = False module_name = fn.__module__ if module_name.startswith("hy.core"): module_name = None _hy_macros[module_name][name] = fn return fn return _
def __init__(self, spy=False, output_fn=None, locals=None, filename="<input>"): self.spy = spy if output_fn is None: self.output_fn = repr elif callable(output_fn): self.output_fn = output_fn else: if "." in output_fn: parts = [mangle(x) for x in output_fn.split(".")] module, f = '.'.join(parts[:-1]), parts[-1] self.output_fn = getattr(importlib.import_module(module), f) else: self.output_fn = __builtins__[mangle(output_fn)] code.InteractiveConsole.__init__(self, locals=locals, filename=filename)
def macroexpand(tree, compiler, once=False): """Expand the toplevel macros for the `tree`. Load the macros from the given `module_name`, then expand the (top-level) macros in `tree` until we no longer can. """ load_macros(compiler.module_name) while True: if not isinstance(tree, HyExpression) or tree == []: break fn = tree[0] if fn in ("quote", "quasiquote") or not isinstance(fn, HySymbol): break fn = mangle(fn) m = _hy_macros[compiler.module_name].get(fn) or _hy_macros[None].get( fn) if not m: break opts = {} if m._hy_macro_pass_compiler: opts['compiler'] = compiler try: m_copy = make_empty_fn_copy(m) m_copy(compiler.module_name, *tree[1:], **opts) except TypeError as e: msg = "expanding `" + str(tree[0]) + "': " msg += str(e).replace("<lambda>()", "", 1).strip() raise HyMacroExpansionError(tree, msg) try: obj = m(compiler.module_name, *tree[1:], **opts) except HyTypeError as e: if e.expression is None: e.expression = tree raise except Exception as e: msg = "expanding `" + str(tree[0]) + "': " + repr(e) raise HyMacroExpansionError(tree, msg) tree = replace_hy_obj(obj, tree) if once: break tree = wrap_value(tree) return tree
def macroexpand(tree, compiler, once=False): """Expand the toplevel macros for the `tree`. Load the macros from the given `module_name`, then expand the (top-level) macros in `tree` until we no longer can. """ load_macros(compiler.module_name) while True: if not isinstance(tree, HyExpression) or tree == []: break fn = tree[0] if fn in ("quote", "quasiquote") or not isinstance(fn, HySymbol): break fn = mangle(fn) m = _hy_macros[compiler.module_name].get(fn) or _hy_macros[None].get(fn) if not m: break opts = {} if m._hy_macro_pass_compiler: opts['compiler'] = compiler try: m_copy = make_empty_fn_copy(m) m_copy(compiler.module_name, *tree[1:], **opts) except TypeError as e: msg = "expanding `" + str(tree[0]) + "': " msg += str(e).replace("<lambda>()", "", 1).strip() raise HyMacroExpansionError(tree, msg) try: obj = m(compiler.module_name, *tree[1:], **opts) except HyTypeError as e: if e.expression is None: e.expression = tree raise except Exception as e: msg = "expanding `" + str(tree[0]) + "': " + repr(e) raise HyMacroExpansionError(tree, msg) tree = replace_hy_obj(obj, tree) if once: break tree = wrap_value(tree) return tree
def __init__(self, spy=False, output_fn=None, locals=None, filename="<input>"): self.spy = spy if output_fn is None: self.output_fn = repr elif callable(output_fn): self.output_fn = output_fn else: if "." in output_fn: parts = [mangle(x) for x in output_fn.split(".")] module, f = '.'.join(parts[:-1]), parts[-1] self.output_fn = getattr(importlib.import_module(module), f) else: self.output_fn = __builtins__[mangle(output_fn)] code.InteractiveConsole.__init__(self, locals=locals, filename=filename) # Pre-mangle symbols for repl recent results: *1, *2, *3 self._repl_results_symbols = [mangle("*{}".format(i + 1)) for i in range(3)] self.locals.update({sym: None for sym in self._repl_results_symbols})
def runsource(self, source, filename='<input>', symbol='single'): global SIMPLE_TRACEBACKS try: try: do = import_buffer_to_hst(source) except PrematureEndOfInput: return True except LexException as e: if e.source is None: e.source = source e.filename = filename print(e, file=sys.stderr) return False try: def ast_callback(main_ast, expr_ast): if self.spy: # Mush the two AST chunks into a single module for # conversion into Python. new_ast = ast.Module(main_ast.body + [ast.Expr(expr_ast.body)]) print(astor.to_source(new_ast)) value = hy_eval(do, self.locals, "__console__", ast_callback) except HyTypeError as e: if e.source is None: e.source = source e.filename = filename if SIMPLE_TRACEBACKS: print(e, file=sys.stderr) else: self.showtraceback() return False except Exception: self.showtraceback() return False if value is not None: # Make the last non-None value available to # the user as `*1`. self.locals[mangle("*1")] = value # Print the value. try: output = self.output_fn(value) except Exception: self.showtraceback() return False print(output) return False
def macroexpand_1(tree, compiler): """Expand the toplevel macro from `tree` once, in the context of `module_name`.""" if isinstance(tree, HyExpression): if tree == []: return tree fn = tree[0] if fn in ("quote", "quasiquote"): return tree ntree = HyExpression(tree[:]) ntree.replace(tree) opts = {} if isinstance(fn, HySymbol): fn = mangle(str_type(fn)) m = _hy_macros[compiler.module_name].get(fn) if m is None: m = _hy_macros[None].get(fn) if m is not None: if m._hy_macro_pass_compiler: opts['compiler'] = compiler try: m_copy = make_empty_fn_copy(m) m_copy(compiler.module_name, *ntree[1:], **opts) except TypeError as e: msg = "expanding `" + str(tree[0]) + "': " msg += str(e).replace("<lambda>()", "", 1).strip() raise HyMacroExpansionError(tree, msg) try: obj = m(compiler.module_name, *ntree[1:], **opts) except HyTypeError as e: if e.expression is None: e.expression = tree raise except Exception as e: msg = "expanding `" + str(tree[0]) + "': " + repr(e) raise HyMacroExpansionError(tree, msg) replace_hy_obj(obj, tree) return obj return ntree return tree
def error_handler(e, use_simple_traceback=False): self.locals[mangle("*e")] = e if use_simple_traceback: print(e, file=sys.stderr) else: self.showtraceback()