> I would suggest mapping these to method names in the plugins. You could then 
> write
>
>     class MyTransform(Transform):
>          def pre_analyse_types(self, node, name):
>              ...
>
> instead of the current "process_node()" method.
>   
I respectfully disagree strongly :-) From a simple design standpoint, 
mixing information about which phase one is in and the simple contract 
that a Transform must obey to doesn't make sense.

Also, it kinds of breaks IoC:

http://en.wikipedia.org/wiki/Inversion_of_Control

Apart from a puristic perspective, it has practical consequenceses: In 
time a lot of transform will run in the same phase, especially between 
the type deduction and type coercion phase, and this binds down written 
transforms so that it is difficult to later divide into sub-phases and 
so on to get them all run in the right order.

I always assumed one would use a standard plugin pattern like this:

MyPlugin.py:

import MyTransform

def register_cython_module(controller):
  controller.add_transform_to_phase("myphase", MyTransform.MyTransform)
  controller.add_commandline_argument_i_need(....)


Basically, Cython on startup loads a list of modules, and if they 
contain a register_cython_module call it is called with something 
wrapping the Cython compiler options object as parameter.


>
> that determines when to run the plugin. If the plugin provided a set of
> interesting nodes instead, the infrastructure could store them in a dict
> (mapping node types to a list of plugins) and directly select the
> transformations that can run on that node.
Again I think this is wrong design. The functionality you want should 
definitely be provided, however it would simply be either a base class 
or a wrapper class (leaning towards the former) for a transform:

class MyTransform(NodeFilterTransform):
  def __init__(self):
    NodeFilterTransform.__init__(self, [ForStatNode, ForListNode,])

However, again, I think this will probably be more generic, doing 
something like

import cython.dom as d

class MyTransform(TemplateMatchTransform):
  match = d.if(cond=d.bool, body=d.any, else=d.any)
  def process_if(self, node, name): ...
  process_if = register_template(match, process_if)


(Or even match = "some-xpath-inspired-thing").

Basically, both approaches (+ another one using XPath, and another one 
and so on) can be used, live in seperate base classes, and transforms 
pick the most convenient to extend.

Building type filtering directly into the core however locks you to The 
One Right approach, while different transforms will have different 
needs. I cannot see any performance benefits either.


-- 
Dag Sverre

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to