Skip to content

Commit

Permalink
feat(repl): Dump last added global or local when input processed
Browse files Browse the repository at this point in the history
  • Loading branch information
giann committed Oct 20, 2023
1 parent 72ada3e commit 37d4e61
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 154 deletions.
2 changes: 1 addition & 1 deletion src/buzz_api.zig
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ fn valueDump(value: Value, vm: *VM, seen: *std.AutoHashMap(*_obj.Obj, void), dep
}

/// Dump value
export fn bz_valueDump(value: Value, vm: *VM) void {
pub export fn bz_valueDump(value: Value, vm: *VM) void {
var seen = std.AutoHashMap(*_obj.Obj, void).init(vm.gc.allocator);
defer seen.deinit();

Expand Down
152 changes: 2 additions & 150 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,155 +18,7 @@ const BuildOptions = @import("build_options");
const clap = @import("ext/clap/clap.zig");
const GarbageCollector = @import("memory.zig").GarbageCollector;
const MIRJIT = @import("mirjit.zig");
const ln = @import("linenoise.zig");

fn toNullTerminated(allocator: std.mem.Allocator, string: []const u8) ![:0]u8 {
return allocator.dupeZ(u8, string);
}

fn repl(allocator: Allocator) !void {
var import_registry = ImportRegistry.init(allocator);
var gc = GarbageCollector.init(allocator);
gc.type_registry = TypeRegistry{
.gc = &gc,
.registry = std.StringHashMap(*ObjTypeDef).init(allocator),
};
var imports = std.StringHashMap(Parser.ScriptImport).init(allocator);
var vm = try VM.init(&gc, &import_registry, .Repl);
vm.mir_jit = if (BuildOptions.jit)
MIRJIT.init(&vm)
else
null;
defer {
if (vm.mir_jit != null) {
vm.mir_jit.?.deinit();
vm.mir_jit = null;
}
}
var parser = Parser.init(
&gc,
&imports,
false,
.Repl,
);
var codegen = CodeGen.init(
&gc,
&parser,
.Repl,
if (vm.mir_jit) |*jit| jit else null,
);
defer {
codegen.deinit();
vm.deinit();
parser.deinit();
// gc.deinit();
var it = imports.iterator();
while (it.next()) |kv| {
kv.value_ptr.*.globals.deinit();
}
imports.deinit();
// TODO: free type_registry and its keys which are on the heap
}

var stdout = std.io.getStdOut().writer();
var stderr = std.io.getStdErr().writer();
var stdin = std.io.getStdIn().reader();
_ = stdin;
printBanner(stdout, false);

_ = ln.linenoiseHistorySetMaxLen(100);
_ = ln.linenoiseHistoryLoad("./buzz_history");
while (true) {
// _ = stdout.write("\n→ ") catch unreachable;
// const read_source = stdin.readUntilDelimiterOrEofAlloc(
// gc.allocator,
// '\n',
// 16 * 8 * 64,
// ) catch unreachable;

const read_source = ln.linenoise("> ");
const source = std.mem.span(read_source);

_ = ln.linenoiseHistoryAdd(source);
_ = ln.linenoiseHistorySave("./buzz_history");

if (source.len > 0) {
runSource(
source,
"REPL",
&vm,
&codegen,
&parser,
&gc,
) catch |err| {
if (BuildOptions.debug) {
stderr.print("Failed with error {}\n", .{err}) catch unreachable;
}
};
}
}
}

fn runSource(
source: []const u8,
file_name: []const u8,
vm: *VM,
codegen: *CodeGen,
parser: *Parser,
gc: *GarbageCollector,
) !void {
var total_timer = std.time.Timer.start() catch unreachable;
var timer = try std.time.Timer.start();
var parsing_time: u64 = undefined;
var codegen_time: u64 = undefined;
var running_time: u64 = undefined;

if (try parser.parse(source, file_name)) |function_node| {
parsing_time = timer.read();
timer.reset();

if (try codegen.generate(FunctionNode.cast(function_node).?)) |function| {
codegen_time = timer.read();
timer.reset();

try vm.interpret(
function,
null,
);

running_time = timer.read();
} else {
return CompileError.Recoverable;
}

if (BuildOptions.show_perf) {
const parsing_ms: f64 = @as(f64, @floatFromInt(parsing_time)) / 1000000;
const codegen_ms: f64 = @as(f64, @floatFromInt(codegen_time)) / 1000000;
const running_ms: f64 = @as(f64, @floatFromInt(running_time)) / 1000000;
const gc_ms: f64 = @as(f64, @floatFromInt(gc.gc_time)) / 1000000;
const jit_ms: f64 = if (vm.mir_jit) |jit|
@as(f64, @floatFromInt(jit.jit_time)) / 1000000
else
0;
std.debug.print(
"\u{001b}[2mParsing: {d} ms\nCodegen: {d} ms\nRun: {d} ms\nJIT: {d} ms\nGC: {d} ms\nTotal: {d} ms\nFull GC: {} | GC: {} | Max allocated: {} bytes\n\u{001b}[0m",
.{
parsing_ms,
codegen_ms,
running_ms,
jit_ms,
gc_ms,
@as(f64, @floatFromInt(total_timer.read())) / 1000000,
gc.full_collection_count,
gc.light_collection_count,
gc.max_allocated,
},
);
}
} else {
return CompileError.Recoverable;
}
}
const repl = @import("repl.zig").repl;

fn runFile(allocator: Allocator, file_name: []const u8, args: [][:0]u8, flavor: RunFlavor) !void {
var total_timer = std.time.Timer.start() catch unreachable;
Expand Down Expand Up @@ -434,7 +286,7 @@ pub fn main() !void {

var positionals = std.ArrayList([:0]u8).init(allocator);
for (res.positionals) |pos| {
try positionals.append(try toNullTerminated(allocator, pos));
try positionals.append(try allocator.dupeZ(u8, pos));
}
defer {
for (positionals.items) |pos| {
Expand Down
11 changes: 8 additions & 3 deletions src/parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2524,8 +2524,13 @@ pub const Parser = struct {
}

if (parsed_type == null and value != null and value.?.type_def != null) {
self.current.?.locals[slot].type_def = value.?.type_def.?;
var_type = value.?.type_def.?;

if (self.current.?.scope_depth == 0) {
self.globals.items[slot].type_def = var_type;
} else {
self.current.?.locals[slot].type_def = var_type;
}
} else if (parsed_type == null) {
self.reporter.reportErrorAt(
.inferred_type,
Expand Down Expand Up @@ -4593,9 +4598,9 @@ pub const Parser = struct {
self.reporter.reportErrorFmt(
.field_access,
callee.location,
"{s} is not field accessible",
"`{s}` is not field accessible",
.{
@tagName(callee_def_type),
(try callee.type_def.?.toStringAlloc(self.gc.allocator)).items,
},
);
},
Expand Down
Loading

0 comments on commit 37d4e61

Please sign in to comment.