array type fix; method registration

pull/3358/head
Alexander Medvednikov 2020-01-07 13:10:05 +01:00
parent 6d30697d9b
commit d823d82207
5 changed files with 35 additions and 12 deletions

View File

@ -15,6 +15,13 @@ pub:
element_size int
}
/*
struct Foo {
a []string
b [][]string
}
*/
// Internal function, used by V (`nums := []int`)
fn new_array(mylen int, cap int, elm_size int) array {
cap_ := if cap == 0 { 1 } else { cap }

View File

@ -15,14 +15,14 @@ pub fn (p mut Parser) parse_array_ti(nr_muls int) types.TypeIdent {
return types.new_ti(._array_fixed, name, idx, nr_muls)
}
// array
p.check(.rsbr)
elem_ti := p.parse_ti()
mut nr_dims := 1
for p.tok.kind == .lsbr {
p.check(.lsbr)
p.next()
p.check(.rsbr)
nr_dims++
}
p.check(.rsbr)
idx,name := p.table.find_or_register_array(&elem_ti, nr_dims)
return types.new_ti(._array, name, idx, nr_muls)
}

View File

@ -10,7 +10,6 @@ import (
)
pub fn (p mut Parser) call_expr() (ast.CallExpr,types.TypeIdent) {
// println('got fn call')
tok := p.tok
fn_name := p.check_name()
p.check(.lpar)
@ -19,6 +18,7 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,types.TypeIdent) {
mut args := []ast.Expr
mut return_ti := types.void_ti
if f := p.table.find_fn(fn_name) {
// println('found fn $fn_name')
return_ti = f.return_ti
for i, arg in f.args {
e,ti := p.expr(0)
@ -81,8 +81,10 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
p.check(.key_fn)
// Receiver?
mut rec_name := ''
mut is_method := false
mut rec_ti := types.void_ti
if p.tok.kind == .lpar {
is_method = true
p.next()
rec_name = p.check_name()
if p.tok.kind == .key_mut {
@ -135,11 +137,13 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
ti = p.parse_ti()
p.return_ti = ti
}
p.table.register_fn(table.Fn{
name: name
args: args
return_ti: ti
})
if !is_method {
p.table.register_fn(table.Fn{
name: name
args: args
return_ti: ti
})
}
stmts := p.parse_block()
return ast.FnDecl{
name: name

View File

@ -168,6 +168,12 @@ pub fn (p mut Parser) top_stmt() ast.Stmt {
.key_struct {
return p.struct_decl()
}
.lsbr {
p.next()
p.check(.name)
p.check(.rsbr)
return ast.Module{}
}
else {
p.error('bad top level statement')
return ast.Module{} // silence C warning
@ -592,7 +598,7 @@ fn (p mut Parser) if_expr() (ast.Expr,types.TypeIdent) {
else_stmts: else_stmts
ti: ti
// left: left
}
p.inside_if = false
return node,ti
@ -755,7 +761,7 @@ fn (p mut Parser) return_stmt() ast.Return {
}
for i, exp_ti in expected_tis {
got_ti := got_tis[i]
if !types.check(exp_ti, got_ti) {
if !types.check(got_ti, exp_ti) {
p.error('cannot use `$got_ti.name` as type `$exp_ti.name` in return argument')
}
}
@ -791,7 +797,7 @@ fn (p mut Parser) var_decl() ast.VarDecl {
return ast.VarDecl{
name: name
expr: expr // p.expr(token.lowest_prec)
ti: ti
}
}

View File

@ -32,7 +32,7 @@ pub enum Kind {
_variadic
}
pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct |
pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct |
Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic
pub struct TypeIdent {
@ -92,6 +92,12 @@ pub fn (ti &TypeIdent) str() string {
}
pub fn check(got, expected &TypeIdent) bool {
if expected.kind == ._voidptr {
return true
}
if expected.name == 'array' {
return true
}
if got.idx != expected.idx {
return false
}