v2: remove duplication & slight cleanup. share prefs with v1
parent
f1f8a2e4dd
commit
21b6dace8f
|
@ -7,7 +7,7 @@ import (
|
||||||
os
|
os
|
||||||
strings
|
strings
|
||||||
filepath
|
filepath
|
||||||
v.builder
|
v.pref
|
||||||
//compiler.x64
|
//compiler.x64
|
||||||
time
|
time
|
||||||
)
|
)
|
||||||
|
@ -21,7 +21,7 @@ struct Parser {
|
||||||
// the #include directives in the parsed .v file
|
// the #include directives in the parsed .v file
|
||||||
file_pcguard string
|
file_pcguard string
|
||||||
v &V
|
v &V
|
||||||
pref &Preferences // Preferences shared from V struct
|
pref &pref.Preferences // Preferences shared from V struct
|
||||||
mut:
|
mut:
|
||||||
scanner &Scanner
|
scanner &Scanner
|
||||||
tokens []Token
|
tokens []Token
|
||||||
|
@ -36,7 +36,7 @@ mut:
|
||||||
table &Table
|
table &Table
|
||||||
import_table ImportTable // Holds imports for just the file being parsed
|
import_table ImportTable // Holds imports for just the file being parsed
|
||||||
pass Pass
|
pass Pass
|
||||||
os builder.OS
|
os pref.OS
|
||||||
inside_const bool
|
inside_const bool
|
||||||
expr_var Var
|
expr_var Var
|
||||||
has_immutable_field bool
|
has_immutable_field bool
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
os.cmdline
|
os.cmdline
|
||||||
strings
|
strings
|
||||||
filepath
|
filepath
|
||||||
|
v.pref
|
||||||
v.builder
|
v.builder
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,15 +16,6 @@ pub const (
|
||||||
Version = '0.1.25'
|
Version = '0.1.25'
|
||||||
)
|
)
|
||||||
|
|
||||||
enum BuildMode {
|
|
||||||
// `v program.v'
|
|
||||||
// Build user code only, and add pre-compiled vlib (`cc program.o builtin.o os.o...`)
|
|
||||||
default_mode
|
|
||||||
// `v -lib ~/v/os`
|
|
||||||
// build any module (generate os.o + os.vh)
|
|
||||||
build_module
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
supported_platforms = ['windows', 'mac', 'macos', 'linux', 'freebsd', 'openbsd', 'netbsd',
|
supported_platforms = ['windows', 'mac', 'macos', 'linux', 'freebsd', 'openbsd', 'netbsd',
|
||||||
'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
|
'dragonfly', 'android', 'js', 'solaris', 'haiku', 'linux_or_macos']
|
||||||
|
@ -45,7 +37,7 @@ enum Pass {
|
||||||
|
|
||||||
struct V {
|
struct V {
|
||||||
pub mut:
|
pub mut:
|
||||||
os builder.OS // the OS to build for
|
os pref.OS // the OS to build for
|
||||||
out_name_c string // name of the temporary C file
|
out_name_c string // name of the temporary C file
|
||||||
files []string // all V files that need to be parsed and compiled
|
files []string // all V files that need to be parsed and compiled
|
||||||
dir string // directory (or file) being compiled (TODO rename to path?)
|
dir string // directory (or file) being compiled (TODO rename to path?)
|
||||||
|
@ -53,7 +45,7 @@ pub mut:
|
||||||
table &Table // table with types, vars, functions etc
|
table &Table // table with types, vars, functions etc
|
||||||
cgen &CGen // C code generator
|
cgen &CGen // C code generator
|
||||||
//x64 &x64.Gen
|
//x64 &x64.Gen
|
||||||
pref &Preferences // all the preferences and settings extracted to a struct for reusability
|
pref &pref.Preferences // all the preferences and settings extracted to a struct for reusability
|
||||||
lang_dir string // "~/code/v"
|
lang_dir string // "~/code/v"
|
||||||
out_name string // "program.exe"
|
out_name string // "program.exe"
|
||||||
vroot string
|
vroot string
|
||||||
|
@ -74,59 +66,6 @@ pub mut:
|
||||||
v_fmt_file_result string // >> file with formatted output generated by vlib/compiler/vfmt.v
|
v_fmt_file_result string // >> file with formatted output generated by vlib/compiler/vfmt.v
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Preferences {
|
|
||||||
pub mut:
|
|
||||||
build_mode BuildMode
|
|
||||||
// nofmt bool // disable vfmt
|
|
||||||
is_test bool // `v test string_test.v`
|
|
||||||
is_script bool // single file mode (`v program.v`), main function can be skipped
|
|
||||||
is_live bool // main program that contains live/hot code
|
|
||||||
is_solive bool // a shared library, that will be used in a -live main program
|
|
||||||
is_so bool // an ordinary shared library, -shared, no matter if it is live or not
|
|
||||||
is_prof bool // benchmark every function
|
|
||||||
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
|
|
||||||
is_prod bool // use "-O2"
|
|
||||||
is_verbose bool // print extra information with `v.log()`
|
|
||||||
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
|
|
||||||
is_repl bool
|
|
||||||
is_run bool
|
|
||||||
show_c_cmd bool // `v -show_c_cmd` prints the C command to build program.v.c
|
|
||||||
sanitize bool // use Clang's new "-fsanitize" option
|
|
||||||
is_debug bool // false by default, turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
|
|
||||||
is_vlines bool // turned on by -g, false by default (it slows down .tmp.c generation slightly).
|
|
||||||
is_keep_c bool // -keep_c , tell v to leave the generated .tmp.c alone (since by default v will delete them after c backend finishes)
|
|
||||||
// NB: passing -cg instead of -g will set is_vlines to false and is_g to true, thus making v generate cleaner C files,
|
|
||||||
// which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks).
|
|
||||||
is_pretty_c bool // -pretty_c , tell v to run clang-format -i over the produced C file, before it is compiled. Use with -keep_c or with -o x.c .
|
|
||||||
is_cache bool // turns on v usage of the module cache to speed up compilation.
|
|
||||||
is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
|
|
||||||
no_auto_free bool // `v -nofree` disable automatic `free()` insertion for better performance in some applications (e.g. compilers)
|
|
||||||
cflags string // Additional options which will be passed to the C compiler.
|
|
||||||
// For example, passing -cflags -Os will cause the C compiler to optimize the generated binaries for size.
|
|
||||||
// You could pass several -cflags XXX arguments. They will be merged with each other.
|
|
||||||
// You can also quote several options at the same time: -cflags '-Os -fno-inline-small-functions'.
|
|
||||||
ccompiler string // the name of the used C compiler
|
|
||||||
building_v bool
|
|
||||||
autofree bool
|
|
||||||
compress bool
|
|
||||||
// skip_builtin bool // Skips re-compilation of the builtin module
|
|
||||||
// to increase compilation time.
|
|
||||||
// This is on by default, since a vast majority of users do not
|
|
||||||
// work on the builtin module itself.
|
|
||||||
// generating_vh bool
|
|
||||||
fast bool // use tcc/x64 codegen
|
|
||||||
enable_globals bool // allow __global for low level code
|
|
||||||
// is_fmt bool
|
|
||||||
is_bare bool
|
|
||||||
user_mod_path string // `v -user_mod_path /Users/user/modules` adds a new lookup path for imported modules
|
|
||||||
vlib_path string
|
|
||||||
vpath string
|
|
||||||
x64 bool
|
|
||||||
output_cross_c bool
|
|
||||||
prealloc bool
|
|
||||||
v2 bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Should be called by main at the end of the compilation process, to cleanup
|
// Should be called by main at the end of the compilation process, to cleanup
|
||||||
pub fn (v &V) finalize_compilation() {
|
pub fn (v &V) finalize_compilation() {
|
||||||
// TODO remove
|
// TODO remove
|
||||||
|
@ -379,7 +318,7 @@ pub fn (v mut V) compile2() {
|
||||||
println('all .v files:')
|
println('all .v files:')
|
||||||
println(v.files)
|
println(v.files)
|
||||||
}
|
}
|
||||||
mut b := builder.new_builder(v.v2_prefs())
|
mut b := v.new_v2()
|
||||||
b.build_c(v.files, v.out_name)
|
b.build_c(v.files, v.out_name)
|
||||||
v.cc()
|
v.cc()
|
||||||
}
|
}
|
||||||
|
@ -391,23 +330,22 @@ pub fn (v mut V) compile_x64() {
|
||||||
}
|
}
|
||||||
//v.files << v.v_files_from_dir(filepath.join(v.pref.vlib_path,'builtin','bare'))
|
//v.files << v.v_files_from_dir(filepath.join(v.pref.vlib_path,'builtin','bare'))
|
||||||
v.files << v.dir
|
v.files << v.dir
|
||||||
mut b := builder.new_builder(v.v2_prefs())
|
v.set_module_lookup_paths()
|
||||||
|
mut b := v.new_v2()
|
||||||
// move all this logic to v2
|
// move all this logic to v2
|
||||||
b.build_x64(v.files, v.out_name)
|
b.build_x64(v.files, v.out_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make v2 prefs from v1
|
// make v2 from v1
|
||||||
fn (v &V) v2_prefs() builder.Preferences {
|
fn (v &V) new_v2() builder.Builder {
|
||||||
return builder.Preferences{
|
mut b := builder.new_builder(v.pref)
|
||||||
os: v.os
|
b = { b|
|
||||||
vpath: v.pref.vpath
|
os: v.os,
|
||||||
vlib_path: v.pref.vlib_path
|
module_path: v_modules_path,
|
||||||
mod_path: v_modules_path
|
compiled_dir: v.compiled_dir,
|
||||||
compile_dir: v.compiled_dir
|
module_search_paths: v.module_lookup_paths
|
||||||
user_mod_path: v.pref.user_mod_path
|
|
||||||
is_test: v.pref.is_test
|
|
||||||
is_verbose: v.pref.is_verbose,
|
|
||||||
}
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (v mut V) generate_init() {
|
fn (v mut V) generate_init() {
|
||||||
|
@ -956,7 +894,7 @@ pub fn new_v(args []string) &V {
|
||||||
}
|
}
|
||||||
|
|
||||||
// build mode
|
// build mode
|
||||||
mut build_mode := BuildMode.default_mode
|
mut build_mode := pref.BuildMode.default_mode
|
||||||
mut mod := ''
|
mut mod := ''
|
||||||
joined_args := args.join(' ')
|
joined_args := args.join(' ')
|
||||||
if joined_args.contains('build module ') {
|
if joined_args.contains('build module ') {
|
||||||
|
@ -1014,7 +952,7 @@ pub fn new_v(args []string) &V {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut _os := builder.OS.mac
|
mut _os := pref.OS.mac
|
||||||
// No OS specifed? Use current system
|
// No OS specifed? Use current system
|
||||||
if target_os == '' {
|
if target_os == '' {
|
||||||
$if linux {
|
$if linux {
|
||||||
|
@ -1078,7 +1016,7 @@ pub fn new_v(args []string) &V {
|
||||||
}
|
}
|
||||||
obfuscate := '-obf' in args
|
obfuscate := '-obf' in args
|
||||||
is_repl := '-repl' in args
|
is_repl := '-repl' in args
|
||||||
pref := &Preferences{
|
pref := &pref.Preferences{
|
||||||
is_test: is_test
|
is_test: is_test
|
||||||
is_script: is_script
|
is_script: is_script
|
||||||
is_so: '-shared' in args
|
is_so: '-shared' in args
|
||||||
|
@ -1225,7 +1163,7 @@ pub fn cescaped_path(s string) string {
|
||||||
return s.replace('\\', '\\\\')
|
return s.replace('\\', '\\\\')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn os_from_string(os string) builder.OS {
|
pub fn os_from_string(os string) pref.OS {
|
||||||
match os {
|
match os {
|
||||||
'linux' {
|
'linux' {
|
||||||
return .linux
|
return .linux
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
filepath
|
filepath
|
||||||
v.ast
|
v.ast
|
||||||
v.table
|
v.table
|
||||||
|
v.pref
|
||||||
v.checker
|
v.checker
|
||||||
v.parser
|
v.parser
|
||||||
v.gen
|
v.gen
|
||||||
|
@ -14,22 +15,24 @@ import (
|
||||||
|
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
pub:
|
pub:
|
||||||
table &table.Table
|
pref &pref.Preferences
|
||||||
checker checker.Checker
|
table &table.Table
|
||||||
|
checker checker.Checker
|
||||||
|
os pref.OS // the OS to build for
|
||||||
|
compiled_dir string // contains os.realpath() of the dir of the final file beeing compiled, or the dir itself when doing `v .`
|
||||||
|
module_path string
|
||||||
|
module_search_paths []string
|
||||||
mut:
|
mut:
|
||||||
prefs Preferences
|
parsed_files []ast.File
|
||||||
parsed_files []ast.File
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_builder(prefs Preferences) Builder {
|
pub fn new_builder(pref &pref.Preferences) Builder {
|
||||||
table := table.new_table()
|
table := table.new_table()
|
||||||
mut b:= Builder{
|
return Builder{
|
||||||
prefs: prefs
|
pref: pref
|
||||||
table: table
|
table: table
|
||||||
checker: checker.new_checker(table)
|
checker: checker.new_checker(table)
|
||||||
}
|
}
|
||||||
b.set_module_search_paths()
|
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (b mut Builder) gen_c(v_files []string) string {
|
pub fn (b mut Builder) gen_c(v_files []string) string {
|
||||||
|
@ -54,11 +57,6 @@ pub fn (b mut Builder) build_x64(v_files []string, out_file string) {
|
||||||
println('x64 GEN: ${time.ticks() - ticks}ms')
|
println('x64 GEN: ${time.ticks() - ticks}ms')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn (b &Builder) parse_module_files() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse all deps from already parsed files
|
// parse all deps from already parsed files
|
||||||
pub fn (b mut Builder) parse_imports() {
|
pub fn (b mut Builder) parse_imports() {
|
||||||
mut done_imports := []string
|
mut done_imports := []string
|
||||||
|
@ -108,7 +106,7 @@ pub fn (b &Builder) v_files_from_dir(dir string) []string {
|
||||||
mut files := os.ls(dir)or{
|
mut files := os.ls(dir)or{
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if b.prefs.is_verbose {
|
if b.pref.is_verbose {
|
||||||
println('v_files_from_dir ("$dir")')
|
println('v_files_from_dir ("$dir")')
|
||||||
}
|
}
|
||||||
files.sort()
|
files.sort()
|
||||||
|
@ -119,22 +117,22 @@ pub fn (b &Builder) v_files_from_dir(dir string) []string {
|
||||||
if file.ends_with('_test.v') {
|
if file.ends_with('_test.v') {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (file.ends_with('_win.v') || file.ends_with('_windows.v')) && b.prefs.os != .windows {
|
if (file.ends_with('_win.v') || file.ends_with('_windows.v')) && b.os != .windows {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (file.ends_with('_lin.v') || file.ends_with('_linux.v')) && b.prefs.os != .linux {
|
if (file.ends_with('_lin.v') || file.ends_with('_linux.v')) && b.os != .linux {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (file.ends_with('_mac.v') || file.ends_with('_darwin.v')) && b.prefs.os != .mac {
|
if (file.ends_with('_mac.v') || file.ends_with('_darwin.v')) && b.os != .mac {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if file.ends_with('_nix.v') && b.prefs.os == .windows {
|
if file.ends_with('_nix.v') && b.os == .windows {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if file.ends_with('_js.v') && b.prefs.os != .js {
|
if file.ends_with('_js.v') && b.os != .js {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if file.ends_with('_c.v') && b.prefs.os == .js {
|
if file.ends_with('_c.v') && b.os == .js {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -162,7 +160,7 @@ fn verror(err string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (b &Builder) log(s string) {
|
pub fn (b &Builder) log(s string) {
|
||||||
if b.prefs.is_verbose {
|
if b.pref.is_verbose {
|
||||||
println(s)
|
println(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,36 +5,6 @@ import (
|
||||||
filepath
|
filepath
|
||||||
)
|
)
|
||||||
|
|
||||||
fn (b mut Builder) set_module_search_paths() {
|
|
||||||
msearch_path := if b.prefs.vpath.len > 0 { b.prefs.vpath } else { b.prefs.mod_path }
|
|
||||||
// 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
|
|
||||||
// with the _test.v files, *guarantees* that the tested module can be found
|
|
||||||
// without needing to set custom options/flags.
|
|
||||||
// 1) search in the *same* directory, as the compiled final v program source
|
|
||||||
// (i.e. the . in `v .` or file.v in `v file.v`)
|
|
||||||
// 2) search in the modules/ in the same directory.
|
|
||||||
// 3) search in vlib/
|
|
||||||
// 4.1) search in -vpath (if given)
|
|
||||||
// 4.2) search in ~/.vmodules/ (i.e. modules installed with vpm) (no -vpath)
|
|
||||||
b.prefs.module_search_paths = []
|
|
||||||
if b.prefs.is_test {
|
|
||||||
b.prefs.module_search_paths << filepath.basedir(b.prefs.compile_dir) // pdir of _test.v
|
|
||||||
}
|
|
||||||
b.prefs.module_search_paths << b.prefs.compile_dir
|
|
||||||
b.prefs.module_search_paths << filepath.join(b.prefs.compile_dir,'modules')
|
|
||||||
b.prefs.module_search_paths << b.prefs.vlib_path
|
|
||||||
b.prefs.module_search_paths << msearch_path
|
|
||||||
if b.prefs.user_mod_path.len > 0 {
|
|
||||||
b.prefs.module_search_paths << b.prefs.user_mod_path
|
|
||||||
}
|
|
||||||
if b.prefs.is_verbose {
|
|
||||||
b.log('b.prefs.module_search_paths: $b.prefs.module_search_paths')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
fn module_path(mod string) string {
|
fn module_path(mod string) string {
|
||||||
// submodule support
|
// submodule support
|
||||||
|
@ -43,13 +13,13 @@ fn module_path(mod string) string {
|
||||||
|
|
||||||
fn (b &Builder) find_module_path(mod string) ?string {
|
fn (b &Builder) find_module_path(mod string) ?string {
|
||||||
mod_path := module_path(mod)
|
mod_path := module_path(mod)
|
||||||
for search_path in b.prefs.module_search_paths {
|
for search_path in b.module_search_paths {
|
||||||
try_path := filepath.join(search_path,mod_path)
|
try_path := filepath.join(search_path,mod_path)
|
||||||
if b.prefs.is_verbose {
|
if b.pref.is_verbose {
|
||||||
println(' >> trying to find $mod in $try_path ..')
|
println(' >> trying to find $mod in $try_path ..')
|
||||||
}
|
}
|
||||||
if os.is_dir(try_path) {
|
if os.is_dir(try_path) {
|
||||||
if b.prefs.is_verbose {
|
if b.pref.is_verbose {
|
||||||
println(' << found $try_path .')
|
println(' << found $try_path .')
|
||||||
}
|
}
|
||||||
return try_path
|
return try_path
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
module builder
|
|
||||||
|
|
||||||
pub struct Preferences {
|
|
||||||
pub mut:
|
|
||||||
// paths
|
|
||||||
vpath string
|
|
||||||
vlib_path string
|
|
||||||
compile_dir string // contains os.realpath() of the dir of the final file beeing compiled, or the dir itself when doing `v .`
|
|
||||||
mod_path string
|
|
||||||
user_mod_path string
|
|
||||||
module_search_paths []string
|
|
||||||
// settings
|
|
||||||
os OS // the OS to build for
|
|
||||||
is_test bool
|
|
||||||
is_verbose bool
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum OS {
|
|
||||||
mac
|
|
||||||
linux
|
|
||||||
windows
|
|
||||||
freebsd
|
|
||||||
openbsd
|
|
||||||
netbsd
|
|
||||||
dragonfly
|
|
||||||
js // TODO
|
|
||||||
android
|
|
||||||
solaris
|
|
||||||
haiku
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
import (
|
import (
|
||||||
os
|
os
|
||||||
filepath
|
filepath
|
||||||
|
v.pref
|
||||||
v.builder
|
v.builder
|
||||||
term
|
term
|
||||||
)
|
)
|
||||||
|
@ -23,7 +24,7 @@ fn test_c_files() {
|
||||||
ctext := os.read_file('$vroot/vlib/v/gen/tests/${i}.c') or {
|
ctext := os.read_file('$vroot/vlib/v/gen/tests/${i}.c') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
mut b := builder.new_builder(builder.Preferences{})
|
mut b := builder.new_builder(pref.Preferences{})
|
||||||
res := b.gen_c([path])
|
res := b.gen_c([path])
|
||||||
if compare_texts(res, ctext) {
|
if compare_texts(res, ctext) {
|
||||||
eprintln('${term_ok} ${i}')
|
eprintln('${term_ok} ${i}')
|
||||||
|
|
|
@ -12,6 +12,19 @@ pub enum BuildMode {
|
||||||
build_module
|
build_module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum OS {
|
||||||
|
mac
|
||||||
|
linux
|
||||||
|
windows
|
||||||
|
freebsd
|
||||||
|
openbsd
|
||||||
|
netbsd
|
||||||
|
dragonfly
|
||||||
|
js // TODO
|
||||||
|
android
|
||||||
|
solaris
|
||||||
|
haiku
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Preferences {
|
pub struct Preferences {
|
||||||
pub mut:
|
pub mut:
|
||||||
|
@ -65,4 +78,3 @@ pub mut:
|
||||||
prealloc bool
|
prealloc bool
|
||||||
v2 bool
|
v2 bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue