compiler: get existing parser using path
parent
68bcf6830c
commit
24136ab88b
|
@ -64,7 +64,7 @@ fn (v mut V) cc() {
|
||||||
}
|
}
|
||||||
if v.pref.build_mode == .build_module {
|
if v.pref.build_mode == .build_module {
|
||||||
// Create the modules & out directory if it's not there.
|
// Create the modules & out directory if it's not there.
|
||||||
out_dir := v_modules_path + v.dir
|
out_dir := '$v_modules_path${os.PathSeparator}$v.dir'
|
||||||
if !os.dir_exists(out_dir) {
|
if !os.dir_exists(out_dir) {
|
||||||
os.mkdir(out_dir)
|
os.mkdir(out_dir)
|
||||||
}
|
}
|
||||||
|
|
100
compiler/main.v
100
compiler/main.v
|
@ -65,6 +65,7 @@ mut:
|
||||||
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?)
|
||||||
|
rdir string // abs dir
|
||||||
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
|
||||||
pref &Preferences // all the preferences and settings extracted to a struct for reusability
|
pref &Preferences // all the preferences and settings extracted to a struct for reusability
|
||||||
|
@ -218,11 +219,13 @@ fn (v mut V) add_parser(parser Parser) {
|
||||||
fn (v mut V) parse(file string, pass Pass) {
|
fn (v mut V) parse(file string, pass Pass) {
|
||||||
//println('parse($file, $pass)')
|
//println('parse($file, $pass)')
|
||||||
for i, p in v.parsers {
|
for i, p in v.parsers {
|
||||||
if p.file_path == file {
|
if os.realpath(p.file_path) == os.realpath(file) {
|
||||||
v.parsers[i].parse(pass)
|
v.parsers[i].parse(pass)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mut p := v.new_parser_from_file(file)
|
||||||
|
p.parse(pass)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -566,7 +569,7 @@ fn (v &V) v_files_from_dir(dir string) []string {
|
||||||
if file.ends_with('_c.v') && v.os == .js {
|
if file.ends_with('_c.v') && v.os == .js {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
res << '$dir/$file'
|
res << '$dir${os.PathSeparator}$file'
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -596,15 +599,16 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
// resolve deps & add imports in correct order
|
// resolve deps & add imports in correct order
|
||||||
for mod in v.resolve_deps().imports() {
|
for mod in v.resolve_deps().imports() {
|
||||||
// if mod == v.mod { continue } // Building this module? Skip. TODO it's a hack.
|
// if mod == v.mod { continue } // Building this module? Skip. TODO it's a hack.
|
||||||
if mod == 'main' { continue } // main files will get added last
|
if mod == 'builtin' { continue } // builtin already added
|
||||||
|
if mod == 'main' { continue } // main files will get added last
|
||||||
|
|
||||||
// use cached built module if exists
|
// use cached built module if exists
|
||||||
vh_path := '$v_modules_path/${mod}.vh'
|
// vh_path := '$v_modules_path/${mod}.vh'
|
||||||
if os.file_exists(vh_path) {
|
// if os.file_exists(vh_path) {
|
||||||
println('using cached module `$mod`: $vh_path')
|
// println('using cached module `$mod`: $vh_path')
|
||||||
v.files << vh_path
|
// v.files << vh_path
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
// standard module
|
// standard module
|
||||||
vfiles := v.v_files_from_dir(v.find_module_path(mod))
|
vfiles := v.v_files_from_dir(v.find_module_path(mod))
|
||||||
for file in vfiles {
|
for file in vfiles {
|
||||||
|
@ -621,14 +625,14 @@ fn (v mut V) add_v_files_to_compile() {
|
||||||
// get builtin files
|
// get builtin files
|
||||||
fn (v &V) get_builtin_files() []string {
|
fn (v &V) get_builtin_files() []string {
|
||||||
$if js {
|
$if js {
|
||||||
return v.v_files_from_dir('$v.vroot/vlib/builtin/js/')
|
return v.v_files_from_dir('$v.vroot${os.PathSeparator}vlib${os.PathSeparator}builtin${os.PathSeparator}js')
|
||||||
}
|
}
|
||||||
return v.v_files_from_dir('$v.vroot/vlib/builtin/')
|
return v.v_files_from_dir('$v.vroot${os.PathSeparator}vlib${os.PathSeparator}builtin')
|
||||||
}
|
}
|
||||||
|
|
||||||
// get user files
|
// get user files
|
||||||
fn (v &V) get_user_files() []string {
|
fn (v &V) get_user_files() []string {
|
||||||
mut dir := v.dir
|
mut dir := v.rdir
|
||||||
v.log('get_v_files($dir)')
|
v.log('get_v_files($dir)')
|
||||||
// Need to store user files separately, because they have to be added after libs, but we dont know
|
// Need to store user files separately, because they have to be added after libs, but we dont know
|
||||||
// which libs need to be added yet
|
// which libs need to be added yet
|
||||||
|
@ -636,16 +640,16 @@ fn (v &V) get_user_files() []string {
|
||||||
// v volt/slack_test.v: compile all .v files to get the environment
|
// v volt/slack_test.v: compile all .v files to get the environment
|
||||||
// I need to implement user packages! TODO
|
// I need to implement user packages! TODO
|
||||||
is_test_with_imports := dir.ends_with('_test.v') &&
|
is_test_with_imports := dir.ends_with('_test.v') &&
|
||||||
(dir.contains('/volt') || dir.contains('/c2volt'))// TODO
|
(dir.contains('${os.PathSeparator}volt') || dir.contains('${os.PathSeparator}c2volt'))// TODO
|
||||||
if is_test_with_imports {
|
if is_test_with_imports {
|
||||||
user_files << dir
|
user_files << dir
|
||||||
pos := dir.last_index('/')
|
pos := dir.last_index(os.PathSeparator)
|
||||||
dir = dir.left(pos) + '/'// TODO WHY IS THIS .neEDED?
|
dir = dir.left(pos) + os.PathSeparator// TODO WHY IS THIS .neEDED?
|
||||||
}
|
}
|
||||||
if dir.ends_with('.v') {
|
if dir.ends_with('.v') {
|
||||||
// Just compile one file and get parent dir
|
// Just compile one file and get parent dir
|
||||||
user_files << dir
|
user_files << dir
|
||||||
dir = dir.all_before('/')
|
dir = dir.all_before('${os.PathSeparator}')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Add .v files from the directory being compiled
|
// Add .v files from the directory being compiled
|
||||||
|
@ -668,33 +672,30 @@ fn (v &V) get_user_files() []string {
|
||||||
// parse deps from already parsed builtin/user files
|
// parse deps from already parsed builtin/user files
|
||||||
fn (v mut V) parse_lib_imports() {
|
fn (v mut V) parse_lib_imports() {
|
||||||
mut done_fits := []string
|
mut done_fits := []string
|
||||||
|
mut done_imports := []string
|
||||||
for {
|
for {
|
||||||
for _, fit in v.table.file_imports {
|
for _, fit in v.table.file_imports {
|
||||||
if fit.file_path in done_fits { continue }
|
if fit.file_path in done_fits { continue }
|
||||||
v.parse_file_imports(fit)
|
for _, mod in fit.imports {
|
||||||
done_fits << fit.file_path
|
import_path := v.find_module_path(mod)
|
||||||
}
|
vfiles := v.v_files_from_dir(import_path)
|
||||||
if v.table.file_imports.size == done_fits.len { break}
|
if vfiles.len == 0 {
|
||||||
}
|
verror('cannot import module $mod (no .v files in "$import_path")')
|
||||||
}
|
}
|
||||||
|
// Add all imports referenced by these libs
|
||||||
// parse imports from file import table
|
for file in vfiles {
|
||||||
fn (v mut V) parse_file_imports(fit &FileImportTable) {
|
if file in done_imports { continue }
|
||||||
for _, mod in fit.imports {
|
v.parse(file, .imports)
|
||||||
import_path := v.find_module_path(mod)
|
done_imports << file
|
||||||
vfiles := v.v_files_from_dir(import_path)
|
// if p.import_table.module_name != mod {
|
||||||
if vfiles.len == 0 {
|
// verror('bad module name: $file was imported as `$mod` but it is defined as module `$p.import_table.module_name`')
|
||||||
verror('cannot import module $mod (no .v files in "$import_path")')
|
// }
|
||||||
}
|
//if p.pref.autofree { p.scanner.text.free() free(p.scanner) }
|
||||||
// Add all imports referenced by these libs
|
|
||||||
for file in vfiles {
|
|
||||||
mut p := v.new_parser_from_file(file)
|
|
||||||
p.parse(.imports)
|
|
||||||
if p.import_table.module_name != mod {
|
|
||||||
verror('bad module name: $file was imported as `$mod` but it is defined as module `$p.import_table.module_name`')
|
|
||||||
}
|
}
|
||||||
//if p.pref.autofree { p.scanner.text.free() free(p.scanner) }
|
|
||||||
}
|
}
|
||||||
|
done_fits << fit.file_path
|
||||||
|
}
|
||||||
|
if v.table.file_imports.size == done_fits.len { break}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,7 +745,7 @@ fn new_v(args[]string) &V {
|
||||||
joined_args := args.join(' ')
|
joined_args := args.join(' ')
|
||||||
target_os := get_arg(joined_args, 'os', '')
|
target_os := get_arg(joined_args, 'os', '')
|
||||||
mut out_name := get_arg(joined_args, 'o', 'a.out')
|
mut out_name := get_arg(joined_args, 'o', 'a.out')
|
||||||
|
|
||||||
mut dir := args.last()
|
mut dir := args.last()
|
||||||
if 'run' in args {
|
if 'run' in args {
|
||||||
dir = get_all_after(joined_args, 'run', '')
|
dir = get_all_after(joined_args, 'run', '')
|
||||||
|
@ -752,9 +753,11 @@ fn new_v(args[]string) &V {
|
||||||
if dir.ends_with(os.PathSeparator) {
|
if dir.ends_with(os.PathSeparator) {
|
||||||
dir = dir.all_before_last(os.PathSeparator)
|
dir = dir.all_before_last(os.PathSeparator)
|
||||||
}
|
}
|
||||||
|
adir := os.realpath(dir)
|
||||||
if args.len < 2 {
|
if args.len < 2 {
|
||||||
dir = ''
|
dir = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// println('new compiler "$dir"')
|
// println('new compiler "$dir"')
|
||||||
// build mode
|
// build mode
|
||||||
mut build_mode := BuildMode.default_mode
|
mut build_mode := BuildMode.default_mode
|
||||||
|
@ -763,15 +766,15 @@ fn new_v(args[]string) &V {
|
||||||
if joined_args.contains('build module ') {
|
if joined_args.contains('build module ') {
|
||||||
build_mode = .build_module
|
build_mode = .build_module
|
||||||
// v build module ~/v/os => os.o
|
// v build module ~/v/os => os.o
|
||||||
//mod = os.dir(dir)
|
mod = if adir.contains(os.PathSeparator) {
|
||||||
mod = if dir.contains(os.PathSeparator) {
|
adir.all_after(os.PathSeparator)
|
||||||
dir.all_after(os.PathSeparator)
|
|
||||||
} else {
|
} else {
|
||||||
dir
|
adir
|
||||||
}
|
}
|
||||||
println('Building module "${mod}" (dir="$dir")...')
|
println('Building module "${mod}" (dir="$dir")...')
|
||||||
//out_name = '$TmpPath/vlib/${base}.o'
|
//out_name = '$TmpPath/vlib/${base}.o'
|
||||||
out_name = mod + '.o'
|
out_name = mod + '.o'
|
||||||
|
println('$out_name')
|
||||||
// Cross compiling? Use separate dirs for each os
|
// Cross compiling? Use separate dirs for each os
|
||||||
/*
|
/*
|
||||||
if target_os != os.user_os() {
|
if target_os != os.user_os() {
|
||||||
|
@ -864,7 +867,7 @@ fn new_v(args[]string) &V {
|
||||||
//exit(1)
|
//exit(1)
|
||||||
}
|
}
|
||||||
//println('out_name:$out_name')
|
//println('out_name:$out_name')
|
||||||
mut out_name_c := os.realpath( out_name ) + '.tmp.c'
|
mut out_name_c := os.realpath('${out_name}.tmp.c')
|
||||||
|
|
||||||
cflags := get_cmdline_cflags(args)
|
cflags := get_cmdline_cflags(args)
|
||||||
|
|
||||||
|
@ -906,6 +909,7 @@ fn new_v(args[]string) &V {
|
||||||
return &V{
|
return &V{
|
||||||
os: _os
|
os: _os
|
||||||
out_name: out_name
|
out_name: out_name
|
||||||
|
rdir: rdir
|
||||||
dir: dir
|
dir: dir
|
||||||
lang_dir: vroot
|
lang_dir: vroot
|
||||||
table: new_table(obfuscate)
|
table: new_table(obfuscate)
|
||||||
|
@ -927,7 +931,7 @@ fn env_vflags_and_os_args() []string {
|
||||||
if os.args.len > 1 {
|
if os.args.len > 1 {
|
||||||
args << os.args.right(1)
|
args << os.args.right(1)
|
||||||
}
|
}
|
||||||
}else{
|
} else{
|
||||||
args << os.args
|
args << os.args
|
||||||
}
|
}
|
||||||
return args
|
return args
|
||||||
|
|
|
@ -85,7 +85,7 @@ fn v_type_str(typ_ string) string {
|
||||||
|
|
||||||
fn (v &V) generate_vh() {
|
fn (v &V) generate_vh() {
|
||||||
println('Generating a V header file for module `$v.mod`')
|
println('Generating a V header file for module `$v.mod`')
|
||||||
dir := v_modules_path + v.mod
|
dir := '$v_modules_path${os.PathSeparator}$v.mod'
|
||||||
path := dir + '.vh'
|
path := dir + '.vh'
|
||||||
if !os.dir_exists(dir) {
|
if !os.dir_exists(dir) {
|
||||||
os.mkdir(dir)
|
os.mkdir(dir)
|
||||||
|
|
|
@ -7,7 +7,7 @@ module main
|
||||||
import os
|
import os
|
||||||
|
|
||||||
const (
|
const (
|
||||||
v_modules_path = os.home_dir() + '/.vmodules/'
|
v_modules_path = os.home_dir() + '.vmodules'
|
||||||
)
|
)
|
||||||
|
|
||||||
// add a module and its deps (module speficic dag method)
|
// add a module and its deps (module speficic dag method)
|
||||||
|
@ -33,8 +33,8 @@ pub fn(graph &DepGraph) imports() []string {
|
||||||
fn (v &V) module_path(mod string) string {
|
fn (v &V) module_path(mod string) string {
|
||||||
// submodule support
|
// submodule support
|
||||||
if mod.contains('.') {
|
if mod.contains('.') {
|
||||||
//return mod.replace('.', os.PathSeparator)
|
return mod.replace('.', os.PathSeparator)
|
||||||
return mod.replace('.', '/')
|
// return mod.replace('.', '/')
|
||||||
}
|
}
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
@ -45,15 +45,15 @@ fn (v &V) module_path(mod string) string {
|
||||||
fn (v &V) find_module_path(mod string) string {
|
fn (v &V) find_module_path(mod string) string {
|
||||||
mod_path := v.module_path(mod)
|
mod_path := v.module_path(mod)
|
||||||
// First check for local modules in the same directory
|
// First check for local modules in the same directory
|
||||||
mut import_path := os.getwd() + '/$mod_path'
|
mut import_path := os.getwd() + '${os.PathSeparator}$mod_path'
|
||||||
// Now search in vlib/
|
// Now search in vlib/
|
||||||
if !os.dir_exists(import_path) {
|
if !os.dir_exists(import_path) {
|
||||||
import_path = '$v.lang_dir/vlib/$mod_path'
|
import_path = '$v.lang_dir${os.PathSeparator}vlib${os.PathSeparator}$mod_path'
|
||||||
}
|
}
|
||||||
//println('ip=$import_path')
|
//println('ip=$import_path')
|
||||||
// Finally try modules installed with vpm (~/.vmodules)
|
// Finally try modules installed with vpm (~/.vmodules)
|
||||||
if !os.dir_exists(import_path) {
|
if !os.dir_exists(import_path) {
|
||||||
import_path = '$v_modules_path/$mod_path'
|
import_path = '$v_modules_path${os.PathSeparator}$mod_path'
|
||||||
if !os.dir_exists(import_path){
|
if !os.dir_exists(import_path){
|
||||||
verror('module "$mod" not found')
|
verror('module "$mod" not found')
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,10 +119,10 @@ fn (v mut V) new_parser_from_file(path string) Parser {
|
||||||
mut p := v.new_parser(new_scanner_file(path), path)
|
mut p := v.new_parser(new_scanner_file(path), path)
|
||||||
p = { p|
|
p = { p|
|
||||||
file_path: path,
|
file_path: path,
|
||||||
file_name: path.all_after('/'),
|
file_name: path.all_after(os.PathSeparator),
|
||||||
file_platform: path_platform,
|
file_platform: path_platform,
|
||||||
file_pcguard: path_pcguard,
|
file_pcguard: path_pcguard,
|
||||||
is_script: (v.pref.is_script && path == v.dir)
|
is_script: (v.pref.is_script && os.realpath(path) == os.realpath(path))
|
||||||
}
|
}
|
||||||
if p.pref.building_v {
|
if p.pref.building_v {
|
||||||
p.scanner.should_print_relative_paths_on_error = false
|
p.scanner.should_print_relative_paths_on_error = false
|
||||||
|
|
|
@ -724,7 +724,7 @@ fn (s mut Scanner) debug_tokens() {
|
||||||
s.pos = 0
|
s.pos = 0
|
||||||
s.debug = true
|
s.debug = true
|
||||||
|
|
||||||
fname := s.file_path.all_after('/')
|
fname := s.file_path.all_after(os.PathSeparator)
|
||||||
println('\n===DEBUG TOKENS $fname===')
|
println('\n===DEBUG TOKENS $fname===')
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
module main
|
module main
|
||||||
|
|
||||||
|
import os
|
||||||
import math
|
import math
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
|
@ -862,7 +863,7 @@ fn (table &Table) qualify_module(mod string, file_path string) string {
|
||||||
for m in table.imports {
|
for m in table.imports {
|
||||||
if m.contains('.') && m.contains(mod) {
|
if m.contains('.') && m.contains(mod) {
|
||||||
m_parts := m.split('.')
|
m_parts := m.split('.')
|
||||||
m_path := m_parts.join('/')
|
m_path := m_parts.join(os.PathSeparator)
|
||||||
if mod == m_parts[m_parts.len-1] && file_path.contains(m_path) {
|
if mod == m_parts[m_parts.len-1] && file_path.contains(m_path) {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue