chore: remove duplicate code for knot-related ir generation functions
This commit is contained in:
parent
d9f0a04417
commit
5c133e5fa2
2 changed files with 70 additions and 120 deletions
187
src/AstGen.zig
187
src/AstGen.zig
|
|
@ -1514,32 +1514,24 @@ fn defaultBlock(
|
|||
});
|
||||
}
|
||||
|
||||
fn stitchDeclInner(
|
||||
const KnotInfo = struct {
|
||||
decl_name: IndexSlice,
|
||||
};
|
||||
|
||||
fn prototypeAndBody(
|
||||
gi: *GenIr,
|
||||
scope: *Scope,
|
||||
node: *const Ast.Node,
|
||||
prototype_node: *const Ast.Node,
|
||||
body_node: ?*const Ast.Node,
|
||||
) InnerError!void {
|
||||
const astgen = gi.astgen;
|
||||
const prototype_data = prototype_node.data.bin;
|
||||
const identifier_node = prototype_data.lhs.?;
|
||||
const decl_inst = try gi.addAsIndex(.{
|
||||
.tag = .declaration,
|
||||
.data = .{ .payload = undefined },
|
||||
});
|
||||
) InnerError!KnotInfo {
|
||||
const decl_name = try gi.astgen.strFromNode(prototype_node.data.bin.lhs.?);
|
||||
|
||||
var decl_block = gi.makeSubBlock();
|
||||
defer decl_block.unstack();
|
||||
|
||||
const stitch_inst = try decl_block.makePayloadNode(.decl_stitch);
|
||||
|
||||
if (prototype_data.rhs) |args_node| {
|
||||
if (prototype_node.data.bin.rhs) |args_node| {
|
||||
const args_data = args_node.data.list;
|
||||
for (args_data.items) |arg| {
|
||||
assert(arg.tag == .parameter_decl);
|
||||
const arg_str = try astgen.strFromNode(arg);
|
||||
const arg_inst = try decl_block.addStrTok(.param, arg_str.index, arg.loc.start);
|
||||
const arg_str = try gi.astgen.strFromNode(arg);
|
||||
const arg_inst = try gi.addStrTok(.param, arg_str.index, arg.loc.start);
|
||||
|
||||
// TODO: Maybe make decl accept a ref?
|
||||
try scope.insert(arg_str.index, .{
|
||||
|
|
@ -1549,101 +1541,72 @@ fn stitchDeclInner(
|
|||
}
|
||||
}
|
||||
if (body_node) |body| {
|
||||
const body_data = body.data.list;
|
||||
try blockInner(&decl_block, scope, body_data.items);
|
||||
} else {
|
||||
try blockInner(&decl_block, scope, &.{});
|
||||
try blockStmt(gi, scope, body);
|
||||
}
|
||||
if (!decl_block.endsWithNoReturn()) {
|
||||
_ = try decl_block.addUnaryNode(.implicit_ret, .none);
|
||||
if (!gi.endsWithNoReturn()) {
|
||||
_ = try gi.addUnaryNode(.implicit_ret, .none);
|
||||
}
|
||||
|
||||
const decl_str = try astgen.strFromNode(identifier_node);
|
||||
try setDeclStitchPayload(stitch_inst, &decl_block);
|
||||
try setDeclaration(decl_inst, .{
|
||||
.name = decl_str.index,
|
||||
.value = stitch_inst,
|
||||
.gi = gi,
|
||||
.node = node,
|
||||
});
|
||||
return .{ .decl_name = decl_name };
|
||||
}
|
||||
|
||||
fn stitchDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerError!void {
|
||||
const knot_data = decl_node.data.bin;
|
||||
const prototype_node = knot_data.lhs;
|
||||
const body_node = knot_data.rhs;
|
||||
var decl_scope = parent_scope.makeChild();
|
||||
defer decl_scope.deinit();
|
||||
|
||||
return stitchDeclInner(gi, &decl_scope, decl_node, prototype_node.?, body_node);
|
||||
}
|
||||
|
||||
fn functionDeclInner(
|
||||
gi: *GenIr,
|
||||
scope: *Scope,
|
||||
node: *const Ast.Node,
|
||||
prototype_node: *const Ast.Node,
|
||||
body_node: ?*const Ast.Node,
|
||||
) InnerError!void {
|
||||
const astgen = gi.astgen;
|
||||
const prototype_data = prototype_node.data.bin;
|
||||
const identifier_node = prototype_data.lhs.?;
|
||||
fn stitchDecl(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||
const data = node.data.bin;
|
||||
const prototype_node = data.lhs.?;
|
||||
const body_node = data.rhs;
|
||||
const decl_inst = try gi.addAsIndex(.{
|
||||
.tag = .declaration,
|
||||
.data = .{ .payload = undefined },
|
||||
});
|
||||
|
||||
var decl_block = gi.makeSubBlock();
|
||||
defer decl_block.unstack();
|
||||
var child_block = gi.makeSubBlock();
|
||||
defer child_block.unstack();
|
||||
|
||||
const stitch_inst = try decl_block.makePayloadNode(.decl_function);
|
||||
var child_scope = scope.makeChild();
|
||||
defer child_scope.deinit();
|
||||
|
||||
if (prototype_data.rhs) |args_node| {
|
||||
const args_data = args_node.data.list;
|
||||
for (args_data.items) |arg| {
|
||||
assert(arg.tag == .parameter_decl);
|
||||
const arg_str = try astgen.strFromNode(arg);
|
||||
const arg_inst = try decl_block.addStrTok(.param, arg_str.index, arg.loc.start);
|
||||
const knot_info = try prototypeAndBody(&child_block, &child_scope, prototype_node, body_node);
|
||||
const stitch_inst = try child_block.makePayloadNode(.decl_stitch);
|
||||
|
||||
// TODO: Maybe make decl accept a ref?
|
||||
try scope.insert(arg_str.index, .{
|
||||
.decl_node = arg,
|
||||
.inst_index = arg_inst.toIndex().?,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (body_node) |body| {
|
||||
try blockStmt(&decl_block, scope, body);
|
||||
}
|
||||
if (!decl_block.endsWithNoReturn()) {
|
||||
_ = try decl_block.addUnaryNode(.implicit_ret, .none);
|
||||
}
|
||||
|
||||
const decl_str = try astgen.strFromNode(identifier_node);
|
||||
try setDeclStitchPayload(stitch_inst, &decl_block);
|
||||
try setDeclStitchPayload(stitch_inst, &child_block);
|
||||
try setDeclaration(decl_inst, .{
|
||||
.name = decl_str.index,
|
||||
.name = knot_info.decl_name.index,
|
||||
.value = stitch_inst,
|
||||
.gi = gi,
|
||||
.node = node,
|
||||
});
|
||||
}
|
||||
|
||||
fn functionDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerError!void {
|
||||
const knot_data = decl_node.data.bin;
|
||||
const prototype_node = knot_data.lhs;
|
||||
const body_node = knot_data.rhs;
|
||||
var decl_scope = parent_scope.makeChild();
|
||||
defer decl_scope.deinit();
|
||||
fn functionDecl(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||
const data = node.data.bin;
|
||||
const prototype_node = data.lhs.?;
|
||||
const body_node = data.rhs;
|
||||
const decl_inst = try gi.addAsIndex(.{
|
||||
.tag = .declaration,
|
||||
.data = .{ .payload = undefined },
|
||||
});
|
||||
|
||||
return functionDeclInner(gi, &decl_scope, decl_node, prototype_node.?, body_node);
|
||||
var child_block = gi.makeSubBlock();
|
||||
defer child_block.unstack();
|
||||
|
||||
var child_scope = scope.makeChild();
|
||||
defer child_scope.deinit();
|
||||
|
||||
const knot_info = try prototypeAndBody(&child_block, &child_scope, prototype_node, body_node);
|
||||
const stitch_inst = try child_block.makePayloadNode(.decl_function);
|
||||
|
||||
try setDeclStitchPayload(stitch_inst, &child_block);
|
||||
try setDeclaration(decl_inst, .{
|
||||
.name = knot_info.decl_name.index,
|
||||
.value = stitch_inst,
|
||||
.gi = gi,
|
||||
.node = node,
|
||||
});
|
||||
}
|
||||
|
||||
fn knotDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerError!void {
|
||||
const astgen = gi.astgen;
|
||||
const data = decl_node.data.knot_decl;
|
||||
fn knotDecl(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||
const data = node.data.knot_decl;
|
||||
const prototype_node = data.prototype;
|
||||
const identifier_node = prototype_node.data.bin.lhs.?;
|
||||
const nested_nodes = data.children;
|
||||
const decl_inst = try gi.addAsIndex(.{
|
||||
.tag = .declaration,
|
||||
.data = .{ .payload = undefined },
|
||||
|
|
@ -1653,39 +1616,26 @@ fn knotDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerE
|
|||
var child_block = gi.makeSubBlock();
|
||||
defer child_block.unstack();
|
||||
|
||||
const knot_inst = try gi.makePayloadNode(.decl_knot);
|
||||
var child_scope = parent_scope.makeChild();
|
||||
var child_scope = scope.makeChild();
|
||||
defer child_scope.deinit();
|
||||
|
||||
if (prototype_node.data.bin.rhs) |args_node| {
|
||||
const args_data = args_node.data.list;
|
||||
for (args_data.items) |arg| {
|
||||
assert(arg.tag == .parameter_decl);
|
||||
const arg_str = try astgen.strFromNode(arg);
|
||||
const arg_inst = try child_block.addStrTok(.param, arg_str.index, arg.loc.start);
|
||||
|
||||
// TODO: Maybe make decl accept a ref?
|
||||
try child_scope.insert(arg_str.index, .{
|
||||
.decl_node = arg,
|
||||
.inst_index = arg_inst.toIndex().?,
|
||||
});
|
||||
const knot_inst = try gi.makePayloadNode(.decl_knot);
|
||||
const body_node: ?*const Ast.Node = blk: {
|
||||
if (nested_nodes.len > 0) {
|
||||
const first_child = nested_nodes[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
node_index += 1;
|
||||
break :blk first_child;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.children.len > 0) {
|
||||
const first_child = data.children[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try blockStmt(&child_block, &child_scope, first_child);
|
||||
node_index += 1;
|
||||
}
|
||||
}
|
||||
if (!child_block.endsWithNoReturn()) {
|
||||
_ = try child_block.addUnaryNode(.implicit_ret, .none);
|
||||
}
|
||||
break :blk null;
|
||||
};
|
||||
const knot_info = try prototypeAndBody(&child_block, &child_scope, prototype_node, body_node);
|
||||
|
||||
var nested_block = child_block.makeSubBlock();
|
||||
defer nested_block.unstack();
|
||||
|
||||
for (data.children[node_index..]) |nested_decl_node| {
|
||||
for (nested_nodes[node_index..]) |nested_decl_node| {
|
||||
switch (nested_decl_node.tag) {
|
||||
.stitch_decl => try stitchDecl(&nested_block, &child_scope, nested_decl_node),
|
||||
.function_decl => try functionDecl(&nested_block, &child_scope, nested_decl_node),
|
||||
|
|
@ -1693,13 +1643,12 @@ fn knotDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerE
|
|||
}
|
||||
}
|
||||
|
||||
const name_str = try gi.astgen.strFromNode(identifier_node);
|
||||
try setDeclKnotPayload(knot_inst, &child_block, &nested_block);
|
||||
try setDeclaration(decl_inst, .{
|
||||
.name = name_str.index,
|
||||
.name = knot_info.decl_name.index,
|
||||
.value = knot_inst,
|
||||
.gi = gi,
|
||||
.node = decl_node,
|
||||
.node = node,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -217,7 +217,8 @@ const Options = struct {
|
|||
fn testRunner(gpa: std.mem.Allocator, source_bytes: [:0]const u8, options: Options) !void {
|
||||
const io_r = options.input_reader;
|
||||
const io_w = options.transcript_writer;
|
||||
var story = try ink.Story.loadFromString(gpa, source_bytes, .{
|
||||
var story = try ink.Story.fromSourceBytes(gpa, source_bytes, .{
|
||||
.filename = "<STDIN>",
|
||||
.error_writer = options.error_writer,
|
||||
});
|
||||
defer story.deinit();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue