diff --git a/core/sort/sort.odin b/core/sort/sort.odin index f511de226..4394cd259 100644 --- a/core/sort/sort.odin +++ b/core/sort/sort.odin @@ -189,6 +189,14 @@ merge_sort :: proc(array: $A/[]$T) { } +compare_bools :: proc(a, b: bool) -> int { + switch { + case !a && b: return -1; + case a && !b: return +1; + } + return 0; +} + compare_ints :: proc(a, b: int) -> int { switch delta := a - b; { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2193af114..405316220 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -4440,8 +4440,8 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, // NOTE(bill): override DeclInfo for dependency Entity *e = lhs[tuple_index]; if (e != nullptr) { - DeclInfo *decl = decl_info_of_entity(e); - if (decl) c->decl = decl; + // DeclInfo *decl = decl_info_of_entity(e); + // if (decl) c->decl = decl; type_hint = e->type; if (e->flags & EntityFlag_Ellipsis) { GB_ASSERT(is_type_slice(e->type)); @@ -4449,13 +4449,12 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, type_hint = e->type->Slice.elem; } } - } - if (lhs != nullptr && tuple_index >= lhs_count && is_variadic) { + } else if (lhs != nullptr && tuple_index >= lhs_count && is_variadic) { // NOTE(bill): override DeclInfo for dependency Entity *e = lhs[lhs_count-1]; if (e != nullptr) { - DeclInfo *decl = decl_info_of_entity(e); - if (decl) c->decl = decl; + // DeclInfo *decl = decl_info_of_entity(e); + // if (decl) c->decl = decl; type_hint = e->type; if (e->flags & EntityFlag_Ellipsis) { GB_ASSERT(is_type_slice(e->type)); @@ -4930,6 +4929,40 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { return err; } +Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize *lhs_count_, bool *is_variadic) { + Entity **lhs = nullptr; + isize lhs_count = -1; + + if (proc_type == nullptr) { + return nullptr; + } + + GB_ASSERT(is_type_proc(proc_type)); + TypeProc *pt = &base_type(proc_type)->Proc; + *is_variadic = pt->variadic; + + if (!pt->is_polymorphic || pt->is_poly_specialized) { + if (pt->params != nullptr) { + lhs = pt->params->Tuple.variables.data; + lhs_count = pt->params->Tuple.variables.count; + } + } else { + // NOTE(bill): Create 'lhs' list in order to ignore parameters which are polymorphic + lhs_count = pt->params->Tuple.variables.count; + lhs = gb_alloc_array(heap_allocator(), Entity *, lhs_count); + for_array(i, pt->params->Tuple.variables) { + Entity *e = pt->params->Tuple.variables[i]; + if (!is_type_polymorphic(e->type)) { + lhs[i] = e; + } + } + } + + if (lhs_count_) *lhs_count_ = lhs_count; + + return lhs; +} + CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call) { ast_node(ce, CallExpr, call); @@ -4960,28 +4993,11 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type isize lhs_count = -1; bool is_variadic = false; if (proc_type != nullptr && is_type_proc(proc_type)) { - TypeProc *pt = &base_type(proc_type)->Proc; - is_variadic = pt->variadic; - - if (!pt->is_polymorphic || pt->is_poly_specialized) { - if (pt->params != nullptr) { - lhs = pt->params->Tuple.variables.data; - lhs_count = pt->params->Tuple.variables.count; - } - } else { - // NOTE(bill): Create 'lhs' list in order to ignore parameters which are polymorphic - lhs_count = pt->params->Tuple.variables.count; - lhs = gb_alloc_array(heap_allocator(), Entity *, lhs_count); - for_array(i, pt->params->Tuple.variables) { - Entity *e = pt->params->Tuple.variables[i]; - if (!is_type_polymorphic(e->type)) { - lhs[i] = e; - } - } - } + lhs = populate_proc_parameter_list(c, proc_type, &lhs_count, &is_variadic); + } + if (operand->mode != Addressing_ProcGroup) { + check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, is_variadic); } - - check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, is_variadic); } if (operand->mode == Addressing_ProcGroup) { @@ -4998,6 +5014,13 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type Entity *e = procs[0]; + Entity **lhs = nullptr; + isize lhs_count = -1; + bool is_variadic = false; + lhs = populate_proc_parameter_list(c, e->type, &lhs_count, &is_variadic); + check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, is_variadic); + + 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; @@ -5006,6 +5029,8 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type return data; } + check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false, false); + ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count); isize valid_count = 0; defer (gb_free(heap_allocator(), valids)); @@ -5015,7 +5040,6 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type for_array(i, procs) { Entity *p = procs[i]; - check_entity_decl(c, p, nullptr, nullptr); Type *pt = base_type(p->type); if (pt != nullptr && is_type_proc(pt)) { CallArgumentError err = CallArgumentError_None; diff --git a/src/ir.cpp b/src/ir.cpp index 08960efab..4eee6f54f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7687,6 +7687,7 @@ void ir_build_assign_op(irProcedure *proc, irAddr const &lhs, irValue *value, To } else { change = ir_emit_conv(proc, value, type); } + irValue *new_value = ir_emit_arith(proc, op, old_value, change, type); ir_addr_store(proc, lhs, new_value); } @@ -8394,14 +8395,20 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { // +=, -=, etc i32 op = cast(i32)as->op.kind; op += Token_Add - Token_AddEq; // Convert += to + - irAddr lhs = ir_build_addr(proc, as->lhs[0]); - irValue *value = ir_build_expr(proc, as->rhs[0]); - ir_build_assign_op(proc, lhs, value, cast(TokenKind)op); - break; - } - } + if (op == Token_CmpAnd || op == Token_CmpOr) { + Type *type = as->lhs[0]->tav.type; + irValue *new_value = ir_emit_logical_binary_expr(proc, cast(TokenKind)op, as->lhs[0], as->rhs[0], type); - gb_temp_arena_memory_end(tmp); + irAddr lhs = ir_build_addr(proc, as->lhs[0]); + ir_addr_store(proc, lhs, new_value); + } else { + irAddr lhs = ir_build_addr(proc, as->lhs[0]); + irValue *value = ir_build_expr(proc, as->rhs[0]); + ir_build_assign_op(proc, lhs, value, cast(TokenKind)op); + } + return; + } + } case_end; case_ast_node(es, ExprStmt, node); diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 6fed6d97d..c47511285 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -32,9 +32,8 @@ TOKEN_KIND(Token__OperatorBegin, ""), \ TOKEN_KIND(Token_AndNot, "&~"), \ TOKEN_KIND(Token_Shl, "<<"), \ TOKEN_KIND(Token_Shr, ">>"), \ -\ - TOKEN_KIND(Token_CmpAnd, "&&"), \ - TOKEN_KIND(Token_CmpOr, "||"), \ + TOKEN_KIND(Token_CmpAnd, "&&"), \ + TOKEN_KIND(Token_CmpOr, "||"), \ \ TOKEN_KIND(Token__AssignOpBegin, ""), \ TOKEN_KIND(Token_AddEq, "+="), \