summaryrefslogtreecommitdiff
path: root/src/parser.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.zig')
-rw-r--r--src/parser.zig110
1 files changed, 55 insertions, 55 deletions
diff --git a/src/parser.zig b/src/parser.zig
index 7bbfdab..af465f8 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -46,8 +46,8 @@ const Lexer = struct {
}
fn readWord(self: *Lexer, allocator: Allocator) ![]const u8 {
- var word = ArrayList(u8).init(allocator);
- defer word.deinit();
+ var word = ArrayList(u8){};
+ defer word.deinit(allocator);
var in_quotes = false;
var quote_char: u8 = '"';
@@ -63,18 +63,18 @@ const Lexer = struct {
in_quotes = false;
self.advance();
} else {
- try word.append(ch);
+ try word.append(allocator, ch);
self.advance();
}
},
'|', '>', '<', '\n' => {
if (!in_quotes) break;
- try word.append(ch);
+ try word.append(allocator, ch);
self.advance();
},
else => {
if (!in_quotes and std.ascii.isWhitespace(ch)) break;
- try word.append(ch);
+ try word.append(allocator, ch);
self.advance();
},
}
@@ -127,7 +127,7 @@ const Lexer = struct {
}
pub fn tokenize(self: *Lexer, allocator: Allocator) !ArrayList(Token) {
- var tokens = ArrayList(Token).init(allocator);
+ var tokens = ArrayList(Token){};
while (true) {
const token = try self.nextToken(allocator);
@@ -135,7 +135,7 @@ const Lexer = struct {
.Eof => true,
else => false,
};
- try tokens.append(token);
+ try tokens.append(allocator, token);
if (is_eof) break;
}
@@ -206,7 +206,7 @@ const Parser = struct {
fn parseRedirectedCommand(self: *Parser) !Command {
const command = try self.parseSimpleCommand();
- var redirects = ArrayList(Redirect).init(self.allocator);
+ var redirects = ArrayList(Redirect){};
while (true) {
const redirect_type = switch (self.currentToken()) {
@@ -221,14 +221,14 @@ const Parser = struct {
const target_str = try self.expectWord();
const target = try parseFilespec(self.allocator, target_str);
- try redirects.append(Redirect{
+ try redirects.append(self.allocator, Redirect{
.redirect_type = redirect_type,
.target = target,
});
}
if (redirects.items.len == 0) {
- redirects.deinit();
+ redirects.deinit(self.allocator);
return command;
} else {
const command_ptr = try self.allocator.create(Command);
@@ -242,23 +242,23 @@ const Parser = struct {
.Eof, .Newline => return Command.Empty,
.Word => |command_name| {
self.advance();
- var args = ArrayList([]const u8).init(self.allocator);
+ var args = ArrayList([]const u8){};
// Collect arguments
while (true) {
switch (self.currentToken()) {
.Word => |arg| {
- try args.append(arg);
+ try args.append(self.allocator, arg);
self.advance();
},
else => break,
}
}
- const result = try self.parseBuiltinCommand(command_name, args);
+ const result = try self.parseBuiltinCommand(command_name, &args);
// For builtin commands, free the args ArrayList (the strings inside belong to tokens and will be freed later)
if (result == .Builtin) {
- args.deinit();
+ args.deinit(self.allocator);
}
return result;
},
@@ -266,35 +266,35 @@ const Parser = struct {
}
}
- fn parseBuiltinCommand(self: *Parser, command_name: []const u8, args: ArrayList([]const u8)) !Command {
+ fn parseBuiltinCommand(self: *Parser, command_name: []const u8, args: *ArrayList([]const u8)) !Command {
const cmd_upper = try std.ascii.allocUpperString(self.allocator, command_name);
defer self.allocator.free(cmd_upper);
// Check for /? help flag first
- if (hasHelpFlag(args.items)) {
+ if (hasHelpFlag(args.*.items)) {
const cmd_copy = try self.allocator.dupe(u8, cmd_upper);
return Command{ .Builtin = BuiltinCommand{ .Help = .{ .command = cmd_copy } } };
}
if (std.mem.eql(u8, cmd_upper, "HELP")) {
- const help_command = if (args.items.len > 0)
- try self.allocator.dupe(u8, args.items[0])
+ const help_command = if (args.*.items.len > 0)
+ try self.allocator.dupe(u8, args.*.items[0])
else
null;
return Command{ .Builtin = BuiltinCommand{ .Help = .{ .command = help_command } } };
} else if (std.mem.eql(u8, cmd_upper, "ECHO")) {
- if (args.items.len == 0) {
+ if (args.*.items.len == 0) {
return Command{ .Builtin = BuiltinCommand.EchoPlain };
} else {
- const first_arg_upper = try std.ascii.allocUpperString(self.allocator, args.items[0]);
+ const first_arg_upper = try std.ascii.allocUpperString(self.allocator, args.*.items[0]);
defer self.allocator.free(first_arg_upper);
- if (std.mem.eql(u8, first_arg_upper, "ON") and args.items.len == 1) {
+ if (std.mem.eql(u8, first_arg_upper, "ON") and args.*.items.len == 1) {
return Command{ .Builtin = BuiltinCommand.EchoOn };
- } else if (std.mem.eql(u8, first_arg_upper, "OFF") and args.items.len == 1) {
+ } else if (std.mem.eql(u8, first_arg_upper, "OFF") and args.*.items.len == 1) {
return Command{ .Builtin = BuiltinCommand.EchoOff };
} else {
- const message = try std.mem.join(self.allocator, " ", args.items);
+ const message = try std.mem.join(self.allocator, " ", args.*.items);
return Command{ .Builtin = BuiltinCommand{ .EchoText = .{ .message = message } } };
}
}
@@ -307,9 +307,9 @@ const Parser = struct {
} else if (std.mem.eql(u8, cmd_upper, "VERIFY")) {
return Command{ .Builtin = BuiltinCommand.Verify };
} else if (std.mem.eql(u8, cmd_upper, "DIR")) {
- const separated = try self.separateFlagsFromArgs(args.items);
- defer separated.flags.deinit();
- defer separated.positional.deinit();
+ var separated = try self.separateFlagsFromArgs(args.*.items);
+ defer separated.flags.deinit(self.allocator);
+ defer separated.positional.deinit(self.allocator);
const path = if (separated.positional.items.len == 0)
try self.allocator.dupe(u8, ".")
@@ -338,74 +338,74 @@ const Parser = struct {
} else if (std.mem.eql(u8, cmd_upper, "TIME")) {
return Command{ .Builtin = BuiltinCommand.Time };
} else if (std.mem.eql(u8, cmd_upper, "TYPE")) {
- if (args.items.len == 0) {
+ if (args.*.items.len == 0) {
return error.ExpectedWord; // Will be caught and show "Bad command or file name"
}
- const file_spec = try parseFilespec(self.allocator, args.items[0]);
+ const file_spec = try parseFilespec(self.allocator, args.*.items[0]);
return Command{ .Builtin = BuiltinCommand{ .Type = .{ .file = file_spec } } };
} else if (std.mem.eql(u8, cmd_upper, "SORT")) {
return Command{ .Builtin = BuiltinCommand.Sort };
} else if (std.mem.eql(u8, cmd_upper, "CD") or std.mem.eql(u8, cmd_upper, "CHDIR")) {
- const path = if (args.items.len == 0)
+ const path = if (args.*.items.len == 0)
try self.allocator.dupe(u8, "")
else
- try self.allocator.dupe(u8, args.items[0]);
+ try self.allocator.dupe(u8, args.*.items[0]);
return Command{ .Builtin = BuiltinCommand{ .Chdir = .{ .path = path } } };
} else if (std.mem.eql(u8, cmd_upper, "COPY")) {
- if (args.items.len < 2) {
+ if (args.*.items.len < 2) {
return error.ExpectedWord; // Will show "Bad command or file name"
}
- const from_spec = try parseFilespec(self.allocator, args.items[0]);
- const to_spec = try parseFilespec(self.allocator, args.items[1]);
+ const from_spec = try parseFilespec(self.allocator, args.*.items[0]);
+ const to_spec = try parseFilespec(self.allocator, args.*.items[1]);
return Command{ .Builtin = BuiltinCommand{ .Copy = .{ .from = from_spec, .to = to_spec } } };
} else if (std.mem.eql(u8, cmd_upper, "DEL") or std.mem.eql(u8, cmd_upper, "ERASE")) {
- if (args.items.len == 0) {
+ if (args.*.items.len == 0) {
return error.ExpectedWord; // Will show "Bad command or file name"
}
- const path = try self.allocator.dupe(u8, args.items[0]);
+ const path = try self.allocator.dupe(u8, args.*.items[0]);
return Command{ .Builtin = BuiltinCommand{ .Remove = .{ .path = path } } };
} else if (std.mem.eql(u8, cmd_upper, "MD") or std.mem.eql(u8, cmd_upper, "MKDIR")) {
- if (args.items.len == 0) {
+ if (args.*.items.len == 0) {
return error.ExpectedWord; // Will show "Bad command or file name"
}
- const path = try self.allocator.dupe(u8, args.items[0]);
+ const path = try self.allocator.dupe(u8, args.*.items[0]);
return Command{ .Builtin = BuiltinCommand{ .Mkdir = .{ .path = path } } };
} else if (std.mem.eql(u8, cmd_upper, "RD") or std.mem.eql(u8, cmd_upper, "RMDIR")) {
- if (args.items.len == 0) {
+ if (args.*.items.len == 0) {
return error.ExpectedWord; // Will show "Bad command or file name"
}
- const path = try self.allocator.dupe(u8, args.items[0]);
+ const path = try self.allocator.dupe(u8, args.*.items[0]);
return Command{ .Builtin = BuiltinCommand{ .Rmdir = .{ .path = path } } };
} else if (std.mem.eql(u8, cmd_upper, "REN") or std.mem.eql(u8, cmd_upper, "RENAME")) {
- if (args.items.len < 2) {
+ if (args.*.items.len < 2) {
return error.ExpectedWord; // Will show "Bad command or file name"
}
- const from_spec = try parseFilespec(self.allocator, args.items[0]);
- const to_spec = try parseFilespec(self.allocator, args.items[1]);
+ const from_spec = try parseFilespec(self.allocator, args.*.items[0]);
+ const to_spec = try parseFilespec(self.allocator, args.*.items[1]);
return Command{ .Builtin = BuiltinCommand{ .Rename = .{ .from = from_spec, .to = to_spec } } };
} else if (std.mem.eql(u8, cmd_upper, "MOVE")) {
// MOVE command is more complex - for now just show not implemented
return Command{ .Builtin = BuiltinCommand.Move };
} else if (std.mem.eql(u8, cmd_upper, "PATH")) {
- if (args.items.len == 0) {
+ if (args.*.items.len == 0) {
return Command{ .Builtin = BuiltinCommand.PathGet };
} else {
// PATH=value or PATH value
- const value = if (std.mem.startsWith(u8, args.items[0], "="))
- try self.allocator.dupe(u8, args.items[0][1..]) // Skip the '='
+ const value = if (std.mem.startsWith(u8, args.*.items[0], "="))
+ try self.allocator.dupe(u8, args.*.items[0][1..]) // Skip the '='
else
- try self.allocator.dupe(u8, args.items[0]);
+ try self.allocator.dupe(u8, args.*.items[0]);
return Command{ .Builtin = BuiltinCommand{ .PathSet = .{ .value = value } } };
}
} else {
// External command - need to duplicate all strings
const program_copy = try self.allocator.dupe(u8, command_name);
- var args_copy = ArrayList([]const u8).init(self.allocator);
- for (args.items) |arg| {
+ var args_copy = ArrayList([]const u8){};
+ for (args.*.items) |arg| {
const arg_copy = try self.allocator.dupe(u8, arg);
- try args_copy.append(arg_copy);
+ try args_copy.append(self.allocator, arg_copy);
}
- args.deinit(); // Free the original args list (but not the strings, as they belong to tokens)
+ args.*.deinit(self.allocator); // Free the original args list (but not the strings, as they belong to tokens)
return Command{ .External = .{ .program = program_copy, .args = args_copy } };
}
}
@@ -420,14 +420,14 @@ const Parser = struct {
}
fn separateFlagsFromArgs(self: *Parser, args: []const []const u8) !struct { flags: ArrayList([]const u8), positional: ArrayList([]const u8) } {
- var flags = ArrayList([]const u8).init(self.allocator);
- var positional = ArrayList([]const u8).init(self.allocator);
+ var flags = ArrayList([]const u8){};
+ var positional = ArrayList([]const u8){};
for (args) |arg| {
if (arg.len > 0 and arg[0] == '/') {
- try flags.append(arg);
+ try flags.append(self.allocator, arg);
} else {
- try positional.append(arg);
+ try positional.append(self.allocator, arg);
}
}
@@ -463,7 +463,7 @@ pub fn parse(input: []const u8, allocator: Allocator) !Command {
else => {},
}
}
- tokens.deinit();
+ tokens.deinit(allocator);
}
var parser = Parser.init(tokens, allocator);