001    package railo.transformer.bytecode.op;
002    
003    import org.objectweb.asm.Opcodes;
004    import org.objectweb.asm.Type;
005    import org.objectweb.asm.commons.GeneratorAdapter;
006    
007    import railo.runtime.exp.TemplateException;
008    import railo.transformer.bytecode.BytecodeContext;
009    import railo.transformer.bytecode.BytecodeException;
010    import railo.transformer.bytecode.Literal;
011    import railo.transformer.bytecode.Position;
012    import railo.transformer.bytecode.cast.CastDouble;
013    import railo.transformer.bytecode.expression.ExprDouble;
014    import railo.transformer.bytecode.expression.Expression;
015    import railo.transformer.bytecode.expression.ExpressionBase;
016    import railo.transformer.bytecode.literal.LitDouble;
017    import railo.transformer.bytecode.util.Methods;
018    import railo.transformer.bytecode.util.Types;
019    
020    public final class OpNegateNumber extends ExpressionBase implements ExprDouble {
021    
022            private ExprDouble expr;
023            
024    
025            public static final int PLUS = 0;
026            public static final int MINUS = 1;
027    
028            private OpNegateNumber(Expression expr, Position start, Position end) {
029            super(start,end);
030            this.expr=CastDouble.toExprDouble(expr);
031        }
032        
033        /**
034         * Create a String expression from a Expression
035         * @param left 
036         * @param right 
037         * 
038         * @return String expression
039         * @throws TemplateException 
040         */
041        public static ExprDouble toExprDouble(Expression expr, Position start, Position end) {
042            if(expr instanceof Literal) {
043                    Double d=((Literal) expr).getDouble(null);
044                    if(d!=null) {
045                            return LitDouble.toExprDouble(-d.doubleValue(),start,end);
046                    }
047            }
048            return new OpNegateNumber(expr,start,end);
049        }
050        
051        public static ExprDouble toExprDouble(Expression expr, int operation, Position start, Position end) {
052            if(operation==MINUS) return toExprDouble(expr, start,end);
053            return CastDouble.toExprDouble(expr);
054        }
055            
056            
057            /**
058             *
059             * @see railo.transformer.bytecode.expression.ExpressionBase#_writeOut(org.objectweb.asm.commons.GeneratorAdapter, int)
060             */
061            public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
062                    GeneratorAdapter adapter = bc.getAdapter();
063            if(mode==MODE_REF) {
064                _writeOut(bc,MODE_VALUE);
065                adapter.invokeStatic(Types.CASTER,Methods.METHOD_TO_DOUBLE_FROM_DOUBLE);
066                return Types.DOUBLE;
067            }
068            
069            expr.writeOut(bc, MODE_VALUE);
070            adapter.visitInsn(Opcodes.DNEG);
071            
072    
073            return Types.DOUBLE_VALUE;
074            }
075    }