feat: semantics for if statements and multi-prong if statements
This commit is contained in:
parent
9658c8a308
commit
ce5385ebac
6 changed files with 553 additions and 317 deletions
108
src/Ir.zig
108
src/Ir.zig
|
|
@ -24,6 +24,8 @@ pub const Inst = struct {
|
|||
decl_var,
|
||||
decl_ref,
|
||||
block,
|
||||
condbr,
|
||||
@"break",
|
||||
alloc_local,
|
||||
load_local,
|
||||
store_local,
|
||||
|
|
@ -33,11 +35,19 @@ pub const Inst = struct {
|
|||
div,
|
||||
mod,
|
||||
neg,
|
||||
not,
|
||||
cmp_eq,
|
||||
cmp_neq,
|
||||
cmp_gt,
|
||||
cmp_gte,
|
||||
cmp_lt,
|
||||
cmp_lte,
|
||||
true_literal,
|
||||
false_literal,
|
||||
integer,
|
||||
string,
|
||||
content,
|
||||
content_push,
|
||||
content_flush,
|
||||
};
|
||||
|
||||
pub const Data = union {
|
||||
|
|
@ -45,11 +55,11 @@ pub const Inst = struct {
|
|||
payload_index: u32,
|
||||
},
|
||||
un: struct {
|
||||
lhs: Inst.Index,
|
||||
lhs: Index,
|
||||
},
|
||||
bin: struct {
|
||||
lhs: Inst.Index,
|
||||
rhs: Inst.Index,
|
||||
lhs: Index,
|
||||
rhs: Index,
|
||||
},
|
||||
integer: struct {
|
||||
value: u64,
|
||||
|
|
@ -66,7 +76,7 @@ pub const Inst = struct {
|
|||
|
||||
pub const Declaration = struct {
|
||||
name: NullTerminatedString,
|
||||
value: Inst.Index,
|
||||
value: Index,
|
||||
};
|
||||
|
||||
pub const Knot = struct {
|
||||
|
|
@ -80,6 +90,16 @@ pub const Inst = struct {
|
|||
pub const Block = struct {
|
||||
body_len: u32,
|
||||
};
|
||||
|
||||
pub const Break = struct {
|
||||
block_inst: Index,
|
||||
};
|
||||
|
||||
pub const CondBr = struct {
|
||||
condition: Index,
|
||||
then_body_len: u32,
|
||||
else_body_len: u32,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Global = struct {
|
||||
|
|
@ -112,29 +132,6 @@ pub fn deinit(ir: *Ir, gpa: std.mem.Allocator) void {
|
|||
ir.* = undefined;
|
||||
}
|
||||
|
||||
const Prefix = struct {
|
||||
buf: std.ArrayListUnmanaged(u8) = .empty,
|
||||
|
||||
pub fn deinit(self: *Prefix, gpa: std.mem.Allocator) void {
|
||||
self.buf.deinit(gpa);
|
||||
}
|
||||
|
||||
pub fn writeIndent(self: *const Prefix, writer: *std.Io.Writer) !void {
|
||||
try writer.writeAll(self.buf.items);
|
||||
}
|
||||
|
||||
pub fn pushChildPrefix(self: *Prefix, gpa: std.mem.Allocator) !usize {
|
||||
const old_len = self.buf.items.len;
|
||||
const seg: []const u8 = " ";
|
||||
try self.buf.appendSlice(gpa, seg);
|
||||
return old_len;
|
||||
}
|
||||
|
||||
pub fn restore(self: *Prefix, new_len: usize) void {
|
||||
self.buf.shrinkRetainingCapacity(new_len);
|
||||
}
|
||||
};
|
||||
|
||||
const Render = struct {
|
||||
gpa: std.mem.Allocator,
|
||||
prefix: Prefix,
|
||||
|
|
@ -145,6 +142,29 @@ const Render = struct {
|
|||
WriteFailed,
|
||||
};
|
||||
|
||||
const Prefix = struct {
|
||||
buf: std.ArrayListUnmanaged(u8) = .empty,
|
||||
|
||||
pub fn deinit(self: *Prefix, gpa: std.mem.Allocator) void {
|
||||
self.buf.deinit(gpa);
|
||||
}
|
||||
|
||||
pub fn writeIndent(self: *const Prefix, writer: *std.Io.Writer) !void {
|
||||
try writer.writeAll(self.buf.items);
|
||||
}
|
||||
|
||||
pub fn pushChildPrefix(self: *Prefix, gpa: std.mem.Allocator) !usize {
|
||||
const old_len = self.buf.items.len;
|
||||
const seg: []const u8 = " ";
|
||||
try self.buf.appendSlice(gpa, seg);
|
||||
return old_len;
|
||||
}
|
||||
|
||||
pub fn restore(self: *Prefix, new_len: usize) void {
|
||||
self.buf.shrinkRetainingCapacity(new_len);
|
||||
}
|
||||
};
|
||||
|
||||
fn renderSimple(r: *Render, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
return io_w.print("{s}(?)", .{@tagName(inst.tag)});
|
||||
|
|
@ -183,6 +203,26 @@ const Render = struct {
|
|||
try io_w.writeAll(")");
|
||||
}
|
||||
|
||||
fn renderBreak(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.Break, inst.data.payload.payload_index);
|
||||
|
||||
try io_w.print("{s}(%{d})", .{ @tagName(inst.tag), extra.data.block_inst });
|
||||
}
|
||||
|
||||
fn renderCondbr(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.CondBr, inst.data.payload.payload_index);
|
||||
const then_body = ir.bodySlice(extra.end, extra.data.then_body_len);
|
||||
const else_body = ir.bodySlice(extra.end + then_body.len, extra.data.else_body_len);
|
||||
|
||||
try io_w.print("{s}(%{d}, ", .{ @tagName(inst.tag), extra.data.condition });
|
||||
try renderBodyInner(r, ir, then_body);
|
||||
try io_w.writeAll(", ");
|
||||
try renderBodyInner(r, ir, else_body);
|
||||
try io_w.writeAll(")");
|
||||
}
|
||||
|
||||
fn renderKnotDecl(r: *Render, ir: Ir, inst: Inst) Error!void {
|
||||
const io_w = r.writer;
|
||||
const extra = ir.extraData(Inst.Knot, inst.data.payload.payload_index);
|
||||
|
|
@ -244,6 +284,8 @@ const Render = struct {
|
|||
const str_bytes = inst.data.string.get(ir);
|
||||
try io_w.print("{s}(\"{s}\")", .{ @tagName(inst.tag), str_bytes });
|
||||
},
|
||||
.condbr => try r.renderCondbr(ir, inst),
|
||||
.@"break" => try r.renderBreak(ir, inst),
|
||||
.alloc_local => try r.renderSimple(inst),
|
||||
.load_local => try r.renderUnary(inst),
|
||||
.store_local => try r.renderBinary(inst),
|
||||
|
|
@ -254,6 +296,13 @@ const Render = struct {
|
|||
.div => try r.renderBinary(inst),
|
||||
.mod => try r.renderBinary(inst),
|
||||
.neg => try r.renderUnary(inst),
|
||||
.not => try r.renderUnary(inst),
|
||||
.cmp_eq => try r.renderBinary(inst),
|
||||
.cmp_neq => try r.renderBinary(inst),
|
||||
.cmp_gt => try r.renderBinary(inst),
|
||||
.cmp_gte => try r.renderBinary(inst),
|
||||
.cmp_lt => try r.renderBinary(inst),
|
||||
.cmp_lte => try r.renderBinary(inst),
|
||||
.true_literal => {
|
||||
try io_w.print("{s}", .{@tagName(inst.tag)});
|
||||
},
|
||||
|
|
@ -268,7 +317,8 @@ const Render = struct {
|
|||
const str_bytes = inst.data.string.get(ir);
|
||||
try io_w.print("{s}(\"{s}\")", .{ @tagName(inst.tag), str_bytes });
|
||||
},
|
||||
.content => try r.renderUnary(inst),
|
||||
.content_push => try r.renderSimple(inst),
|
||||
.content_flush => try r.renderUnary(inst),
|
||||
}
|
||||
try io_w.writeAll("\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue