From 2b685fc80a84622c8a82d71344f15714d2af28ea Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 9 Apr 2020 15:59:19 +0200 Subject: [PATCH] table: bring back parse_cflag() --- vlib/v/builder/cflags.v | 95 ++--------------------------------------- vlib/v/fmt/fmt.v | 2 +- vlib/v/table/cflags.v | 93 ++++++++++++++++++++++++++++++++++++++++ vlib/v/table/table.v | 79 +++++++++++++++++++++------------- 4 files changed, 147 insertions(+), 122 deletions(-) create mode 100644 vlib/v/table/cflags.v diff --git a/vlib/v/builder/cflags.v b/vlib/v/builder/cflags.v index 94a609620c..87f1558c5e 100644 --- a/vlib/v/builder/cflags.v +++ b/vlib/v/builder/cflags.v @@ -24,17 +24,17 @@ fn (v &Builder) get_os_cflags() []CFlag { if v.pref.compile_defines.len > 0 { ctimedefines << v.pref.compile_defines } - // QTODO - /* for flag in v.table.cflags { - if flag.os == '' || (flag.os == 'linux' && v.pref.os == .linux) || (flag.os == 'darwin' && v.pref.os == .mac) || (flag.os == 'freebsd' && v.pref.os == .freebsd) || (flag.os == 'windows' && v.pref.os == .windows) || (flag.os == 'mingw' && v.pref.os == .windows && v.pref.ccompiler != 'msvc') || (flag.os == 'solaris' && v.pref.os == .solaris) { + if flag.os == '' || (flag.os == 'linux' && v.pref.os == .linux) || (flag.os == 'darwin' && + v.pref.os == .mac) || (flag.os == 'freebsd' && v.pref.os == .freebsd) || (flag.os == 'windows' && + v.pref.os == .windows) || (flag.os == 'mingw' && v.pref.os == .windows && v.pref.ccompiler != + 'msvc') || (flag.os == 'solaris' && v.pref.os == .solaris) { flags << flag } if flag.os in ctimedefines { flags << flag } } -*/ return flags } @@ -65,93 +65,6 @@ fn (cf &CFlag) format() string { return '$cf.name $value'.trim_space() } -// check if cflag is in table -/* -QTODO -fn (table &Table) has_cflag(cflag CFlag) bool { - for cf in table.cflags { - if cf.os == cflag.os && cf.name == cflag.name && cf.value == cflag.value { - return true - } - } - return false -} - -// parse the flags to (table.cflags) []CFlag -// Note: clean up big time (joe-c) -fn (table mut Table) parse_cflag(cflag string, mod string, ctimedefines []string) ?bool { - allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L', ] - flag_orig := cflag.trim_space() - mut flag := flag_orig - if flag == '' { - return true - } - mut fos := '' - mut allowed_os_overrides := ['linux', 'darwin', 'freebsd', 'windows', 'mingw', 'solaris'] - allowed_os_overrides << ctimedefines - for os_override in allowed_os_overrides { - if !flag.starts_with( os_override ) { continue } - pos := flag.index(' ') or { - return none - } - fos = flag[..pos].trim_space() - flag = flag[pos..].trim_space() - } - for { - mut name := '' - mut value := '' - if flag[0] == `-` { - for f in allowed_flags { - i := 1 + f.len - if i <= flag.len && f == flag[1..i] { - name = flag[..i].trim_space() - flag = flag[i..].trim_space() - break - } - } - } - mut index := flag.index(' -') or { - -1 - } - for index > -1 { - mut has_next := false - for f in allowed_flags { - i := index + 2 + f.len - if i <= flag.len && f == flag[index + 2..i] { - value = flag[..index + 1].trim_space() - flag = flag[index + 1..].trim_space() - has_next = true - break - } - } - if has_next { - break - } - index = flag.index_after(' -', index + 1) - } - if index == -1 { - value = flag.trim_space() - } - if (name in ['-I', '-l', '-L']) && value == '' { - hint := if name == '-l' { 'library name' } else { 'path' } - return error('bad #flag `$flag_orig`: missing $hint after `$name`') - } - cf := CFlag{ - mod: mod - os: fos - name: name - value: value - } - if !table.has_cflag(cf) { - table.cflags << cf - } - if index == -1 { - break - } - } - return true -} -*/ // TODO: implement msvc specific c_options_before_target and c_options_after_target ... fn (cflags []CFlag) c_options_before_target_msvc() string { return '' diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 5894b8c7d7..a0baa447a3 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -451,7 +451,7 @@ fn (f mut Fmt) expr(node ast.Expr) { f.writeln('\t$it.var_name |') // TODO StructInit copy pasta for i, field in it.fields { - f.write('$field: ') + f.write('\t$field: ') f.expr(it.exprs[i]) f.writeln('') } diff --git a/vlib/v/table/cflags.v b/vlib/v/table/cflags.v new file mode 100644 index 0000000000..d0f1a73a4e --- /dev/null +++ b/vlib/v/table/cflags.v @@ -0,0 +1,93 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module table + +import v.builder + +// check if cflag is in table +fn (table &Table) has_cflag(cflag builder.CFlag) bool { + for cf in table.cflags { + if cf.os == cflag.os && cf.name == cflag.name && cf.value == cflag.value { + return true + } + } + return false +} + +// parse the flags to (table.cflags) []CFlag +// Note: clean up big time (joe-c) +fn (table mut Table) parse_cflag(cflag, mod string, ctimedefines []string) ?bool { + allowed_flags := ['framework', 'library', 'Wa', 'Wl', 'Wp', 'I', 'l', 'L'] + flag_orig := cflag.trim_space() + mut flag := flag_orig + if flag == '' { + return true + } + mut fos := '' + mut allowed_os_overrides := ['linux', 'darwin', 'freebsd', 'windows', 'mingw', 'solaris'] + allowed_os_overrides << ctimedefines + for os_override in allowed_os_overrides { + if !flag.starts_with(os_override) { + continue + } + pos := flag.index(' ') or { + return none + } + fos = flag[..pos].trim_space() + flag = flag[pos..].trim_space() + } + for { + mut name := '' + mut value := '' + if flag[0] == `-` { + for f in allowed_flags { + i := 1 + f.len + if i <= flag.len && f == flag[1..i] { + name = flag[..i].trim_space() + flag = flag[i..].trim_space() + break + } + } + } + mut index := flag.index(' -') or { + -1 + } + for index > -1 { + mut has_next := false + for f in allowed_flags { + i := index + 2 + f.len + if i <= flag.len && f == flag[index + 2..i] { + value = flag[..index + 1].trim_space() + flag = flag[index + 1..].trim_space() + has_next = true + break + } + } + if has_next { + break + } + index = flag.index_after(' -', index + 1) + } + if index == -1 { + value = flag.trim_space() + } + if (name in ['-I', '-l', '-L']) && value == '' { + hint := if name == '-l' { 'library name' } else { 'path' } + return error('bad #flag `$flag_orig`: missing $hint after `$name`') + } + cf := builder.CFlag{ + mod: mod + os: fos + name: name + value: value + } + if !table.has_cflag(cf) { + table.cflags << cf + } + if index == -1 { + break + } + } + return true +} diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 5e742dc63d..0701ecd37f 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -3,18 +3,19 @@ // that can be found in the LICENSE file. module table -import os +import ( + os + v.builder +) pub struct Table { - // struct_fields map[string][]string pub mut: types []TypeSymbol - // type_idxs Hashmap type_idxs map[string]int - // fns Hashmap fns map[string]Fn imports []string // List of all imports modules []string // List of all modules registered by the application + cflags []builder.CFlag // TODO a different module? importing builder from table feels weird } pub struct Fn { @@ -35,10 +36,10 @@ pub: pub struct Var { pub: - name string - is_mut bool + name string + is_mut bool mut: - typ Type + typ Type } pub fn new_table() &Table { @@ -133,7 +134,7 @@ pub fn (t &Table) type_has_method(s &TypeSymbol, name string) bool { pub fn (t &Table) type_find_method(s &TypeSymbol, name string) ?Fn { // println('type_find_method($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx') mut ts := s - for { + for { if method := ts.find_method(name) { return method } @@ -157,7 +158,7 @@ pub fn (t &Table) struct_has_field(s &TypeSymbol, name string) bool { pub fn (t &Table) struct_find_field(s &TypeSymbol, name string) ?Field { // println('struct_find_field($s.name, $name) types.len=$t.types.len s.parent_idx=$s.parent_idx') mut ts := s - for { + for { if field := ts.find_field(name) { return field } @@ -206,10 +207,9 @@ pub fn (t mut Table) register_builtin_type_symbol(typ TypeSymbol) int { existing_type := t.types[existing_idx] t.types[existing_idx] = { typ | - kind:existing_type.kind + kind: existing_type.kind } - } - else { + } else { t.types[existing_idx] = typ } } @@ -230,7 +230,7 @@ pub fn (t mut Table) register_type_symbol(typ TypeSymbol) int { // println('overriding type placeholder `$typ.name`') t.types[existing_idx] = { typ | - methods:ex_type.methods + methods: ex_type.methods } return existing_idx } @@ -241,7 +241,7 @@ pub fn (t mut Table) register_type_symbol(typ TypeSymbol) int { // panic('cannot register type `$typ.name`, another type with this name exists') return -1 } - } + } } typ_idx := t.types.len t.types << typ @@ -259,17 +259,33 @@ pub fn (t &Table) known_type(name string) bool { [inline] pub fn (t &Table) array_name(elem_type Type, nr_dims int) string { elem_type_sym := t.get_type_symbol(elem_type) - return 'array_${elem_type_sym.name}' + if type_is_ptr(elem_type) { '_ptr' } else { '' } + if nr_dims > 1 { '_${nr_dims}d' } else { '' } + return 'array_${elem_type_sym.name}' + if type_is_ptr(elem_type) { + '_ptr' + } else { + '' + } + if nr_dims > 1 { + '_${nr_dims}d' + } else { + '' + } } [inline] -pub fn (t &Table) array_fixed_name(elem_type Type, size int, nr_dims int) string { +pub fn (t &Table) array_fixed_name(elem_type Type, size, nr_dims int) string { elem_type_sym := t.get_type_symbol(elem_type) - return 'array_fixed_${elem_type_sym.name}_${size}' + if type_is_ptr(elem_type) { '_ptr' } else { '' } + if nr_dims > 1 { '_${nr_dims}d' } else { '' } + return 'array_fixed_${elem_type_sym.name}_${size}' + if type_is_ptr(elem_type) { + '_ptr' + } else { + '' + } + if nr_dims > 1 { + '_${nr_dims}d' + } else { + '' + } } [inline] -pub fn (t &Table) map_name(key_type Type, value_type Type) string { +pub fn (t &Table) map_name(key_type, value_type Type) string { key_type_sym := t.get_type_symbol(key_type) value_type_sym := t.get_type_symbol(value_type) suffix := if type_is_ptr(value_type) { '_ptr' } else { '' } @@ -317,7 +333,7 @@ pub fn (t mut Table) find_or_register_array(elem_type Type, nr_dims int) int { return t.register_type_symbol(array_type) } -pub fn (t mut Table) find_or_register_array_fixed(elem_type Type, size int, nr_dims int) int { +pub fn (t mut Table) find_or_register_array_fixed(elem_type Type, size, nr_dims int) int { name := t.array_fixed_name(elem_type, size, nr_dims) // existing existing_idx := t.type_idxs[name] @@ -402,7 +418,7 @@ pub fn (t &Table) value_type(typ Type) Type { info := typ_sym.info as Map return info.value_type } - if typ_sym.kind == .string && table.type_is_ptr(typ) { + if typ_sym.kind == .string && type_is_ptr(typ) { // (&string)[i] => string return string_type } @@ -439,24 +455,25 @@ pub fn (t &Table) check(got, expected Type) bool { if exp_idx == voidptr_type_idx || got_idx == voidptr_type_idx { return true } - if (exp_idx in pointer_type_idxs || exp_idx in number_type_idxs) // - && (got_idx in pointer_type_idxs || got_idx in number_type_idxs) { + if (exp_idx in pointer_type_idxs || exp_idx in number_type_idxs) && (got_idx in pointer_type_idxs || + got_idx in number_type_idxs) { return true } // see hack in checker IndexExpr line #691 - if (got_idx == byte_type_idx && exp_idx == byteptr_type_idx) // - || (exp_idx == byte_type_idx && got_idx == byteptr_type_idx) { + if (got_idx == byte_type_idx && exp_idx == byteptr_type_idx) || (exp_idx == byte_type_idx && + got_idx == byteptr_type_idx) { return true } - if (got_idx == char_type_idx && exp_idx == charptr_type_idx) // - || (exp_idx == char_type_idx && got_idx == charptr_type_idx) { + if (got_idx == char_type_idx && exp_idx == charptr_type_idx) || (exp_idx == char_type_idx && + got_idx == charptr_type_idx) { return true } // # 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) // 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_) { + if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() && + got_type_sym.kind == .enum_) { return true } // TODO @@ -475,11 +492,13 @@ pub fn (t &Table) check(got, expected Type) bool { } // TODO // accept [] when an expected type is an array - if got_type_sym.kind == .array && got_type_sym.name == 'array_void' && exp_type_sym.kind == .array { + if got_type_sym.kind == .array && got_type_sym.name == 'array_void' && exp_type_sym.kind == + .array { return true } // type alias - if (got_type_sym.kind == .alias && got_type_sym.parent_idx == exp_idx) || (exp_type_sym.kind == .alias && exp_type_sym.parent_idx == got_idx) { + if (got_type_sym.kind == .alias && got_type_sym.parent_idx == exp_idx) || (exp_type_sym.kind == + .alias && exp_type_sym.parent_idx == got_idx) { return true } // sum type @@ -512,7 +531,7 @@ pub fn (t &Table) check(got, expected Type) bool { // Once we have a module format we can read from module file instead // this is not optimal -pub fn (table &Table) qualify_module(mod string, file_path string) string { +pub fn (table &Table) qualify_module(mod, file_path string) string { for m in table.imports { if m.contains('.') && m.contains(mod) { m_parts := m.split('.')