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

from .....exceptions import MonadError
from ... import graph
from . import show, string

__all__ = [
    'appendFile', 'bindIO', 'catch', 'getChar', 'ioError', 'putChar'
  , 'readFile', 'returnIO', 'seqIO', 'writeFile'
  ]

[docs] def appendFile(rts, func): return writeFile(rts, func, 'a')
[docs] def bindIO(rts, lhs): io_a = rts.variable(lhs, 0) io_a.hnf() a = rts.variable(io_a, 0) yield rts.prelude.apply yield lhs.successors[1] yield a
[docs] def catch(rts, func): try: _1 = rts.variable(func, 0) _1.hnf() except (IOError, MonadError) as exc: yield rts.prelude.apply yield func.successors[1] idx = getattr(exc, 'CTOR_INDEX', 0) yield graph.Node( rts.prelude.IOError.info.typedef.constructors[idx] , string.pystring(rts, str(exc)) ) else: yield rts.Fwd yield func.successors[0]
[docs] def getChar(rts): yield rts.prelude.IO yield graph.Node(rts.prelude.Char, rts.stdin.read(1))
[docs] def ioError(rts, func): yield rts.prelude.error showf = rts.symbol('Prelude._impl#show#Prelude.Show#Prelude.IOError') yield graph.Node(showf, func[0])
[docs] def putChar(rts, a): rts.stdout.write(a.unboxed_value) yield rts.prelude.IO yield graph.Node(rts.prelude.Unit)
[docs] def readFile(rts, filename): filename = rts.topython(filename.target) # Read the file now, so that an error is raised while the action executes # (and ``catch`` can handle it). The file holds UTF-8: each code point # becomes one character, and a malformed byte sequence becomes the # replacement character, as in PAKCS. An empty file gives the empty string. with open(filename, 'rb') as istream: data = istream.read() yield rts.prelude.IO yield string.pystring(rts, data.decode('utf-8', 'replace'))
[docs] def returnIO(rts, _0): yield rts.prelude.IO yield _0.successors[0]
[docs] def seqIO(rts, lhs): _1 = rts.variable(lhs, 0) _1.hnf() yield rts.Fwd yield lhs.successors[1]
[docs] def writeFile(rts, func, mode='w'): ''' Write a string to a file (``mode`` 'w') or append it ('a'). The step runs again when the evaluation of the string is interrupted, for instance when the step budget rotates the queue. The first entry truncates the file and then turns the node into ``prim_appendFile``, so a later entry appends to the characters already written. The characters are written as UTF-8. ''' filename = rts.topython(func.successors[0]) List = getattr(rts.prelude, '.types')['[]'] Char = getattr(rts.prelude, '.types')['Char'] with open(filename, mode, encoding='utf-8') as ostream: if mode == 'w': func.rewrite(rts.prelude.prim_appendFile, *func.successors) while True: _1 = rts.variable(func, 1) _1.hnf(typedef=List) tag = _1.info.tag if tag == 0: # Cons char = rts.variable(_1, 0) char.hnf(typedef=Char) ostream.write(char.unboxed_value) func.successors[1] = _1.successors[1] else: # Nil assert tag == 1 yield rts.prelude.IO yield graph.Node(rts.prelude.Unit) break