interfaces: preparatory fixes

pull/4587/head
Alexander Medvednikov 2020-04-25 08:00:28 +02:00
parent 5600fd8613
commit f1f9e423c3
7 changed files with 109 additions and 49 deletions

View File

@ -18,6 +18,7 @@ const (
'vlib/v/tests/pointers_test.v', 'vlib/v/tests/pointers_test.v',
'vlib/v/tests/string_interpolation_variadic_test.v', 'vlib/v/tests/string_interpolation_variadic_test.v',
'vlib/v/tests/type_test.v', 'vlib/v/tests/type_test.v',
'vlib/v/tests/interface_test.v',
'vlib/v/tests/valgrind/valgrind_test.v', // ubuntu-musl only 'vlib/v/tests/valgrind/valgrind_test.v', // ubuntu-musl only
'vlib/v/tests/pointers_str_test.v', 'vlib/v/tests/pointers_str_test.v',
'vlib/net/http/cookie_test.v', 'vlib/net/http/cookie_test.v',

View File

@ -153,11 +153,11 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
} }
// //
g.finish() g.finish()
return g.hashes() + g.comptime_defines.str() + '\n// V typedefs:\n' + g.typedefs.str() + '\n// V typedefs2:\n' + g.typedefs2.str() + return g.hashes() + g.comptime_defines.str() + '\n// V typedefs:\n' + g.typedefs.str() +
'\n// V cheaders:\n' + g.cheaders.str() + '\n// V includes:\n' + g.includes.str() + '\n// V definitions:\n' + '\n// V typedefs2:\n' + g.typedefs2.str() + '\n// V cheaders:\n' + g.cheaders.str() + '\n// V includes:\n' +
g.definitions.str() + g.interface_table() + '\n// V gowrappers:\n' + g.gowrappers.str() + '\n// V stringliterals:\n' + g.includes.str() + '\n// V definitions:\n' + g.definitions.str() + g.interface_table() + '\n// V gowrappers:\n' +
g.stringliterals.str() + '\n// V auto str functions:\n' + g.auto_str_funcs.str() + '\n// V out\n' + g.gowrappers.str() + '\n// V stringliterals:\n' + g.stringliterals.str() + '\n// V auto str functions:\n' +
g.out.str() + '\n// THE END.' g.auto_str_funcs.str() + '\n// V out\n' + g.out.str() + '\n// THE END.'
} }
pub fn (g Gen) hashes() string { pub fn (g Gen) hashes() string {
@ -189,7 +189,6 @@ pub fn (mut g Gen) init() {
if g.pref.build_mode != .build_module { if g.pref.build_mode != .build_module {
g.stringliterals.writeln('void vinit_string_literals(){') g.stringliterals.writeln('void vinit_string_literals(){')
} }
if g.pref.compile_defines_all.len > 0 { if g.pref.compile_defines_all.len > 0 {
g.comptime_defines.writeln('// V compile time defines by -d or -define flags:') g.comptime_defines.writeln('// V compile time defines by -d or -define flags:')
g.comptime_defines.writeln('// All custom defines : ' + g.pref.compile_defines_all.join(',')) g.comptime_defines.writeln('// All custom defines : ' + g.pref.compile_defines_all.join(','))
@ -2313,7 +2312,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('%"PRId64"') g.write('%"PRId64"')
} else if node.expr_types[i] == table.u64_type { } else if node.expr_types[i] == table.u64_type {
g.write('%"PRIu64"') g.write('%"PRIu64"')
} else if g.typ( node.expr_types[i] ).starts_with('Option') { } else if g.typ(node.expr_types[i]).starts_with('Option') {
g.write('%.*s') g.write('%.*s')
} else { } else {
g.write('%"PRId32"') g.write('%"PRId32"')
@ -2405,7 +2404,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('${str_fn_name}(') g.write('${str_fn_name}(')
g.expr(expr) g.expr(expr)
g.write(',0).str') g.write(',0).str')
} else if g.typ( node.expr_types[i] ).starts_with('Option') { } else if g.typ(node.expr_types[i]).starts_with('Option') {
str_fn_name := 'Option_str' str_fn_name := 'Option_str'
g.write('${str_fn_name}(*(Option*)&') g.write('${str_fn_name}(*(Option*)&')
g.expr(expr) g.expr(expr)
@ -2560,34 +2559,84 @@ fn op_to_fn_name(name string) string {
fn (mut g Gen) comp_if_to_ifdef(name string, is_comptime_optional bool) string { fn (mut g Gen) comp_if_to_ifdef(name string, is_comptime_optional bool) string {
match name { match name {
// platforms/os-es: // platforms/os-es:
'windows' { return '_WIN32' } 'windows' {
'mac' { return '__APPLE__' } return '_WIN32'
'macos' { return '__APPLE__' } }
'linux' { return '__linux__' } 'mac' {
'freebsd' { return '__FreeBSD__' } return '__APPLE__'
'openbsd' { return '__OpenBSD__' } }
'netbsd' { return '__NetBSD__' } 'macos' {
'dragonfly' { return '__DragonFly__' } return '__APPLE__'
'android' { return '__ANDROID__' } }
'solaris' { return '__sun' } 'linux' {
'haiku' { return '__haiku__' } return '__linux__'
'linux_or_macos' { return '' } }
'freebsd' {
return '__FreeBSD__'
}
'openbsd' {
return '__OpenBSD__'
}
'netbsd' {
return '__NetBSD__'
}
'dragonfly' {
return '__DragonFly__'
}
'android' {
return '__ANDROID__'
}
'solaris' {
return '__sun'
}
'haiku' {
return '__haiku__'
}
'linux_or_macos' {
return ''
}
// //
'js' { return '_VJS' } 'js' {
return '_VJS'
}
// compilers: // compilers:
'tinyc' { return '__TINYC__' } 'tinyc' {
'clang' { return '__clang__' } return '__TINYC__'
'mingw' { return '__MINGW32__' } }
'msvc' { return '_MSC_VER' } 'clang' {
return '__clang__'
}
'mingw' {
return '__MINGW32__'
}
'msvc' {
return '_MSC_VER'
}
// other: // other:
'debug' { return '_VDEBUG' } 'debug' {
'glibc' { return '__GLIBC__' } return '_VDEBUG'
'prealloc' { return 'VPREALLOC' } }
'no_bounds_checking' { return 'CUSTOM_DEFINE_no_bounds_checking' } 'glibc' {
'x64' { return 'TARGET_IS_64BIT' } return '__GLIBC__'
'x32' { return 'TARGET_IS_32BIT' } }
'little_endian' { return 'TARGET_ORDER_IS_LITTLE' } 'prealloc' {
'big_endian' { return 'TARGET_ORDER_IS_BIG' } return 'VPREALLOC'
}
'no_bounds_checking' {
return 'CUSTOM_DEFINE_no_bounds_checking'
}
'x64' {
return 'TARGET_IS_64BIT'
}
'x32' {
return 'TARGET_IS_32BIT'
}
'little_endian' {
return 'TARGET_ORDER_IS_LITTLE'
}
'big_endian' {
return 'TARGET_ORDER_IS_BIG'
}
else { else {
if is_comptime_optional || g.pref.compile_defines_all.len > 0 && name in g.pref.compile_defines_all { if is_comptime_optional || g.pref.compile_defines_all.len > 0 && name in g.pref.compile_defines_all {
return 'CUSTOM_DEFINE_${name}' return 'CUSTOM_DEFINE_${name}'
@ -3129,6 +3178,7 @@ fn (v &Gen) interface_table() string {
continue continue
} }
info := t.info as table.Interface info := t.info as table.Interface
println(info.gen_types)
// interface_name is for example Speaker // interface_name is for example Speaker
interface_name := t.name interface_name := t.name
mut methods := '' mut methods := ''

View File

@ -203,7 +203,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
g.expr(node.left) g.expr(node.left)
g.write('._interface_idx][1]))(') g.write('._interface_idx][1]))(')
g.expr(node.left) g.expr(node.left)
g.writeln('._object );') g.write('._object)')
return return
} }
// rec_sym := g.table.get_type_symbol(node.receiver_type) // rec_sym := g.table.get_type_symbol(node.receiver_type)

View File

@ -226,14 +226,15 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
} }
p.next() // `interface` p.next() // `interface`
interface_name := p.check_name() interface_name := p.check_name()
//println('interface decl $interface_name') // println('interface decl $interface_name')
p.check(.lcbr) p.check(.lcbr)
// Declare the type // Declare the type
t := table.TypeSymbol{ t := table.TypeSymbol{
kind: .interface_ kind: .interface_
name: interface_name name: interface_name
info: table.Struct{ info: table.Interface{
//is_interface: true gen_types: []
foo: 'foo'
} }
} }
typ := p.table.register_type_symbol(t) typ := p.table.register_type_symbol(t)
@ -260,7 +261,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
method.return_type = p.parse_type() method.return_type = p.parse_type()
} }
methods << method methods << method
//println('register method $name') // println('register method $name')
ts.register_method(table.Fn{ ts.register_method(table.Fn{
name: name name: name
args: args args: args

View File

@ -214,9 +214,10 @@ pub const (
pub const ( pub const (
builtin_type_names = ['void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64', builtin_type_names = ['void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64',
'u16' 'u16'
'u32', 'u64', 'f32', 'f64', 'string', 'ustring', 'char', 'byte', 'bool', 'none', 'array', 'u32'
'array_fixed', 'map' 'u64', 'f32', 'f64', 'string', 'ustring', 'char', 'byte', 'bool', 'none', 'array', 'array_fixed'
'struct', 'mapnode', 'size_t'] 'map', 'struct'
'mapnode', 'size_t']
) )
pub struct MultiReturn { pub struct MultiReturn {
@ -499,6 +500,7 @@ pub mut:
pub struct Interface { pub struct Interface {
gen_types []string gen_types []string
foo string
} }
pub struct Enum { pub struct Enum {

View File

@ -119,13 +119,11 @@ pub fn (s &TypeSymbol) has_field(name string) bool {
pub fn (s &TypeSymbol) find_field(name string) ?Field { pub fn (s &TypeSymbol) find_field(name string) ?Field {
match s.info { match s.info {
Struct { Struct { for field in it.fields {
for field in it.fields {
if field.name == name { if field.name == name {
return field return field
} }
} } }
}
else {} else {}
} }
return none return none
@ -390,7 +388,7 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int {
return t.register_type_symbol(mr_type) return t.register_type_symbol(mr_type)
} }
pub fn (mut t Table) find_or_register_fn_type(f Fn, is_anon bool, has_decl bool) int { pub fn (mut t Table) find_or_register_fn_type(f Fn, is_anon, has_decl bool) int {
name := if f.name.len == 0 { 'anon_fn_$f.signature()' } else { f.name } name := if f.name.len == 0 { 'anon_fn_$f.signature()' } else { f.name }
return t.register_type_symbol(TypeSymbol{ return t.register_type_symbol(TypeSymbol{
kind: .function kind: .function
@ -485,6 +483,16 @@ pub fn (t &Table) check(got, expected Type) bool {
// # NOTE: use symbols from this point on for perf // # NOTE: use symbols from this point on for perf
got_type_sym := t.get_type_symbol(got) got_type_sym := t.get_type_symbol(got)
exp_type_sym := t.get_type_symbol(expected) exp_type_sym := t.get_type_symbol(expected)
//
if exp_type_sym.kind == .interface_ {
info := got_type_sym.info as Interface
println('gen_types before')
println(info.gen_types)
info.gen_types << got_type_sym.name
println('adding gen_type $got_type_sym.name')
println(info.gen_types)
return true
}
// allow enum value to be used as int // allow enum value to be used as int
if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() && if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() &&
got_type_sym.kind == .enum_) { got_type_sym.kind == .enum_) {

View File

@ -33,15 +33,14 @@ interface Speaker {
speak() speak()
} }
/*
fn perform_speak(s Speaker) { fn perform_speak(s Speaker) {
s.speak() s.speak()
assert true assert true
/* /*
name := s.name() name := s.name()
assert name == 'Dog' || name == 'Cat' assert name == 'Dog' || name == 'Cat'
println(s.name())
*/ */
println(s.name())
} }
fn test_perform_speak() { fn test_perform_speak() {
@ -56,7 +55,6 @@ fn test_perform_speak() {
} }
*/ */
} }
*/
/* /*
interface Speak2er { interface Speak2er {