diff options
| author | Ginger Bill <bill@gingerbill.org> | 2016-09-19 22:26:07 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2016-09-19 22:26:07 +0100 |
| commit | 3b266b194f36507208b6f90145475d93b53896ee (patch) | |
| tree | 1e35cd6180d220614ca6553cfe5678122570c85e /src/checker/expr.cpp | |
| parent | 9561dc33cef4c5881034d429524a0498331a740e (diff) | |
enum_to_string fix; enum count, min_value, max_value
Diffstat (limited to 'src/checker/expr.cpp')
| -rw-r--r-- | src/checker/expr.cpp | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 05e539bac..231e467bf 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -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; |