Python bindings

Cf0x10 programs may be easily invoked from Python:

>>> from cf0x10.interpreter import Program
>>>
>>> p = Program('"Hello, world"')
>>> p.execute(sys.stdin, sys.stdout, [])
Hello, world

In your Python program, just decorate functions with @comefrom to make them eligible jump targets from Cf0x10 programs:

>>> from cf0x10.bindings import comefrom
>>>
>>> @comefrom('if who')
... def cf_greeting(io, scope):
...     io.stdout.write("Hello, %s" % scope['who'])
>>>
>>> p = Program('who = "world"', additional_bindings=[cf_greeting])
>>> p.execute(sys.stdin, sys.stdout, [])
Hello, world
class cf0x10.bindings.Binding(fn)

The Binding class encapsulates a Comefrom0x10 block bound to a Python function. Client code normally will not need to instantiate bindings directly, as the decorators provide all required functionality.

cf0x10.bindings.comefrom(comefrom_what)

Indicates that the decorated function should be invoked when the interpreter encounters a condition that satisfies comefrom_what. This uses a syntax identical to the tail of a comefrom statement, in an ordinary Cf0x10 program, so:

@comefrom('foo if bar')
def example(io, scope):
    pass

Is essentially equivalent to defining this block in a cf0x10 program’s global scope:

example
  comefrom foo if bar
cf0x10.bindings.setvar(name)

Declares that the decorated function expects to change the value of the indicated variable. This declares a global variable in the cf0x10 program.

The bound function can set variables by assigning the value in the scope object. Values must be of a type that can be converted to a Comefrom0x10 type, that is, numbers or strings:

@comefrom('')
@setvar('foo')
def example(io, scope):
    scope['foo'] = 'bar'

Assignment may cause jumps to comefrom statements, the same way as in cf0x10 code, except:

  • Jumps from bound functions are queued and executed after the function returns
  • No self-jumps

Bound functions can only trigger jumps by assignment, that is, they cannot trigger unconditional jumps.