diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 834e5a0d15..6fac905971 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -16,12 +16,13 @@ const ( ) pub struct Checker { - table &table.Table + table &table.Table mut: - file ast.File - nr_errors int - errors []string - expected_type table.Type + file ast.File + nr_errors int + errors []string + expected_type table.Type + fn_return_type table.Type // current function's return type } pub fn new_checker(table &table.Table) Checker { @@ -108,6 +109,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type if !found_field { c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos) } + c.expected_type = field.typ expr_type := c.expr(expr) expr_type_sym := c.table.get_type_symbol(expr_type) field_type_sym := c.table.get_type_symbol(field.typ) @@ -124,6 +126,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type { // println('checker: infix expr(op $infix_expr.op.str())') left_type := c.expr(infix_expr.left) + c.expected_type = left_type right_type := c.expr(infix_expr.right) if !c.table.check(right_type, left_type) { left := c.table.get_type_symbol(left_type) @@ -279,6 +282,7 @@ pub fn (c mut Checker) selector_expr(selector_expr ast.SelectorExpr) table.Type // TODO: non deferred pub fn (c mut Checker) return_stmt(return_stmt ast.Return) { mut got_types := []table.Type + c.expected_type = c.fn_return_type if return_stmt.exprs.len == 0 { return } @@ -367,6 +371,7 @@ fn (c mut Checker) stmt(node ast.Stmt) { // c.expected_type = table.void_type match mut node { ast.FnDecl { + c.fn_return_type = it.typ for stmt in it.stmts { c.stmt(stmt) } @@ -605,6 +610,7 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type { for i, block in node.blocks { if i < node.match_exprs.len { match_expr := node.match_exprs[i] + c.expected_type = node.typ c.expr(match_expr) } for stmt in block.stmts { @@ -738,10 +744,13 @@ pub fn (c mut Checker) index_expr(node ast.IndexExpr) table.Type { // If a short form is used, `expected_type` needs to be an enum // with this value. pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type { - // println('checker: enum: $node.enum_name') typ_idx := if node.enum_name == '' { c.expected_type } else { // c.table.find_type_idx(node.enum_name) } typ := c.table.get_type_symbol(table.Type(typ_idx)) + // println('checker: enum_val: $node.enum_name typeidx=$typ_idx tname=$typ.name') + if typ.kind != .enum_ { + c.error('not an enum', node.pos) + } // info := typ.info as table.Enum info := typ.enum_info() // rintln('checker: x = $info.x enum val $c.expected_type $typ.name') diff --git a/vlib/v/scanner/scanner_test.v b/vlib/v/scanner/scanner_test.v index 6c3f3c0b28..ce936ee22a 100644 --- a/vlib/v/scanner/scanner_test.v +++ b/vlib/v/scanner/scanner_test.v @@ -9,7 +9,7 @@ import ( fn test_scan() { text := 'println(2 + 3)' - mut scanner := new_scanner(text) + mut scanner := new_scanner(text, .skip_comments) mut token_kinds := []token.Kind for { tok := scanner.scan() @@ -25,24 +25,21 @@ fn test_scan() { assert token_kinds[3] == .plus assert token_kinds[4] == .number assert token_kinds[5] == .rpar - // test number costants input format - mut c := 0xa_0 + mut c := 0xa0 assert c == 0xa0 - c = 0b10_01 + c = 0b1001 assert c == 9 - c = 1_000_000 + c = 1000000 assert c == 1000000 - // test float conversion and reading - d := f64(23_000_000e-3) - assert int(d) == 23000 + d := f64(23000000e-3) + assert int(d) == 23000 mut e := f64(1.2E3) * f64(-1e-1) assert e == -120.0 e = f64(1.2E3) * f64(1e-1) 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 } -