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 },
|
.data = .{ .payload = undefined },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var node_index: usize = 0;
|
||||||
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);
|
const knot_inst = try gi.makePayloadNode(.decl_knot);
|
||||||
|
|
||||||
var child_scope = parent_scope.makeChild();
|
var child_scope = parent_scope.makeChild();
|
||||||
defer child_scope.deinit();
|
defer child_scope.deinit();
|
||||||
|
|
||||||
|
|
@ -1432,18 +1432,18 @@ fn knotDecl(gi: *GenIr, parent_scope: *Scope, decl_node: *const Ast.Node) InnerE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (nested_decls_list.len > 0) {
|
||||||
var start_index: usize = 0;
|
const first_child = nested_decls_list[0];
|
||||||
const first_child = nested_decls_list[0];
|
if (first_child.tag == .block_stmt) {
|
||||||
if (first_child.tag == .block_stmt) {
|
try blockStmt(&child_block, &child_scope, first_child);
|
||||||
try blockStmt(&child_block, &child_scope, first_child);
|
node_index += 1;
|
||||||
start_index += 1;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var nested_block = child_block.makeSubBlock();
|
var nested_block = child_block.makeSubBlock();
|
||||||
defer nested_block.unstack();
|
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) {
|
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),
|
||||||
|
|
@ -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();
|
var file_scope = gi.makeSubBlock();
|
||||||
defer file_scope.unstack();
|
defer file_scope.unstack();
|
||||||
|
|
||||||
// TODO: Make sure this is non-nullable.
|
// TODO: Make sure this is non-nullable.
|
||||||
const nested_decls_list = file_node.data.list.items orelse return;
|
const nested_decls_list = file_node.data.list.items orelse return;
|
||||||
if (nested_decls_list.len == 0) return;
|
if (nested_decls_list.len > 0) {
|
||||||
|
const first_child = nested_decls_list[0];
|
||||||
const first_child = nested_decls_list[0];
|
if (first_child.tag == .block_stmt) {
|
||||||
if (first_child.tag == .block_stmt) {
|
try defaultBlock(&file_scope, scope, first_child);
|
||||||
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) {
|
switch (child_node.tag) {
|
||||||
.knot_decl => try knotDecl(gi, scope, child_node),
|
.knot_decl => try knotDecl(gi, scope, child_node),
|
||||||
.stitch_decl => try stitchDecl(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 {
|
fn nodeListFromScratch(p: *Parse, start_offset: usize, end_offset: usize) Error![]*Ast.Node {
|
||||||
const span = end_offset - start_offset;
|
const span = end_offset - start_offset;
|
||||||
assert(span > 0);
|
assert(span >= 0);
|
||||||
|
|
||||||
const list = try p.arena.alloc(*Ast.Node, span);
|
const list = try p.arena.alloc(*Ast.Node, span);
|
||||||
defer p.scratch.shrinkRetainingCapacity(start_offset);
|
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;
|
var scope: ?*Module.Namespace = namespace;
|
||||||
while (scope) |s| : (scope = s.parent) {
|
while (scope) |s| : (scope = s.parent) {
|
||||||
if (s.decls.get(ident)) |decl| switch (decl.tag) {
|
if (s.decls.get(ident)) |decl| switch (decl.tag) {
|
||||||
.knot => return .{ .knot = .{
|
.knot, .stitch => return .{ .knot = .{
|
||||||
.namespace = decl.namespace.?,
|
.namespace = decl.namespace.?,
|
||||||
.const_index = ident,
|
.const_index = ident,
|
||||||
} },
|
} },
|
||||||
|
|
@ -814,6 +814,27 @@ pub fn analyzeTopLevelDecl(
|
||||||
try analyzeNestedDecl(sema, child_namespace, st);
|
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,
|
else => unreachable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ pub const Module = struct {
|
||||||
|
|
||||||
pub const Tag = enum {
|
pub const Tag = enum {
|
||||||
knot,
|
knot,
|
||||||
|
stitch,
|
||||||
variable,
|
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 {
|
fn testEqual(source_bytes: [:0]const u8, expected_ast: []const u8) !void {
|
||||||
const gpa = std.testing.allocator;
|
const gpa = std.testing.allocator;
|
||||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
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