From 5c8617ec688c2cd072fc179b604df537735e2982 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 6 Mar 2020 17:05:58 +0100 Subject: [PATCH] ast: set IndexType.container_type; array_get() --- vlib/v/ast/ast.v | 9 +-- vlib/v/checker/checker.v | 5 +- vlib/v/gen/cgen.v | 152 +++++++++++++++++++++------------------ vlib/v/gen/tests/1.c | 8 +-- vlib/v/gen/tests/4.c | 2 +- 5 files changed, 95 insertions(+), 81 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 554a3b94da..0009796515 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -311,10 +311,11 @@ pub: pub struct IndexExpr { pub: // op token.Kind - pos token.Position - left Expr - index Expr // [0], [start..end] etc - // typ table.Type + pos token.Position + left Expr + index Expr // [0], [start..end] etc +mut: + container_type table.Type // array, map, fixed array } pub struct IfExpr { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 25364042a8..d23822c06e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -566,7 +566,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { return table.bool_type } ast.IndexExpr { - return c.index_expr(it) + return c.index_expr(mut it) } ast.InfixExpr { return c.infix_expr(it) @@ -798,7 +798,7 @@ pub fn (c mut Checker) postfix_expr(node ast.PostfixExpr) table.Type { return typ } -pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { +pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { typ := c.expr(node.left) mut is_range := false // TODO is_range := node.index is ast.RangeExpr match node.index { @@ -808,6 +808,7 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { else {} } if !is_range { + node.container_type = typ typ_sym := c.table.get_type_symbol(typ) index_type := c.expr(node.index) index_type_sym := c.table.get_type_symbol(index_type) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 06c4057efb..e57158c782 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -173,72 +173,8 @@ fn (g mut Gen) stmt(node ast.Stmt) { } } ast.FnDecl { - if it.is_c || it.name == 'malloc' || it.no_body { - return - } - g.reset_tmp_count() g.fn_decl = it // &it - is_main := it.name == 'main' - if is_main { - g.write('int ${it.name}(') - } - else { - type_sym := g.table.get_type_symbol(it.typ) - mut name := it.name - if it.is_method { - name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name - } - name = name.replace('.', '__') - // type_name := g.table.type_to_str(it.typ) - type_name := type_sym.name.replace('.', '__') // g.table.type_to_str(it.typ) - g.write('$type_name ${name}(') - g.definitions.write('$type_name ${name}(') - } - // Receiver is the first argument - if it.is_method { - // styp := g.table.type_to_str(it.receiver.typ) - sym := g.table.get_type_symbol(it.receiver.typ) - styp := sym.name.replace('.', '__') - g.write('$styp $it.receiver.name') - g.definitions.write('$styp $it.receiver.name') - if it.args.len > 0 { - g.write(', ') - g.definitions.write(', ') - } - } - // - no_names := it.args.len > 0 && it.args[0].name == 'arg_1' - for i, arg in it.args { - arg_type_sym := g.table.get_type_symbol(arg.typ) - mut arg_type_name := arg_type_sym.name.replace('.', '__') - if i == it.args.len - 1 && it.is_variadic { - arg_type_name = 'variadic_$arg_type_name' - } - if no_names { - g.write(arg_type_name) - g.definitions.write(arg_type_name) - } - else { - g.write(arg_type_name + ' ' + arg.name) - g.definitions.write(arg_type_name + ' ' + arg.name) - } - if i < it.args.len - 1 { - g.write(', ') - g.definitions.write(', ') - } - } - g.writeln(') { ') - if !is_main { - g.definitions.writeln(');') - } - for stmt in it.stmts { - g.stmt(stmt) - } - if is_main { - g.writeln('return 0;') - } - g.writeln('}') - g.fn_decl = 0 + g.gen_fn_decl(it) } ast.ForCStmt { g.write('for (') @@ -338,6 +274,74 @@ fn (g mut Gen) stmt(node ast.Stmt) { } } +fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { + if it.is_c || it.name == 'malloc' || it.no_body { + return + } + g.reset_tmp_count() + is_main := it.name == 'main' + if is_main { + g.write('int ${it.name}(') + } + else { + type_sym := g.table.get_type_symbol(it.typ) + mut name := it.name + if it.is_method { + name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name + } + name = name.replace('.', '__') + // type_name := g.table.type_to_str(it.typ) + type_name := type_sym.name.replace('.', '__') // g.table.type_to_str(it.typ) + g.write('$type_name ${name}(') + g.definitions.write('$type_name ${name}(') + } + // Receiver is the first argument + if it.is_method { + // styp := g.table.type_to_str(it.receiver.typ) + sym := g.table.get_type_symbol(it.receiver.typ) + styp := sym.name.replace('.', '__') + g.write('$styp $it.receiver.name') + g.definitions.write('$styp $it.receiver.name') + if it.args.len > 0 { + g.write(', ') + g.definitions.write(', ') + } + } + // + no_names := it.args.len > 0 && it.args[0].name == 'arg_1' + for i, arg in it.args { + arg_type_sym := g.table.get_type_symbol(arg.typ) + mut arg_type_name := arg_type_sym.name.replace('.', '__') + if i == it.args.len - 1 && it.is_variadic { + arg_type_name = 'variadic_$arg_type_name' + } + if no_names { + g.write(arg_type_name) + g.definitions.write(arg_type_name) + } + else { + g.write(arg_type_name + ' ' + arg.name) + g.definitions.write(arg_type_name + ' ' + arg.name) + } + if i < it.args.len - 1 { + g.write(', ') + g.definitions.write(', ') + } + } + g.writeln(') { ') + if !is_main { + g.definitions.writeln(');') + } + for stmt in it.stmts { + g.stmt(stmt) + } + if is_main { + g.writeln('return 0;') + } + g.writeln('}') + g.fn_decl = 0 +} + fn (g mut Gen) expr(node ast.Expr) { // println('cgen expr() line_nr=$node.pos.line_nr') match node { @@ -596,11 +600,19 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) { } else {} } - if !is_range { - g.expr(node.left) - g.write('[') - g.expr(node.index) - g.write(']') + // if !is_range && node.container_type == 0 { + // } + if !is_range && node.container_type != 0 { + sym := g.table.get_type_symbol(node.container_type) + if sym.kind == .array { + g.write('array_get(') + g.expr(node.left) + g.write(', ') + // g.write('[') + g.expr(node.index) + g.write(')') + } + // g.write(']') } } diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 627d8c362e..34533bb61d 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -66,7 +66,7 @@ i < 10; i++) { 1, 2, 3, }); array_int nums2 = array_slice(nums, 0, 2); - int number = nums[0]; + int number = array_get(nums, 0); array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (bool[]){ true, false, }); @@ -74,16 +74,16 @@ i < 10; i++) { (User){ }, }); - bool b = bools[0]; + bool b = array_get(bools, 0); array_string mystrings = new_array_from_c_array(2, 2, sizeof(array_string), (string[]){ tos3("a"), tos3("b"), }); - string s = mystrings[0]; + string s = array_get(mystrings, 0); int x = 0; x = get_int2(); int n = get_int2(); bool q = true || false; - bool b2 = bools[0] || true; + bool b2 = array_get(bools, 0) || true; bool b3 = get_bool() || true; int f = array_int_first(nums); } diff --git a/vlib/v/gen/tests/4.c b/vlib/v/gen/tests/4.c index 0c3fffefaf..dffbee6898 100644 --- a/vlib/v/gen/tests/4.c +++ b/vlib/v/gen/tests/4.c @@ -50,7 +50,7 @@ int main() { array_Foo arr_foo = new_array_from_c_array(1, 1, sizeof(array_Foo), (Foo[]){ a, }); - Foo af_idx_el = arr_foo[0]; + Foo af_idx_el = array_get(arr_foo, 0); string foo_a = af_idx_el.a; return 0; }