1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: (var x X) receiver syntax

This commit is contained in:
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.token
import v.util 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() first_pos := p.tok.position()
tok := p.tok tok := p.tok
name := p.check_name() 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? // 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 // 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 { if is_amp && rec_mut {
p.error('use `(f mut Foo)` or `(f &Foo)` instead of `(f mut &Foo)`') p.error('use `(f mut Foo)` or `(f &Foo)` instead of `(f mut &Foo)`')
} }

View File

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