diff options
| author | Zen1th <39484230+zenith391@users.noreply.github.com> | 2021-11-10 00:52:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-11-09 18:52:30 -0500 |
| commit | 0d7359ca9b7e1c88d62ce3ecc6542584fe5df489 (patch) | |
| tree | 259335fd862ce44db56c716e5de3080e26cbe80a /src/Sema.zig | |
| parent | c77698d69ea5c3e09b1b9404f634e512627ad321 (diff) | |
| download | zig-0d7359ca9b7e1c88d62ce3ecc6542584fe5df489.tar.gz zig-0d7359ca9b7e1c88d62ce3ecc6542584fe5df489.zip | |
stage2: Implement Sema.floatToInt (#10097)
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 300d319167..ac1bd8b421 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9642,9 +9642,29 @@ fn zirFrameSize(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].pl_node; - const src = inst_data.src(); - // TODO don't forget the safety check! - return sema.fail(block, src, "TODO: Sema.zirFloatToInt", .{}); + const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; + const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; + const dest_ty = try sema.resolveType(block, ty_src, extra.lhs); + const operand = sema.resolveInst(extra.rhs); + const operand_ty = sema.typeOf(operand); + + _ = try sema.checkIntType(block, ty_src, dest_ty); + try sema.checkFloatType(block, operand_src, operand_ty); + + if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { + const target = sema.mod.getTarget(); + const result_val = val.floatToInt(sema.arena, dest_ty, target) catch |err| switch (err) { + error.FloatCannotFit => { + return sema.fail(block, operand_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty }); + }, + else => |e| return e, + }; + return sema.addConstant(dest_ty, result_val); + } + + try sema.requireRuntimeBlock(block, operand_src); + return block.addTyOp(.float_to_int, dest_ty, operand); } fn zirIntToFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -12434,7 +12454,13 @@ fn coerceNum( if (val.floatHasFraction()) { return sema.fail(block, inst_src, "fractional component prevents float value {} from coercion to type '{}'", .{ val, dest_ty }); } - return sema.fail(block, inst_src, "TODO float to int", .{}); + const result_val = val.floatToInt(sema.arena, dest_ty, target) catch |err| switch (err) { + error.FloatCannotFit => { + return sema.fail(block, inst_src, "integer value {d} cannot be stored in type '{}'", .{ std.math.floor(val.toFloat(f64)), dest_ty }); + }, + else => |e| return e, + }; + return try sema.addConstant(dest_ty, result_val); }, .Int, .ComptimeInt => { if (!val.intFitsInType(dest_ty, target)) { |
