refactor: working towards a better astgen patterns

This commit is contained in:
Brett Broadhurst 2026-03-08 04:22:57 -06:00
parent d6ff3a40bd
commit 95d89b7bf9
Failed to generate hash of commit
7 changed files with 922 additions and 596 deletions

View file

@ -218,6 +218,7 @@ pub const Error = struct {
panic, panic,
unexpected_token, unexpected_token,
unknown_identifier, unknown_identifier,
redefined_identifier,
assignment_to_const, assignment_to_const,
expected_newline, expected_newline,
expected_expression, expected_expression,

View file

@ -162,6 +162,7 @@ fn renderError(r: *Render, writer: *std.Io.Writer, err: Ast.Error) !void {
switch (err.tag) { switch (err.tag) {
.panic => try renderErrorf(r, writer, err, "parser panicked"), .panic => try renderErrorf(r, writer, err, "parser panicked"),
.unknown_identifier => try renderErrorf(r, writer, err, "unknown identifier"), .unknown_identifier => try renderErrorf(r, writer, err, "unknown identifier"),
.redefined_identifier => try renderErrorf(r, writer, err, "redefined identifier"),
.assignment_to_const => try renderErrorf(r, writer, err, "assignment to constant value"), .assignment_to_const => try renderErrorf(r, writer, err, "assignment to constant value"),
.unexpected_token => try renderErrorf(r, writer, err, "unexpected token"), .unexpected_token => try renderErrorf(r, writer, err, "unexpected token"),
.expected_newline => try renderErrorf(r, writer, err, "expected newline"), .expected_newline => try renderErrorf(r, writer, err, "expected newline"),

File diff suppressed because it is too large Load diff

View file

@ -497,11 +497,48 @@ pub fn loadFromString(
return error.Invalid; return error.Invalid;
} }
var story = try AstGen.generate(gpa, &ast); const comp_unit = try AstGen.generate(gpa, &ast);
defer comp_unit.deinit(gpa);
comp_unit.dumpStringsWithHex();
var story: Story = .{
.allocator = gpa,
.can_advance = false,
.dump_writer = options.dump_writer,
};
errdefer story.deinit(); errdefer story.deinit();
try story.divert("@main@"); for (comp_unit.knots) |compiled_chunk| {
story.dump_writer = options.dump_writer; const chunk_name = comp_unit.resolveString(compiled_chunk.name_ref);
var constant_pool: std.ArrayList(*Object) = .empty;
try constant_pool.ensureUnusedCapacity(gpa, compiled_chunk.constants.len);
defer constant_pool.deinit(gpa);
for (comp_unit.resolveConstants(compiled_chunk.constants)) |constant| {
switch (constant) {
.number => |value| {
const object: *Object.Number = try .create(&story, .{ .integer = value });
constant_pool.appendAssumeCapacity(&object.base);
},
.string => |ref| {
const bytes = comp_unit.resolveString(ref);
const object: *Object.String = try .create(&story, bytes);
constant_pool.appendAssumeCapacity(&object.base);
},
}
}
const runtime_chunk: *Object.ContentPath = try .create(&story, .{
.name = try .create(&story, chunk_name),
.arity = @intCast(compiled_chunk.arity),
.locals_count = @intCast(compiled_chunk.stack_size - compiled_chunk.arity),
.const_pool = try constant_pool.toOwnedSlice(gpa),
.bytes = try gpa.dupe(u8, comp_unit.resolveInstructions(compiled_chunk.instructions)),
});
try story.paths.append(gpa, &runtime_chunk.base);
}
try story.divert("$__main__$");
story.can_advance = true; story.can_advance = true;
return story; return story;
} }

View file

@ -262,17 +262,23 @@ pub const Object = struct {
base: Object, base: Object,
name: *Object.String, name: *Object.String,
arity: usize, arity: usize,
// TODO: Rename this to stack size.
locals_count: usize, locals_count: usize,
// TODO: Rename this to constant_pool.
const_pool: []*Object, const_pool: []*Object,
bytes: []const u8, bytes: []const u8,
pub fn create( pub const CreateOptions = struct {
story: *Story,
name: *Object.String, name: *Object.String,
arity: usize, arity: usize,
locals_count: usize, locals_count: usize,
const_pool: []*Object, const_pool: []*Object,
bytes: []const u8, bytes: []const u8,
};
pub fn create(
story: *Story,
options: CreateOptions,
) error{OutOfMemory}!*ContentPath { ) error{OutOfMemory}!*ContentPath {
const gpa = story.allocator; const gpa = story.allocator;
const alloc_len = @sizeOf(ContentPath); const alloc_len = @sizeOf(ContentPath);
@ -285,11 +291,11 @@ pub const Object = struct {
.is_marked = false, .is_marked = false,
.node = .{}, .node = .{},
}, },
.name = name, .name = options.name,
.arity = arity, .arity = options.arity,
.locals_count = locals_count, .locals_count = options.locals_count,
.const_pool = const_pool, .const_pool = options.const_pool,
.bytes = bytes, .bytes = options.bytes,
}; };
story.gc_objects.prepend(&object.base.node); story.gc_objects.prepend(&object.base.node);

View file

@ -0,0 +1,42 @@
// RUN: %ink-compiler --stdin --compile-only --dump-ast < %s | FileCheck %s
// CHECK: File "<STDIN>"
// CHECK-NEXT: `--BlockStmt <line:36, line:42>
// CHECK-NEXT: |--VarDecl <line:36, col:1:10>
// CHECK-NEXT: |  |--Identifier `x` <col:5, col:6>
// CHECK-NEXT: |  `--NumberLiteral `1` <col:9, col:10>
// CHECK-NEXT: `--ContentStmt <line:38, col:1:48>
// CHECK-NEXT: `--Content <col:1, col:48>
// CHECK-NEXT: `--MultiIfStmt <col:1, col:45>
// CHECK-NEXT: |--IfBranch <col:3, col:11>
// CHECK-NEXT: |  |--LogicalEqualityExpr <col:3, col:9>
// CHECK-NEXT: |  |  |--Identifier `x` <col:3, col:4>
// CHECK-NEXT: |  |  `--NumberLiteral `1` <col:8, col:9>
// CHECK-NEXT: |  `--BlockStmt <line:39, line:39>
// CHECK-NEXT: |   `--ContentStmt <line:39, col:11:14>
// CHECK-NEXT: |   `--Content <col:11, col:14>
// CHECK-NEXT: |   `--StringLiteral `One` <col:11, col:14>
// CHECK-NEXT: |--IfBranch <col:3, col:11>
// CHECK-NEXT: |  |--LogicalEqualityExpr <col:3, col:9>
// CHECK-NEXT: |  |  |--Identifier `x` <col:3, col:4>
// CHECK-NEXT: |  |  `--NumberLiteral `2` <col:8, col:9>
// CHECK-NEXT: |  `--BlockStmt <line:40, line:40>
// CHECK-NEXT: |   `--ContentStmt <line:40, col:11:14>
// CHECK-NEXT: |   `--Content <col:11, col:14>
// CHECK-NEXT: |   `--StringLiteral `Two` <col:11, col:14>
// CHECK-NEXT: `--IfBranch <col:3, col:11>
// CHECK-NEXT: |--LogicalEqualityExpr <col:3, col:9>
// CHECK-NEXT: |  |--Identifier `x` <col:3, col:4>
// CHECK-NEXT: |  `--NumberLiteral `3` <col:8, col:9>
// CHECK-NEXT: `--BlockStmt <line:41, line:41>
// CHECK-NEXT: `--ContentStmt <line:41, col:11:16>
// CHECK-NEXT: `--Content <col:11, col:16>
// CHECK-NEXT: `--StringLiteral `Three` <col:11, col:16>
VAR x = 1
{
- x == 1: One
- x == 2: Two
- x == 3: Three
}

View file

@ -0,0 +1,47 @@
// RUN: %ink-compiler --stdin --compile-only --dump-ast < %s | FileCheck %s
// CHECK: File "<STDIN>"
// CHECK-NEXT: `--BlockStmt <line:41, line:47>
// CHECK-NEXT: |--TempDecl <line:41, col:3:15>
// CHECK-NEXT: |  |--Identifier `foo` <col:8, col:11>
// CHECK-NEXT: |  `--NumberLiteral `3` <col:14, col:15>
// CHECK-NEXT: `--ContentStmt <line:42, col:1:97>
// CHECK-NEXT: `--Content <col:1, col:97>
// CHECK-NEXT: `--MultiIfStmt <col:5, col:94>
// CHECK-NEXT: |--IfBranch <col:7, col:17>
// CHECK-NEXT: |  |--LogicalEqualityExpr <col:7, col:15>
// CHECK-NEXT: |  |  |--Identifier `foo` <col:7, col:10>
// CHECK-NEXT: |  |  `--NumberLiteral `1` <col:14, col:15>
// CHECK-NEXT: |  `--BlockStmt <line:43, line:43>
// CHECK-NEXT: |   `--ContentStmt <line:43, col:17:21>
// CHECK-NEXT: |   `--Content <col:17, col:21>
// CHECK-NEXT: |   `--StringLiteral `One!` <col:17, col:21>
// CHECK-NEXT: |--IfBranch <col:7, col:17>
// CHECK-NEXT: |  |--LogicalEqualityExpr <col:7, col:15>
// CHECK-NEXT: |  |  |--Identifier `foo` <col:7, col:10>
// CHECK-NEXT: |  |  `--NumberLiteral `2` <col:14, col:15>
// CHECK-NEXT: |  `--BlockStmt <line:44, line:44>
// CHECK-NEXT: |   `--ContentStmt <line:44, col:17:21>
// CHECK-NEXT: |   `--Content <col:17, col:21>
// CHECK-NEXT: |   `--StringLiteral `Two!` <col:17, col:21>
// CHECK-NEXT: |--IfBranch <col:7, col:17>
// CHECK-NEXT: |  |--LogicalEqualityExpr <col:7, col:15>
// CHECK-NEXT: |  |  |--Identifier `foo` <col:7, col:10>
// CHECK-NEXT: |  |  `--NumberLiteral `3` <col:14, col:15>
// CHECK-NEXT: |  `--BlockStmt <line:45, line:45>
// CHECK-NEXT: |   `--ContentStmt <line:45, col:17:23>
// CHECK-NEXT: |   `--Content <col:17, col:23>
// CHECK-NEXT: |   `--StringLiteral `Three!` <col:17, col:23>
// CHECK-NEXT: `--ElseBranch <col:7, col:13>
// CHECK-NEXT: `--BlockStmt <line:46, line:46>
// CHECK-NEXT: `--ContentStmt <line:46, col:13:28>
// CHECK-NEXT: `--Content <col:13, col:28>
// CHECK-NEXT: `--StringLiteral `Something else!` <col:13, col:28>
~ temp foo = 3
{
- foo == 1: One!
- foo == 2: Two!
- foo == 3: Three!
- else: Something else!
}