diff options
| author | gingerBill <bill@gingerbill.org> | 2018-08-14 17:07:56 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-08-14 17:07:56 +0100 |
| commit | acc010cba5df63b38704245254e721187335a7b2 (patch) | |
| tree | 2b92d291e6c3804f6e5cc177c5ed0443798d1f8d /src/check_expr.cpp | |
| parent | 89f4e7a8dbed4272f85f10568a542697aa3b38f8 (diff) | |
Add `bit_set` type
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 114 |
1 files changed, 83 insertions, 31 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d6ef8027f..d12f162ed 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -841,6 +841,9 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, case Type_Enum: return false; + case Type_BitSet: + return false; + case Type_Union: if (source->kind == Type_Union) { TypeUnion *x = &poly->Union; @@ -1115,8 +1118,8 @@ bool check_unary_op(CheckerContext *c, Operand *o, Token op) { break; case Token_Xor: - if (!is_type_integer(type) && !is_type_boolean(type)) { - error(op, "Operator '%.*s' is only allowed with integers or booleans", LIT(op.string)); + if (!is_type_integer(type) && !is_type_boolean(type) && !is_type_bit_set(type)) { + error(op, "Operator '%.*s' is only allowed with integers, booleans, or bit sets", LIT(op.string)); } break; @@ -1142,33 +1145,17 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { switch (op.kind) { case Token_Sub: case Token_SubEq: - if (!is_type_numeric(type) && !is_type_pointer(type)) { - error(op, "Operator '%.*s' is only allowed with numeric or pointer expressions", LIT(op.string)); - return false; - } -#if defined(NO_POINTER_ARITHMETIC) - if (is_type_pointer(type)) { - error(o->expr, "Pointer arithmetic is not supported"); - return false; - } -#else - if (is_type_pointer(type)) { - o->type = t_int; - } - if (base_type(type) == t_rawptr) { - gbString str = type_to_string(type); - error(o->expr, "Invalid pointer type for pointer arithmetic: '%s'", str); - gb_string_free(str); + if (!is_type_numeric(type)) { + error(op, "Operator '%.*s' is only allowed with numeric expressions", LIT(op.string)); return false; } break; -#endif case Token_Mul: case Token_Quo: - case Token_AddEq: case Token_MulEq: case Token_QuoEq: + case Token_AddEq: if (!is_type_numeric(type)) { error(op, "Operator '%.*s' is only allowed with numeric expressions", LIT(op.string)); return false; @@ -1194,24 +1181,30 @@ bool check_binary_op(CheckerContext *c, Operand *o, Token op) { case Token_OrEq: case Token_Xor: case Token_XorEq: - if (!is_type_integer(type) && !is_type_boolean(type)) { - error(op, "Operator '%.*s' is only allowed with integers or booleans", LIT(op.string)); + if (!is_type_integer(type) && !is_type_boolean(type) && !is_type_bit_set(type)) { + error(op, "Operator '%.*s' is only allowed with integers, booleans, or bit sets", LIT(op.string)); return false; } break; case Token_Mod: case Token_ModMod: - case Token_AndNot: case Token_ModEq: case Token_ModModEq: - case Token_AndNotEq: if (!is_type_integer(type)) { error(op, "Operator '%.*s' is only allowed with integers", LIT(op.string)); return false; } break; + case Token_AndNot: + case Token_AndNotEq: + if (!is_type_integer(type) && !is_type_bit_set(type)) { + error(op, "Operator '%.*s' is only allowed with integers and bit sets", LIT(op.string)); + return false; + } + break; + case Token_CmpAnd: case Token_CmpOr: case Token_CmpAndEq: @@ -2329,7 +2322,11 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) { return; } - Type *t = core_type(target_type); + Type *t = base_type(target_type); + if (c->in_enum_type) { + t = core_type(target_type); + } + switch (t->kind) { case Type_Basic: if (operand->mode == Addressing_Constant) { @@ -4264,6 +4261,12 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type } else { pt = type_to_string(t); } + String prefix = {}; + String prefix_sep = {}; + if (proc->pkg) { + prefix = proc->pkg->name; + prefix_sep = str_lit("."); + } String name = proc->token.string; char const *sep = "::"; @@ -4271,7 +4274,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type sep = ":="; } // gb_printf_err("\t%.*s %s %s at %.*s(%td:%td) with score %lld\n", LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column, cast(long long)valids[i].score); - gb_printf_err("\t%.*s %s %s at %.*s(%td:%td)\n", LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column); + gb_printf_err("\t%.*s%.*s%.*s %s %s at %.*s(%td:%td)\n", LIT(prefix), LIT(prefix_sep), LIT(name), sep, pt, LIT(pos.file), pos.line, pos.column); } if (procs.count > 0) { gb_printf_err("\n"); @@ -5096,9 +5099,6 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type switch (t->kind) { case Type_Struct: { - if (is_type_union(t)) { - is_constant = false; - } if (cl->elems.count == 0) { break; // NOTE(bill): No need to init } @@ -5111,7 +5111,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type break; } - { // Checker values + if (is_type_struct(t)) { // Checker values isize field_count = t->Struct.fields.count; isize min_field_count = t->Struct.fields.count; for (isize i = min_field_count-1; i >= 0; i--) { @@ -5220,6 +5220,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type } } } + break; } @@ -5409,6 +5410,39 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type break; } + case Type_BitSet: { + if (cl->elems.count == 0) { + break; // NOTE(bill): No need to init + } + Type *et = base_type(t->BitSet.base_type); + isize field_count = 0; + if (et->kind == Type_Enum) { + field_count = et->Enum.fields.count; + } + + if (cl->elems[0]->kind == Ast_FieldValue) { + error(cl->elems[0], "'field = value' in a bit_set a literal is not allowed"); + } else { + for_array(index, cl->elems) { + Entity *field = nullptr; + Ast *elem = cl->elems[index]; + if (elem->kind == Ast_FieldValue) { + error(elem, "'field = value' in a bit_set a literal is not allowed"); + continue; + } + + check_expr(c, o, elem); + + if (is_constant) { + is_constant = o->mode == Addressing_Constant; + } + + check_assignment(c, o, t->BitSet.base_type, str_lit("bit_set literal")); + } + } + break; + } + default: { if (cl->elems.count == 0) { break; // NOTE(bill): No need to init @@ -6108,6 +6142,24 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = write_expr_to_string(str, at->elem); case_end; + case_ast_node(bf, BitFieldType, node); + str = gb_string_appendc(str, "bit_field "); + if (bf->align) { + str = gb_string_appendc(str, "#align "); + str = write_expr_to_string(str, bf->align); + } + str = gb_string_appendc(str, "{"); + str = write_struct_fields_to_string(str, bf->fields); + str = gb_string_appendc(str, "}"); + case_end; + + case_ast_node(bs, BitSetType, node); + str = gb_string_appendc(str, "bit_set["); + str = write_expr_to_string(str, bs->base_type); + str = gb_string_appendc(str, "]"); + case_end; + + case_ast_node(mt, MapType, node); str = gb_string_appendc(str, "map["); str = write_expr_to_string(str, mt->key); |