diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index faf1db3939..f6fe7ac2d2 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -626,6 +626,7 @@ pub: expr Expr // `buf` arg Expr // `n` in `string(buf, n)` typ table.Type // `string` + typname string mut: expr_type table.Type // `byteptr` has_arg bool diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 25d4d16800..d51a21b1d3 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -72,7 +72,7 @@ pub fn (x Expr) str() string { return it.name } InfixExpr { - return '(${it.left.str()} $it.op.str() ${it.right.str()})' + return '${it.left.str()} $it.op.str() ${it.right.str()}' } PrefixExpr { return it.op.str() + it.right.str() @@ -80,6 +80,9 @@ pub fn (x Expr) str() string { IntegerLiteral { return it.val } + FloatLiteral { + return it.val + } StringLiteral { return '"$it.val"' } @@ -113,6 +116,9 @@ pub fn (x Expr) str() string { IndexExpr { return '${it.left.str()}[${it.index.str()}]' } + CastExpr { + return '${it.typname}(${it.expr.str()})' + } else { return '[unhandled expr type ${typeof(x)}]' } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 4059a07584..962c55cb10 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -676,7 +676,11 @@ fn (c mut Checker) stmt(node ast.Stmt) { // c.expected_type = table.void_type match mut node { ast.AssertStmt { - c.expr(it.expr) + assert_type := c.expr(it.expr) + if assert_type != table.bool_type_idx { + atype_name := c.table.get_type_symbol(assert_type).name + c.error('assert can be used only with `bool` expressions, but found `${atype_name}` instead', it.pos) + } } ast.AssignStmt { c.assign_stmt(mut it) @@ -875,6 +879,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { if it.has_arg { c.expr(it.arg) } + it.typname = c.table.get_type_symbol(it.typ).name return it.typ } ast.CallExpr { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index d9d12947d6..bb0e23ac02 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -611,11 +611,10 @@ fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) { if g.is_test { g.writeln('{') g.writeln(' g_test_oks++;') - g.writeln(' cb_assertion_ok( _STR("${mod_path}"), ${a.pos.line_nr}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );') - // g.writeln(' println(_STR("OK ${mod_path}:${a.pos.line_nr}: fn ${g.fn_decl.name}(): assert $s_assertion"));') + g.writeln(' cb_assertion_ok( _STR("${mod_path}"), ${a.pos.line_nr+1}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );') g.writeln('}else{') g.writeln(' g_test_fails++;') - g.writeln(' cb_assertion_failed( _STR("${mod_path}"), ${a.pos.line_nr}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );') + g.writeln(' cb_assertion_failed( _STR("${mod_path}"), ${a.pos.line_nr+1}, _STR("assert ${s_assertion}"), _STR("${g.fn_decl.name}()") );') g.writeln(' exit(1);') g.writeln(' // TODO') g.writeln(' // Maybe print all vars in a test function if it fails?') @@ -623,7 +622,7 @@ fn (g mut Gen) gen_assert_stmt(a ast.AssertStmt) { return } g.writeln('{}else{') - g.writeln(' eprintln(_STR("${mod_path}:${a.pos.line_nr}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));') + g.writeln(' eprintln(_STR("${mod_path}:${a.pos.line_nr+1}: FAIL: fn ${g.fn_decl.name}(): assert $s_assertion"));') g.writeln(' exit(1);') g.writeln('}') } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 0f05196ef4..e445183622 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -354,10 +354,11 @@ pub fn (p mut Parser) stmt() ast.Stmt { } .key_assert { p.next() + assert_pos := p.tok.position() expr := p.expr(0) return ast.AssertStmt{ expr: expr - pos: p.tok.position() + pos: assert_pos } } .key_mut, .key_static { diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 75938068c8..12a1b57e62 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -724,6 +724,10 @@ pub fn (s mut Scanner) scan() token.Token { s.ignore_line() s.line_comment = s.text[start + 1..s.pos] comment := s.line_comment.trim_space() + s.pos-- + // fix line_nr, \n was read, and the comment is marked + // on the next line + s.line_nr-- if s.comments_mode == .parse_comments { // Find out if this comment is on its own line (for vfmt) mut is_separate_line_comment := true @@ -735,10 +739,6 @@ pub fn (s mut Scanner) scan() token.Token { if is_separate_line_comment { comment = '|' + comment } - s.pos-- - // fix line_nr, \n was read, and the comment is marked - // on the next line - s.line_nr-- return s.new_token(.comment, comment) } // s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"') diff --git a/vlib/v/scanner/scanner_test.v b/vlib/v/scanner/scanner_test.v index 73b596a29e..a94eee2a03 100644 --- a/vlib/v/scanner/scanner_test.v +++ b/vlib/v/scanner/scanner_test.v @@ -39,5 +39,5 @@ fn test_scan() { assert e == 120.0 assert 1.23e+10 == 1.23e10 assert 1.23e+10 == 1.23e0010 - assert -1.23e+10 == 1.23e0010 * -1.0 + assert (-1.23e+10) == (1.23e0010 * -1.0) }