From 87fe1d0b3ce915d75fabda475cb9a3fcdcf30dc1 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Tue, 1 Mar 2022 19:13:44 -0800 Subject: [PATCH] Snippets support. Parse, print. --- implementations/Python/joy/parser.py | 8 ++++++++ implementations/Python/joy/utils/snippets.py | 9 ++++----- implementations/Python/joy/utils/stack.py | 11 ++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/implementations/Python/joy/parser.py b/implementations/Python/joy/parser.py index c07573f..33a5be9 100644 --- a/implementations/Python/joy/parser.py +++ b/implementations/Python/joy/parser.py @@ -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) diff --git a/implementations/Python/joy/utils/snippets.py b/implementations/Python/joy/utils/snippets.py index 843c325..803b88b 100644 --- a/implementations/Python/joy/utils/snippets.py +++ b/implementations/Python/joy/utils/snippets.py @@ -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)) - diff --git a/implementations/Python/joy/utils/stack.py b/implementations/Python/joy/utils/stack.py index 1e9764f..ab8ae03 100644 --- a/implementations/Python/joy/utils/stack.py +++ b/implementations/Python/joy/utils/stack.py @@ -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) )