Compiles a comparison between `test` and `rhs`, leaving the boolean result in `dest`.
(
ctx: &mut Context,
pos: LineCol,
test: (Register, ExprType),
rhs: (Register, ExprType),
relop: CaseRelOp,
dest: Register,
)
| 281 | |
| 282 | /// Compiles a comparison between `test` and `rhs`, leaving the boolean result in `dest`. |
| 283 | fn compile_case_relop( |
| 284 | ctx: &mut Context, |
| 285 | pos: LineCol, |
| 286 | test: (Register, ExprType), |
| 287 | rhs: (Register, ExprType), |
| 288 | relop: CaseRelOp, |
| 289 | dest: Register, |
| 290 | ) -> Result<()> { |
| 291 | let (test_reg, test_type) = test; |
| 292 | let (rhs_reg, rhs_type) = rhs; |
| 293 | let op_name = case_relop_name(&relop); |
| 294 | let opcode = match (test_type, rhs_type) { |
| 295 | (ExprType::Double, ExprType::Integer) => { |
| 296 | ctx.codegen.emit(bytecode::make_integer_to_double(rhs_reg), pos); |
| 297 | case_relop_instr(&relop, ExprType::Double) |
| 298 | } |
| 299 | |
| 300 | (ExprType::Integer, ExprType::Double) => { |
| 301 | ctx.codegen.emit(bytecode::make_integer_to_double(test_reg), pos); |
| 302 | case_relop_instr(&relop, ExprType::Double) |
| 303 | } |
| 304 | |
| 305 | (lhs, rhs) if lhs == rhs => case_relop_instr(&relop, lhs), |
| 306 | _ => None, |
| 307 | }; |
| 308 | |
| 309 | match opcode { |
| 310 | Some(opcode) => { |
| 311 | ctx.codegen.emit(opcode(dest, test_reg, rhs_reg), pos); |
| 312 | Ok(()) |
| 313 | } |
| 314 | None => Err(Error::BinaryOpType(pos, op_name, test_type, rhs_type)), |
| 315 | } |
| 316 | } |
| 317 | |
| 318 | /// Compiles one `CASE` guard and returns the register and source position of its boolean result. |
| 319 | fn compile_case_guard( |
no test coverage detected