From a456c21249b80f63e24a8a5440808727a3d8efdc Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Thu, 19 Mar 2020 19:40:21 +1100 Subject: [PATCH] gen: cgen sum cast in struct init --- vlib/v/ast/ast.v | 11 +++++++---- vlib/v/checker/checker.v | 6 ++++-- vlib/v/gen/cgen.v | 14 +++++++------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index c512f01323..72206e9385 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -112,10 +112,13 @@ pub: pub struct StructInit { pub: - pos token.Position - typ table.Type - fields []string - exprs []Expr + pos token.Position + typ table.Type + fields []string + exprs []Expr +mut: + expr_types []table.Type + expected_types []table.Type } // import statement diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 12e18b47ef..9cc2229257 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -71,7 +71,7 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) { } } -pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type { +pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type { // typ := c.table.find_type(struct_init.typ.typ.name) or { // c.error('unknown struct: $struct_init.typ.typ.name', struct_init.pos) // panic('') @@ -117,6 +117,8 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type if !c.table.check(expr_type, field.typ) { c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$field.name`', struct_init.pos) } + struct_init.expr_types << expr_type + struct_init.expected_types << field.typ } } else {} @@ -726,7 +728,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { return table.string_type } ast.StructInit { - return c.check_struct_init(it) + return c.struct_init(mut it) } ast.Type { return it.typ diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 55be43404e..89053c7ea3 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -345,7 +345,7 @@ fn (g mut Gen) stmt(node ast.Stmt) { } // use instead of expr() when you need to cast to sum type (can add other casts also) -fn (g mut Gen) expr_with_cast(got_type table.Type, exp_type table.Type, expr ast.Expr) { +fn (g mut Gen) expr_with_cast(expr ast.Expr, got_type table.Type, exp_type table.Type) { // cast to sum type if exp_type != table.void_type && exp_type != 0 && got_type != 0 { exp_sym := g.table.get_type_symbol(exp_type) @@ -432,7 +432,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { if !is_fixed_array_init { g.write(' = ') if !is_decl { - g.expr_with_cast(assign_stmt.left_types[i], ident_var_info.typ, val) + g.expr_with_cast(val, assign_stmt.left_types[i], ident_var_info.typ) } else { g.expr(val) @@ -603,7 +603,7 @@ fn (g mut Gen) expr(node ast.Expr) { g.write(', ') } g.is_assign_expr = false - g.expr_with_cast(it.right_type, it.left_type, it.val) + g.expr_with_cast(it.val, it.right_type, it.left_type) if g.is_array_set { g.write(' })') g.is_array_set = false @@ -854,7 +854,7 @@ fn (g mut Gen) expr(node ast.Expr) { } for i, field in it.fields { g.write('\t.$field = ') - g.expr(it.exprs[i]) + g.expr_with_cast(it.exprs[i], it.expr_types[i], it.expected_types[i]) g.writeln(', ') } if it.fields.len == 0 { @@ -964,7 +964,7 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) { if right_sym.kind == .array { // push an array => PUSH_MANY g.write('_PUSH_MANY(&') - g.expr_with_cast(node.right_type, node.left_type, node.left) + g.expr_with_cast(node.left, node.right_type, node.left_type) g.write(', (') g.expr(node.right) styp := g.typ(node.left_type) @@ -976,7 +976,7 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) { elem_type_str := g.typ(info.elem_type) // g.write('array_push(&') g.write('_PUSH(&') - g.expr_with_cast(node.right_type, info.elem_type, node.left) + g.expr_with_cast(node.left, node.right_type, info.elem_type) g.write(', (') g.expr(node.right) g.write('), $tmp, $elem_type_str)') @@ -1328,7 +1328,7 @@ fn (g mut Gen) return_statement(it ast.Return) { // Automatic Dereference g.write('*') } - g.expr_with_cast(it.types[0], g.fn_decl.return_type, it.exprs[0]) + g.expr_with_cast(it.exprs[0], it.types[0], g.fn_decl.return_type) } g.writeln(';') }