diff --git a/relational/optimizations.py b/relational/optimizations.py index 8191a8c..22e8bb0 100644 --- a/relational/optimizations.py +++ b/relational/optimizations.py @@ -53,6 +53,27 @@ RENAME = parser.RENAME ARROW = parser.ARROW +def replace_leaves(node, context): + ''' + Node is a parsed tree + context is a dictionary containing + parsed trees as values. + + If a name appearing in node appears + also in context, the parse tree is + modified to replace the node with the + subtree found in context. + ''' + print(node, ' ' ,node.__class__) + if node.kind == parser.UNARY: + replace_leaves(node.child, context) + elif node.kind == parser.BINARY: + replace_leaves(node.left, context) + replace_leaves(node.right, context) + elif node.name in context: + replace_node(node, context[node.name]) + + def replace_node(replace, replacement): '''This function replaces "replace" node with the node "with", the father of the node will now point to the with node''' diff --git a/relational/optimizer.py b/relational/optimizer.py index e564039..89b8312 100644 --- a/relational/optimizer.py +++ b/relational/optimizer.py @@ -25,6 +25,7 @@ from relational import optimizations from relational import parser +from relational.maintenance import UserInterface # Stuff that was here before, keeping it for compatibility @@ -38,6 +39,24 @@ tokenize = parser.tokenize tree = parser.tree # End of the stuff +def optimize_program(code, rels): + ''' + Optimize an entire program, composed by multiple expressions + and assignments. + ''' + lines = code.split('\n') + context = {} + + for line in lines: + line = line.strip() + if line.startswith(';') or not line: + continue + res, query = UserInterface.split_query(line) + last_res = res + parsed = parser.tree(query) + optimizations.replace_leaves(parsed, context) + context[res] = parsed + return optimize_all(context[last_res], rels) def optimize_all(expression, rels, specific=True, general=True, debug=None): '''This function performs all the available optimizations.