2006-10-03

Fiddling about with Python AST objects

I spent most of yesterday evening trying to get the ProductionNode to compile. I have modified it so that I now send in the AST for the Action part of a Rule. I kept getting a strange CodeGenerator error which felt a bit too "deep" into Python for me to have to worry about.

Using the same example as previously:

>>> import pyRete
>>> @pyRete.Rule
... def foo(a = Type1, b = Type2):
... salience = 100
... if a.n > b.n:
... print a.n, "is larger than", b.n
The following AST is the Action part:
Stmt([Printnl([Getattr(Name('a'), 'n'), Const('is larger than'), Getattr(Name('b'), 'n')], None)])
but when I send this to the CodeGenerator it screams that there's no "scope". I did a lot of Googling and a lot of going through the pycodegen module's code. It took me a while to figure it out but when I started comparing my partial AST with:
>>> import compiler
>>> print compiler.parse("""print a.n, "is larger than", b.n""")
Module(None, Stmt([Printnl([Getattr(Name('a'), 'n'), Const('is larger than'), Getattr(Name('b'), 'n')], None)]))
it all fell into place. If I wrap my AST in a Module object everything works out great.

I also noted that I allow *any* code to be executed in the Action part. I really hoped I wouldn't have to parse that node but I cannot allow, for example: If statements, class and function definitions, ..., return statements, etc etc.

The good news is that it's a lot easier to write a Visitor that only has to raise an Exception if it finds something it doesn't like than it is to write one that has to take everything apart and assemble it according to another structure.

Inga kommentarer: