From d38687f893a70454111bc4f01323f8b6a57e8245 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 19 Dec 2019 23:36:18 +0300 Subject: [PATCH] run vfmt on cc, cgen, comptime, if_match --- vlib/builtin/array.v | 3 + vlib/compiler/cc.v | 228 ++++++++++++++------------------- vlib/compiler/cgen.v | 264 ++++++++++++++++++++++----------------- vlib/compiler/comptime.v | 117 +++++++++-------- vlib/compiler/if_match.v | 98 +++++---------- vlib/compiler/vfmt.v | 4 +- 6 files changed, 353 insertions(+), 361 deletions(-) diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 16af0276ba..8ca220ace1 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -453,7 +453,9 @@ 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 } @@ -484,3 +486,4 @@ pub fn (a []byte) eq(a2 []byte) bool { pub fn (a []f32) eq(a2 []f32) bool { return array_eq(a, a2) } +*/ diff --git a/vlib/compiler/cc.v b/vlib/compiler/cc.v index 6463b31e1a..b9eebf0224 100644 --- a/vlib/compiler/cc.v +++ b/vlib/compiler/cc.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 ( @@ -11,12 +10,11 @@ import ( ) fn todo() { - } fn (v &V) no_cc_installed() bool { $if windows { - os.exec('$v.pref.ccompiler -v') or { + os.exec('$v.pref.ccompiler -v')or{ if v.pref.is_verbose { println('C compiler not found, trying to build with msvc...') } @@ -49,7 +47,8 @@ fn (v mut V) cc() { ret := os.system('$vexe -o $vjs_path -os js $vdir/v.v') if ret == 0 { println('Done.') - } else { + } + else { println('Failed.') exit(1) } @@ -61,9 +60,10 @@ fn (v mut V) cc() { } } } - // v.out_name_c may be on a different partition than v.out_name - os.mv_by_cp(v.out_name_c, v.out_name) or { panic(err) } + os.mv_by_cp(v.out_name_c, v.out_name)or{ + panic(err) + } exit(0) } // Cross compiling for Windows @@ -80,54 +80,47 @@ fn (v mut V) cc() { } } // arguments for the C compiler - mut a := [v.pref.cflags, '-std=gnu11', - '-Wall', - '-Wextra', - // TODO : activate -Werror once no warnings remain -// '-Werror', - // TODO : try and remove the below workaround options when the corresponding - // warnings are totally fixed/removed - '-Wno-unused-variable', - //'-Wno-unused-but-set-variable', - '-Wno-unused-parameter', - '-Wno-unused-result', - '-Wno-unused-function', - '-Wno-missing-braces', - '-Wno-unused-label'] + mut a := [v.pref.cflags, '-std=gnu11', '-Wall', '-Wextra', + // TODO : activate -Werror once no warnings remain + // '-Werror', + // TODO : try and remove the below workaround options when the corresponding + // warnings are totally fixed/removed + '-Wno-unused-variable', + // '-Wno-unused-but-set-variable', + '-Wno-unused-parameter', '-Wno-unused-result', '-Wno-unused-function', '-Wno-missing-braces', '-Wno-unused-label'] // TCC on Linux by default, unless -cc was provided // TODO if -cc = cc, TCC is still used, default compiler should be // used instead. if v.pref.fast { $if linux { - $if !android { - tcc_3rd := '$vdir/thirdparty/tcc/bin/tcc' - //println('tcc third "$tcc_3rd"') - tcc_path := '/var/tmp/tcc/bin/tcc' - if os.exists(tcc_3rd) && !os.exists(tcc_path) { - //println('moving tcc') - // if there's tcc in thirdparty/, that means this is - // a prebuilt V_linux.zip. - // Until the libtcc1.a bug is fixed, we neeed to move - // it to /var/tmp/ - os.system('mv $vdir/thirdparty/tcc /var/tmp/') + $if !android { + tcc_3rd := '$vdir/thirdparty/tcc/bin/tcc' + // println('tcc third "$tcc_3rd"') + tcc_path := '/var/tmp/tcc/bin/tcc' + if os.exists(tcc_3rd) && !os.exists(tcc_path) { + // println('moving tcc') + // if there's tcc in thirdparty/, that means this is + // a prebuilt V_linux.zip. + // Until the libtcc1.a bug is fixed, we neeed to move + // it to /var/tmp/ + os.system('mv $vdir/thirdparty/tcc /var/tmp/') + } + if v.pref.ccompiler == 'cc' && os.exists(tcc_path) { + // TODO tcc bug, needs an empty libtcc1.a fila + // os.mkdir('/var/tmp/tcc/lib/tcc/') or { panic(err) } + // os.create('/var/tmp/tcc/lib/tcc/libtcc1.a') + v.pref.ccompiler = tcc_path + a << '-m64' + } } - if v.pref.ccompiler == 'cc' && os.exists(tcc_path) { - // TODO tcc bug, needs an empty libtcc1.a fila - //os.mkdir('/var/tmp/tcc/lib/tcc/') or { panic(err) } - //os.create('/var/tmp/tcc/lib/tcc/libtcc1.a') - v.pref.ccompiler = tcc_path - a << '-m64' - } - } } $else { verror('-fast is only supported on Linux right now') } } - //linux_host := os.user_os() == 'linux' + // linux_host := os.user_os() == 'linux' v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name') - if v.pref.is_so { - a << '-shared -fPIC '// -Wl,-z,defs' + a << '-shared -fPIC ' // -Wl,-z,defs' v.out_name = v.out_name + '.so' } if v.pref.is_bare { @@ -135,39 +128,31 @@ fn (v mut V) cc() { } if v.pref.build_mode == .build_module { // Create the modules & out directory if it's not there. - mut out_dir := if v.dir.starts_with('vlib') { - '$v_modules_path${os.path_separator}cache${os.path_separator}$v.dir' - } else { - '$v_modules_path${os.path_separator}$v.dir' - } + mut out_dir := if v.dir.starts_with('vlib') { '$v_modules_path${os.path_separator}cache${os.path_separator}$v.dir' } else { '$v_modules_path${os.path_separator}$v.dir' } pdir := out_dir.all_before_last(os.path_separator) if !os.is_dir(pdir) { os.mkdir_all(pdir) } - v.out_name = '${out_dir}.o' //v.out_name + v.out_name = '${out_dir}.o' // v.out_name println('Building ${v.out_name}...') } - debug_mode := v.pref.is_debug mut debug_options := '-g' mut optimization_options := '-O2' - mut guessed_compiler := v.pref.ccompiler if guessed_compiler == 'cc' && v.pref.is_prod { // deliberately guessing only for -prod builds for performance reasons - if ccversion := os.exec('cc --version') { + if ccversion:=os.exec('cc --version'){ if ccversion.exit_code == 0 { - if ccversion.output.contains('This is free software;') - && ccversion.output.contains('Free Software Foundation, Inc.') { + if ccversion.output.contains('This is free software;') && ccversion.output.contains('Free Software Foundation, Inc.') { guessed_compiler = 'gcc' } - if ccversion.output.contains('clang version '){ + if ccversion.output.contains('clang version ') { guessed_compiler = 'clang' } } } } - if v.pref.ccompiler.contains('clang') || guessed_compiler == 'clang' { if debug_mode { debug_options = '-g -O0 -no-pie' @@ -180,57 +165,60 @@ fn (v mut V) cc() { } optimization_options = '-O3 -fno-strict-aliasing -flto' } - if debug_mode { a << debug_options } if v.pref.is_prod { a << optimization_options } - - if debug_mode && os.user_os() != 'windows'{ + if debug_mode && os.user_os() != 'windows' { a << ' -rdynamic ' // needed for nicer symbolic backtraces } - if v.pref.ccompiler != 'msvc' && v.os != .freebsd { a << '-Werror=implicit-function-declaration' } - for f in v.generate_hotcode_reloading_compiler_flags() { a << f } - - mut libs := ''// builtin.o os.o http.o etc + mut libs := '' // builtin.o os.o http.o etc if v.pref.build_mode == .build_module { a << '-c' } else if v.pref.is_cache { - builtin_o_path := filepath.join(v_modules_path, 'cache', 'vlib', 'builtin.o') + builtin_o_path := filepath.join(v_modules_path,'cache','vlib','builtin.o') a << builtin_o_path.replace('builtin.o', 'strconv.o') // TODO hack no idea why this is needed if os.exists(builtin_o_path) { libs = builtin_o_path - } else { + } + else { println('$builtin_o_path not found... building module builtin') os.system('$vexe build module vlib${os.path_separator}builtin') } for imp in v.table.imports { - if imp.contains('vweb') { continue } // not working - if imp == 'webview' { continue } - + if imp.contains('vweb') { + continue + } // not working + if imp == 'webview' { + continue + } imp_path := imp.replace('.', os.path_separator) - path := '$v_modules_path${os.path_separator}cache${os.path_separator}vlib${os.path_separator}${imp_path}.o' - //println('adding ${imp_path}.o') + path := '$v_modules_path${os.path_separator}cache${os.path_separator}vlib${os.path_separator}${imp_path}.o' + // println('adding ${imp_path}.o') if os.exists(path) { libs += ' ' + path - } else { + } + else { println('$path not found... building module $imp') if path.ends_with('vlib/ui.o') { println('copying ui...') - os.cp('$vdir/thirdparty/ui/ui.o', path) or { panic('error copying ui files') } - os.cp('$vdir/thirdparty/ui/ui.vh', v_modules_path + - '/vlib/ui.vh') or { panic('error copying ui files') } - - } else { + os.cp('$vdir/thirdparty/ui/ui.o', path)or{ + panic('error copying ui files') + } + os.cp('$vdir/thirdparty/ui/ui.vh', v_modules_path + '/vlib/ui.vh')or{ + panic('error copying ui files') + } + } + else { os.system('$vexe build module vlib${os.path_separator}$imp_path') } } @@ -259,7 +247,7 @@ fn (v mut V) cc() { // Output executable name a << '-o "$v.out_name"' if os.is_dir(v.out_name) { - verror('\'$v.out_name\' is a directory') + verror("\'$v.out_name\' is a directory") } // macOS code can include objective C TODO remove once objective C is replaced with C if v.os == .mac { @@ -275,33 +263,27 @@ fn (v mut V) cc() { a << '-mmacosx-version-min=10.7' } cflags := v.get_os_cflags() - // add .o files a << cflags.c_options_only_object_files() - // add all flags (-I -l -L etc) not .o files a << cflags.c_options_without_object_files() - a << libs // Without these libs compilation will fail on Linux // || os.user_os() == 'linux' - if !v.pref.is_bare && v.pref.build_mode != .build_module && v.os in [ .linux, .freebsd, - .openbsd, .netbsd, .dragonfly, .solaris, .haiku ] { + if !v.pref.is_bare && v.pref.build_mode != .build_module && v.os in [.linux, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .haiku] { a << '-lm -lpthread ' // -ldl is a Linux only thing. BSDs have it in libc. if v.os == .linux { a << ' -ldl ' } if v.os == .freebsd { - // FreeBSD: backtrace needs execinfo library while linking + // FreeBSD: backtrace needs execinfo library while linking a << ' -lexecinfo ' } } - if !v.pref.is_bare && v.os == .js && os.user_os() == 'linux' { a << '-lm' } - args := a.join(' ') start: todo() @@ -313,7 +295,7 @@ start: println(cmd) } ticks := time.ticks() - res := os.exec(cmd) or { + res := os.exec(cmd)or{ // C compilation failed. // If we are on Windows, try msvc println('C compilation failed.') @@ -324,6 +306,7 @@ start: return } */ + verror(err) return } @@ -337,29 +320,22 @@ start: goto start } } - - verror('C compiler error, while attempting to run: \n' + - '-----------------------------------------------------------\n' + - '$cmd\n' + - '-----------------------------------------------------------\n' + - 'Probably your C compiler is missing. \n' + - 'Please reinstall it, or make it available in your PATH.\n\n' + - missing_compiler_info()) + verror('C compiler error, while attempting to run: \n' + '-----------------------------------------------------------\n' + '$cmd\n' + '-----------------------------------------------------------\n' + 'Probably your C compiler is missing. \n' + 'Please reinstall it, or make it available in your PATH.\n\n' + missing_compiler_info()) } - if v.pref.is_debug { println(res.output) - } else { + } + else { partial_output := res.output.limit(200).trim_right('\r\n') print(partial_output) if res.output.len > partial_output.len { println('...\n(Use `v -g` to print the entire error message)\n') - }else{ + } + else { println('') } } - verror('C error. This should never happen. ' + - '\nPlease create a GitHub issue: https://github.com/vlang/v/issues/new/choose') + verror('C error. This should never happen. ' + '\nPlease create a GitHub issue: https://github.com/vlang/v/issues/new/choose') } diff := time.ticks() - ticks // Print the C command @@ -389,6 +365,7 @@ start: println('linux cross compilation done. resulting binary: "$v.out_name"') } */ + if !v.pref.is_keep_c && v.out_name_c != 'v.c' { os.rm(v.out_name_c) } @@ -409,8 +386,7 @@ start: println('install upx with `brew install upx`') } $if linux { - println('install upx\n' + - 'for example, on Debian/Ubuntu run `sudo apt install upx`') + println('install upx\n' + 'for example, on Debian/Ubuntu run `sudo apt install upx`') } $if windows { // :) @@ -419,7 +395,6 @@ start: } } - fn (c mut V) cc_windows_cross() { if !c.out_name.ends_with('.exe') { c.out_name = c.out_name + '.exe' @@ -427,28 +402,20 @@ fn (c mut V) cc_windows_cross() { mut args := '-o $c.out_name -w -L. ' cflags := c.get_os_cflags() // -I flags - args += if c.pref.ccompiler == 'msvc' { - cflags.c_options_before_target_msvc() - } else { - cflags.c_options_before_target() - } + args += if c.pref.ccompiler == 'msvc' { cflags.c_options_before_target_msvc() } else { cflags.c_options_before_target() } mut libs := '' if c.pref.build_mode == .default_mode { libs = '"$v_modules_path/vlib/builtin.o"' if !os.exists(libs) { - println('`$libs` not found') - exit(1) + println('`$libs` not found') + exit(1) } for imp in c.table.imports { - libs += ' "$v_modules_path/vlib/${imp}.o"' + libs += ' "$v_modules_path/vlib/${imp}.o"' } } args += ' $c.out_name_c ' - args += if c.pref.ccompiler == 'msvc' { - cflags.c_options_after_target_msvc() - } else { - cflags.c_options_after_target() - } + args += if c.pref.ccompiler == 'msvc' { cflags.c_options_after_target_msvc() } else { cflags.c_options_after_target() } println('Cross compiling for Windows...') winroot := '$v_modules_path/winroot' if !os.is_dir(winroot) { @@ -456,8 +423,7 @@ fn (c mut V) cc_windows_cross() { println('"$winroot" not found.') println('Download it from $winroot_url and save it in $v_modules_path') println('Unzip it afterwards.\n') - println('winroot.zip contains all library and header files needed '+ - 'to cross-compile for Windows.') + println('winroot.zip contains all library and header files needed ' + 'to cross-compile for Windows.') exit(1) } mut obj_name := c.out_name @@ -466,21 +432,18 @@ fn (c mut V) cc_windows_cross() { include := '-I $winroot/include ' cmd := 'clang -o $obj_name -w $include -m32 -c -target x86_64-win32 $v_modules_path/$c.out_name_c' if c.pref.show_c_cmd { - println(cmd) + println(cmd) } if os.system(cmd) != 0 { println('Cross compilation for Windows failed. Make sure you have clang installed.') exit(1) } if c.pref.build_mode != .build_module { - link_cmd := 'lld-link $obj_name $winroot/lib/libcmt.lib ' + - '$winroot/lib/libucrt.lib $winroot/lib/kernel32.lib $winroot/lib/libvcruntime.lib ' + - '$winroot/lib/uuid.lib' + link_cmd := 'lld-link $obj_name $winroot/lib/libcmt.lib ' + '$winroot/lib/libucrt.lib $winroot/lib/kernel32.lib $winroot/lib/libvcruntime.lib ' + '$winroot/lib/uuid.lib' if c.pref.show_c_cmd { println(link_cmd) } - - if os.system(link_cmd) != 0 { + if os.system(link_cmd) != 0 { println('Cross compilation for Windows failed. Make sure you have lld linker installed.') exit(1) } @@ -492,7 +455,7 @@ fn (c mut V) cc_windows_cross() { fn (c &V) build_thirdparty_obj_files() { for flag in c.get_os_cflags() { if flag.value.ends_with('.o') { - rest_of_module_flags := c.get_rest_of_module_cflags( flag ) + rest_of_module_flags := c.get_rest_of_module_cflags(flag) if c.pref.ccompiler == 'msvc' || c.no_cc_installed() { build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags) } @@ -506,22 +469,24 @@ fn (c &V) build_thirdparty_obj_files() { fn find_c_compiler() string { args := env_vflags_and_os_args().join(' ') defaultcc := find_c_compiler_default() - return get_arg( args, 'cc', defaultcc ) + return get_arg(args, 'cc', defaultcc) } fn find_c_compiler_default() string { - //fast_clang := '/usr/local/Cellar/llvm/8.0.0/bin/clang' - //if os.exists(fast_clang) { - // return fast_clang - //} + // fast_clang := '/usr/local/Cellar/llvm/8.0.0/bin/clang' + // if os.exists(fast_clang) { + // return fast_clang + // } // TODO fix $if after 'string' - $if windows { return 'gcc' } + $if windows { + return 'gcc' + } return 'cc' } fn find_c_compiler_thirdparty_options() string { fullargs := env_vflags_and_os_args() - mut cflags := get_cmdline_cflags( fullargs ) + mut cflags := get_cmdline_cflags(fullargs) $if !windows { cflags += ' -fPIC' } @@ -535,7 +500,7 @@ fn get_cmdline_cflags(args []string) string { mut cflags := '' for ci, cv in args { if cv == '-cflags' { - cflags += args[ci+1] + ' ' + cflags += args[ci + 1] + ' ' } } return cflags @@ -553,3 +518,4 @@ fn missing_compiler_info() string { } return '' } + diff --git a/vlib/compiler/cgen.v b/vlib/compiler/cgen.v index 541680be5c..42deff08ea 100644 --- a/vlib/compiler/cgen.v +++ b/vlib/compiler/cgen.v @@ -1,34 +1,33 @@ // 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 os import strings struct CGen { - out os.File - out_path string - //types []string - thread_fns []string - //buf strings.Builder - is_user bool + out os.File + out_path string + // types []string + thread_fns []string + // buf strings.Builder + is_user bool mut: - lines []string - lines_extra []string - typedefs []string - type_aliases []string - includes []string - thread_args []string - consts []string - const_defines []string - fns []string - so_fns []string - consts_init []string - pass Pass + lines []string + lines_extra []string + typedefs []string + type_aliases []string + includes []string + thread_args []string + consts []string + const_defines []string + fns []string + so_fns []string + consts_init []string + pass Pass nogen bool - prev_tmps []string + prev_tmps []string tmp_line string cur_line string prev_line string @@ -38,19 +37,21 @@ mut: file string line int line_directives bool - cut_pos int + cut_pos int } fn new_cgen(out_name_c string) &CGen { path := out_name_c - out := os.create(path) or { + out := os.create(path)or{ println('failed to create $path') - return &CGen{} + return &CGen{ + } } - gen := &CGen { + gen := &CGen{ out_path: path out: out - //buf: strings.new_builder(10000) + // buf: strings.new_builder(10000) + lines: make(0, 1000, sizeof(string)) } return gen @@ -118,9 +119,8 @@ fn (g mut CGen) save() { g.out.close() } - // returns expression's type, and entire expression's string representation) -fn (p mut Parser) tmp_expr() (string, string) { +fn (p mut Parser) tmp_expr() (string,string) { // former start_tmp() if p.cgen.is_tmp { p.cgen.prev_tmps << p.cgen.tmp_line @@ -130,16 +130,16 @@ fn (p mut Parser) tmp_expr() (string, string) { p.cgen.is_tmp = true // typ := p.bool_expression() - res := p.cgen.tmp_line if p.cgen.prev_tmps.len > 0 { p.cgen.tmp_line = p.cgen.prev_tmps.last() - p.cgen.prev_tmps = p.cgen.prev_tmps[0..p.cgen.prev_tmps.len-1] - } else { + p.cgen.prev_tmps = p.cgen.prev_tmps[0..p.cgen.prev_tmps.len - 1] + } + else { p.cgen.tmp_line = '' p.cgen.is_tmp = false } - return typ, res + return typ,res } fn (g &CGen) add_placeholder() int { @@ -170,10 +170,10 @@ fn (g mut CGen) set_placeholder(pos int, val string) { if g.nogen || g.pass != .main { return } - //if pos == 0 { - //g.prepend_to_statement(val) - //return - //} + // if pos == 0 { + // g.prepend_to_statement(val) + // return + // } // g.lines.set(pos, val) if g.is_tmp { left := g.tmp_line[..pos] @@ -208,9 +208,9 @@ fn (g mut CGen) register_thread_fn(wrapper_name, wrapper_text, struct_text strin fn (v &V) prof_counters() string { res := []string // Global fns - //for f in c.table.fns { - //res << 'double ${c.table.cgen_name(f)}_time;' - //} + // for f in c.table.fns { + // res << 'double ${c.table.cgen_name(f)}_time;' + // } // Methods /* for typ in c.table.types { @@ -222,16 +222,17 @@ fn (v &V) prof_counters() string { } } */ + return res.join(';\n') } fn (p &Parser) print_prof_counters() string { res := []string // Global fns - //for f in p.table.fns { - //counter := '${p.table.cgen_name(f)}_time' - //res << 'if ($counter) printf("%%f : $f.name \\n", $counter);' - //} + // for f in p.table.fns { + // counter := '${p.table.cgen_name(f)}_time' + // res << 'if ($counter) printf("%%f : $f.name \\n", $counter);' + // } // Methods /* for typ in p.table.types { @@ -246,6 +247,7 @@ fn (p &Parser) print_prof_counters() string { } } */ + return res.join(';\n') } @@ -267,7 +269,6 @@ fn (g mut CGen) add_to_main(s string) { g.fn_main = g.fn_main + s } - fn build_thirdparty_obj_file(path string, moduleflags []CFlag) { obj_path := os.realpath(path) if os.exists(obj_path) { @@ -275,11 +276,13 @@ fn build_thirdparty_obj_file(path string, moduleflags []CFlag) { } println('$obj_path not found, building it...') parent := os.dir(obj_path) - files := os.ls(parent) or { panic(err) } + files := os.ls(parent)or{ + panic(err) + } mut cfiles := '' for file in files { if file.ends_with('.c') { - cfiles += '"' + os.realpath( parent + os.path_separator + file ) + '" ' + cfiles += '"' + os.realpath(parent + os.path_separator + file) + '" ' } } cc := find_c_compiler() @@ -287,7 +290,7 @@ fn build_thirdparty_obj_file(path string, moduleflags []CFlag) { btarget := moduleflags.c_options_before_target() atarget := moduleflags.c_options_after_target() cmd := '$cc $cc_thirdparty_options $btarget -c -o "$obj_path" $cfiles $atarget ' - res := os.exec(cmd) or { + res := os.exec(cmd)or{ println('failed thirdparty object build cmd: $cmd') verror(err) return @@ -302,42 +305,82 @@ fn build_thirdparty_obj_file(path string, moduleflags []CFlag) { fn os_name_to_ifdef(name string) string { match name { - 'windows' { return '_WIN32' } - 'mac' { return '__APPLE__' } - 'macos' { return '__APPLE__' } - 'linux' { return '__linux__' } - 'freebsd' { return '__FreeBSD__' } - 'openbsd'{ return '__OpenBSD__' } - 'netbsd'{ return '__NetBSD__' } - 'dragonfly'{ return '__DragonFly__' } - 'msvc'{ return '_MSC_VER' } - 'android'{ return '__BIONIC__' } - 'js' {return '_VJS' } - 'solaris'{ return '__sun' } - 'haiku' { return '__haiku__' } - else { verror('bad os ifdef name "$name"') } - } - //verror('bad os ifdef name "$name"') + 'windows' { + return '_WIN32' + } + 'mac' { + return '__APPLE__' + } + 'macos' { + return '__APPLE__' + } + 'linux' { + return '__linux__' + } + 'freebsd' { + return '__FreeBSD__' + } + 'openbsd' { + return '__OpenBSD__' + } + 'netbsd' { + return '__NetBSD__' + } + 'dragonfly' { + return '__DragonFly__' + } + 'msvc' { + return '_MSC_VER' + } + 'android' { + return '__BIONIC__' + } + 'js' { + return '_VJS' + } + 'solaris' { + return '__sun' + } + 'haiku' { + return '__haiku__' + } + else { + verror('bad os ifdef name "$name"') + }} + // verror('bad os ifdef name "$name"') return '' } fn platform_postfix_to_ifdefguard(name string) string { s := match name { - '.v' { '' }// no guard needed - '_win.v', '_windows.v' { '#ifdef _WIN32' } - '_nix.v' { '#ifndef _WIN32' } - '_lin.v', '_linux.v' { '#ifdef __linux__' } - '_mac.v', '_darwin.v' { '#ifdef __APPLE__' } - '_bsd.v', '_freebsd.v '{ '#ifdef __FreeBSD__'} - '_solaris.v' { '#ifdef __sun' } - '_haiku.v' { '#ifdef __haiku__' } - else { - - //verror('bad platform_postfix "$name"') - // TODO + '.v'{ '' + } // no guard needed + '_win.v','_windows.v'{ + '#ifdef _WIN32' } - } + '_nix.v'{ + '#ifndef _WIN32' + } + '_lin.v','_linux.v'{ + '#ifdef __linux__' + } + '_mac.v','_darwin.v'{ + '#ifdef __APPLE__' + } + '_bsd.v','_freebsd.v '{ + '#ifdef __FreeBSD__' + } + '_solaris.v'{ + '#ifdef __sun' + } + '_haiku.v'{ + '#ifdef __haiku__' + } + else { + // verror('bad platform_postfix "$name"') + // TODO + ''}} if s == '' { verror('bad platform_postfix "$name"') } @@ -366,8 +409,7 @@ fn (v &V) type_definitions() string { // sort structs types_sorted := sort_structs(types) // Generate C code - res := types_to_c(builtin_types,v.table) + '\n//----\n' + - types_to_c(types_sorted, v.table) + res := types_to_c(builtin_types, v.table) + '\n//----\n' + types_to_c(types_sorted, v.table) return res } @@ -385,13 +427,12 @@ fn sort_structs(types []Type) []Type { mut field_deps := []string for field in t.fields { // Need to handle fixed size arrays as well (`[10]Point`) - ft := if field.typ.starts_with('[') { field.typ.all_after(']') } - else { field.typ } + ft := if field.typ.starts_with('[') { field.typ.all_after(']') } else { field.typ } // skip if not in types list or already in deps if !(ft in type_names) || ft in field_deps { continue } - field_deps << ft//field.typ + field_deps << ft // field.typ } // add type and dependant types to graph dep_graph.add(t.name, field_deps) @@ -399,10 +440,7 @@ fn sort_structs(types []Type) []Type { // sort graph dep_graph_sorted := dep_graph.resolve() if !dep_graph_sorted.acyclic { - verror('cgen.sort_structs(): the following structs form a dependency cycle:\n' + - dep_graph_sorted.display_cycles() + - '\nyou can solve this by making one or both of the dependant struct fields references, eg: field &MyStruct' + - '\nif you feel this is an error, please create a new issue here: https://github.com/vlang/v/issues and tag @joe-conigliaro') + verror('cgen.sort_structs(): the following structs form a dependency cycle:\n' + dep_graph_sorted.display_cycles() + '\nyou can solve this by making one or both of the dependant struct fields references, eg: field &MyStruct' + '\nif you feel this is an error, please create a new issue here: https://github.com/vlang/v/issues and tag @joe-conigliaro') } // sort types mut types_sorted := []Type @@ -419,35 +457,33 @@ fn sort_structs(types []Type) []Type { // Generates interface table and interface indexes fn (v &V) interface_table() string { - mut sb := strings.new_builder(100) - for _, t in v.table.typesmap { - if t.cat != .interface_ { - continue - } - mut methods := '' - sb.writeln('// NR methods = $t.gen_types.len') - for i, gen_type in t.gen_types { - methods += '{' - for j, method in t.methods { - // Cat_speak - methods += '${gen_type}_${method.name}' - if j < t.methods.len - 1 { - methods += ', ' - } - } - methods += '}, ' - // Speaker_Cat_index = 0 - sb.writeln('int _${t.name}_${gen_type}_index = $i;') - } - if t.gen_types.len > 0 { -// methods = '{TCCSKIP(0)}' -// } - sb.writeln('void* (* ${t.name}_name_table[][$t.methods.len]) = ' + -'{ $methods }; ') -} - continue - } - return sb.str() + mut sb := strings.new_builder(100) + for _, t in v.table.typesmap { + if t.cat != .interface_ { + continue + } + mut methods := '' + sb.writeln('// NR methods = $t.gen_types.len') + for i, gen_type in t.gen_types { + methods += '{' + for j, method in t.methods { + // Cat_speak + methods += '${gen_type}_${method.name}' + if j < t.methods.len - 1 { + methods += ', ' + } + } + methods += '}, ' + // Speaker_Cat_index = 0 + sb.writeln('int _${t.name}_${gen_type}_index = $i;') + } + if t.gen_types.len > 0 { + // methods = '{TCCSKIP(0)}' + // } + sb.writeln('void* (* ${t.name}_name_table[][$t.methods.len]) = ' + '{ $methods }; ') + } + continue + } + return sb.str() } - diff --git a/vlib/compiler/comptime.v b/vlib/compiler/comptime.v index df13b3c1e9..f49a49f730 100644 --- a/vlib/compiler/comptime.v +++ b/vlib/compiler/comptime.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 compiler import ( - vweb.tmpl // for `$vweb_html()` + vweb.tmpl // for `$vweb_html()` os strings ) @@ -34,10 +33,7 @@ fn (p mut Parser) comp_time() { } p.check(.lcbr) os := os_from_string(name) - if ((!not && os != p.os) || (not && os == p.os)) && - !p.scanner.is_fmt && - !p.pref.output_cross_c - { + if ((!not && os != p.os) || (not && os == p.os)) && !p.scanner.is_fmt && !p.pref.output_cross_c { // `$if os {` for a different target, skip everything inside // to avoid compilation errors (like including // on non-Windows systems) @@ -48,23 +44,25 @@ fn (p mut Parser) comp_time() { } if p.tok == .lcbr { stack++ - } else if p.tok == .rcbr { + } + else if p.tok == .rcbr { stack-- } if p.tok == .eof { break } if stack <= 0 && p.tok == .rcbr { - //p.warn('exiting $stack') + // p.warn('exiting $stack') p.next() break } p.next() } - } else { + } + else { p.statements_no_rcbr() } - if ! (p.tok == .dollar && p.peek() == .key_else) { + if !(p.tok == .dollar && p.peek() == .key_else) { p.genln('#endif') } } @@ -108,7 +106,7 @@ fn (p mut Parser) comp_time() { } if_returns := p.returns p.returns = false - //p.gen('/* returns $p.returns */') + // p.gen('/* returns $p.returns */') if p.tok == .dollar && p.peek() == .key_else { p.fspace() p.next() @@ -120,8 +118,9 @@ fn (p mut Parser) comp_time() { p.genln('#endif') else_returns := p.returns p.returns = if_returns && else_returns - //p.gen('/* returns $p.returns */') - } else if p.tok == .key_else { + // p.gen('/* returns $p.returns */') + } + else if p.tok == .key_else { p.error('use `$' + 'else` instead of `else` in comptime if statements') } } @@ -134,7 +133,7 @@ fn (p mut Parser) comp_time() { p.check(.key_in) p.check_name() p.check(.dot) - p.check_name()// fields + p.check_name() // fields p.check(.lcbr) // for p.tok != .rcbr && p.tok != .eof { res_name := p.check_name() @@ -143,9 +142,9 @@ fn (p mut Parser) comp_time() { p.check(.dollar) p.check(.name) p.check(.assign) - _, val := p.tmp_expr() - //p.bool_expression() - //val := p.cgen.end_tmp() + _,val := p.tmp_expr() + // p.bool_expression() + // val := p.cgen.end_tmp() p.check(.rcbr) // } } @@ -166,7 +165,7 @@ fn (p mut Parser) comp_time() { p.error('vweb HTML template "$path" not found') } } - p.check(.name) // skip `vweb.html()` TODO + p.check(.name) // skip `vweb.html()` TODO p.check(.dot) p.check(.name) p.check(.lpar) @@ -209,9 +208,9 @@ fn (p mut Parser) chash() { flag = flag.replace('@VPATH', p.pref.vpath) flag = flag.replace('@VLIB_PATH', p.pref.vlib_path) flag = flag.replace('@VMOD', v_modules_path) - //p.log('adding flag "$flag"') + // p.log('adding flag "$flag"') _ = p.table.parse_cflag(flag, p.mod) or { - p.error_with_token_index(err, p.cur_tok_index()-1) + p.error_with_token_index(err, p.cur_tok_index() - 1) return } } @@ -226,7 +225,7 @@ fn (p mut Parser) chash() { } */ if p.file_pcguard.len != 0 { - //println('p: $p.file_platform $p.file_pcguard') + // println('p: $p.file_platform $p.file_pcguard') p.cgen.includes << '$p.file_pcguard\n#$hash\n#endif' return } @@ -236,11 +235,13 @@ fn (p mut Parser) chash() { } // TODO remove after ui_mac.m is removed else if hash.contains('embed') { - pos := hash.index('embed') or { return } - file := hash[pos+5..] - //if p.pref.build_mode != .default_mode { - p.genln('#include $file') - //} + pos := hash.index('embed') or { + return + } + file := hash[pos + 5..] + // if p.pref.build_mode != .default_mode { + p.genln('#include $file') + // } } else if hash.contains('define') { // Move defines on top @@ -248,8 +249,8 @@ fn (p mut Parser) chash() { p.cgen.includes << '#$hash' } } - //// Don't parse a non-JS V file (`#-js` flag) - else if hash == '-js' { + // // Don't parse a non-JS V file (`#-js` flag) + else if hash == '-js' { $if js { for p.tok != .eof { p.next() @@ -262,7 +263,11 @@ fn (p mut Parser) chash() { $if !js { if !p.can_chash { println('hash="$hash"') - if hash.starts_with('include') { println("include") } else {} + if hash.starts_with('include') { + println('include') + } + else { + } p.error('bad token `#` (embedding C code is no longer supported)') } } @@ -278,7 +283,6 @@ fn (p mut Parser) comptime_method_call(typ Type) { mut j := 0 for method in typ.methods { if method.typ != 'void' { - continue } receiver := method.args[0] @@ -289,8 +293,7 @@ fn (p mut Parser) comptime_method_call(typ Type) { if j > 0 { p.gen(' else ') } - p.genln('if ( string_eq($var, _STR("$method.name")) ) ' + - '${typ.name}_$method.name ($amp $p.expr_var.name);') + p.genln('if ( string_eq($var, _STR("$method.name")) ) ' + '${typ.name}_$method.name ($amp $p.expr_var.name);') j++ } p.check(.lpar) @@ -310,7 +313,10 @@ fn (p mut Parser) gen_array_str(typ Type) { p.add_method(typ.name, Fn{ name: 'str' typ: 'string' - args: [Var{typ: typ.name, is_arg:true}] + args: [Var{ + typ: typ.name + is_arg: true + }] is_method: true is_public: true receiver_typ: typ.name @@ -320,8 +326,8 @@ fn (p mut Parser) gen_array_str(typ Type) { is_array := elm_type.starts_with('array_') if is_array { p.gen_array_str(elm_type2) - } else if p.typ_to_fmt(elm_type, 0) == '' && - !p.table.type_has_method(elm_type2, 'str') { + } + else if p.typ_to_fmt(elm_type, 0) == '' && !p.table.type_has_method(elm_type2, 'str') { p.error('cant print ${elm_type}[], unhandled print of ${elm_type}') } p.v.vgen_buf.writeln(' @@ -346,12 +352,14 @@ fn (p mut Parser) gen_struct_str(typ Type) { p.add_method(typ.name, Fn{ name: 'str' typ: 'string' - args: [Var{typ: typ.name, is_arg:true}] + args: [Var{ + typ: typ.name + is_arg: true + }] is_method: true is_public: true receiver_typ: typ.name }) - mut sb := strings.new_builder(typ.fields.len * 20) sb.writeln('pub fn (a $typ.name) str() string {\nreturn') sb.writeln("'{") @@ -373,7 +381,8 @@ fn (p mut Parser) gen_varg_str(typ Type) { is_array := elm_type.starts_with('array_') if is_array { p.gen_array_str(elm_type2) - } else if elm_type2.cat == .struct_ { + } + else if elm_type2.cat == .struct_ { p.gen_struct_str(elm_type2) } p.v.vgen_buf.writeln(' @@ -407,7 +416,7 @@ fn (p mut Parser) gen_array_filter(str_typ string, method_ph int) { } array_int b = tmp2; */ - val_type:=str_typ[6..] + val_type := str_typ[6..] p.open_scope() p.register_var(Var{ name: 'it' @@ -418,14 +427,14 @@ fn (p mut Parser) gen_array_filter(str_typ string, method_ph int) { p.cgen.resetln('') tmp := p.get_tmp() a := p.expr_var.name - p.cgen.set_placeholder(method_ph,'\n$str_typ $tmp = new_array(0, $a .len,sizeof($val_type));\n') + p.cgen.set_placeholder(method_ph, '\n$str_typ $tmp = new_array(0, $a .len,sizeof($val_type));\n') p.genln('for (int i = 0; i < ${a}.len; i++) {') p.genln('$val_type it = (($val_type*)${a}.data)[i];') p.gen('if (') p.bool_expression() p.genln(') array_push(&$tmp, &it);') - //p.genln(') array_push(&$tmp, &((($val_type*)${a}.data)[i]));') - //p.genln(') array_push(&$tmp, ${a}.data + i * ${a}.element_size);') + // p.genln(') array_push(&$tmp, &((($val_type*)${a}.data)[i]));') + // p.genln(') array_push(&$tmp, ${a}.data + i * ${a}.element_size);') p.genln('}') p.gen(tmp) // TODO why does this `gen()` work? p.check(.rpar) @@ -447,7 +456,7 @@ fn (p mut Parser) gen_array_map(str_typ string, method_ph int) string { } array_int b = tmp2; */ - val_type:=str_typ[6..] + val_type := str_typ[6..] p.open_scope() p.register_var(Var{ name: 'it' @@ -459,9 +468,8 @@ fn (p mut Parser) gen_array_map(str_typ string, method_ph int) string { tmp := p.get_tmp() tmp_elm := p.get_tmp() a := p.expr_var.name - map_type, expr := p.tmp_expr() - p.cgen.set_placeholder(method_ph,'\narray $tmp = new_array(0, $a .len, ' + - 'sizeof($map_type));\n') + map_type,expr := p.tmp_expr() + p.cgen.set_placeholder(method_ph, '\narray $tmp = new_array(0, $a .len, ' + 'sizeof($map_type));\n') p.genln('for (int i = 0; i < ${a}.len; i++) {') p.genln('$val_type it = (($val_type*)${a}.data)[i];') p.genln('_PUSH(&$tmp, $expr, $tmp_elm, $map_type)') @@ -476,7 +484,7 @@ fn (p mut Parser) comptime_if_block(name string) { p.genln('#ifdef $name') p.check(.lcbr) p.statements_no_rcbr() - if ! (p.tok == .dollar && p.peek() == .key_else) { + if !(p.tok == .dollar && p.peek() == .key_else) { p.genln('#endif') } } @@ -484,9 +492,16 @@ fn (p mut Parser) comptime_if_block(name string) { fn (p mut Parser) gen_enum_flag_methods(typ mut Type) { for method in ['set', 'clear', 'toggle', 'has'] { typ.methods << Fn{ - name: method, + name: method typ: if method == 'has' { 'bool' } else { 'void' } - args: [Var{typ: typ.name, is_mut: true, is_arg:true}, Var{typ: typ.name, is_arg: true}] + args: [Var{ + typ: typ.name + is_mut: true + is_arg: true + }, Var{ + typ: typ.name + is_arg: true + }] is_method: true is_public: true receiver_typ: typ.name @@ -496,10 +511,10 @@ fn (p mut Parser) gen_enum_flag_methods(typ mut Type) { pub fn (e mut $typ.name) set(flag $typ.name) { *e = int(*e) | (1 << int(flag)) } pub fn (e mut $typ.name) clear(flag $typ.name) { *e = int(*e) &~ (1 << int(flag)) } pub fn (e mut $typ.name) toggle(flag $typ.name) { *e = int(*e) ^ (1 << int(flag)) } -pub fn (e &$typ.name) has(flag $typ.name) bool { return int(*e)&(1 << int(flag)) != 0 }' -) +pub fn (e &$typ.name) has(flag $typ.name) bool { return int(*e)&(1 << int(flag)) != 0 }') p.cgen.fns << 'void ${typ.name}_set($typ.name *e, $typ.name flag);' p.cgen.fns << 'void ${typ.name}_clear($typ.name *e, $typ.name flag);' p.cgen.fns << 'void ${typ.name}_toggle($typ.name *e, $typ.name flag);' p.cgen.fns << 'bool ${typ.name}_has($typ.name *e, $typ.name flag);' } + diff --git a/vlib/compiler/if_match.v b/vlib/compiler/if_match.v index 253ed68a88..e5e1198d67 100644 --- a/vlib/compiler/if_match.v +++ b/vlib/compiler/if_match.v @@ -1,30 +1,28 @@ // 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 ) - // Returns type if used as expression + + fn (p mut Parser) match_statement(is_expr bool) string { p.check(.key_match) p.fspace() - typ, expr := p.tmp_expr() + typ,expr := p.tmp_expr() if typ.starts_with('array_') { p.error('arrays cannot be compared') } // is it safe to use p.cgen.insert_before ??? tmp_var := p.get_tmp() p.cgen.insert_before('$typ $tmp_var = $expr;') - p.fspace() p.check(.lcbr) mut i := 0 mut all_cases_return := true - // stores typ of resulting variable mut res_typ := '' defer { @@ -36,108 +34,89 @@ fn (p mut Parser) match_statement(is_expr bool) string { if p.tok == .arrow { p.error(warn_match_arrow) } - // unwrap match if there is only else if i == 0 { p.fspace() if is_expr { // statements are dissallowed (if match is expression) so user cant declare variables there and so on - // allow braces is else got_brace := p.tok == .lcbr if got_brace { p.fspace() p.check(.lcbr) } - p.gen('( ') - res_typ = p.bool_expression() - p.gen(' )') - // allow braces in else if got_brace { p.check(.rcbr) } - return res_typ - } else { + } + else { p.returns = false p.check(.lcbr) - p.genln('{ ') p.statements() p.returns = all_cases_return && p.returns return '' } } - if is_expr { // statements are dissallowed (if match is expression) so // user cant declare variables there and so on p.gen(':(') - // allow braces is else got_brace := p.tok == .lcbr if got_brace { p.fspace() p.check(.lcbr) } - p.check_types(p.bool_expression(), res_typ) - // allow braces in else if got_brace { p.check(.rcbr) } - - p.gen(strings.repeat(`)`, i+1)) - + p.gen(strings.repeat(`)`, i + 1)) return res_typ - } else { + } + else { p.returns = false p.genln('else // default:') - p.fspace() p.check(.lcbr) - p.genln('{ ') p.statements() - p.returns = all_cases_return && p.returns return '' } } - if i > 0 { if is_expr { p.gen(': (') - } else { + } + else { p.gen('else ') } - } else if is_expr { + } + else if is_expr { p.gen('(') } - if is_expr { p.gen('(') - } else { + } + else { p.gen('if (') } - ph := p.cgen.add_placeholder() - // Multiple checks separated by comma mut got_comma := false - for { if got_comma { p.gen(') || (') } - mut got_string := false - if typ == 'string' { got_string = true p.gen('string_eq($tmp_var, ') @@ -145,15 +124,12 @@ fn (p mut Parser) match_statement(is_expr bool) string { else { p.gen('$tmp_var == ') } - p.expected_type = typ p.check_types(p.bool_expression(), typ) p.expected_type = '' - if got_string { p.gen(')') } - if p.tok != .comma { if got_comma { p.gen(') ') @@ -165,41 +141,34 @@ fn (p mut Parser) match_statement(is_expr bool) string { got_comma = true } p.gen(')') - if p.tok == .arrow { p.error(warn_match_arrow) p.check(.arrow) } - // statements are dissallowed (if match is expression) so user cant declare variables there and so on if is_expr { p.gen('? (') - // braces are required for now p.check(.lcbr) - if i == 0 { // on the first iteration we set value of res_typ res_typ = p.bool_expression() - } else { + } + else { // later on we check that the value is of res_typ type p.check_types(p.bool_expression(), res_typ) } - // braces are required for now p.fgen_nl() p.check(.rcbr) - p.gen(')') } else { p.returns = false p.fspace() p.check(.lcbr) - p.genln('{ ') p.statements() - all_cases_return = all_cases_return && p.returns // p.gen(')') } @@ -207,20 +176,19 @@ fn (p mut Parser) match_statement(is_expr bool) string { p.fgen_nl() } p.error('match must be exhaustive') - //p.returns = false // only get here when no default, so return is not guaranteed + // p.returns = false // only get here when no default, so return is not guaranteed return '' } fn (p mut Parser) switch_statement() { - p.error('`switch` statement has been removed, use `match` instead:\n' + - 'https://vlang.io/docs#match') + p.error('`switch` statement has been removed, use `match` instead:\n' + 'https://vlang.io/docs#match') } fn (p mut Parser) if_statement(is_expr bool, elif_depth int) string { if is_expr { - //if p.fileis('if_expr') { - //println('IF EXPR') - //} + // if p.fileis('if_expr') { + // println('IF EXPR') + // } p.inside_if_expr = true p.gen('((') } @@ -241,7 +209,7 @@ fn (p mut Parser) if_statement(is_expr bool, elif_depth int) string { p.next() p.check(.decl_assign) p.is_var_decl = true - option_type, expr := p.tmp_expr()// := p.bool_expression() + option_type,expr := p.tmp_expr() // := p.bool_expression() if !option_type.starts_with('Option_') { p.error('`if x := opt() {` syntax requires a function that returns an optional value') } @@ -249,27 +217,30 @@ fn (p mut Parser) if_statement(is_expr bool, elif_depth int) string { typ := option_type[7..] // Option_User tmp = get_user(1); // if (tmp.ok) { - // User user = *(User*)tmp.data; - // [statements] + // User user = *(User*)tmp.data; + // [statements] // } p.cgen.insert_before('$option_type $option_tmp = $expr; ') p.check(.lcbr) p.genln(option_tmp + '.ok) {') p.genln('$typ $var_name = *($typ*) $option_tmp . data;') - p.register_var(Var { + p.register_var(Var{ name: var_name typ: typ is_mut: false // TODO + is_used: true // TODO - //is_alloc: p.is_alloc || typ.starts_with('array_') - //line_nr: p.tokens[ var_token_idx ].line_nr - //token_idx: var_token_idx + // is_alloc: p.is_alloc || typ.starts_with('array_') + // line_nr: p.tokens[ var_token_idx ].line_nr + // token_idx: var_token_idx + }) p.statements() p.close_scope() p.returns = false return 'void' - } else { + } + else { p.check_types(p.bool_expression(), 'bool') } if is_expr { @@ -297,7 +268,8 @@ fn (p mut Parser) if_statement(is_expr bool, elif_depth int) string { if p.tok == .key_else { if p.inside_if_expr { p.fspace() - } else { + } + else { p.fgen_nl() } p.check(.key_else) @@ -348,5 +320,3 @@ fn (p mut Parser) if_statement(is_expr bool, elif_depth int) string { return typ } - - diff --git a/vlib/compiler/vfmt.v b/vlib/compiler/vfmt.v index d00d569e96..ca28ad9fc4 100644 --- a/vlib/compiler/vfmt.v +++ b/vlib/compiler/vfmt.v @@ -250,7 +250,9 @@ fn (p &Parser) gen_fmt() { if s == '' { return } - if !p.file_path.contains('table.v') {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 } path := os.tmpdir() + '/' + p.file_name println('generating ${path}') mut out := os.create(path) or {