Source code for py_register_machine2.core.register

#!/usr/bin/python3

"""
**py_register_machine2.core.register**: Registers for the register machine
"""

from ..core import parts
from ..engine_tools.conversions import int_to_bytes, bytes_to_int

[docs]class Register(parts.Register): """ The basic standard register. Permitts read and write, does not execute any callbacks on read/write. See also: Register_ """ def __init__(self, name, width = 64): parts.Register.__init__(self, name, width = width)
[docs]class OutputRegister(parts.Register): """ .. _OutputRegister: Used to print data to the user. The ``write`` call will convert ``word`` using ``chr`` and write the resulting ``str`` to ``open_stream``. The ``read`` call will return the last written ``word``. ``open_stream`` might be a ``file`` (like ``sys.stdout``) or an ``io.StringIO`` object. """ def __init__(self, name, open_stream, width = 64): parts.Register.__init__(self, name, width = width) self.open_stream = open_stream
[docs] def write(self, word): """ .. _SOwrite: Write the ``chr`` representation of ``word`` to the ``open_stream``. If ``chr(word)`` fails due ``OverflowError``, a ``"?"`` will be written. """ self.repr_.setvalue(word) try: self.open_stream.write(chr(self.repr_.getvalue())) except OverflowError: self.open_stream.write("?")
[docs]class StreamIORegister(parts.Register): """ .. _StreamIORegister: Input/Output Register via streams. The ``open_stream_in`` has to be readable, ``open_stream_out`` writeable. """ def __init__(self, name, open_stream_in, open_stream_out, width = 64): parts.Registers.__init(self, name, width = width) self.open_stream_in = open_stream_in self.open_stream_out = open_stream_out
[docs] def read(self): """ Read a ``str`` from ``open_stream_in`` and convert it to an integer using ``ord``. The result will be truncated according to Integer_. """ self.repr_.setvalue(ord(self.open_stream_in.read(1))) return self.value.getvalue()
[docs] def write(self, word): """ Works like SOwrite_. """ self.repr_.setvalue(word) try: self.open_stream.write(chr(self.value.getvalue())) except OverflowError: self.open_stream.write("?")
[docs]class BStreamIORegister(parts.Register): """ .. _BStreamIORegister: Works like StreamIORegister_, but ``open_stream_in`` and ``open_stream_out`` are byte streams (like ``open("fname", "rb")``). * A ``read`` operation will read ``width // 8`` bytes and convert them to one ``int``. * A ``write`` operation will write ``width // 8`` bytes """ def __init__(self, name, open_stream_in, open_stream_out, width = 64): parts.Registers.__init(self, name, width = width) self.open_stream_in = open_stream_in self.open_stream_out = open_stream_out
[docs] def read(self): """ Reads enough bytes from ``open_stream_in`` to fill the ``width`` (if available) and converts them to an ``int``. Returns this ``int``. """ int_ = bytes_to_int(self.open_stream_in.read(math.ceil(self.width / 8)), self.width) self.repr_.setvalue(int_) return self.value.getvalue()
[docs] def write(self, word): """ Converts the ``int`` ``word`` to a ``bytes`` object and writes them to ``open_stream_out``. See ``int_to_bytes``. """ bytes_ = int_to_bytes(word, self.width) self.open_stream_out.write(bytes_)