From f7042e9038bab232d9025f767b62546702bada5c Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Sat, 21 Mar 2020 23:57:11 +1100 Subject: [PATCH] cgen: sum type cast & map str() receiver --- vlib/v/checker/checker.v | 9 ++++++++- vlib/v/gen/cgen.v | 34 +++++++++++++++++++++++----------- vlib/v/gen/tests/3.c | 4 ++-- vlib/v/parser/parser.v | 4 ++++ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 422dae1ab6..3fc8988dca 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -333,7 +333,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) } // TODO: str methods if typ_sym.kind in [.map] && name == 'str' { - method_call_expr.receiver_type = typ + method_call_expr.receiver_type = table.new_type(c.table.type_idxs['map_string']) method_call_expr.return_type = table.string_type return table.string_type } @@ -997,9 +997,16 @@ pub fn (c mut Checker) index_expr(node mut ast.IndexExpr) table.Type { } value_type := c.table.value_type(typ) if value_type != table.void_type { + if c.is_amp { + return table.type_to_ptr(value_type) + } return value_type } } + // TODO: handle these globally, not individually + if c.is_amp { + return table.type_to_ptr(typ) + } return typ } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 36c1c7a33e..84daf47d3f 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1525,8 +1525,11 @@ fn (g mut Gen) call_args(args []ast.CallArg) { } if arg.expected_type != 0 { g.ref_or_deref_arg(arg) + g.expr_with_cast(arg.expr, arg.typ, arg.expected_type) + } + else { + g.expr(arg.expr) } - g.expr(arg.expr) if i != args.len - 1 { g.write(', ') } @@ -1670,7 +1673,9 @@ void* obj; int typ; } $name;') } - else {} + else { + g.typedefs.writeln('#define _type_idx_$name $i') + } } } } @@ -1730,15 +1735,22 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { if i >= node.exprs.len { continue } - match node.expr_types[i] { - table.string_type { - g.write('%.*s') - } - table.int_type { - g.write('%d') - } - else {} - } + // TODO: fix match, sum type false positive + // match node.expr_types[i] { + // table.string_type { + // g.write('%.*s') + // } + // table.int_type { + // g.write('%d') + // } + // else {} + // } + if node.expr_types[i] == table.string_type { + g.write('%.*s') + } + else if node.expr_types[i] == table.int_type { + g.write('%d') + } } g.write('", ') // Build args diff --git a/vlib/v/gen/tests/3.c b/vlib/v/gen/tests/3.c index 5d8f05769f..75ba9d8b5e 100644 --- a/vlib/v/gen/tests/3.c +++ b/vlib/v/gen/tests/3.c @@ -72,8 +72,8 @@ int main(int argc, char** argv) { user.name = tos3("bob"); Option_int n = get_opt(); int a = /*opt*/(*(int*)n.data) + 3; - handle_expr((IfExpr){ -0}); + handle_expr(/* sum type cast */ (Expr) {.obj = memdup(&(IfExpr[]) {(IfExpr){ +0}}, sizeof(IfExpr)), .typ = 25}); return 0; } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ba000e00c7..d050c3a0ed 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1685,6 +1685,7 @@ fn (p mut Parser) global_decl() ast.GlobalDecl { fn (p mut Parser) match_expr() ast.MatchExpr { p.check(.key_match) + pos := p.tok.position() is_mut := p.tok.kind == .key_mut mut is_sum_type := false if is_mut { @@ -1695,6 +1696,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { mut branches := []ast.MatchBranch for { mut exprs := []ast.Expr + branch_pos := p.tok.position() p.open_scope() // final else if p.tok.kind == .key_else { @@ -1739,6 +1741,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { branches << ast.MatchBranch{ exprs: exprs stmts: stmts + pos: branch_pos } p.close_scope() if p.tok.kind == .rcbr { @@ -1750,6 +1753,7 @@ fn (p mut Parser) match_expr() ast.MatchExpr { branches: branches cond: cond is_sum_type: is_sum_type + pos: pos } }