Skip to content

Example 3 peforth as an assistant or a debugger

H.C. Chen edited this page Oct 8, 2017 · 1 revision

Run python in a DOS Box and create two variables x and y:

Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.

c:\Users\hcche\Documents\GitHub\peforth>python
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> x = 123
>>> y = 345

Not a great job here but if peforth can be of any assistance in this case then it certainly can help you in any practical case. Now let's invoke peforth:

>>> import peforth
p e f o r t h    v1.06
source code http://github.com/hcchengithub/peforth
Type 'peforth.ok()' enters forth interpreter, 'exit' to come back.

*** Start self-test
*** Data stack should be empty ... pass
*** Rreturn stack should have less than 2 cells ... pass
*** // adds help to the last word ... pass
*** TIB lines after \ should be ignored ... pass
... snip ...
... snip ...
*** obj>keys .members .source ... pass
*** dos cd slice WshShell ... pass
*** End of kernel self-test ... pass
>>>

peforth starts with a long list of self-test results. The greeing above all the self-test messages tells you the project URL address on GitHub and the command to enter peforth interpreter. So let's do it but with an argument loc=locals() :

>>> peforth.ok(loc=locals())
OK .s
      0: ({'__name__': '__main__', '__doc__': None, '__package__': None, 
      '__loader__': <class '_frozen_importlib.BuiltinImporter'>, 
      '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 
      'x': 123, 'y': 345, 
      'peforth': <module 'peforth' from 'C:\\Users\\hcche\\AppData\\Local\\Programs\\Python\\
      Python36\\lib\\site-packages\\peforth\\__init__.py'>}, 
      '<== Identifiers ok() Prompt ==>', 'OK ') (<class 'tuple'>)

"OK" is the traditional FORTH command prompt. Type .s to see the data stack. If peforth.ok() was called without any arguament then the data stack should be empty. While now the data stack has a tuple with 3 things ({locals() dict},'<== Identifiers ok() Prompt ==>','OK '). The first thing is a dict of locals at the point where we called peforth.ok(). The last thing is the FORTH prompt which is now the traditional "OK" because we didn't change it. If we want to then peforth.ok('bp123>> ') is an example to invoke peforth interpreter with prompt "bp123>>" instead of the default "OK", as shown below:

>>> peforth.ok('bp123>> ')
bp123>> .s
empty

bp123>>

So the [0] cell of the tuple on TOS is what we are interested. Let's name it locals as a FORTH constant and check it out:

OK :> [0] constant locals
OK locals . cr
{'__name__': '__main__', '__doc__': None, '__package__': None, 
'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, 
'__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 
'x': 123, 'y': 345, 'peforth': <module 'peforth' from 'C:\\Users\\hcche\\AppData\\
Local\\Programs\\Python\\Python36\\lib\\site-packages\\peforth\\__init__.py'>}
OK

Do you find x and y in the above dict? Let's print x value in FORTH way and change it :

OK locals :> ['x'] . cr
123
OK locals :: ['x']=321

Leave peforth and go back to python interpreter and check what happened to x :

OK exit
>>> x
321
>>> x = 332211
>>> peforth.ok()  # Note! no argument
OK locals :> ['x'] . cr
332211
OK locals :: ['x']=112233
OK exit
>>> x
112233

We can actually do this back and forth as shown above. If we create a new variable z now in python can peforth see it?

>>> z = 998877
>>> peforth.ok()   # Note! no argument
OK locals :> ['z'] . cr
998877

B i n g o ! Why? The constant locals is the same dictionary of locals() at the point in python.

OK locals type . cr
<class 'dict'>

Can we create something in peforth and bring it back to python? Sure! Press Ctrl-D to start a multiple line input to type in a function and end with another Ctrl-D as below:

OK ^D
<py>
def hi():
    print("hello world!!")
push(hi)  # put hi onto TOS of peforth
</py>
constant hi // ( -- func ) hello world
^D

Now constant hi is the function and this is a way to execute it:

OK hi       # put the function on TOS 
OK execute  # execute TOS, whatever it is
hello world!!
OK hi .
<function compyle_anonymous.<locals>.hi at 0x0000018B836EEEA0>OK
OK

Put hi into locals , can it be seen in python?

OK
OK hi py: v('locals')['hi']=pop()  # explained below ...
OK exit
>>> hi
<function compyle_anonymous.<locals>.hi at 0x0000018B836EEEA0>
>>> hi()
hello world!!
>>>

Yes!

That locals in peforth is a constant. Any peforth constant and value has a pythonic reference for python code to access them. For example, hi constant's absolute reference to be seen in python is:

>>> peforth.vm.forth['hi']
<function compyle_anonymous.<locals>.hi at 0x0000018B836EEEA0>
>>>

OK py> vm.forth['hi'] . cr
<function compyle_anonymous.<locals>.hi at 0x0000018B836EEEA0>
OK

The referene peforth.vm.forth['hi'] for when in python and vm.forth['hi'] for when in peforth is long and, when peforth start to support vocabulary in the future, variables in different vocabularies will make references even longer, like these:

vm.forth['hi']
vm.assembler['begin']
vm.win32['working-dir']
vm.tensorflow['layer2']

So we have a shorter and related form to access them. If they are accessed from the same context as they are from then the reference can be as short as:

v('hi')
v('begin')
v('working-dir')
v('layer2')

Recently peforth does not support vocabulary yet, the following explanations are for the future.

The 'forth' vocabulary is the root. We also have r() to specifically access variables in the 'forth' or root vocabulary. Assume the context is now 'assembler' and we want to reach the 'hi' function in 'forth' and other variables in foreign vocabularies:

\ when context is 'assembler'
r('hi')
v('begin')
vm.win32['working-dir']  # foreign variable
vm.tensorflow['layer2']  # foreign variable

I guess that's all for peforth to be your debugger or an assistant in your python works.

Have fun!

Clone this wiki locally