Add bit_set type

This commit is contained in:
gingerBill
2018-08-14 17:07:56 +01:00
parent 89f4e7a8db
commit acc010cba5
14 changed files with 509 additions and 45 deletions
+70 -1
View File
@@ -681,6 +681,59 @@ void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, Ast *node)
}
void check_bit_set_type(CheckerContext *ctx, Type *type, Ast *node) {
ast_node(bs, BitSetType, node);
GB_ASSERT(type->kind == Type_BitSet);
Type *bt = check_type_expr(ctx, bs->base_type, nullptr);
type->BitSet.base_type = bt;
if (!is_type_enum(bt)) {
error(bs->base_type, "Expected an enum type for a bit_set");
} else {
Type *et = base_type(bt);
GB_ASSERT(et->kind == Type_Enum);
if (!is_type_integer(et->Enum.base_type)) {
error(bs->base_type, "Enum type for bit_set must be an integer");
return;
}
i64 min_value = 0;
i64 max_value = 0;
BigInt v64 = {}; big_int_from_i64(&v64, 64);
for_array(i, et->Enum.fields) {
Entity *e = et->Enum.fields[i];
if (e->kind != Entity_Constant) {
continue;
}
ExactValue value = exact_value_to_integer(e->Constant.value);
GB_ASSERT(value.kind == ExactValue_Integer);
BigInt v = value.value_integer;
if (big_int_cmp(&v, &BIG_INT_ZERO) < 0) {
error(bs->base_type, "Negative enum values are not allowed in a bit_set");
return;
}
if (big_int_cmp(&v, &v64) >= 0) {
error(bs->base_type, "Enum values overe 64 are not allowed in a bit_set");
return;
}
i64 x = big_int_to_i64(&v);
min_value = gb_min(min_value, x);
max_value = gb_max(max_value, x);
}
type->BitSet.min = min_value;
type->BitSet.max = max_value;
}
}
bool check_type_specialization_to(CheckerContext *ctx, Type *specialization, Type *type, bool compound, bool modify_type) {
if (type == nullptr ||
type == t_invalid) {
@@ -1014,6 +1067,12 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
type = t_invalid;
}
}
if (p->flags&FieldFlag_auto_cast) {
error(name, "'auto_cast' can only be applied variable fields");
p->flags &= ~FieldFlag_auto_cast;
}
param = alloc_entity_type_name(scope, name->Ident.token, type, EntityState_Resolved);
param->TypeName.is_type_alias = true;
} else {
@@ -1885,18 +1944,28 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
check_enum_type(ctx, *type, named_type, e);
check_close_scope(ctx);
(*type)->Enum.node = e;
ctx->in_enum_type = false;
return true;
case_end;
case_ast_node(et, BitFieldType, e);
*type = alloc_type_bit_field();
set_base_type(named_type, *type);
check_open_scope(ctx, e);
check_bit_field_type(ctx, *type, e);
return true;
case_end;
case_ast_node(bs, BitSetType, e);
*type = alloc_type_bit_set();
set_base_type(named_type, *type);
check_open_scope(ctx, e);
check_bit_set_type(ctx, *type, e);
check_close_scope(ctx);
return true;
case_end;
case_ast_node(pt, ProcType, e);
bool ips = ctx->in_polymorphic_specialization;
defer (ctx->in_polymorphic_specialization = ips);