| ... | ... | @@ -293,6 +293,7 @@ pub const DeclGen = struct { |
| 293 | 293 | try dg.renderType(w, t.elemType()); |
| 294 | 294 | try w.writeAll(" *"); |
| 295 | 295 | }, |
| 296 | .Null, .Undefined => unreachable, // must be const or comptime |
| 296 | 297 | else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{ |
| 297 | 298 | @tagName(e), |
| 298 | 299 | }), |
| ... | ... | @@ -387,6 +388,7 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi |
| 387 | 388 | |
| 388 | 389 | for (body.instructions) |inst| { |
| 389 | 390 | const result_value = switch (inst.tag) { |
| 391 | .constant => unreachable, // excluded from function bodies |
| 390 | 392 | .add => try genBinOp(o, inst.castTag(.add).?, " + "), |
| 391 | 393 | .alloc => try genAlloc(o, inst.castTag(.alloc).?), |
| 392 | 394 | .arg => genArg(o), |
| ... | ... | @@ -415,8 +417,10 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi |
| 415 | 417 | .brvoid => try genBrVoid(o, inst.castTag(.brvoid).?.block), |
| 416 | 418 | .switchbr => try genSwitchBr(o, inst.castTag(.switchbr).?), |
| 417 | 419 | // booland and boolor are non-short-circuit operations |
| 418 | | .booland => try genBinOp(o, inst.castTag(.booland).?, " & "), |
| 419 | | .boolor => try genBinOp(o, inst.castTag(.boolor).?, " | "), |
| 420 | .booland, .bitand => try genBinOp(o, inst.castTag(.booland).?, " & "), |
| 421 | .boolor, .bitor => try genBinOp(o, inst.castTag(.boolor).?, " | "), |
| 422 | .xor => try genBinOp(o, inst.castTag(.xor).?, " ^ "), |
| 423 | .not => try genUnOp(o, inst.castTag(.not).?, "!"), |
| 420 | 424 | else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}), |
| 421 | 425 | }; |
| 422 | 426 | switch (result_value) { |
| ... | ... | @@ -541,6 +545,22 @@ fn genBinOp(o: *Object, inst: *Inst.BinOp, operator: []const u8) !CValue { |
| 541 | 545 | return local; |
| 542 | 546 | } |
| 543 | 547 | |
| 548 | fn genUnOp(o: *Object, inst: *Inst.UnOp, operator: []const u8) !CValue { |
| 549 | if (inst.base.isUnused()) |
| 550 | return CValue.none; |
| 551 | |
| 552 | const operand = try o.resolveInst(inst.operand); |
| 553 | |
| 554 | const writer = o.writer(); |
| 555 | const local = try o.allocLocal(inst.base.ty, .Const); |
| 556 | |
| 557 | try writer.print(" = {s}", .{operator}); |
| 558 | try o.writeCValue(writer, operand); |
| 559 | try writer.writeAll(";\n"); |
| 560 | |
| 561 | return local; |
| 562 | } |
| 563 | |
| 544 | 564 | fn genCall(o: *Object, inst: *Inst.Call) !CValue { |
| 545 | 565 | if (inst.func.castTag(.constant)) |func_inst| { |
| 546 | 566 | const fn_decl = if (func_inst.val.castTag(.extern_fn)) |extern_fn| |