Skip to content

Commit

Permalink
Many internal refactors, split stdlib from dt-only things
Browse files Browse the repository at this point in the history
  • Loading branch information
booniepepper committed Jul 10, 2023
1 parent b5c28d2 commit 6b3557c
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 96 deletions.
8 changes: 8 additions & 0 deletions demos/shell.dt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env dt

# TODO: Try making a very simple repl-based shell

ls .s

repl

11 changes: 3 additions & 8 deletions src/builtins.zig
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,9 @@ pub fn norm(dt: *DtMachine) !void {

fn _p(val: DtVal, allocator: Allocator, writer: std.fs.File.Writer) !void {
switch (val) {
.string => |s| {
var unescaped = try std.mem.replaceOwned(u8, allocator, s, "\\n", "\n");
unescaped = try std.mem.replaceOwned(u8, allocator, unescaped, "\\\"", "\"");
try writer.print("{s}", .{unescaped});
},
else => {
try val.print(allocator);
},
// When printing strings, do not show " around a string.
.string => |s| try writer.print("{s}", .{s}),
else => try val.print(allocator),
}
}

Expand Down
52 changes: 52 additions & 0 deletions src/dt.dt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
### Flags and such ###

[ [ action flag ]:
args [ flag eq? ] any?
action swap do?
] \handle-flag def

[ "dt " p version pl ] \print-version def

[ [ print-version 0 exit ] "--version" handle-flag ] \--version def

[ print-version
[ "USAGE: dt FLAGS CODE..."
"dt is \"duct tape\" for your unix pipes."
""
"dt can be used in pipes to transform data with general purpose programming"
"operations. It can also excel in short shebang scripts, or be explored as"
"an interactive REPL (read-eval-print loop)."
""
"More info at https://dt.plumbing"
] pls
0 exit
] \print-help def

[ [ print-help 0 exit ] "--help" handle-flag ] \--help def

[ --help --version ] \handle-flags def

[ handle-flags args unwords eval ] \run-args def!


### PIPE things ###

[ read-lines run-args ] \pipe-thru-args def!


### Shebang things ###

[ args deq swap drop ] \shebang-args def!


### REPL things ###

[ red "dt " p version pl norm inspire pl ] \repl-greet def

[ \.q \quit def
\.q \exit def
] \repl-prelude def

[ handle-flags repl-greet repl-prelude repl ] \main-repl def!

[ "» " p read-line eval repl ] \repl def!
10 changes: 6 additions & 4 deletions src/interpret.zig
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ pub const DtMachine = struct {
return DtError.CommandUndefined;
}

pub fn loadFile(self: *DtMachine, code: []const u8) !void {
var toks = Token.parse(self.alloc, code);
while (try toks.next()) |token| try self.interpret(token);
}

pub fn red(self: *DtMachine) !void {
try self.norm();
try self.stdoutConfig.setColor(stdout, Color.red);
Expand Down Expand Up @@ -374,10 +379,7 @@ pub const DtVal = union(enum) {
}
try stdout.print("]", .{});
},
.string => |s| {
const escaped = try string.escape(allocator, s);
try stdout.print("\"{s}\"", .{escaped});
},
.string => |s| try stdout.print("\"{s}\"", .{s}),
.err => |e| try stdout.print("~{s}~", .{e}),
}
}
Expand Down
74 changes: 32 additions & 42 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const builtins = @import("builtins.zig");
pub const version = "0.11.1"; // Update in build.zig.zon as well. TODO: Change to @import when it's supported for zon

const stdlib = @embedFile("stdlib.dt");
const dtlib = @embedFile("dt.dt");

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
Expand All @@ -28,73 +29,62 @@ pub fn main() !void {
var machine = try DtMachine.init(arena.allocator());

try builtins.defineAll(&machine);
try machine.loadFile(stdlib);
try machine.loadFile(dtlib);

try loadStdlib(arena.allocator(), &machine);
const stdinPiped = !std.io.getStdIn().isTty();
const stdoutPiped = !std.io.getStdOut().isTty();

if (try readShebangFile(arena.allocator())) |fileContents| {
var toks = Token.parse(arena.allocator(), fileContents);
return while (try toks.next()) |token| try machine.interpret(token);
} else if (!std.io.getStdIn().isTty()) {
return machine.loadFile(fileContents) catch |e| return doneOrDie(&machine, e);
} else if (stdinPiped) {
return handlePipedStdin(&machine);
} else if (!std.io.getStdOut().isTty()) {
} else if (stdoutPiped) {
return handlePipedStdoutOnly(&machine);
}

return readEvalPrintLoop(&machine);
}

