114 lines
5.8 KiB
Plaintext
114 lines
5.8 KiB
Plaintext
console_commands_to_register : [..]string;
|
|
|
|
add_console_registration_code :: (w: *Workspace) {
|
|
builder : String_Builder;
|
|
print_to_builder(*builder, "register_commands :: () {\n");
|
|
for console_commands_to_register {
|
|
print_to_builder(*builder, "array_add(*console_command_procs, %__command_front);\n", it);
|
|
print_to_builder(*builder, "array_add(*console_command_names, \"%\");\n", it);
|
|
}
|
|
print_to_builder(*builder, "}\n");
|
|
add_build_string(builder_to_string(*builder), w.*);
|
|
}
|
|
|
|
add_console_commands :: (message: *Message, w: *Workspace) {
|
|
if message.kind == .PHASE {
|
|
phase_message := cast(*Message_Phase) message;
|
|
if phase_message.phase == .TYPECHECKED_ALL_WE_CAN {
|
|
if console_commands_to_register.count > 0 {
|
|
add_console_registration_code(w);
|
|
array_reset(*console_commands_to_register);
|
|
}
|
|
}
|
|
}
|
|
if message.kind != .TYPECHECKED then return;
|
|
code := cast(*Message_Typechecked) message;
|
|
|
|
all_commands_builder : String_Builder;
|
|
|
|
for code.declarations {
|
|
import := it.expression.enclosing_load.enclosing_import;
|
|
expression := it.expression;
|
|
if expression.expression && expression.expression.kind == .PROCEDURE_HEADER {
|
|
header := cast(*Code_Procedure_Header) expression.expression;
|
|
is_command := false;
|
|
for expression.notes {
|
|
if it.text == "Command" {
|
|
is_command = true;
|
|
}
|
|
}
|
|
if !is_command then continue;
|
|
|
|
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);
|
|
}
|
|
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_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 {
|
|
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, "return \"Something really really weird has happened. Your argument count somehow went trough all the return checks....\";\n");
|
|
print_to_builder(*builder, "}\n");
|
|
str := builder_to_string(*builder);
|
|
// print("Generated: %\n", str);
|
|
array_add(*console_commands_to_register, sprint("%", expression.name));
|
|
add_build_string(str, w.*);
|
|
free(str);
|
|
}
|
|
}
|
|
return;
|
|
|
|
}
|