mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
Fix ||= and &&=
This commit is contained in:
@@ -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 {
|
compare_ints :: proc(a, b: int) -> int {
|
||||||
switch delta := a - b; {
|
switch delta := a - b; {
|
||||||
|
|||||||
+52
-28
@@ -4440,8 +4440,8 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count,
|
|||||||
// NOTE(bill): override DeclInfo for dependency
|
// NOTE(bill): override DeclInfo for dependency
|
||||||
Entity *e = lhs[tuple_index];
|
Entity *e = lhs[tuple_index];
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
// DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl) c->decl = decl;
|
// if (decl) c->decl = decl;
|
||||||
type_hint = e->type;
|
type_hint = e->type;
|
||||||
if (e->flags & EntityFlag_Ellipsis) {
|
if (e->flags & EntityFlag_Ellipsis) {
|
||||||
GB_ASSERT(is_type_slice(e->type));
|
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;
|
type_hint = e->type->Slice.elem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (lhs != nullptr && tuple_index >= lhs_count && is_variadic) {
|
||||||
if (lhs != nullptr && tuple_index >= lhs_count && is_variadic) {
|
|
||||||
// NOTE(bill): override DeclInfo for dependency
|
// NOTE(bill): override DeclInfo for dependency
|
||||||
Entity *e = lhs[lhs_count-1];
|
Entity *e = lhs[lhs_count-1];
|
||||||
if (e != nullptr) {
|
if (e != nullptr) {
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
// DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl) c->decl = decl;
|
// if (decl) c->decl = decl;
|
||||||
type_hint = e->type;
|
type_hint = e->type;
|
||||||
if (e->flags & EntityFlag_Ellipsis) {
|
if (e->flags & EntityFlag_Ellipsis) {
|
||||||
GB_ASSERT(is_type_slice(e->type));
|
GB_ASSERT(is_type_slice(e->type));
|
||||||
@@ -4930,6 +4929,40 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
|
|||||||
return err;
|
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) {
|
CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call) {
|
||||||
ast_node(ce, CallExpr, call);
|
ast_node(ce, CallExpr, call);
|
||||||
|
|
||||||
@@ -4960,28 +4993,11 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
isize lhs_count = -1;
|
isize lhs_count = -1;
|
||||||
bool is_variadic = false;
|
bool is_variadic = false;
|
||||||
if (proc_type != nullptr && is_type_proc(proc_type)) {
|
if (proc_type != nullptr && is_type_proc(proc_type)) {
|
||||||
TypeProc *pt = &base_type(proc_type)->Proc;
|
lhs = populate_proc_parameter_list(c, proc_type, &lhs_count, &is_variadic);
|
||||||
is_variadic = pt->variadic;
|
}
|
||||||
|
if (operand->mode != Addressing_ProcGroup) {
|
||||||
if (!pt->is_polymorphic || pt->is_poly_specialized) {
|
check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, is_variadic);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_unpack_arguments(c, lhs, lhs_count, &operands, ce->args, false, is_variadic);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operand->mode == Addressing_ProcGroup) {
|
if (operand->mode == Addressing_ProcGroup) {
|
||||||
@@ -4998,6 +5014,13 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
|
|
||||||
Entity *e = procs[0];
|
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 = {};
|
CallArgumentData data = {};
|
||||||
CallArgumentError err = call_checker(c, call, e->type, e, operands, CallArgumentMode_ShowErrors, &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;
|
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;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_unpack_arguments(c, nullptr, -1, &operands, ce->args, false, false);
|
||||||
|
|
||||||
ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count);
|
ValidIndexAndScore *valids = gb_alloc_array(heap_allocator(), ValidIndexAndScore, procs.count);
|
||||||
isize valid_count = 0;
|
isize valid_count = 0;
|
||||||
defer (gb_free(heap_allocator(), valids));
|
defer (gb_free(heap_allocator(), valids));
|
||||||
@@ -5015,7 +5040,6 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
|
|||||||
|
|
||||||
for_array(i, procs) {
|
for_array(i, procs) {
|
||||||
Entity *p = procs[i];
|
Entity *p = procs[i];
|
||||||
check_entity_decl(c, p, nullptr, nullptr);
|
|
||||||
Type *pt = base_type(p->type);
|
Type *pt = base_type(p->type);
|
||||||
if (pt != nullptr && is_type_proc(pt)) {
|
if (pt != nullptr && is_type_proc(pt)) {
|
||||||
CallArgumentError err = CallArgumentError_None;
|
CallArgumentError err = CallArgumentError_None;
|
||||||
|
|||||||
+14
-7
@@ -7687,6 +7687,7 @@ void ir_build_assign_op(irProcedure *proc, irAddr const &lhs, irValue *value, To
|
|||||||
} else {
|
} else {
|
||||||
change = ir_emit_conv(proc, value, type);
|
change = ir_emit_conv(proc, value, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *new_value = ir_emit_arith(proc, op, old_value, change, type);
|
irValue *new_value = ir_emit_arith(proc, op, old_value, change, type);
|
||||||
ir_addr_store(proc, lhs, new_value);
|
ir_addr_store(proc, lhs, new_value);
|
||||||
}
|
}
|
||||||
@@ -8394,14 +8395,20 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
|
|||||||
// +=, -=, etc
|
// +=, -=, etc
|
||||||
i32 op = cast(i32)as->op.kind;
|
i32 op = cast(i32)as->op.kind;
|
||||||
op += Token_Add - Token_AddEq; // Convert += to +
|
op += Token_Add - Token_AddEq; // Convert += to +
|
||||||
irAddr lhs = ir_build_addr(proc, as->lhs[0]);
|
if (op == Token_CmpAnd || op == Token_CmpOr) {
|
||||||
irValue *value = ir_build_expr(proc, as->rhs[0]);
|
Type *type = as->lhs[0]->tav.type;
|
||||||
ir_build_assign_op(proc, lhs, value, cast(TokenKind)op);
|
irValue *new_value = ir_emit_logical_binary_expr(proc, cast(TokenKind)op, as->lhs[0], as->rhs[0], type);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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_end;
|
||||||
|
|
||||||
case_ast_node(es, ExprStmt, node);
|
case_ast_node(es, ExprStmt, node);
|
||||||
|
|||||||
+2
-3
@@ -32,9 +32,8 @@ TOKEN_KIND(Token__OperatorBegin, ""), \
|
|||||||
TOKEN_KIND(Token_AndNot, "&~"), \
|
TOKEN_KIND(Token_AndNot, "&~"), \
|
||||||
TOKEN_KIND(Token_Shl, "<<"), \
|
TOKEN_KIND(Token_Shl, "<<"), \
|
||||||
TOKEN_KIND(Token_Shr, ">>"), \
|
TOKEN_KIND(Token_Shr, ">>"), \
|
||||||
\
|
TOKEN_KIND(Token_CmpAnd, "&&"), \
|
||||||
TOKEN_KIND(Token_CmpAnd, "&&"), \
|
TOKEN_KIND(Token_CmpOr, "||"), \
|
||||||
TOKEN_KIND(Token_CmpOr, "||"), \
|
|
||||||
\
|
\
|
||||||
TOKEN_KIND(Token__AssignOpBegin, ""), \
|
TOKEN_KIND(Token__AssignOpBegin, ""), \
|
||||||
TOKEN_KIND(Token_AddEq, "+="), \
|
TOKEN_KIND(Token_AddEq, "+="), \
|
||||||
|
|||||||
Reference in New Issue
Block a user