summaryrefslogtreecommitdiff
path: root/src/eval.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.zig')
-rw-r--r--src/eval.zig186
1 files changed, 20 insertions, 166 deletions
diff --git a/src/eval.zig b/src/eval.zig
index 9b00462..5aa43e4 100644
--- a/src/eval.zig
+++ b/src/eval.zig
@@ -34,10 +34,6 @@ const InputSource = cmdTypes.InputSource;
const STDOUT_BUFFER_SIZE: usize = 1024;
const STDERR_BUFFER_SIZE: usize = 1024;
-fn isLeapYear(year: u32) bool {
- return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0);
-}
-
pub fn executeCommand(command: Command, allocator: Allocator) !CommandStatus {
return executeCommandWithOutput(command, allocator, null, null);
}
@@ -48,122 +44,32 @@ fn executeCommandWithOutput(command: Command, allocator: Allocator, output_captu
.Builtin => |builtin_cmd| {
switch (builtin_cmd) {
- .EchoText => |echo| {
- const output = try std.fmt.allocPrint(allocator, "{s}\n", .{echo.message});
- defer allocator.free(output);
- if (output_capture) |capture| {
- try capture.write(output);
- } else {
- print("{s}", .{output});
- }
- return CommandStatus{ .Code = 0 };
+ .EchoText => |echo_text| {
+ return echo_text.eval(allocator, output_capture, input_source);
},
- .Cls => {
- if (output_capture == null) {
- // Clear screen - only works when not redirected
- print("\x1B[2J\x1B[H", .{});
- }
- return CommandStatus{ .Code = 0 };
+ .Cls => |cls| {
+ return cls.eval(allocator, output_capture, input_source);
},
.Exit => {
return CommandStatus.ExitShell;
},
- .EchoPlain => {
- const output = "ECHO is on\n";
- if (output_capture) |capture| {
- try capture.write(output);
- } else {
- print("{s}", .{output});
- }
- return CommandStatus{ .Code = 0 };
+ .EchoPlain => |echo_plain| {
+ return echo_plain.eval(allocator, output_capture, input_source);
},
- .EchoOn => {
- const output = "ECHO is on\n";
- if (output_capture) |capture| {
- try capture.write(output);
- } else {
- print("{s}", .{output});
- }
- return CommandStatus{ .Code = 0 };
+ .EchoOn => |echo_on| {
+ return echo_on.eval(allocator, output_capture, input_source);
},
- .EchoOff => {
- return CommandStatus{ .Code = 0 };
+ .EchoOff => |echo_off| {
+ return echo_off.eval(allocator, output_capture, input_source);
},
- .Ver => {
- const output = "MB-DOSE Version 6.22\n";
- if (output_capture) |capture| {
- try capture.write(output);
- } else {
- print("{s}", .{output});
- }
- return CommandStatus{ .Code = 0 };
+ .Ver => |ver| {
+ return ver.eval(allocator, output_capture, input_source);
},
- .Date => {
- const timestamp = std.time.timestamp();
- const epoch_seconds = @as(u64, @intCast(timestamp));
- const epoch_day = @divFloor(epoch_seconds, std.time.s_per_day);
-
- // Calculate days since Unix epoch (1970-01-01)
- // Unix epoch is 719163 days since year 1 AD
- const days_since_year_1 = epoch_day + 719163;
-
- // Simple algorithm to convert days to year/month/day
- var year: u32 = 1;
- var remaining_days = days_since_year_1;
-
- // Find the year
- while (true) {
- const days_in_year: u64 = if (isLeapYear(year)) 366 else 365;
- if (remaining_days < days_in_year) break;
- remaining_days -= days_in_year;
- year += 1;
- }
-
- // Days in each month (non-leap year)
- const days_in_month = [_]u32{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
- var month: u32 = 1;
- for (days_in_month, 1..) |days, m| {
- var month_days = days;
- // Adjust February for leap years
- if (m == 2 and isLeapYear(year)) {
- month_days = 29;
- }
-
- if (remaining_days < month_days) {
- month = @intCast(m);
- break;
- }
- remaining_days -= month_days;
- }
-
- const day = remaining_days + 1; // Days are 1-indexed
-
- const output = try std.fmt.allocPrint(allocator, "Current date is {d:0>2}/{d:0>2}/{d}\n", .{ month, day, year });
- defer allocator.free(output);
- if (output_capture) |capture| {
- try capture.write(output);
- } else {
- print("{s}", .{output});
- }
- return CommandStatus{ .Code = 0 };
+ .Date => |date| {
+ return date.eval(allocator, output_capture, input_source);
},
- .Time => {
- const timestamp = std.time.timestamp();
- const epoch_seconds = @as(u64, @intCast(timestamp));
- const day_seconds = epoch_seconds % std.time.s_per_day;
- const hours = day_seconds / std.time.s_per_hour;
- const minutes = (day_seconds % std.time.s_per_hour) / std.time.s_per_min;
- const seconds = day_seconds % std.time.s_per_min;
-
- const output = try std.fmt.allocPrint(allocator, "Current time is {d:0>2}:{d:0>2}:{d:0>2}\n", .{ hours, minutes, seconds });
- defer allocator.free(output);
- if (output_capture) |capture| {
- try capture.write(output);
- } else {
- print("{s}", .{output});
- }
- return CommandStatus{ .Code = 0 };
+ .Time => |time| {
+ return time.eval(allocator, output_capture, input_source);
},
.Dir => |dir| {
return dir.eval(allocator, output_capture, input_source);
@@ -171,54 +77,8 @@ fn executeCommandWithOutput(command: Command, allocator: Allocator, output_captu
.Type => |type_cmd| {
return type_cmd.eval(allocator, output_capture, input_source);
},
- .Sort => {
- var lines = ArrayList([]const u8).init(allocator);
- defer {
- for (lines.items) |line| {
- allocator.free(line);
- }
- lines.deinit();
- }
-
- // Read input lines
- if (input_source) |source| {
- // Read from input redirection
- while (try source.readLine(allocator)) |line| {
- try lines.append(line);
- }
- } else {
- // Read from stdin (simplified - just show message)
- const msg = "SORT: Use input redirection (< file.txt) to sort file contents\n";
- if (output_capture) |capture| {
- try capture.write(msg);
- } else {
- print("{s}", .{msg});
- }
- return CommandStatus{ .Code = 0 };
- }
-
- // Sort the lines
- std.mem.sort([]const u8, lines.items, {}, struct {
- fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool {
- return std.mem.order(u8, lhs, rhs) == .lt;
- }
- }.lessThan);
-
- // Output sorted lines
- var output_buffer = ArrayList(u8).init(allocator);
- defer output_buffer.deinit();
-
- for (lines.items) |line| {
- try output_buffer.writer().print("{s}\n", .{line});
- }
-
- if (output_capture) |capture| {
- try capture.write(output_buffer.items);
- } else {
- print("{s}", .{output_buffer.items});
- }
-
- return CommandStatus{ .Code = 0 };
+ .Sort => |sort| {
+ return sort.eval(allocator, output_capture, input_source);
},
.Chdir => |chdir| {
return chdir.eval(allocator, output_capture, input_source);
@@ -238,14 +98,8 @@ fn executeCommandWithOutput(command: Command, allocator: Allocator, output_captu
.Rename => |rename| {
return rename.eval(allocator, output_capture, input_source);
},
- .Move => {
- const error_msg = "MOVE command not yet implemented\n";
- if (output_capture) |capture| {
- try capture.write(error_msg);
- } else {
- print("{s}", .{error_msg});
- }
- return CommandStatus{ .Code = 1 };
+ .Move => |move| {
+ return move.eval(allocator, output_capture, input_source);
},
.PathGet => |path_get| {
return path_get.eval(allocator, output_capture, input_source);