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:
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
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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
}
}