From 2411b8d1e7d2e751eda3e2424db99c24b354aae1 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 9 Oct 2019 23:38:33 +0300 Subject: [PATCH] module cache fixes; do not allow function names starting with _ --- compiler/cc.v | 2 +- compiler/cgen.v | 2 +- compiler/compile_errors.v | 2 +- compiler/fn.v | 17 +++++++++------ compiler/main.v | 3 --- compiler/module_header.v | 21 +++++++++++++++--- compiler/parser.v | 2 +- compiler/table.v | 2 +- vlib/builtin/array.v | 45 +++++++++++++++++++++++++++++++++++++-- vlib/builtin/builtin.v | 2 +- vlib/builtin/hashmap.v | 2 +- vlib/builtin/js/array.v | 2 +- vlib/builtin/map.v | 13 +++++++++-- vlib/strings/builder_c.v | 2 +- vlib/strings/builder_js.v | 2 +- vlib/term/colors.v | 4 ++-- vlib/term/colors_nix.v | 7 ------ vlib/term/colors_win.v | 7 ------ 18 files changed, 95 insertions(+), 42 deletions(-) diff --git a/compiler/cc.v b/compiler/cc.v index a2fb9f4d44..aa6c7e5d57 100644 --- a/compiler/cc.v +++ b/compiler/cc.v @@ -10,9 +10,9 @@ import ( ) fn (v mut V) cc() { - // build any thirdparty obj files v.build_thirdparty_obj_files() // Just create a C/JavaScript file and exit + // for example: `v -o v.c compiler` if v.out_name.ends_with('.c') || v.out_name.ends_with('.js') { // Translating V code to JS by launching vjs $if !js { diff --git a/compiler/cgen.v b/compiler/cgen.v index 5e8c1c0abc..4ea21c6701 100644 --- a/compiler/cgen.v +++ b/compiler/cgen.v @@ -47,7 +47,7 @@ fn new_cgen(out_name_c string) &CGen { out_path: path out: out //buf: strings.new_builder(10000) - lines: _make(0, 1000, sizeof(string)) + lines: make(0, 1000, sizeof(string)) } return gen } diff --git a/compiler/compile_errors.v b/compiler/compile_errors.v index e0cd92f4e2..790f60d8ac 100644 --- a/compiler/compile_errors.v +++ b/compiler/compile_errors.v @@ -224,7 +224,7 @@ fn (s mut Scanner) get_scanner_pos_of_token(t &Token) ScannerPos { // of the token. Continue scanning for some more lines of context too. s.goto_scanner_position(ScannerPos{}) s.file_lines = []string - + mut prevlinepos := 0 // NB: TCC BUG workaround: removing the `mut ate:=0 ate++` line // below causes a bug in v, when v is compiled with tcc, and v diff --git a/compiler/fn.v b/compiler/fn.v index a2072bd976..afa6a61e97 100644 --- a/compiler/fn.v +++ b/compiler/fn.v @@ -214,7 +214,7 @@ fn (p mut Parser) fn_decl() { p.register_var(receiver) } // +-/* methods - if p.tok == .plus || p.tok == .minus || p.tok == .mul { + if p.tok in [TokenKind.plus, .minus, .mul] { f.name = p.tok.str() p.next() } @@ -226,17 +226,21 @@ fn (p mut Parser) fn_decl() { is_c := f.name == 'C' && p.tok == .dot // Just fn signature? only builtin.v + default build mode if p.pref.build_mode == .build_module { - println('\n\nfn_decl() name=$f.name receiver_typ=$receiver_typ nogen=$p.cgen.nogen') + //println('\n\nfn_decl() name=$f.name receiver_typ=$receiver_typ nogen=$p.cgen.nogen') } if is_c { p.check(.dot) f.name = p.check_name() f.is_c = true } - else if !p.pref.translated && !p.file_path.contains('view.v') { + else if !p.pref.translated { if contains_capital(f.name) { p.error('function names cannot contain uppercase letters, use snake_case instead') } + if f.name[0] == `_` { + // TODO error + p.warn('function names cannot start with `_`') + } if f.name.contains('__') { p.error('function names cannot contain double underscores, use single underscores instead') } @@ -382,8 +386,9 @@ fn (p mut Parser) fn_decl() { } p.add_method(receiver_t.name, f) } - else { - // println('register_fn typ=$typ isg=$is_generic') + else if p.first_pass(){ + // println('register_fn $f.name typ=$typ isg=$is_generic pass=$p.pass ' + +//'$p.file_name') p.table.register_fn(f) } if p.is_vh || p.first_pass() || is_live || is_fn_header || skip_main_in_test { @@ -807,7 +812,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) &Fn { file_path := p.file_path.replace('\\', '\\\\') // escape \ p.cgen.resetln(p.cgen.cur_line.replace( 'v_panic (', - '_panic_debug ($p.scanner.line_nr, tos2((byte *)"$file_path"), tos2((byte *)"$mod_name"), tos2((byte *)"$fn_name"), ' + 'panic_debug ($p.scanner.line_nr, tos3("$file_path"), tos3("$mod_name"), tos2((byte *)"$fn_name"), ' )) } for i, arg in f.args { diff --git a/compiler/main.v b/compiler/main.v index 52367c534b..f62291fe35 100644 --- a/compiler/main.v +++ b/compiler/main.v @@ -785,12 +785,9 @@ fn new_v(args[]string) &V { if args.len < 2 { dir = '' } - - // println('new compiler "$dir"') // build mode mut build_mode := BuildMode.default_mode mut mod := '' - //if args.contains('-lib') { if joined_args.contains('build module ') { build_mode = .build_module // v build module ~/v/os => os.o diff --git a/compiler/module_header.v b/compiler/module_header.v index 04e2ddfc62..058d69d33a 100644 --- a/compiler/module_header.v +++ b/compiler/module_header.v @@ -72,6 +72,18 @@ fn v_type_str(typ_ string) string { typ_ } typ = typ.replace('Option_', '?') + if typ.contains('_V_MulRet') { + words := typ.replace('_V_MulRet_', '').split('_V_') + typ = '(' + for i in 0 .. words.len { + typ += words[i] + if i != words.len - 1 { + typ += ',' + } + } + typ += ')' + return typ + } //println('"$typ"') if typ == '*void' { return 'voidptr' @@ -132,13 +144,16 @@ fn (v &V) generate_vh() { file.writeln('\n') } // Types - file.writeln('// Types2') + file.writeln('// Types') for _, typ in v.table.typesmap { //println(typ.name) if typ.mod != v.mod && typ.mod != ''{ // int, string etc mod == '' //println('skipping type "$typ.name"') continue } + if typ.name.contains('_V_MulRet') { + continue + } mut name := typ.name if typ.name.contains('__') { name = typ.name.all_after('__') @@ -179,7 +194,7 @@ fn (v &V) generate_vh() { if f.mod == v.mod || f.mod == ''{ fns << f } else { - println('skipping fn $f.name mod=$f.mod') + //println('skipping fn $f.name mod=$f.mod') } } for _, f in fns { @@ -199,7 +214,7 @@ fn (v &V) generate_vh() { file.writeln('\n// Methods //////////////////') for _, typ in v.table.typesmap { if typ.mod != v.mod { //&& typ.mod != '' { - println('skipping method typ $typ.name mod=$typ.mod') + //println('skipping method typ $typ.name mod=$typ.mod') continue } for method in typ.methods { diff --git a/compiler/parser.v b/compiler/parser.v index b154cde221..18dd91fab7 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -122,7 +122,7 @@ fn (v mut V) new_parser_from_file(path string) Parser { is_vh: path.ends_with('.vh') } if p.pref.building_v { - p.scanner.should_print_relative_paths_on_error = false + p.scanner.should_print_relative_paths_on_error = true } v.cgen.file = path p.scan_tokens() diff --git a/compiler/table.v b/compiler/table.v index 14f588bda7..ef9cd79892 100644 --- a/compiler/table.v +++ b/compiler/table.v @@ -562,7 +562,7 @@ fn (t &Table) find_type(name_ string) Type { return t.typesmap[name] } -fn (p mut Parser) _check_types(got_, expected_ string, throw bool) bool { +fn (p mut Parser) check_types2(got_, expected_ string, throw bool) bool { mut got := got_ mut expected := expected_ //p.log('check types got="$got" exp="$expected" ') diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 7eeb86f586..01c7f4d100 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -29,7 +29,7 @@ fn new_array(mylen, cap, elm_size int) array { // TODO -pub fn _make(len, cap, elm_size int) array { +pub fn make(len, cap, elm_size int) array { return new_array(len, cap, elm_size) } @@ -111,6 +111,13 @@ pub fn (a mut array) delete(idx int) { a.cap-- } +fn (a array) get(i int) voidptr { + if i < 0 || i >= a.len { + panic('array index out of range: $i/$a.len') + } + return a.data + i * a.element_size +} + fn (a array) _get(i int) voidptr { if i < 0 || i >= a.len { panic('array index out of range: $i/$a.len') @@ -175,6 +182,22 @@ fn (a mut array) set(idx int, val voidptr) { C.memcpy(a.data + a.element_size * idx, val, a.element_size) } +fn (arr mut array) push(val voidptr) { + if arr.len >= arr.cap - 1 { + cap := (arr.len + 1) * 2 + // println('_push: realloc, new cap=$cap') + if arr.cap == 0 { + arr.data = calloc(cap * arr.element_size) + } + else { + arr.data = C.realloc(arr.data, cap * arr.element_size) + } + arr.cap = cap + } + C.memcpy(arr.data + arr.element_size * arr.len, val, arr.element_size) + arr.len++ +} + fn (arr mut array) _push(val voidptr) { if arr.len >= arr.cap - 1 { cap := (arr.len + 1) * 2 @@ -209,6 +232,24 @@ pub fn (arr mut array) _push_many(val voidptr, size int) { arr.len += size } +// `val` is array.data +// TODO make private, right now it's used by strings.Builder +pub fn (arr mut array) push_many(val voidptr, size int) { + if arr.len >= arr.cap - size { + cap := (arr.len + size) * 2 + // println('_push: realloc, new cap=$cap') + if arr.cap == 0 { + arr.data = calloc(cap * arr.element_size) + } + else { + arr.data = C.realloc(arr.data, cap * arr.element_size) + } + arr.cap = cap + } + C.memcpy(arr.data + arr.element_size * arr.len, val, arr.element_size * size) + arr.len += size +} + pub fn (a array) reverse() array { arr := array { len: a.len @@ -291,7 +332,7 @@ pub fn (a mut []int) sort() { a.sort_with_compare(compare_ints) } -// Looking for an array index based on value. +// Looking for an array index based on value. // If there is, it will return the index and if not, it will return `-1` // TODO: Implement for all types pub fn (a []string) index(v string) int { diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index 10b06e6ffd..f9f229571f 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -57,7 +57,7 @@ pub fn print_backtrace(){ } // replaces panic when -debug arg is passed -fn _panic_debug(line_no int, file, mod, fn_name, s string) { +fn panic_debug(line_no int, file, mod, fn_name, s string) { println('================ V panic ================') println(' module: $mod') println(' function: ${fn_name}()') diff --git a/vlib/builtin/hashmap.v b/vlib/builtin/hashmap.v index 65fcb1af10..de1009d8a4 100644 --- a/vlib/builtin/hashmap.v +++ b/vlib/builtin/hashmap.v @@ -47,7 +47,7 @@ fn new_hashmap(planned_nr_items int) hashmap { return hashmap{ cap: cap elm_size: 4 - table: _make(cap, cap, sizeof(hashmapentry)) + table: make(cap, cap, sizeof(hashmapentry)) } } diff --git a/vlib/builtin/js/array.v b/vlib/builtin/js/array.v index 373645e0f1..bc341fa235 100644 --- a/vlib/builtin/js/array.v +++ b/vlib/builtin/js/array.v @@ -34,7 +34,7 @@ pub fn _make(len, cap, elm_size int) array { */ -pub fn _make(len, cap, elm_size int) array { +pub fn make(len, cap, elm_size int) array { return array{} } diff --git a/vlib/builtin/map.v b/vlib/builtin/map.v index 9d92d1bd1c..7f6cb6c16e 100644 --- a/vlib/builtin/map.v +++ b/vlib/builtin/map.v @@ -125,6 +125,15 @@ fn (m mut map) _set(key string, val voidptr) { m.insert(mut m.root, key, val) } +fn (m mut map) set(key string, val voidptr) { + if isnil(m.root) { + m.root = new_node(key, val, m.element_size) + m.size++ + return + } + m.insert(mut m.root, key, val) +} + /* fn (m map) bs(query string, start, end int, out voidptr) { // println('bs "$query" $start -> $end') @@ -210,8 +219,8 @@ pub fn (m mut map) delete(key string) { m.size-- } -pub fn (m map) exists(key string) { - panic('map.exists(key) was removed from the language. Use `key in map` instead.') +fn (m map) exists(key string) bool { + return !isnil(m.root) && m.root.find2(key, m.element_size) } fn (m map) _exists(key string) bool { diff --git a/vlib/strings/builder_c.v b/vlib/strings/builder_c.v index 9861a2f1dc..10d68d2c9c 100644 --- a/vlib/strings/builder_c.v +++ b/vlib/strings/builder_c.v @@ -13,7 +13,7 @@ pub: pub fn new_builder(initial_size int) Builder { return Builder { - buf: _make(0, initial_size, sizeof(byte)) + buf: make(0, initial_size, sizeof(byte)) } } diff --git a/vlib/strings/builder_js.v b/vlib/strings/builder_js.v index 9861a2f1dc..10d68d2c9c 100644 --- a/vlib/strings/builder_js.v +++ b/vlib/strings/builder_js.v @@ -13,7 +13,7 @@ pub: pub fn new_builder(initial_size int) Builder { return Builder { - buf: _make(0, initial_size, sizeof(byte)) + buf: make(0, initial_size, sizeof(byte)) } } diff --git a/vlib/term/colors.v b/vlib/term/colors.v index 541d0e164c..5639e6bb42 100644 --- a/vlib/term/colors.v +++ b/vlib/term/colors.v @@ -4,11 +4,11 @@ module term -fn _format(msg, open, close string) string { +pub fn format(msg, open, close string) string { return '\x1b[' + open + 'm' + msg + '\x1b[' + close + 'm' } -fn _format_rgb(r, g, b int, msg, open, close string) string { +pub fn format_rgb(r, g, b int, msg, open, close string) string { return '\x1b[' + open + ';2;' + r.str() + ';' + g.str() + ';' + b.str() + 'm' + msg + '\x1b[' + close + 'm' } diff --git a/vlib/term/colors_nix.v b/vlib/term/colors_nix.v index efbc5313ec..37274c1957 100644 --- a/vlib/term/colors_nix.v +++ b/vlib/term/colors_nix.v @@ -4,10 +4,3 @@ module term -pub fn format(msg, open, close string) string { - return _format(msg, open, close) -} - -pub fn format_rgb(r, g, b int, msg, open, close string) string { - return _format_rgb(r, g, b, msg, open, close) -} diff --git a/vlib/term/colors_win.v b/vlib/term/colors_win.v index efbc5313ec..37274c1957 100644 --- a/vlib/term/colors_win.v +++ b/vlib/term/colors_win.v @@ -4,10 +4,3 @@ module term -pub fn format(msg, open, close string) string { - return _format(msg, open, close) -} - -pub fn format_rgb(r, g, b int, msg, open, close string) string { - return _format_rgb(r, g, b, msg, open, close) -}