Last active
November 2, 2019 22:54
-
-
Save jolod/982f66beb423bd9f998d05c5c5f2fbc0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # I rewrote the code so that you can keep the os calls unchanged and only add yield before it. | |
| # The interpreter is now represented by a class with static methods instead. The class only | |
| # serves as a dictionary of functions. | |
| import collections | |
| import os | |
| import types | |
| Op = collections.namedtuple('Op', ['op', 'args', 'kwargs']) | |
| class Ops: | |
| def __getattribute__(self, attr): | |
| return lambda *args, **kwargs: Op(attr, args, kwargs) | |
| def count_chars_of_file(fn): | |
| os = Ops() | |
| fd = yield os.open(fn) | |
| text = yield os.read(fd) | |
| n = len(text) | |
| yield os.close(fd) | |
| return n | |
| class Os: | |
| @staticmethod | |
| def open(filename): | |
| fd = os.open(filename, os.O_RDONLY) | |
| return fd | |
| @staticmethod | |
| def read(fh): | |
| text = os.read(fh, 10000) | |
| return text | |
| @staticmethod | |
| def close(fh): | |
| os.close(fh) | |
| return None | |
| def runProgram(prog): | |
| ops = Os() | |
| def runOp(op): | |
| return ops.__getattribute__(op.op)(*op.args, **op.kwargs) | |
| try: | |
| op = prog.send(None) | |
| while True: | |
| if isinstance(op, Op): | |
| r = runOp(op) | |
| op = prog.send(r) | |
| elif isinstance(op, types.GeneratorType): | |
| r = runProgram(op) | |
| op = prog.send(r) | |
| except StopIteration as e: | |
| return e.value | |
| if __name__ == '__main__': | |
| import sys | |
| filename = sys.argv[0] | |
| program = count_chars_of_file(filename) | |
| output = runProgram(program) | |
| print(output) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Added namespacing, so the full name of the action is 'os.open'. | |
| # The namespace is passed to the action object, and the interpreter | |
| # is now represented by a dictionary of objects, where the keys are | |
| # the namespaces. | |
| import collections | |
| import os | |
| import types | |
| Op = collections.namedtuple('Op', ['qual', 'op', 'args', 'kwargs']) | |
| class Ops: | |
| def __init__(self, namespace): | |
| self.__namespace = namespace | |
| def __getattribute__(self, attr): | |
| cls = type(self) | |
| if attr.startswith('_' + cls.__name__ + '__'): | |
| return super(cls, self).__getattribute__(attr) | |
| else: | |
| return lambda *args, **kwargs: Op(self.__namespace, attr, args, kwargs) | |
| def count_chars_of_file(fn): | |
| os = Ops('os') | |
| fd = yield os.open(fn) | |
| text = yield os.read(fd) | |
| n = len(text) | |
| yield os.close(fd) | |
| return n | |
| class Os: | |
| @staticmethod | |
| def open(filename): | |
| fd = os.open(filename, os.O_RDONLY) | |
| return fd | |
| @staticmethod | |
| def read(fh): | |
| text = os.read(fh, 10000) | |
| return text | |
| @staticmethod | |
| def close(fh): | |
| os.close(fh) | |
| return None | |
| def runProgram(prog): | |
| ops = dict(os = Os()) | |
| def runOp(op): | |
| base = ops.get(op.qual, None) | |
| if not base: | |
| raise Exception("No handlers for qualifier: " + op.qual) | |
| opname = op.op | |
| try: | |
| f = base.__getattribute__(opname) | |
| except: | |
| raise Exception("No handler for {!s}.{!s}".format(op.qual, opname)) | |
| return f(*op.args, **op.kwargs) | |
| try: | |
| op = prog.send(None) | |
| while True: | |
| if isinstance(op, Op): | |
| r = runOp(op) | |
| op = prog.send(r) | |
| elif isinstance(op, types.GeneratorType): | |
| r = runProgram(op) | |
| op = prog.send(r) | |
| else: | |
| raise Exception(op) | |
| except StopIteration as e: | |
| return e.value | |
| if __name__ == '__main__': | |
| import sys | |
| filename = sys.argv[0] | |
| program = count_chars_of_file(filename) | |
| output = runProgram(program) | |
| print(output) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment