From 7778cbe9f5e512b13553940f1e73bdbe8223e0dc Mon Sep 17 00:00:00 2001 From: Enzo Date: Sat, 4 Jul 2020 23:37:41 +0200 Subject: [PATCH] all: make `os` global in scripts (#5669) --- vlib/v/builder/builder.v | 34 +++++++++++++++++++++------------- vlib/v/builder/compile.v | 37 +++++++++++++++++++++---------------- vlib/v/checker/checker.v | 13 ++++++++++--- vlib/v/parser/parser.v | 10 ++++++---- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 8d50248309..d1124437bb 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -57,14 +57,17 @@ pub fn new_builder(pref &pref.Preferences) Builder { // parse all deps from already parsed files pub fn (mut b Builder) parse_imports() { mut done_imports := []string{} + if b.pref.is_script { + done_imports << 'os' + } // NB: b.parsed_files is appended in the loop, // so we can not use the shorter `for in` form. for i := 0; i < b.parsed_files.len; i++ { ast_file := b.parsed_files[i] - for _, imp in ast_file.imports { + for imp in ast_file.imports { mod := imp.mod if mod == 'builtin' { - verror('cannot import module "$mod"') + verror('cannot import module "builtin"') break } if mod in done_imports { @@ -88,7 +91,7 @@ pub fn (mut b Builder) parse_imports() { for file in parsed_files { if file.mod.name != mod { // v.parsers[pidx].error_with_token_index('bad module definition: ${v.parsers[pidx].file_path} imports module "$mod" but $file is defined as module `$p_mod`', 1 - verror('bad module definition: ${ast_file.path} imports module "$mod" but $file.path is defined as module `$file.mod.name`') + verror('bad module definition: $ast_file.path imports module "$mod" but $file.path is defined as module `$file.mod.name`') } } b.parsed_files << parsed_files @@ -109,16 +112,14 @@ pub fn (mut b Builder) resolve_deps() { graph := b.import_graph() deps_resolved := graph.resolve() cycles := deps_resolved.display_cycles() - if cycles.len > 1 { - eprintln('warning: import cycle detected between the following modules: \n' + cycles) - // TODO: error, when v itself does not have v.table -> v.ast -> v.table cycles anymore - return - } if b.pref.is_verbose { eprintln('------ resolved dependencies graph: ------') eprintln(deps_resolved.display()) eprintln('------------------------------------------') } + if cycles.len > 1 { + verror('error: import cycle detected between the following modules: \n' + cycles) + } mut mods := []string{} for node in deps_resolved.nodes { mods << node.name @@ -148,8 +149,14 @@ pub fn (b &Builder) import_graph() &depgraph.DepGraph { mut deps := []string{} if p.mod.name !in builtins { deps << 'builtin' + if b.pref.backend == .c { + // TODO JavaScript backend doesn't handle os for now + if b.pref.is_script && p.mod.name != 'os' { + deps << 'os' + } + } } - for _, m in p.imports { + for m in p.imports { deps << m.mod } graph.add(p.mod.name, deps) @@ -200,7 +207,8 @@ pub fn (b Builder) find_module_path(mod, fpath string) ?string { vmod_file_location := mcache.get_by_file(fpath) mod_path := module_path(mod) mut module_lookup_paths := []string{} - if vmod_file_location.vmod_file.len != 0 && vmod_file_location.vmod_folder !in b.module_search_paths { + if vmod_file_location.vmod_file.len != 0 && + vmod_file_location.vmod_folder !in b.module_search_paths { module_lookup_paths << vmod_file_location.vmod_folder } module_lookup_paths << b.module_search_paths @@ -237,7 +245,7 @@ fn (b &Builder) print_warnings_and_errors() { eprintln(ferror) if err.details.len > 0 { eprintln('details: $err.details') - } + } // eprintln('') if i > b.max_nr_errors { return @@ -255,7 +263,7 @@ fn (b &Builder) print_warnings_and_errors() { eprintln(ferror) if err.details.len > 0 { eprintln('details: $err.details') - } + } // eprintln('') if i > b.max_nr_errors { return @@ -274,7 +282,7 @@ fn (b &Builder) print_warnings_and_errors() { f := stmt as ast.FnDecl if f.name == fn_name { fline := f.pos.line_nr - println('${file.path}:${fline}:') + println('$file.path:$fline:') } } } diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 006b2be190..863a1473ae 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -36,7 +36,7 @@ pub fn compile(command string, pref &pref.Preferences) { .x64 { b.compile_x64() } } if pref.is_stats { - println('compilation took: ${sw.elapsed().milliseconds()} ms') + println('compilation took: $sw.elapsed().milliseconds() ms') } // running does not require the parsers anymore b.myfree() @@ -59,9 +59,7 @@ fn (mut b Builder) run_compiled_executable_and_exit() { if b.pref.is_verbose { println('============ running $b.pref.out_name ============') } - - mut cmd := '"${b.pref.out_name}"' - + mut cmd := '"$b.pref.out_name"' if b.pref.backend == .js { cmd = 'node "${b.pref.out_name}.js"' } @@ -138,16 +136,23 @@ pub fn (v Builder) get_builtin_files() []string { // Lookup for built-in folder in lookup path. // Assumption: `builtin/` folder implies usable implementation of builtin for location in v.pref.lookup_path { - if !os.exists(os.join_path(location, 'builtin')) { - continue + if os.exists(os.join_path(location, 'builtin')) { + mut builtin_files := []string{} + if v.pref.is_bare { + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'bare')) + } else if v.pref.backend == .js { + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin', 'js')) + } else { + builtin_files << v.v_files_from_dir(os.join_path(location, 'builtin')) + } + if v.pref.backend == .c { + // TODO JavaScript backend doesn't handle os for now + if v.pref.is_script && os.exists(os.join_path(location, 'os')) { + builtin_files << v.v_files_from_dir(os.join_path(location, 'os')) + } + } + return builtin_files } - if v.pref.is_bare { - return v.v_files_from_dir(os.join_path(location, 'builtin', 'bare')) - } - if v.pref.backend == .js { - return v.v_files_from_dir(os.join_path(location, 'builtin', 'js')) - } - return v.v_files_from_dir(os.join_path(location, 'builtin')) } // Panic. We couldn't find the folder. verror('`builtin/` not included on module lookup path. @@ -159,7 +164,7 @@ pub fn (v Builder) get_user_files() []string { if v.pref.path == 'vlib/builtin' { // get_builtin_files() has already added the builtin files: return [] - } + } mut dir := v.pref.path v.log('get_v_files($dir)') // Need to store user files separately, because they have to be added after @@ -227,11 +232,11 @@ pub fn (v Builder) get_user_files() []string { // Just compile one file and get parent dir user_files << single_v_file if v.pref.is_verbose { - v.log('> just compile one file: "${single_v_file}"') + v.log('> just compile one file: "$single_v_file"') } } else { if v.pref.is_verbose { - v.log('> add all .v files from directory "${dir}" ...') + v.log('> add all .v files from directory "$dir" ...') } // Add .v files from the directory being compiled user_files << v.v_files_from_dir(dir) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 1d0256e322..54a09b4818 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1021,6 +1021,14 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { f = f1 } } + if c.pref.is_script && !found { + os_name := 'os.$fn_name' + if f1 := c.table.find_fn(os_name) { + call_expr.name = os_name + found = true + f = f1 + } + } // check for arg (var) of fn type if !found { scope := c.file.scope.innermost(call_expr.pos.pos) @@ -1181,7 +1189,6 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { return true } */ - if !c.check_types(typ, arg.typ) { // str method, allow type with str method if fn arg is string if arg_typ_sym.kind == .string && typ_sym.has_method('str') { @@ -2835,9 +2842,9 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool) // print_backtrace() // } mut details := '' - if c.error_details.len > 0 { + if c.error_details.len > 0 { details = c.error_details.join('\n') - c.error_details = [] + c.error_details = [] } if warn && !c.pref.skip_warnings { c.nr_warnings++ diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 4397c0bbc6..c0cd23783d 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -115,13 +115,15 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme global_scope: global_scope } if pref.is_vet && p.scanner.text.contains('\n ') { - source_lines := os.read_lines(path) or { []string{} } + source_lines := os.read_lines(path) or { + []string{} + } for lnumber, line in source_lines { if line.starts_with(' ') { - eprintln('${p.scanner.file_path}:${lnumber+1}: Looks like you are using spaces for indentation.') + eprintln('$p.scanner.file_path:${lnumber+1}: Looks like you are using spaces for indentation.') } } - eprintln('NB: You can run `v fmt -w file.v` to fix these automatically') + eprintln('NB: You can run `v fmt -w file.v` to fix these automatically') exit(1) } return p.parse() @@ -598,7 +600,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt { p.error_with_pos('const can only be defined at the top level (outside of functions)', p.tok.position()) } - // literals, 'if', etc. in here + // literals, 'if', etc. in here else { return p.parse_multi_expr(is_top_level) }