#load(path, type)

where `type` can be `string` or `[]T` where `T` is a simple type
This commit is contained in:
gingerBill
2022-08-11 14:30:14 +01:00
parent 70dc0c15fd
commit a7c3906003
4 changed files with 143 additions and 9 deletions
+42 -7
View File
@@ -1169,11 +1169,11 @@ LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, As
String name = bd->name.string;
GB_ASSERT(name == "load");
if (ce->args.count != 1) {
if (ce->args.count != 1 && ce->args.count != 2) {
if (ce->args.count == 0) {
error(ce->close, "'#load' expects 1 argument, got 0");
error(ce->close, "'#%.*s' expects 1 or 2 arguments, got 0", LIT(name));
} else {
error(ce->args[0], "'#load' expects 1 argument, got %td", ce->args.count);
error(ce->args[0], "'#%.*s' expects 1 or 2 arguments, got %td", LIT(name), ce->args.count);
}
return LoadDirective_Error;
@@ -1183,13 +1183,13 @@ LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, As
Operand o = {};
check_expr(c, &o, arg);
if (o.mode != Addressing_Constant) {
error(arg, "'#load' expected a constant string argument");
error(arg, "'#%.*s' expected a constant string argument", LIT(name));
return LoadDirective_Error;
}
if (!is_type_string(o.type)) {
gbString str = type_to_string(o.type);
error(arg, "'#load' expected a constant string, got %s", str);
error(arg, "'#%.*s' expected a constant string, got %s", LIT(name), str);
gb_string_free(str);
return LoadDirective_Error;
}
@@ -1197,8 +1197,43 @@ LoadDirectiveResult check_load_directive(CheckerContext *c, Operand *operand, As
GB_ASSERT(o.value.kind == ExactValue_String);
operand->type = t_u8_slice;
if (type_hint && is_type_string(type_hint)) {
operand->type = type_hint;
if (ce->args.count == 1) {
if (type_hint && is_type_string(type_hint)) {
operand->type = type_hint;
}
} else if (ce->args.count == 2) {
bool failed = false;
Ast *arg_type = ce->args[1];
Type *type = check_type(c, arg_type);
if (type != nullptr && type != t_invalid) {
if (is_type_string(type)) {
operand->type = type;
} else if (is_type_slice(type) /*|| is_type_array(type) || is_type_enumerated_array(type)*/) {
Type *elem = nullptr;
Type *bt = base_type(type);
if (bt->kind == Type_Slice) {
elem = bt->Slice.elem;
} else if (bt->kind == Type_Array) {
elem = bt->Array.elem;
} else if (bt->kind == Type_EnumeratedArray) {
elem = bt->EnumeratedArray.elem;
}
GB_ASSERT(elem != nullptr);
if (is_type_load_safe(elem)) {
operand->type = type;
} else {
failed = true;
}
} else {
failed = true;
}
}
if (failed) {
gbString type_str = type_to_string(type);
error(arg_type, "'#%.*s' invalid type, expected a string, or slice of simple types, got %s", LIT(name), type_str);
gb_string_free(type_str);
}
}
operand->mode = Addressing_Constant;