parser: (var x X) receiver syntax

pull/4447/head
Alexander Medvednikov 2020-04-16 15:40:21 +02:00
parent 8760313ce5
commit 4b5acfd960
2 changed files with 35 additions and 34 deletions

View File

@ -9,7 +9,7 @@ import v.scanner
import v.token
import v.util
pub fn (p mut Parser) call_expr(is_c bool, is_js bool, mod string) ast.CallExpr {
pub fn (p mut Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr {
first_pos := p.tok.position()
tok := p.tok
name := p.check_name()
@ -123,7 +123,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
// }
// TODO: talk to alex, should mut be parsed with the type like this?
// or should it be a property of the arg, like this ptr/mut becomes indistinguishable
rec_type = p.parse_type()
rec_type = p.parse_type_with_mut(rec_mut)
if is_amp && rec_mut {
p.error('use `(f mut Foo)` or `(f &Foo)` instead of `(f mut &Foo)`')
}

View File

@ -1,10 +1,9 @@
module parser
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
import (
v.table
)
import v.table
pub fn (p mut Parser) parse_array_type() table.Type {
p.check(.lsbr)
@ -20,7 +19,7 @@ pub fn (p mut Parser) parse_array_type() table.Type {
// array
p.check(.rsbr)
elem_type := p.parse_type()
mut nr_dims := 1
var nr_dims := 1
for p.tok.kind == .lsbr {
p.check(.lsbr)
p.check(.rsbr)
@ -50,14 +49,13 @@ pub fn (p mut Parser) parse_map_type() table.Type {
pub fn (p mut Parser) parse_multi_return_type() table.Type {
p.check(.lpar)
mut mr_types := []table.Type
var mr_types := []table.Type
for {
mr_type := p.parse_type()
mr_types << mr_type
if p.tok.kind == .comma {
p.check(.comma)
}
else {
} else {
break
}
}
@ -71,8 +69,8 @@ pub fn (p mut Parser) parse_fn_type(name string) table.Type {
// p.warn('parse fn')
p.check(.key_fn)
line_nr := p.tok.line_nr
args,is_variadic := p.fn_args()
mut return_type := table.void_type
args, is_variadic := p.fn_args()
var return_type := table.void_type
if p.tok.line_nr == line_nr && p.tok.kind.is_start_of_type() {
return_type = p.parse_type()
}
@ -86,14 +84,22 @@ pub fn (p mut Parser) parse_fn_type(name string) table.Type {
return table.new_type(idx)
}
pub fn (p mut Parser) parse_type_with_mut(is_mut bool) table.Type {
typ := p.parse_type()
if is_mut {
return table.type_set_nr_muls(typ, 1)
}
return typ
}
pub fn (p mut Parser) parse_type() table.Type {
// optional
mut is_optional := false
var is_optional := false
if p.tok.kind == .question {
p.next()
is_optional = true
}
mut nr_muls := 0
var nr_muls := 0
if p.tok.kind == .key_mut {
nr_muls++
p.next()
@ -102,8 +108,7 @@ pub fn (p mut Parser) parse_type() table.Type {
for p.tok.kind in [.and, .amp] {
if p.tok.kind == .and {
nr_muls += 2
}
else {
} else {
nr_muls++
}
p.next()
@ -114,7 +119,7 @@ pub fn (p mut Parser) parse_type() table.Type {
p.next()
p.check(.dot)
}
mut typ := p.parse_any_type(is_c, is_js, nr_muls > 0)
var typ := p.parse_any_type(is_c, is_js, nr_muls > 0)
if is_optional {
typ = table.type_set(typ, .optional)
}
@ -124,16 +129,14 @@ pub fn (p mut Parser) parse_type() table.Type {
return typ
}
pub fn (p mut Parser) parse_any_type(is_c bool, is_js bool, is_ptr bool) table.Type {
mut name := p.tok.lit
pub fn (p mut Parser) parse_any_type(is_c, is_js, is_ptr bool) table.Type {
var name := p.tok.lit
if is_c {
name = 'C.$name'
}
else if is_js {
} else if is_js {
name = 'JS.$name'
}
// `module.Type`
else if p.peek_tok.kind == .dot {
} else if p.peek_tok.kind == .dot {
// `module.Type`
// /if !(p.tok.lit in p.table.imports) {
if !p.known_import(name) {
println(p.table.imports)
@ -143,26 +146,24 @@ pub fn (p mut Parser) parse_any_type(is_c bool, is_js bool, is_ptr bool) table.T
p.check(.dot)
// prefix with full module
name = '${p.imports[name]}.$p.tok.lit'
}
else if p.expr_mod != '' {
} else if p.expr_mod != '' {
name = p.expr_mod + '.' + name
}
// `Foo` in module `mod` means `mod.Foo`
else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) {
} else if !(p.mod in ['builtin', 'main']) && !(name in table.builtin_type_names) {
// `Foo` in module `mod` means `mod.Foo`
name = p.mod + '.' + name
}
// p.warn('get type $name')
match p.tok.kind {
// func
.key_fn {
// func
return p.parse_fn_type('')
}
// array
.lsbr {
// array
return p.parse_array_type()
}
// multiple return
.lpar {
// multiple return
if is_ptr {
p.error('parse_type: unexpected `&` before multiple returns')
}
@ -225,10 +226,10 @@ pub fn (p mut Parser) parse_any_type(is_c bool, is_js bool, is_ptr bool) table.T
'bool' {
return table.bool_type
}
// struct / enum / placeholder
else {
// struct / enum / placeholder
// struct / enum
mut idx := p.table.find_type_idx(name)
var idx := p.table.find_type_idx(name)
if idx > 0 {
return table.new_type(idx)
}
@ -237,7 +238,7 @@ pub fn (p mut Parser) parse_any_type(is_c bool, is_js bool, is_ptr bool) table.T
// println('NOT FOUND: $name - adding placeholder - $idx')
return table.new_type(idx)
}
}
}
}
}
}