aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-05-06 11:32:35 +0100
committergingerBill <bill@gingerbill.org>2019-05-06 11:32:35 +0100
commitab0afa548b40ea3c0be6ebcbe1571cd6c3569021 (patch)
treec430175c4b571b2c61ce4677b6379c225445e792 /src
parentea1690b7a128e435b86e332d0742150cb9db02b0 (diff)
Fix ||= and &&=
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp80
-rw-r--r--src/ir.cpp19
-rw-r--r--src/tokenizer.cpp5
3 files changed, 67 insertions, 37 deletions
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);
+
+ 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;
}
}
-
- gb_temp_arena_memory_end(tmp);
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, "+="), \