{ "cells": [ { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [], "source": [ "def new_machine():\n", " return {'pc': 0, \n", " 'a': 0,\n", " 'b': 0, \n", " 'c': 0,\n", " 'instructions': []}" ] }, { "cell_type": "code", "execution_count": 193, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def show_machine(machine):\n", " return ', '.join('{}: {}'.format(sk, machine[int(sk) if sk.isnumeric() else sk]) \n", " for sk in sorted(str(k) for k in machine)\n", " if sk != 'instructions')" ] }, { "cell_type": "code", "execution_count": 112, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def inc(reg, machine):\n", " machine[reg] += 1\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 113, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def dec(reg, machine):\n", " machine[reg] -= 1\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 114, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def jmp(addr, machine):\n", " machine['pc'] += addr" ] }, { "cell_type": "code", "execution_count": 115, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def jpz(reg, addr, machine):\n", " if machine[reg] == 0:\n", " machine['pc'] += addr\n", " else:\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 116, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def set_literal(reg, literal, machine):\n", " machine[reg] = literal\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 117, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def cpy(from_reg, to_reg, machine):\n", " machine[to_reg] = machine[from_reg]\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 129, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def sto(reg, addr, machine):\n", " machine[addr] = machine[reg]\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 130, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def ld(reg, addr, machine):\n", " if addr in machine:\n", " machine[reg] = machine[addr]\n", " else:\n", " machine[reg] = 0\n", " machine['pc'] += 1" ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [], "source": [ "instruction_table = {'inc': inc, 'dec': dec, 'jmp': jmp,\n", " 'jpz': jpz, 'set': set_literal, 'cpy': cpy,\n", " 'sto': sto, 'ld': ld}\n", "numeric_args_table = {'jmp': [0], 'jpz': [1], 'set': [1], 'sto': [1], 'ld': [1]}" ] }, { "cell_type": "code", "execution_count": 121, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def parse(instruction):\n", " words = instruction.split()\n", " instr = words[0]\n", " args = words[1:]\n", " if instr in numeric_args_table:\n", " for p in numeric_args_table[instr]:\n", " args[p] = int(args[p])\n", " return instruction_table[instr], args" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 2, 'b': 1, 'c': 0, 'instructions': [], 'pc': 3}" ] }, "execution_count": 122, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = new_machine()\n", "inc('a', m)\n", "cargs = ['a', 'b']\n", "cpy(*cargs, m)\n", "inc('a', m)\n", "m" ] }, { "cell_type": "code", "execution_count": 123, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def program_from_instructions(prog, machine):\n", " machine['instructions'] = [parse(instr) for instr in prog]" ] }, { "cell_type": "code", "execution_count": 124, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def program_from_listing(listing, machine):\n", " program_from_instructions([i for i in listing.split('\\n') if i], machine)" ] }, { "cell_type": "code", "execution_count": 156, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def run(machine, initial_state=None, trace=False):\n", " if initial_state:\n", " machine.update(initial_state)\n", " while machine['pc'] < len(machine['instructions']):\n", " if trace:\n", " print(show_machine(machine))\n", " cmd, args = machine['instructions'][machine['pc']]\n", " cmd(*args, machine)" ] }, { "cell_type": "code", "execution_count": 146, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def execute(listing, initial_state=None, trace=False):\n", " m = new_machine()\n", " program_from_listing(listing, m)\n", " run(m, initial_state=initial_state, trace=trace)\n", " return m" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 3,\n", " 'b': 2,\n", " 'c': 0,\n", " 'instructions': [(, ['a']),\n", " (, ['a']),\n", " (, ['a', 'b']),\n", " (, ['a'])],\n", " 'pc': 4}" ] }, "execution_count": 127, "metadata": {}, "output_type": "execute_result" } ], "source": [ "program = \"\"\"\n", "inc a\n", "inc a\n", "cpy a b\n", "inc a\n", "\"\"\"\n", "execute(program)" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'c': 20,\n", " 'instructions': [(, ['a', 10]),\n", " (, ['a']),\n", " (, ['b']),\n", " (, ['b', 1]),\n", " (, ['a', 2]),\n", " (, [-4])],\n", " 1: 10,\n", " 'b': 10,\n", " 'pc': 6,\n", " 'a': 0}" ] }, "execution_count": 143, "metadata": {}, "output_type": "execute_result" } ], "source": [ "program = \"\"\"\n", "set a 10\n", "dec a\n", "inc b\n", "sto b 1\n", "jpz a 2\n", "jmp -4\n", "\"\"\"\n", "# m = new_machine()\n", "# program_from_listing(program, m)\n", "# run(m)\n", "execute(program, initial_state={'c': 20})" ] }, { "cell_type": "code", "execution_count": 159, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': 0,\n", " 'b': 1,\n", " 'c': 5,\n", " 'instructions': [(, ['c', 'a']),\n", " (, ['b', 0]),\n", " (, ['a']),\n", " (, ['b', 3]),\n", " (, ['b']),\n", " (, [2]),\n", " (, ['b']),\n", " (, ['a', 3]),\n", " (, [-6])],\n", " 'pc': 10}" ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "program = \"\"\"\n", "cpy c a\n", "set b 0\n", "dec a\n", "jpz b 3\n", "dec b\n", "jmp 2\n", "inc b\n", "jpz a 3\n", "jmp -6\n", "\"\"\"\n", "# m = new_machine()\n", "# program_from_listing(program, m)\n", "# run(m)\n", "execute(program, initial_state={'c': 5})" ] }, { "cell_type": "code", "execution_count": 196, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'10: 10, a: 0, b: 0, c: 5, pc: 11'" ] }, "execution_count": 196, "metadata": {}, "output_type": "execute_result" } ], "source": [ "program = \"\"\"\n", "sto a 10\n", "set c 0\n", "set b 0\n", "dec a\n", "jpz b 4\n", "dec b\n", "inc c\n", "jmp 2\n", "inc b\n", "jpz a 2\n", "jmp -7\n", "\"\"\"\n", "# m = new_machine()\n", "# program_from_listing(program, m)\n", "# run(m)\n", "show_machine(execute(program, initial_state={'a': 10}))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2+" } }, "nbformat": 4, "nbformat_minor": 2 }