12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- from macropy.core.macros import *
- from macropy.core.quotes import macros, q, ast, u
- from macropy.core.hquotes import macros, hq, ast, u, name
- from macropy.core.cleanup import ast_ctx_fixer
- macros = Macros()
- def _():
- """Placeholder for a function argument in the `f` macro."""
- @macros.expr
- def f(tree, gen_sym, **kw):
- """Macro to concisely create function literals; any `_`s within the
- wrapped expression becomes an argument to the generated function."""
- @Walker
- def underscore_search(tree, collect, **kw):
- if isinstance(tree, Name) and tree.id == "_":
- name = gen_sym("_")
- tree.id = name
- collect(name)
- return tree
- tree, used_names = underscore_search.recurse_collect(tree)
- new_tree = q[lambda: ast[tree]]
- new_tree.args.args = [Name(id = x) for x in used_names]
- return new_tree
- @macros.expr
- def lazy(tree, **kw):
- """Macro to wrap an expression in a lazy memoizing thunk. This can be
- called via `thing()` to extract the value. The wrapped expression is
- only evaluated the first time the thunk is called and the result cached
- for all subsequent evaluations."""
- return hq[Lazy(lambda: ast[tree])]
- def get_interned(store, index, thunk):
- if store[index] is None:
- store[index] = [thunk()]
- return store[index][0]
- @register(injected_vars)
- def interned_count(**kw):
- return [0]
- @register(injected_vars)
- def interned_name(gen_sym, **kw):
- return gen_sym()
- @register(post_processing)
- def interned_processing(tree, gen_sym, interned_count, interned_name, **kw):
- if interned_count[0] != 0:
- with q as code:
- name[interned_name] = [None for x in range(u[interned_count[0]])]
- code = ast_ctx_fixer.recurse(code)
- code = map(fix_missing_locations, code)
- tree.body = code + tree.body
- return tree
- @macros.expr
- def interned(tree, interned_name, interned_count, **kw):
- """Macro to intern the wrapped expression on a per-module basis"""
- interned_count[0] += 1
- return hq[get_interned(name[interned_name], interned_count[0] - 1, lambda: ast[tree])]
|