add basics of generic command parsing
This commit is contained in:
parent
d86e9efe43
commit
27f499dfbb
1 changed files with 41 additions and 22 deletions
63
src/lang.zig
63
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;
|
||||
|
|
Loading…
Reference in a new issue