.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/vm/foundations/plot_06_forth.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_vm_foundations_plot_06_forth.py: Forth: programming with stack words (Moore 1970) ================================================ Charles Moore's Forth has no named variables in expressions: words such as ``DUP``, ``DROP``, ``SWAP``, ``OVER`` and ``ROT`` rearrange the stack, and each word is documented by its *stack diagram*: ``OVER ( a b -- a b a )``. Small, fast and easy to implement, Forth ran telescopes and spacecraft. Bitcoin Script is described as Forth-like, and the EVM's ``DUP`` and ``SWAP`` families serve the same purpose. What to look for ---------------- Each stack word matches its diagram. The polynomial ``a x**2 + b x + c`` is computed by Horner's rule with stack words only, and gives the same values as Python for every input. The history behind this experiment: :doc:`/history/vm_breakthroughs`. See :doc:`/exercises/vm` for a worked solution to the exercise. .. GENERATED FROM PYTHON SOURCE LINES 24-26 Check every stack diagram ------------------------- .. GENERATED FROM PYTHON SOURCE LINES 26-41 .. code-block:: Python import matplotlib.pyplot as plt import blockchainkit as bk diagrams = { "DUP": ((1,), (1, 1)), "DROP": ((1, 2), (1,)), "SWAP": ((1, 2), (2, 1)), "OVER": ((1, 2), (1, 2, 1)), "ROT": ((1, 2, 3), (2, 3, 1)), } for word, (before, after) in diagrams.items(): assert bk.vm.execute([(word, None)], arguments=before).stack == after print(f"{word:4s} ( {' '.join(map(str, before))} -- {' '.join(map(str, after))} )") .. rst-class:: sphx-glr-script-out .. code-block:: none DUP ( 1 -- 1 1 ) DROP ( 1 2 -- 1 ) SWAP ( 1 2 -- 2 1 ) OVER ( 1 2 -- 1 2 1 ) ROT ( 1 2 3 -- 2 3 1 ) .. GENERATED FROM PYTHON SOURCE LINES 42-45 Horner's rule without variables ------------------------------- ( x -- a*x*x + b*x + c ) as ((a * x) + b) * x + c, keeping x with OVER. .. GENERATED FROM PYTHON SOURCE LINES 45-65 .. code-block:: Python a, b, c = 3, 5, 7 horner = bk.vm.assemble(f""" PUSH {a} OVER MUL # x a*x PUSH {b} ADD # x a*x+b MUL # (a*x+b)*x PUSH {c} ADD """) xs = list(range(0, 11)) values = [bk.vm.execute(horner, arguments=(x,)).stack[0] for x in xs] assert values == [a * x * x + b * x + c for x in xs] fig, ax = plt.subplots(figsize=(6, 4)) ax.plot(xs, values, "o") ax.set(xlabel="x", ylabel="result", title=f"{a}x² + {b}x + {c} from stack words") fig.tight_layout() .. image-sg:: /api/gallery/vm/foundations/images/sphx_glr_plot_06_forth_001.png :alt: 3x² + 5x + 7 from stack words :srcset: /api/gallery/vm/foundations/images/sphx_glr_plot_06_forth_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 66-70 Exercise -------- Define ``NIP ( a b -- b )`` and ``TUCK ( a b -- b a b )`` from the five words above and check them with ``bk.vm.execute``. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.095 seconds) .. _sphx_glr_download_api_gallery_vm_foundations_plot_06_forth.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../../../lite/lab/index.html?path=api/gallery/vm/foundations/plot_06_forth.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_06_forth.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_06_forth.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_06_forth.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_