This isn't much, but it is a start. Phase refactoring seems like it will become a bit difficult and I think it is better left for dev1 if possible; I need to work with someone who know the source more intimately. It appears that some parts must almost be "rebuilt" or at least control flow heavily altered between statements, it is all about keeping the changes to a minimum... the good news is that a certain amount of spaghetti will disappear through the process (you know -- the things that break in a different part of the code when you change another part in the code; while not necesarrily the root of all evil, it does make it harder to get to know a codebase).
But I have patch for some trivial stuff at the "top" of the call chain that at least is a good point for discussion (if somebody else cares how this is done). It can be found here: http://wiki.cython.org/DagSverreSeljebotn/patches?action=AttachFile&do=get&target=phaserefactoring1.diff and succeeds the testcases; I consider it ready for inclusion. Basically, what it does is turn this (psuedo-code describing overall structure, you won't find this anywhere): for each function in module: construct_function_scope analyse_control_flow analyse_declarations analyse_expressions generate_code into for each function in module: construct_function_scope for each function in module: analyse_control_flow for each function in module: analyse_declarations for each function in module: analyse_expressions for each function in module: generate_code However, each of these are in turn run as recursive calls just like before. In particular, analyse_expressions is still one phase and not easily seperateable (it should be split in three I think: analyse types, coercion, allocate temps). Also, these are all "function-level"; on module-level things happen like before, i.e. analyse_declarations in the module level is run at another time (and for the nearest future it should remain this way; just consider module-level and function-level analysis different phases). The new code is implemented using visitor transforms. One could argue about this, but I do think it leads to pretty neat code. The third for-loop in the psuedo-code above is this implemented like this: Cython/Compiler/Transforms/Analysis.py [is this source structure ok?]: class AnalyseFunctionBodyDeclarations(VisitorTransform): def pre_FuncDefNode(self, node): node.body.analyse_declarations(node.scope) return False # do not recurse beyond first function level Cython/Compiler/ModuleNode.py: class ModuleNode: def generate_c_code(self, env, options, result): ... import Cython.Compiler.Transforms.Analysis as Analysis ... Analysis.AnalyseFunctionBodyDeclarations()(self, env=env) ... self.body.generate_function_definitions(env, code, options.transforms) ... The only non-trivial part is that the function scope is constructed by a tree transform that adds the "scope" and "scopenode" attributes in the following way: The FuncDefNodes and ModuleNodes gets their "scope" attribute set to the object that was previously passed around everywhere as the "env" parameter (this is then read back in order to pass the "env" correctly). All nodes also have their "scopenode" attribute set to the node that caused creation of the enclosing scope. I.e., rather than relying on a passed in env passed recursively from the function/module, it is possible for nodes to look up self.scopenode.scope. This will aid seperation of phases. -- Dag Sverre _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
