Source code for curry.backends.py.currylib.prelude.string

from ... import graph
from .....utility.strings import ensure_str
import array, sys

__all__ = ['_biGenerator', '_biString', 'codepoints', 'pystring', 'text']

def _biGenerator(rts, gen):
  '''
  Implements a Python generator as a Curry list.  The generator is single-pass,
  so is not safe for general use.  This is used to implement IO actions.
  '''
  try:
    item = next(gen.target)
  except StopIteration:
    yield rts.prelude.Nil
  else:
    item = rts.expr(item)
    # The item is built now, after set_goal walked the goal.  A free variable
    # made outside this evaluation (a curry.free marker used before) is new
    # to the variable table.  See rts_freevars.register_freevars.
    if rts.istate.external_freevars:
      rts.register_freevars(item)
    yield rts.prelude.Cons
    yield item
    yield graph.Node(rts.prelude._biGenerator, gen.target)

# A Char is a Unicode code point.  A string literal is kept as a memoryview of
# 4-byte code points: a slice of a memoryview costs O(1), so _biString walks a
# long string one character at a time.
CODEPOINT_FORMAT = next(
    code for code in 'IL' if array.array(code).itemsize == 4
  )
_UTF32 = 'utf-32-le' if sys.byteorder == 'little' else 'utf-32-be'

[docs] def codepoints(string): '''The code points of a Python string as a memoryview of 4-byte integers.''' return memoryview(ensure_str(string).encode(_UTF32)).cast(CODEPOINT_FORMAT)
[docs] def text(memory): '''The Python string held by a memoryview that ``codepoints`` made.''' return ''.join(map(chr, memory))
# Convert a Python string to a Curry string.
[docs] def pystring(rts, string): return graph.Node(rts.prelude._biString, codepoints(string))
ensure_char = chr # memoryview element is an integer def _biString(rts, _1): ''' Implements a Curry string efficiently as a Python memory view. ''' mem = _1.target if mem: yield rts.prelude.Cons yield graph.Node(rts.prelude.Char, ensure_char(mem[0])) yield graph.Node(rts.prelude._biString, mem[1:]) else: yield rts.prelude.Nil