diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-02-17 20:25:31 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-02-17 20:25:31 -0500 |
| commit | 6fcc7840d1d46e45579045e3452f0e884576a31b (patch) | |
| tree | 212840ccc14c5f513a89bf31d477c5b9928a3f86 /compile.c | |
| parent | 7cbd20062472012caee73f6a438978be97d2ace2 (diff) | |
Clean up more binops
Diffstat (limited to 'compile.c')
| -rw-r--r-- | compile.c | 73 |
1 files changed, 62 insertions, 11 deletions
@@ -68,14 +68,46 @@ CORD compile(env_t *env, ast_t *ast) code_err(ast, "I can't do binary operations between %T and %T", lhs_t, rhs_t); switch (binop->op) { - case BINOP_MULT: return CORD_asprintf("(%r * %r)", lhs, rhs); - case BINOP_DIVIDE: return CORD_asprintf("(%r / %r)", lhs, rhs); - case BINOP_MOD: return CORD_asprintf("mod(%r, %r)", lhs, rhs); - case BINOP_MOD1: return CORD_asprintf("mod1(%r, %r)", lhs, rhs); - case BINOP_PLUS: return CORD_asprintf("(%r + %r)", lhs, rhs); - case BINOP_MINUS: return CORD_asprintf("(%r - %r)", lhs, rhs); - case BINOP_LSHIFT: return CORD_asprintf("(%r << %r)", lhs, rhs); - case BINOP_RSHIFT: return CORD_asprintf("(%r >> %r)", lhs, rhs); + case BINOP_MULT: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("(%r * %r)", lhs, rhs); + } + case BINOP_DIVIDE: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("(%r / %r)", lhs, rhs); + } + case BINOP_MOD: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("mod(%r, %r)", lhs, rhs); + } + case BINOP_MOD1: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("mod1(%r, %r)", lhs, rhs); + } + case BINOP_PLUS: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("(%r + %r)", lhs, rhs); + } + case BINOP_MINUS: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("(%r - %r)", lhs, rhs); + } + case BINOP_LSHIFT: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("(%r << %r)", lhs, rhs); + } + case BINOP_RSHIFT: { + if (operand_t->tag != IntType && operand_t->tag != NumType) + code_err(ast, "Math operations are only supported for numeric types"); + return CORD_asprintf("(%r >> %r)", lhs, rhs); + } case BINOP_EQ: { switch (operand_t->tag) { case BoolType: case IntType: case NumType: case PointerType: case FunctionType: @@ -124,9 +156,28 @@ CORD compile(env_t *env, ast_t *ast) return CORD_asprintf("(generic_compare($stack(%r), $stack(%r), %r) >= 0)", lhs, rhs, compile_type_info(env, operand_t)); } } - case BINOP_AND: return CORD_asprintf("and(%r, %r)", lhs, rhs); - case BINOP_OR: return CORD_asprintf("or(%r, %r)", lhs, rhs); - case BINOP_XOR: return CORD_asprintf("xor(%r, %r)", lhs, rhs); + case BINOP_AND: { + if (operand_t->tag == BoolType) + return CORD_asprintf("(%r && %r)", lhs, rhs); + else if (operand_t->tag == IntType) + return CORD_asprintf("(%r & %r)", lhs, rhs); + else + code_err(ast, "Boolean operators are only supported for Bool and integer types"); + } + case BINOP_OR: { + if (operand_t->tag == BoolType) + return CORD_asprintf("(%r || %r)", lhs, rhs); + else if (operand_t->tag == IntType) + return CORD_asprintf("(%r | %r)", lhs, rhs); + else + code_err(ast, "Boolean operators are only supported for Bool and integer types"); + } + case BINOP_XOR: { + if (operand_t->tag == BoolType || operand_t->tag == IntType) + return CORD_asprintf("(%r ^ %r)", lhs, rhs); + else + code_err(ast, "Boolean operators are only supported for Bool and integer types"); + } default: break; } code_err(ast, "unimplemented binop"); |
