From 67cf7f18e6a5b6dd5bd538a41542cd25a22a1fd7 Mon Sep 17 00:00:00 2001 From: BigBlack <840206@qq.com> Date: Wed, 18 Dec 2019 08:26:04 +0800 Subject: [PATCH] array of pointers support --- vlib/builtin/array_test.v | 13 +++++++++++++ vlib/compiler/expression.v | 2 +- vlib/compiler/for.v | 4 ++-- vlib/compiler/gen_c.v | 6 +----- vlib/compiler/parser.v | 17 ++++++++++------- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 56ba06216d..9abc9b7a7e 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -3,6 +3,19 @@ const ( A = 8 ) +fn test_pointer() { + mut arr := []*int + a := 1 + b := 2 + c := 3 + arr << &a + arr << &b + arr << &c + assert *arr[0] == 1 + arr[1] = &c + assert *arr[1] == 3 +} + fn test_ints() { mut a := [1, 5, 2, 3] assert a.len == 4 diff --git a/vlib/compiler/expression.v b/vlib/compiler/expression.v index 655d550abe..c2eb9756b8 100644 --- a/vlib/compiler/expression.v +++ b/vlib/compiler/expression.v @@ -416,7 +416,7 @@ fn (p mut Parser) expression() string { // a << 7 => int tmp = 7; array_push(&a, &tmp); // _PUSH(&a, expression(), tmp, string) tmp := p.get_tmp() - tmp_typ := typ[6..]// skip "array_" + tmp_typ := typ[6..].replace('_ptr','*')// skip "array_" p.check_space(.left_shift) // Get the value we are pushing p.gen(', (') diff --git a/vlib/compiler/for.v b/vlib/compiler/for.v index 5badadfaf2..5ba2dfaa16 100644 --- a/vlib/compiler/for.v +++ b/vlib/compiler/for.v @@ -89,7 +89,7 @@ fn (p mut Parser) for_st() { p.gen_for_varg_header(i, expr, typ, val) } else if is_arr { - typ = typ[6..] + typ = typ[6..].replace('_ptr','*') p.gen_for_header(i, tmp, typ, val) } else if is_map { @@ -174,7 +174,7 @@ fn (p mut Parser) for_st() { p.gen_for_range_header(i, range_end, tmp, typ, val) } else if is_arr { - typ = typ[6..]// all after `array_` + typ = typ[6..].replace('_ptr','*')// all after `array_` p.gen_for_header(i, tmp, typ, val) } else if is_str { diff --git a/vlib/compiler/gen_c.v b/vlib/compiler/gen_c.v index 90f7c39101..38ebecd82c 100644 --- a/vlib/compiler/gen_c.v +++ b/vlib/compiler/gen_c.v @@ -676,11 +676,7 @@ fn (p mut Parser) gen_array_push(ph int, typ, expr_type, tmp, elm_type string) { // Don't dereference if it's already a mutable array argument (`fn foo(mut []int)`) push_call := if typ.contains('*'){'_PUSH('} else { '_PUSH(&'} p.cgen.set_placeholder(ph, push_call) - if elm_type.ends_with('*') { - p.gen('), $tmp, ${elm_type[..elm_type.len - 1]})') - } else { - p.gen('), $tmp, $elm_type)') - } + p.gen('), $tmp, $elm_type)') } } diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 5d038b5e98..26ed66a4cd 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -2090,7 +2090,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string { } if is_arr { if is_arr0 { - typ = typ[6..] + typ = typ[6..].replace('_ptr', '*') } p.gen_array_at(typ, is_arr0, fn_ph) } @@ -2203,6 +2203,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string { // } // `m[key]`. no =, just a getter else if (is_map || is_arr || (is_str && !p.builtin_mod)) && is_indexer { + typ = typ.replace('_ptr','*') p.index_get(typ, fn_ph, IndexConfig{ is_arr: is_arr is_map: is_map @@ -2496,16 +2497,16 @@ fn (p mut Parser) array_init() string { p.check(.rsbr) // type after `]`? (e.g. "[]string") exp_array := p.expected_type.starts_with('array_') - if p.tok != .name && p.tok != .lsbr && i == 0 && !exp_array { - p.error('specify array type: `[]typ` instead of `[]`') - } - if p.tok == .name && i == 0 && + if p.tok != .name && p.tok != .mul && p.tok != .lsbr && i == 0 && !exp_array { + p.error('specify array type: `[]typ` instead of `[]`') + } + if i == 0 && (p.tok == .name || p.tok == .mul) && p.tokens[p.token_idx-2].line_nr == p.tokens[p.token_idx-1].line_nr { // TODO // vals.len == 0 { if exp_array { p.error('no need to specify the full array type here, use `[]` instead of `[]${p.expected_type[6..]}`') } - typ = p.get_type() + typ = p.get_type().replace('*','_ptr') } else if exp_array && i == 0 { // allow `known_array = []` typ = p.expected_type[6..] @@ -2536,7 +2537,9 @@ fn (p mut Parser) array_init() string { // if ptr { // typ += '_ptr" // } - p.gen_array_init(typ, no_alloc, new_arr_ph, i) + + real := typ.replace('_ptr','*') + p.gen_array_init(real, no_alloc, new_arr_ph, i) typ = 'array_$typ' p.register_array(typ) return typ