diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 8b2a456ed..3732f65d5 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -50,7 +50,7 @@ (return panic))]] `(if ~test (do ~@body) None)) -(defmacro defreader [&compiler key #* body] +(defmacro defreader [_hy_compiler key #* body] "Define a new reader macro. Reader macros are expanded at read time and allow you to modify the behavior @@ -89,9 +89,9 @@ See the :ref:`reader macros docs ` for more detailed information on how reader macros work and are defined. " - (when (not (isinstance &compiler.scope hy.scoping.ScopeGlobal)) - (raise (&compiler._syntax-error - &compiler.this + (when (not (isinstance _hy_compiler.scope hy.scoping.ScopeGlobal)) + (raise (_hy_compiler._syntax-error + _hy_compiler.this f"Cannot define reader macro outside of global scope."))) (when (not (isinstance key hy.models.Symbol)) @@ -113,7 +113,7 @@ (get _hy_reader_macros ~dispatch-key))))) -(defmacro get-macro [&compiler arg1 [arg2 None]] +(defmacro get-macro [_hy_compiler arg1 [arg2 None]] "Get the function object used to implement a macro. This works for all sorts of macros: core macros, global (i.e., module-level) macros, local macros, and reader macros. For regular (non-reader) macros, ``get-macro`` is called with one argument, a symbol or string literal, which can be premangled or not according to taste. For reader macros, this argument must be preceded by the literal keyword ``:reader`` (and note that the hash mark, ``#``, is not included in the name of the reader macro). :: (get-macro my-macro) @@ -131,9 +131,9 @@ [(hy.mangle arg1) False])) (setv namespace (if reader? "_hy_reader_macros" "_hy_macros")) (cond - (and (not reader?) (setx local (.get (_local-macros &compiler) name))) + (and (not reader?) (setx local (.get (_local-macros _hy_compiler) name))) local - (in name (getattr &compiler.module namespace {})) + (in name (getattr _hy_compiler.module namespace {})) `(get ~(hy.models.Symbol namespace) ~name) (in name (getattr builtins namespace {})) `(get (. hy.I.builtins ~(hy.models.Symbol namespace)) ~name) @@ -143,7 +143,7 @@ name))))) -(defmacro local-macros [&compiler] +(defmacro local-macros [_hy_compiler] #[[Expands to a dictionary mapping the mangled names of local macros to the function objects used to implement those macros. Thus, ``local-macros`` provides a rough local equivalent of ``_hy_macros``. :: (defn f [] @@ -156,12 +156,12 @@ The equivalency is rough in the sense that ``local-macros`` returns a literal dictionary, not a preexisting object that Hy uses for resolving macro names. So, modifying the dictionary will have no effect. See also :hy:func:`get-macro `.]] - (_local-macros &compiler)) + (_local-macros _hy_compiler)) -(defn _local_macros [&compiler] +(defn _local_macros [_hy_compiler] (setv seen #{}) (dfor - state &compiler.local_state_stack + state _hy_compiler.local_state_stack m (get state "macros") :if (not-in m seen) :do (.add seen m) diff --git a/hy/macros.py b/hy/macros.py index e32566163..9f4f77ce5 100644 --- a/hy/macros.py +++ b/hy/macros.py @@ -43,18 +43,18 @@ def pattern_macro(names, pattern, shadow=None): def dec(fn): def wrapper_maker(name): - def wrapper(hy_compiler, *args): + def wrapper(_hy_compiler, *args): if shadow and any(is_unpack("iterable", x) for x in args): # Try a shadow function call with this name instead. return Expression( [Expression(map(Symbol, [".", "hy", "pyops", name])), *args] - ).replace(hy_compiler.this) + ).replace(_hy_compiler.this) - expr = hy_compiler.this + expr = _hy_compiler.this if py_version_required and sys.version_info < py_version_required: - raise hy_compiler._syntax_error( + raise _hy_compiler._syntax_error( expr, "`{}` requires Python {} or later".format( name, ".".join(map(str, py_version_required)) @@ -64,13 +64,13 @@ def wrapper(hy_compiler, *args): try: parse_tree = pattern.parse(args) except NoParseError as e: - raise hy_compiler._syntax_error( + raise _hy_compiler._syntax_error( expr[min(e.state.pos + 1, len(expr) - 1)], "parse error for pattern macro '{}': {}".format( name, e.msg.replace("end of input", "end of macro call") ), ) - return fn(hy_compiler, expr, name, *parse_tree) + return fn(_hy_compiler, expr, name, *parse_tree) return wrapper @@ -415,10 +415,11 @@ def macroexpand(tree, module, compiler=None, once=False, result_ok=True): if compiler: compiler.this = tree obj = m( + # If the macro's first parameter is named + # `_hy_compiler`, pass in the current compiler object + # in its place. *([compiler] - if m.__code__.co_varnames and m.__code__.co_varnames[0] in ( - 'compiler', 'hy_compiler', 'hyx_XampersandXcompiler', - 'ETname') + if m.__code__.co_varnames[:1] == ('_hy_compiler',) else []), *tree[1:]) if isinstance(obj, (hy.compiler.Result, AST)):