001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2006-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.calc.impl; 011 012import mondrian.calc.*; 013import mondrian.olap.*; 014import mondrian.olap.type.*; 015 016import java.util.List; 017 018/** 019 * Enhanced expression compiler. It can generate code to convert between 020 * scalar types. 021 * 022 * @author jhyde 023 * @since Sep 29, 2005 024 */ 025public class BetterExpCompiler extends AbstractExpCompiler { 026 public BetterExpCompiler(Evaluator evaluator, Validator validator) { 027 super(evaluator, validator); 028 } 029 030 public BetterExpCompiler( 031 Evaluator evaluator, 032 Validator validator, 033 List<ResultStyle> resultStyles) 034 { 035 super(evaluator, validator, resultStyles); 036 } 037 038 public TupleCalc compileTuple(Exp exp) { 039 final Calc calc = compile(exp); 040 final Type type = exp.getType(); 041 if (type instanceof TupleType) { 042 assert calc instanceof TupleCalc; 043 return (TupleCalc) calc; 044 } else if (type instanceof MemberType) { 045 assert calc instanceof MemberCalc; 046 final MemberCalc memberCalc = (MemberCalc) calc; 047 return new AbstractTupleCalc(exp, new Calc[] {memberCalc}) { 048 public Member[] evaluateTuple(Evaluator evaluator) { 049 return new Member[] {memberCalc.evaluateMember(evaluator)}; 050 } 051 }; 052 } else { 053 throw Util.newInternal("cannot cast " + exp); 054 } 055 } 056 057 public ListCalc compileList(Exp exp, boolean mutable) { 058 final ListCalc listCalc = super.compileList(exp, mutable); 059 if (mutable && listCalc.getResultStyle() == ResultStyle.LIST) { 060 // Wrap the expression in an expression which creates a mutable 061 // copy. 062 return new CopyListCalc(listCalc); 063 } 064 return listCalc; 065 } 066 067 private static class CopyListCalc extends AbstractListCalc { 068 private final ListCalc listCalc; 069 070 public CopyListCalc(ListCalc listCalc) { 071 super(new DummyExp(listCalc.getType()), new Calc[]{listCalc}); 072 this.listCalc = listCalc; 073 } 074 075 public TupleList evaluateList(Evaluator evaluator) { 076 TupleList list = listCalc.evaluateList(evaluator); 077 return list.cloneList(-1); 078 } 079 } 080} 081 082// End BetterExpCompiler.java