def evaluate(self, example, parser=Lissp()): lissp = self.lissp(example.document.text[example.start:example.end]) if lissp: python = example.parsed.source parser.compiler.ns = example.namespace hissp = parser.reads(lissp) compiled = parser.compiler.compile(hissp) + "\n" from difflib import context_diff assert norm_gensym_eq(compiled, python), ''.join( context_diff( indent(python, " ").splitlines(True), indent(compiled, " ").splitlines(True), )) return super().evaluate(example)
def evaluate(self, example, parser=Lissp()): lissp = self.lissp(example.document.text[example.start:example.end]) if lissp: python = example.parsed.source parser.compiler.ns = example.namespace hissp = parser.reads(lissp) compiled = parser.compiler.compile(hissp) + "\n" assert norm_gensym_eq(compiled, python), dedent(f""" EXPECTED PYTHON: {indent(python, " ")} ACTUALLY COMPILED TO: {indent(compiled, " ")} . """) return super().evaluate(example)
class LisspREPL(InteractiveConsole): """Lissp's Read-Evaluate-Print Loop, layered on Python's. You can initialize the REPL with a locals dict, which is useful for debugging other modules. Call interact() to start. """ def __init__(self, locals=None, filename="<console>"): super().__init__(locals, filename) self.lissp = Lissp(ns=locals) self.locals = self.lissp.ns def runsource(self, source, filename="<input>", symbol="single"): """:meta private:""" try: self.lissp.filename = filename source = self.lissp.compile(source) except SoftSyntaxError: return True except CompileError as e: print(f'{sys.ps1}# CompileError', file=sys.stderr) print(e, file=sys.stderr) return False except SyntaxError: self.showsyntaxerror() return False except BaseException: print(f'{sys.ps1}# Compilation failed!', file=sys.stderr) self.showtraceback() return False print(sys.ps1, source.replace("\n", f"\n{sys.ps2}"), sep="", file=sys.stderr) return super().runsource(source, filename, symbol) def raw_input(self, prompt=""): """:meta private:""" prompt = {sys.ps2: ps2, sys.ps1: ps1}.get(prompt, prompt) return super().raw_input(prompt) def interact(self, banner=None, exitmsg=None): """Imports readline if available, then super().interact().""" with suppress(ImportError): # noinspection PyUnresolvedReferences import readline return super().interact(banner, exitmsg)
def preprocess_atom(lexer, match, ctx=None): value: str = match.group(0) index: int = match.start() v = Lissp.atom(value) if isinstance(v, (complex, float)): yield index, pt.Number.Float, value return if type(v) in {dict, list, set}: yield index, pt.Literal, value return if not isinstance(v, str): v = value.replace('\\', '') elif re.fullmatch(r'.+\.$', v): # module yield index, pt.Name.Other, value return elif m:=re.fullmatch(r'((?:[^.]*[^.\\]\.)+)(\..+)', value): yield index, pt.Name.Other, m[1] index+=len(m[1]) yield index, pt.Name, m[2] return
class REPL(InteractiveConsole): def __init__(self, locals=None, filename="<console>"): super().__init__(locals, filename) sys.ps1 = "#> " sys.ps2 = "#.." self.lissp = Lissp(ns=locals) self.locals = self.lissp.ns def runsource(self, source, filename="<input>", symbol="single"): try: self.lissp.filename = filename source = self.lissp.compile(source) except SoftSyntaxError: return True except SyntaxError: self.showsyntaxerror() return False except BaseException: import traceback traceback.print_exc() return False print(">>>", source.replace("\n", "\n... "), file=sys.stderr) super().runsource(source, filename, symbol)
def _no_interact(code, ns): Lissp(ns=ns, evaluate=True).compile(code)
def __init__(self, locals=None, filename="<console>"): super().__init__(locals, filename) self.lissp = Lissp(ns=locals) self.locals = self.lissp.ns