From 27f499dfbb2dd926611865babbab90e58a96dcb5 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 30 May 2020 17:48:14 -0300 Subject: [PATCH] add basics of generic command parsing --- src/lang.zig | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/lang.zig b/src/lang.zig index 88dcda1..2b3c003 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -318,32 +318,51 @@ pub const Lang = struct { self.doError("No command given", .{}); continue; } - var command = cmd_opt.?; + const command_string = cmd_opt.?; - var ctype_opt = self.getCommand(command); - var ctype: CommandType = undefined; - if (ctype_opt) |ctype_val| { - ctype = ctype_val; - } else { - self.doError("Unknown command '{}' ({})", .{ command, command.len }); + var found: bool = false; + + inline for (@typeInfo(NewCommand).Struct.decls) |cmd_struct_decl| { + const struct_name = cmd_struct_decl.name; + comptime var lowered_command_name = [_]u8{0} ** struct_name.len; + comptime { + for (struct_name) |c, i| { + lowered_command_name[i] = std.ascii.toLower(c); + } + } + + if (std.mem.eql(u8, &lowered_command_name, command_string)) { + found = true; + + // Based on the command struct fields, we need to decide + // how to actually get its arguments and creating the struct + // itself. + + const command_struct = cmd_struct_decl.data.Type; + var cmd: command_struct = undefined; + inline for (@typeInfo(command_struct).Struct.fields) |cmd_field| { + + // TODO: crash when no arguments are left but we still need + // arguments... + const argument = tok_it.next().?; + const argument_value = switch (cmd_field.field_type) { + usize => try std.fmt.parseInt(usize, arg, 10), + i32 => try std.fmt.parseInt(i32, arg, 10), + f32 => try std.fmt.parseFloat(f32, arg), + else => @panic("Invalid parameter type (" ++ @typeName(cmd_field.field_type) ++ ") left on command struct " ++ @typeName(command_struct) ++ "."), + }; + + @field(cmd, cmd_field.name) = argument_value; + } + } + } + + if (!found) { + self.doError("Unknown command '{}' ({})", .{ command_string, command_string.len }); continue; } - var args = ArgList.init(self.allocator); - errdefer args.deinit(); - - while (tok_it.next()) |arg| { - try args.append(arg); - } - - // construct final Command based on command - var cmd = Command{ .command = ctype, .args = args }; - self.validateCommand(cmd) catch |err| { - //self.doError("error validating command '{}': {}", command, err); - continue; - }; - - try cmds.append(cmd); + // try cmds.append(cmd); } if (self.has_error) return ParseError.ParseFail;