v2: clean up IndexExpr type check

pull/3635/head^2
Alexander Medvednikov 2020-02-03 11:29:50 +01:00
parent e5f5117a7e
commit 6489b48c9c
3 changed files with 38 additions and 38 deletions

View File

@ -249,7 +249,7 @@ pub:
pos token.Position
left Expr
index Expr // [0], [start..end] etc
typ table.Type
// typ table.Type
}
pub struct IfExpr {

View File

@ -199,11 +199,9 @@ fn (c &Checker) stmt(node ast.Stmt) {
typ := c.expr(it.expr)
// it.typ = typ
// println('checker: var decl $typ.name it.typ=$it.typ.name $it.pos.line_nr')
/*
if typ.kind != .void {
it.typ = typ
}
*/
// if it.typ.kind == .unresolved {
// it.ti = typ
// println('unresolved var')
@ -313,14 +311,32 @@ pub fn (c &Checker) expr(node ast.Expr) table.Type {
pub fn (c &Checker) index_expr(node ast.IndexExpr) table.Type {
mut typ := c.expr(node.left)
if typ.name.starts_with('array_') {
elm_typ := typ.name[6..]
// TODO `typ = ... or ...`
x := c.table.find_type(elm_typ) or {
c.error(elm_typ, node.pos)
exit(0)
mut is_range := false // TODO is_range := node.index is ast.RangeExpr
match node.index {
ast.RangeExpr {
is_range = true
}
else {}
}
// TODO
// info := ti.info as table.Array
// ti = p.table.types[info.elem_type_idx]
if typ.name.starts_with('array_') {
if is_range {} // `x[start..end]` has the same type as `x`
else {
elm_typ := typ.name[6..]
// TODO `typ = ... or ...`
x := c.table.find_type(elm_typ) or {
c.error(elm_typ, node.pos)
exit(0)
}
typ = x
// Check index type
index_type := c.expr(node.index)
if index_type.kind != .int {
c.error('non-integer index (type `$index_type.name`)', node.pos)
}
}
typ = x
}
else {
typ = table.int_type

View File

@ -491,7 +491,7 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
node,typ = p.dot_expr(node, typ)
}
else if p.tok.kind == .lsbr {
node,typ = p.index_expr(node, typ)
node = p.index_expr(node) // , typ)
}
else if p.tok.kind.is_infix() {
node,typ = p.infix_expr(node)
@ -524,38 +524,20 @@ fn (p mut Parser) prefix_expr() (ast.Expr,table.Type) {
return expr,ti
}
fn (p mut Parser) index_expr(left ast.Expr, typ_ table.Type) (ast.Expr,table.Type) {
mut typ := typ_
// TODO
// info := ti.info as table.Array
// ti = p.table.types[info.elem_type_idx]
if typ.name.starts_with('array_') {
elm_typ := typ.name[6..]
// TODO `typ = ... or ...`
x := p.table.find_type(elm_typ) or {
p.error(elm_typ)
exit(0)
}
typ = x
}
else {
typ = table.int_type
}
// fn (p mut Parser) index_expr(left ast.Expr, typ_ table.Type) (ast.Expr,table.Type) {
fn (p mut Parser) index_expr(left ast.Expr) ast.Expr {
// mut typ := typ_
// println('index expr$p.tok.str() line=$p.tok.line_nr')
p.next() // [
// `numbers[..end]`
mut index_expr := ast.Expr{}
if p.tok.kind == .dotdot {
// `numbers[..end]`
index_expr = p.range_expr(left)
typ = typ_ // set the type back to array
// typ = typ_ // set the type back to array
}
else {
// println('start index expr')
mut index_type := table.Type{}
index_expr,index_type = p.expr(0)
if index_type.kind != .int {
p.error('non-integer index (type `$typ.name`)')
}
index_expr,_ = p.expr(0)
}
// println('end expr typ=$typ.name')
p.check(.rsbr)
@ -565,10 +547,12 @@ fn (p mut Parser) index_expr(left ast.Expr, typ_ table.Type) (ast.Expr,table.Typ
node = ast.IndexExpr{
left: left
index: index_expr
typ: typ
pos: p.tok.position()
// typ: typ
}
// return node
return node,typ
return node
// return node,typ
}
fn (p mut Parser) dot_expr(left ast.Expr, left_ti &table.Type) (ast.Expr,table.Type) {