v: split the interpreter to cmd/tools/vinterpret.v

pull/12802/head
Delyan Angelov 2021-12-11 23:51:42 +02:00
parent adf353702e
commit 9b7a50b1a2
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
8 changed files with 111 additions and 88 deletions

View File

@ -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 {

View File

@ -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')
}

View File

@ -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 {

View File

@ -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

View File

@ -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
}
}

View File

@ -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')
}

View File

@ -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)

View File

@ -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)
}