Source code for curry.icurry.readcurry

from . import types
from ..utility import readcurry as rc
from ..utility.trampoline import trampoline

__all__ = ['load', 'loads']

class Decoder(object):
  '''
  Decode the `readcurry` representation of ICurry into Python ICurry.  The
  walk runs on a stack of its own (:func:`utility.trampoline.trampoline`),
  so a nested application of any depth needs no recursion (issue #125).
  '''
  def decode(self, arg):
    return trampoline(self._decode(arg))

  def _decode(self, arg):
    if isinstance(arg, rc.Identifier):
      return getattr(types, arg.name)
    elif isinstance(arg, rc.Applic):
      ty = getattr(types, arg.f.name)
      args = []
      for x in arg.args:
        x = yield self._decode(x)
        args.append(x)
      return self.apply(ty, *args)
    elif isinstance(arg, (list, tuple)):
      out = []
      for x in arg:
        x = yield self._decode(x)
        out.append(x)
      return type(arg)(out)
    elif isinstance(arg, types.IUnboxedLiteral):
      return arg
    raise TypeError('not handled: %r' % arg)

  # Types in need of special processing to convert name triples into dotted
  # qualified names.
  QNAME_TYPES = (
      types.ICall, types.IConsBranch, types.IFunction, types.IConstructor
    )

  LITERAL_TYPES = types.IChar, types.IFloat, types.IInt

  def apply(self, ty, *args):
    if issubclass(ty, types.IDataType):
      (qual, name, _), ctors = args
      symbolname = '%s.%s' % (qual, name)
      ctors = [self.apply(types.IConstructor, *ctor) for ctor in ctors]
      return ty(symbolname, ctors)
    elif issubclass(ty, self.QNAME_TYPES):
      qual, name, _ = args[0]
      symbolname = '%s.%s' % (qual, name)
      return ty(symbolname, *args[1:])
    else:
      return ty(*args)

[docs] def loads(rcdata, decoder=Decoder()): '''Load ICurry encoded as readcurry.''' return decoder.decode(rcdata)
[docs] def load(file, decoder=Decoder()): '''Load ICurry from an .icy file.''' if isinstance(file, str): with open(file, 'r', encoding='utf-8') as istream: text = istream.read() else: text = file.read() rcdata = rc.parse(text) return loads(rcdata, decoder)