table: use optional in find_method()
parent
059cb9cb74
commit
13e4c79f58
|
@ -224,30 +224,22 @@ fn (p mut Parser) comptime_method_call(typ Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) gen_array_str(typ Type) {
|
fn (p mut Parser) gen_array_str(typ Type) {
|
||||||
//println('gen array str "$typ.name"')
|
p.add_method(typ.name, Fn{
|
||||||
p.table.add_method(typ.name, Fn{
|
name: 'str'
|
||||||
name: 'str',
|
|
||||||
typ: 'string'
|
typ: 'string'
|
||||||
args: [Var{typ: typ.name, is_arg:true}]
|
args: [Var{typ: typ.name, is_arg:true}]
|
||||||
is_method: true
|
is_method: true
|
||||||
is_public: true
|
is_public: true
|
||||||
receiver_typ: typ.name
|
receiver_typ: typ.name
|
||||||
})
|
})
|
||||||
/*
|
elm_type := typ.name.right(6)
|
||||||
tt := p.table.find_type(typ.name)
|
|
||||||
for m in tt.methods {
|
|
||||||
println(m.name + ' ' + m.typ)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
t := typ.name
|
|
||||||
elm_type := t.right(6)
|
|
||||||
elm_type2 := p.table.find_type(elm_type)
|
elm_type2 := p.table.find_type(elm_type)
|
||||||
if p.typ_to_fmt(elm_type, 0) == '' &&
|
if p.typ_to_fmt(elm_type, 0) == '' &&
|
||||||
!p.table.type_has_method(elm_type2, 'str') {
|
!p.table.type_has_method(elm_type2, 'str') {
|
||||||
p.error('cant print ${elm_type}[], unhandled print of ${elm_type}')
|
p.error('cant print ${elm_type}[], unhandled print of ${elm_type}')
|
||||||
}
|
}
|
||||||
p.cgen.fns << '
|
p.cgen.fns << '
|
||||||
string ${t}_str($t a) {
|
string ${typ.name}_str($typ.name a) {
|
||||||
strings__Builder sb = strings__new_builder(a.len * 3);
|
strings__Builder sb = strings__new_builder(a.len * 3);
|
||||||
strings__Builder_write(&sb, tos2("[")) ;
|
strings__Builder_write(&sb, tos2("[")) ;
|
||||||
for (int i = 0; i < a.len; i++) {
|
for (int i = 0; i < a.len; i++) {
|
||||||
|
|
|
@ -368,7 +368,7 @@ fn (p mut Parser) fn_decl() {
|
||||||
}
|
}
|
||||||
p.table.register_type2(receiver_t)
|
p.table.register_type2(receiver_t)
|
||||||
}
|
}
|
||||||
p.table.add_method(receiver_t.name, f)
|
p.add_method(receiver_t.name, f)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// println('register_fn typ=$typ isg=$is_generic')
|
// println('register_fn typ=$typ isg=$is_generic')
|
||||||
|
|
|
@ -37,7 +37,7 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
|
||||||
p.statements()
|
p.statements()
|
||||||
p.genln('$typ $name = *($typ*) $tmp . data;')
|
p.genln('$typ $name = *($typ*) $tmp . data;')
|
||||||
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
|
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
|
||||||
p.error('`or` block must return/continue/break/panic')
|
p.error('`or` block must return/exit/continue/break/panic')
|
||||||
}
|
}
|
||||||
p.returns = false
|
p.returns = false
|
||||||
return typ
|
return typ
|
||||||
|
@ -150,7 +150,7 @@ fn (table mut Table) fn_gen_name(f &Fn) string {
|
||||||
name = name.replace('-', 'minus')
|
name = name.replace('-', 'minus')
|
||||||
}
|
}
|
||||||
// Avoid name conflicts (with things like abs(), print() etc).
|
// Avoid name conflicts (with things like abs(), print() etc).
|
||||||
// Generate b_abs(), b_print()
|
// Generate v_abs(), v_print()
|
||||||
// TODO duplicate functionality
|
// TODO duplicate functionality
|
||||||
if f.mod == 'builtin' && f.name in CReserved {
|
if f.mod == 'builtin' && f.name in CReserved {
|
||||||
return 'v_$name'
|
return 'v_$name'
|
||||||
|
|
|
@ -626,7 +626,7 @@ fn (p mut Parser) struct_decl() {
|
||||||
if is_interface {
|
if is_interface {
|
||||||
f := p.interface_method(field_name, name)
|
f := p.interface_method(field_name, name)
|
||||||
if p.first_pass() {
|
if p.first_pass() {
|
||||||
p.table.add_method(typ.name, f)
|
p.add_method(typ.name, f)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1771,7 +1771,7 @@ fn (p mut Parser) dot(str_typ string, method_ph int) string {
|
||||||
//println('ORM dot $str_typ')
|
//println('ORM dot $str_typ')
|
||||||
//}
|
//}
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
typ := p.find_type(str_typ)
|
mut typ := p.find_type(str_typ)
|
||||||
if typ.name.len == 0 {
|
if typ.name.len == 0 {
|
||||||
p.error('dot(): cannot find type `$str_typ`')
|
p.error('dot(): cannot find type `$str_typ`')
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1781,7 @@ fn (p mut Parser) dot(str_typ string, method_ph int) string {
|
||||||
}
|
}
|
||||||
field_name := p.lit
|
field_name := p.lit
|
||||||
p.fgen(field_name)
|
p.fgen(field_name)
|
||||||
p.log('dot() field_name=$field_name typ=$str_typ')
|
//p.log('dot() field_name=$field_name typ=$str_typ')
|
||||||
//if p.fileis('main.v') {
|
//if p.fileis('main.v') {
|
||||||
//println('dot() field_name=$field_name typ=$str_typ prev_tok=${prev_tok.str()}')
|
//println('dot() field_name=$field_name typ=$str_typ prev_tok=${prev_tok.str()}')
|
||||||
//}
|
//}
|
||||||
|
@ -1795,7 +1795,7 @@ fn (p mut Parser) dot(str_typ string, method_ph int) string {
|
||||||
if !typ.is_c && !p.is_c_fn_call && !has_field && !has_method && !p.first_pass() {
|
if !typ.is_c && !p.is_c_fn_call && !has_field && !has_method && !p.first_pass() {
|
||||||
if typ.name.starts_with('Option_') {
|
if typ.name.starts_with('Option_') {
|
||||||
opt_type := typ.name.right(7)
|
opt_type := typ.name.right(7)
|
||||||
p.error('unhandled option type: $opt_type?')
|
p.error('unhandled option type: `?$opt_type`')
|
||||||
}
|
}
|
||||||
//println('error in dot():')
|
//println('error in dot():')
|
||||||
//println('fields:')
|
//println('fields:')
|
||||||
|
@ -1850,7 +1850,10 @@ struct $f.parent_fn {
|
||||||
return field.typ
|
return field.typ
|
||||||
}
|
}
|
||||||
// method
|
// method
|
||||||
method := p.table.find_method(typ, field_name)
|
method := p.table.find_method(typ, field_name) or {
|
||||||
|
p.error('could not find method `$field_name`') // should never happen
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
p.fn_call(method, method_ph, '', str_typ)
|
p.fn_call(method, method_ph, '', str_typ)
|
||||||
// Methods returning `array` should return `array_string`
|
// Methods returning `array` should return `array_string`
|
||||||
if method.typ == 'array' && typ.name.starts_with('array_') {
|
if method.typ == 'array' && typ.name.starts_with('array_') {
|
||||||
|
@ -3543,7 +3546,7 @@ fn (p mut Parser) go_statement() {
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
typ := p.table.find_type(v.typ)
|
typ := p.table.find_type(v.typ)
|
||||||
method := p.table.find_method(typ, p.lit)
|
method := p.table.find_method(typ, p.lit) or { panic('go method') }
|
||||||
p.async_fn_call(method, 0, var_name, v.typ)
|
p.async_fn_call(method, 0, var_name, v.typ)
|
||||||
}
|
}
|
||||||
// Normal function
|
// Normal function
|
||||||
|
|
|
@ -438,29 +438,38 @@ fn (table &Table) find_field(typ &Type, name string) ?Var {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (table mut Table) add_method(type_name string, f Fn) {
|
fn (p mut Parser) add_method(type_name string, f Fn) {
|
||||||
|
if !p.first_pass() && f.name != 'str' {
|
||||||
|
return
|
||||||
|
}
|
||||||
if type_name == '' {
|
if type_name == '' {
|
||||||
print_backtrace()
|
print_backtrace()
|
||||||
cerror('add_method: empty type')
|
cerror('add_method: empty type')
|
||||||
}
|
}
|
||||||
// TODO table.typesmap[type_name].methods << f
|
// TODO table.typesmap[type_name].methods << f
|
||||||
mut t := table.typesmap[type_name]
|
mut t := p.table.typesmap[type_name]
|
||||||
|
if type_name == 'str' {
|
||||||
|
println(t.methods.len)
|
||||||
|
}
|
||||||
|
|
||||||
t.methods << f
|
t.methods << f
|
||||||
table.typesmap[type_name] = t
|
if type_name == 'str' {
|
||||||
|
println(t.methods.len)
|
||||||
|
}
|
||||||
|
p.table.typesmap[type_name] = t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t &Type) has_method(name string) bool {
|
fn (t &Type) has_method(name string) bool {
|
||||||
method := t.find_method(name)
|
_ := t.find_method(name) or { return false }
|
||||||
return (method.name != '')
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (table &Table) type_has_method(typ &Type, name string) bool {
|
fn (table &Table) type_has_method(typ &Type, name string) bool {
|
||||||
method := table.find_method(typ, name)
|
_ := table.find_method(typ, name) or { return false }
|
||||||
return (method.name != '')
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use `?Fn`
|
fn (table &Table) find_method(typ &Type, name string) ?Fn {
|
||||||
fn (table &Table) find_method(typ &Type, name string) Fn {
|
|
||||||
t := table.typesmap[typ.name]
|
t := table.typesmap[typ.name]
|
||||||
for method in t.methods {
|
for method in t.methods {
|
||||||
if method.name == name {
|
if method.name == name {
|
||||||
|
@ -469,12 +478,17 @@ fn (table &Table) find_method(typ &Type, name string) Fn {
|
||||||
}
|
}
|
||||||
if typ.parent != '' {
|
if typ.parent != '' {
|
||||||
parent := table.find_type(typ.parent)
|
parent := table.find_type(typ.parent)
|
||||||
return parent.find_method(name)
|
for method in parent.methods {
|
||||||
|
if method.name == name {
|
||||||
|
return method
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return none
|
||||||
}
|
}
|
||||||
return Fn{}
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (t &Type) find_method(name string) Fn {
|
fn (t &Type) find_method(name string) ?Fn {
|
||||||
// println('$t.name find_method($name) methods.len=$t.methods.len')
|
// println('$t.name find_method($name) methods.len=$t.methods.len')
|
||||||
for method in t.methods {
|
for method in t.methods {
|
||||||
// println('method=$method.name')
|
// println('method=$method.name')
|
||||||
|
@ -482,9 +496,7 @@ fn (t &Type) find_method(name string) Fn {
|
||||||
return method
|
return method
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//println('ret Fn{}')
|
return none
|
||||||
return Fn{}
|
|
||||||
//return none
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -512,6 +524,7 @@ fn (t &Table) find_type(name_ string) Type {
|
||||||
name = name.left(name.len - 1)
|
name = name.left(name.len - 1)
|
||||||
}
|
}
|
||||||
if !(name in t.typesmap) {
|
if !(name in t.typesmap) {
|
||||||
|
//println('ret Type')
|
||||||
return Type{}
|
return Type{}
|
||||||
}
|
}
|
||||||
return t.typesmap[name]
|
return t.typesmap[name]
|
||||||
|
@ -520,7 +533,7 @@ fn (t &Table) find_type(name_ string) Type {
|
||||||
fn (p mut Parser) _check_types(got_, expected_ string, throw bool) bool {
|
fn (p mut Parser) _check_types(got_, expected_ string, throw bool) bool {
|
||||||
mut got := got_
|
mut got := got_
|
||||||
mut expected := expected_
|
mut expected := expected_
|
||||||
p.log('check types got="$got" exp="$expected" ')
|
//p.log('check types got="$got" exp="$expected" ')
|
||||||
if p.pref.translated {
|
if p.pref.translated {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ fn test_array_str() {
|
||||||
println(f)
|
println(f)
|
||||||
//s := f.str()
|
//s := f.str()
|
||||||
//println(s)
|
//println(s)
|
||||||
n := [i64(1), 2, 3]
|
n := [1, 2, 3]
|
||||||
assert n.str() == '[1, 2, 3]'
|
assert n.str() == '[1, 2, 3]'
|
||||||
println(n) // make sure the array is printable
|
println(n) // make sure the array is printable
|
||||||
n2 := [4,5,6]
|
n2 := [4,5,6]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
+ fix non-ascii rendering in gg (ä, å, etc)
|
+ fix non-ascii rendering in gg (ä, å, etc)
|
||||||
- cache all tokens once
|
- cache all tokens once
|
||||||
- enable vfmt
|
- enable vfmt
|
||||||
|
- bring back vdoc and regenerate all module docs
|
||||||
- optimize the parser (reduce map lookups)
|
- optimize the parser (reduce map lookups)
|
||||||
- cache vlib (right now it's re-compiled every time)
|
- cache vlib (right now it's re-compiled every time)
|
||||||
- fix openssl on older linux distros
|
- fix openssl on older linux distros
|
||||||
|
@ -31,4 +32,6 @@
|
||||||
+ o(log n) type lookup
|
+ o(log n) type lookup
|
||||||
- prebuilt binaries for all platforms
|
- prebuilt binaries for all platforms
|
||||||
- fix interfaces
|
- fix interfaces
|
||||||
|
- `none` keyword for optionals
|
||||||
|
- table: migrate all find*** functions to optionals
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue