| ... | ... | @@ -217,6 +217,11 @@ pub const DeclGen = struct { |
| 217 | 217 | try writer.writeAll(" }"); |
| 218 | 218 | } |
| 219 | 219 | }, |
| 220 | .ErrorSet => { |
| 221 | const payload = val.castTag(.@"error").?; |
| 222 | // error values will be #defined at the top of the file |
| 223 | return writer.print("zig_error_{s}", .{payload.data.name}); |
| 224 | }, |
| 220 | 225 | else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement value {s}", .{ |
| 221 | 226 | @tagName(e), |
| 222 | 227 | }), |
| ... | ... | @@ -327,6 +332,16 @@ pub const DeclGen = struct { |
| 327 | 332 | try dg.renderType(w, child_type); |
| 328 | 333 | try w.writeAll(" payload; bool is_null; }"); |
| 329 | 334 | }, |
| 335 | .ErrorSet => { |
| 336 | comptime std.debug.assert(Type.initTag(.anyerror).abiSize(std.Target.current) == 2); |
| 337 | try w.writeAll("uint16_t"); |
| 338 | }, |
| 339 | .ErrorUnion => { |
| 340 | // TODO this needs to be typedeffed since different structs are different types. |
| 341 | try w.writeAll("struct { "); |
| 342 | try dg.renderType(w, t.errorUnionChild()); |
| 343 | try w.writeAll(" payload; uint16_t error; }"); |
| 344 | }, |
| 330 | 345 | .Null, .Undefined => unreachable, // must be const or comptime |
| 331 | 346 | else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{ |
| 332 | 347 | @tagName(e), |
| ... | ... | @@ -464,6 +479,8 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi |
| 464 | 479 | .wrap_optional => try genWrapOptional(o, inst.castTag(.wrap_optional).?), |
| 465 | 480 | .optional_payload => try genOptionalPayload(o, inst.castTag(.optional_payload).?), |
| 466 | 481 | .optional_payload_ptr => try genOptionalPayload(o, inst.castTag(.optional_payload).?), |
| 482 | .is_err => try genIsErr(o, inst.castTag(.is_err).?), |
| 483 | .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?), |
| 467 | 484 | else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}), |
| 468 | 485 | }; |
| 469 | 486 | switch (result_value) { |
| ... | ... | @@ -900,6 +917,18 @@ fn genWrapOptional(o: *Object, inst: *Inst.UnOp) !CValue { |
| 900 | 917 | return local; |
| 901 | 918 | } |
| 902 | 919 | |
| 920 | fn genIsErr(o: *Object, inst: *Inst.UnOp) !CValue { |
| 921 | const writer = o.writer(); |
| 922 | const maybe_deref = if (inst.base.tag == .is_err_ptr) "[0]" else ""; |
| 923 | const operand = try o.resolveInst(inst.operand); |
| 924 | |
| 925 | const local = try o.allocLocal(Type.initTag(.bool), .Const); |
| 926 | try writer.writeAll(" = ("); |
| 927 | try o.writeCValue(writer, operand); |
| 928 | try writer.print("){s}.error != 0;\n", .{maybe_deref}); |
| 929 | return local; |
| 930 | } |
| 931 | |
| 903 | 932 | fn IndentWriter(comptime UnderlyingWriter: type) type { |
| 904 | 933 | return struct { |
| 905 | 934 | const Self = @This(); |