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}