From 66b262beb290a212e20aa4e175eb35527c325814 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 6 Oct 2019 14:39:15 -0300 Subject: [PATCH 1/3] repl: open file as read and append to cmds before open as write closes #7 --- src/main.zig | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/main.zig b/src/main.zig index a54a7c5..502c52b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -28,12 +28,6 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { const scri_path = try (args_it.next(allocator) orelse @panic("expected scri path")); - var file = try std.fs.File.openWrite(scri_path); - defer file.close(); - - var out = file.outStream(); - var stream = &out.stream; - // the thing here is that 'load :0' would load the scri_path, since we // now have a 'repl' argument right before it. to counteract that, the // initial repl buffer contains 'load :1' instead. @@ -49,6 +43,37 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { defer cmds.deinit(); + // if the scri file already had commands, we add them up on the cmd list + var file_read = try std.fs.openReead(scri_path); + const total_bytes = try file_read.getEndPos(); + + if (total_bytes > 0) { + var scri_existing = try allocator.alloc(u8, total_bytes); + defer allocator.free(scri_existing); + + _ = try file.read(slice); + file_read.close(); + + var existing_cmds = try lang.parse(scri_existing); + defer existing_cmds.deinit(); + + // copy the existing command list into the repl's command list + var it = existing_cmds.iterator(); + while (it.next()) |existing_cmd| { + try cmds.append(existing_cmd); + } + } + + var file = try std.fs.File.openWrite(scri_path); + defer file.close(); + + var out = file.outStream(); + var stream = &out.stream; + + // since we opened the file for writing, it becomes empty, so, to ensure + // we don't fuck up later on, we print cmds before starting the repl + try printer.printList(cmds, stream); + // we keep // - a CommandList with the full commands we have right now // - a Command with the current last typed successful command @@ -99,6 +124,8 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { try printer.printList(cmds, stdout); continue; } else if (std.mem.eql(u8, line, "save")) { + // seek to 0 instead of appending the new command + // NOTE appending single command might be faster try file.seekTo(0); try printer.printList(cmds, stream); continue; From 80036c4c0d4c5dd351b4ecf7aca65a21a7c13dd7 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 6 Oct 2019 15:07:30 -0300 Subject: [PATCH 2/3] fix other things related to reading scri file on repl --- src/lang.zig | 1 + src/main.zig | 44 +++++++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/lang.zig b/src/lang.zig index 9724dfb..a75193b 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -140,6 +140,7 @@ pub const ArgList = std.ArrayList([]const u8); pub const KeywordMap = std.StringHashMap(CommandType); +/// A parser. pub const Lang = struct { allocator: *std.mem.Allocator, keywords: KeywordMap, diff --git a/src/main.zig b/src/main.zig index 502c52b..9e333f5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -25,45 +25,49 @@ fn wrapInCmdList(allocator: *std.mem.Allocator, cmd: langs.Command) !langs.Comma pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { var stdout_file = try std.io.getStdOut(); const stdout = &stdout_file.outStream().stream; - const scri_path = try (args_it.next(allocator) orelse @panic("expected scri path")); + var file_read = try std.fs.File.openRead(scri_path); + const total_bytes = try file_read.getEndPos(); + // the thing here is that 'load :0' would load the scri_path, since we // now have a 'repl' argument right before it. to counteract that, the // initial repl buffer contains 'load :1' instead. - var loadargs = langs.ArgList.init(allocator); - defer loadargs.deinit(); - try loadargs.append(":1"); - - var cmds = try wrapInCmdList(allocator, langs.Command{ - .command = .Load, - .args = loadargs, - }); + // TODO load should -1 the index if its on repl + var cmds = langs.CommandList.init(allocator); defer cmds.deinit(); - // if the scri file already had commands, we add them up on the cmd list - var file_read = try std.fs.openReead(scri_path); - const total_bytes = try file_read.getEndPos(); + var lang = langs.Lang.init(allocator); + defer lang.deinit(); if (total_bytes > 0) { + // those MUST BE long lived, we can't defer them here var scri_existing = try allocator.alloc(u8, total_bytes); - defer allocator.free(scri_existing); - - _ = try file.read(slice); - file_read.close(); - + _ = try file_read.read(scri_existing); var existing_cmds = try lang.parse(scri_existing); - defer existing_cmds.deinit(); // copy the existing command list into the repl's command list var it = existing_cmds.iterator(); while (it.next()) |existing_cmd| { try cmds.append(existing_cmd); } + } else { + // if there isn't any commands on the file, we load our default + // 'load :1' command + var loadargs = langs.ArgList.init(allocator); + // defer loadargs.deinit(); + try loadargs.append(":1"); + + try cmds.append(langs.Command{ + .command = .Load, + .args = loadargs, + }); } + file_read.close(); + var file = try std.fs.File.openWrite(scri_path); defer file.close(); @@ -72,6 +76,7 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { // since we opened the file for writing, it becomes empty, so, to ensure // we don't fuck up later on, we print cmds before starting the repl + try printer.printList(cmds, stdout); try printer.printList(cmds, stream); // we keep @@ -83,9 +88,6 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { // - one runner that gets copied from the original on every new // command the user issues - var lang = langs.Lang.init(allocator); - defer lang.deinit(); - var current: langs.Command = undefined; var runner = runners.Runner.init(allocator); From 7cf16f9ffa202ea68b669f27b7d8214cbff06bb5 Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 6 Oct 2019 15:12:19 -0300 Subject: [PATCH 3/3] deinit existing_cmds (not long lived) --- src/main.zig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main.zig b/src/main.zig index 9e333f5..7a05be3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -30,12 +30,6 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { var file_read = try std.fs.File.openRead(scri_path); const total_bytes = try file_read.getEndPos(); - // the thing here is that 'load :0' would load the scri_path, since we - // now have a 'repl' argument right before it. to counteract that, the - // initial repl buffer contains 'load :1' instead. - - // TODO load should -1 the index if its on repl - var cmds = langs.CommandList.init(allocator); defer cmds.deinit(); @@ -43,10 +37,15 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { defer lang.deinit(); if (total_bytes > 0) { - // those MUST BE long lived, we can't defer them here + // this MUST BE long lived (a reference to it is kept inside + // existing_cmds, and then passed along to cmds), + // we can't defer them here var scri_existing = try allocator.alloc(u8, total_bytes); _ = try file_read.read(scri_existing); + + // we can defer this because we copy the Command structs back to cmds var existing_cmds = try lang.parse(scri_existing); + defer existing_cmds.deinit(); // copy the existing command list into the repl's command list var it = existing_cmds.iterator(); @@ -56,8 +55,9 @@ pub fn doRepl(allocator: *std.mem.Allocator, args_it: var) !void { } else { // if there isn't any commands on the file, we load our default // 'load :1' command + + // TODO load should +1 the index if its on repl var loadargs = langs.ArgList.init(allocator); - // defer loadargs.deinit(); try loadargs.append(":1"); try cmds.append(langs.Command{