// TODO: Can this be done at comptime somehow?
fn loadStdlib(allocator: Allocator, machine: *DtMachine) !void {
var toks = Token.parse(allocator, stdlib);
while (try toks.next()) |token| try machine.interpret(token);
fn handlePipedStdin(dt: *DtMachine) !void {
dt.handleCmd("pipe-thru-args") catch |e| return doneOrDie(dt, e);
}

fn handlePipedStdin(machine: *DtMachine) !void {
machine.interpret(.{ .term = "pipe-thru-args" }) catch |e| {
if (e == error.BrokenPipe) return;

try machine.red();
try stderr.print("RIP: {any}\n", .{e});
try machine.norm();

std.os.exit(1);
};
}

fn handlePipedStdoutOnly(machine: *DtMachine) !void {
machine.interpret(.{ .term = "run-args" }) catch |e| {
if (e == error.BrokenPipe) return;

try machine.red();
try stderr.print("RIP: {any}\n", .{e});
try machine.norm();

std.os.exit(1);
};
fn handlePipedStdoutOnly(dt: *DtMachine) !void {
dt.handleCmd("run-args") catch |e| return doneOrDie(dt, e);
}

fn readEvalPrintLoop(machine: *DtMachine) !void {
machine.interpret(.{ .term = "run-args" }) catch |e| {
try machine.red();
try stderr.print("RIP: {any}\n", .{e});
try machine.norm();
fn readEvalPrintLoop(dt: *DtMachine) !void {
dt.handleCmd("run-args") catch |e| return doneOrDie(dt, e);

std.os.exit(1);
};

while (true) machine.interpret(.{ .term = "main-repl" }) catch |e| switch (e) {
while (true) dt.handleCmd("main-repl") catch |e| switch (e) {
error.EndOfStream => {
try stderr.print("\n", .{});
return;
},
else => {
try machine.red();
try dt.red();
try stderr.print("Recovering from: {any}\n", .{e});
try machine.norm();
try dt.norm();
},
};
}

fn doneOrDie(dt: *DtMachine, reason: anyerror) !void {
try stderr.print("\n", .{});
switch (reason) {
error.EndOfStream => return,
error.BrokenPipe => return,
else => {
try dt.red();
try stderr.print("RIP: {any}\n", .{reason});
try dt.norm();

std.os.exit(1);
},
}
}

fn readShebangFile(allocator: Allocator) !?[]const u8 {
var args = std.process.args();
_ = args.skip();
Expand Down
36 changes: 0 additions & 36 deletions src/stdlib.dt
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,6 @@
[ def? not ] \undef? def


### Flags and such ###

[ [ action flag ]:
args [ flag eq? ] any?
action swap do?
] \handle-flag def

[ "dt " p version pl ] \print-version def
[ [ print-version 0 exit ] "--version" handle-flag ] \--version def

[ "Good luck, this help hasn't been finished yet." pl 0 exit ] \print-help def
[ [ print-help 0 exit ] "--help" handle-flag ] \--help def

[ --help --version ] \handle-flags def

[ handle-flags args unwords eval ] \run-args def


### PIPE things ###

[ read-lines run-args ] \pipe-thru-args def


### Shebang things ###

[ args deq swap drop ] \shebang-args def


### REPL things ###

[ red "dt " p version pl norm inspire pl ] \repl-greet def
[ handle-flags repl-greet repl ] \main-repl def
[ "» " p read-line eval repl ] \repl def
[ .q ] \quit def


### Display ###

[ p nl ] \pl def
Expand Down
9 changes: 3 additions & 6 deletions src/string.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,11 @@ pub fn escape(allocator: Allocator, unescaped: String) !String {
}

pub fn unescape(allocator: Allocator, unescaped: String) !String {
var buf: []u8 = undefined;
var result = try allocator.dupe(u8, unescaped);

for (escapes) |esc| {
buf = std.mem.replaceOwned(u8, allocator, unescaped, esc.to, esc.from) catch |e| {
allocator.free(buf);
return e;
};
result = try std.mem.replaceOwned(u8, allocator, result, esc.to, esc.from);
}

return buf;
return result;
}

0 comments on commit 6b3557c

Please sign in to comment.