diff options
| author | gingerBill <bill@gingerbill.org> | 2020-04-19 21:45:04 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2020-04-19 21:45:04 +0100 |
| commit | 97f7a558faaf206bb7d10eaf3adce99322fd9541 (patch) | |
| tree | 2a3e8f91525692f14de4064751efae62699f10bb /src/check_expr.cpp | |
| parent | 2c91c21021e1c4d1d675ee430e0d7ccf88e882be (diff) | |
`#optional_ok` tag for procedures
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 9879d3b8b..357c6b53a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5750,12 +5750,41 @@ bool check_assignment_arguments(CheckerContext *ctx, Array<Operand> const &lhs, optional_ok = true; tuple_index += 2; + } else if (o.mode == Addressing_OptionalOk) { + Type *tuple = o.type; + GB_ASSERT(is_type_tuple(tuple)); + GB_ASSERT(tuple->Tuple.variables.count == 2); + Ast *expr = unparen_expr(o.expr); + if (expr->kind == Ast_CallExpr) { + expr->CallExpr.optional_ok_one = true; + } + Operand val = o; + val.type = tuple->Tuple.variables[0]->type; + val.mode = Addressing_Value; + array_add(operands, val); + tuple_index += 1; } else { array_add(operands, o); tuple_index += 1; } } else { TypeTuple *tuple = &o.type->Tuple; + if (o.mode == Addressing_OptionalOk) { + GB_ASSERT(tuple->variables.count == 2); + if (lhs.count == 1) { + Ast *expr = unparen_expr(o.expr); + if (expr->kind == Ast_CallExpr) { + expr->CallExpr.optional_ok_one = true; + } + Operand val = o; + val.type = tuple->variables[0]->type; + val.mode = Addressing_Value; + array_add(operands, val); + tuple_index += 1; + continue; + } + } + for_array(j, tuple->variables) { o.type = tuple->variables[j]->type; array_add(operands, o); @@ -5839,6 +5868,22 @@ bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, } } else { TypeTuple *tuple = &o.type->Tuple; + if (o.mode == Addressing_OptionalOk) { + GB_ASSERT(tuple->variables.count == 2); + if (lhs_count == 1) { + Ast *expr = unparen_expr(o.expr); + if (expr->kind == Ast_CallExpr) { + expr->CallExpr.optional_ok_one = true; + } + Operand val = o; + val.type = tuple->variables[0]->type; + val.mode = Addressing_Value; + array_add(operands, val); + tuple_index += 1; + continue; + } + } + for_array(j, tuple->variables) { o.type = tuple->variables[j]->type; array_add(operands, o); @@ -7332,7 +7377,7 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Type *t if (pl->inlining == ProcInlining_no_inline) { error(call, "'inline' cannot be applied to a procedure that has be marked as 'no_inline'"); } - } + } } break; } @@ -7342,6 +7387,11 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Type *t } operand->expr = call; + + if (pt->kind == Type_Proc && pt->Proc.optional_ok) { + operand->mode = Addressing_OptionalOk; + } + return Expr_Expr; } |