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/string_interpolation_variadic_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/pointers_str_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()
return g.hashes() + g.comptime_defines.str() + '\n// V typedefs:\n' + g.typedefs.str() + '\n// V typedefs2:\n' + g.typedefs2.str() +
'\n// V cheaders:\n' + g.cheaders.str() + '\n// V includes:\n' + g.includes.str() + '\n// V definitions:\n' +
g.definitions.str() + g.interface_table() + '\n// V gowrappers:\n' + g.gowrappers.str() + '\n// V stringliterals:\n' +
g.stringliterals.str() + '\n// V auto str functions:\n' + g.auto_str_funcs.str() + '\n// V out\n' +
g.out.str() + '\n// THE END.'
return g.hashes() + g.comptime_defines.str() + '\n// V typedefs:\n' + g.typedefs.str() +
'\n// V typedefs2:\n' + g.typedefs2.str() + '\n// V cheaders:\n' + g.cheaders.str() + '\n// V includes:\n' +
g.includes.str() + '\n// V definitions:\n' + g.definitions.str() + g.interface_table() + '\n// V gowrappers:\n' +
g.gowrappers.str() + '\n// V stringliterals:\n' + g.stringliterals.str() + '\n// V auto str functions:\n' +
g.auto_str_funcs.str() + '\n// V out\n' + g.out.str() + '\n// THE END.'
}
pub fn (g Gen) hashes() string {
@ -189,7 +189,6 @@ pub fn (mut g Gen) init() {
if g.pref.build_mode != .build_module {
g.stringliterals.writeln('void vinit_string_literals(){')
}
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('// 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"')
} else if node.expr_types[i] == table.u64_type {
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')
} else {
g.write('%"PRId32"')
@ -2405,7 +2404,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('${str_fn_name}(')
g.expr(expr)
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'
g.write('${str_fn_name}(*(Option*)&')
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 {
match name {
// platforms/os-es:
'windows' { return '_WIN32' }
'mac' { return '__APPLE__' }
'macos' { return '__APPLE__' }
'linux' { return '__linux__' }
'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 '' }
'windows' {
return '_WIN32'
}
'mac' {
return '__APPLE__'
}
'macos' {
return '__APPLE__'
}
'linux' {
return '__linux__'
}
'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:
'tinyc' { return '__TINYC__' }
'clang' { return '__clang__' }
'mingw' { return '__MINGW32__' }
'msvc' { return '_MSC_VER' }
'tinyc' {
return '__TINYC__'
}
'clang' {
return '__clang__'
}
'mingw' {
return '__MINGW32__'
}
'msvc' {
return '_MSC_VER'
}
// other:
'debug' { return '_VDEBUG' }
'glibc' { return '__GLIBC__' }
'prealloc' { 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' }
'debug' {
return '_VDEBUG'
}
'glibc' {
return '__GLIBC__'
}
'prealloc' {
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 {
if is_comptime_optional || g.pref.compile_defines_all.len > 0 && name in g.pref.compile_defines_all {
return 'CUSTOM_DEFINE_${name}'
@ -3129,6 +3178,7 @@ fn (v &Gen) interface_table() string {
continue
}
info := t.info as table.Interface
println(info.gen_types)
// interface_name is for example Speaker
interface_name := t.name
mut methods := ''

View File

@ -203,7 +203,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
g.expr(node.left)
g.write('._interface_idx][1]))(')
g.expr(node.left)
g.writeln('._object );')
g.write('._object)')
return
}
// 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`
interface_name := p.check_name()
//println('interface decl $interface_name')
// println('interface decl $interface_name')
p.check(.lcbr)
// Declare the type
t := table.TypeSymbol{
kind: .interface_
name: interface_name
info: table.Struct{
//is_interface: true
info: table.Interface{
gen_types: []
foo: 'foo'
}
}
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()
}
methods << method
//println('register method $name')
// println('register method $name')
ts.register_method(table.Fn{
name: name
args: args

View File

@ -214,9 +214,10 @@ pub const (
pub const (
builtin_type_names = ['void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64',
'u16'
'u32', 'u64', 'f32', 'f64', 'string', 'ustring', 'char', 'byte', 'bool', 'none', 'array',
'array_fixed', 'map'
'struct', 'mapnode', 'size_t']
'u32'
'u64', 'f32', 'f64', 'string', 'ustring', 'char', 'byte', 'bool', 'none', 'array', 'array_fixed'
'map', 'struct'
'mapnode', 'size_t']
)
pub struct MultiReturn {
@ -499,6 +500,7 @@ pub mut:
pub struct Interface {
gen_types []string
foo string
}
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 {
match s.info {
Struct {
for field in it.fields {
Struct { for field in it.fields {
if field.name == name {
return field
}
}
}
} }
else {}
}
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)
}
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 }
return t.register_type_symbol(TypeSymbol{
kind: .function
@ -485,6 +483,16 @@ pub fn (t &Table) check(got, expected Type) bool {
// # NOTE: use symbols from this point on for perf
got_type_sym := t.get_type_symbol(got)
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
if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() &&
got_type_sym.kind == .enum_) {

View File

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