001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.bytecode.cast;
020
021import lucee.runtime.exp.TemplateException;
022import lucee.transformer.bytecode.BytecodeContext;
023import lucee.transformer.bytecode.BytecodeException;
024import lucee.transformer.bytecode.Literal;
025import lucee.transformer.bytecode.expression.ExprBoolean;
026import lucee.transformer.bytecode.expression.ExprDouble;
027import lucee.transformer.bytecode.expression.ExprString;
028import lucee.transformer.bytecode.expression.Expression;
029import lucee.transformer.bytecode.expression.ExpressionBase;
030import lucee.transformer.bytecode.literal.LitDouble;
031import lucee.transformer.bytecode.util.Methods;
032import lucee.transformer.bytecode.util.Types;
033
034import org.objectweb.asm.Type;
035import org.objectweb.asm.commons.GeneratorAdapter;
036import org.objectweb.asm.commons.Method;
037
038/**
039 * cast a Expression to a Double
040 */
041public final class CastDouble extends ExpressionBase implements ExprDouble,Cast {
042    
043    private Expression expr;
044    
045    private CastDouble(Expression expr) {
046        super(expr.getStart(),expr.getEnd());
047        this.expr=expr;
048    }
049    
050    /**
051     * Create a String expression from a Expression
052     * @param expr
053     * @return String expression
054     * @throws TemplateException 
055     */
056    public static ExprDouble toExprDouble(Expression expr)  {
057        if(expr instanceof ExprDouble) return (ExprDouble) expr;
058        if(expr instanceof Literal) {
059            Double dbl = ((Literal)expr).getDouble(null);
060            if(dbl!=null) return LitDouble.toExprDouble(dbl.doubleValue(),expr.getStart(),expr.getEnd());
061        }
062        return new CastDouble(expr);
063    }
064
065    /**
066     * @see lucee.transformer.bytecode.expression.Expression#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
067     */
068    public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
069
070        GeneratorAdapter adapter = bc.getAdapter();
071        if(expr instanceof ExprBoolean) {
072            expr.writeOut(bc,MODE_VALUE);
073            if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_BOOLEAN);
074            else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_BOOLEAN);
075        }
076        else if(expr instanceof ExprDouble) {
077            expr.writeOut(bc,mode);
078            //if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_DOUBLE);
079            //if(mode==MODE_REF) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE);
080        }
081        else if(expr instanceof ExprString) {
082            expr.writeOut(bc,MODE_REF);
083            if(mode==MODE_VALUE)adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_STRING);
084            else adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_STRING);
085        }
086        else {
087                Type rtn = expr.writeOut(bc,mode);
088                if(mode==MODE_VALUE) {
089                        if(!Types.isPrimitiveType(rtn)) {
090                                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE);
091                        }
092                        else if(Types.DOUBLE_VALUE.equals(rtn)) {}
093                        else if(Types.BOOLEAN_VALUE.equals(rtn))        {
094                                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE_FROM_BOOLEAN);
095                        }
096                        else {
097                                adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn}));
098                                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_VALUE);
099                        }
100                        return Types.DOUBLE_VALUE;
101                }
102                else if(Types.isPrimitiveType(rtn))     {
103                        if(Types.DOUBLE_VALUE.equals(rtn))      {
104                                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE);
105                        }
106                        else if(Types.BOOLEAN_VALUE.equals(rtn))        {
107                                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_BOOLEAN);
108                        }
109                        else {
110                                adapter.invokeStatic(Types.CASTER,new Method("toRef",Types.toRefType(rtn),new Type[]{rtn}));
111                                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE);
112                        }
113                        return Types.DOUBLE;
114                }
115                //else {
116                if(!Types.DOUBLE.equals(rtn)) adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE);
117                return Types.DOUBLE;
118                //}
119        }
120        
121
122        if(mode==MODE_VALUE)return Types.DOUBLE_VALUE;
123        return Types.DOUBLE;
124    }
125
126        @Override
127        public Expression getExpr() {
128                return expr;
129        }
130
131}
132
133
134
135