/* // $Id: //guest/julian_hyde/saffron/src/main/saffron/rel/convert/JavaConverter.java#1 $ // Saffron preprocessor and data engine // Copyright (C) 2002 Julian Hyde <julian.hyde@mail.com> // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the // Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // See the COPYING file located in the top-level-directory of // the archive of this library for complete text of license. */ package saffron.rel.convert; import openjava.mop.OJClass; import openjava.mop.Toolbox; import openjava.ptree.*; import saffron.opt.CallingConvention; import saffron.opt.Cluster; import saffron.opt.Implementor; import saffron.rel.Rel; import saffron.util.Util; /** * <code>JavaConverter</code> converts a plan from * <code>inConvention</code> to {@link CallingConvention#INLINE}. **/ class JavaConverter extends Converter { JavaConverter(Cluster cluster, Rel child, int inConvention) { super(cluster, child, inConvention); } public Object clone() { return new JavaConverter(cluster, child, inConvention); } // implement Rel public int getConvention() { return CallingConvention.JAVA; } public static boolean canConvert(int inConvention) { switch (inConvention) { case CallingConvention.ARRAY: case CallingConvention.ITERATOR: case CallingConvention.ENUMERATION: case CallingConvention.VECTOR: case CallingConvention.MAP: case CallingConvention.HASHTABLE: return true; case CallingConvention.COLLECTION: // do this via Iterator default: return false; } } // implement Converter protected Object implementArray(Implementor implementor, int ordinal) { switch (ordinal) { case -1: // Generate // V[] v = <<exp>>; // for (int i = 0; i < v.length; i++) { // V row = v[i]; // <<parent>> // } StatementList stmtList = implementor.getStatementList(); Variable variableArray = implementor.newVariable(), variableIndex = implementor.newVariable(); StatementList forBody = new StatementList(); Expression exp = (Expression) implementor.implementChild( this, 0, child); stmtList.add( new VariableDeclaration( TypeName.forOJClass(getType(exp)), variableArray.toString(), exp)); stmtList.add( new ForStatement( new TypeName("int"), new VariableDeclarator[] { new VariableDeclarator( variableIndex.toString(), Literal.constantZero())}, new BinaryExpression( variableIndex, BinaryExpression.LESS, new FieldAccess( variableArray, "length")), new ExpressionList( new UnaryExpression( UnaryExpression.POST_INCREMENT, variableIndex)), forBody)); Variable variableRow = implementor.newVariable(); forBody.add( new VariableDeclaration( TypeName.forOJClass(getRowType()), variableRow.toString(), new ArrayAccess( variableArray, variableIndex))); implementor.bind(this, variableRow); implementor.generateParentBody(this, forBody); return null; default: throw Util.newInternal( "implement: ordinal=" + ordinal); } } // implement Converter protected Object implementIterator( Implementor implementor, int ordinal) { switch (ordinal) { case -1: // called from parent // All the work gets done when our child calls us back. Util.discard(implementor.implementChild(this, 0, child)); return null; case 0: // called from child // Generate // Iterator i = <<child>>; // while (i.hasNext()) { // V v = (Type) i.next(); // <<body>> // } // StatementList stmtList = implementor.getStatementList(), whileBody = new StatementList(); Variable variableIter = implementor.newVariable(), variableRow = implementor.newVariable(); // todo: replace 'null' with 'child' below Util.assert(false); stmtList.add( new VariableDeclaration( new TypeName("java.util.Iterator.class"), variableIter.toString(), null /*child*/)); stmtList.add( new WhileStatement( new MethodCall( variableIter, "hasNext", null), whileBody)); TypeName typeName = TypeName.forOJClass(child.getRowType()); whileBody.add( new VariableDeclaration( typeName, variableRow.toString(), new CastExpression( typeName, new MethodCall( variableRow, "next", null)))); implementor.bind(this, variableRow); implementor.generateParentBody(this, whileBody); return null; default: throw Util.newInternal( "implement: ordinal=" + ordinal); } } // implement Converter public Object implementVector( Implementor implementor, int ordinal) { switch (ordinal) { case -1: // Generate // for (Enumeration e = <<exp>>.elements(); e.hasMoreElements();) { // Row row = (Row) e.nextElement(); // <<parent>> // } StatementList stmtList = implementor.getStatementList(); Variable variable_enum = implementor.newVariable(), variable_row = implementor.newVariable(); StatementList forBody = new StatementList(); Expression exp = (Expression) implementor.implementChild( this, 0, child); OJClass rowType = child.getRowType(); stmtList.add( new ForStatement( TypeName.forOJClass(Util.clazzEnumeration), new VariableDeclarator[] { new VariableDeclarator( variable_enum.toString(), new MethodCall( exp, "elements", new ExpressionList()))}, new MethodCall( variable_enum, "hasMoreElements", null), new ExpressionList(), forBody)); forBody.add( new VariableDeclaration( TypeName.forOJClass(rowType), new VariableDeclarator( variable_row.toString(), new CastExpression( TypeName.forOJClass(rowType), new MethodCall( variable_enum, "nextElement", null))))); implementor.bind(this, variable_row); implementor.generateParentBody(this, forBody); return null; default: throw Util.newInternal( "implement: ordinal=" + ordinal); } } // implement Converter public Object implementEnumeration( Implementor implementor, int ordinal) { switch (ordinal) { case -1: // Generate // for (Enumeration enum = <<exp>>; enum.hasMoreElements();) // { // Row row = enum.nextElement(); // <<parent>> // } StatementList stmtList = implementor.getStatementList(); Variable variable_enum = implementor.newVariable(), variable_row = implementor.newVariable(); StatementList forBody = new StatementList(); Expression exp = (Expression) implementor.implementChild( this, 0, child); stmtList.add( new ForStatement( TypeName.forOJClass(Util.clazzEnumeration), new VariableDeclarator[] { new VariableDeclarator( variable_enum.toString(), exp)}, new MethodCall( variable_enum, "hasMoreElements", null), new ExpressionList(), forBody)); forBody.add( new VariableDeclaration( TypeName.forOJClass(Toolbox.clazzObject), new VariableDeclarator( variable_row.toString(), new MethodCall( variable_enum, "nextElement", null)))); implementor.bind(this, variable_row); implementor.generateParentBody(this, forBody); return null; default: throw Util.newInternal( "implement: ordinal=" + ordinal); } } // implement Converter protected Object implementMap( Implementor implementor, int ordinal) { switch (ordinal) { case -1: // Generate // Map m = <<exp>>; // for (Iterator entries = m.entrySet().iterator(); // entries.hasNext();) { // Map.Entry entry = (Map.Entry) keys.next(); // Row row = new Row(entry.getKey(), entry.getValue()); // <<parent>> // } StatementList stmtList = implementor.getStatementList(); Variable variable_m = implementor.newVariable(), variable_entries = implementor.newVariable(), variable_entry = implementor.newVariable(), variable_row = implementor.newVariable(); StatementList forBody = new StatementList(); Expression exp = (Expression) implementor.implementChild( this, 0, child); stmtList.add( new VariableDeclaration( TypeName.forOJClass(Util.clazzMap), variable_m.toString(), exp)); stmtList.add( new ForStatement( TypeName.forOJClass(Util.clazzIterator), new VariableDeclarator[] { new VariableDeclarator( variable_entries.toString(), new MethodCall( new MethodCall( variable_m, "entrySet", null), "iterator", null))}, new MethodCall( variable_entries, "hasNext", null), new ExpressionList(), forBody)); forBody.add( new VariableDeclaration( TypeName.forOJClass(Toolbox.clazzMapEntry), new VariableDeclarator( variable_entry.toString(), new CastExpression( TypeName.forOJClass(Toolbox.clazzMapEntry), new MethodCall( variable_entries, "next", null))))); forBody.add( new VariableDeclaration( TypeName.forOJClass(getRowType()), variable_row.toString(), new AllocationExpression( TypeName.forOJClass(getRowType()), new ExpressionList( new MethodCall( variable_entry, "getKey", null), new MethodCall( variable_entry, "getValue", null))))); implementor.bind(this, variable_row); implementor.generateParentBody(this, forBody); return null; default: throw Util.newInternal( "implement: ordinal=" + ordinal); } } // implement Converter protected Object implementHashtable( Implementor implementor, int ordinal) { switch (ordinal) { case -1: // Generate // Hashtable h = <<exp>>; // for (Enumeration keys = h.keys(); keys.hasMoreElements();) { // Object key = keys.nextElement(); // Object value = h.get(key); // Row row = new Row(key, value); // <<parent>> // } StatementList stmtList = implementor.getStatementList(); Variable variable_h = implementor.newVariable(), variable_keys = implementor.newVariable(), variable_key = implementor.newVariable(), variable_value = implementor.newVariable(), variable_row = implementor.newVariable(); StatementList forBody = new StatementList(); Expression exp = (Expression) implementor.implementChild( this, 0, child); stmtList.add( new VariableDeclaration( TypeName.forOJClass(Util.clazzHashtable), variable_h.toString(), exp)); stmtList.add( new ForStatement( TypeName.forOJClass(Util.clazzEnumeration), new VariableDeclarator[] { new VariableDeclarator( variable_keys.toString(), new MethodCall( variable_h, "keys", null))}, new MethodCall( variable_keys, "hasMoreElements", null), new ExpressionList(), forBody)); forBody.add( new VariableDeclaration( TypeName.forOJClass(Toolbox.clazzObject), new VariableDeclarator( variable_key.toString(), new MethodCall( variable_keys, "nextElement", null)))); forBody.add( new VariableDeclaration( TypeName.forOJClass(Toolbox.clazzObject), new VariableDeclarator( variable_value.toString(), new MethodCall( variable_h, "get", new ExpressionList(variable_key))))); forBody.add( new VariableDeclaration( TypeName.forOJClass(getRowType()), variable_row.toString(), new AllocationExpression( TypeName.forOJClass(getRowType()), new ExpressionList( variable_key, variable_value)))); implementor.bind(this, variable_row); implementor.generateParentBody(this, forBody); return null; default: throw Util.newInternal( "implement: ordinal=" + ordinal); } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#4 | 1853 | Julian Hyde |
saffron: Further improve binding of rows to variables. |
||
#3 | 1748 | Julian Hyde |
saffron: convert unit tests to JUnit; add CallingConvention.ITERABLE; lots of other stuff; release 0.1. |
||
#2 | 1474 | Julian Hyde |
saffron: Aggregations are working. Renamed 'aggregator' to 'aggregation'. |
||
#1 | 1467 | Julian Hyde |
saffron: First saffron check-in; incorporate my changes to openjava. |