diff options
| author | gingerBill <bill@gingerbill.org> | 2018-07-08 11:03:56 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-07-08 11:03:56 +0100 |
| commit | 0e91298fd1d16de9bc0c11b9ccf0dcd7e43603a2 (patch) | |
| tree | 453c6f5960ee3eb2dc52a01524f0de8251b0acee /src | |
| parent | e515220694c79f44f0ee2783287667dc4ab5e5fe (diff) | |
Rename `free` to `delete` for non pointer types
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.cpp | 17 | ||||
| -rw-r--r-- | src/ir.cpp | 101 | ||||
| -rw-r--r-- | src/parser.cpp | 2 |
3 files changed, 72 insertions, 48 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 6079fa202..8b3e6dfe7 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4496,6 +4496,23 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type Array<Entity *> procs = proc_group_entities(c, *operand); + if (procs.count == 1) { + Ast *ident = operand->expr; + while (ident->kind == Ast_SelectorExpr) { + Ast *s = ident->SelectorExpr.selector; + ident = s; + } + + Entity *e = procs[0]; + + CallArgumentData data = {}; + CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &data); + Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e; + add_entity_use(c, ident, entity_to_use); + + return data; + } + ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count); isize valid_count = 0; defer (gb_free(heap_allocator(), valids)); diff --git a/src/ir.cpp b/src/ir.cpp index c5cf04ddb..75fd2c592 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6581,7 +6581,7 @@ void ir_build_range_string(irProcedure *proc, irValue *expr, Type *val_type, } void ir_build_range_interval(irProcedure *proc, AstBinaryExpr *node, Type *val_type, - irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) { + irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) { // TODO(bill): How should the behaviour work for lower and upper bounds checking for iteration? // If 'lower' is changed, should 'val' do so or is that not typical behaviour? @@ -6638,6 +6638,58 @@ void ir_build_range_interval(irProcedure *proc, AstBinaryExpr *node, Type *val_t if (done_) *done_ = done; } +void ir_build_range_enum(irProcedure *proc, Type *enum_type, Type *val_type, irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) { + Type *t = enum_type; + GB_ASSERT(is_type_enum(t)); + Type *enum_ptr = alloc_type_pointer(t); + t = base_type(t); + Type *core_elem = core_type(t); + i64 enum_count = t->Enum.fields.count; + irValue *max_count = ir_const_int(enum_count); + + irValue *ti = ir_type_info(proc, t); + irValue *variant = ir_emit_struct_ep(proc, ti, 2); + irValue *eti_ptr = ir_emit_conv(proc, variant, t_type_info_enum_ptr); + irValue *values = ir_emit_load(proc, ir_emit_struct_ep(proc, eti_ptr, 2)); + irValue *values_data = ir_slice_elem(proc, values); + + irValue *offset_ = ir_add_local_generated(proc, t_int); + ir_emit_store(proc, offset_, v_zero); + + irBlock *loop = ir_new_block(proc, nullptr, "for.enum.loop"); + ir_emit_jump(proc, loop); + ir_start_block(proc, loop); + + irBlock *body = ir_new_block(proc, nullptr, "for.enum.body"); + irBlock *done = ir_new_block(proc, nullptr, "for.enum.done"); + + irValue *offset = ir_emit_load(proc, offset_); + irValue *cond = ir_emit_comp(proc, Token_Lt, offset, max_count); + ir_emit_if(proc, cond, body, done); + ir_start_block(proc, body); + + irValue *val_ptr = ir_emit_ptr_offset(proc, values_data, offset); + ir_emit_increment(proc, offset_); + + irValue *val = nullptr; + if (val_type != nullptr) { + if (is_type_float(core_elem)) { + irValue *f = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_f64_ptr)); + val = ir_emit_conv(proc, f, t); + } else if (is_type_integer(core_elem)) { + irValue *i = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_i64_ptr)); + val = ir_emit_conv(proc, i, t); + } else { + GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem)); + } + } + + if (val_) *val_ = val; + if (idx_) *idx_ = offset; + if (loop_) *loop_ = loop; + if (done_) *done_ = done; +} + void ir_store_type_case_implicit(irProcedure *proc, Ast *clause, irValue *value) { Entity *e = implicit_entity_of_node(clause); GB_ASSERT(e != nullptr); @@ -7003,52 +7055,7 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { if (is_ast_range(expr)) { ir_build_range_interval(proc, &expr->BinaryExpr, val0_type, &val, &key, &loop, &done); } else if (tav.mode == Addressing_Type) { - TokenPos pos = ast_token(expr).pos; - gbAllocator a = ir_allocator(); - Type *t = tav.type; - GB_ASSERT(is_type_enum(t)); - Type *enum_ptr = alloc_type_pointer(t); - t = base_type(t); - Type *core_elem = core_type(t); - i64 enum_count = t->Enum.fields.count; - irValue *max_count = ir_const_int(enum_count); - - irValue *ti = ir_type_info(proc, t); - irValue *variant = ir_emit_struct_ep(proc, ti, 2); - irValue *eti_ptr = ir_emit_conv(proc, variant, t_type_info_enum_ptr); - irValue *values = ir_emit_load(proc, ir_emit_struct_ep(proc, eti_ptr, 2)); - irValue *values_data = ir_slice_elem(proc, values); - - irValue *offset_ = ir_add_local_generated(proc, t_int); - ir_emit_store(proc, offset_, v_zero); - - loop = ir_new_block(proc, nullptr, "for.enum.loop"); - ir_emit_jump(proc, loop); - ir_start_block(proc, loop); - - irBlock *body = ir_new_block(proc, nullptr, "for.enum.body"); - done = ir_new_block(proc, nullptr, "for.enum.done"); - - irValue *offset = ir_emit_load(proc, offset_); - irValue *cond = ir_emit_comp(proc, Token_Lt, offset, max_count); - ir_emit_if(proc, cond, body, done); - ir_start_block(proc, body); - - irValue *val_ptr = ir_emit_ptr_offset(proc, values_data, offset); - ir_emit_increment(proc, offset_); - - key = offset; - if (val0_type != nullptr) { - if (is_type_float(core_elem)) { - irValue *f = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_f64_ptr)); - val = ir_emit_conv(proc, f, t); - } else if (is_type_integer(core_elem)) { - irValue *i = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_i64_ptr)); - val = ir_emit_conv(proc, i, t); - } else { - GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem)); - } - } + ir_build_range_enum(proc, tav.type, val0_type, &val, &key, &loop, &done); } else { Type *expr_type = type_of_expr(rs->expr); Type *et = base_type(type_deref(expr_type)); diff --git a/src/parser.cpp b/src/parser.cpp index 600c35608..39f67b4c4 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4292,7 +4292,7 @@ bool parse_file(Parser *p, AstFile *f) { CommentGroup *docs = f->lead_comment; f->package_token = expect_token(f, Token_package); - if (f->error_count > 0) { + if (f->package_token.kind != Token_package) { return false; } Token package_name = expect_token_after(f, Token_Ident, "package"); |