Exemplo n.º 1
0
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)))
Exemplo n.º 2
0
Arquivo: macros.py Projeto: kartikm/hy
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)))
Exemplo n.º 3
0
    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})
Exemplo n.º 4
0
Arquivo: macros.py Projeto: kartikm/hy
    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
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
Arquivo: macros.py Projeto: kartikm/hy
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 _
Exemplo n.º 7
0
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 _
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
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
Exemplo n.º 10
0
Arquivo: macros.py Projeto: kartikm/hy
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
Exemplo n.º 11
0
    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})
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
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
Exemplo n.º 14
0
 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()
Exemplo n.º 15
0
 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()