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", .{});
|
self.doError("No command given", .{});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var command = cmd_opt.?;
|
const command_string = cmd_opt.?;
|
||||||
|
|
||||||
var ctype_opt = self.getCommand(command);
|
var found: bool = false;
|
||||||
var ctype: CommandType = undefined;
|
|
||||||
if (ctype_opt) |ctype_val| {
|
inline for (@typeInfo(NewCommand).Struct.decls) |cmd_struct_decl| {
|
||||||
ctype = ctype_val;
|
const struct_name = cmd_struct_decl.name;
|
||||||
} else {
|
comptime var lowered_command_name = [_]u8{0} ** struct_name.len;
|
||||||
self.doError("Unknown command '{}' ({})", .{ command, command.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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = ArgList.init(self.allocator);
|
// try cmds.append(cmd);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.has_error) return ParseError.ParseFail;
|
if (self.has_error) return ParseError.ParseFail;
|
||||||
|
|
Loading…
Reference in a new issue