From c4f6125a31957a1369e6024b1e14793058c4ae46 Mon Sep 17 00:00:00 2001 From: Joe Conigliaro Date: Thu, 19 Mar 2020 00:50:21 +1100 Subject: [PATCH] gen/checker: add errors for as cast & for in var --- vlib/v/ast/ast.v | 6 ++++-- vlib/v/checker/checker.v | 12 ++++++++++++ vlib/v/gen/cgen.v | 7 +++---- vlib/v/parser/parser.v | 9 ++++++--- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 8bf191a5f4..8f537c3b2e 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -377,8 +377,8 @@ pub struct ForStmt { pub: cond Expr stmts []Stmt - pos token.Position is_inf bool // `for {}` + pos token.Position } pub struct ForInStmt { @@ -400,12 +400,13 @@ pub: // inc Stmt // i++; inc Expr // i++; stmts []Stmt + pos token.Position } pub struct ReturnStmt { tok_kind token.Kind // or pos - pos token.Position results []Expr + pos token.Position } // #include etc @@ -435,6 +436,7 @@ pub struct AsCast { pub: expr Expr typ table.Type + pos token.Position mut: expr_type table.Type } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7b1270a1f6..215ef45a0b 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -618,6 +618,18 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { } ast.AsCast { it.expr_type = c.expr(it.expr) + expr_type_sym := c.table.get_type_symbol(it.expr_type) + type_sym := c.table.get_type_symbol(it.typ) + if expr_type_sym.kind == .sum_type { + info := expr_type_sym.info as table.SumType + if !it.typ in info.variants { + c.error('cannot cast `$expr_type_sym.name` to `$type_sym.name`', it.pos) + // c.error('only $info.variants can be casted to `$typ`', it.pos) + } + } + else { + c.error('cannot cast non sum type `$type_sym.name` using `as`', it.pos) + } return it.typ } ast.AssignExpr { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 9719874a9e..d7ec38f5a8 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -282,9 +282,12 @@ fn (g mut Gen) stmt(node ast.Stmt) { g.write('; $i < ') g.expr(it.high) g.writeln('; $i++) { ') + g.writeln('int $it.val_var = $i;') g.stmts(it.stmts) g.writeln('}') } + //TODO: + else {} } ast.ForStmt { g.write('while (') @@ -569,10 +572,6 @@ fn (g mut Gen) expr(node ast.Expr) { g.expr(it.expr) g.write('.obj') } - else { - g.write('/* as */ ($styp)') - g.expr(it.expr) - } } ast.AssignExpr { if ast.expr_is_blank_ident(it.left) { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index a1ac77fc2f..fd6ce9d9e0 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -827,11 +827,13 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr { node = p.index_expr(node) } else if p.tok.kind == .key_as { + pos := p.tok.position() p.next() typ = p.parse_type() node = ast.AsCast{ expr: node typ: typ + pos: pos } } // TODO: handle in later stages since this @@ -1036,11 +1038,11 @@ fn (p mut Parser) enum_val() ast.EnumVal { fn (p mut Parser) for_statement() ast.Stmt { p.check(.key_for) + pos := p.tok.position() p.open_scope() // defer { p.close_scope() } // Infinite loop if p.tok.kind == .lcbr { - pos := p.tok.position() stmts := p.parse_block() p.close_scope() return ast.ForStmt{ @@ -1092,6 +1094,7 @@ fn (p mut Parser) for_statement() ast.Stmt { init: init cond: cond inc: inc + pos: pos } } // `for i in vals`, `for i in start .. end` @@ -1135,12 +1138,12 @@ fn (p mut Parser) for_statement() ast.Stmt { p.close_scope() return ast.ForInStmt{ stmts: stmts - pos: p.tok.position() cond: cond key_var: key_var_name val_var: val_var_name high: high_expr is_range: is_range + pos: pos } } // `for cond {` @@ -1150,7 +1153,7 @@ fn (p mut Parser) for_statement() ast.Stmt { return ast.ForStmt{ cond: cond stmts: stmts - pos: p.tok.position() + pos: pos } }