refactor: make room for loading and outputting pre-compiled files
This commit is contained in:
parent
3afbbb6ec2
commit
96866ba9ae
11 changed files with 537 additions and 433 deletions
146
src/Story.zig
146
src/Story.zig
|
|
@ -1,13 +1,14 @@
|
|||
//! Virtual machine state for story execution.
|
||||
const std = @import("std");
|
||||
const tokenizer = @import("tokenizer.zig");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const Ast = @import("Ast.zig");
|
||||
const AstGen = @import("AstGen.zig");
|
||||
const Module = @import("compile.zig").Module;
|
||||
const Compilation = @import("compile.zig").Compilation;
|
||||
pub const Loader = @import("Story/Loader.zig");
|
||||
pub const Object = @import("Story/Object.zig");
|
||||
const Dumper = @import("Story/Dumper.zig");
|
||||
pub const Dumper = @import("Story/Dumper.zig");
|
||||
const ink = @import("root.zig");
|
||||
const assert = std.debug.assert;
|
||||
const Story = @This();
|
||||
|
||||
gpa: std.mem.Allocator,
|
||||
|
|
@ -42,17 +43,6 @@ internal_counter: usize = 0,
|
|||
|
||||
pub const default_knot_name: [:0]const u8 = "$__main__$";
|
||||
|
||||
pub const VariableObserver = struct {
|
||||
callback: Callback,
|
||||
context: Context,
|
||||
|
||||
pub const Callback = *const fn (Value, Context) anyerror!void;
|
||||
|
||||
pub const Context = struct {
|
||||
ptr: *anyopaque,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Opcode = enum(u8) {
|
||||
/// Exit the VM normally.
|
||||
exit,
|
||||
|
|
@ -118,6 +108,17 @@ pub const Opcode = enum(u8) {
|
|||
_,
|
||||
};
|
||||
|
||||
pub const VariableObserver = struct {
|
||||
callback: Callback,
|
||||
context: Context,
|
||||
|
||||
pub const Callback = *const fn (Value, Context) anyerror!void;
|
||||
|
||||
pub const Context = struct {
|
||||
ptr: *anyopaque,
|
||||
};
|
||||
};
|
||||
|
||||
pub const CallFrame = struct {
|
||||
/// Pointer to the knot that initiated the call.
|
||||
callee: *Object.Knot,
|
||||
|
|
@ -936,70 +937,6 @@ pub fn dump(story: *Story, writer: *std.Io.Writer) !void {
|
|||
return Dumper.dump(story, writer);
|
||||
}
|
||||
|
||||
pub const LoadOptions = struct {
|
||||
filename: []const u8,
|
||||
error_writer: *std.Io.Writer,
|
||||
dump_writer: ?*std.Io.Writer = null,
|
||||
dump_use_color: bool = true,
|
||||
dump_ast: bool = false,
|
||||
dump_ir: bool = false,
|
||||
};
|
||||
|
||||
pub fn fromSourceBytes(
|
||||
gpa: std.mem.Allocator,
|
||||
source_bytes: [:0]const u8,
|
||||
options: LoadOptions,
|
||||
) !Story {
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_allocator.deinit();
|
||||
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
var comp = try Module.compile(gpa, arena, .{
|
||||
.source_bytes = source_bytes,
|
||||
.filename = options.filename,
|
||||
.dump_writer = options.dump_writer,
|
||||
.dump_use_color = options.dump_use_color,
|
||||
.dump_ast = options.dump_ast,
|
||||
.dump_ir = options.dump_ir,
|
||||
});
|
||||
defer comp.deinit();
|
||||
|
||||
if (comp.errors.items.len > 0) {
|
||||
for (comp.errors.items) |err| {
|
||||
try comp.renderError(options.error_writer, err);
|
||||
}
|
||||
return error.LoadFailed;
|
||||
}
|
||||
|
||||
// TODO: Make this configureable.
|
||||
const stack_size = 128;
|
||||
const eval_stack_ptr = try gpa.alloc(Value, stack_size);
|
||||
errdefer gpa.free(eval_stack_ptr);
|
||||
|
||||
const call_stack_ptr = try gpa.alloc(CallFrame, stack_size);
|
||||
errdefer gpa.free(call_stack_ptr);
|
||||
|
||||
var story: Story = .{
|
||||
.gpa = gpa,
|
||||
.arena = .init(gpa),
|
||||
.can_advance = false,
|
||||
.dump_writer = null,
|
||||
.stack = eval_stack_ptr,
|
||||
.call_stack = call_stack_ptr,
|
||||
};
|
||||
errdefer story.deinit();
|
||||
|
||||
try comp.setupStoryRuntime(gpa, &story);
|
||||
if (story.getKnot(Story.default_knot_name)) |knot| {
|
||||
try story.pushStack(.{ .object = &knot.base });
|
||||
try story.divert(knot, 0);
|
||||
}
|
||||
return story;
|
||||
}
|
||||
|
||||
var read_buffer: [4096]u8 align(std.heap.page_size_min) = undefined;
|
||||
|
||||
pub const LoadFileOptions = struct {
|
||||
error_writer: *std.Io.Writer,
|
||||
};
|
||||
|
|
@ -1009,6 +946,7 @@ pub fn readSourceFile(
|
|||
filename: []const u8,
|
||||
options: LoadFileOptions,
|
||||
) !Story {
|
||||
var read_buffer: [4096]u8 align(std.heap.page_size_min) = undefined;
|
||||
// FIXME: Temporary until 0.16.x
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_allocator.deinit();
|
||||
|
|
@ -1030,3 +968,53 @@ pub fn readSourceFile(
|
|||
.dump_ir = false,
|
||||
});
|
||||
}
|
||||
|
||||
pub const LoadOptions = struct {
|
||||
filename: [:0]const u8,
|
||||
errors: *std.ArrayListUnmanaged(Compilation.Error),
|
||||
stack_size: usize = 128,
|
||||
};
|
||||
|
||||
pub fn fromSourceBytes(
|
||||
gpa: std.mem.Allocator,
|
||||
source_bytes: [:0]const u8,
|
||||
options: LoadOptions,
|
||||
) !Story {
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
var tree = try Ast.parse(gpa, arena, source_bytes, options.filename, 0);
|
||||
defer tree.deinit(gpa);
|
||||
|
||||
var ir = try AstGen.generate(gpa, &tree);
|
||||
defer ir.deinit(gpa);
|
||||
|
||||
var cu = Compilation.build(gpa, tree, ir, options.errors) catch |err| switch (err) {
|
||||
else => |e| return e,
|
||||
};
|
||||
defer cu.deinit();
|
||||
|
||||
if (cu.hasCompileErrors()) {
|
||||
return error.CompilationError;
|
||||
}
|
||||
return .fromCompilation(gpa, &cu, .{
|
||||
.stack_size = options.stack_size,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn fromCompilation(
|
||||
gpa: std.mem.Allocator,
|
||||
cu: *Compilation,
|
||||
options: Loader.Options,
|
||||
) !Story {
|
||||
return Loader.fromCompilation(gpa, cu, options);
|
||||
}
|
||||
|
||||
pub fn fromCachedCompilation(
|
||||
gpa: std.mem.Allocator,
|
||||
bytes: []const u8,
|
||||
options: Loader.Options,
|
||||
) !Story {
|
||||
return Loader.fromCachedCompilation(gpa, bytes, options);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue