From: <th...@us...> - 2009-10-18 18:22:12
|
Revision: 10755 http://pcgen.svn.sourceforge.net/pcgen/?rev=10755&view=rev Author: thpr Date: 2009-10-18 18:21:46 +0000 (Sun, 18 Oct 2009) Log Message: ----------- Updates and changes necessary to have Formula Compiler capable of parsing all PCGen Formulas Modified Paths: -------------- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AddOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AndOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/DivOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/ExponentOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/MultOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/OrOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RelationalOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RemOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/SubOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/VariableOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/compile/FormulaCompiler.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractAssociativeOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractOrderedOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/FormulaOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/NodeEvaluator.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/OperationUtilities.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/ConstantOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/IfOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/NaryMethodOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/NoOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/UnaryMethodOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/parse/SimpleNode.java sandbox/FormulaCompiler/src/pcgen/base/formula/parse/formula.jjt sandbox/FormulaCompiler/test/pcgen/base/formula/FormulaTest.java Added Paths: ----------- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/InvertOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/TransparentOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractBinaryOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractFormulaOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/CountOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/GroupOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/StringOperation.java sandbox/FormulaCompiler/src/pcgen/base/formula/operation/VarOperation.java sandbox/FormulaCompiler/src/pcgen/base/lang/ sandbox/FormulaCompiler/src/pcgen/base/lang/CaseInsensitiveString.java sandbox/FormulaCompiler/src/pcgen/base/util/ sandbox/FormulaCompiler/src/pcgen/base/util/CaseInsensitiveMap.java sandbox/FormulaCompiler/test/pcgen/base/formula/FormulaFileTest.java Removed Paths: ------------- sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractSimpleAssociativeOperation.java Property Changed: ---------------- sandbox/FormulaCompiler/src/pcgen/base/formula/parse/ Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AddOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AddOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AddOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -19,14 +19,14 @@ import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.AbstractSimpleAssociativeOperation; +import pcgen.base.formula.core.AbstractAssociativeOperation; /** * @author Thomas Parker (th...@us...) * * Performs an Addition (+) operation between the child SimpleNodes. */ -public final class AddOperation extends AbstractSimpleAssociativeOperation +public final class AddOperation extends AbstractAssociativeOperation { /** @@ -37,16 +37,8 @@ super(Opcodes.DADD); } - @Override - protected int process(int a, int b) + protected String getSign() { - return a + b; + return "+"; } - - @Override - protected double process(double a, double b) - { - return a + b; - } - } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AndOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AndOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/AndOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -17,13 +17,11 @@ */ package pcgen.base.formula.baseops; -import java.util.ArrayList; -import java.util.List; - import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.FormulaOperation; + +import pcgen.base.formula.core.AbstractBinaryOperation; import pcgen.base.formula.core.NodeEvaluator; import pcgen.base.formula.core.OperationUtilities; import pcgen.base.formula.parse.SimpleNode; @@ -35,67 +33,9 @@ * child SimpleNodes are non-Zero, then this SimpleNode will resolve to 1.0. * Otherwise, it will resolve to 0.0 */ -public final class AndOperation implements FormulaOperation +public final class AndOperation extends AbstractBinaryOperation { - /** - * Performs constant replacement on the SimpleNode given. This will return a - * SimpleNode which (if possible) reduces the given SimpleNode into a less - * complex operation. If both of the children of the given SimpleNode are - * constant, then the logical AND operation will be performed and a constant - * SimpleNode will be returned. - * - * If no simplification can be performed, then this method reserves the - * right to return a reference to the original SimpleNode. It is assumed - * that ownership of the given and returned SimpleNode are the domain of the - * calling method. - * - * @param root - * The SimpleNode to be simplified (if possible) - * @return A SimpleNode with constants reduced. - */ - public SimpleNode doConstantReplacement(SimpleNode root) - { - int childCount = root.jjtGetNumChildren(); - List<SimpleNode> children = new ArrayList<SimpleNode>(childCount); - for (int i = 0; i < childCount; i++) - { - SimpleNode child = (SimpleNode) root.jjtGetChild(i); - boolean childConstant = OperationUtilities.isConstant(child); - if (childConstant) - { - if (Double.parseDouble(child.getText()) == 0.0) - { - // If something is false, then we're done! - return OperationUtilities.getIntegerNode(0); - } - // Don't add non-zero "true" items - unnecessary. - } - else - { - children.add(child); - } - } - // If no children, then all were "true" constants: - if (children.isEmpty()) - { - return OperationUtilities.getIntegerNode(1); - } - // Just OR the non-constant children - if (children.size() == 1) - { - return children.get(0); - } - SimpleNode newNode = new SimpleNode(root.getID()); - newNode.setOperation(this); - int childNum = 1; - for (SimpleNode node : children) - { - newNode.jjtAddChild(node, childNum++); - } - return newNode; - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc) { @@ -120,4 +60,10 @@ mv.visitLabel(escapeLabel); return Math.max(lhsm, rhsm); } + + @Override + protected String getSign() + { + return "&&"; + } } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/DivOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/DivOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/DivOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -20,8 +20,6 @@ import org.objectweb.asm.Opcodes; import pcgen.base.formula.core.AbstractAssociativeOperation; -import pcgen.base.formula.core.OperationUtilities; -import pcgen.base.formula.parse.SimpleNode; /** * @author Thomas Parker (th...@us...) @@ -43,10 +41,8 @@ super(Opcodes.DDIV); } - @Override - protected SimpleNode getSimplifiedNode(String text1, String text2) + protected String getSign() { - double sum = Double.parseDouble(text1) / Double.parseDouble(text2); - return OperationUtilities.getDoubleNode(sum); + return "/"; } } \ No newline at end of file Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/ExponentOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/ExponentOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/ExponentOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -23,13 +23,12 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; -import pcgen.base.formula.core.FormulaOperation; + +import pcgen.base.formula.core.AbstractFormulaOperation; import pcgen.base.formula.core.NodeEvaluator; -import pcgen.base.formula.core.OperationUtilities; -import pcgen.base.formula.lang.ProgrammingError; import pcgen.base.formula.parse.SimpleNode; -public final class ExponentOperation implements FormulaOperation +public final class ExponentOperation extends AbstractFormulaOperation { private final String opClassName; @@ -74,54 +73,6 @@ opMethod = m; } - public SimpleNode doConstantReplacement(SimpleNode root) - { - // TODO Verify node has proper # of children - int childCount = root.jjtGetNumChildren(); - if (!OperationUtilities.isConstant((SimpleNode) root.jjtGetChild(0))) - { - // Can be simplified, but a bear right now... - // Two modes of simplification: - // 1) remove ^1 - // 2) collapse constants - // Note that var^2^var2^3 CAN be collapsed... associative - // var^2^var2 * var^2^var2 * var^2^var2 - // var^2 * var^2 * var^2 (repeated var2 times) - // var * var * var * var * var * var (repeated var2 times) - // var^6^var2 - return root; - } - String text1 = ((SimpleNode) root.jjtGetChild(0)).getText(); - double d1 = Double.parseDouble(text1); - for (int i = 1; i < childCount; i++) - { - if (OperationUtilities.isConstant((SimpleNode) root.jjtGetChild(i))) - { - String text2 = ((SimpleNode) root.jjtGetChild(i)).getText(); - double d2 = Double.parseDouble(text2); - double retValue = Math.pow(d1, d2); - d1 = retValue; - if (i == childCount - 1) - { - return OperationUtilities.getDoubleNode(d1); - } - } - else - { - SimpleNode newNode = new SimpleNode(root.getID()); - newNode.setOperation(this); - SimpleNode constantNode = OperationUtilities.getDoubleNode(d1); - newNode.jjtAddChild(constantNode, 0); - for (int j = i; j < childCount; j++) - { - newNode.jjtAddChild(root.jjtGetChild(j), j - i + 1); - } - return newNode; - } - } - throw new ProgrammingError(); - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc) { @@ -146,4 +97,13 @@ return max; } + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + for (int i = 1; i < node.jjtGetNumChildren(); i++) + { + writeString(mv, "^"); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(i)); + } + } } Added: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/InvertOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/InvertOperation.java (rev 0) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/InvertOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -0,0 +1,48 @@ +/* + * Copyright (c) Thomas Parker, 2005-2009. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This program 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.base.formula.baseops; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import pcgen.base.formula.core.AbstractFormulaOperation; +import pcgen.base.formula.core.NodeEvaluator; +import pcgen.base.formula.parse.SimpleNode; + +public class InvertOperation extends AbstractFormulaOperation { + + public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node, int loc) { + SimpleNode rhs = (SimpleNode) node.jjtGetChild(0); + int max = ev.evaluate(mv, rhs, loc); + performOperation(mv, loc); + return max; + } + + private void performOperation(MethodVisitor mv, int loc) { + mv.visitLdcInsn(0.0); + mv.visitVarInsn(Opcodes.DLOAD, loc); + mv.visitInsn(Opcodes.DSUB); // calculate + } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + writeString(mv, "-"); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + } +} Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/MultOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/MultOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/MultOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -19,14 +19,14 @@ import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.AbstractSimpleAssociativeOperation; +import pcgen.base.formula.core.AbstractAssociativeOperation; /** * @author Thomas Parker (th...@us...) * * Performs a Multiplication (*) operation between the child SimpleNodes. */ -public final class MultOperation extends AbstractSimpleAssociativeOperation +public final class MultOperation extends AbstractAssociativeOperation { /** * Creates a new MultOperation @@ -36,16 +36,8 @@ super(Opcodes.DMUL); } - @Override - protected int process(int a, int b) + protected String getSign() { - return a * b; + return "*"; } - - @Override - protected double process(double a, double b) - { - return a * b; - } - } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/OrOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/OrOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/OrOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -17,14 +17,11 @@ */ package pcgen.base.formula.baseops; -import java.util.ArrayList; -import java.util.List; - import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.FormulaOperation; +import pcgen.base.formula.core.AbstractBinaryOperation; import pcgen.base.formula.core.NodeEvaluator; import pcgen.base.formula.core.OperationUtilities; import pcgen.base.formula.parse.SimpleNode; @@ -36,7 +33,7 @@ * child SimpleNode is non-Zero, then this SimpleNode will resolve to 1.0. * Otherwise, it will resolve to 0.0 */ -public final class OrOperation implements FormulaOperation +public final class OrOperation extends AbstractBinaryOperation { /** @@ -47,64 +44,6 @@ super(); } - /** - * Performs constant replacement on the SimpleNode given. This will return a - * SimpleNode which (if possible) reduces the given SimpleNode into a less - * complex operation. If both of the children of the given SimpleNode are - * constant, then the logical OR operation will be performed and a constant - * SimpleNode will be returned. - * - * If no simplification can be performed, then this method reserves the - * right to return a reference to the original SimpleNode. It is assumed - * that ownership of the given and returned SimpleNode are the domain of the - * calling method. - * - * @param root - * The SimpleNode to be simplified (if possible) - * @return A SimpleNode with constants reduced. - */ - public SimpleNode doConstantReplacement(SimpleNode root) - { - int childCount = root.jjtGetNumChildren(); - List<SimpleNode> children = new ArrayList<SimpleNode>(childCount); - for (int i = 0; i < childCount; i++) - { - SimpleNode child = (SimpleNode) root.jjtGetChild(i); - boolean childConstant = OperationUtilities.isConstant(child); - if (childConstant) - { - if (Double.parseDouble(child.getText()) != 0.0) - { - // If something is true, then we're done! - return OperationUtilities.getIntegerNode(1); - } - // Don't add non-zero "false" items - unnecessary. - } - else - { - children.add(child); - } - } - // If no children, then all were "false" constants: - if (children.isEmpty()) - { - return OperationUtilities.getIntegerNode(0); - } - // Just OR the non-constant children - if (children.size() == 1) - { - return children.get(0); - } - SimpleNode newNode = new SimpleNode(root.getID()); - newNode.setOperation(this); - int childNum = 1; - for (SimpleNode node : children) - { - newNode.jjtAddChild(node, childNum++); - } - return newNode; - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc) { @@ -129,4 +68,10 @@ mv.visitLabel(escapeLabel); return Math.max(lhsm, rhsm); } + + @Override + protected String getSign() + { + return "||"; + } } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RelationalOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RelationalOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RelationalOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -20,60 +20,23 @@ import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.FormulaOperation; + +import pcgen.base.formula.core.AbstractBinaryOperation; import pcgen.base.formula.core.NodeEvaluator; -import pcgen.base.formula.core.OperationUtilities; import pcgen.base.formula.parse.SimpleNode; -public class RelationalOperation implements FormulaOperation +public class RelationalOperation extends AbstractBinaryOperation { private final int operator; + private final String out; - public RelationalOperation(int oper) + public RelationalOperation(int oper, String output) { operator = oper; + out = output; } - public SimpleNode doConstantReplacement(SimpleNode root) - { - // TODO Verify node has proper # of children - SimpleNode lhs = (SimpleNode) root.jjtGetChild(0); - SimpleNode rhs = (SimpleNode) root.jjtGetChild(1); - if (!OperationUtilities.isConstant(lhs) - || !OperationUtilities.isConstant(rhs)) - { - return root; - } - double dl = Double.parseDouble(lhs.getText()); - double dr = Double.parseDouble(rhs.getText()); - boolean result; - switch (operator) - { - case Opcodes.IFEQ: - result = dl == dr; - break; - case Opcodes.IFNE: - result = dl != dr; - break; - case Opcodes.IFLT: - result = dl < dr; - break; - case Opcodes.IFGT: - result = dl > dr; - break; - case Opcodes.IFLE: - result = dl <= dr; - break; - case Opcodes.IFGE: - result = dl >= dr; - break; - default: - throw new RuntimeException("Error in Opcodes"); - } - return OperationUtilities.getIntegerNode(result ? 1 : 0); - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc) { @@ -102,4 +65,10 @@ mv.visitLabel(escapeLabel); } + @Override + protected String getSign() + { + return out; + } + } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RemOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RemOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/RemOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -21,8 +21,6 @@ import org.objectweb.asm.Opcodes; import pcgen.base.formula.core.AbstractOrderedOperation; -import pcgen.base.formula.core.OperationUtilities; -import pcgen.base.formula.parse.SimpleNode; /** * @author Thomas Parker (th...@us...) @@ -35,25 +33,16 @@ private static final int INSTRUCTION = Opcodes.DREM; @Override - protected SimpleNode getSimplifiedNode(String text1, String text2) - { - if (areIntegers(text1, text2)) - { - int sum = Integer.parseInt(text1) % Integer.parseInt(text2); - return OperationUtilities.getIntegerNode(sum); - } - else - { - double sum = Double.parseDouble(text1) % Double.parseDouble(text2); - return OperationUtilities.getDoubleNode(sum); - } - } - - @Override protected void performOperation(MethodVisitor mv, int loc) { mv.visitVarInsn(Opcodes.DLOAD, loc); // lhs mv.visitVarInsn(Opcodes.DLOAD, loc + 2); mv.visitInsn(INSTRUCTION); // calculate } + + @Override + protected String getSign() + { + return "%"; + } } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/SubOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/SubOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/SubOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -19,14 +19,14 @@ import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.AbstractSimpleAssociativeOperation; +import pcgen.base.formula.core.AbstractAssociativeOperation; /** * @author Thomas Parker (th...@us...) * * Performs a Subtraction (-) operation between the child SimpleNodes. */ -public final class SubOperation extends AbstractSimpleAssociativeOperation +public final class SubOperation extends AbstractAssociativeOperation { /** * Creates a new SubOperation @@ -36,16 +36,8 @@ super(Opcodes.DSUB); } - @Override - protected int process(int a, int b) + protected String getSign() { - return a - b; + return "-"; } - - @Override - protected double process(double a, double b) - { - return a - b; - } - } Added: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/TransparentOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/TransparentOperation.java (rev 0) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/TransparentOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -0,0 +1,40 @@ +/* + * Copyright (c) Thomas Parker, 2005-2009. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This program 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.base.formula.baseops; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import pcgen.base.formula.core.AbstractFormulaOperation; +import pcgen.base.formula.core.NodeEvaluator; +import pcgen.base.formula.parse.SimpleNode; + +public class TransparentOperation extends AbstractFormulaOperation { + + public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node, int loc) { + int max = ev.evaluate(mv, (SimpleNode) node.jjtGetChild(0), loc); + mv.visitVarInsn(Opcodes.DLOAD, loc); + return max; + } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + } +} Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/VariableOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/VariableOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/baseops/VariableOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -22,13 +22,14 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; + import pcgen.base.formula.compile.Reference; -import pcgen.base.formula.core.FormulaOperation; +import pcgen.base.formula.core.AbstractFormulaOperation; import pcgen.base.formula.core.NodeEvaluator; import pcgen.base.formula.lang.ProgrammingError; import pcgen.base.formula.parse.SimpleNode; -public final class VariableOperation implements FormulaOperation +public final class VariableOperation extends AbstractFormulaOperation { private static final String GET_VARIABLE_METHOD_NAME = "getVariable"; @@ -65,11 +66,6 @@ } } - public SimpleNode doConstantReplacement(SimpleNode root) - { - return root; - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc) { @@ -80,4 +76,9 @@ GET_VARIABLE_METHOD_NAME, METHOD_DESCRIPTOR); return loc + 2; } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + writeString(mv, varName); + } } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/compile/FormulaCompiler.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/compile/FormulaCompiler.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/compile/FormulaCompiler.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -20,13 +20,13 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.StringReader; -import java.util.HashMap; import java.util.Map; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; + import pcgen.base.formula.core.FormulaOperation; import pcgen.base.formula.core.NodeEvaluator; import pcgen.base.formula.core.OperationUtilities; @@ -34,6 +34,7 @@ import pcgen.base.formula.parse.ParseException; import pcgen.base.formula.parse.SimpleNode; import pcgen.base.formula.parse.TokenMgrError; +import pcgen.base.util.CaseInsensitiveMap; /** * @author Thomas Parker @@ -55,8 +56,7 @@ private static int formulaCount; - private Map<String, FormulaOperation> functionMap = new HashMap<String, FormulaOperation>( - 10); + private Map<Object, FormulaOperation> functionMap = new CaseInsensitiveMap<FormulaOperation>(); public FormulaCompiler() { @@ -71,7 +71,7 @@ SimpleNode root = null; try { - System.err.println("\nquery = " + queryStr + "\n"); + //System.err.println("query = " + queryStr + "\n"); root = parser.query(); } catch (ParseException e) @@ -86,17 +86,16 @@ } if (root == null) { - System.err.println("argh!"); + System.err.println("argh: " + queryStr); return null; } // dump the result tree to the console for debug purposes - root.dump(""); + //root.dump(""); String formulaName = Formula.class.getPackage().getName() + ".dynamic.Formula" + formulaCount++; - optimizeFormula(root); - root.dump(""); + //root.dump(""); // Don't build unique class if really simple if (root.jjtGetNumChildren() == 1) @@ -138,21 +137,6 @@ * and how smart this gets to removing unnecessary parenthesis... */ - private void optimizeFormula(SimpleNode root) - { - int childCount = root.jjtGetNumChildren(); - for (int i = 0; i < childCount; i++) - { - SimpleNode childNode = (SimpleNode) root.jjtGetChild(i); - optimizeFormula(childNode); - SimpleNode sn = childNode.doConstantReplacement(); - if (!childNode.equals(sn)) - { - root.jjtAddChild(sn, i); - } - } - } - private byte[] createFormulaBytecode(String formulaName, SimpleNode root) { ClassWriter cw = new ClassWriter(false); @@ -183,6 +167,21 @@ mv.visitEnd(); cw.visitEnd(); + MethodVisitor tv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, + null); + tv.visitCode(); + tv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); + tv.visitInsn(DUP); + tv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); + tv.visitVarInsn(ASTORE, 0); + stringify(tv, (SimpleNode) root.jjtGetChild(0)); + //Other Stuff here + tv.visitVarInsn(ALOAD, 0); + tv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); + tv.visitInsn(ARETURN); + tv.visitMaxs(2, 1); + tv.visitEnd(); + byte[] bytecode = cw.toByteArray(); try { @@ -206,6 +205,11 @@ return max; } + public void stringify(MethodVisitor mv, SimpleNode node) + { + node.visitToString(this, mv); + } + public FormulaOperation registerFunction(String s, FormulaOperation co) { return functionMap.put(s, co); @@ -215,14 +219,22 @@ public FormulaCompiler clone() throws CloneNotSupportedException { FormulaCompiler fc = (FormulaCompiler) super.clone(); - fc.functionMap = new HashMap<String, FormulaOperation>(functionMap); + fc.functionMap = new CaseInsensitiveMap<FormulaOperation>(); + fc.functionMap.putAll(functionMap); fc.classLoader = new ByteClassLoader(); return fc; } + + public String testToString() + { + StringBuilder sb = new StringBuilder(); + sb.append("blah"); + return sb.toString(); + } public static class ByteClassLoader extends ClassLoader { - public Class defineByteClass(String s, byte[] ba, int off, int l) + public Class<?> defineByteClass(String s, byte[] ba, int off, int l) { return super.defineClass(s, ba, off, l); } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractAssociativeOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractAssociativeOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractAssociativeOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -17,16 +17,12 @@ */ package pcgen.base.formula.core; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import pcgen.base.formula.parse.SimpleNode; -public abstract class AbstractAssociativeOperation implements FormulaOperation +public abstract class AbstractAssociativeOperation extends AbstractFormulaOperation { private final int inst; @@ -69,87 +65,6 @@ mv.visitInsn(inst); // calculate } - /** - * Performs constant replacement on the SimpleNode given. This will return a - * SimpleNode which (if possible) reduces the given SimpleNode into a less - * complex operation. If both of the children of the given SimpleNode are - * constant, then the addition operation will be performed and a constant - * SimpleNode will be returned. - * - * If no simplification can be performed, then this method reserves the - * right to return a reference to the original SimpleNode. It is assumed - * that ownership of the given and returned SimpleNode are the domain of the - * calling method. - * - * @param root - * The SimpleNode to be simplified (if possible) - * @return A SimpleNode with constants reduced. - */ - public SimpleNode doConstantReplacement(SimpleNode root) - { - int childCount = root.jjtGetNumChildren(); - List<SimpleNode> constantChildren = new ArrayList<SimpleNode>(); - List<SimpleNode> variableChildren = new ArrayList<SimpleNode>(); - /* - * This assumes the first item is special, such that a?b?c is equivalent - * to a?c?b but not necessarily b?c?a where a, b, c, are constants and ? - * is the arithmetic operation. In this way, this class can be used for - * subtraction (without too much negative impact on addition & - * multiplication) - */ - List<List<SimpleNode>> nodeLists = new LinkedList<List<SimpleNode>>(); - SimpleNode first = (SimpleNode) root.jjtGetChild(0); - if (OperationUtilities.isConstant(first)) - { - nodeLists.add(constantChildren); - nodeLists.add(variableChildren); - } - else - { - nodeLists.add(variableChildren); - nodeLists.add(constantChildren); - } - - for (int i = 0; i < childCount; i++) - { - SimpleNode child = (SimpleNode) root.jjtGetChild(i); - if (OperationUtilities.isConstant(child)) - { - constantChildren.add(child); - } - else - { - variableChildren.add(child); - } - } - if (constantChildren.size() <= 1) - { - return root; - } - while (constantChildren.size() > 1) - { - String text1 = constantChildren.remove(0).getText(); - String text2 = constantChildren.remove(0).getText(); - constantChildren.add(getSimplifiedNode(text1, text2)); - } - SimpleNode constantNode = constantChildren.get(0); - if (variableChildren.isEmpty()) - { - return constantNode; - } - SimpleNode newNode = new SimpleNode(root.getID()); - newNode.setOperation(this); - int childNum = 0; - for (List<SimpleNode> list : nodeLists) - { - for (SimpleNode node : list) - { - newNode.jjtAddChild(node, childNum++); - } - } - return newNode; - } - public boolean areIntegers(String text1, String text2) { return (text1.indexOf(".") == -1 || text1.indexOf(".") == text1 @@ -158,5 +73,15 @@ .length()); } - protected abstract SimpleNode getSimplifiedNode(String text1, String text2); + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + for (int i = 1; i < node.jjtGetNumChildren(); i++) + { + writeString(mv, getSign()); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(i)); + } + } + + protected abstract String getSign(); } Added: sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractBinaryOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractBinaryOperation.java (rev 0) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractBinaryOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -0,0 +1,35 @@ +/* + * Copyright (c) Thomas Parker, 2005-2009. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This program 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.base.formula.core; + +import org.objectweb.asm.MethodVisitor; + +import pcgen.base.formula.parse.SimpleNode; + +public abstract class AbstractBinaryOperation extends AbstractFormulaOperation +{ + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + writeString(mv, getSign()); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(1)); + } + + protected abstract String getSign(); +} Added: sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractFormulaOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractFormulaOperation.java (rev 0) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractFormulaOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -0,0 +1,32 @@ +/* + * Copyright (c) Thomas Parker, 2005-2009. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This program 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.base.formula.core; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +public abstract class AbstractFormulaOperation implements FormulaOperation { + + public void writeString(MethodVisitor mv, String str) { + mv.visitVarInsn(Opcodes.ALOAD, 0); + mv.visitLdcInsn(str); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", + "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); + mv.visitInsn(Opcodes.POP); + } +} Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractOrderedOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractOrderedOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractOrderedOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -17,15 +17,12 @@ */ package pcgen.base.formula.core; -import java.util.LinkedList; -import java.util.List; - import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import pcgen.base.formula.parse.SimpleNode; -public abstract class AbstractOrderedOperation implements FormulaOperation +public abstract class AbstractOrderedOperation extends AbstractFormulaOperation { public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, @@ -56,60 +53,6 @@ protected abstract void performOperation(MethodVisitor mv, int loc); - /** - * Performs constant replacement on the SimpleNode given. This will return a - * SimpleNode which (if possible) reduces the given SimpleNode into a less - * complex operation. If both of the children of the given SimpleNode are - * constant, then the multiplication operation will be performed and a - * constant SimpleNode will be returned. - * - * If no simplification can be performed, then this method reserves the - * right to return a reference to the original SimpleNode. It is assumed - * that ownership of the given and returned SimpleNode are the domain of the - * calling method. - * - * @param root - * The SimpleNode to be simplified (if possible) - * @return A SimpleNode with constants reduced. - */ - public SimpleNode doConstantReplacement(SimpleNode root) - { - // Simplify only up to first variable... - SimpleNode child1 = (SimpleNode) root.jjtGetChild(0); - if (!OperationUtilities.isConstant(child1)) - { - return root; - } - List<SimpleNode> children = new LinkedList<SimpleNode>(); - for (int i = 1; i < root.jjtGetNumChildren(); i++) - { - children.add((SimpleNode) root.jjtGetChild(i)); - } - while (!children.isEmpty()) - { - SimpleNode child2 = children.remove(0); - if (!OperationUtilities.isConstant(child2)) - { - SimpleNode newNode = new SimpleNode(root.getID()); - newNode.setOperation(this); - newNode.jjtAddChild(child1, 0); - newNode.jjtAddChild(child2, 1); - int childNum = 2; - for (SimpleNode node : children) - { - newNode.jjtAddChild(node, childNum++); - } - return newNode; - } - String text1 = child1.getText(); - String text2 = child2.getText(); - child1 = getSimplifiedNode(text1, text2); - } - return child1; - } - - protected abstract SimpleNode getSimplifiedNode(String text1, String text2); - public boolean areIntegers(String text1, String text2) { return (text1.indexOf(".") == -1 || text1.indexOf(".") == text1 @@ -117,4 +60,16 @@ && (text2.indexOf(".") == -1 || text2.indexOf(".") == text2 .length()); } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + for (int i = 1; i < node.jjtGetNumChildren(); i++) + { + writeString(mv, getSign()); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(i)); + } + } + + protected abstract String getSign(); } Deleted: sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractSimpleAssociativeOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractSimpleAssociativeOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/AbstractSimpleAssociativeOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -1,49 +0,0 @@ -/* - * Copyright (c) Thomas Parker, 2005-2009. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at - * your option) any later version. - * - * This program 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 Lesser - * General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ -package pcgen.base.formula.core; - -import pcgen.base.formula.parse.SimpleNode; - -public abstract class AbstractSimpleAssociativeOperation extends AbstractAssociativeOperation -{ - - public AbstractSimpleAssociativeOperation(int instruction) - { - super(instruction); - } - - @Override - protected SimpleNode getSimplifiedNode(String text1, String text2) - { - if (areIntegers(text1, text2)) - { - int sum = process(Integer.parseInt(text1), Integer.parseInt(text2)); - return OperationUtilities.getIntegerNode(sum); - } - else - { - double sum = process(Double.parseDouble(text1), Double - .parseDouble(text2)); - return OperationUtilities.getDoubleNode(sum); - } - } - - protected abstract int process(int parseInt, int parseInt2); - - protected abstract double process(double parseInt, double parseInt2); -} Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/core/FormulaOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/FormulaOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/FormulaOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -18,46 +18,18 @@ package pcgen.base.formula.core; import org.objectweb.asm.MethodVisitor; + import pcgen.base.formula.parse.SimpleNode; /** * @author Thomas Parker (th...@us...) * * A FormulaOperation is an operation that can be performed on a Formula to be - * compiled. An operation must be capable of defining two potential operations. - * - * First, a FormulaOperation must be able to define when the FormulaOperation - * can be simplified. Simplification can occur if the FormulaOperation will - * always return an identical result. For example, An AddOperation for 1 + 3 - * will always return 4; thus, that AddOperation could be reduced to a - * ConstantOperation with a value of 4. It is recognized that some - * FormulaOperations may never be simplified. - * - * Second, a FormulaOperation must be able to define the Java bytecode to + * compiled. An operation must be capable of defining the Java bytecode to * perform the operation (by visiting an org.objectweb.asm.MethodVisitor). */ public interface FormulaOperation { - /** - * Evaluate the given SimpleNode and return a SimpleNode that is simplified - * to pre-calculate any constant nodes. Note that pre-calculation may not be - * possible. - * - * In any case, it is expected that this method will be reference-semantic. - * Therefore, if the given SimpleNode cannot be simplified, the - * implementation of doConstantReplacement may simply return the given - * SimpleNode. If a some simplification is possible, the implementation of - * doConstantReplacement may return a SimpleNode which is a child (or - * grandchild, etc.) of the given SimpleNode, or may return a new - * SimpleNode. No assumption should be made as to the existing relationship - * of the SimpleNode returned by this method. - * - * @param root - * The SimpleNode to be evaluated for constant nodes - * @return A SimpleNode which has been simplified to pre-calculate constant - * nodes. - */ - public SimpleNode doConstantReplacement(SimpleNode root); /** * Visits the Bytecode (in the ASM .visit* sense) to define a series of Java @@ -80,4 +52,6 @@ int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc); + void visitToString(NodeEvaluator ev, MethodVisitor mv, SimpleNode simpleNode); + } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/core/NodeEvaluator.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/NodeEvaluator.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/NodeEvaluator.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -31,4 +31,5 @@ public int evaluate(MethodVisitor mv, SimpleNode node, int loc); + public void stringify(MethodVisitor mv, SimpleNode node); } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/core/OperationUtilities.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/core/OperationUtilities.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/core/OperationUtilities.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -20,7 +20,6 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import pcgen.base.formula.operation.ConstantOperation; import pcgen.base.formula.parse.FormulaParserTreeConstants; import pcgen.base.formula.parse.SimpleNode; @@ -48,20 +47,4 @@ mv.visitInsn(Opcodes.DCMPL); return max; } - - public static SimpleNode getIntegerNode(int sum) - { - SimpleNode newNode = new SimpleNode(FormulaParserTreeConstants.JJTINT); - newNode.setToken(Integer.toString(sum)); - newNode.setOperation(ConstantOperation.getInstance()); - return newNode; - } - - public static SimpleNode getDoubleNode(double sum) - { - SimpleNode newNode = new SimpleNode(FormulaParserTreeConstants.JJTDBL); - newNode.setToken(Double.toString(sum)); - newNode.setOperation(ConstantOperation.getInstance()); - return newNode; - } } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/operation/ConstantOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/operation/ConstantOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/operation/ConstantOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -19,31 +19,12 @@ import org.objectweb.asm.MethodVisitor; -import pcgen.base.formula.core.FormulaOperation; +import pcgen.base.formula.core.AbstractFormulaOperation; import pcgen.base.formula.core.NodeEvaluator; import pcgen.base.formula.parse.SimpleNode; -public final class ConstantOperation implements FormulaOperation +public final class ConstantOperation extends AbstractFormulaOperation { - - /** - * Holds the instance of ConstantOperation - */ - private static ConstantOperation instance = null; - - /** - * Constructs a ConstantOperation - */ - private ConstantOperation() - { - super(); - } - - public SimpleNode doConstantReplacement(SimpleNode root) - { - return root; - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, SimpleNode node, int loc) { @@ -51,17 +32,8 @@ return loc + 2; } - /** - * Returns the ConstantOperation instance (Singleton Factory) - * - * @return The ConstantOperation instance - */ - public static ConstantOperation getInstance() - { - if (instance == null) - { - instance = new ConstantOperation(); - } - return instance; + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + writeString(mv, node.getText()); } } Added: sandbox/FormulaCompiler/src/pcgen/base/formula/operation/CountOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/operation/CountOperation.java (rev 0) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/operation/CountOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -0,0 +1,55 @@ +/* + * Copyright (c) Thomas Parker, 2005-2009. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This program 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.base.formula.operation; + +import org.objectweb.asm.MethodVisitor; + +import pcgen.base.formula.core.AbstractFormulaOperation; +import pcgen.base.formula.core.NodeEvaluator; +import pcgen.base.formula.parse.SimpleNode; + +public class CountOperation extends AbstractFormulaOperation { + + public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node, int loc) { + //TODO Dummy operation for now + mv.visitLdcInsn(1.0); + return loc + 2; + } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + SimpleNode firstChild = (SimpleNode) node.jjtGetChild(0); + if (firstChild.toString().equals("FParen")) + { + writeString(mv, "count"); + } + else + { + writeString(mv, "COUNT"); + } + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + int childCount = node.jjtGetNumChildren(); + for (int i = 1; i < childCount; i++) + { + writeString(mv, ","); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(i)); + } + } + +} Added: sandbox/FormulaCompiler/src/pcgen/base/formula/operation/GroupOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/operation/GroupOperation.java (rev 0) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/operation/GroupOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -0,0 +1,66 @@ +/* + * Copyright (c) Thomas Parker, 2005-2009. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This program 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 Lesser + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package pcgen.base.formula.operation; + +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import pcgen.base.formula.core.AbstractFormulaOperation; +import pcgen.base.formula.core.NodeEvaluator; +import pcgen.base.formula.parse.SimpleNode; + +public class GroupOperation extends AbstractFormulaOperation { + + private final String openGroup; + private final String closeGroup; + + public GroupOperation(String open, String close) { + openGroup = open; + closeGroup = close; + } + + public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node, int loc) { + // TODO Verify node has proper # of children + int max = ev.evaluate(mv, (SimpleNode) node.jjtGetChild(0), loc); + + int childCount = node.jjtGetNumChildren(); + for (int i = 1; i < childCount; i++) + { + SimpleNode rhs = (SimpleNode) node.jjtGetChild(i); + int rhsm = ev.evaluate(mv, rhs, loc + 2); + max = Math.max(max, rhsm); + } + mv.visitVarInsn(Opcodes.DLOAD, loc); + return max; + } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + writeString(mv, openGroup); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + int childCount = node.jjtGetNumChildren(); + for (int i = 1; i < childCount; i++) + { + writeString(mv, ","); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(i)); + } + writeString(mv, closeGroup); + } + +} Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/operation/IfOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/operation/IfOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/operation/IfOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -20,12 +20,12 @@ import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; -import pcgen.base.formula.core.FormulaOperation; + +import pcgen.base.formula.core.AbstractFormulaOperation; import pcgen.base.formula.core.NodeEvaluator; -import pcgen.base.formula.core.OperationUtilities; import pcgen.base.formula.parse.SimpleNode; -public class IfOperation implements FormulaOperation +public class IfOperation extends AbstractFormulaOperation { public IfOperation() @@ -60,26 +60,18 @@ return Math.max(Math.max(testm, trm), frm); } - public SimpleNode doConstantReplacement(SimpleNode root) - { - if (root.jjtGetNumChildren() != 3) + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + writeString(mv, "if("); + + ev.stringify(mv, (SimpleNode) node.jjtGetChild(0)); + int childCount = node.jjtGetNumChildren(); + for (int i = 1; i < childCount; i++) { - throw new IllegalArgumentException( - "OrOperation expects a JJTIF SimpleNode to contain 3 children"); + writeString(mv, ", "); + ev.stringify(mv, (SimpleNode) node.jjtGetChild(i)); } - SimpleNode child1 = (SimpleNode) root.jjtGetChild(0); - if (!OperationUtilities.isConstant(child1)) - { - return root; - } - if (Double.parseDouble(child1.getText()) == 0.0) - { - return (SimpleNode) root.jjtGetChild(2); - } - else - { - return (SimpleNode) root.jjtGetChild(1); - } - } + writeString(mv, ")"); + } } Modified: sandbox/FormulaCompiler/src/pcgen/base/formula/operation/NaryMethodOperation.java =================================================================== --- sandbox/FormulaCompiler/src/pcgen/base/formula/operation/NaryMethodOperation.java 2009-10-18 13:37:41 UTC (rev 10754) +++ sandbox/FormulaCompiler/src/pcgen/base/formula/operation/NaryMethodOperation.java 2009-10-18 18:21:46 UTC (rev 10755) @@ -17,22 +17,19 @@ */ package pcgen.base.formula.operation; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; -import pcgen.base.formula.core.FormulaOperation; +import pcgen.base.formula.core.AbstractFormulaOperation; import pcgen.base.formula.core.NodeEvaluator; -import pcgen.base.formula.core.OperationUtilities; +import pcgen.base.formula.parse.Node; import pcgen.base.formula.parse.SimpleNode; -public class NaryMethodOperation implements FormulaOperation +public class NaryMethodOperation extends AbstractFormulaOperation { private final String opClassName; @@ -80,83 +77,13 @@ this(Class.forName(className), method); } - public SimpleNode doConstantReplacement(SimpleNode root) - { - // TODO Verify node has proper # of children - int childCount = root.jjtGetNumChildren(); - int constantChildCount = 0; - int variableChildCount = 0; - for (int i = 1; i < childCount; i++) - { - if (OperationUtilities.isConstant((SimpleNode) root.jjtGetChild(i))) - { - constantChildCount++; - } - else - { - variableChildCount++; - } - } - if (constantChildCount <= 1) - { - return root; - } - SimpleNode newNode = new SimpleNode(root.getID()); - newNode.setOperation(this); - newNode.jjtAddChild(root.jjtGetChild(0), 0); - int childNum = 1; - List<SimpleNode> constantChildren = new ArrayList<SimpleNode>(); - for (int i = 1; i < childCount; i++) - { - SimpleNode child = (SimpleNode) root.jjtGetChild(i); - if (OperationUtilities.isConstant(child)) - { - constantChildren.add(child); - } - else - { - newNode.jjtAddChild(child, childNum++); - } - } - String text1 = constantChildren.get(0).getText(); - Double d1 = Double.valueOf(text1); - for (int i = 1; i < constantChildren.size(); i++) - { - String text2 = constantChildren.get(i).getText(); - Double d2 = Double.valueOf(text2); - try - { - Double retValue = (Double) opMethod.invoke(null, new Object[] { - d1, d2 }); - d1 = retValue; - } - catch (IllegalArgumentException e) - { - e.printStackTrace(); - } - catch (IllegalAccessException e) - { - e.printStackTrace(); - } - catch (InvocationTargetException e) - { - e.printStackTrace(); - } - } - SimpleNode constantNode = OperationUtilities.getDoubleNode(d1 - .doubleValue()); - if (variableChildCount == 0) - { - return constantNode; - } - newNode.jjtAddChild(constantNode, childNum); - return newNode; - } - public int visitBytecode(NodeEvaluator ev, MethodVisitor mv, - SimpleNode node, int loc) + SimpleNode sn, int loc) { + // TODO Verify sn has proper # of children + // node is the group (formed from the parens) // TODO Verify node has proper # of children + Node node = sn.jjtGetChild(0); SimpleNode lhs = (SimpleNode) node.jjtGetChild(0); int max = ev.evaluate(mv, lhs, loc); int childCount = node.jjtGetNumChildren(); @@ -182,4 +109,17 @@ { return "NaryOperation: " + opMethod; } + + public void visitToString(NodeEvaluator ev, MethodVisitor mv, + SimpleNode node) { + writeString(m... [truncated message content] |