tracing.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. from macropy.core.macros import *
  2. from macropy.core.hquotes import macros, u, hq, unhygienic
  3. import copy
  4. macros = Macros()
  5. def wrap(printer, txt, x):
  6. string = txt + " -> " + repr(x)
  7. printer(string)
  8. return x
  9. def wrap_simple(printer, txt, x):
  10. string = txt
  11. printer(string)
  12. return x
  13. @macros.expr
  14. def log(tree, exact_src, **kw):
  15. """Prints out source code of the wrapped expression and the value it
  16. evaluates to"""
  17. new_tree = hq[wrap(unhygienic[log], u[exact_src(tree)], ast[tree])]
  18. return new_tree
  19. @macros.expr
  20. def show_expanded(tree, expand_macros, **kw):
  21. """Prints out the expanded version of the wrapped source code, after all
  22. macros inside it have been expanded"""
  23. expanded_tree = expand_macros(tree)
  24. new_tree = hq[wrap_simple(unhygienic[log], u[unparse(expanded_tree)], ast[expanded_tree])]
  25. return new_tree
  26. @macros.block
  27. def show_expanded(tree, expand_macros, **kw):
  28. """Prints out the expanded version of the wrapped source code, after all
  29. macros inside it have been expanded"""
  30. new_tree = []
  31. for stmt in tree:
  32. new_stmt = expand_macros(stmt)
  33. with hq as code:
  34. unhygienic[log](u[unparse(new_stmt)])
  35. new_tree.append(code)
  36. new_tree.append(new_stmt)
  37. return new_tree
  38. def trace_walk_func(tree, exact_src):
  39. @Walker
  40. def trace_walk(tree, stop, **kw):
  41. if isinstance(tree, expr) and \
  42. tree._fields != () and \
  43. type(tree) is not Name:
  44. try:
  45. literal_eval(tree)
  46. stop()
  47. return tree
  48. except ValueError:
  49. txt = exact_src(tree)
  50. trace_walk.walk_children(tree)
  51. wrapped = hq[wrap(unhygienic[log], u[txt], ast[tree])]
  52. stop()
  53. return wrapped
  54. elif isinstance(tree, stmt):
  55. txt = exact_src(tree)
  56. trace_walk.walk_children(tree)
  57. with hq as code:
  58. unhygienic[log](u[txt])
  59. stop()
  60. return [code, tree]
  61. return trace_walk.recurse(tree)
  62. @macros.expr
  63. def trace(tree, exact_src, **kw):
  64. """Traces the wrapped code, printing out the source code and evaluated
  65. result of every statement and expression contained within it"""
  66. ret = trace_walk_func(tree, exact_src)
  67. return ret
  68. @macros.block
  69. def trace(tree, exact_src, **kw):
  70. """Traces the wrapped code, printing out the source code and evaluated
  71. result of every statement and expression contained within it"""
  72. ret = trace_walk_func(tree, exact_src)
  73. return ret
  74. def require_transform(tree, exact_src):
  75. ret = trace_walk_func(copy.deepcopy(tree), exact_src)
  76. trace_walk_func(copy.deepcopy(tree), exact_src)
  77. new = hq[ast[tree] or wrap_require(lambda log: ast[ret])]
  78. return new
  79. def wrap_require(thunk):
  80. out = []
  81. thunk(out.append)
  82. raise AssertionError("Require Failed\n" + "\n".join(out))
  83. @macros.expr
  84. def require(tree, exact_src, **kw):
  85. """A version of assert that traces the expression's evaluation in the
  86. case of failure. If used as a block, performs this on every expression
  87. within the block"""
  88. return require_transform(tree, exact_src)
  89. @macros.block
  90. def require(tree, exact_src, **kw):
  91. """A version of assert that traces the expression's evaluation in the
  92. case of failure. If used as a block, performs this on every expression
  93. within the block"""
  94. for expr in tree:
  95. expr.value = require_transform(expr.value, exact_src)
  96. return tree
  97. @macros.expose_unhygienic
  98. def log(x):
  99. print(x)