Пример #1
0
def as_model(x):
    """Recurisvely promote an object ``x`` into its canonical model form.

    When creating macros its possible to return non-Hy model objects or
    even create an expression with non-Hy model elements::

       => (defmacro hello []
       ...  "world!")

       => (defmacro print-inc [a]
       ...  `(print ~(+ a 1)))
       => (print-inc 1)
       2  ; in this case the unquote form (+ 1 1) would splice the literal
          ; integer ``2`` into the print statement, *not* the model representation
          ; ``(hy.model.Integer 2)``

    This is perfectly fine, because Hy autoboxes these literal values into their
    respective model forms at compilation time.

    The one case where this distinction between the spliced composit form and
    the canonical model tree representation matters, is when comparing some
    spliced model tree with another known tree::

       => (= `(print ~(+ 1 1)) '(print 2))
       False  ; False because the literal int ``2`` in the spliced form is not
              ; equal to the ``(hy.model.Integer 2)`` value in the known form.

       => (= (hy.as-model `(print ~(+ 1 1)) '(print 2)))
       True  ; True because ``as-model`` has walked the expression and promoted
             ; the literal int ``2`` to its model for ``(hy.model.Integer 2)``
    """

    if id(x) in _seen:
        raise HyWrapperError("Self-referential structure detected in {!r}".format(x))

    new = _wrappers.get(type(x), lambda y: y)(x)
    if not isinstance(new, Object):
        raise HyWrapperError("Don't know how to wrap {!r}: {!r}".format(type(x), x))
    if isinstance(x, Object):
        new = new.replace(x, recursive=False)
    return new
Пример #2
0
def wrap_value(x):
    """Wrap `x` into the corresponding Hy type.

    This allows replace_hy_obj to convert a non Hy object to a Hy object.

    This also allows a macro to return an unquoted expression transparently.

    """

    new = _wrappers.get(type(x), lambda y: y)(x)
    if not isinstance(new, Object):
        raise HyWrapperError("Don't know how to wrap {!r}: {!r}".format(type(x), x))
    if isinstance(x, Object):
        new = new.replace(x, recursive=False)
    return new