1/*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License.  Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 */
15
16package javassist.compiler.ast;
17
18import javassist.compiler.CompileError;
19import javassist.compiler.TokenId;
20
21/**
22 * Integer constant.
23 */
24public class IntConst extends ASTree {
25    protected long value;
26    protected int type;
27
28    public IntConst(long v, int tokenId) { value = v; type = tokenId; }
29
30    public long get() { return value; }
31
32    public void set(long v) { value = v; }
33
34    /* Returns IntConstant, CharConstant, or LongConstant.
35     */
36    public int getType() { return type; }
37
38    public String toString() { return Long.toString(value); }
39
40    public void accept(Visitor v) throws CompileError {
41        v.atIntConst(this);
42    }
43
44    public ASTree compute(int op, ASTree right) {
45        if (right instanceof IntConst)
46            return compute0(op, (IntConst)right);
47        else if (right instanceof DoubleConst)
48            return compute0(op, (DoubleConst)right);
49        else
50            return null;
51    }
52
53    private IntConst compute0(int op, IntConst right) {
54        int type1 = this.type;
55        int type2 = right.type;
56        int newType;
57        if (type1 == TokenId.LongConstant || type2 == TokenId.LongConstant)
58            newType = TokenId.LongConstant;
59        else if (type1 == TokenId.CharConstant
60                 && type2 == TokenId.CharConstant)
61            newType = TokenId.CharConstant;
62        else
63            newType = TokenId.IntConstant;
64
65        long value1 = this.value;
66        long value2 = right.value;
67        long newValue;
68        switch (op) {
69        case '+' :
70            newValue = value1 + value2;
71            break;
72        case '-' :
73            newValue = value1 - value2;
74            break;
75        case '*' :
76            newValue = value1 * value2;
77            break;
78        case '/' :
79            newValue = value1 / value2;
80            break;
81        case '%' :
82            newValue = value1 % value2;
83            break;
84        case '|' :
85            newValue = value1 | value2;
86            break;
87        case '^' :
88            newValue = value1 ^ value2;
89            break;
90        case '&' :
91            newValue = value1 & value2;
92            break;
93        case TokenId.LSHIFT :
94            newValue = value << (int)value2;
95            newType = type1;
96            break;
97        case TokenId.RSHIFT :
98            newValue = value >> (int)value2;
99            newType = type1;
100            break;
101        case TokenId.ARSHIFT :
102            newValue = value >>> (int)value2;
103            newType = type1;
104            break;
105        default :
106            return null;
107        }
108
109        return new IntConst(newValue, newType);
110    }
111
112    private DoubleConst compute0(int op, DoubleConst right) {
113        double value1 = (double)this.value;
114        double value2 = right.value;
115        double newValue;
116        switch (op) {
117        case '+' :
118            newValue = value1 + value2;
119            break;
120        case '-' :
121            newValue = value1 - value2;
122            break;
123        case '*' :
124            newValue = value1 * value2;
125            break;
126        case '/' :
127            newValue = value1 / value2;
128            break;
129        case '%' :
130            newValue = value1 % value2;
131            break;
132        default :
133            return null;
134        }
135
136        return new DoubleConst(newValue, right.type);
137    }
138}
139