mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-21 21:24:59 -07:00
typeid as keyword (ready to implement polymorphic name parameters)
This commit is contained in:
+42
-15
@@ -24,21 +24,27 @@ struct Array {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make_from_ptr(T *data, isize count, isize capacity);
|
||||
template <typename T> void array_free (Array<T> *array);
|
||||
template <typename T> void array_add (Array<T> *array, T const &t);
|
||||
template <typename T> T array_pop (Array<T> *array);
|
||||
template <typename T> void array_clear (Array<T> *array);
|
||||
template <typename T> void array_reserve (Array<T> *array, isize capacity);
|
||||
template <typename T> void array_resize (Array<T> *array, isize count);
|
||||
template <typename T> void array_set_capacity (Array<T> *array, isize capacity);
|
||||
template <typename T> Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count);
|
||||
template <typename T> void array_init (Array<T> *array, gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count);
|
||||
template <typename T> Array<T> array_make (gbAllocator const &a, isize count, isize capacity);
|
||||
template <typename T> Array<T> array_make_from_ptr (T *data, isize count, isize capacity);
|
||||
template <typename T> void array_free (Array<T> *array);
|
||||
template <typename T> void array_add (Array<T> *array, T const &t);
|
||||
template <typename T> T array_pop (Array<T> *array);
|
||||
template <typename T> void array_clear (Array<T> *array);
|
||||
template <typename T> void array_reserve (Array<T> *array, isize capacity);
|
||||
template <typename T> void array_resize (Array<T> *array, isize count);
|
||||
template <typename T> void array_set_capacity (Array<T> *array, isize capacity);
|
||||
template <typename T> Array<T> array_slice (Array<T> const &array, isize lo, isize hi);
|
||||
|
||||
|
||||
template <typename T> void array_ordered_remove (Array<T> *array, isize index);
|
||||
template <typename T> void array_unordered_remove(Array<T> *array, isize index);
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
T *array_end_ptr(Array<T> *array) {
|
||||
@@ -201,6 +207,27 @@ gb_inline Array<T> array_slice(Array<T> const &array, isize lo, isize hi) {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename T>
|
||||
void array_ordered_remove(Array<T> *array, isize index) {
|
||||
GB_ASSERT(0 <= index && index < array->count);
|
||||
|
||||
isize bytes = (gb_size_of(T)*n) * (array->count-(index+1));
|
||||
gb_memmove(array->data+index, array->data+index+1, bytes);
|
||||
array->count -= 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void array_unordered_remove(Array<T> *array, isize index) {
|
||||
GB_ASSERT(0 <= index && index < array->count);
|
||||
|
||||
isize n = array->count-1;
|
||||
if (index != n) {
|
||||
gb_memmove(array->data+index, array->data+n, gb_size_of(T));
|
||||
}
|
||||
array_pop(array);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+9
-5
@@ -232,12 +232,11 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Type *def)
|
||||
GB_ASSERT(e->type == nullptr);
|
||||
|
||||
DeclInfo *decl = decl_info_of_entity(e);
|
||||
if (decl != nullptr && total_attribute_count(decl) > 0) {
|
||||
error(decl->attributes[0], "Attributes are not allowed on type declarations");
|
||||
if (decl != nullptr) {
|
||||
check_decl_attributes(ctx, decl->attributes, const_decl_attribute, nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool is_distinct = is_type_distinct(type_expr);
|
||||
Ast *te = remove_type_alias_clutter(type_expr);
|
||||
e->type = t_invalid;
|
||||
@@ -254,6 +253,11 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Type *def)
|
||||
check_type_path_pop(ctx);
|
||||
|
||||
named->Named.base = base_type(bt);
|
||||
|
||||
if (is_distinct && is_type_typeid(e->type)) {
|
||||
error(type_expr, "'distinct' cannot be applied to 'typeid'");
|
||||
is_distinct = false;
|
||||
}
|
||||
if (!is_distinct) {
|
||||
e->type = bt;
|
||||
named->Named.base = bt;
|
||||
@@ -393,8 +397,8 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
|
||||
|
||||
|
||||
DeclInfo *decl = decl_info_of_entity(e);
|
||||
if (decl != nullptr && total_attribute_count(decl) > 0) {
|
||||
error(decl->attributes[0], "Attributes are not allowed on constant value declarations");
|
||||
if (decl != nullptr) {
|
||||
check_decl_attributes(ctx, decl->attributes, const_decl_attribute, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -3200,10 +3200,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
|
||||
add_type_info_type(c, t);
|
||||
|
||||
t = base_type(t);
|
||||
if (is_operand_value(o) && are_types_identical(t, t_type_info_ptr)) {
|
||||
add_package_dependency(c, "runtime", "__typeid_of");
|
||||
} else if (o.mode != Addressing_Type) {
|
||||
error(expr, "Expected a type or type info for 'typeid_of'");
|
||||
if (o.mode != Addressing_Type) {
|
||||
error(expr, "Expected a type for 'typeid_of'");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6069,6 +6067,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
}
|
||||
case_end;
|
||||
|
||||
case Ast_TypeidType:
|
||||
case Ast_TypeType:
|
||||
case Ast_PolyType:
|
||||
case Ast_ProcType:
|
||||
@@ -6077,7 +6076,6 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
case Ast_DynamicArrayType:
|
||||
case Ast_StructType:
|
||||
case Ast_UnionType:
|
||||
// case Ast_RawUnionType:
|
||||
case Ast_EnumType:
|
||||
case Ast_MapType:
|
||||
o->mode = Addressing_Type;
|
||||
@@ -6512,6 +6510,14 @@ gbString write_expr_to_string(gbString str, Ast *node) {
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(tt, TypeidType, node);
|
||||
str = gb_string_appendc(str, "typeid");
|
||||
if (tt->specialization) {
|
||||
str = gb_string_appendc(str, "/");
|
||||
str = write_expr_to_string(str, tt->specialization);
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(pt, ProcType, node);
|
||||
str = gb_string_appendc(str, "proc(");
|
||||
str = write_expr_to_string(str, pt->params);
|
||||
|
||||
@@ -1190,6 +1190,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
if (specialization == t_invalid){
|
||||
specialization = nullptr;
|
||||
}
|
||||
// warning(type_expr, "'type' parameters are deprecated, please use a polymorphic identifier with a type of 'typeid'. For example, '$T: typeid'");
|
||||
|
||||
if (operands != nullptr) {
|
||||
detemine_type_from_operand = true;
|
||||
@@ -1263,10 +1264,30 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
|
||||
for_array(j, p->names) {
|
||||
Ast *name = p->names[j];
|
||||
|
||||
bool is_poly_name = false;
|
||||
|
||||
switch (name->kind) {
|
||||
case Ast_Ident:
|
||||
break;
|
||||
case Ast_PolyType:
|
||||
GB_ASSERT(name->PolyType.specialization == nullptr);
|
||||
is_poly_name = true;
|
||||
name = name->PolyType.type;
|
||||
break;
|
||||
}
|
||||
if (!ast_node_expect(name, Ast_Ident)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_poly_name) {
|
||||
if (type != nullptr && is_type_typeid(type)) {
|
||||
is_type_param = true;
|
||||
} else {
|
||||
error(name, "Polymorphic names are not yet supported for non-typeid parameters");
|
||||
}
|
||||
}
|
||||
|
||||
Entity *param = nullptr;
|
||||
if (is_type_param) {
|
||||
if (operands != nullptr) {
|
||||
@@ -2022,6 +2043,14 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
|
||||
return check_type_internal(ctx, dt->type, type, named_type);
|
||||
case_end;
|
||||
|
||||
case_ast_node(tt, TypeidType, e);
|
||||
e->tav.mode = Addressing_Type;
|
||||
e->tav.type = t_typeid;
|
||||
*type = t_typeid;
|
||||
set_base_type(named_type, *type);
|
||||
return true;
|
||||
case_end;
|
||||
|
||||
case_ast_node(pt, PolyType, e);
|
||||
Ast *ident = pt->type;
|
||||
if (ident->kind != Ast_Ident) {
|
||||
|
||||
+59
-1
@@ -1367,7 +1367,6 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||
|
||||
for_array(i, c->info.definitions) {
|
||||
Entity *e = c->info.definitions[i];
|
||||
// if (e->scope->is_global && !is_type_poly_proc(e->type)) { // TODO(bill): is the check enough?
|
||||
if (e->scope == builtin_pkg->scope) { // TODO(bill): is the check enough?
|
||||
if (e->type == nullptr) {
|
||||
add_dependency_to_set(c, e);
|
||||
@@ -1806,6 +1805,14 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DECL_ATTRIBUTE_PROC(const_decl_attribute) {
|
||||
if (name == "private") {
|
||||
// NOTE(bill): Handled elsewhere `check_collect_value_decl`
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2025,6 +2032,49 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
||||
|
||||
ast_node(vd, ValueDecl, decl);
|
||||
|
||||
bool entity_is_private = false;
|
||||
for_array(i, vd->attributes) {
|
||||
Ast *attr = vd->attributes[i];
|
||||
if (attr->kind != Ast_Attribute) continue;
|
||||
auto *elems = &attr->Attribute.elems;
|
||||
for (isize j = 0; j < elems->count; j++) {
|
||||
Ast *elem = (*elems)[j];
|
||||
String name = {};
|
||||
Ast *value = nullptr;
|
||||
switch (elem->kind) {
|
||||
case_ast_node(i, Ident, elem);
|
||||
name = i->token.string;
|
||||
case_end;
|
||||
case_ast_node(fv, FieldValue, elem);
|
||||
GB_ASSERT(fv->field->kind == Ast_Ident);
|
||||
name = fv->field->Ident.token.string;
|
||||
value = fv->value;
|
||||
case_end;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (name == "private") {
|
||||
if (value != nullptr) {
|
||||
error(value, "'%.*s' does not expect a value", LIT(name));
|
||||
}
|
||||
|
||||
if (entity_is_private) {
|
||||
error(elem, "Previous declaration of '%.*s'", LIT(name));
|
||||
} else {
|
||||
entity_is_private = true;
|
||||
}
|
||||
array_unordered_remove(elems, j);
|
||||
j -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entity_is_private && !(c->scope->flags&ScopeFlag_File)) {
|
||||
error(decl, "Attribute 'private' is not allowed on a non file scope entity");
|
||||
}
|
||||
|
||||
|
||||
if (vd->is_mutable) {
|
||||
if (!(c->scope->flags&ScopeFlag_File)) {
|
||||
// NOTE(bill): local scope -> handle later and in order
|
||||
@@ -2044,6 +2094,10 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
||||
Entity *e = alloc_entity_variable(c->scope, name->Ident.token, nullptr, false);
|
||||
e->identifier = name;
|
||||
|
||||
if (entity_is_private) {
|
||||
e->flags |= EntityFlag_NotExported;
|
||||
}
|
||||
|
||||
if (vd->is_using) {
|
||||
vd->is_using = false; // NOTE(bill): This error will be only caught once
|
||||
error(name, "'using' is not allowed at the file scope");
|
||||
@@ -2145,6 +2199,10 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
||||
}
|
||||
e->identifier = name;
|
||||
|
||||
if (entity_is_private) {
|
||||
e->flags |= EntityFlag_NotExported;
|
||||
}
|
||||
|
||||
if (vd->is_using) {
|
||||
if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) {
|
||||
d->is_using = true;
|
||||
|
||||
+1
-3
@@ -47,6 +47,7 @@ enum EntityFlag {
|
||||
EntityFlag_PolyConst = 1<<13,
|
||||
EntityFlag_NotExported = 1<<14,
|
||||
|
||||
|
||||
EntityFlag_CVarArg = 1<<20,
|
||||
EntityFlag_AutoCast = 1<<21,
|
||||
};
|
||||
@@ -113,9 +114,6 @@ struct Entity {
|
||||
String link_prefix;
|
||||
bool is_foreign;
|
||||
bool is_export;
|
||||
|
||||
// bool default_is_nil;
|
||||
// bool default_is_location;
|
||||
bool is_immutable;
|
||||
} Variable;
|
||||
struct {
|
||||
|
||||
+2
-2
@@ -5159,7 +5159,7 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
||||
for_array(i, ce->args) {
|
||||
Ast *arg = ce->args[i];
|
||||
TypeAndValue tav = type_and_value_of_expr(arg);
|
||||
GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s", expr_to_string(arg));
|
||||
GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s", expr_to_string(arg), expr_to_string(expr));
|
||||
GB_ASSERT_MSG(tav.mode != Addressing_ProcGroup, "%s", expr_to_string(arg));
|
||||
Type *at = tav.type;
|
||||
if (at->kind == Type_Tuple) {
|
||||
@@ -5973,7 +5973,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
|
||||
ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr)));
|
||||
String field_names[2] = {
|
||||
str_lit("data"),
|
||||
str_lit("typeid"),
|
||||
str_lit("id"),
|
||||
};
|
||||
Type *field_types[2] = {
|
||||
t_rawptr,
|
||||
|
||||
+56
-10
@@ -78,6 +78,7 @@ Token ast_token(Ast *node) {
|
||||
return ast_token(node->UnionField.name);
|
||||
|
||||
case Ast_TypeType: return node->TypeType.token;
|
||||
case Ast_TypeidType: return node->TypeidType.token;
|
||||
case Ast_HelperType: return node->HelperType.token;
|
||||
case Ast_DistinctType: return node->DistinctType.token;
|
||||
case Ast_PolyType: return node->PolyType.token;
|
||||
@@ -307,6 +308,9 @@ Ast *clone_ast(Ast *node) {
|
||||
n->UnionField.list = clone_ast(n->UnionField.list);
|
||||
break;
|
||||
|
||||
case Ast_TypeidType:
|
||||
n->TypeidType.specialization = clone_ast(n->TypeidType.specialization);
|
||||
break;
|
||||
case Ast_TypeType:
|
||||
n->TypeType.specialization = clone_ast(n->TypeType.specialization);
|
||||
break;
|
||||
@@ -409,7 +413,7 @@ void syntax_error(Ast *node, char *fmt, ...) {
|
||||
|
||||
bool ast_node_expect(Ast *node, AstKind kind) {
|
||||
if (node->kind != kind) {
|
||||
syntax_error(node, "Expected %.*s, got %.*s", LIT(ast_strings[node->kind]));
|
||||
error(node, "Expected %.*s, got %.*s", LIT(ast_strings[kind]), LIT(ast_strings[node->kind]));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -824,6 +828,13 @@ Ast *ast_union_field(AstFile *f, Ast *name, Ast *list) {
|
||||
}
|
||||
|
||||
|
||||
Ast *ast_typeid_type(AstFile *f, Token token, Ast *specialization) {
|
||||
Ast *result = alloc_ast_node(f, Ast_TypeidType);
|
||||
result->TypeidType.token = token;
|
||||
result->TypeidType.specialization = specialization;
|
||||
return result;
|
||||
}
|
||||
|
||||
Ast *ast_type_type(AstFile *f, Token token, Ast *specialization) {
|
||||
Ast *result = alloc_ast_node(f, Ast_TypeType);
|
||||
result->TypeType.token = token;
|
||||
@@ -1354,10 +1365,14 @@ Ast * parse_block_stmt(AstFile *f, b32 is_when);
|
||||
|
||||
|
||||
|
||||
Ast *parse_ident(AstFile *f) {
|
||||
Ast *parse_ident(AstFile *f, bool allow_poly_names=false) {
|
||||
Token token = f->curr_token;
|
||||
if (token.kind == Token_Ident) {
|
||||
advance_token(f);
|
||||
} else if (allow_poly_names && token.kind == Token_Dollar) {
|
||||
Token dollar = token;
|
||||
Ast *name = ast_ident(f, expect_token(f, Token_Ident));
|
||||
return ast_poly_type(f, dollar, name, nullptr);
|
||||
} else {
|
||||
token.string = str_lit("_");
|
||||
expect_token(f, Token_Ident);
|
||||
@@ -1752,6 +1767,15 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
||||
return ast_poly_type(f, token, type, specialization);
|
||||
} break;
|
||||
|
||||
case Token_typeid: {
|
||||
Token token = expect_token(f, Token_typeid);
|
||||
// Ast *specialization = nullptr;
|
||||
// if (allow_token(f, Token_Quo)) {
|
||||
// specialization = parse_type(f);
|
||||
// }
|
||||
return ast_typeid_type(f, token, nullptr);
|
||||
} break;
|
||||
|
||||
case Token_type_of: {
|
||||
Ast *i = ast_implicit(f, expect_token(f, Token_type_of));
|
||||
Ast *type = parse_call_expr(f, i);
|
||||
@@ -2324,11 +2348,11 @@ Array<Ast *> parse_rhs_expr_list(AstFile *f) {
|
||||
return parse_expr_list(f, false);
|
||||
}
|
||||
|
||||
Array<Ast *> parse_ident_list(AstFile *f) {
|
||||
Array<Ast *> parse_ident_list(AstFile *f, bool allow_poly_names) {
|
||||
auto list = array_make<Ast *>(heap_allocator());
|
||||
|
||||
for (;;) {
|
||||
array_add(&list, parse_ident(f));
|
||||
array_add(&list, parse_ident(f, allow_poly_names));
|
||||
if (f->curr_token.kind != Token_Comma ||
|
||||
f->curr_token.kind == Token_EOF) {
|
||||
break;
|
||||
@@ -2660,12 +2684,18 @@ Ast *parse_proc_type(AstFile *f, Token proc_token) {
|
||||
if (field->type->kind == Ast_TypeType ||
|
||||
field->type->kind == Ast_PolyType) {
|
||||
is_generic = true;
|
||||
break;
|
||||
goto end;
|
||||
}
|
||||
for_array(j, field->names) {
|
||||
Ast *name = field->names[j];
|
||||
if (name->kind == Ast_PolyType) {
|
||||
is_generic = true;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
end:
|
||||
return ast_proc_type(f, proc_token, params, results, tags, cc, is_generic);
|
||||
}
|
||||
|
||||
@@ -2805,7 +2835,7 @@ struct AstAndFlags {
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
Array<Ast *> convert_to_ident_list(AstFile *f, Array<AstAndFlags> list, bool ignore_flags) {
|
||||
Array<Ast *> convert_to_ident_list(AstFile *f, Array<AstAndFlags> list, bool ignore_flags, bool allow_poly_names) {
|
||||
auto idents = array_make<Ast *>(heap_allocator(), 0, list.count);
|
||||
// Convert to ident list
|
||||
for_array(i, list) {
|
||||
@@ -2821,6 +2851,20 @@ Array<Ast *> convert_to_ident_list(AstFile *f, Array<AstAndFlags> list, bool ign
|
||||
case Ast_Ident:
|
||||
case Ast_BadExpr:
|
||||
break;
|
||||
|
||||
case Ast_PolyType:
|
||||
if (allow_poly_names) {
|
||||
if (ident->PolyType.specialization == nullptr) {
|
||||
syntax_error(ident, "Polymorphic identifiers are not yet supported");
|
||||
break;
|
||||
} else {
|
||||
syntax_error(ident, "Expected a polymorphic identifier without any specialization");
|
||||
}
|
||||
} else {
|
||||
syntax_error(ident, "Expected a non-polymorphic identifier");
|
||||
}
|
||||
/*fallthrough*/
|
||||
|
||||
default:
|
||||
syntax_error(ident, "Expected an identifier");
|
||||
ident = ast_ident(f, blank_token);
|
||||
@@ -2891,6 +2935,8 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
|
||||
auto list = array_make<AstAndFlags>(heap_allocator());
|
||||
defer (array_free(&list));
|
||||
|
||||
bool allow_poly_names = allow_type_token;
|
||||
|
||||
isize total_name_count = 0;
|
||||
bool allow_ellipsis = allowed_flags&FieldFlag_ellipsis;
|
||||
bool seen_ellipsis = false;
|
||||
@@ -2915,7 +2961,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
|
||||
|
||||
|
||||
if (f->curr_token.kind == Token_Colon) {
|
||||
Array<Ast *> names = convert_to_ident_list(f, list, true); // Copy for semantic reasons
|
||||
Array<Ast *> names = convert_to_ident_list(f, list, true, allow_poly_names); // Copy for semantic reasons
|
||||
if (names.count == 0) {
|
||||
syntax_error(f->curr_token, "Empty field declaration");
|
||||
}
|
||||
@@ -2971,7 +3017,7 @@ Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKi
|
||||
CommentGroup *docs = f->lead_comment;
|
||||
|
||||
u32 set_flags = parse_field_prefixes(f);
|
||||
Array<Ast *> names = parse_ident_list(f);
|
||||
Array<Ast *> names = parse_ident_list(f, allow_poly_names);
|
||||
if (names.count == 0) {
|
||||
syntax_error(f->curr_token, "Empty field declaration");
|
||||
break;
|
||||
|
||||
@@ -418,6 +418,10 @@ AST_KIND(_DeclEnd, "", bool) \
|
||||
Ast *list; \
|
||||
}) \
|
||||
AST_KIND(_TypeBegin, "", bool) \
|
||||
AST_KIND(TypeidType, "typeid", struct { \
|
||||
Token token; \
|
||||
Ast *specialization; \
|
||||
}) \
|
||||
AST_KIND(TypeType, "type", struct { \
|
||||
Token token; \
|
||||
Ast *specialization; \
|
||||
|
||||
@@ -86,6 +86,7 @@ TOKEN_KIND(Token__KeywordBegin, ""), \
|
||||
TOKEN_KIND(Token_foreign, "foreign"), \
|
||||
TOKEN_KIND(Token_package, "package"), \
|
||||
TOKEN_KIND(Token_type, "type"), \
|
||||
TOKEN_KIND(Token_typeid, "typeid"), \
|
||||
TOKEN_KIND(Token_when, "when"), \
|
||||
TOKEN_KIND(Token_if, "if"), \
|
||||
TOKEN_KIND(Token_else, "else"), \
|
||||
|
||||
+4
-4
@@ -1794,17 +1794,17 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
||||
// IMPORTANT TODO(bill): Should these members be available to should I only allow them with
|
||||
// `Raw_Any` type?
|
||||
String data_str = str_lit("data");
|
||||
String typeid_str = str_lit("typeid");
|
||||
String id_str = str_lit("id");
|
||||
gb_local_persist Entity *entity__any_data = alloc_entity_field(nullptr, make_token_ident(data_str), t_rawptr, false, 0);
|
||||
gb_local_persist Entity *entity__any_typeid = alloc_entity_field(nullptr, make_token_ident(typeid_str), t_typeid, false, 1);
|
||||
gb_local_persist Entity *entity__any_id = alloc_entity_field(nullptr, make_token_ident(id_str), t_typeid, false, 1);
|
||||
|
||||
if (field_name == data_str) {
|
||||
selection_add_index(&sel, 0);
|
||||
sel.entity = entity__any_data;
|
||||
return sel;
|
||||
} else if (field_name == typeid_str) {
|
||||
} else if (field_name == id_str) {
|
||||
selection_add_index(&sel, 1);
|
||||
sel.entity = entity__any_typeid;
|
||||
sel.entity = entity__any_id;
|
||||
return sel;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user