001/*
002 * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003 *
004 * This file is part of
005 * CleanSheets - a spreadsheet application for the Java platform.
006 *
007 * CleanSheets is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 2 of the License, or
010 * (at your option) any later version.
011 *
012 * CleanSheets is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with CleanSheets; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020 */
021package csheets.core.formula.util;
022        
023import csheets.core.formula.BinaryOperation;
024import csheets.core.formula.Expression;
025import csheets.core.formula.FunctionCall;
026import csheets.core.formula.Literal;
027import csheets.core.formula.Reference;
028import csheets.core.formula.UnaryOperation;
029import csheets.core.formula.compiler.IllegalFunctionCallException;
030import csheets.core.formula.lang.CellReference;
031import csheets.core.formula.lang.ReferenceOperation;
032
033/**
034 * A base-class for classes that rebuild expressions. In this form, it simply
035 * copies expressions.
036 * @author Einar Pehrson
037 */
038public class ExpressionBuilder implements ExpressionVisitor {
039
040        /**
041         * Creates a new expression builder.
042         */
043        public ExpressionBuilder() {}
044
045        /**
046         * Returns a copy of the given expression.
047         * @param expression the expression to rebuild
048         * @return the rebuilt expression
049         */
050        public Expression getExpression(Expression expression) {
051                return (Expression)expression.accept(this);
052        }
053
054        public Expression visitLiteral(Literal literal) {
055                return new Literal(literal.getValue());
056        }
057
058        public Expression visitUnaryOperation(UnaryOperation operation) {
059                Expression operand = (Expression)operation.getOperand().accept(this);
060                return new UnaryOperation(operation.getOperator(), operand);
061        }
062
063        public Expression visitBinaryOperation(BinaryOperation operation) {
064                Expression leftOperand = (Expression)operation.getLeftOperand().accept(this);
065                Expression rightOperand = (Expression)operation.getRightOperand().accept(this);
066                return new BinaryOperation(leftOperand, operation.getOperator(), rightOperand);
067        }
068
069        public Expression visitReference(Reference reference) {
070                if (reference instanceof CellReference) {
071                        CellReference cellRef = (CellReference)reference;
072                        return new CellReference(cellRef.getCell(),
073                                cellRef.isColumnAbsolute(), cellRef.isRowAbsolute());
074                } else {
075                        ReferenceOperation refOp = (ReferenceOperation)reference;
076                        return new ReferenceOperation(
077                                (Reference)refOp.getLeftOperand().accept(this),
078                                refOp.getOperator(),
079                                (Reference)refOp.getRightOperand().accept(this));
080                }
081        }
082
083        public Expression visitFunctionCall(FunctionCall call) {
084                Expression[] arguments = call.getArguments();
085                Expression[] newArguments = new Expression[arguments.length];
086                int i = 0;
087                for (Expression argument : arguments)
088                        newArguments[i++] = (Expression)argument.accept(this);
089                try {
090                        return new FunctionCall(call.getFunction(), newArguments);
091                } catch (IllegalFunctionCallException e) {
092                        // Doesn't happen
093                        return null;
094                }
095        }
096}