v2: fix array init

pull/3919/head
Joe Conigliaro 2020-03-04 12:50:32 +11:00
parent bac6fc6ee2
commit d501ea0afb
4 changed files with 64 additions and 79 deletions

View File

@ -239,7 +239,7 @@ pub fn f64_to_str_l(f f64) string {
m_sgn_flag := false m_sgn_flag := false
mut sgn := 1 mut sgn := 1
mut b := [18+8]byte mut b := [26]byte
mut d_pos := 1 mut d_pos := 1
mut i := 0 mut i := 0
mut i1 := 0 mut i1 := 0

View File

@ -478,6 +478,7 @@ pub:
pos token.Position pos token.Position
exprs []Expr exprs []Expr
mut: mut:
elem_type table.Type
typ table.Type typ table.Type
} }

View File

@ -366,8 +366,16 @@ pub fn (c mut Checker) assign_stmt(assign_stmt ast.AssignStmt) {
pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
mut elem_type := table.void_type mut elem_type := table.void_type
// []string - was set in parser
if array_init.typ != table.void_type {
return array_init.typ
}
// a = [] // a = []
if array_init.exprs.len == 0 {} if array_init.exprs.len == 0 {
return c.expected_type
}
// [1,2,3]
if array_init.exprs.len > 0 && array_init.elem_type == table.void_type {
for i, expr in array_init.exprs { for i, expr in array_init.exprs {
c.expr(expr) c.expr(expr)
typ := c.expr(expr) typ := c.expr(expr)
@ -382,12 +390,21 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type {
c.error('expected array element with type `$elem_type_sym.name`', array_init.pos) c.error('expected array element with type `$elem_type_sym.name`', array_init.pos)
} }
} }
// only inits if know types like []string set the type in parser idx := c.table.find_or_register_array(elem_type, 1)
// as the rest could be result of expression, so do it here array_init.typ = table.new_type(idx)
if array_init.typ == 0 { }
is_fixed := false // [50]byte
fixed_size := 1 else if array_init.exprs.len == 1 && array_init.elem_type != table.void_type {
idx := if is_fixed { c.table.find_or_register_array_fixed(elem_type, fixed_size, 1) } else { c.table.find_or_register_array(elem_type, 1) } mut fixed_size := 1
match array_init.exprs[0] {
ast.IntegerLiteral {
fixed_size = it.val
}
else {
c.error('expecting `int` for fixed size', array_init.pos)
}
}
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size, 1)
array_type := table.new_type(idx) array_type := table.new_type(idx)
array_init.typ = array_type array_init.typ = array_type
} }

View File

@ -824,15 +824,17 @@ pub fn (p mut Parser) expr(precedence int) (ast.Expr,table.Type) {
else if p.tok.kind == .key_as { else if p.tok.kind == .key_as {
p.next() p.next()
typ = p.parse_type() typ = p.parse_type()
node = ast.AsCast { node = ast.AsCast{
typ: typ typ: typ
} }
} }
// TODO: handle in later stages since this
// will fudge left shift as it makes it right assoc
// `arr << 'a'` | `arr << 'a' + 'b'` // `arr << 'a'` | `arr << 'a' + 'b'`
else if p.tok.kind == .left_shift { else if p.tok.kind == .left_shift {
tok := p.tok tok := p.tok
p.next() p.next()
right,_ := p.expr(precedence-1) right,_ := p.expr(precedence - 1)
node = ast.InfixExpr{ node = ast.InfixExpr{
left: node left: node
right: right right: right
@ -1280,46 +1282,22 @@ fn (p mut Parser) string_expr() (ast.Expr,table.Type) {
fn (p mut Parser) array_init() ast.ArrayInit { fn (p mut Parser) array_init() ast.ArrayInit {
p.check(.lsbr) p.check(.lsbr)
// `[]` - empty array with an automatically deduced type
// p.warn('array_init() exp=$p.expected_type') // p.warn('array_init() exp=$p.expected_type')
/* mut array_type := table.void_type
if p.expected_type != 0 { mut elem_type := table.void_type
sym := p.table.get_type_symbol(p.expected_type)
println(sym.name)
}
*/
/* TODO: joe
if p.tok.kind == .rsbr && int(p.expected_type) != 0 && p.table.get_type_symbol(p.expected_type).kind == .array {
// p.warn('[] expr')
node = ast.ArrayInit{
// typ: array_type
exprs: []
pos: p.tok.position()
}
p.check(.rsbr)
return node,p.expected_type
}
*/
mut array_type := table.Type(0)
mut exprs := []ast.Expr mut exprs := []ast.Expr
// mut is_fixed := false
// mut fixed_size := 0
if p.tok.kind == .rsbr { if p.tok.kind == .rsbr {
// []typ => `[]` and `typ` must be on the same line // []typ => `[]` and `typ` must be on the same line
line_nr := p.tok.line_nr line_nr := p.tok.line_nr
p.check(.rsbr) p.check(.rsbr)
// []string // []string
if p.tok.kind == .name && p.tok.line_nr == line_nr { if p.tok.kind == .name && p.tok.line_nr == line_nr {
val_type := p.parse_type() elem_type = p.parse_type()
// this is set here becasue its a known type, others could be the // this is set here becasue its a known type, others could be the
// result of expr so we do those in checker // result of expr so we do those in checker
idx := p.table.find_or_register_array(val_type, 1) idx := p.table.find_or_register_array(elem_type, 1)
array_type = table.new_type(idx) array_type = table.new_type(idx)
} }
// []
else {}
// TODO ?
} }
else { else {
// [1,2,3] // [1,2,3]
@ -1330,24 +1308,13 @@ fn (p mut Parser) array_init() ast.ArrayInit {
p.check(.comma) p.check(.comma)
} }
} }
// line_nr := p.tok.line_nr line_nr := p.tok.line_nr
p.check(.rsbr) p.check(.rsbr)
// Fixed size array? (`[100]byte`) // [100]byte
// NOTE: this should be hanled in parse_type() ?
/*
if exprs.len == 1 && p.tok.kind == .name && p.tok.line_nr == line_nr { if exprs.len == 1 && p.tok.kind == .name && p.tok.line_nr == line_nr {
is_fixed = true elem_type = p.parse_type()
val_type = p.parse_type() // p.warn('fixed size array')
match exprs[0] {
ast.IntegerLiteral {
fixed_size = it.val
} }
else {}
}
p.warn('fixed size array')
}
*/
} }
// ! // !
if p.tok.kind == .not { if p.tok.kind == .not {
@ -1356,9 +1323,8 @@ fn (p mut Parser) array_init() ast.ArrayInit {
if p.tok.kind == .not { if p.tok.kind == .not {
p.next() p.next()
} }
// idx := if is_fixed { p.table.find_or_register_array_fixed(val_type, fixed_size, 1) } else { p.table.find_or_register_array(val_type, 1) }
// array_type := table.new_type(idx)
return ast.ArrayInit{ return ast.ArrayInit{
elem_type: elem_type
typ: array_type typ: array_type
exprs: exprs exprs: exprs
pos: p.tok.position() pos: p.tok.position()
@ -1799,6 +1765,7 @@ fn (p mut Parser) match_expr() ast.Expr {
} }
} }
*/ */
p.close_scope() p.close_scope()
if p.tok.kind == .rcbr { if p.tok.kind == .rcbr {
break break