fix: simple knot tests
This commit is contained in:
parent
9ca2200448
commit
cd94a43cc9
7 changed files with 75 additions and 41 deletions
|
|
@ -1410,11 +1410,11 @@ fn knotDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerE
|
|||
.data = .{ .payload = undefined },
|
||||
});
|
||||
|
||||
var node_index: usize = 0;
|
||||
var child_block = gi.makeSubBlock();
|
||||
defer child_block.unstack();
|
||||
|
||||
const knot_inst = try gi.makePayloadNode(.decl_knot);
|
||||
|
||||
var child_scope = parent_scope.makeChild();
|
||||
defer child_scope.deinit();
|
||||
|
||||
|
|
@ -1432,18 +1432,18 @@ fn knotDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerE
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
var start_index: usize = 0;
|
||||
const first_child = nested_decls_list[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try blockStmt(&child_block, &child_scope, first_child);
|
||||
start_index += 1;
|
||||
if (nested_decls_list.len > 0) {
|
||||
const first_child = nested_decls_list[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try blockStmt(&child_block, &child_scope, first_child);
|
||||
node_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
var nested_block = child_block.makeSubBlock();
|
||||
defer nested_block.unstack();
|
||||
|
||||
for (nested_decls_list[start_index..]) |nested_decl_node| {
|
||||
for (nested_decls_list[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),
|
||||
|
|
@ -1469,18 +1469,20 @@ fn file(gi: *GenIr, scope: *Scope, file_node: *const Ast.Node) InnerError!void {
|
|||
},
|
||||
});
|
||||
|
||||
var node_index: usize = 0;
|
||||
var file_scope = gi.makeSubBlock();
|
||||
defer file_scope.unstack();
|
||||
|
||||
// TODO: Make sure this is non-nullable.
|
||||
const nested_decls_list = file_node.data.list.items orelse return;
|
||||
if (nested_decls_list.len == 0) return;
|
||||
|
||||
const first_child = nested_decls_list[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try defaultBlock(&file_scope, scope, first_child);
|
||||
if (nested_decls_list.len > 0) {
|
||||
const first_child = nested_decls_list[0];
|
||||
if (first_child.tag == .block_stmt) {
|
||||
try defaultBlock(&file_scope, scope, first_child);
|
||||
node_index += 1;
|
||||
}
|
||||
}
|
||||
for (nested_decls_list[1..]) |child_node| {
|
||||
for (nested_decls_list[node_index..]) |child_node| {
|
||||
switch (child_node.tag) {
|
||||
.knot_decl => try knotDecl(gi, scope, child_node),
|
||||
.stitch_decl => try stitchDecl(gi, scope, child_node),
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ fn popScratch(p: *Parse, context: *const StmtContext) *Ast.Node {
|
|||
|
||||
fn nodeListFromScratch(p: *Parse, start_offset: usize, end_offset: usize) Error![]*Ast.Node {
|
||||
const span = end_offset - start_offset;
|
||||
assert(span > 0);
|
||||
assert(span >= 0);
|
||||
|
||||
const list = try p.arena.alloc(*Ast.Node, span);
|
||||
defer p.scratch.shrinkRetainingCapacity(start_offset);
|
||||
|
|
|
|||
23
src/Sema.zig
23
src/Sema.zig
|
|
@ -90,7 +90,7 @@ pub fn lookupInNamespace(
|
|||
var scope: ?*Module.Namespace = namespace;
|
||||
while (scope) |s| : (scope = s.parent) {
|
||||
if (s.decls.get(ident)) |decl| switch (decl.tag) {
|
||||
.knot => return .{ .knot = .{
|
||||
.knot, .stitch => return .{ .knot = .{
|
||||
.namespace = decl.namespace.?,
|
||||
.const_index = ident,
|
||||
} },
|
||||
|
|
@ -814,6 +814,27 @@ pub fn analyzeTopLevelDecl(
|
|||
try analyzeNestedDecl(sema, child_namespace, st);
|
||||
}
|
||||
},
|
||||
.decl_stitch => {
|
||||
const child_namespace = try sema.module.createNamespace(namespace);
|
||||
const gop = try namespace.decls.getOrPut(sema.arena, decl_name);
|
||||
if (gop.found_existing) {
|
||||
return sema.fail(src_loc, "duplicate identifier", .{});
|
||||
} else {
|
||||
gop.value_ptr.* = .{
|
||||
.tag = .stitch,
|
||||
.decl_inst = extra.value,
|
||||
.args_count = 0,
|
||||
.namespace = child_namespace,
|
||||
};
|
||||
}
|
||||
|
||||
try sema.module.queueWorkItem(.{
|
||||
.tag = .stitch,
|
||||
.decl_name = decl_name,
|
||||
.inst_index = extra.value,
|
||||
.namespace = child_namespace,
|
||||
});
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ pub const Module = struct {
|
|||
|
||||
pub const Tag = enum {
|
||||
knot,
|
||||
stitch,
|
||||
variable,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -93,6 +93,41 @@ test "parser: temporary assignment" {
|
|||
);
|
||||
}
|
||||
|
||||
test "parser: simple knot" {
|
||||
try testEqual(
|
||||
\\=== knot ===
|
||||
\\Hello, world!
|
||||
,
|
||||
\\File "<STDIN>"
|
||||
\\`--KnotDecl <line:1, line:2>
|
||||
\\ |--KnotProto <col:1, col:13>
|
||||
\\ | `--Identifier `knot` <col:5, col:9>
|
||||
\\ `--BlockStmt <line:2, line:2>
|
||||
\\ `--ContentStmt <line:2, col:1:14>
|
||||
\\ `--Content <col:1, col:14>
|
||||
\\ `--StringLiteral `Hello, world!` <col:1, col:14>
|
||||
\\
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
test "parser: empty knot declarations" {
|
||||
try testEqual(
|
||||
\\== a
|
||||
\\== b
|
||||
,
|
||||
\\File "<STDIN>"
|
||||
\\|--KnotDecl <line:1, line:1>
|
||||
\\| `--KnotProto <col:1, col:5>
|
||||
\\| `--Identifier `a` <col:4, col:5>
|
||||
\\`--KnotDecl <line:2, line:2>
|
||||
\\ `--KnotProto <col:1, col:5>
|
||||
\\ `--Identifier `b` <col:4, col:5>
|
||||
\\
|
||||
,
|
||||
);
|
||||
}
|
||||
|
||||
fn testEqual(source_bytes: [:0]const u8, expected_ast: []const u8) !void {
|
||||
const gpa = std.testing.allocator;
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
// RUN: %ink-compiler --stdin --compile-only --dump-ast < %s | FileCheck %s
|
||||
|
||||
// CHECK: File "<STDIN>"
|
||||
// CHECK-NEXT: |--KnotDecl <line:11, line:11>
|
||||
// CHECK-NEXT: | `--KnotProto <col:1, col:5>
|
||||
// CHECK-NEXT: | `--Identifier `a` <col:4, col:5>
|
||||
// CHECK-NEXT: `--KnotDecl <line:12, line:12>
|
||||
// CHECK-NEXT: `--KnotProto <col:1, col:5>
|
||||
// CHECK-NEXT: `--Identifier `b` <col:4, col:5>
|
||||
|
||||
== a
|
||||
== b
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
// RUN: %ink-compiler --stdin --compile-only --dump-ast < %s | FileCheck %s
|
||||
|
||||
// CHECK: File "<STDIN>"
|
||||
// CHECK-NEXT: `--KnotDecl <line:12, line:13>
|
||||
// CHECK-NEXT: |--KnotProto <col:1, col:13>
|
||||
// CHECK-NEXT: | `--Identifier `knot` <col:5, col:9>
|
||||
// CHECK-NEXT: `--BlockStmt <line:13, line:13>
|
||||
// CHECK-NEXT: `--ContentStmt <line:13, col:1:14>
|
||||
// CHECK-NEXT: `--Content <col:1, col:14>
|
||||
// CHECK-NEXT: `--StringLiteral `Hello, world!` <col:1, col:14>
|
||||
|
||||
=== knot ===
|
||||
Hello, world!
|
||||
Loading…
Add table
Add a link
Reference in a new issue