On Sat, Jun 13, 2009 at 3:54 AM, Simon Forman<[email protected]> wrote:
> Hello,
>
> I spent most of the last week reading the pdfs from the vpri.org site
> and I am bowled over.  It's amazing what you're accomplishing.
> Congratulations.
>
> I am trying to understand the COLA architecture by way of building a
> model of it in the python language.  I think I've got the basic object
> model down okay, but I'm having trouble grokking the eval/transform
> system.  I suspect there's an elegant twist there I'm just missing.
>
> The attached files are:
> co.py - a python version of the basic object model.
> la.py - an attempt at making the transformation engine.
> rootbeer.py - a "port" of la.py to the co.py object model.
>
> Could someone take a look at those, or just fill in some detail about
> section 5 "Behaviour: symbolic expressions and transformations" from
> http://www.vpri.org/pdf/rn2006001a_colaswp.pdf "Accessible
> Language-Based Environments of Recursive Theories"? I think I'm
> missing something about how the transformation engine is supposed to
> work.  I dug through the Jolt(?) code but I could locate the magic.
>
> Thank you in advance, and thank you all for doing such incredible
> work.  The object model alone is breathtaking.
>


I think I've managed to create a simple version of a COLA in python,
following the descriptions in the pdfs on vpri.org.  I was a little
confused over the description of how the transform function was
supposed to work with the symbols and contexts, but I think I made it
work sufficiently like the paper(s) describe. In any event the simple
COLA certainly works.

Again, the COLA architecture is just breathtaking.  I am so moved by
the idea that a page or two of code can be so powerful and general.

I'm trying now to create a very simple "bridge" between the COLA and
Pepsi.  I implemented a very simple Forth-like system using the COLA
structures and on top of that I am writing a very simple parser (based
on "A BNF Parser in Forth"
http://www.bradrodriguez.com/papers/bnfparse.htm) which I hope then to
use to parse pepsi source. My general idea is to write just enough
code to be able to turn any basic COLA into a pepsi compiler, and
thence into a full-fledged Coke/OMeta system capable of all the great
and powerful magics.

Is there a grammar for Pepsi? I've read
http://piumarta.com/software/cola/pepsi.html and could figure it out
from that document but I'd rather just work with a formal grammar.

Warm regards,
~Simon

-- 
"The history of mankind for the last four centuries is rather like
that of an imprisoned sleeper, stirring clumsily and uneasily while
the prison that restrains and shelters him catches fire, not waking
but incorporating the crackling and warmth of the fire with ancient
and incongruous dreams, than like that of a man consciously awake to
danger and opportunity."  --H. P. Wells, "A Short History of the
World"
'''

A simple model of an Object Model as per:

"Open Reusable Object Models", Ian Piumarta, Alessandro Warth
http://www.vpri.org/pdf/tr2006003a_objmod.pdf

This departs in several ways from the OM described in that paper. It's
meant mainly as a rough sketch done to better understand the ideas.

There is no specific symbol type, we just use strings. The vtable also
has no specific type, it's just an Object.  Last, I lean on the python
dict type to act as the vtable's storage.
'''

class Object:
    '''
    Root of the whole system, has a vtable and some data.
    '''
    def __init__(self, vtable):
        self.vtable = vtable
        self.data = None

def send(obj, name, *args, **keyword_args):
    method = bind(obj, name)
    return method(obj, *args, **keyword_args)

def bind(obj, name):
    if obj.vtable is obj and name == 'lookup':
        return lookup(obj, name)
    return send(obj.vtable, 'lookup', name)

def addMethod(vtable, name, implementation):
    vtable.data[name] = implementation

def lookup(vtable, name):
    try:
        return vtable.data[name]
    except KeyError:
        if vtable.parent is not None:
            return send(vtable.parent, 'lookup', name)
        raise Exception("lookup failed for %r" % name)

def delegated(vtable):
    vt = None if vtable is None else vtable.vtable
    child = Object(vt) # allocate() from the paper.
    child.parent = vtable
    child.data = {} # Map names to methods.
    return child


def bootstrap():

    # Create the VTable's VTable.
    vtvt = delegated(None)

    # VTable is its own VTable.
    vtvt.vtable = vtvt

    # Create a VTable for Objects. (Use delegated(None) so it has no
    # parent.  In other words Object, not VTable, is the root of the
    # system.)
    object_vt = delegated(None)

    # Manually tell it it's a VTable.
    object_vt.vtable = vtvt

    # VTable is a kind of Object. Thus its VTable's parent is Object's
    # VTable and since it's its own VTable we just set its parent here.
    vtvt.parent = object_vt

    # Give VTable a lookup method by directly calling addMethod().
    addMethod(vtvt, 'lookup', lookup)

    # Now the send() and bind() machinery will work.
    assert lookup is send(vtvt, 'lookup', 'lookup')

    # Add addMethod() to the VTable.
    addMethod(vtvt, 'addMethod', addMethod)

    # We can add the rest using send().
    send(vtvt, 'addMethod', 'allocate', Object) # Use class as allocate().
    send(vtvt, 'addMethod', 'delegated', delegated)

    # We're done.
    return object_vt, vtvt
#!/usr/bin/env python
'''
Playing with integrating la.py and co.py

So this is basically an attempt to understand:

"Accessible Language-Based Environments of Recursive Theories", Ian
Piumarta - http://www.vpri.org/pdf/rn2006001a_colaswp.pdf

by implementing [part of] it in python. The co module implements the
object model as simply and directly as I could, and the la module tries
to implement the transformation engine using that object module.

I'm not quite getting it.  This works, but I think there's a much more
elegant system just out of sight and the secret's in the way you dispatch
the transform method to objects vs symbols. I'm not sure though.

This is a somewhat more elegant take on rootbeer.py, I'm still not quite
getting it though.

The following classes/methods are constructed.

    Object.eval
    Object.transform
    Object.typeOf

    Symbol.transform
    Symbol.setName / Symbol.getName
    Symbol.setSymbol

    AST.init

'''
from co import send


def Eval(tree, context):
    symbol = send(tree, 'typeOf')
    if symbol is None:
        return
    method = send(symbol, 'transform', context)
    assert method is not None
    new_tree = method(tree, context)
    if new_tree is None:
        return
    return send(new_tree, 'eval', context)

def setName(symbol, name): symbol.name = name
def getName(symbol): return symbol.name
def setSymbol(symbol, thing): thing.symbol = symbol

def transform(symbol, context):
    name = send(symbol, 'getName')
    method = send(context, 'lookup', name)
    assert method is not None
    return method

def typeOf(obj):
    try: return obj.symbol
    except AttributeError: pass

def init_ast(ast, symbol, *values):
    ast.data = list(values)
    send(symbol, 'setSymbol', ast)


# At this point the basic eval/transform widgetry is done. It still needs
# some cruft to work though: ASTs and symbols to attach to the ASTs.

def setUpTransformEngine(object_vt, vtvt):
    # Create a Symbol object type.
    symbol_vt = send(vtvt, 'delegated')

    # Create ast object type.
    ast_vt = send(object_vt, 'delegated')

    send(object_vt, 'addMethod', 'eval', Eval)
    send(object_vt, 'addMethod', 'transform', Eval)
    send(object_vt, 'addMethod', 'typeOf', typeOf)

    send(symbol_vt, 'addMethod', 'setName', setName)
    send(symbol_vt, 'addMethod', 'getName', getName)
    send(symbol_vt, 'addMethod', 'setSymbol', setSymbol)
    send(symbol_vt, 'addMethod', 'transform', transform)

    send(ast_vt, 'addMethod', 'init', init_ast)

    return symbol_vt, ast_vt
_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc

Reply via email to