quotes.py 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """Implementation of the Quasiquotes macro.
  2. `u`, `name`, `ast` and `ast_list` are the unquote delimiters, used to
  3. interpolate things into a quoted section.
  4. """
  5. from macropy.core.macros import *
  6. macros = Macros()
  7. @Walker
  8. def unquote_search(tree, **kw):
  9. res = check_annotated(tree)
  10. if res:
  11. func, right = res
  12. for f in [u, name, ast, ast_list]:
  13. if f.__name__ == func:
  14. return f(right)
  15. @macros.expr
  16. def q(tree, **kw):
  17. tree = unquote_search.recurse(tree)
  18. tree = ast_repr(tree)
  19. return tree
  20. @macros.block
  21. def q(tree, target, **kw):
  22. """Quasiquote macro, used to lift sections of code into their AST
  23. representation which can be manipulated at runtime. Used together with
  24. the `u`, `name`, `ast`, `ast_list` unquotes."""
  25. body = unquote_search.recurse(tree)
  26. new_body = ast_repr(body)
  27. return [Assign([target], new_body)]
  28. @macro_stub
  29. def u(tree):
  30. """Splices a value into the quoted code snippet, converting it into an AST
  31. via ast_repr"""
  32. return Literal(Call(Name(id="ast_repr"), [tree], [], None, None))
  33. @macro_stub
  34. def name(tree):
  35. "Splices a string value into the quoted code snippet as a Name"
  36. return Literal(Call(Name(id="Name"), [], [keyword("id", tree)], None, None))
  37. @macro_stub
  38. def ast(tree):
  39. "Splices an AST into the quoted code snippet"
  40. return Literal(tree)
  41. @macro_stub
  42. def ast_list(tree):
  43. """Splices a list of ASTs into the quoted code snippet as a List node"""
  44. return Literal(Call(Name(id="List"), [], [keyword("elts", tree)], None, None))