diff options
Diffstat (limited to 'src/parser.zig')
-rw-r--r-- | src/parser.zig | 110 |
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); |