get default arguments to work with console command registration

This commit is contained in:
Tuomas Katajisto 2025-07-27 23:18:51 +03:00
parent 7344c44576
commit 67384f30e9
3 changed files with 91 additions and 19 deletions

View File

@ -33,18 +33,35 @@ parse_argument_float :: (s: string) -> bool {
return false;
}
command_add :: (a: int, b: int) -> int {
return a + b;
#scope_export
string_to_bool :: (s: string) -> (bool, bool) {
if s == {
case "True"; #through;
case "TRUE"; #through;
case "1"; #through;
case "true"; #through;
case "t"; #through;
case "T";
return true, true;
case "False"; #through;
case "FALSE"; #through;
case "0"; #through;
case "false"; #through;
case "f"; #through;
case "F";
return false, true;
case;
return false, false;
}
if s == "true" || s == "TRUE" return true, true;
if s == "false" || s == "FALSE" return false, true;
return false, false;
}
command_add_front :: (args: []string) {
if verify_argument_count(2,2,args.count) {
array_add(*console_report, sprint("Argument count error: count = % not in range %..%.", args.count, 2, 2));
return;
}
}
#scope_export
add :: (a: int, b: int) -> int {
return a + b;
} @Command
console_command_procs : [..]([]string) -> string;
console_command_names : [..]string;
@ -118,13 +135,18 @@ draw_console :: (theme: *GR.Overall_Theme) {
array_add(*console_report, copy_string(tprint("> %", new)));
state.text = console_input_start;
found := false;
args := split(trim(new), " ");
if args.count < 1 then return;
for it, idx : console_command_names {
print("%\n", it);
if it == new {
array_add(*console_report, console_command_procs[idx](.[]));
if it == args[0] {
args.count -= 1;
args.data += 1;
array_add(*console_report, console_command_procs[idx](args));
found = true;
break;
}
}
// array_reset(*args);
if !found then array_add(*console_report, "Unknown command.");
}

View File

@ -108,8 +108,8 @@ handle_tool_click :: () {
current_color : Vector3 = .{1.0, 0.0, 0.0};
reset_trile :: () {
print("Reset called!\n");
reset_trile :: (a: bool = false) {
print("Reset called, with arg: %!\n", a);
} @Command
tick_trile_editor :: () {

View File

@ -43,14 +43,64 @@ add_console_commands :: (message: *Message, w: *Workspace) {
if expression.flags & .SCOPE_FILE {
compiler_report(sprint("Command % is file scoped, that is not okay. Commands must be exported.", expression.name), make_location(cast(*Code_Node)expression), .ERROR);
}
// @ToDo: Count argument range properly.
arg_count := header.arguments.count;
arg_count_min := header.arguments.count;
for arg, i : header.arguments {
if arg.expression != null then arg_count_min -= 1;
}
builder : String_Builder;
print_to_builder(*builder, "%__command_front :: (args: []string) -> string {\n", expression.name);
print_to_builder(*builder, "if !verify_argument_count(%, %, args.count) return sprint(\"Wrong number of arguments! Expected \%, got \%.\", %, args.count);\n", arg_count, arg_count, arg_count);
print_to_builder(*builder, "return sprint(\"\%\", %());\n", expression.name);
print_to_builder(*builder, "if !verify_argument_count(%, %, args.count) return sprint(\"Wrong number of arguments! Expected \%, got \%.\", %, args.count);\n", arg_count_min, arg_count, arg_count);
get_call_string :: (num: int) -> string {
sep := "";
call_args_builder : String_Builder;
for 0..num-1 {
print_to_builder(*call_args_builder, "%xx a%", sep, it);
sep = ", ";
}
return builder_to_string(*call_args_builder);
}
for arg, i : header.arguments {
print("ARG% (%): %\n", i, arg.type_inst.result.type, arg.name);
type_tag := arg.type_inst.result.type;
arg_name := arg.name;
if type_tag == {
case .INTEGER;
print_to_builder(*builder, "a% : int; success% : bool;\n", i, i);
print_to_builder(*builder, "if args.count > % {\n", i);
print_to_builder(*builder, "a%, success% = string_to_int(args[%]);\n", i, i, i);
print_to_builder(*builder, "if !success% then return sprint(\"Can't parse value \% for argument % at position % to type %.\", args[%]);\n", i, arg_name, i, type_tag, i);
print_to_builder(*builder, "}\n");
case .FLOAT;
print_to_builder(*builder, "a% : float; success% : bool;\n", i, i);
print_to_builder(*builder, "if args.count > % {\n", i);
print_to_builder(*builder, "a%, success% = string_to_float(args[%]);\n", i, i, i);
print_to_builder(*builder, "if !success% then return sprint(\"Can't parse value \% for argument % at position % to type %.\", args[%]);\n", i, arg_name, i, type_tag, i);
print_to_builder(*builder, "}\n");
case .BOOL;
print_to_builder(*builder, "a% : bool; success% : bool;\n", i, i);
print_to_builder(*builder, "if args.count > % {\n", i);
print_to_builder(*builder, "a%, success% = string_to_bool(args[%]);\n", i, i, i);
print_to_builder(*builder, "if !success% then return sprint(\"Can't parse value \% for argument % at position % to type %.\", args[%]);\n", i, arg_name, i, type_tag, i);
print_to_builder(*builder, "}\n");
case .STRING;
print_to_builder(*builder, "a% : string;;\n", i);
print_to_builder(*builder, "if args.count > % {\n", i);
print_to_builder(*builder, "a% := args[%];\n", i, i);
print_to_builder(*builder, "}\n");
case;
compiler_report(sprint("Argument % is of type %, which is not handled by automatic command registration.", arg_name, type_tag), make_location(cast(*Code_Node)arg), .ERROR);
}
}
for arg_count_min..arg_count {
print_to_builder(*builder, "if args.count == % then return sprint(\"\%\", %(%));\n", it, expression.name, get_call_string(it));
}
print_to_builder(*builder, "}\n");
str := builder_to_string(*builder);
print("%\n", str);