gen/checker: add errors for as cast & for in var

pull/4057/head
Joe Conigliaro 2020-03-19 00:50:21 +11:00
parent 96af21ff68
commit c4f6125a31
4 changed files with 25 additions and 9 deletions

View File

@ -377,8 +377,8 @@ pub struct ForStmt {
pub: pub:
cond Expr cond Expr
stmts []Stmt stmts []Stmt
pos token.Position
is_inf bool // `for {}` is_inf bool // `for {}`
pos token.Position
} }
pub struct ForInStmt { pub struct ForInStmt {
@ -400,12 +400,13 @@ pub:
// inc Stmt // i++; // inc Stmt // i++;
inc Expr // i++; inc Expr // i++;
stmts []Stmt stmts []Stmt
pos token.Position
} }
pub struct ReturnStmt { pub struct ReturnStmt {
tok_kind token.Kind // or pos tok_kind token.Kind // or pos
pos token.Position
results []Expr results []Expr
pos token.Position
} }
// #include etc // #include etc
@ -435,6 +436,7 @@ pub struct AsCast {
pub: pub:
expr Expr expr Expr
typ table.Type typ table.Type
pos token.Position
mut: mut:
expr_type table.Type expr_type table.Type
} }

View File

@ -618,6 +618,18 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type {
} }
ast.AsCast { ast.AsCast {
it.expr_type = c.expr(it.expr) 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 return it.typ
} }
ast.AssignExpr { ast.AssignExpr {

View File

@ -282,9 +282,12 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.write('; $i < ') g.write('; $i < ')
g.expr(it.high) g.expr(it.high)
g.writeln('; $i++) { ') g.writeln('; $i++) { ')
g.writeln('int $it.val_var = $i;')
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} }
//TODO:
else {}
} }
ast.ForStmt { ast.ForStmt {
g.write('while (') g.write('while (')
@ -569,10 +572,6 @@ fn (g mut Gen) expr(node ast.Expr) {
g.expr(it.expr) g.expr(it.expr)
g.write('.obj') g.write('.obj')
} }
else {
g.write('/* as */ ($styp)')
g.expr(it.expr)
}
} }
ast.AssignExpr { ast.AssignExpr {
if ast.expr_is_blank_ident(it.left) { if ast.expr_is_blank_ident(it.left) {

View File

@ -827,11 +827,13 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
node = p.index_expr(node) node = p.index_expr(node)
} }
else if p.tok.kind == .key_as { else if p.tok.kind == .key_as {
pos := p.tok.position()
p.next() p.next()
typ = p.parse_type() typ = p.parse_type()
node = ast.AsCast{ node = ast.AsCast{
expr: node expr: node
typ: typ typ: typ
pos: pos
} }
} }
// TODO: handle in later stages since this // 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 { fn (p mut Parser) for_statement() ast.Stmt {
p.check(.key_for) p.check(.key_for)
pos := p.tok.position()
p.open_scope() p.open_scope()
// defer { p.close_scope() } // defer { p.close_scope() }
// Infinite loop // Infinite loop
if p.tok.kind == .lcbr { if p.tok.kind == .lcbr {
pos := p.tok.position()
stmts := p.parse_block() stmts := p.parse_block()
p.close_scope() p.close_scope()
return ast.ForStmt{ return ast.ForStmt{
@ -1092,6 +1094,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
init: init init: init
cond: cond cond: cond
inc: inc inc: inc
pos: pos
} }
} }
// `for i in vals`, `for i in start .. end` // `for i in vals`, `for i in start .. end`
@ -1135,12 +1138,12 @@ fn (p mut Parser) for_statement() ast.Stmt {
p.close_scope() p.close_scope()
return ast.ForInStmt{ return ast.ForInStmt{
stmts: stmts stmts: stmts
pos: p.tok.position()
cond: cond cond: cond
key_var: key_var_name key_var: key_var_name
val_var: val_var_name val_var: val_var_name
high: high_expr high: high_expr
is_range: is_range is_range: is_range
pos: pos
} }
} }
// `for cond {` // `for cond {`
@ -1150,7 +1153,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
return ast.ForStmt{ return ast.ForStmt{
cond: cond cond: cond
stmts: stmts stmts: stmts
pos: p.tok.position() pos: pos
} }
} }