mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
enum_to_string fix; enum count, min_value, max_value
This commit is contained in:
@@ -631,7 +631,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
|
||||
}
|
||||
|
||||
b32 add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
|
||||
if (!are_strings_equal(entity->token.string, make_string("_"))) {
|
||||
if (entity->token.string != make_string("_")) {
|
||||
Entity *insert_entity = scope_insert_entity(scope, entity);
|
||||
if (insert_entity) {
|
||||
Entity *up = insert_entity->using_parent;
|
||||
@@ -676,7 +676,7 @@ void add_entity_use(CheckerInfo *i, AstNode *identifier, Entity *entity) {
|
||||
|
||||
|
||||
void add_file_entity(Checker *c, Scope *file_scope, AstNode *identifier, Entity *e, DeclInfo *d) {
|
||||
GB_ASSERT(are_strings_equal(identifier->Ident.string, e->token.string));
|
||||
GB_ASSERT(identifier->Ident.string == e->token.string);
|
||||
add_entity(c, file_scope, identifier, e);
|
||||
map_set(&c->info.entities, hash_pointer(e), d);
|
||||
}
|
||||
@@ -1048,7 +1048,7 @@ void check_parsed_files(Checker *c) {
|
||||
warning(id->token, "Multiple #import of the same file within this scope");
|
||||
}
|
||||
|
||||
if (are_strings_equal(id->import_name.string, make_string("_"))) {
|
||||
if (id->import_name.string == make_string("_")) {
|
||||
// NOTE(bill): Add imported entities to this file's scope
|
||||
gb_for_array(elem_index, scope->elements.entries) {
|
||||
Entity *e = scope->elements.entries[elem_index].value;
|
||||
|
||||
+36
-5
@@ -545,6 +545,7 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec
|
||||
}
|
||||
|
||||
|
||||
|
||||
void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *node) {
|
||||
GB_ASSERT(node->kind == AstNode_EnumType);
|
||||
GB_ASSERT(is_type_enum(enum_type));
|
||||
@@ -571,12 +572,37 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
Entity **fields = gb_alloc_array(c->allocator, Entity *, gb_array_count(et->fields));
|
||||
isize field_index = 0;
|
||||
ExactValue iota = make_exact_value_integer(-1);
|
||||
i64 min_value = 0;
|
||||
i64 max_value = 0;
|
||||
|
||||
Type *constant_type = enum_type;
|
||||
if (named_type != NULL) {
|
||||
constant_type = named_type;
|
||||
}
|
||||
Token blank_token = {Token_Identifier};
|
||||
blank_token.string = make_string("");
|
||||
Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));;
|
||||
|
||||
gb_for_array(i, et->fields) {
|
||||
AstNode *field = et->fields[i];
|
||||
|
||||
ast_node(f, FieldValue, field);
|
||||
Token name_token = f->field->Ident;
|
||||
|
||||
if (name_token.string == make_string("count")) {
|
||||
error(name_token, "`count` is a reserved identifier for enums");
|
||||
fields[field_index++] = blank_entity;
|
||||
continue;
|
||||
} else if (name_token.string == make_string("min_value")) {
|
||||
error(name_token, "`min_value` is a reserved identifier for enums");
|
||||
fields[field_index++] = blank_entity;
|
||||
continue;
|
||||
} else if (name_token.string == make_string("max_value")) {
|
||||
error(name_token, "`max_value` is a reserved identifier for enums");
|
||||
fields[field_index++] = blank_entity;
|
||||
continue;
|
||||
}
|
||||
|
||||
Operand o = {};
|
||||
if (f->value != NULL) {
|
||||
check_expr(c, &o, f->value);
|
||||
@@ -598,11 +624,14 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
iota = exact_binary_operator_value(add_token, iota, make_exact_value_integer(1));
|
||||
}
|
||||
|
||||
Type *constant_type = enum_type;
|
||||
if (named_type != NULL) {
|
||||
constant_type = named_type;
|
||||
}
|
||||
|
||||
Entity *e = make_entity_constant(c->allocator, c->context.scope, name_token, constant_type, iota);
|
||||
if (min_value > iota.value_integer) {
|
||||
min_value = iota.value_integer;
|
||||
}
|
||||
if (max_value < iota.value_integer) {
|
||||
max_value = iota.value_integer;
|
||||
}
|
||||
|
||||
HashKey key = hash_string(name_token.string);
|
||||
if (map_get(&entity_map, key)) {
|
||||
@@ -614,6 +643,8 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
}
|
||||
add_entity_use(&c->info, f->field, e);
|
||||
}
|
||||
enum_type->Record.min_value = min_value;
|
||||
enum_type->Record.max_value = max_value;
|
||||
enum_type->Record.other_fields = fields;
|
||||
enum_type->Record.other_field_count = gb_array_count(et->fields);
|
||||
}
|
||||
@@ -732,7 +763,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
|
||||
o->expr = n;
|
||||
Entity *e = scope_lookup_entity(c->context.scope, n->Ident.string);
|
||||
if (e == NULL) {
|
||||
if (are_strings_equal(n->Ident.string, make_string("_"))) {
|
||||
if (n->Ident.string == make_string("_")) {
|
||||
error(n->Ident, "`_` cannot be used as a value type");
|
||||
} else {
|
||||
auto *entries = c->context.scope->elements.entries;
|
||||
|
||||
@@ -162,7 +162,7 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
||||
// NOTE(bill): Ignore assignments to `_`
|
||||
if (node->kind == AstNode_Ident) {
|
||||
ast_node(i, Ident, node);
|
||||
if (are_strings_equal(i->string, make_string("_"))) {
|
||||
if (i->string == make_string("_")) {
|
||||
add_entity_definition(&c->info, node, NULL);
|
||||
check_assignment(c, op_a, NULL, make_string("assignment to `_` identifier"));
|
||||
if (op_a->mode == Addressing_Invalid)
|
||||
@@ -503,7 +503,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
|
||||
|
||||
if ((d->scope->is_file || d->scope->is_global) &&
|
||||
are_strings_equal(e->token.string, make_string("main"))) {
|
||||
e->token.string == make_string("main")) {
|
||||
if (proc_type != NULL) {
|
||||
auto *pt = &proc_type->Proc;
|
||||
if (pt->param_count != 0 ||
|
||||
@@ -701,7 +701,7 @@ void check_var_decl_node(Checker *c, AstNode *node) {
|
||||
String str = token.string;
|
||||
Entity *found = NULL;
|
||||
// NOTE(bill): Ignore assignments to `_`
|
||||
b32 can_be_ignored = are_strings_equal(str, make_string("_"));
|
||||
b32 can_be_ignored = str == make_string("_");
|
||||
if (!can_be_ignored) {
|
||||
found = current_scope_lookup_entity(c->context.scope, str);
|
||||
}
|
||||
|
||||
+44
-15
@@ -120,6 +120,8 @@ struct Type {
|
||||
|
||||
// enum only
|
||||
Type * enum_base; // Default is `int`
|
||||
i64 min_value;
|
||||
i64 max_value;
|
||||
|
||||
// struct only
|
||||
i64 * struct_offsets;
|
||||
@@ -710,12 +712,12 @@ void selection_add_index(Selection *s, isize index) {
|
||||
gb_global Entity *entity__any_type_info = NULL;
|
||||
gb_global Entity *entity__any_data = NULL;
|
||||
gb_global Entity *entity__string_data = NULL;
|
||||
gb_global Entity *entity__string_count = NULL;
|
||||
gb_global Entity *entity__string_count = NULL;
|
||||
|
||||
Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection sel = empty_selection) {
|
||||
GB_ASSERT(type_ != NULL);
|
||||
|
||||
if (are_strings_equal(field_name, make_string("_"))) {
|
||||
if (field_name == make_string("_")) {
|
||||
return empty_selection;
|
||||
}
|
||||
|
||||
@@ -740,11 +742,11 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
entity__any_data = make_entity_field(a, NULL, token, t_rawptr, false, 1);
|
||||
}
|
||||
|
||||
if (are_strings_equal(field_name, type_info_str)) {
|
||||
if (field_name == type_info_str) {
|
||||
selection_add_index(&sel, 0);
|
||||
sel.entity = entity__any_type_info;
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, data_str)) {
|
||||
} else if (field_name == data_str) {
|
||||
selection_add_index(&sel, 1);
|
||||
sel.entity = entity__any_data;
|
||||
return sel;
|
||||
@@ -765,11 +767,11 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
entity__string_count = make_entity_field(a, NULL, token, t_int, false, 1);
|
||||
}
|
||||
|
||||
if (are_strings_equal(field_name, data_str)) {
|
||||
if (field_name == data_str) {
|
||||
selection_add_index(&sel, 0);
|
||||
sel.entity = entity__string_data;
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, count_str)) {
|
||||
} else if (field_name == count_str) {
|
||||
selection_add_index(&sel, 1);
|
||||
sel.entity = entity__string_count;
|
||||
return sel;
|
||||
@@ -780,8 +782,8 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
return sel;
|
||||
} else if (type->kind == Type_Array) {
|
||||
String count_str = make_string("count");
|
||||
// NOTE(bill):U nderlying memory address cannot be changed
|
||||
if (are_strings_equal(field_name, count_str)) {
|
||||
// NOTE(bill): Underlying memory address cannot be changed
|
||||
if (field_name == count_str) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
@@ -791,7 +793,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
} else if (type->kind == Type_Vector) {
|
||||
String count_str = make_string("count");
|
||||
// NOTE(bill): Vectors are not addressable
|
||||
if (are_strings_equal(field_name, count_str)) {
|
||||
if (field_name == count_str) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
@@ -803,21 +805,21 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
String count_str = make_string("count");
|
||||
String capacity_str = make_string("capacity");
|
||||
|
||||
if (are_strings_equal(field_name, data_str)) {
|
||||
if (field_name == data_str) {
|
||||
selection_add_index(&sel, 0);
|
||||
Token token = {Token_Identifier};
|
||||
token.string = data_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_field(a, NULL, token, make_type_pointer(a, type->Slice.elem), false, 0);
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, count_str)) {
|
||||
} else if (field_name == count_str) {
|
||||
selection_add_index(&sel, 1);
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_field(a, NULL, token, t_int, false, 1);
|
||||
return sel;
|
||||
} else if (are_strings_equal(field_name, capacity_str)) {
|
||||
} else if (field_name == capacity_str) {
|
||||
selection_add_index(&sel, 2);
|
||||
Token token = {Token_Identifier};
|
||||
token.string = capacity_str;
|
||||
@@ -837,7 +839,7 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
GB_ASSERT(f->kind == Entity_TypeName);
|
||||
String str = f->token.string;
|
||||
|
||||
if (are_strings_equal(field_name, str)) {
|
||||
if (field_name == str) {
|
||||
return make_selection(f, NULL, i);
|
||||
}
|
||||
}
|
||||
@@ -848,16 +850,43 @@ Selection lookup_field(Type *type_, String field_name, b32 is_type, Selection se
|
||||
GB_ASSERT(f->kind != Entity_Variable);
|
||||
String str = f->token.string;
|
||||
|
||||
if (are_strings_equal(field_name, str)) {
|
||||
if (field_name == str) {
|
||||
return make_selection(f, NULL, i);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_type_enum(type)) {
|
||||
String count_str = make_string("count");
|
||||
String min_value_str = make_string("min_value");
|
||||
String max_value_str = make_string("max_value");
|
||||
|
||||
if (field_name == count_str) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = count_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_constant(a, NULL, token, t_int, make_exact_value_integer(type->Record.other_field_count));
|
||||
return sel;
|
||||
} else if (field_name == min_value_str) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = min_value_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_constant(a, NULL, token, type->Record.enum_base, make_exact_value_integer(type->Record.min_value));
|
||||
return sel;
|
||||
} else if (field_name == max_value_str) {
|
||||
Token token = {Token_Identifier};
|
||||
token.string = max_value_str;
|
||||
// HACK(bill): Memory leak
|
||||
sel.entity = make_entity_constant(a, NULL, token, type->Record.enum_base, make_exact_value_integer(type->Record.max_value));
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (!is_type_enum(type) && !is_type_union(type)) {
|
||||
for (isize i = 0; i < type->Record.field_count; i++) {
|
||||
Entity *f = type->Record.fields[i];
|
||||
GB_ASSERT(f->kind == Entity_Variable && f->Variable.is_field);
|
||||
String str = f->token.string;
|
||||
if (are_strings_equal(field_name, str)) {
|
||||
if (field_name == str) {
|
||||
selection_add_index(&sel, i);
|
||||
sel.entity = f;
|
||||
return sel;
|
||||
|
||||
Reference in New Issue
Block a user