allow interface method with empty (void) return type

-> only look for type declaration if no new line has been
   while skipping whitespace
pull/951/head^2
marco 2019-07-03 21:53:25 +02:00 committed by Alexander Medvednikov
parent 7fdd94fcbb
commit 155e1fa961
3 changed files with 68 additions and 13 deletions

View File

@ -393,6 +393,25 @@ fn (p mut Parser) type_decl() {
p.table.register_type_with_parent(name, parent)
}
fn (p mut Parser) interface_method(field_name, receiver string) &Fn {
mut method := &Fn {
name: field_name
is_interface: true
is_method: true
receiver_typ: receiver
}
p.log('is interface. field=$field_name run=$p.run')
p.fn_args(mut method)
if p.scanner.has_gone_over_line_end() {
method.typ = 'void'
} else {
method.typ = p.get_type()// method return type
p.fspace()
p.fgenln('')
}
return method
}
// also unions and interfaces
fn (p mut Parser) struct_decl() {
// Attribute before type?
@ -525,18 +544,7 @@ fn (p mut Parser) struct_decl() {
// We are in an interface?
// `run() string` => run is a method, not a struct field
if is_interface {
mut interface_method := &Fn {
name: field_name
is_interface: true
is_method: true
receiver_typ: name
}
println('is interface. field=$field_name run=$p.run')
p.fn_args(mut interface_method)
p.fspace()
interface_method.typ = p.get_type()// method return type
typ.add_method(interface_method)
p.fgenln('')
typ.add_method(p.interface_method(field_name, name))
continue
}
// `pub` access mod

View File

@ -120,6 +120,20 @@ fn (s mut Scanner) ident_number() string {
return number
}
fn (s Scanner) has_gone_over_line_end() bool {
mut i := s.pos-1
for i >= 0 && !is_white(s.text[i]) {
i--
}
for i >= 0 && is_white(s.text[i]) {
if is_nl(s.text[i]) {
return true
}
i--
}
return false
}
fn (s mut Scanner) skip_whitespace() {
for s.pos < s.text.len && is_white(s.text[s.pos]) {
if is_nl(s.text[s.pos]) {
@ -148,7 +162,8 @@ fn (s mut Scanner) cao_change(operator string) {
s.text = s.text.substr(0, s.pos - operator.len) + ' = ' + s.get_var_name(s.pos - operator.len) + ' ' + operator + ' ' + s.text.substr(s.pos + 1, s.text.len)
}
fn (s mut Scanner) scan() ScanRes {
fn (s mut Scanner) scan()
ScanRes {
// if s.file_path == 'd.v' {
// println('\nscan()')
// }

View File

@ -0,0 +1,32 @@
struct Dog {
}
fn (d Dog) speak() {
println('dog.speak()')
}
fn (d Dog) name() string {
return 'old gray'
}
interface Speaker {
name() string
speak()
}
interface Speak2er {
speak()
name() string
}
fn perform_speak(s Speaker) bool {
s.speak()
return true
}
fn test_perform_speak() {
d := Dog{}
assert perform_speak(d)
}