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.op; 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.Position; 026import lucee.transformer.bytecode.cast.CastDouble; 027import lucee.transformer.bytecode.expression.ExprDouble; 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.Opcodes; 035import org.objectweb.asm.Type; 036import org.objectweb.asm.commons.GeneratorAdapter; 037 038public final class OpNegateNumber extends ExpressionBase implements ExprDouble { 039 040 private ExprDouble expr; 041 042 043 public static final int PLUS = 0; 044 public static final int MINUS = 1; 045 046 private OpNegateNumber(Expression expr, Position start, Position end) { 047 super(start,end); 048 this.expr=CastDouble.toExprDouble(expr); 049 } 050 051 /** 052 * Create a String expression from a Expression 053 * @param left 054 * @param right 055 * 056 * @return String expression 057 * @throws TemplateException 058 */ 059 public static ExprDouble toExprDouble(Expression expr, Position start, Position end) { 060 if(expr instanceof Literal) { 061 Double d=((Literal) expr).getDouble(null); 062 if(d!=null) { 063 return LitDouble.toExprDouble(-d.doubleValue(),start,end); 064 } 065 } 066 return new OpNegateNumber(expr,start,end); 067 } 068 069 public static ExprDouble toExprDouble(Expression expr, int operation, Position start, Position end) { 070 if(operation==MINUS) return toExprDouble(expr, start,end); 071 return CastDouble.toExprDouble(expr); 072 } 073 074 075 /** 076 * 077 * @see lucee.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int) 078 */ 079 public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException { 080 GeneratorAdapter adapter = bc.getAdapter(); 081 if(mode==MODE_REF) { 082 _writeOut(bc,MODE_VALUE); 083 adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE); 084 return Types.DOUBLE; 085 } 086 087 expr.writeOut(bc, MODE_VALUE); 088 adapter.visitInsn(Opcodes.DNEG); 089 090 091 return Types.DOUBLE_VALUE; 092 } 093}