diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 530b379fcc..474cedcb2a 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -17,7 +17,7 @@ pub: // Private function, used by V (`nums := []int`) fn new_array(mylen, cap, elm_size int) array { - cap_ := if cap == 0 {1}else {cap} + cap_ := if cap == 0 { 1 } else { cap } arr := array{ len: mylen cap: cap @@ -34,7 +34,7 @@ pub fn make(len, cap, elm_size int) array { // Private function, used by V (`nums := [1, 2, 3]`) fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array { - cap_ := if cap == 0 {1}else {cap} + cap_ := if cap == 0 { 1 } else { cap } arr := array{ len: len cap: cap @@ -60,7 +60,7 @@ fn new_array_from_c_array_no_alloc(len, cap, elm_size int, c_array voidptr) arra // Private function. Doubles array capacity if needed fn (a mut array) ensure_cap(required int) { if required > a.cap { - mut cap := if a.cap == 0 {2}else {a.cap * 2} + mut cap := if a.cap == 0 { 2 } else { a.cap * 2 } for required > cap { cap *= 2 } @@ -204,7 +204,7 @@ fn (a array) right(n int) array { // used internally for [2..4] fn (a array) slice2(start, _end int, end_max bool) array { - end := if end_max {a.len}else {_end} + end := if end_max { a.len } else { _end } return a.slice(start, end) } @@ -372,7 +372,7 @@ pub fn (b []byte) hex() string { // TODO: implement for all types pub fn copy(dst, src []byte) int { if dst.len > 0 && src.len > 0 { - min := if dst.len < src.len {dst.len}else {src.len} + min := if dst.len < src.len { dst.len } else { src.len } C.memcpy(dst.data, src.left(min).data, dst.element_size * min) return min } @@ -454,7 +454,6 @@ pub fn (a []int) reduce(iter fn(accum, curr int)int, accum_start int) int { // array_eq checks if two arrays contain all the same elements in the same order. // []int == []int (also for: i64, f32, f64, byte, string) fn array_eq(a1, a2 []T) bool { - if a1.len != a2.len { return false } diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index e1f6f2268c..efe067491d 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -1,7 +1,6 @@ // Copyright (c) 2019 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 builtin __global g_m2_buf byteptr @@ -11,12 +10,13 @@ fn init() { $if windows { if is_atty(0) > 0 { C._setmode(C._fileno(C.stdin), C._O_U16TEXT) - } else { + } + else { C._setmode(C._fileno(C.stdin), C._O_U8TEXT) } C._setmode(C._fileno(C.stdout), C._O_U8TEXT) C.SetConsoleMode(C.GetStdHandle(C.STD_OUTPUT_HANDLE), C.ENABLE_PROCESSED_OUTPUT | 0x0004) // ENABLE_VIRTUAL_TERMINAL_PROCESSING - C.setbuf(C.stdout,0) + C.setbuf(C.stdout, 0) } } @@ -29,26 +29,31 @@ pub fn isnil(v voidptr) bool { return v == 0 } -fn on_panic(f fn (int) int) { +fn on_panic(f fn(int)int) { // TODO } pub fn print_backtrace_skipping_top_frames(skipframes int) { $if windows { $if msvc { - if print_backtrace_skipping_top_frames_msvc(skipframes) { return } + if print_backtrace_skipping_top_frames_msvc(skipframes) { + return + } } $if mingw { - if print_backtrace_skipping_top_frames_mingw(skipframes) { return } + if print_backtrace_skipping_top_frames_mingw(skipframes) { + return + } + } + } $else { + if print_backtrace_skipping_top_frames_nix(skipframes) { + return } - }$else{ - if print_backtrace_skipping_top_frames_nix(skipframes) { return } } println('print_backtrace_skipping_top_frames is not implemented on this platform for now...\n') } - -pub fn print_backtrace(){ +pub fn print_backtrace() { // at the time of backtrace_symbols_fd call, the C stack would look something like this: // 1 frame for print_backtrace_skipping_top_frames // 1 frame for print_backtrace itself @@ -58,7 +63,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}()') @@ -99,9 +104,8 @@ pub fn print(s string) { } } - -__global total_m i64 = 0 -__global nr_mallocs int = 0 +__global total_m i64=0 +__global nr_mallocs int=0 [unsafe_fn] pub fn malloc(n int) byteptr { @@ -120,7 +124,7 @@ pub fn malloc(n int) byteptr { } return ptr } -/* + /* TODO #ifdef VPLAY if n > 10000 { @@ -133,6 +137,7 @@ TODO print_backtrace() #endif */ + } pub fn calloc(n int) byteptr { @@ -166,3 +171,4 @@ pub fn is_atty(fd int) int { return C.isatty(fd) } } + diff --git a/vlib/builtin/builtin_nix.v b/vlib/builtin/builtin_nix.v index eb98ceb6b0..4425cace72 100644 --- a/vlib/builtin/builtin_nix.v +++ b/vlib/builtin/builtin_nix.v @@ -1,7 +1,6 @@ // Copyright (c) 2019 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 builtin pub fn println(s string) { @@ -20,9 +19,15 @@ fn print_backtrace_skipping_top_frames_mingw(skipframes int) bool { fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool { skipframes := xskipframes + 2 - $if macos { return print_backtrace_skipping_top_frames_mac(skipframes) } - $if linux { return print_backtrace_skipping_top_frames_linux(skipframes) } - $if freebsd { return print_backtrace_skipping_top_frames_freebsd(skipframes) } + $if macos { + return print_backtrace_skipping_top_frames_mac(skipframes) + } + $if linux { + return print_backtrace_skipping_top_frames_linux(skipframes) + } + $if freebsd { + return print_backtrace_skipping_top_frames_freebsd(skipframes) + } return false } @@ -30,20 +35,20 @@ fn print_backtrace_skipping_top_frames_nix(xskipframes int) bool { // so there is no need to have their twins in builtin_windows.v fn print_backtrace_skipping_top_frames_mac(skipframes int) bool { $if macos { - buffer := [100]byteptr - nr_ptrs := C.backtrace(*voidptr(buffer), 100) - C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_ptrs-skipframes, 1) + buffer := [100]byteptr + nr_ptrs := C.backtrace(*voidptr(buffer), 100) + C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_ptrs - skipframes, 1) } return true } fn print_backtrace_skipping_top_frames_freebsd(skipframes int) bool { $if freebsd { - buffer := [100]byteptr - nr_ptrs := C.backtrace(*voidptr(buffer), 100) - C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_ptrs-skipframes, 1) - } - return true + buffer := [100]byteptr + nr_ptrs := C.backtrace(*voidptr(buffer), 100) + C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_ptrs - skipframes, 1) + } + return true } fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { @@ -51,44 +56,50 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool { println('TODO: print_backtrace_skipping_top_frames_linux $skipframes with tcc fails tests with "stack smashing detected" .') return false } - $if !android { // backtrace is not available on Android. + $if !android { + // backtrace is not available on Android. $if glibc { buffer := [100]byteptr nr_ptrs := C.backtrace(*voidptr(buffer), 100) - nr_actual_frames := nr_ptrs-skipframes + nr_actual_frames := nr_ptrs - skipframes mut sframes := []string - csymbols := C.backtrace_symbols(*voidptr(&buffer[skipframes]), - nr_actual_frames) - for i in 0..nr_actual_frames { sframes << tos2(csymbols[i]) } + csymbols := C.backtrace_symbols(*voidptr(&buffer[skipframes]), nr_actual_frames) + for i in 0 .. nr_actual_frames { + sframes << tos2(csymbols[i]) + } for sframe in sframes { executable := sframe.all_before('(') addr := sframe.all_after('[').all_before(']') beforeaddr := sframe.all_before('[') cmd := 'addr2line -e $executable $addr' - // taken from os, to avoid depending on the os module inside builtin.v f := C.popen(cmd.str, 'r') if isnil(f) { - println(sframe) continue + println(sframe) + continue } buf := [1000]byte mut output := '' for C.fgets(voidptr(buf), 1000, f) != 0 { output += tos(buf, vstrlen(buf)) } - output = output.trim_space()+':' + output = output.trim_space() + ':' if 0 != C.pclose(f) { - println(sframe) continue + println(sframe) + continue } - if output in ['??:0:','??:?:'] { output = '' } - println( '${output:-46s} | ${addr:14s} | $beforeaddr') + if output in ['??:0:', '??:?:'] { + output = '' + } + println('${output:-46s} | ${addr:14s} | $beforeaddr') } - //C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_actual_frames, 1) + // C.backtrace_symbols_fd(*voidptr(&buffer[skipframes]), nr_actual_frames, 1) return true - }$else{ + } $else { C.printf('backtrace_symbols_fd is missing, so printing backtraces is not available.\n') C.printf('Some libc implementations like musl simply do not provide it.\n') } } return false } + diff --git a/vlib/builtin/cfns.v b/vlib/builtin/cfns.v index fa685d6891..ceccfa720b 100644 --- a/vlib/builtin/cfns.v +++ b/vlib/builtin/cfns.v @@ -1,166 +1,403 @@ module builtin - - // fn C.memcpy(byteptr, byteptr, int) voidptr -fn C.memmove(byteptr, byteptr, int) voidptr -//fn C.malloc(int) byteptr + +fn C.memmove(byteptr, byteptr, int) voidptr +// fn C.malloc(int) byteptr fn C.realloc(a byteptr, b int) byteptr + fn C.qsort(voidptr, int, int, voidptr) -fn C.sprintf(a ...voidptr) byteptr -fn C.strlen(s byteptr) int -fn C.isdigit(s byteptr) bool +fn C.sprintf(a ...voidptr) byteptr + + +fn C.strlen(s byteptr) int + + +fn C.isdigit(s byteptr) bool // stdio.h fn C.popen(c byteptr, t byteptr) voidptr - // fn backtrace(a voidptr, b int) int -fn backtrace_symbols(voidptr, int) &byteptr -fn backtrace_symbols_fd(voidptr, int, int) + +fn backtrace_symbols(voidptr, int) &byteptr + + +fn backtrace_symbols_fd(voidptr, int, int) // fn proc_pidpath(int, voidptr, int) int + fn C.realpath(byteptr, byteptr) &char - - fn C.chmod(byteptr, int) int + + fn C.printf(byteptr, ...byteptr) int + + fn C.fputs(byteptr) int + + fn C.fflush(byteptr) int // TODO define args in these functions fn C.fseek() int + + fn C.fopen() voidptr + + fn C.fwrite() int + + fn C.fclose() int + + fn C.pclose() int + + fn C.system() int + + fn C.setenv() int + + fn C.unsetenv() int + + fn C.access() int + + fn C.remove() int + + fn C.rmdir() int + + fn C.chdir() int + + fn C.fread() int + + fn C.rewind() int + + fn C.stat() int + + fn C.lstat() int + + fn C.rename() int + + fn C.fgets() int + + fn C.memset() int + + fn C.sigemptyset() int + + fn C.getcwd() int + + fn C.signal() int + + fn C.mktime() int + + fn C.gettimeofday() int + + fn C.sleep() int + + fn C.usleep() int + + fn C.opendir() voidptr + + fn C.closedir() int + + fn C.mkdir() int + + fn C.srand() int + + fn C.atof() int + + fn C.tolower() int + + fn C.toupper() int + + fn C.getchar() int + + fn C.strerror() charptr + + fn C.snprintf() int + + fn C.fprintf(byteptr, ...byteptr) + fn C.WIFEXITED() bool + + fn C.WEXITSTATUS() int + + fn C.WIFSIGNALED() bool + + fn C.WTERMSIG() int + + fn C.DEFAULT_LE() bool + + fn C.DEFAULT_EQ() bool + + fn C.DEFAULT_GT() bool + + fn C.DEFAULT_EQUAL() bool + + fn C.DEFAULT_NOT_EQUAL() bool + + fn C.DEFAULT_LT() bool + + fn C.DEFAULT_GE() bool + + fn C.isatty() int + fn C.syscall() int + + fn C.sysctl() int - - - - - - // Windows fn C._setmode(int, int) int + + fn C._fileno(int) int + + fn C._get_osfhandle(fd int) C.intptr_t + + fn C.GetModuleFileNameW(hModule voidptr, lpFilename &u16, nSize u32) u32 + + fn C.CreatePipe(hReadPipe &voidptr, hWritePipe &voidptr, lpPipeAttributes voidptr, nSize u32) bool + + fn C.SetHandleInformation(hObject voidptr, dwMask u32, dwFlags u32) bool + + fn C.ExpandEnvironmentStringsW(lpSrc &u16, lpDst &u16, nSize u32) u32 + + fn C.CreateProcessW(lpApplicationName &u16, lpCommandLine &u16, lpProcessAttributes voidptr, lpThreadAttributes voidptr, bInheritHandles bool, dwCreationFlags u32, lpEnvironment voidptr, lpCurrentDirectory &u16, lpStartupInfo voidptr, lpProcessInformation voidptr) bool + + fn C.ReadFile(hFile voidptr, lpBuffer voidptr, nNumberOfBytesToRead u32, lpNumberOfBytesRead voidptr, lpOverlapped voidptr) bool + + fn C.GetFileAttributesW(lpFileName byteptr) u32 + + fn C.RegQueryValueExW(hKey voidptr, lpValueName &u16, lpReserved &u32, lpType &u32, lpData byteptr, lpcbData &u32) int + + fn C.RegOpenKeyExW(hKey voidptr, lpSubKey &u16, ulOptions u32, samDesired u32, phkResult voidptr) int + + fn C.RegCloseKey() + + fn C.RegQueryValueEx() voidptr + + fn C.RemoveDirectory() int + + fn C.GetStdHandle() voidptr + + fn C.SetConsoleMode() + + fn C.GetConsoleMode() int + + fn C._putws() + + fn C.wprintf() + + fn C.setbuf() + + fn C.SymCleanup() + + fn C.MultiByteToWideChar() int + + fn C.wcslen() int + + fn C.WideCharToMultiByte() int + + fn C._wstat() + + fn C._wrename() + + fn C._wfopen() voidptr + + fn C._wpopen() voidptr + + fn C._pclose() int + + fn C._wsystem() int + + fn C._wgetenv() voidptr + + fn C._putenv() int + + fn C._waccess() int + + fn C._wremove() + + fn C.ReadConsole() + + fn C.fgetws() voidptr + + fn C.GetModuleFileName() int + + fn C._wchdir() + + fn C._wgetcwd() int + + fn C._fullpath() int + + fn C.GetCommandLine() voidptr + + fn C.CommandLineToArgvW() &voidptr + + fn C.LocalFree() + + fn C.FindFirstFileW() voidptr + + fn C.FindFirstFile() voidptr + + fn C.FindNextFile() voidptr + + fn C.FindClose() + + fn C.MAKELANGID() int + + fn C.FormatMessage() voidptr + + fn C.CloseHandle() + + fn C.GetExitCodeProcess() + + fn C.RegOpenKeyEx() voidptr + + fn C.GetTickCount() i64 + fn C.Sleep() + + fn C.WSAStartup(u16, &voidptr) int + + fn C.WSAGetLastError() int + + fn C.closesocket(int) int + + fn C.vschannel_init(&C.TlsContext) -fn C.request(&C.TlsContext,int, &u16, byteptr, &byteptr) + + +fn C.request(&C.TlsContext, int, &u16, byteptr, &byteptr) + + fn C.vschannel_cleanup(&C.TlsContext) -fn C.URLDownloadToFile(int, &u16,&u16, int, int) + + +fn C.URLDownloadToFile(int, &u16, &u16, int, int) + + fn C.GetLastError() u32 + + fn C.CreateDirectory(byteptr, int) bool -fn C.BCryptGenRandom(int,voidptr,int,int) int -fn C.CreateMutex(int,bool,byteptr) voidptr -fn C.WaitForSingleObject(voidptr,int) int + + +fn C.BCryptGenRandom(int, voidptr, int, int) int + + +fn C.CreateMutex(int, bool, byteptr) voidptr + + +fn C.WaitForSingleObject(voidptr, int) int + + fn C.ReleaseMutex(voidptr) bool + diff --git a/vlib/builtin/float.v b/vlib/builtin/float.v index d7165a7429..000b876a85 100644 --- a/vlib/builtin/float.v +++ b/vlib/builtin/float.v @@ -143,3 +143,4 @@ fn (a f64) gebit(b f64) bool { fn (a f32) gebit(b f32) bool { return C.DEFAULT_GE(a, b) } + diff --git a/vlib/builtin/hashmap.v b/vlib/builtin/hashmap.v index fca198289e..26dcb78b4f 100644 --- a/vlib/builtin/hashmap.v +++ b/vlib/builtin/hashmap.v @@ -1,9 +1,7 @@ // Copyright (c) 2019 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 builtin - /* This is work in progress. A very early test version of the hashmap with a fixed size. @@ -14,69 +12,78 @@ module builtin the performance gains are basically non-existent. */ + struct hashmap { - cap int - keys []string - table []hashmapentry - elm_size int + cap int + keys []string + table []hashmapentry + elm_size int pub: nr_collisions int } struct hashmapentry { - key string - val int - next &hashmapentry // linked list for collisions + key string + val int + next &hashmapentry // linked list for collisions } const ( - min_cap = 2 << 10 - max_cap = 2 << 20 + min_cap = 2<<10 + max_cap = 2<<20 ) fn new_hashmap(planned_nr_items int) hashmap { mut cap := planned_nr_items * 5 if cap < min_cap { cap = min_cap - } + } if cap > max_cap { cap = max_cap - } + } return hashmap{ cap: cap elm_size: 4 table: make(cap, cap, sizeof(hashmapentry)) - } -} + } +} fn (m mut hashmap) set(key string, val int) { - mut hash := int(b_fabs( key.hash() )) + mut hash := int(b_fabs(key.hash())) idx := hash % m.cap if m.table[idx].key.len != 0 { - //println('\nset() idx=$idx key="$key" hash="$hash" val=$val') + // println('\nset() idx=$idx key="$key" hash="$hash" val=$val') m.nr_collisions++ - //println('collision:' + m.table[idx].key) + // println('collision:' + m.table[idx].key) mut e := &m.table[idx] for e.next != 0 { e = e.next - } - e.next = &hashmapentry{key, val, 0} - } else { - m.table[idx] = hashmapentry{key, val, 0} + } + e.next = &hashmapentry{ + key,val,0} } -} + else { + m.table[idx] = hashmapentry{ + key,val,0} + } +} fn (m mut hashmap) get(key string) int { - hash := int(b_fabs( key.hash() )) + hash := int(b_fabs(key.hash())) idx := hash % m.cap mut e := &m.table[idx] - for e.next != 0 { // todo unsafe { + for e.next != 0 { + // todo unsafe { if e.key == key { return e.val - } + } e = e.next - } + } return e.val } -[inline] fn b_fabs(v int) f64 { return if v < 0 { -v } else { v } } +[inline] +fn b_fabs(v int) f64 { + return if v < 0 { -v } else { v } +} + diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index c01b543e11..840c210386 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -1,11 +1,10 @@ // Copyright (c) 2019 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 builtin pub fn ptr_str(ptr voidptr) string { - buf := malloc(sizeof(double) * 5 + 1)// TODO + buf := malloc(sizeof(double) * 5 + 1) // TODO C.sprintf(charptr(buf), '%p', ptr) return tos(buf, vstrlen(buf)) } @@ -19,7 +18,7 @@ pub fn (nn int) str() string { return '0' } max := 16 - mut buf := calloc(max+1) + mut buf := calloc(max + 1) mut len := 0 mut is_neg := false if n < 0 { @@ -42,12 +41,20 @@ pub fn (nn int) str() string { return tos(buf + max - len, len) } -pub fn (n i8) str() string { return int(n).str() } -pub fn (n i16) str() string { return int(n).str() } -pub fn (n u16) str() string { return int(n).str() } +pub fn (n i8) str() string { + return int(n).str() +} + +pub fn (n i16) str() string { + return int(n).str() +} + +pub fn (n u16) str() string { + return int(n).str() +} pub fn (nn u32) str() string { - mut n := nn + mut n := nn if n == u32(0) { return '0' } @@ -84,6 +91,7 @@ pub fn (nn byte) str() string { } */ + pub fn (nn i64) str() string { mut n := nn if n == i64(0) { @@ -113,7 +121,7 @@ pub fn (nn i64) str() string { } pub fn (nn u64) str() string { - mut n := nn + mut n := nn if n == u64(0) { return '0' } @@ -138,24 +146,16 @@ pub fn (b bool) str() string { } pub fn (n int) hex() string { - len := if n >= 0 { - n.str().len + 3 - } else { - 11 - } + len := if n >= 0 { n.str().len + 3 } else { 11 } hex := malloc(len) // 0x + \n count := int(C.sprintf(charptr(hex), '0x%x', n)) return tos(hex, count) } pub fn (n i64) hex() string { - len := if n >= i64(0) { - n.str().len + 3 - } else { - 19 - } + len := if n >= i64(0) { n.str().len + 3 } else { 19 } hex := malloc(len) - count := int(C.sprintf(charptr(hex), '0x%' C.PRIx64, n)) + count := int(C.sprintf(charptr(hex), '0x%'C.PRIx64, n)) return tos(hex, count) } @@ -169,21 +169,21 @@ pub fn (a []byte) contains(val byte) bool { } pub fn (c rune) str() string { - fst_byte := int(c) >> 8 * 3 & 0xff + fst_byte := int(c)>>8 * 3 & 0xff len := utf8_char_len(fst_byte) - mut str := string { + mut str := string{ len: len str: malloc(len + 1) } for i := 0; i < len; i++ { - str.str[i] = int(c) >> 8 * (3 - i) & 0xff + str.str[i] = int(c)>>8 * (3 - i) & 0xff } str[len] = `\0` return str } pub fn (c byte) str() string { - mut str := string { + mut str := string{ len: 1 str: malloc(2) } diff --git a/vlib/builtin/map.v b/vlib/builtin/map.v index 6acf7ae62a..a7a3c24b6d 100644 --- a/vlib/builtin/map.v +++ b/vlib/builtin/map.v @@ -1,28 +1,27 @@ // Copyright (c) 2019 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 builtin import strings pub struct map { element_size int - root &mapnode + root &mapnode pub: - size int + size int } struct mapnode { - left &mapnode - right &mapnode + left &mapnode + right &mapnode is_empty bool // set by delete() - key string - val voidptr + key string + val voidptr } fn new_map(cap, elm_size int) map { - res := map { + res := map{ element_size: elm_size root: 0 } @@ -31,7 +30,7 @@ fn new_map(cap, elm_size int) map { // `m := { 'one': 1, 'two': 2 }` fn new_map_init(cap, elm_size int, keys &string, vals voidptr) map { - mut res := map { + mut res := map{ element_size: elm_size root: 0 } @@ -42,7 +41,7 @@ fn new_map_init(cap, elm_size int, keys &string, vals voidptr) map { } fn new_node(key string, val voidptr, element_size int) &mapnode { - new_e := &mapnode { + new_e := &mapnode{ key: key val: malloc(element_size) left: 0 @@ -65,7 +64,8 @@ fn (m mut map) insert(n mut mapnode, key string, val voidptr) { if n.left == 0 { n.left = new_node(key, val, m.element_size) m.size++ - } else { + } + else { m.insert(mut n.left, key, val) } return @@ -73,12 +73,13 @@ fn (m mut map) insert(n mut mapnode, key string, val voidptr) { if n.right == 0 { n.right = new_node(key, val, m.element_size) m.size++ - } else { + } + else { m.insert(mut n.right, key, val) } } -fn (n & mapnode) find(key string, out voidptr, element_size int) bool{ +fn (n &mapnode) find(key string, out voidptr, element_size int) bool { if n.key == key { C.memcpy(out, n.val, element_size) return true @@ -86,35 +87,39 @@ fn (n & mapnode) find(key string, out voidptr, element_size int) bool{ else if n.key > key { if n.left == 0 { return false - } else { + } + else { return n.left.find(key, out, element_size) } } else { if n.right == 0 { return false - } else { + } + else { return n.right.find(key, out, element_size) } } } // same as `find`, but doesn't return a value. Used by `exists` -fn (n & mapnode) find2(key string, element_size int) bool{ +fn (n &mapnode) find2(key string, element_size int) bool { if n.key == key && !n.is_empty { return true } else if n.key > key { if isnil(n.left) { return false - } else { + } + else { return n.left.find2(key, element_size) } } else { if isnil(n.right) { return false - } else { + } + else { return n.right.find2(key, element_size) } } @@ -156,6 +161,7 @@ fn (m map) bs(query string, start, end int, out voidptr) { } */ + fn preorder_keys(node &mapnode, keys mut []string, key_i int) int { mut i := key_i if !node.is_empty { @@ -181,7 +187,7 @@ pub fn (m &map) keys() []string { } fn (m map) get(key string, out voidptr) bool { - //println('g') + // println('g') if m.root == 0 { return false } @@ -197,14 +203,16 @@ pub fn (n mut mapnode) delete(key string, element_size int) { else if n.key > key { if isnil(n.left) { return - } else { + } + else { n.left.delete(key, element_size) } } else { if isnil(n.right) { return - } else { + } + else { n.right.delete(key, element_size) } } @@ -223,10 +231,10 @@ fn (m map) exists(key string) bool { pub fn (m map) print() { println('<<<<<<<<') - //for i := 0; i < m.entries.len; i++ { - // entry := m.entries[i] - // println('$entry.key => $entry.val') - //} + // for i := 0; i < m.entries.len; i++ { + // entry := m.entries[i] + // println('$entry.key => $entry.val') + // } /* for i := 0; i < m.cap * m.element_size; i++ { b := m.table[i] @@ -235,6 +243,7 @@ pub fn (m map) print() { println('') } */ + println('>>>>>>>>>>') } @@ -266,9 +275,10 @@ pub fn (m map_string) str() string { } mut sb := strings.new_builder(50) sb.writeln('{') - for key, val in m { + for key, val in m { sb.writeln(' "$key" => "$val"') } sb.writeln('}') return sb.str() } + diff --git a/vlib/builtin/option.v b/vlib/builtin/option.v index 91137c8fac..388db670ba 100644 --- a/vlib/builtin/option.v +++ b/vlib/builtin/option.v @@ -1,9 +1,7 @@ // Copyright (c) 2019 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 builtin - /* struct Option2 { data T @@ -14,12 +12,13 @@ struct Option2 { } */ + struct Option { - data [300]byte - error string - ecode int - ok bool - is_none bool + data [300]byte + error string + ecode int + ok bool + is_none bool } // `fn foo() ?Foo { return foo }` => `fn foo() ?Foo { return opt_ok(foo); }` @@ -27,7 +26,7 @@ fn opt_ok(data voidptr, size int) Option { if size >= 300 { panic('option size too big: $size (max is 300), this is a temporary limit') } - res := Option { + res := Option{ ok: true } C.memcpy(res.data, data, size) @@ -36,21 +35,21 @@ fn opt_ok(data voidptr, size int) Option { // used internally when returning `none` fn opt_none() Option { - return Option{ is_none: true } + return Option{ + is_none: true + } } pub fn error(s string) Option { - return Option { + return Option{ error: s } } pub fn error_with_code(s string, code int) Option { - return Option { + return Option{ error: s ecode: code } } - - diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index b128541830..04c282cf08 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -1,11 +1,9 @@ // Copyright (c) 2019 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 builtin import strconv - /* NB: A V string should be/is immutable from the point of view of V user programs after it is first created. A V string is @@ -45,11 +43,11 @@ NB: A V string should be/is immutable from the point of view of pub struct string { -//mut: - //hash_cache int + // mut: + // hash_cache int pub: str byteptr // points to a C style 0 terminated string of bytes. - len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str). + len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str). } pub struct ustring { @@ -70,7 +68,7 @@ pub fn tos(s byteptr, len int) string { if s == 0 { panic('tos(): nil string') } - return string { + return string{ str: s len: len } @@ -89,7 +87,7 @@ pub fn tos2(s byteptr) string { if s == 0 { panic('tos2: nil string') } - return string { + return string{ str: s len: vstrlen(s) } @@ -100,14 +98,14 @@ pub fn tos3(s charptr) string { if s == 0 { panic('tos3: nil string') } - return string { + return string{ str: byteptr(s) len: C.strlen(s) } } pub fn (a string) clone() string { - mut b := string { + mut b := string{ len: a.len str: malloc(a.len + 1) } @@ -128,14 +126,16 @@ pub fn (s string) cstr() byteptr { // cstring_to_vstring creates a copy of cstr and turns it into a v string pub fn cstring_to_vstring(cstr byteptr) string { slen := C.strlen(cstr) - mut s := byteptr( memdup(cstr, slen+1) ) + mut s := byteptr(memdup(cstr, slen + 1)) s[slen] = `\0` return tos(s, slen) } pub fn (s string) replace_once(rep, with string) string { - index := s.index(rep) or { return s } - return s.substr(0,index) + with + s.substr(index + rep.len, s.len) + index := s.index(rep) or { + return s + } + return s.substr(0, index) + with + s.substr(index + rep.len, s.len) } pub fn (s string) replace(rep, with string) string { @@ -160,7 +160,7 @@ pub fn (s string) replace(rep, with string) string { } // Now we know the number of replacements we need to do and we can calc the len of the new string new_len := s.len + idxs.len * (with.len - rep.len) - mut b := malloc(new_len + 1)// add a newline just in case + mut b := malloc(new_len + 1) // add a newline just in case // Fill the new string mut idx_pos := 0 mut cur_idx := idxs[idx_pos] @@ -191,7 +191,7 @@ pub fn (s string) replace(rep, with string) string { } struct RepIndex { - idx int + idx int val_idx int } @@ -199,7 +199,6 @@ fn (a mut []RepIndex) sort() { a.sort_with_compare(compare_rep_index) } - // TODO /* fn (a RepIndex) < (b RepIndex) bool { @@ -207,6 +206,7 @@ fn (a RepIndex) < (b RepIndex) bool { } */ + fn compare_rep_index(a, b &RepIndex) int { if a.idx < b.idx { return -1 @@ -232,10 +232,10 @@ pub fn (s string) replace_each(vals []string) string { mut new_len := s.len mut idxs := []RepIndex mut idx := 0 - for rep_i := 0; rep_i < vals.len; rep_i+=2 { + for rep_i := 0; rep_i < vals.len; rep_i += 2 { // vals: ['rep1, 'with1', 'rep2', 'with2'] rep := vals[rep_i] - with := vals[rep_i+1] + with := vals[rep_i + 1] for { idx = s.index_after(rep, idx) if idx == -1 { @@ -243,7 +243,8 @@ pub fn (s string) replace_each(vals []string) string { } // We need to remember both the position in the string, // and which rep/with pair it refers to. - idxs << RepIndex{idx, rep_i} + idxs << RepIndex{ + idx,rep_i} idx++ new_len += with.len - rep.len } @@ -253,7 +254,7 @@ pub fn (s string) replace_each(vals []string) string { return s } idxs.sort() - mut b := malloc(new_len + 1)// add a \0 just in case + mut b := malloc(new_len + 1) // add a \0 just in case // Fill the new string mut idx_pos := 0 mut cur_idx := idxs[idx_pos] @@ -262,7 +263,7 @@ pub fn (s string) replace_each(vals []string) string { // Reached the location of rep, replace it with "with" if i == cur_idx.idx { rep := vals[cur_idx.val_idx] - with := vals[cur_idx.val_idx+1] + with := vals[cur_idx.val_idx + 1] for j := 0; j < with.len; j++ { b[b_i] = with[j] b_i++ @@ -290,7 +291,7 @@ pub fn (s string) bool() bool { } pub fn (s string) int() int { - return int(strconv.common_parse_int(s,0,32, false, false)) + return int(strconv.common_parse_int(s, 0, 32, false, false)) } pub fn (s string) i64() i64 { @@ -298,12 +299,12 @@ pub fn (s string) i64() i64 { } pub fn (s string) f32() f32 { - //return C.atof(charptr(s.str)) + // return C.atof(charptr(s.str)) return f32(strconv.atof64(s)) } pub fn (s string) f64() f64 { - //return C.atof(charptr(s.str)) + // return C.atof(charptr(s.str)) return strconv.atof64(s) } @@ -317,7 +318,8 @@ pub fn (s string) u64() u64 { // == fn (s string) eq(a string) bool { - if isnil(s.str) { // should never happen + if isnil(s.str) { + // should never happen panic('string.eq(): nil string') } if s.len != a.len { @@ -370,7 +372,7 @@ fn (s string) ge(a string) bool { // TODO `fn (s string) + (a string)` ? To be consistent with operator overloading syntax. fn (s string) add(a string) string { new_len := a.len + s.len - mut res := string { + mut res := string{ len: new_len str: malloc(new_len + 1) } @@ -380,7 +382,7 @@ fn (s string) add(a string) string { for j := 0; j < a.len; j++ { res[s.len + j] = a[j] } - res[new_len] = `\0`// V strings are not null terminated, but just in case + res[new_len] = `\0` // V strings are not null terminated, but just in case return res } @@ -412,7 +414,9 @@ pub fn (s string) split_nth(delim string, nth int) []string { j++ } was_last := nth > 0 && res.len == nth - if was_last{break} + if was_last { + break + } last := i == s.len - 1 if is_delim || last { if !is_delim && last { @@ -427,7 +431,7 @@ pub fn (s string) split_nth(delim string, nth int) []string { } i++ } - if s.ends_with (delim) && (nth < 1 || res.len < nth) { + if s.ends_with(delim) && (nth < 1 || res.len < nth) { res << '' } return res @@ -460,6 +464,7 @@ fn (s string) left(n int) string { } return s.substr(0, n) } + // 'hello'.right(2) => 'llo' fn (s string) right(n int) string { if n >= s.len { @@ -479,8 +484,7 @@ fn (s string) substr(start, end int) string { panic('substr($start, $end) out of bounds (len=$s.len)') } len := end - start - - mut res := string { + mut res := string{ len: len str: malloc(len + 1) } @@ -488,13 +492,13 @@ fn (s string) substr(start, end int) string { res.str[i] = s.str[start + i] } res.str[len] = `\0` - -/* + /* res := string { str: s.str + start len: len } */ + return res } @@ -536,39 +540,40 @@ pub fn (s string) index(p string) ?int { // KMP search fn (s string) index_kmp(p string) int { - if p.len > s.len { - return -1 - } - mut prefix := [0].repeat(p.len) - mut j := 0 - for i := 1; i < p.len; i++ { - for p[j] != p[i] && j > 0 { - j = prefix[j - 1] - } - if p[j] == p[i] { - j++ - } - prefix[i] = j - } - j = 0 - for i := 0; i < s.len; i++ { - for p[j] != s[i] && j > 0 { - j = prefix[j - 1] - } - if p[j] == s[i] { - j++ - } - if j == p.len { - return i - p.len + 1 - } - } - return -1 + if p.len > s.len { + return -1 + } + mut prefix := [0].repeat(p.len) + mut j := 0 + for i := 1; i < p.len; i++ { + for p[j] != p[i] && j > 0 { + j = prefix[j - 1] + } + if p[j] == p[i] { + j++ + } + prefix[i] = j + } + j = 0 + for i := 0; i < s.len; i++ { + for p[j] != s[i] && j > 0 { + j = prefix[j - 1] + } + if p[j] == s[i] { + j++ + } + if j == p.len { + return i - p.len + 1 + } + } + return -1 } - pub fn (s string) index_any(chars string) int { for c in chars { - index := s.index(c.str()) or { continue } + index := s.index(c.str()) or { + continue + } return index } return -1 @@ -620,7 +625,7 @@ pub fn (s string) index_after(p string, start int) int { } pub fn (s string) index_byte(c byte) int { - for i:=0; i=0; i-- { + for i := s.len - 1; i >= 0; i-- { if s[i] == c { return i } @@ -666,7 +671,9 @@ pub fn (s string) contains(p string) bool { } pub fn (s string) starts_with(p string) bool { - idx := s.index(p) or { return false } + idx := s.index(p) or { + return false + } return idx == 0 } @@ -699,29 +706,31 @@ pub fn (s string) to_upper() string { pub fn (s string) capitalize() string { sl := s.to_lower() - cap := sl[0].str().to_upper() + sl.right(1) + cap := sl[0].str().to_upper() + sl.right(1) return cap } pub fn (s string) title() string { - words := s.split(' ') - mut tit := []string - + words := s.split(' ') + mut tit := []string for word in words { tit << word.capitalize() } title := tit.join(' ') - return title } // 'hey [man] how you doin' // find_between('[', ']') == 'man' pub fn (s string) find_between(start, end string) string { - start_pos := s.index(start) or { return '' } + start_pos := s.index(start) or { + return '' + } // First get everything to the right of 'start' val := s.right(start_pos + start.len) - end_pos := val.index(end) or { return val } + end_pos := val.index(end) or { + return val + } return val.left(end_pos) } @@ -756,8 +765,9 @@ pub fn (a []string) to_c() voidptr { } */ + pub fn (c byte) is_space() bool { - return c in [` `,`\n`,`\t`,`\v`,`\f`,`\r`] + return c in [` `, `\n`, `\t`, `\v`, `\f`, `\r`] } pub fn (s string) trim_space() string { @@ -786,7 +796,7 @@ pub fn (s string) trim(cutset string) string { return '' } } - return s.substr(pos_left, pos_right+1) + return s.substr(pos_left, pos_right + 1) } pub fn (s string) trim_left(cutset string) string { @@ -810,7 +820,7 @@ pub fn (s string) trim_right(cutset string) string { for pos >= -1 && s[pos] in cs_arr { pos-- } - return s.left(pos+1) + return s.left(pos + 1) } // fn print_cur_thread() { @@ -855,10 +865,11 @@ pub fn (s mut []string) sort_by_len() { } pub fn (s string) ustring() ustring { - mut res := ustring { + mut res := ustring{ s: s // runes will have at least s.len elements, save reallocations // TODO use VLA for small strings? + runes: new_array(0, s.len, sizeof(int)) } for i := 0; i < s.len; i++ { @@ -874,11 +885,12 @@ pub fn (s string) ustring() ustring { // It's called from functions like draw_text() where we know that the string is going to be freed // right away. Uses global buffer for storing runes []int array. __global g_ustring_runes []int + pub fn (s string) ustring_tmp() ustring { if g_ustring_runes.len == 0 { g_ustring_runes = new_array(0, 128, sizeof(int)) } - mut res := ustring { + mut res := ustring{ s: s } res.runes = g_ustring_runes @@ -922,7 +934,7 @@ fn (u ustring) ge(a ustring) bool { } fn (u ustring) add(a ustring) ustring { - mut res := ustring { + mut res := ustring{ s: u.s + a.s runes: new_array(0, u.s.len + a.s.len, sizeof(int)) } @@ -996,12 +1008,7 @@ pub fn (u ustring) substr(_start, _end int) string { if _start > _end || _start > u.len || _end > u.len || _start < 0 || _end < 0 { panic('substr($_start, $_end) out of bounds (len=$u.len)') } - end := if _end >= u.len { - u.s.len - } - else { - u.runes[_end] - } + end := if _end >= u.len { u.s.len } else { u.runes[_end] } return u.s.substr(u.runes[_start], end) } @@ -1068,7 +1075,9 @@ fn (arr []string) free() { // all_before('23:34:45.234', '.') == '23:34:45' pub fn (s string) all_before(dot string) string { - pos := s.index(dot) or { return s } + pos := s.index(dot) or { + return s + } return s.left(pos) } @@ -1131,12 +1140,12 @@ pub fn (s string) reverse() string { if s.len == 0 { return '' } - mut res := string { + mut res := string{ len: s.len str: malloc(s.len) } for i := s.len - 1; i >= 0; i-- { - res[s.len-i-1] = s[i] + res[s.len - i - 1] = s[i] } return res } @@ -1158,9 +1167,8 @@ pub fn (c byte) is_white() bool { return i == 10 || i == 32 || i == 9 || i == 13 || c == `\r` } - pub fn (s string) hash() int { - //mut h := s.hash_cache + // mut h := s.hash_cache mut h := 0 if h == 0 && s.len > 0 { for c in s { @@ -1185,11 +1193,12 @@ pub fn (s string) repeat(count int) string { return s } mut ret := malloc(s.len * count + 1) - for i in 0..count { - for j in 0..s.len { - ret[i*s.len + j] = s[j] + for i in 0 .. count { + for j in 0 .. s.len { + ret[i * s.len + j] = s[j] } } ret[s.len * count] = 0 return string(ret) } + diff --git a/vlib/builtin/utf8.v b/vlib/builtin/utf8.v index 8350384850..46cd84338e 100644 --- a/vlib/builtin/utf8.v +++ b/vlib/builtin/utf8.v @@ -1,38 +1,46 @@ // Copyright (c) 2019 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 builtin pub fn utf8_char_len(b byte) int { - return (( 0xe5000000 >> (( b >> 3 ) & 0x1e )) & 3 ) + 1 + return ((0xe5000000>>((b>>3) & 0x1e)) & 3) + 1 } // Convert utf32 to utf8 // utf32 == Codepoint pub fn utf32_to_str(code u32) string { - icode := int(code) //Prevents doing casts everywhere - mut buffer := malloc(5) - if icode <= 127 /* 0x7F */ { + icode := int(code) // Prevents doing casts everywhere + mut buffer := malloc(5) + if icode <= 127/* 0x7F */ { buffer[0] = icode return tos(buffer, 1) } - if (icode <= 2047 /* 0x7FF */) { - buffer[0] = 192 /*0xC0*/ | (icode >> 6) /* 110xxxxx */ - buffer[1] = 128 /*0x80*/ | (icode & 63 /*0x3F*/) /* 10xxxxxx */ + if (icode <= 2047/* 0x7FF */) { + buffer[0] = 192/*0xC0*/ | (icode>>6)/* 110xxxxx */ + + buffer[1] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */ + return tos(buffer, 2) } - if (icode <= 65535 /* 0xFFFF */) { - buffer[0] = 224 /*0xE0*/ | (icode >> 12) /* 1110xxxx */ - buffer[1] = 128 /*0x80*/ | ((icode >> 6) & 63 /*0x3F*/) /* 10xxxxxx */ - buffer[2] = 128 /*0x80*/ | (icode & 63 /*0x3F*/) /* 10xxxxxx */ + if (icode <= 65535/* 0xFFFF */) { + buffer[0] = 224/*0xE0*/ | (icode>>12)/* 1110xxxx */ + + buffer[1] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ + + buffer[2] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */ + return tos(buffer, 3) } - if (icode <= 1114111 /* 0x10FFFF */) { - buffer[0] = 240 /*0xF0*/ | (icode >> 18) /* 11110xxx */ - buffer[1] = 128 /*0x80*/ | ((icode >> 12) & 63 /*0x3F*/) /* 10xxxxxx */ - buffer[2] = 128 /*0x80*/ | ((icode >> 6) & 63 /*0x3F*/) /* 10xxxxxx */ - buffer[3] = 128 /*0x80*/ | (icode & 63 /*0x3F*/) /* 10xxxxxx */ + if (icode <= 1114111/* 0x10FFFF */) { + buffer[0] = 240/*0xF0*/ | (icode>>18)/* 11110xxx */ + + buffer[1] = 128/*0x80*/ | ((icode>>12) & 63/*0x3F*/)/* 10xxxxxx */ + + buffer[2] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ + + buffer[3] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */ + return tos(buffer, 4) } return '' @@ -40,28 +48,37 @@ pub fn utf32_to_str(code u32) string { // TODO copypasta pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string { - icode := int(code) //Prevents doing casts everywhere - mut buffer := byteptr(buf) - if icode <= 127 /* 0x7F */ { + icode := int(code) // Prevents doing casts everywhere + mut buffer := byteptr(buf) + if icode <= 127/* 0x7F */ { buffer[0] = icode return tos(buffer, 1) } - if (icode <= 2047 /* 0x7FF */) { - buffer[0] = 192 /*0xC0*/ | (icode >> 6) /* 110xxxxx */ - buffer[1] = 128 /*0x80*/ | (icode & 63 /*0x3F*/) /* 10xxxxxx */ + if (icode <= 2047/* 0x7FF */) { + buffer[0] = 192/*0xC0*/ | (icode>>6)/* 110xxxxx */ + + buffer[1] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */ + return tos(buffer, 2) } - if (icode <= 65535 /* 0xFFFF */) { - buffer[0] = 224 /*0xE0*/ | (icode >> 12) /* 1110xxxx */ - buffer[1] = 128 /*0x80*/ | ((icode >> 6) & 63 /*0x3F*/) /* 10xxxxxx */ - buffer[2] = 128 /*0x80*/ | (icode & 63 /*0x3F*/) /* 10xxxxxx */ + if (icode <= 65535/* 0xFFFF */) { + buffer[0] = 224/*0xE0*/ | (icode>>12)/* 1110xxxx */ + + buffer[1] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ + + buffer[2] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */ + return tos(buffer, 3) } - if (icode <= 1114111 /* 0x10FFFF */) { - buffer[0] = 240 /*0xF0*/ | (icode >> 18) /* 11110xxx */ - buffer[1] = 128 /*0x80*/ | ((icode >> 12) & 63 /*0x3F*/) /* 10xxxxxx */ - buffer[2] = 128 /*0x80*/ | ((icode >> 6) & 63 /*0x3F*/) /* 10xxxxxx */ - buffer[3] = 128 /*0x80*/ | (icode & 63 /*0x3F*/) /* 10xxxxxx */ + if (icode <= 1114111/* 0x10FFFF */) { + buffer[0] = 240/*0xF0*/ | (icode>>18)/* 11110xxx */ + + buffer[1] = 128/*0x80*/ | ((icode>>12) & 63/*0x3F*/)/* 10xxxxxx */ + + buffer[2] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */ + + buffer[3] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */ + return tos(buffer, 4) } return '' @@ -79,12 +96,12 @@ pub fn (_rune string) utf32_code() int { mut b := byte(int(_rune[0])) // TODO should be // res := int( rune[0] << rune.len) - b = b << _rune.len + b = b<<_rune.len mut res := int(b) mut shift := 6 - _rune.len for i := 1; i < _rune.len; i++ { c := int(_rune[i]) - res = res << shift + res = res<>= 4 - } else { - b += 4 - } - if ((x & 12) != 0) { //0x0C - x >>= 2 - } else { - b += 2 - } - if ((x & 2) == 0) { //0x02 - b++ - } - return b + mut b := 0 + mut x := c + if ((x & 240) != 0) { + // 0xF0 + x >>= 4 + } + else { + b += 4 + } + if ((x & 12) != 0) { + // 0x0C + x >>= 2 + } + else { + b += 2 + } + if ((x & 2) == 0) { + // 0x02 + b++ + } + return b } // Reads an utf8 character from standard input pub fn utf8_getchar() int { - c := C.getchar() - len := utf8_len(~c) - if c < 0 { - return 0 - } else if len == 0 { - return c - } else if len == 1 { - return -1 - } else { - mut uc := c & ((1 << (7 - len)) - 1) - for i := 0; i + 1 < len; i++ { - c2 := C.getchar() - if c2 != -1 && (c2 >> 6) == 2 { - uc <<= 6 - uc |= (c2 & 63) - } else if c2 == -1 { - return 0 - } else { - return -1 - } - } - return uc - } + c := C.getchar() + len := utf8_len(~c) + if c < 0 { + return 0 + } + else if len == 0 { + return c + } + else if len == 1 { + return -1 + } + else { + mut uc := c & ((1<<(7 - len)) - 1) + for i := 0; i + 1 < len; i++ { + c2 := C.getchar() + if c2 != -1 && (c2>>6) == 2 { + uc <<= 6 + uc |= (c2 & 63) + } + else if c2 == -1 { + return 0 + } + else { + return -1 + } + } + return uc + } } + diff --git a/vlib/compiler/fn.v b/vlib/compiler/fn.v index af636e595d..dbefd82587 100644 --- a/vlib/compiler/fn.v +++ b/vlib/compiler/fn.v @@ -3,8 +3,6 @@ // that can be found in the LICENSE file. module compiler - - import ( strings ) diff --git a/vlib/compiler/gen_c.v b/vlib/compiler/gen_c.v index 38ebecd82c..c312e56082 100644 --- a/vlib/compiler/gen_c.v +++ b/vlib/compiler/gen_c.v @@ -1,7 +1,6 @@ // Copyright (c) 2019 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 compiler import strings @@ -9,15 +8,16 @@ import strings const ( dot_ptr = '->' ) - // returns the type of the new variable fn (p mut Parser) gen_var_decl(name string, is_static bool) string { p.is_var_decl = true mut typ := p.bool_expression() - //mut typ, expr := p.tmp_expr() + // mut typ, expr := p.tmp_expr() p.is_var_decl = false - if typ.starts_with('...') { typ = typ[3..] } - //p.gen('/*after expr*/') + if typ.starts_with('...') { + typ = typ[3..] + } + // p.gen('/*after expr*/') // Option check ? or { or_else := p.tok == .key_orelse if or_else { @@ -26,39 +26,34 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string { gen_name := p.table.var_cgen_name(name) mut nt_gen := p.table.cgen_name_type_pair(gen_name, typ) // `foo := C.Foo{}` => `Foo foo;` - if !p.is_empty_c_struct_init && !typ.starts_with('['){ + if !p.is_empty_c_struct_init && !typ.starts_with('[') { nt_gen += '=' - } else if typ.starts_with('[') && typ[ typ.len-1 ] != `*` { + } + else if typ.starts_with('[') && typ[typ.len - 1] != `*` { // a fixed_array initializer, like `v := [1.1, 2.2]!!` // ... should translate to the following in C `f32 v[2] = {1.1, 2.2};` initializer := p.cgen.cur_line if initializer.len > 0 { - p.cgen.resetln(' = {' + initializer.all_after('{') ) - } else if initializer.len == 0 { + p.cgen.resetln(' = {' + initializer.all_after('{')) + } + else if initializer.len == 0 { p.cgen.resetln(' = { 0 }') } } - if is_static { nt_gen = 'static $nt_gen' } // Now that we know the type, prepend it // `[typ] [name] = bool_expression();` - //p.cgen.prepend_to_statement(nt_gen) + // p.cgen.prepend_to_statement(nt_gen) p.cgen.set_placeholder(0, nt_gen) return typ } fn (p mut Parser) gen_fn_decl(f Fn, typ, str_args string) { - dll_export_linkage := if p.pref.ccompiler == 'msvc' && p.attr == 'live' && p.pref.is_so { - '__declspec(dllexport) ' - } else if p.attr == 'inline' { - 'static inline ' - } else { - '' - } + dll_export_linkage := if p.pref.ccompiler == 'msvc' && p.attr == 'live' && p.pref.is_so { '__declspec(dllexport) ' } else if p.attr == 'inline' { 'static inline ' } else { '' } fn_name_cgen := p.table.fn_gen_name(f) - //str_args := f.str_args(p.table) + // str_args := f.str_args(p.table) p.genln('$dll_export_linkage$typ $fn_name_cgen ($str_args) {') } @@ -68,12 +63,12 @@ fn (p mut Parser) gen_blank_identifier_assign() { p.check_name() p.check_space(.assign) is_indexer := p.peek() == .lsbr - is_fn_call, next_expr := p.is_expr_fn_call(p.token_idx) + is_fn_call,next_expr := p.is_expr_fn_call(p.token_idx) pos := p.cgen.add_placeholder() p.is_var_decl = true typ := p.bool_expression() if typ == 'void' { - p.error_with_token_index('${next_expr}() $err_used_as_value', p.token_idx-2) + p.error_with_token_index('${next_expr}() $err_used_as_value', p.token_idx - 2) } p.is_var_decl = false if !is_indexer && !is_fn_call { @@ -82,10 +77,12 @@ fn (p mut Parser) gen_blank_identifier_assign() { // handle or if p.tok == .key_orelse { p.gen_handle_option_or_else(typ, '', pos) - } else { + } + else { if is_fn_call { p.gen(';') - } else { + } + else { p.cgen.resetln('{$typ _ = $p.cgen.cur_line;}') } } @@ -104,19 +101,20 @@ fn (p mut Parser) gen_handle_option_or_else(_typ, name string, fn_call_ph int) s or_tok_idx := p.token_idx p.check(.key_orelse) p.check(.lcbr) - p.register_var(Var { + p.register_var(Var{ name: 'err' typ: 'string' is_mut: false is_used: true }) - p.register_var(Var { + p.register_var(Var{ name: 'errcode' typ: 'int' is_mut: false is_used: true }) - if is_assign && !name.contains('.') { // don't initialize struct fields + if is_assign && !name.contains('.') { + // don't initialize struct fields p.genln('$typ $name;') } p.genln('if (!$tmp .ok) {') @@ -128,23 +126,20 @@ fn (p mut Parser) gen_handle_option_or_else(_typ, name string, fn_call_ph int) s // workaround for -g with default optional value // when p.cgen.line_directives is true an extra // line is added so we need to account for that - expr_line := if p.cgen.line_directives { - p.cgen.lines[p.cgen.lines.len-3] - } else { - p.cgen.lines[p.cgen.lines.len-2] - } + expr_line := if p.cgen.line_directives { p.cgen.lines[p.cgen.lines.len - 3] } else { p.cgen.lines[p.cgen.lines.len - 2] } last_expr := expr_line[last_ph..] - p.cgen.lines[p.cgen.lines.len-2] = '' + p.cgen.lines[p.cgen.lines.len - 2] = '' // same here if p.cgen.line_directives { - p.cgen.lines[p.cgen.lines.len-3] = '' + p.cgen.lines[p.cgen.lines.len - 3] = '' } p.genln('if ($tmp .ok) {') p.genln('$name = *($typ*) $tmp . data;') p.genln('} else {') p.genln('$name = $last_expr') p.genln('}') - } else if is_assign { + } + else if is_assign { p.genln('$name = *($typ*)${tmp}.data;') } if !p.returns && last_typ != typ && is_assign && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break { @@ -172,18 +167,18 @@ fn (p mut Parser) gen_handle_question_suffix(f Fn, ph int) string { fn types_to_c(types []Type, table &Table) string { mut sb := strings.new_builder(10) for t in types { - //if t.cat != .union_ && t.cat != .struct_ && t.cat != .objc_interface { + // if t.cat != .union_ && t.cat != .struct_ && t.cat != .objc_interface { if !(t.cat in [.union_, .struct_, .objc_interface, .interface_]) { continue } - //if is_atomic { - //sb.write('_Atomic ') - //} + // if is_atomic { + // sb.write('_Atomic ') + // } if t.cat == .objc_interface { sb.writeln('@interface $t.name : $t.parent { @public') } else { - kind := if t.cat == .union_ {'union'} else {'struct'} + kind := if t.cat == .union_ { 'union' } else { 'struct' } sb.writeln('$kind $t.name {') if t.cat == .interface_ { sb.writeln('\tvoid* _object;') @@ -192,11 +187,10 @@ fn types_to_c(types []Type, table &Table) string { } for field in t.fields { sb.write('\t') - sb.writeln(table.cgen_name_type_pair(field.name, - field.typ) + ';') + sb.writeln(table.cgen_name_type_pair(field.name, field.typ) + ';') } sb.writeln('};\n') - if t.cat == .objc_interface { + if t.cat == .objc_interface { sb.writeln('@end') } } @@ -211,7 +205,8 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) { if p.cgen.is_tmp { index_expr = p.cgen.tmp_line[fn_ph..] p.cgen.resetln(p.cgen.tmp_line[..fn_ph]) - } else { + } + else { index_expr = p.cgen.cur_line[fn_ph..] p.cgen.resetln(p.cgen.cur_line[..fn_ph]) } @@ -221,8 +216,7 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) { if cfg.is_map { p.gen('$tmp') def := type_default(typ) - p.cgen.insert_before('$typ $tmp = $def; ' + - 'bool $tmp_ok = map_get(/*$p.file_name : $p.scanner.line_nr*/$index_expr, & $tmp);') + p.cgen.insert_before('$typ $tmp = $def; ' + 'bool $tmp_ok = map_get(/*$p.file_name : $p.scanner.line_nr*/$index_expr, & $tmp);') } else if cfg.is_arr { if p.pref.translated && !p.builtin_mod { @@ -239,12 +233,13 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) { } } else if cfg.is_str && !p.builtin_mod { - if p.pref.is_bare { + if p.pref.is_bare { p.gen(index_expr) } else if cfg.is_slice { p.gen('string_substr2($index_expr)') - } else { + } + else { p.gen('string_at($index_expr)') } } @@ -255,7 +250,6 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) { // p.cgen.insert_before('if (!${tmp}.str) $tmp = tos("", 0);') p.cgen.insert_before('if (!$tmp_ok) $tmp = tos((byte *)"", 0);') } - } fn (table mut Table) fn_gen_name(f &Fn) string { @@ -265,18 +259,28 @@ fn (table mut Table) fn_gen_name(f &Fn) string { name = name.replace(' ', '') if f.name.len == 1 { match f.name[0] { - `+` { name = name.replace('+', 'op_plus') } - `-` { name = name.replace('-', 'op_minus') } - `*` { name = name.replace('*', 'op_mul') } - `/` { name = name.replace('/', 'op_div') } - `%` { name = name.replace('%', 'op_mod') } - else {} - } + `+` { + name = name.replace('+', 'op_plus') + } + `-` { + name = name.replace('-', 'op_minus') + } + `*` { + name = name.replace('*', 'op_mul') + } + `/` { + name = name.replace('/', 'op_div') + } + `%` { + name = name.replace('%', 'op_mod') + } + else { + }} } } if f.is_interface { - // iname := f.args[0].typ // Speaker - // var := p.expr_var.name + // iname := f.args[0].typ // Speaker + // var := p.expr_var.name return '' } // Avoid name conflicts (with things like abs(), print() etc). @@ -288,20 +292,7 @@ fn (table mut Table) fn_gen_name(f &Fn) string { // Obfuscate but skip certain names // TODO ugly, fix // NB: the order here is from faster to potentially slower checks - if table.obfuscate && - !f.is_c && - f.name != 'main' && f.name != 'WinMain' && f.name != 'main__main' && - f.name != 'gg__vec2' && - f.name != 'build_token_str' && - f.name != 'build_keys' && - f.mod != 'builtin' && - f.mod != 'darwin' && - f.mod != 'os' && - f.mod != 'json' && - !f.name.ends_with('_init') && - !f.name.contains('window_proc') && - !name.ends_with('_str') && - !name.contains('contains') { + if table.obfuscate && !f.is_c && f.name != 'main' && f.name != 'WinMain' && f.name != 'main__main' && f.name != 'gg__vec2' && f.name != 'build_token_str' && f.name != 'build_keys' && f.mod != 'builtin' && f.mod != 'darwin' && f.mod != 'os' && f.mod != 'json' && !f.name.ends_with('_init') && !f.name.contains('window_proc') && !name.ends_with('_str') && !name.contains('contains') { mut idx := table.obf_ids[name] // No such function yet, register it if idx == 0 { @@ -316,10 +307,8 @@ fn (table mut Table) fn_gen_name(f &Fn) string { return name } -fn (p mut Parser) gen_method_call(receiver &Var, receiver_type string, - cgen_name string, ftyp string, method_ph int) -{ - //mut cgen_name := p.table.fn_gen_name(f) +fn (p mut Parser) gen_method_call(receiver &Var, receiver_type string, cgen_name string, ftyp string, method_ph int) { + // mut cgen_name := p.table.fn_gen_name(f) mut method_call := cgen_name + ' (' // if receiver is key_mut or a ref (&), generate & for the first arg if receiver.ref || (receiver.is_mut && !receiver_type.contains('*')) { @@ -337,7 +326,8 @@ fn (p mut Parser) gen_method_call(receiver &Var, receiver_type string, // array_int => int cast = receiver_type.all_after('array_') cast = '*($cast*) ' - } else { + } + else { cast = '(voidptr) ' } } @@ -346,12 +336,12 @@ fn (p mut Parser) gen_method_call(receiver &Var, receiver_type string, fn (p mut Parser) gen_array_at(typ_ string, is_arr0 bool, fn_ph int) { mut typ := typ_ - //p.fgen('[') + // p.fgen('[') // array_int a; a[0] // type is "array_int", need "int" // typ = typ.replace('array_', '') // if is_arr0 { - // typ = typ.right(6) + // typ = typ.right(6) // } // array a; a.first() voidptr // type is "array", need "void*" @@ -372,28 +362,36 @@ fn (p mut Parser) gen_array_at(typ_ string, is_arr0 bool, fn_ph int) { fn (p mut Parser) gen_for_header(i, tmp, var_typ, val string) { p.genln('for (int $i = 0; $i < ${tmp}.len; $i++) {') - if val == '_' { return } + if val == '_' { + return + } p.genln('$var_typ $val = (($var_typ *) $tmp . data)[$i];') } fn (p mut Parser) gen_for_fixed_header(i, tmp, var_typ, val string) { p.genln('for (int $i = 0; $i < sizeof(${tmp}) / sizeof($tmp [0]); $i++) {') - if val == '_' { return } + if val == '_' { + return + } p.genln('$var_typ $val = $tmp[$i];') } fn (p mut Parser) gen_for_str_header(i, tmp, var_typ, val string) { // TODO var_typ is always byte - //p.genln('array_byte bytes_$tmp = string_bytes( $tmp );') + // p.genln('array_byte bytes_$tmp = string_bytes( $tmp );') p.genln(';\nfor (int $i = 0; $i < $tmp .len; $i ++) {') - if val == '_' { return } - //p.genln('$var_typ $val = (($var_typ *) bytes_$tmp . data)[$i];') + if val == '_' { + return + } + // p.genln('$var_typ $val = (($var_typ *) bytes_$tmp . data)[$i];') p.genln('$var_typ $val = ${tmp}.str[$i];') } fn (p mut Parser) gen_for_range_header(i, range_end, tmp, var_type, val string) { p.genln(';\nfor (int $i = $tmp; $i < $range_end; $i++) {') - if val == '_' { return } + if val == '_' { + return + } p.genln('$var_type $val = $i;') } @@ -404,13 +402,17 @@ fn (p mut Parser) gen_for_map_header(i, tmp, var_typ, val, typ string) { p.genln('string $i = ((string*)keys_$tmp .data)[l];') // TODO don't call map_get() for each key, fetch values while traversing // the tree (replace `map_keys()` above with `map_key_vals()`) - if val == '_' { return } + if val == '_' { + return + } p.genln('$var_typ $val = $def; map_get($tmp, $i, & $val);') } fn (p mut Parser) gen_for_varg_header(i, varg, var_typ, val string) { p.genln('for (int $i = 0; $i < ${varg}->len; $i++) {') - if val == '_' { return } + if val == '_' { + return + } p.genln('$var_typ $val = (($var_typ *) $varg->args)[$i];') } @@ -421,17 +423,17 @@ fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_e } if nr_elems == 0 { p.gen(' TCCSKIP(0) })') - } else { + } + else { p.gen(' })') } // Need to do this in the second pass, otherwise it goes to the very top of the out.c file if !p.first_pass() { - p.cgen.set_placeholder(new_arr_ph, - '${new_arr}($nr_elems, $nr_elems, sizeof($typ), EMPTY_ARRAY_OF_ELEMS( $typ, $nr_elems ) { ') + p.cgen.set_placeholder(new_arr_ph, '${new_arr}($nr_elems, $nr_elems, sizeof($typ), EMPTY_ARRAY_OF_ELEMS( $typ, $nr_elems ) { ') } } -fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_pos int, is_cao bool) { +fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool, fn_ph, assign_pos int, is_cao bool) { // `a[0] = 7` // curline right now: `a , 0 = 7` mut val := p.cgen.cur_line[assign_pos..] @@ -441,7 +443,8 @@ fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_po if is_map { if is_ptr { func = 'map_set(' - } else { + } + else { func = 'map_set(&' } // CAO on map is a bit more complicated as it loads @@ -463,12 +466,11 @@ fn (p mut Parser) gen_array_set(typ string, is_ptr, is_map bool,fn_ph, assign_po } p.cgen.set_placeholder(fn_ph, func) if is_cao { - val = cao_tmp + val.all_before('=') + val.all_after('=') + val = cao_tmp + val.all_before('=') + val.all_after('=') } p.gen(', & ($typ []) { $val })') } - // returns true in case of an early return fn (p mut Parser) gen_struct_init(typ string, t Type) bool { // TODO hack. If it's a C type, we may need to add "struct" before declaration: @@ -480,7 +482,7 @@ fn (p mut Parser) gen_struct_init(typ string, t Type) bool { } // TODO tm struct struct bug if typ == 'tm' { - p.cgen.lines[p.cgen.lines.len-1] = '' + p.cgen.lines[p.cgen.lines.len - 1] = '' } p.next() p.check(.lcbr) @@ -511,6 +513,7 @@ fn (p mut Parser) gen_struct_init(typ string, t Type) bool { p.check(.rcbr) return true */ + } p.gen('($t.name*)memdup(&($t.name) {') } @@ -527,7 +530,9 @@ fn (p mut Parser) gen_empty_map(typ string) { fn (p mut Parser) cast(typ string) { p.gen('(') - defer { p.gen(')') } + defer { + p.gen(')') + } p.next() pos := p.cgen.add_placeholder() if p.tok == .rpar { @@ -543,8 +548,7 @@ fn (p mut Parser) cast(typ string) { p.warn('casting `$typ` to `$expr_typ` is not needed') } // `face := FT_Face(cobj)` => `FT_Face face = *((FT_Face*)cobj);` - casting_voidptr_to_value := expr_typ == 'void*' && typ != 'int' && - typ != 'byteptr' && !typ.ends_with('*') + casting_voidptr_to_value := expr_typ == 'void*' && typ != 'int' && typ != 'byteptr' && !typ.ends_with('*') p.expected_type = '' // `string(buffer)` => `tos2(buffer)` // `string(buffer, len)` => `tos(buffer, len)` @@ -561,7 +565,8 @@ fn (p mut Parser) cast(typ string) { } p.gen(', ') p.check_types(p.expression(), 'int') - } else { + } + else { if is_bytearr { p.gen('.data') } @@ -617,30 +622,58 @@ fn type_default(typ string) string { return '{0}' } // Default values for other types are not needed because of mandatory initialization - match typ { - 'bool'{ return '0'} - 'string'{ return 'tos3("")'} - 'i8'{ return '0'} - 'i16'{ return '0'} - 'i64'{ return '0'} - 'u16'{ return '0'} - 'u32'{ return '0'} - 'u64'{ return '0'} - 'byte'{ return '0'} - 'int'{ return '0'} - 'rune'{ return '0'} - 'f32'{ return '0.0'} - 'f64'{ return '0.0'} - 'byteptr'{ return '0'} - 'voidptr'{ return '0'} -else {} - } - return '{0}' - - + match typ { + 'bool' { + return '0' + } + 'string' { + return 'tos3("")' + } + 'i8' { + return '0' + } + 'i16' { + return '0' + } + 'i64' { + return '0' + } + 'u16' { + return '0' + } + 'u32' { + return '0' + } + 'u64' { + return '0' + } + 'byte' { + return '0' + } + 'int' { + return '0' + } + 'rune' { + return '0' + } + 'f32' { + return '0.0' + } + 'f64' { + return '0.0' + } + 'byteptr' { + return '0' + } + 'voidptr' { + return '0' + } + else { + }} + return '{0}' // TODO this results in // error: expected a field designator, such as '.field = 4' - //- Empty ee= (Empty) { . = {0} } ; + // - Empty ee= (Empty) { . = {0} } ; /* return match typ { 'bool'{ '0'} @@ -661,20 +694,22 @@ else {} else { '{0} '} } */ + } fn (p mut Parser) gen_array_push(ph int, typ, expr_type, tmp, elm_type string) { // Two arrays of the same type? push_array := typ == expr_type if push_array { - p.cgen.set_placeholder(ph, '_PUSH_MANY(&' ) + p.cgen.set_placeholder(ph, '_PUSH_MANY(&') p.gen('), $tmp, $typ)') - } else { + } + else { p.check_types(expr_type, elm_type) // Pass tmp var info to the _PUSH macro // Prepend tmp initialisation and push call // Don't dereference if it's already a mutable array argument (`fn foo(mut []int)`) - push_call := if typ.contains('*'){'_PUSH('} else { '_PUSH(&'} + push_call := if typ.contains('*') { '_PUSH(' } else { '_PUSH(&' } p.cgen.set_placeholder(ph, push_call) p.gen('), $tmp, $elm_type)') } diff --git a/vlib/compiler/get_type.v b/vlib/compiler/get_type.v index eb054abe5c..e4dd53455f 100644 --- a/vlib/compiler/get_type.v +++ b/vlib/compiler/get_type.v @@ -1,22 +1,21 @@ // Copyright (c) 2019 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 compiler import ( strings ) -fn (p mut Parser) get_type2() Type{ +fn (p mut Parser) get_type2() Type { mut mul := false mut nr_muls := 0 mut typ := '' cat := TypeCategory.struct_ // multiple returns if p.tok == .lpar { - //p.warn('`()` are no longer necessary in multiple returns' + - //'\nuse `fn foo() int, int {` instead of `fn foo() (int, int) {`') + // p.warn('`()` are no longer necessary in multiple returns' + + // '\nuse `fn foo() int, int {` instead of `fn foo() (int, int) {`') // if p.inside_tuple {p.error('unexpected (')} // p.inside_tuple = true p.check(.lpar) @@ -32,7 +31,7 @@ fn (p mut Parser) get_type2() Type{ p.check(.rpar) // p.inside_tuple = false typ = p.register_multi_return_stuct(types) - return Type { + return Type{ name: typ mod: p.mod cat: cat @@ -40,7 +39,10 @@ fn (p mut Parser) get_type2() Type{ } // fn type if p.tok == .key_fn { - mut f := Fn{name: '_', mod: p.mod} + mut f := Fn{ + name: '_' + mod: p.mod + } p.next() line_nr := p.scanner.line_nr p.fn_args(mut f) @@ -58,8 +60,9 @@ fn (p mut Parser) get_type2() Type{ f.typ = 'void' } // Register anon fn type - fn_typ := Type { - name: f.typ_str()// 'fn (int, int) string' + fn_typ := Type{ + name: f.typ_str() // 'fn (int, int) string' + mod: p.mod func: f cat: .func @@ -79,8 +82,8 @@ fn (p mut Parser) get_type2() Type{ if p.tok == .number || (p.tok == .name && !p.inside_const) { if p.tok == .name { typ += '[${p.mod}__$p.lit]' - - } else { + } + else { typ += '[$p.lit]' } p.next() @@ -99,10 +102,12 @@ fn (p mut Parser) get_type2() Type{ p.error('maps only support string keys for now') } p.check(.rsbr) - val_type := p.get_type()// p.check_name() + val_type := p.get_type() // p.check_name() typ = 'map_$val_type' p.register_map(typ) - return Type{name: typ} + return Type{ + name: typ + } } // ptr/ref mut warn := false @@ -123,7 +128,8 @@ fn (p mut Parser) get_type2() Type{ ti := p.cur_fn.dispatch_of.inst if p.lit in ti.keys() { typ += ti[p.lit] - } else { + } + else { typ += p.lit } // C.Struct import @@ -153,8 +159,7 @@ fn (p mut Parser) get_type2() Type{ // "typ" not found? try "mod__typ" if t.name == '' && !p.builtin_mod { // && !p.first_pass() { - if !typ.contains('array_') && p.mod != 'main' && !typ.contains('__') && - !typ.starts_with('[') { + if !typ.contains('array_') && p.mod != 'main' && !typ.contains('__') && !typ.starts_with('[') { typ = p.prepend_mod(typ) } t = p.table.find_type(typ) @@ -164,7 +169,7 @@ fn (p mut Parser) get_type2() Type{ // for q in p.table.types { // println(q.name) // } - mut t_suggest, tc_suggest := p.table.find_misspelled_type(typ, p, 0.50) + mut t_suggest,tc_suggest := p.table.find_misspelled_type(typ, p, 0.50) if t_suggest.len > 0 { t_suggest = '. did you mean: ($tc_suggest) `$t_suggest`' } @@ -195,15 +200,14 @@ fn (p mut Parser) get_type2() Type{ typ = 'Option_$typ' p.table.register_type_with_parent(typ, 'Option') } - // Because the code uses * to see if it's a pointer if typ == 'byteptr' { typ = 'byte*' } if typ == 'voidptr' { - //if !p.builtin_mod && p.mod != 'os' && p.mod != 'gx' && p.mod != 'gg' && !p.pref.translated { - //p.error('voidptr can only be used in unsafe code') - //} + // if !p.builtin_mod && p.mod != 'os' && p.mod != 'gx' && p.mod != 'gg' && !p.pref.translated { + // p.error('voidptr can only be used in unsafe code') + // } typ = 'void*' } /* @@ -212,6 +216,10 @@ fn (p mut Parser) get_type2() Type{ p.error('2 __ in gettype(): typ="$typ"') } */ - return Type{name: typ, cat: cat} + + return Type{ + name: typ + cat: cat + } } diff --git a/vlib/compiler/vfmt.v b/vlib/compiler/vfmt.v index ca28ad9fc4..7f46640e2d 100644 --- a/vlib/compiler/vfmt.v +++ b/vlib/compiler/vfmt.v @@ -250,9 +250,9 @@ fn (p &Parser) gen_fmt() { if s == '' { return } - files := ['cgen.v', 'comptime.v', 'cc.v', 'if_match.v'] - //if !p.file_path.contains('table.v') {return} - if !(p.file_name in files) { return } + files := ['get_type.v'] + if !p.file_path.contains('vlib/builtin') {return} + //if !(p.file_name in files) { return } path := os.tmpdir() + '/' + p.file_name println('generating ${path}') mut out := os.create(path) or {