From d57fbf48f0cdf4d120679205ef111c3bac4e5545 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 24 Mar 2020 15:28:58 +0000 Subject: Support by-reference semantics in `for value_ref, index in &some_array` and `for key, value_ref in &some_map` --- src/check_stmt.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/check_stmt.cpp') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index e9b6869c8..be2f6b06a 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1484,6 +1484,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { Entity *entities[2] = {}; isize entity_count = 0; bool is_map = false; + bool use_by_reference_for_value = false; Ast *expr = unparen_expr(rs->expr); @@ -1529,26 +1530,31 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { break; case Type_EnumeratedArray: + if (is_ptr) use_by_reference_for_value = true; val0 = t->EnumeratedArray.elem; val1 = t->EnumeratedArray.index; break; case Type_Array: + if (is_ptr) use_by_reference_for_value = true; val0 = t->Array.elem; val1 = t_int; break; case Type_DynamicArray: + if (is_ptr) use_by_reference_for_value = true; val0 = t->DynamicArray.elem; val1 = t_int; break; case Type_Slice: + if (is_ptr) use_by_reference_for_value = true; val0 = t->Slice.elem; val1 = t_int; break; case Type_Map: + if (is_ptr) use_by_reference_for_value = true; is_map = true; val0 = t->Map.key; val1 = t->Map.value; @@ -1628,6 +1634,14 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (found == nullptr) { entity = alloc_entity_variable(ctx->scope, token, type, EntityState_Resolved); entity->flags |= EntityFlag_Value; + if (use_by_reference_for_value) { + if (i == 0 && !is_map) { + entity->flags &= ~EntityFlag_Value; + } else if (i == 1 && is_map) { + entity->flags &= ~EntityFlag_Value; + } + } + add_entity_definition(&ctx->checker->info, name, entity); } else { TokenPos pos = found->token.pos; -- cgit v1.2.3