console.py 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. """Implementation and activation of a basic macro-powered REPL."""
  2. import code
  3. import ast
  4. import sys
  5. from macropy.core.macros import expand_entire_ast, detect_macros
  6. class MacroConsole(code.InteractiveConsole):
  7. def __init__(self, locals=None, filename="<console>"):
  8. code.InteractiveConsole.__init__(self, locals, filename)
  9. self.bindings = []
  10. def runsource(self, source, filename="<input>", symbol="single"):
  11. try:
  12. code = self.compile(source, filename, symbol)
  13. except (OverflowError, SyntaxError, ValueError):
  14. code = ""
  15. pass
  16. if code is None:
  17. # This means it's incomplete
  18. return True
  19. try:
  20. tree = ast.parse(source)
  21. bindings = detect_macros(tree)
  22. for p, names in bindings:
  23. __import__(p)
  24. self.bindings.extend([(sys.modules[p], bindings) for (p, bindings) in bindings])
  25. tree = expand_entire_ast(tree, source, self.bindings)
  26. tree = ast.Interactive(tree.body)
  27. code = compile(tree, filename, symbol, self.compile.compiler.flags, 1)
  28. except (OverflowError, SyntaxError, ValueError):
  29. # Case 1
  30. self.showsyntaxerror(filename)
  31. # This means there's a syntax error
  32. return False
  33. self.runcode(code)
  34. # This means it was successfully compiled; `runcode` takes care of
  35. # any runtime failures
  36. return False