/* arrayDim values of the two oprands must be equal. * If an oprand type is not a numeric type, this method * throws an exception. */ private void atArithBinExpr(Expr expr, int token, int index, int type1) throws CompileError { if (arrayDim != 0) badTypes(expr); int type2 = exprType; if (token == LSHIFT || token == RSHIFT || token == ARSHIFT) if (type2 == INT || type2 == SHORT || type2 == CHAR || type2 == BYTE) exprType = type1; else badTypes(expr); else convertOprandTypes(type1, type2, expr); int p = typePrecedence(exprType); if (p >= 0) { int op = binOp[index + p + 1]; if (op != NOP) { if (p == P_INT && exprType != BOOLEAN) exprType = INT; // type1 may be BYTE, ... bytecode.addOpcode(op); return; } } badTypes(expr); }
/* Produces the opcode to branch if the condition is true. * The oprands are not produced. * * Parameter expr - compare expression ==, !=, <=, >=, <, > */ private void compareExpr(boolean branchIf, int token, int type1, BinExpr expr) throws CompileError { if (arrayDim == 0) convertOprandTypes(type1, exprType, expr); int p = typePrecedence(exprType); if (p == P_OTHER || arrayDim > 0) if (token == EQ) bytecode.addOpcode(branchIf ? IF_ACMPEQ : IF_ACMPNE); else if (token == NEQ) bytecode.addOpcode(branchIf ? IF_ACMPNE : IF_ACMPEQ); else badTypes(expr); else if (p == P_INT) { int op[] = ifOp; for (int i = 0; i < op.length; i += 3) if (op[i] == token) { bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]); return; } badTypes(expr); } else { if (p == P_DOUBLE) if (token == '<' || token == LE) bytecode.addOpcode(DCMPG); else bytecode.addOpcode(DCMPL); else if (p == P_FLOAT) if (token == '<' || token == LE) bytecode.addOpcode(FCMPG); else bytecode.addOpcode(FCMPL); else if (p == P_LONG) bytecode.addOpcode(LCMP); // 1: >, 0: =, -1: < else fatal(); int[] op = ifOp2; for (int i = 0; i < op.length; i += 3) if (op[i] == token) { bytecode.addOpcode(op[i + (branchIf ? 1 : 2)]); return; } badTypes(expr); } }