001    package railo.transformer.bytecode.statement.java;
002    
003    import org.objectweb.asm.Type;
004    import org.objectweb.asm.commons.GeneratorAdapter;
005    
006    import railo.transformer.bytecode.BytecodeContext;
007    import railo.transformer.bytecode.BytecodeException;
008    import railo.transformer.bytecode.expression.ExpressionBase;
009    import railo.transformer.bytecode.util.Types;
010    
011    public class UnaryOp extends ExpressionBase {
012    
013            private DataBag db;
014            private Object operant;
015            private String operation;
016    
017            public UnaryOp(int line,Object operant, String operation, DataBag db) {
018                    super(line);
019                    this.operant=operant;
020                    this.operation=operation;
021                    this.db = db;
022            }
023    
024            public Type _writeOut(BytecodeContext bc, int mode) throws BytecodeException {
025                    
026                    Integer var=db.locals.get(operant);
027                    if(var==null)
028                            throw new BytecodeException("there is no variable with name ["+operation+"] in the enviroment", getLine());
029                    
030                    GeneratorAdapter a = bc.getAdapter();
031                    
032                    if(operation.startsWith("pos")) a.loadLocal(var.intValue());
033                    if("preDecrement".equals(operation))a.iinc(var.intValue(), -1);
034                    else if("posDecrement".equals(operation))a.iinc(var.intValue(), -1);
035                    else if("preIncrement".equals(operation))a.iinc(var.intValue(), 1);
036                    else if("posIncrement".equals(operation))a.iinc(var.intValue(), 1);
037                    if(operation.startsWith("pre")) a.loadLocal(var.intValue());
038                    
039                    return a.getLocalType(var.intValue());
040            }
041    
042            public static Type result(Type left, Type right) {
043                    if(left==Types.DOUBLE_VALUE || right==Types.DOUBLE_VALUE) return Types.DOUBLE_VALUE;
044                    if(left==Types.FLOAT_VALUE || right==Types.FLOAT_VALUE) return Types.FLOAT_VALUE;
045                    if(left==Types.LONG_VALUE || right==Types.LONG_VALUE) return Types.LONG_VALUE;
046                    if(left==Types.INT_VALUE || right==Types.INT_VALUE) return Types.INT_VALUE;
047                    if(left==Types.SHORT_VALUE || right==Types.SHORT_VALUE) return Types.SHORT_VALUE;
048                    
049                    return Types.CHAR;
050            }
051    
052            public static void dup(BytecodeContext bc, Type t) {
053                    String cn=t.getClassName();
054                    if(cn.equals("long") || cn.equals("double")) bc.getAdapter().dup2();
055                    else bc.getAdapter().dup();
056            }
057    
058            
059            
060    }