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,
|
gi: *GenIr,
|
||||||
scope: *Scope,
|
scope: *Scope,
|
||||||
node: *const Ast.Node,
|
|
||||||
prototype_node: *const Ast.Node,
|
prototype_node: *const Ast.Node,
|
||||||
body_node: ?*const Ast.Node,
|
body_node: ?*const Ast.Node,
|
||||||
) InnerError!void {
|
) InnerError!KnotInfo {
|
||||||
const astgen = gi.astgen;
|
const decl_name = try gi.astgen.strFromNode(prototype_node.data.bin.lhs.?);
|
||||||
const prototype_data = prototype_node.data.bin;
|
|
||||||
const identifier_node = prototype_data.lhs.?;
|
|
||||||
const decl_inst = try gi.addAsIndex(.{
|
|
||||||
.tag = .declaration,
|
|
||||||
.data = .{ .payload = undefined },
|
|
||||||
});
|
|
||||||
|
|
||||||
var decl_block = gi.makeSubBlock();
|
if (prototype_node.data.bin.rhs) |args_node| {
|
||||||
defer decl_block.unstack();
|
|
||||||
|
|
||||||
const stitch_inst = try decl_block.makePayloadNode(.decl_stitch);
|
|
||||||
|
|
||||||
if (prototype_data.rhs) |args_node| {
|
|
||||||
const args_data = args_node.data.list;
|
const args_data = args_node.data.list;
|
||||||
for (args_data.items) |arg| {
|
for (args_data.items) |arg| {
|
||||||
assert(arg.tag == .parameter_decl);
|
assert(arg.tag == .parameter_decl);
|
||||||
const arg_str = try astgen.strFromNode(arg);
|
const arg_str = try gi.astgen.strFromNode(arg);
|
||||||
const arg_inst = try decl_block.addStrTok(.param, arg_str.index, arg.loc.start);
|
const arg_inst = try gi.addStrTok(.param, arg_str.index, arg.loc.start);
|
||||||
|
|
||||||
// TODO: Maybe make decl accept a ref?
|
// TODO: Maybe make decl accept a ref?
|
||||||
try scope.insert(arg_str.index, .{
|
try scope.insert(arg_str.index, .{
|
||||||
|
|
@ -1549,101 +1541,72 @@ fn stitchDeclInner(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (body_node) |body| {
|
if (body_node) |body| {
|
||||||
const body_data = body.data.list;
|
try blockStmt(gi, scope, body);
|
||||||
try blockInner(&decl_block, scope, body_data.items);
|
|
||||||
} else {
|
|
||||||
try blockInner(&decl_block, scope, &.{});
|
|
||||||
}
|
}
|
||||||
if (!decl_block.endsWithNoReturn()) {
|
if (!gi.endsWithNoReturn()) {
|
||||||
_ = try decl_block.addUnaryNode(.implicit_ret, .none);
|
_ = try gi.addUnaryNode(.implicit_ret, .none);
|
||||||
}
|
}
|
||||||
|
return .{ .decl_name = decl_name };
|
||||||
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,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stitchDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerError!void {
|
fn stitchDecl(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||||
const knot_data = decl_node.data.bin;
|
const data = node.data.bin;
|
||||||
const prototype_node = knot_data.lhs;
|
const prototype_node = data.lhs.?;
|
||||||
const body_node = knot_data.rhs;
|
const body_node = 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.?;
|
|
||||||
const decl_inst = try gi.addAsIndex(.{
|
const decl_inst = try gi.addAsIndex(.{
|
||||||
.tag = .declaration,
|
.tag = .declaration,
|
||||||
.data = .{ .payload = undefined },
|
.data = .{ .payload = undefined },
|
||||||
});
|
});
|
||||||
|
|
||||||
var decl_block = gi.makeSubBlock();
|
var child_block = gi.makeSubBlock();
|
||||||
defer decl_block.unstack();
|
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 knot_info = try prototypeAndBody(&child_block, &child_scope, prototype_node, body_node);
|
||||||
const args_data = args_node.data.list;
|
const stitch_inst = try child_block.makePayloadNode(.decl_stitch);
|
||||||
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);
|
|
||||||
|
|
||||||
// TODO: Maybe make decl accept a ref?
|
try setDeclStitchPayload(stitch_inst, &child_block);
|
||||||
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 setDeclaration(decl_inst, .{
|
try setDeclaration(decl_inst, .{
|
||||||
.name = decl_str.index,
|
.name = knot_info.decl_name.index,
|
||||||
.value = stitch_inst,
|
.value = stitch_inst,
|
||||||
.gi = gi,
|
.gi = gi,
|
||||||
.node = node,
|
.node = node,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn functionDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerError!void {
|
fn functionDecl(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||||
const knot_data = decl_node.data.bin;
|
const data = node.data.bin;
|
||||||
const prototype_node = knot_data.lhs;
|
const prototype_node = data.lhs.?;
|
||||||
const body_node = knot_data.rhs;
|
const body_node = data.rhs;
|
||||||
var decl_scope = parent_scope.makeChild();
|
const decl_inst = try gi.addAsIndex(.{
|
||||||
defer decl_scope.deinit();
|
.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 {
|
fn knotDecl(gi: *GenIr, scope: *Scope, node: *const Ast.Node) InnerError!void {
|
||||||
const astgen = gi.astgen;
|
const data = node.data.knot_decl;
|
||||||
const data = decl_node.data.knot_decl;
|
|
||||||
const prototype_node = data.prototype;
|
const prototype_node = data.prototype;
|
||||||
const identifier_node = prototype_node.data.bin.lhs.?;
|
const nested_nodes = data.children;
|
||||||
const decl_inst = try gi.addAsIndex(.{
|
const decl_inst = try gi.addAsIndex(.{
|
||||||
.tag = .declaration,
|
.tag = .declaration,
|
||||||
.data = .{ .payload = undefined },
|
.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();
|
var child_block = gi.makeSubBlock();
|
||||||
defer child_block.unstack();
|
defer child_block.unstack();
|
||||||
|
|
||||||
const knot_inst = try gi.makePayloadNode(.decl_knot);
|
var child_scope = scope.makeChild();
|
||||||
var child_scope = parent_scope.makeChild();
|
|
||||||
defer child_scope.deinit();
|
defer child_scope.deinit();
|
||||||
|
|
||||||
if (prototype_node.data.bin.rhs) |args_node| {
|
const knot_inst = try gi.makePayloadNode(.decl_knot);
|
||||||
const args_data = args_node.data.list;
|
const body_node: ?*const Ast.Node = blk: {
|
||||||
for (args_data.items) |arg| {
|
if (nested_nodes.len > 0) {
|
||||||
assert(arg.tag == .parameter_decl);
|
const first_child = nested_nodes[0];
|
||||||
const arg_str = try astgen.strFromNode(arg);
|
if (first_child.tag == .block_stmt) {
|
||||||
const arg_inst = try child_block.addStrTok(.param, arg_str.index, arg.loc.start);
|
node_index += 1;
|
||||||
|
break :blk first_child;
|
||||||
// TODO: Maybe make decl accept a ref?
|
}
|
||||||
try child_scope.insert(arg_str.index, .{
|
|
||||||
.decl_node = arg,
|
|
||||||
.inst_index = arg_inst.toIndex().?,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
break :blk null;
|
||||||
if (data.children.len > 0) {
|
};
|
||||||
const first_child = data.children[0];
|
const knot_info = try prototypeAndBody(&child_block, &child_scope, prototype_node, body_node);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
var nested_block = child_block.makeSubBlock();
|
var nested_block = child_block.makeSubBlock();
|
||||||
defer nested_block.unstack();
|
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) {
|
switch (nested_decl_node.tag) {
|
||||||
.stitch_decl => try stitchDecl(&nested_block, &child_scope, nested_decl_node),
|
.stitch_decl => try stitchDecl(&nested_block, &child_scope, nested_decl_node),
|
||||||
.function_decl => try functionDecl(&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 setDeclKnotPayload(knot_inst, &child_block, &nested_block);
|
||||||
try setDeclaration(decl_inst, .{
|
try setDeclaration(decl_inst, .{
|
||||||
.name = name_str.index,
|
.name = knot_info.decl_name.index,
|
||||||
.value = knot_inst,
|
.value = knot_inst,
|
||||||
.gi = gi,
|
.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 {
|
fn testRunner(gpa: std.mem.Allocator, source_bytes: [:0]const u8, options: Options) !void {
|
||||||
const io_r = options.input_reader;
|
const io_r = options.input_reader;
|
||||||
const io_w = options.transcript_writer;
|
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,
|
.error_writer = options.error_writer,
|
||||||
});
|
});
|
||||||
defer story.deinit();
|
defer story.deinit();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue