all: make `os` global in scripts (#5669)

pull/5674/head
Enzo 2020-07-04 23:37:41 +02:00 committed by GitHub
parent 11866fb017
commit 7778cbe9f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 36 deletions

View File

@ -57,14 +57,17 @@ pub fn new_builder(pref &pref.Preferences) Builder {
// parse all deps from already parsed files // parse all deps from already parsed files
pub fn (mut b Builder) parse_imports() { pub fn (mut b Builder) parse_imports() {
mut done_imports := []string{} mut done_imports := []string{}
if b.pref.is_script {
done_imports << 'os'
}
// NB: b.parsed_files is appended in the loop, // NB: b.parsed_files is appended in the loop,
// so we can not use the shorter `for in` form. // so we can not use the shorter `for in` form.
for i := 0; i < b.parsed_files.len; i++ { for i := 0; i < b.parsed_files.len; i++ {
ast_file := b.parsed_files[i] ast_file := b.parsed_files[i]
for _, imp in ast_file.imports { for imp in ast_file.imports {
mod := imp.mod mod := imp.mod
if mod == 'builtin' { if mod == 'builtin' {
verror('cannot import module "$mod"') verror('cannot import module "builtin"')
break break
} }
if mod in done_imports { if mod in done_imports {
@ -88,7 +91,7 @@ pub fn (mut b Builder) parse_imports() {
for file in parsed_files { for file in parsed_files {
if file.mod.name != mod { 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 // 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 b.parsed_files << parsed_files
@ -109,16 +112,14 @@ pub fn (mut b Builder) resolve_deps() {
graph := b.import_graph() graph := b.import_graph()
deps_resolved := graph.resolve() deps_resolved := graph.resolve()
cycles := deps_resolved.display_cycles() 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 { if b.pref.is_verbose {
eprintln('------ resolved dependencies graph: ------') eprintln('------ resolved dependencies graph: ------')
eprintln(deps_resolved.display()) eprintln(deps_resolved.display())
eprintln('------------------------------------------') eprintln('------------------------------------------')
} }
if cycles.len > 1 {
verror('error: import cycle detected between the following modules: \n' + cycles)
}
mut mods := []string{} mut mods := []string{}
for node in deps_resolved.nodes { for node in deps_resolved.nodes {
mods << node.name mods << node.name
@ -148,8 +149,14 @@ pub fn (b &Builder) import_graph() &depgraph.DepGraph {
mut deps := []string{} mut deps := []string{}
if p.mod.name !in builtins { if p.mod.name !in builtins {
deps << 'builtin' 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 deps << m.mod
} }
graph.add(p.mod.name, deps) 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) vmod_file_location := mcache.get_by_file(fpath)
mod_path := module_path(mod) mod_path := module_path(mod)
mut module_lookup_paths := []string{} 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 << vmod_file_location.vmod_folder
} }
module_lookup_paths << b.module_search_paths module_lookup_paths << b.module_search_paths
@ -274,7 +282,7 @@ fn (b &Builder) print_warnings_and_errors() {
f := stmt as ast.FnDecl f := stmt as ast.FnDecl
if f.name == fn_name { if f.name == fn_name {
fline := f.pos.line_nr fline := f.pos.line_nr
println('${file.path}:${fline}:') println('$file.path:$fline:')
} }
} }
} }

View File

@ -36,7 +36,7 @@ pub fn compile(command string, pref &pref.Preferences) {
.x64 { b.compile_x64() } .x64 { b.compile_x64() }
} }
if pref.is_stats { 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 // running does not require the parsers anymore
b.myfree() b.myfree()
@ -59,9 +59,7 @@ fn (mut b Builder) run_compiled_executable_and_exit() {
if b.pref.is_verbose { if b.pref.is_verbose {
println('============ running $b.pref.out_name ============') println('============ running $b.pref.out_name ============')
} }
mut cmd := '"$b.pref.out_name"'
mut cmd := '"${b.pref.out_name}"'
if b.pref.backend == .js { if b.pref.backend == .js {
cmd = 'node "${b.pref.out_name}.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. // Lookup for built-in folder in lookup path.
// Assumption: `builtin/` folder implies usable implementation of builtin // Assumption: `builtin/` folder implies usable implementation of builtin
for location in v.pref.lookup_path { for location in v.pref.lookup_path {
if !os.exists(os.join_path(location, 'builtin')) { if os.exists(os.join_path(location, 'builtin')) {
continue 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. // Panic. We couldn't find the folder.
verror('`builtin/` not included on module lookup path. verror('`builtin/` not included on module lookup path.
@ -227,11 +232,11 @@ pub fn (v Builder) get_user_files() []string {
// Just compile one file and get parent dir // Just compile one file and get parent dir
user_files << single_v_file user_files << single_v_file
if v.pref.is_verbose { if v.pref.is_verbose {
v.log('> just compile one file: "${single_v_file}"') v.log('> just compile one file: "$single_v_file"')
} }
} else { } else {
if v.pref.is_verbose { 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 // Add .v files from the directory being compiled
user_files << v.v_files_from_dir(dir) user_files << v.v_files_from_dir(dir)

View File

@ -1021,6 +1021,14 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
f = f1 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 // check for arg (var) of fn type
if !found { if !found {
scope := c.file.scope.innermost(call_expr.pos.pos) 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 return true
} }
*/ */
if !c.check_types(typ, arg.typ) { if !c.check_types(typ, arg.typ) {
// str method, allow type with str method if fn arg is string // str method, allow type with str method if fn arg is string
if arg_typ_sym.kind == .string && typ_sym.has_method('str') { if arg_typ_sym.kind == .string && typ_sym.has_method('str') {

View File

@ -115,10 +115,12 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme
global_scope: global_scope global_scope: global_scope
} }
if pref.is_vet && p.scanner.text.contains('\n ') { 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 { for lnumber, line in source_lines {
if line.starts_with(' ') { 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')
@ -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.error_with_pos('const can only be defined at the top level (outside of functions)',
p.tok.position()) p.tok.position())
} }
// literals, 'if', etc. in here // literals, 'if', etc. in here
else { else {
return p.parse_multi_expr(is_top_level) return p.parse_multi_expr(is_top_level)
} }