pyficl - a Python interface to FICL

Introduction

The FICL package is a Forth implementation with a very comprehensive C interface.

This module implements a Python interface to FICL. You can use it to call Forth from Python:

>>> import pyficl
>>> vm = pyficl.System().createVm()
>>> r = vm.evaluate("1 2 + .")
3

and call Python from Forth:

>>> import pyficl
>>> s = pyficl.System()
>>> vm = s.createVm()
>>> def cubed(vm):
...   stk = vm.getDataStack()
...   stk.push(stk.pop() ** 3)
...
>>> s.getDictionary().setPrimitive("cubed", cubed)
>>> r = vm.evaluate("3 cubed .")
27
>>> r = vm.evaluate(""": demo 10 0 do i . ." cubed is " i cubed . cr loop ; demo""")
0 cubed is 0
1 cubed is 1
2 cubed is 8
3 cubed is 27
4 cubed is 64
5 cubed is 125
6 cubed is 216
7 cubed is 343
8 cubed is 512
9 cubed is 729

Download and Build

Easiest is to use easy_install to get it from PyPI: sudo easy_install -U pyficl.

Otherwise you can download it from:

http://excamera.com/files/pyficl-4.0.31.0.tar.gz

extract and run python setup.py install. There is a unit test included in the distribution:

$ python test_ficl.py
.......
----------------------------------------------------------------------
Ran 7 tests in 0.042s

OK

Available Types

System Objects

class pyficl.System(dictionarySize = None)

The top level data structure of the system - System ties a list of virtual machines to their corresponding dictionaries.

createVm()
Returns:new virtual machine
Return type:Vm

Create a new Vm from the heap, and link it into the system VM list. Initializes the VM and binds default sized stacks to it.

getDictionary()
Returns:the system’s dictionary
Return type:Dictionary
lookup()
Parameter:name (str) – name of word to look up
Returns:word representing name
Return type:Word

Returns the Word representing str, or None if word is not found.

Dictionary Objects

class pyficl.Dictionary

A Dictionary is a linked list of FICL_WORDs. It is also Ficl’s memory model. Dictionaries are created when a System is created, and accessed by System.getDictionary().

setPrimitive(name, code)
Parameters:
  • name (str) – Name of new word
  • code (callable) – Function for word

Add a new primitive to the FICL Dictionary called name, which when executed calls the Python function code. The function is passed a single argument, the executing Vm.

>>> import pyficl
>>> s = pyficl.System()
>>> vm = s.createVm()
>>> def myfunc(vm):  print "I WAS CALLED"
>>> s.getDictionary().setPrimitive("myfunc", myfunc)
>>> r = vm.evaluate("myfunc")
I WAS CALLED

Vm Objects

class pyficl.Vm

The virtual machine contains the state for one interpreter. Create a Vm using System.createVm().

evaluate(s)
Parameter:s (str) – input text
Returns:status code, see below
Return type:int

Evaluates a block of input text in the context of the specified interpreter.

>>> import pyficl
>>> vm = pyficl.System().createVm()
>>> stk = vm.getDataStack()
>>> r = vm.evaluate("1 2 + .")
3 

status codes:

FICL_VM_STATUS_OUT_OF_TEXT
is the normal exit condition
FICL_VM_STATUS_ERROR_EXIT
means that the interpreter encountered a syntax error and the vm has been reset to recover (some or all of the text block got ignored
FICL_VM_STATUS_USER_EXIT
means that the user executed the “bye” command to shut down the interpreter. This would be a good time to delete the vm, etc – or you can ignore this signal.
FICL_VM_STATUS_ABORT and FICL_VM_STATUS_ABORTQ
are generated by ‘abort’ and ‘abort”’ commands.
getDataStack()
Returns:the data stack
Return type:Stack

Returns the Vm’s data stack

getReturnStack()
Returns:the return stack
Return type:Stack

Returns the Vm’s return stack

getFloatStack()
Returns:the float stack
Return type:Stack

Returns the Vm’s float stack

executeXT(xt)
Parameter:xt (Word) – Word to execute, obtained from System.lookup()
Returns:status code, see Vm.evaluate()
Return type:int

Executes the given word.

Word Objects

class pyficl.Word

A representation of a single Ficl word. Obtained by System.lookup(), used by Vm.executeXT().

>>> import pyficl
>>> s = pyficl.System()
>>> vm = s.createVm()
>>> stk = vm.getDataStack()
>>> dot = s.lookup(".")
>>> stk.push(787)
>>> r = vm.executeXT(dot)
787 

Stack Objects

class pyficl.Stack

Stacks get heavy use in Ficl and Forth. Each virtual machine (Vm) implements two of them: one holds parameters (Vm.getDataStack()), and the other holds return addresses and control flow information for the virtual machine (Vm.getReturnStack()).

Stack supports the Python iterator protocol, as shown below:

>>> import pyficl
>>> stk = pyficl.System().createVm().getDataStack()
>>> stk.push(101)
>>> stk.push(202)
>>> stk.push(303)
>>> print list(stk)
[303, 202, 101]
>>> for x in stk:
...     print x
303
202
101
reset()
empty the stack
push(i)
Parameter:i (int) – value

Push value i on the stack.

pushFloat(f)
Parameter:f (float) – value

Push floating point value f on the stack.

pushStr(s)
Parameter:s (str) – value

Push s on the stack as a standard Forth counted string ( c-addr u ).

>>> import pyficl
>>> vm = pyficl.System().createVm()
>>> stk = vm.getDataStack()
>>> a = 'Hello world'
>>> stk.pushStr(a)
>>> r = vm.evaluate("TYPE CR")
Hello world
pop()
Returns:top value from stack
Return type:int

Removes and returns the top value from the stack as a Python integer

popFloat()
Returns:top value from stack
Return type:float

Removes and returns the top value from the stack as a Python float

popStr()
Returns:top value from stack
Return type:str

Removes and returns the top value from the stack as a Python string. Assumes that the stack is a counted string ( c-addr u ).

depth()
returns the depth of the stack, in cells.
fetch(n)
Parameter:n (int) – stack item, 0 is top of stack

returns the nth item from the stack.