OSDN Git Service

Snippets support.
authorSimon Forman <sforman@hushmail.com>
Wed, 2 Mar 2022 03:13:44 +0000 (19:13 -0800)
committerSimon Forman <sforman@hushmail.com>
Wed, 2 Mar 2022 03:13:44 +0000 (19:13 -0800)
Parse, print.

implementations/Python/joy/parser.py
implementations/Python/joy/utils/snippets.py
implementations/Python/joy/utils/stack.py

index c07573f..33a5be9 100644 (file)
@@ -38,6 +38,11 @@ around square brackets.
 '''
 from re import Scanner
 from .utils.stack import list_to_stack
+from .utils.snippets import (
+    pat as SNIPPETS,
+    from_string,
+    Snippet,
+    )
 
 
 BRACKETS = r'\[|\]'
@@ -46,6 +51,7 @@ WORDS = r'[^[\]\s]+'
 
 
 token_scanner = Scanner([
+    (SNIPPETS, lambda _, token: from_string(token)),
     (BRACKETS, lambda _, token: token),
     (BLANKS, None),
     (WORDS, lambda _, token: token),
@@ -111,6 +117,8 @@ def _parse(tokens):
             frame.append(True)
         elif tok == 'false':
             frame.append(False)
+        elif isinstance(tok, Snippet):
+            frame.append(tok)
         else:
             try:
                 thing = int(tok)
index 843c325..803b88b 100644 (file)
@@ -2,7 +2,7 @@ from collections import namedtuple
 from re import compile as RE
 
 Snippet = namedtuple('Snippet', 'sha offset length')
-fmt = '{%s %i %i}'
+_fmt = '{%s %i %i}'
 pat = (
     '{'
     '\s*'
@@ -14,21 +14,20 @@ pat = (
     '\s*'
     '}'
     )
-PAT = RE(pat)
+_PAT = RE(pat)
 
 
 def to_string(snip):
-    return fmt % _ts(*snip)
+    return _fmt % _ts(*snip)
 
 def _ts(sha, offset, length):
     return sha.decode('ascii'), offset, length
 
 def from_string(text):
-    m = PAT.match(text)
+    m = _PAT.match(text)
     if not m:
         raise ValueError
     return _fs(**m.groupdict())
 
 def _fs(sha, offset, length):
     return Snippet(sha.encode('ascii'), int(offset), int(length))
-
index 1e9764f..ab8ae03 100644 (file)
@@ -71,6 +71,7 @@ printed left-to-right.  These functions are written to support :doc:`../pretty`.
 
 '''
 from .errors import NotAListError
+from .snippets import Snippet, to_string as snip_to_string
 
 
 def list_to_stack(el, stack=()):
@@ -133,20 +134,24 @@ _JOY_BOOL_LITS = 'false', 'true'
 
 
 def _joy_repr(thing):
-        if isinstance(thing, bool):
-                return _JOY_BOOL_LITS[thing]
-        return repr(thing)
+    if isinstance(thing, bool): return _JOY_BOOL_LITS[thing]
+    if isinstance(thing, Snippet): return snip_to_string(thing)
+    return repr(thing)
 
 
 def _to_string(stack, f):
     if not isinstance(stack, tuple): return _joy_repr(stack)
     if not stack: return ''  # shortcut
+    if isinstance(stack, Snippet): return snip_to_string(stack)
     return ' '.join(map(_s, f(stack)))
 
 
 _s = lambda s: (
     '[%s]' % expression_to_string(s)
         if isinstance(s, tuple)
+        and not isinstance(s, Snippet)
+        # Is it worth making a non-tuple class for Snippet?
+        # Doing this check on each tuple seems a bit much.
     else _joy_repr(s)
     )