diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-11-03 15:15:03 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-11-03 15:15:03 -0500 |
| commit | f656c9eb26154c206915f5f643d88f805315d3b0 (patch) | |
| tree | 226dadba169435d74713905a972c0df6749978b1 | |
| parent | 87176ead2de2b0eb396d75555b3ed2bd5783ce8d (diff) | |
Better error messaging for binops and support for bit shifting by an
integer literal (without a bit size)
| -rw-r--r-- | compile.c | 31 |
1 files changed, 22 insertions, 9 deletions
@@ -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: { |
