Better error messaging for binops and support for bit shifting by an
integer literal (without a bit size)
This commit is contained in:
parent
87176ead2d
commit
f656c9eb26
31
compile.c
31
compile.c
@ -2049,8 +2049,21 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
}
|
||||
|
||||
CORD lhs = compile(env, binop->lhs);
|
||||
|
||||
// Special case for bit shifting by an integer literal:
|
||||
if (binop->op == BINOP_LSHIFT || binop->op == BINOP_RSHIFT) {
|
||||
if (lhs_t->tag == IntType && rhs_t->tag == BigIntType && binop->rhs->tag == Int) {
|
||||
CORD shift_amount = compile_int_to_type(env, binop->rhs, lhs_t);
|
||||
if (binop->op == BINOP_LSHIFT)
|
||||
return CORD_all("(", lhs, " << ", shift_amount, ")");
|
||||
else
|
||||
return CORD_all("(", lhs, " >> ", shift_amount, ")");
|
||||
}
|
||||
}
|
||||
|
||||
CORD rhs = compile(env, binop->rhs);
|
||||
type_t *operand_t;
|
||||
|
||||
if (promote(env, &rhs, rhs_t, lhs_t))
|
||||
operand_t = lhs_t;
|
||||
else if (promote(env, &lhs, lhs_t, rhs_t))
|
||||
@ -2061,7 +2074,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
switch (binop->op) {
|
||||
case BINOP_POWER: {
|
||||
if (operand_t->tag != NumType)
|
||||
code_err(ast, "Exponentiation is only supported for Num types");
|
||||
code_err(ast, "Exponentiation is only supported for Num types, not %T", operand_t);
|
||||
if (operand_t->tag == NumType && Match(operand_t, NumType)->bits == TYPE_NBITS32)
|
||||
return CORD_all("powf(", lhs, ", ", rhs, ")");
|
||||
else
|
||||
@ -2069,42 +2082,42 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
}
|
||||
case BINOP_MULT: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " * ", rhs, ")");
|
||||
}
|
||||
case BINOP_DIVIDE: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " / ", rhs, ")");
|
||||
}
|
||||
case BINOP_MOD: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " % ", rhs, ")");
|
||||
}
|
||||
case BINOP_MOD1: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("((((", lhs, ")-1) % (", rhs, ")) + 1)");
|
||||
}
|
||||
case BINOP_PLUS: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " + ", rhs, ")");
|
||||
}
|
||||
case BINOP_MINUS: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " - ", rhs, ")");
|
||||
}
|
||||
case BINOP_LSHIFT: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " << ", rhs, ")");
|
||||
}
|
||||
case BINOP_RSHIFT: {
|
||||
if (operand_t->tag != IntType && operand_t->tag != NumType && operand_t->tag != ByteType)
|
||||
code_err(ast, "Math operations are only supported for numeric types");
|
||||
code_err(ast, "Math operations are only supported for values of the same numeric type, not %T vs %T", lhs_t, rhs_t);
|
||||
return CORD_all("(", lhs, " >> ", rhs, ")");
|
||||
}
|
||||
case BINOP_EQ: {
|
||||
|
Loading…
Reference in New Issue
Block a user