From 9b7a50b1a25a6371c8ed1af8352cf4c81454a55c Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sat, 11 Dec 2021 23:51:42 +0200 Subject: [PATCH] v: split the interpreter to cmd/tools/vinterpret.v --- cmd/tools/check_os_api_parity.v | 2 +- cmd/tools/vinterpret.v | 24 ++++++++++++++ cmd/v/v.v | 25 +++++++++++--- vlib/v/builder/builder.v | 2 +- vlib/v/builder/c.v | 58 ++++++++++++++++----------------- vlib/v/builder/compile.v | 44 ++++++++----------------- vlib/v/builder/js.v | 30 ++++++++--------- vlib/v/builder/native.v | 14 ++++---- 8 files changed, 111 insertions(+), 88 deletions(-) create mode 100644 cmd/tools/vinterpret.v diff --git a/cmd/tools/check_os_api_parity.v b/cmd/tools/check_os_api_parity.v index de6242ba37..95c4713691 100644 --- a/cmd/tools/check_os_api_parity.v +++ b/cmd/tools/check_os_api_parity.v @@ -98,7 +98,7 @@ fn (app App) gen_api_for_module_in_os(mod_name string, os_name string) string { tmpname := '/tmp/${mod_name}_${os_name}.c' prefs, _ := pref.parse_args([], ['-os', os_name, '-o', tmpname, '-shared', mpath]) mut b := builder.new_builder(prefs) - b.compile_c() + builder.compile_c(mut b) mut res := []string{} for f in b.parsed_files { for s in f.stmts { diff --git a/cmd/tools/vinterpret.v b/cmd/tools/vinterpret.v new file mode 100644 index 0000000000..166aa2f4a3 --- /dev/null +++ b/cmd/tools/vinterpret.v @@ -0,0 +1,24 @@ +module main + +import v.pref +import v.eval +import v.util +import v.builder + +fn main() { + mut args_and_flags := util.join_env_vflags_and_os_args()[1..].filter(it != 'interpret') + prefs, _ := pref.parse_args([], args_and_flags) + builder.compile('interpret', prefs, v_interpret) +} + +fn v_interpret(mut b builder.Builder) { + mut files := b.get_builtin_files() + files << b.get_user_files() + b.set_module_lookup_paths() + b.front_and_middle_stages(files) or { return } + + util.timing_start('INTERPRET') + mut e := eval.new_eval(b.table, b.pref) + e.eval(b.parsed_files) + util.timing_measure('INTERPRET') +} diff --git a/cmd/v/v.v b/cmd/v/v.v index 7ac6e4e0cf..9742d6f5e3 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -27,6 +27,7 @@ const ( 'doctor', 'fmt', 'gret', + 'interpret', 'repl', 'self', 'setup-freetype', @@ -61,10 +62,9 @@ fn main() { timers.show('v start') timers.start('parse_CLI_args') args := os.args[1..] - // args = 123 if args.len == 0 || args[0] in ['-', 'repl'] { - // Running `./v` without args launches repl if args.len == 0 { + // Running `./v` without args launches repl if os.is_atty(0) != 0 { cmd_exit := term.highlight_command('exit') cmd_help := term.highlight_command('v help') @@ -125,11 +125,26 @@ fn main() { } else {} } - if command in ['run', 'build', 'build-module', 'interpret'] || command.ends_with('.v') - || os.exists(command) { + if command in ['run', 'build', 'build-module'] || command.ends_with('.v') || os.exists(command) { // println('command') // println(prefs.path) - builder.compile(command, prefs) + backend_cb := match prefs.backend { + .c { + builder.FnBackend(builder.compile_c) + } + .js_node, .js_freestanding, .js_browser { + builder.compile_js + } + .native { + builder.compile_native + } + .interpret { + eprintln('use `v interpret file.v`') + exit(1) + builder.compile_c + } + } + builder.compile(command, prefs, backend_cb) return } if prefs.is_help { diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 3b3ba045e4..103a252868 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -20,7 +20,6 @@ pub: compiled_dir string // contains os.real_path() of the dir of the final file beeing compiled, or the dir itself when doing `v .` module_path string mut: - pref &pref.Preferences checker &checker.Checker transformer &transformer.Transformer out_name_c string @@ -31,6 +30,7 @@ mut: nr_warnings int // accumulated warning count of scanner, parser, checker, and builder nr_notices int // accumulated notice count of scanner, parser, checker, and builder pub mut: + pref &pref.Preferences module_search_paths []string parsed_files []&ast.File cached_msvc MsvcResult diff --git a/vlib/v/builder/c.v b/vlib/v/builder/c.v index 977fbc868c..b3f7c7bc5b 100644 --- a/vlib/v/builder/c.v +++ b/vlib/v/builder/c.v @@ -5,35 +5,7 @@ import v.pref import v.util import v.gen.c -pub fn (mut b Builder) gen_c(v_files []string) string { - b.front_and_middle_stages(v_files) or { - if err.code != 9999 { - verror(err.msg) - } - return '' - } - // TODO: move gen.cgen() to c.gen() - util.timing_start('C GEN') - res := c.gen(b.parsed_files, b.table, b.pref) - util.timing_measure('C GEN') - // println('cgen done') - // println(res) - return res -} - -pub fn (mut b Builder) build_c(v_files []string, out_file string) { - b.out_name_c = out_file - b.pref.out_name_c = os.real_path(out_file) - b.info('build_c($out_file)') - output2 := b.gen_c(v_files) - os.write_file(out_file, output2) or { panic(err) } - if b.pref.is_stats { - b.stats_lines = output2.count('\n') + 1 - b.stats_bytes = output2.len - } -} - -pub fn (mut b Builder) compile_c() { +pub fn compile_c(mut b Builder) { // cgen.genln('// Generated by V') // println('compile2()') if b.pref.is_verbose { @@ -63,3 +35,31 @@ pub fn (mut b Builder) compile_c() { b.build_c(files, out_name_c) b.cc() } + +pub fn (mut b Builder) gen_c(v_files []string) string { + b.front_and_middle_stages(v_files) or { + if err.code != 9999 { + verror(err.msg) + } + return '' + } + // TODO: move gen.cgen() to c.gen() + util.timing_start('C GEN') + res := c.gen(b.parsed_files, b.table, b.pref) + util.timing_measure('C GEN') + // println('cgen done') + // println(res) + return res +} + +pub fn (mut b Builder) build_c(v_files []string, out_file string) { + b.out_name_c = out_file + b.pref.out_name_c = os.real_path(out_file) + b.info('build_c($out_file)') + output2 := b.gen_c(v_files) + os.write_file(out_file, output2) or { panic(err) } + if b.pref.is_stats { + b.stats_lines = output2.count('\n') + 1 + b.stats_bytes = output2.len + } +} diff --git a/vlib/v/builder/compile.v b/vlib/v/builder/compile.v index 75ad25cd4a..629cc36714 100644 --- a/vlib/v/builder/compile.v +++ b/vlib/v/builder/compile.v @@ -8,20 +8,11 @@ import os import rand import v.pref import v.util -import v.eval import v.checker -fn (mut b Builder) get_vtmp_filename(base_file_name string, postfix string) string { - vtmp := util.get_vtmp_folder() - mut uniq := '' - if !b.pref.reuse_tmpc { - uniq = '.$rand.u64()' - } - fname := os.file_name(os.real_path(base_file_name)) + '$uniq$postfix' - return os.real_path(os.join_path(vtmp, fname)) -} +pub type FnBackend = fn (mut b Builder) -pub fn compile(command string, pref &pref.Preferences) { +pub fn compile(command string, pref &pref.Preferences, backend_cb FnBackend) { odir := os.dir(pref.out_name) // When pref.out_name is just the name of an executable, i.e. `./v -o executable main.v` // without a folder component, just use the current folder instead: @@ -40,12 +31,7 @@ pub fn compile(command string, pref &pref.Preferences) { // println(pref) } mut sw := time.new_stopwatch() - match pref.backend { - .c { b.compile_c() } - .js_node, .js_freestanding, .js_browser { b.compile_js() } - .native { b.compile_native() } - .interpret { b.interpret() } - } + backend_cb(mut b) mut timers := util.get_timers() timers.show_remaining() if pref.is_stats { @@ -80,6 +66,16 @@ pub fn compile(command string, pref &pref.Preferences) { } } +fn (mut b Builder) get_vtmp_filename(base_file_name string, postfix string) string { + vtmp := util.get_vtmp_folder() + mut uniq := '' + if !b.pref.reuse_tmpc { + uniq = '.$rand.u64()' + } + fname := os.file_name(os.real_path(base_file_name)) + '$uniq$postfix' + return os.real_path(os.join_path(vtmp, fname)) +} + // Temporary, will be done by -autofree [unsafe] fn (mut b Builder) myfree() { @@ -182,7 +178,7 @@ fn (mut v Builder) cleanup_run_executable_after_exit(exefile string) { // 'strings' => 'VROOT/vlib/strings' // 'installed_mod' => '~/.vmodules/installed_mod' // 'local_mod' => '/path/to/current/dir/local_mod' -fn (mut v Builder) set_module_lookup_paths() { +pub fn (mut v Builder) set_module_lookup_paths() { // Module search order: // 0) V test files are very commonly located right inside the folder of the // module, which they test. Adding the parent folder of the module folder @@ -349,15 +345,3 @@ pub fn (v &Builder) get_user_files() []string { } return user_files } - -pub fn (mut b Builder) interpret() { - mut files := b.get_builtin_files() - files << b.get_user_files() - b.set_module_lookup_paths() - b.front_and_middle_stages(files) or { return } - - util.timing_start('INTERPRET') - mut e := eval.new_eval(b.table, b.pref) - e.eval(b.parsed_files) - util.timing_measure('INTERPRET') -} diff --git a/vlib/v/builder/js.v b/vlib/v/builder/js.v index cd8df24e30..f71e115c85 100644 --- a/vlib/v/builder/js.v +++ b/vlib/v/builder/js.v @@ -5,6 +5,21 @@ import v.pref import v.util import v.gen.js +pub fn compile_js(mut b Builder) { + mut files := b.get_builtin_files() + files << b.get_user_files() + b.set_module_lookup_paths() + if b.pref.is_verbose { + println('all .v files:') + println(files) + } + mut name := b.pref.out_name + if !name.ends_with('.js') { + name += '.js' + } + b.build_js(files, name) +} + pub fn (mut b Builder) gen_js(v_files []string) string { b.front_and_middle_stages(v_files) or { return '' } util.timing_start('JS GEN') @@ -24,21 +39,6 @@ pub fn (mut b Builder) build_js(v_files []string, out_file string) { } } -pub fn (mut b Builder) compile_js() { - mut files := b.get_builtin_files() - files << b.get_user_files() - b.set_module_lookup_paths() - if b.pref.is_verbose { - println('all .v files:') - println(files) - } - mut name := b.pref.out_name - if !name.ends_with('.js') { - name += '.js' - } - b.build_js(files, name) -} - fn (mut b Builder) run_js() { cmd := 'node ' + b.pref.out_name + '.js' res := os.execute(cmd) diff --git a/vlib/v/builder/native.v b/vlib/v/builder/native.v index 8ad5d1b0b0..feaf37d582 100644 --- a/vlib/v/builder/native.v +++ b/vlib/v/builder/native.v @@ -5,6 +5,13 @@ import v.util import v.gen.native import os +pub fn compile_native(mut b Builder) { + // v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare')) + files := [b.pref.path] + b.set_module_lookup_paths() + b.build_native(files, b.pref.out_name) +} + pub fn (mut b Builder) build_native(v_files []string, out_file string) { if b.pref.os == .windows { eprintln('Warning: v -native is experimental for Windows') @@ -28,10 +35,3 @@ pub fn (mut b Builder) build_native(v_files []string, out_file string) { b.stats_lines, b.stats_bytes = native.gen(b.parsed_files, b.table, out_file, b.pref) util.timing_measure('Native GEN') } - -pub fn (mut b Builder) compile_native() { - // v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare')) - files := [b.pref.path] - b.set_module_lookup_paths() - b.build_native(files, b.pref.out_name) -}