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