feat: runtime content processing, supporting glue
This commit is contained in:
parent
d325cdf965
commit
f5eac49729
12 changed files with 387 additions and 286 deletions
|
|
@ -285,6 +285,13 @@ const GenIr = struct {
|
|||
return last_inst.isNoReturn();
|
||||
}
|
||||
|
||||
fn endsWithContent(self: *GenIr) bool {
|
||||
if (self.isEmpty()) return false;
|
||||
const last_inst_index = self.instructions.items[self.instructions.items.len - 1];
|
||||
const last_inst = self.astgen.instructions.items[@intFromEnum(last_inst_index)];
|
||||
return last_inst.tag == .content_push;
|
||||
}
|
||||
|
||||
fn makeSubBlock(self: *GenIr) GenIr {
|
||||
return .{
|
||||
.astgen = self.astgen,
|
||||
|
|
@ -807,7 +814,7 @@ fn inlineIfStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!Ir.
|
|||
if (data.rhs) |rhs| {
|
||||
// TODO: Revisit this. This isn't quite correct.
|
||||
switch (rhs.tag) {
|
||||
.content => _ = try contentExpr(&then_block, scope, rhs),
|
||||
.content => _ = try content(&then_block, scope, rhs),
|
||||
inline else => |tag| @panic("Unexpected node type: " ++ @tagName(tag)),
|
||||
}
|
||||
}
|
||||
|
|
@ -1051,8 +1058,11 @@ fn switchStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!Ir.In
|
|||
return switch_br.toRef();
|
||||
}
|
||||
|
||||
fn contentExpr(block: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!Ir.Inst.Ref {
|
||||
fn content(block: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!Ir.Inst.Ref {
|
||||
const data = node.data.content;
|
||||
if (data.leading_glue) {
|
||||
_ = try block.addUnaryNode(.content_glue, .none);
|
||||
}
|
||||
for (data.items) |child_node| {
|
||||
switch (child_node.tag) {
|
||||
.string_literal => {
|
||||
|
|
@ -1070,13 +1080,17 @@ fn contentExpr(block: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!I
|
|||
else => unreachable,
|
||||
}
|
||||
}
|
||||
if (data.trailing_glue) {
|
||||
_ = try block.addUnaryNode(.content_glue, .none);
|
||||
} else if (block.endsWithContent()) {
|
||||
_ = try block.addUnaryNode(.content_line, .none);
|
||||
}
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn contentStmt(gen: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!Ir.Inst.Ref {
|
||||
const expr_node = node.data.bin.lhs.?;
|
||||
const expr_ref = try contentExpr(gen, scope, expr_node);
|
||||
return gen.addUnaryNode(.content_flush, expr_ref);
|
||||
fn contentStmt(block: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||
const data = node.data.bin;
|
||||
_ = try content(block, scope, data.lhs.?);
|
||||
}
|
||||
|
||||
fn assignStmt(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||
|
|
@ -1133,6 +1147,9 @@ fn choiceStmt(
|
|||
if (branch_data.rhs) |branch_body| {
|
||||
_ = try blockStmt(&sub_block, scope, branch_body);
|
||||
}
|
||||
if (!sub_block.endsWithNoReturn()) {
|
||||
_ = try sub_block.addUnaryNode(.implicit_ret, .none);
|
||||
}
|
||||
|
||||
const body = sub_block.instructionsSlice();
|
||||
const case_extra_len = @typeInfo(Ir.Inst.SwitchBr.Case).@"struct".fields.len + body.len;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue