Beispiel #1
0
 def _atom(v):
     is_symbol = '\\' == v[0]
     v = Lissp.escape(v)
     if is_symbol:
         return munge(v)
     try:
         val = ast.literal_eval(v)
         if isinstance(val, bytes):  # bytes have their own literals.
             return munge(v)
         return val
     except (ValueError, SyntaxError):
         return munge(v)
Beispiel #2
0
 def atom(v):
     """Preprocesses atoms. Handles escapes and munging."""
     is_symbol = "\\" == v[0]
     v = Lissp.escape(v)
     if is_symbol:
         return munge(v)
     try:
         val = ast.literal_eval(v)
         if isinstance(val, bytes):  # bytes have their own literals.
             return munge(v)
         return val
     except (ValueError, SyntaxError):
         return munge(v)
Beispiel #3
0
 def _custom_macro(self, form, tag, extras):
     assert tag.endswith("#")
     tag = munge(self.escape(tag[:-1]))
     if ".." in tag:
         module, function = tag.split("..", 1)
         m = reduce(getattr, function.split("."), import_module(module))
     else:
         try:
             m = getattr(self.ns["_macro_"], tag + munge("#"))
         except (AttributeError, KeyError):
             raise SyntaxError(f"Unknown reader macro {tag!r}.",
                               self.position())
     with self.compiler.macro_context():
         args, kwargs = _parse_extras(extras)
         return m(form, *args, **kwargs)
Beispiel #4
0
 def test_munge_basic(self):
     self.assertEqual(
         munger.munge(r"""~!@#$%^&*()_+{}|:"<>?`-=[]\;',./"""),
         "xTILDE_xBANG_xAT_xHASH_xDOLR_xPCENT_xCARET_xET_xSTAR_xPAREN_xTHESES_"
         "_xPLUS_xCURLY_xBRACES_xBAR_xCOLON_x2QUOTE_xLT_xGT_xQUERY_xGRAVE_xH_xEQ_"
         "xSQUARE_xBRACKETS_xBSLASH_xSCOLON_x1QUOTE_xCOMMA_.xSLASH_"
     )
Beispiel #5
0
    def parse_macro(self, tag: str, form):
        if tag == "'":
            return "quote", form
        if tag == "`":
            return self.template(form)
        if tag == ",":
            return _Unquote([":?", form])
        if tag == ",@":
            return _Unquote([":*", form])

        assert tag.endswith("#")
        tag = tag[:-1]
        if tag == "_":
            return DROP
        if tag == "$":
            return self.gensym(form)
        if tag == ".":
            return eval(readerless(form), {})
        if ".." in tag and not tag.startswith(".."):
            module, function = tag.split("..", 1)
            function = munge(function)
            if is_string(form):
                form = form[1]
            return reduce(getattr, function.split("."),
                          import_module(module))(form)
        raise ValueError(f"Unknown reader macro {tag}")
Beispiel #6
0
 def parse_tag(self, tag, form):
     if tag == "_":
         return DROP
     if tag == "$":
         return self.gensym(form)
     if tag == ".":
         return eval(readerless(form), {})
     if is_string(form):
         form = form[1]
     tag = munge(self.escape(tag))
     if ".." in tag and not tag.startswith(".."):
         module, function = tag.split("..", 1)
         return reduce(getattr, function.split("."),
                       import_module(module))(form)
     try:
         m = getattr(self.ns["_macro_"], tag)
     except (AttributeError, KeyError):
         raise SyntaxError(f"Unknown reader macro {tag}", self.position())
     return m(form)
Beispiel #7
0
 def _parse(self, tokens: Iterator[Token]) -> Iterator:
     for k, v in tokens:
         if k == "open":
             depth = self.depth
             self.depth += 1
             yield (*self.parse(tokens), )
             if self.depth != depth:
                 raise SyntaxError("Unclosed '('.")
         elif k == "close":
             self.depth -= 1
             if self.depth < 0:
                 raise SyntaxError("Unopened ')'.")
             return
         elif k == "string":
             yield "quote", ast.literal_eval(
                 v.replace("\\\n", "").replace("\n", r"\n")), {
                     ":str": True
                 }
         elif k in {"comment", "whitespace"}:
             continue
         elif k == "macro":
             with {
                     "`": self.gensym_context,
                     ",": self.unquote_context,
                     ",@": self.unquote_context,
             }.get(v, nullcontext)():
                 form = next(self.parse(tokens))
                 yield self.parse_macro(v, form)
         elif k == "symbol":
             try:
                 yield ast.literal_eval(v)
             except (ValueError, SyntaxError):
                 yield munge(v)
         else:
             assert False, "unknown token: " + repr(k)
     if self.depth:
         SyntaxError("Ran out of tokens before completing form.")
Beispiel #8
0
 def test_munge_symbol(self, s):
     self.assertTrue(munger.munge(s).isidentifier())
Beispiel #9
0
 def test_demunge(self, s: str):
     x = munger.munge(s)
     self.assertEqual(x, munger.munge(munger.demunge(x)))
     if not s.startswith(":") and "x" not in s:
         self.assertEqual(unicodedata.normalize("NFKC", s), munger.demunge(x))
Beispiel #10
0
 def test_munge_basic(self):
     self.assertEqual(
         munger.munge(r"~!@#$%^&*+`-=|\:'<>?,/"),
         "xTILDE_xBANG_xAT_xHASH_xDOLLAR_xPERCENT_xCARET_xET_xSTAR_xPLUS_xGRAVE_xH_"
         "xEQ_xBAR_xBSLASH_xCOLON_xQUOTE_xLT_xGT_xQUERY_xCOMMA_xSLASH_",
     )
Beispiel #11
0
 def test_demunge(self, s: str):
     x = munger.munge(s)
     self.assertEqual(x, munger.munge(munger.demunge(x)))
     if "x" not in s:
         self.assertEqual(s, munger.demunge(x))
Beispiel #12
0
 def test_munge_basic(self):
     self.assertEqual(
         munger.munge(r"""~!@#$%^&*()_+{}|:"<>?`-=[]\;',./"""),
         "QzTILDE_QzBANG_QzAT_QzHASH_QzDOLR_QzPCENT_QzCARET_QzET_QzSTAR_QzLPAR_QzRPAR_"
         "_QzPLUS_QzLCUB_QzRCUB_QzBAR_QzCOLON_QzQUOT_QzLT_QzGT_QzQUERY_QzGRAVE_Qz_QzEQ_"
         "QzLSQB_QzRSQB_QzBSOL_QzSEMI_QzAPOS_QzCOMMA_.QzSOL_")