v2: [] expr for known arrays; p.expected_type

pull/3722/head
Alexander Medvednikov 2020-02-12 17:39:35 +01:00
parent ab7a79cb90
commit 9d46fb9f90
3 changed files with 64 additions and 24 deletions

View File

@ -90,8 +90,9 @@ pub fn (p mut Parser) parse_type() table.Type {
if p.tok.kind == .question { if p.tok.kind == .question {
p.next() p.next()
} }
// `module.Type`
if p.peek_tok.kind == .dot { if p.peek_tok.kind == .dot {
///if !(p.tok.lit in p.table.imports) { // /if !(p.tok.lit in p.table.imports) {
if !p.table.known_import(p.tok.lit) { if !p.table.known_import(p.tok.lit) {
println(p.table.imports) println(p.table.imports)
p.error('unknown module `$p.tok.lit`') p.error('unknown module `$p.tok.lit`')

View File

@ -467,6 +467,53 @@ pub fn (p mut Parser) parse_ident(is_c bool) (ast.Ident,table.Type) {
return node,typ return node,typ
} }
fn (p mut Parser) struct_init() (ast.Expr,table.Type) {
mut node := ast.Expr{}
typ := p.parse_type()
// p.warn('struct init typ=$typ.name')
p.check(.lcbr)
mut field_names := []string
mut exprs := []ast.Expr
mut i := 0
sym := p.table.get_type_symbol(typ)
// TODO if sym.info is table.Struct
mut is_struct := false
match sym.info {
table.Struct {
is_struct = true
}
else {}
}
for p.tok.kind != .rcbr {
field_name := p.check_name()
field_names << field_name
// Set expected type for this field's expression
// p.warn('$sym.name field $field_name')
if is_struct {
info := sym.info as table.Struct
field := sym.find_field(field_name) or {
p.error(err)
continue
}
p.expected_type = field.typ
// p.warn('setting exp $field.typ')
}
//
p.check(.colon)
expr,_ := p.expr(0)
exprs << expr
i++
}
node = ast.StructInit{
typ: typ
exprs: exprs
fields: field_names
pos: p.tok.position()
}
p.check(.rcbr)
return node,typ
}
pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) { pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
mut node := ast.Expr{} mut node := ast.Expr{}
mut typ := table.void_type mut typ := table.void_type
@ -518,25 +565,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.Type) {
// struct init // struct init
else if p.peek_tok.kind == .lcbr && (p.tok.lit[0].is_capital() || is_c || p.tok.lit in ['array', 'string', 'ustring', 'mapnode', 'map']) && !p.tok.lit[p.tok.lit.len - 1].is_capital() { else if p.peek_tok.kind == .lcbr && (p.tok.lit[0].is_capital() || is_c || p.tok.lit in ['array', 'string', 'ustring', 'mapnode', 'map']) && !p.tok.lit[p.tok.lit.len - 1].is_capital() {
// || p.table.known_type(p.tok.lit)) { // || p.table.known_type(p.tok.lit)) {
typ = p.parse_type() return p.struct_init()
// p.warn('struct init typ=$typ.name')
p.check(.lcbr)
mut field_names := []string
mut exprs := []ast.Expr
for p.tok.kind != .rcbr {
field_name := p.check_name()
field_names << field_name
p.check(.colon)
expr,_ := p.expr(0)
exprs << expr
}
node = ast.StructInit{
typ: typ
exprs: exprs
fields: field_names
pos: p.tok.position()
}
p.check(.rcbr)
} }
else { else {
mut ident := ast.Ident{} mut ident := ast.Ident{}
@ -1027,17 +1056,24 @@ fn (p mut Parser) array_init() (ast.Expr,table.Type) {
mut node := ast.Expr{} mut node := ast.Expr{}
p.check(.lsbr) p.check(.lsbr)
// `[]` - empty array with an automatically deduced type // `[]` - empty array with an automatically deduced type
// p.warn('array_init() exp=$p.expected_type')
/* /*
if p.peek_tok.kind == .rsbr && p.expected_type.kind == .array { if p.expected_type != 0 {
sym := p.table.get_type_symbol(p.expected_type)
println(sym.name)
}
*/
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{ node = ast.ArrayInit{
// typ: array_type // typ: array_type
exprs: [] exprs: []
pos: p.tok.position() pos: p.tok.position()
} }
p.check(.rsbr)
return node,p.expected_type return node,p.expected_type
} }
*/
mut val_type := table.void_type mut val_type := table.void_type
mut exprs := []ast.Expr mut exprs := []ast.Expr
mut is_fixed := false mut is_fixed := false

View File

@ -77,7 +77,10 @@ pub fn new_scanner(text string) &Scanner {
fn (s &Scanner) scan_res(tok_kind token.Kind, lit string) token.Token { fn (s &Scanner) scan_res(tok_kind token.Kind, lit string) token.Token {
return token.Token{ return token.Token{
tok_kind,lit,s.line_nr + 1} kind: tok_kind
lit: lit
line_nr: s.line_nr + 1
}
} }
fn (s mut Scanner) ident_name() string { fn (s mut Scanner) ident_name() string {