public void atBinExpr(BinExpr expr) throws CompileError { int token = expr.getOperator(); /* arithmetic operators: +, -, *, /, %, |, ^, &, <<, >>, >>> */ int k = lookupBinOp(token); if (k >= 0) { expr.oprand1().accept(this); ASTree right = expr.oprand2(); if (right == null) return; // see TypeChecker.atBinExpr(). int type1 = exprType; int dim1 = arrayDim; String cname1 = className; right.accept(this); if (dim1 != arrayDim) throw new CompileError("incompatible array types"); if (token == '+' && dim1 == 0 && (type1 == CLASS || exprType == CLASS)) atStringConcatExpr(expr, type1, dim1, cname1); else atArithBinExpr(expr, token, k, type1); } else { /* equation: &&, ||, ==, !=, <=, >=, <, > */ if (!booleanExpr(true, expr)) { bytecode.addIndex(7); bytecode.addIconst(0); // false bytecode.addOpcode(Opcode.GOTO); bytecode.addIndex(4); } bytecode.addIconst(1); // true } }
public void atKeyword(Keyword k) throws CompileError { arrayDim = 0; int token = k.get(); switch (token) { case TRUE: bytecode.addIconst(1); exprType = BOOLEAN; break; case FALSE: bytecode.addIconst(0); exprType = BOOLEAN; break; case NULL: bytecode.addOpcode(ACONST_NULL); exprType = NULL; break; case THIS: case SUPER: if (inStaticMethod) throw new CompileError("not-available: " + (token == THIS ? "this" : "super")); bytecode.addAload(0); exprType = CLASS; if (token == THIS) className = getThisName(); else className = getSuperName(); break; default: fatal(); } }
public void atExpr(Expr expr) throws CompileError { // array access, member access, // (unary) +, (unary) -, ++, --, !, ~ int token = expr.getOperator(); ASTree oprand = expr.oprand1(); if (token == '.') { String member = ((Symbol) expr.oprand2()).get(); if (member.equals("class")) atClassObject(expr); // .class else atFieldRead(expr); } else if (token == MEMBER) { // field read /* MEMBER ('#') is an extension by Javassist. * The compiler internally uses # for compiling .class * expressions such as "int.class". */ atFieldRead(expr); } else if (token == ARRAY) atArrayRead(oprand, expr.oprand2()); else if (token == PLUSPLUS || token == MINUSMINUS) atPlusPlus(token, oprand, expr, true); else if (token == '!') { if (!booleanExpr(false, expr)) { bytecode.addIndex(7); bytecode.addIconst(1); bytecode.addOpcode(Opcode.GOTO); bytecode.addIndex(4); } bytecode.addIconst(0); } else if (token == CALL) // method call fatal(); else { expr.oprand1().accept(this); int type = typePrecedence(exprType); if (arrayDim > 0) badType(expr); if (token == '-') { if (type == P_DOUBLE) bytecode.addOpcode(DNEG); else if (type == P_FLOAT) bytecode.addOpcode(FNEG); else if (type == P_LONG) bytecode.addOpcode(LNEG); else if (type == P_INT) { bytecode.addOpcode(INEG); exprType = INT; // type may be BYTE, ... } else badType(expr); } else if (token == '~') { if (type == P_INT) { bytecode.addIconst(-1); bytecode.addOpcode(IXOR); exprType = INT; // type may be BYTE. ... } else if (type == P_LONG) { bytecode.addLconst(-1); bytecode.addOpcode(LXOR); } else badType(expr); } else if (token == '+') { if (type == P_OTHER) badType(expr); // do nothing. ignore. } else fatal(); } }
public void atIntConst(IntConst i) throws CompileError { arrayDim = 0; long value = i.get(); int type = i.getType(); if (type == IntConstant || type == CharConstant) { exprType = (type == IntConstant ? INT : CHAR); bytecode.addIconst((int) value); } else { exprType = LONG; bytecode.addLconst(value); } }
protected void atPlusPlusCore(int dup_code, boolean doDup, int token, boolean isPost, Expr expr) throws CompileError { int t = exprType; if (doDup && isPost) bytecode.addOpcode(dup_code); if (t == INT || t == BYTE || t == CHAR || t == SHORT) { bytecode.addIconst(1); bytecode.addOpcode(token == PLUSPLUS ? IADD : ISUB); exprType = INT; } else if (t == LONG) { bytecode.addLconst((long) 1); bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB); } else if (t == FLOAT) { bytecode.addFconst(1.0f); bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB); } else if (t == DOUBLE) { bytecode.addDconst(1.0); bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB); } else badType(expr); if (doDup && !isPost) bytecode.addOpcode(dup_code); }
int compile(Bytecode code) throws CannotCompileException { code.addIconst(param); return 1; }