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) {
|
||||
//println('gen array str "$typ.name"')
|
||||
p.table.add_method(typ.name, Fn{
|
||||
name: 'str',
|
||||
p.add_method(typ.name, Fn{
|
||||
name: 'str'
|
||||
typ: 'string'
|
||||
args: [Var{typ: typ.name, is_arg:true}]
|
||||
is_method: true
|
||||
is_public: true
|
||||
receiver_typ: typ.name
|
||||
})
|
||||
/*
|
||||
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_type := typ.name.right(6)
|
||||
elm_type2 := p.table.find_type(elm_type)
|
||||
if p.typ_to_fmt(elm_type, 0) == '' &&
|
||||
!p.table.type_has_method(elm_type2, 'str') {
|
||||
p.error('cant print ${elm_type}[], unhandled print of ${elm_type}')
|
||||
}
|
||||
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_write(&sb, tos2("[")) ;
|
||||
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.add_method(receiver_t.name, f)
|
||||
p.add_method(receiver_t.name, f)
|
||||
}
|
||||
else {
|
||||
// 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.genln('$typ $name = *($typ*) $tmp . data;')
|
||||
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
|
||||
return typ
|
||||
|
@ -150,7 +150,7 @@ fn (table mut Table) fn_gen_name(f &Fn) string {
|
|||
name = name.replace('-', 'minus')
|
||||
}
|
||||
// Avoid name conflicts (with things like abs(), print() etc).
|
||||
// Generate b_abs(), b_print()
|
||||
// Generate v_abs(), v_print()
|
||||
// TODO duplicate functionality
|
||||
if f.mod == 'builtin' && f.name in CReserved {
|
||||
return 'v_$name'
|
||||
|
|
|
@ -626,7 +626,7 @@ fn (p mut Parser) struct_decl() {
|
|||
if is_interface {
|
||||
f := p.interface_method(field_name, name)
|
||||
if p.first_pass() {
|
||||
p.table.add_method(typ.name, f)
|
||||
p.add_method(typ.name, f)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
@ -1771,7 +1771,7 @@ fn (p mut Parser) dot(str_typ string, method_ph int) string {
|
|||
//println('ORM dot $str_typ')
|
||||
//}
|
||||
p.check(.dot)
|
||||
typ := p.find_type(str_typ)
|
||||
mut typ := p.find_type(str_typ)
|
||||
if typ.name.len == 0 {
|
||||
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
|
||||
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') {
|
||||
//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.name.starts_with('Option_') {
|
||||
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('fields:')
|
||||
|
@ -1850,7 +1850,10 @@ struct $f.parent_fn {
|
|||
return field.typ
|
||||
}
|
||||
// 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)
|
||||
// Methods returning `array` should return `array_string`
|
||||
if method.typ == 'array' && typ.name.starts_with('array_') {
|
||||
|
@ -3543,7 +3546,7 @@ fn (p mut Parser) go_statement() {
|
|||
p.next()
|
||||
p.check(.dot)
|
||||
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)
|
||||
}
|
||||
// Normal function
|
||||
|
|
|
@ -438,29 +438,38 @@ fn (table &Table) find_field(typ &Type, name string) ?Var {
|
|||
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 == '' {
|
||||
print_backtrace()
|
||||
cerror('add_method: empty type')
|
||||
}
|
||||
// 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
|
||||
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 {
|
||||
method := t.find_method(name)
|
||||
return (method.name != '')
|
||||
_ := t.find_method(name) or { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
fn (table &Table) type_has_method(typ &Type, name string) bool {
|
||||
method := table.find_method(typ, name)
|
||||
return (method.name != '')
|
||||
_ := table.find_method(typ, name) or { return false }
|
||||
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]
|
||||
for method in t.methods {
|
||||
if method.name == name {
|
||||
|
@ -469,12 +478,17 @@ fn (table &Table) find_method(typ &Type, name string) Fn {
|
|||
}
|
||||
if 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 Fn{}
|
||||
}
|
||||
return none
|
||||
}
|
||||
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')
|
||||
for method in t.methods {
|
||||
// println('method=$method.name')
|
||||
|
@ -482,9 +496,7 @@ fn (t &Type) find_method(name string) Fn {
|
|||
return method
|
||||
}
|
||||
}
|
||||
//println('ret Fn{}')
|
||||
return Fn{}
|
||||
//return none
|
||||
return none
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -512,6 +524,7 @@ fn (t &Table) find_type(name_ string) Type {
|
|||
name = name.left(name.len - 1)
|
||||
}
|
||||
if !(name in t.typesmap) {
|
||||
//println('ret Type')
|
||||
return Type{}
|
||||
}
|
||||
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 {
|
||||
mut got := got_
|
||||
mut expected := expected_
|
||||
p.log('check types got="$got" exp="$expected" ')
|
||||
//p.log('check types got="$got" exp="$expected" ')
|
||||
if p.pref.translated {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ fn test_array_str() {
|
|||
println(f)
|
||||
//s := f.str()
|
||||
//println(s)
|
||||
n := [i64(1), 2, 3]
|
||||
n := [1, 2, 3]
|
||||
assert n.str() == '[1, 2, 3]'
|
||||
println(n) // make sure the array is printable
|
||||
n2 := [4,5,6]
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
+ fix non-ascii rendering in gg (ä, å, etc)
|
||||
- cache all tokens once
|
||||
- enable vfmt
|
||||
- bring back vdoc and regenerate all module docs
|
||||
- optimize the parser (reduce map lookups)
|
||||
- cache vlib (right now it's re-compiled every time)
|
||||
- fix openssl on older linux distros
|
||||
|
@ -31,4 +32,6 @@
|
|||
+ o(log n) type lookup
|
||||
- prebuilt binaries for all platforms
|
||||
- fix interfaces
|
||||
- `none` keyword for optionals
|
||||
- table: migrate all find*** functions to optionals
|
||||
|
||||
|
|
Loading…
Reference in New Issue