compiler: get existing parser using path

pull/2233/head
joe-conigliaro 2019-10-05 14:10:28 +10:00 committed by Alexander Medvednikov
parent 68bcf6830c
commit 24136ab88b
7 changed files with 65 additions and 60 deletions

View File

@ -64,7 +64,7 @@ fn (v mut V) cc() {
}
if v.pref.build_mode == .build_module {
// 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) {
os.mkdir(out_dir)
}

View File

@ -65,6 +65,7 @@ mut:
out_name_c string // name of the temporary C file
files []string // all V files that need to be parsed and compiled
dir string // directory (or file) being compiled (TODO rename to path?)
rdir string // abs dir
table &Table // table with types, vars, functions etc
cgen &CGen // C code generator
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) {
//println('parse($file, $pass)')
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)
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 {
continue
}
res << '$dir/$file'
res << '$dir${os.PathSeparator}$file'
}
return res
}
@ -596,15 +599,16 @@ fn (v mut V) add_v_files_to_compile() {
// resolve deps & add imports in correct order
for mod in v.resolve_deps().imports() {
// 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
vh_path := '$v_modules_path/${mod}.vh'
if os.file_exists(vh_path) {
println('using cached module `$mod`: $vh_path')
v.files << vh_path
continue
}
// vh_path := '$v_modules_path/${mod}.vh'
// if os.file_exists(vh_path) {
// println('using cached module `$mod`: $vh_path')
// v.files << vh_path
// continue
// }
// standard module
vfiles := v.v_files_from_dir(v.find_module_path(mod))
for file in vfiles {
@ -621,14 +625,14 @@ fn (v mut V) add_v_files_to_compile() {
// get builtin files
fn (v &V) get_builtin_files() []string {
$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
fn (v &V) get_user_files() []string {
mut dir := v.dir
mut dir := v.rdir
v.log('get_v_files($dir)')
// 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
@ -636,16 +640,16 @@ fn (v &V) get_user_files() []string {
// v volt/slack_test.v: compile all .v files to get the environment
// I need to implement user packages! TODO
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 {
user_files << dir
pos := dir.last_index('/')
dir = dir.left(pos) + '/'// TODO WHY IS THIS .neEDED?
pos := dir.last_index(os.PathSeparator)
dir = dir.left(pos) + os.PathSeparator// TODO WHY IS THIS .neEDED?
}
if dir.ends_with('.v') {
// Just compile one file and get parent dir
user_files << dir
dir = dir.all_before('/')
dir = dir.all_before('${os.PathSeparator}')
}
else {
// 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
fn (v mut V) parse_lib_imports() {
mut done_fits := []string
mut done_imports := []string
for {
for _, fit in v.table.file_imports {
if fit.file_path in done_fits { continue }
v.parse_file_imports(fit)
done_fits << fit.file_path
}
if v.table.file_imports.size == done_fits.len { break}
}
}
// parse imports from file import table
fn (v mut V) parse_file_imports(fit &FileImportTable) {
for _, mod in fit.imports {
import_path := v.find_module_path(mod)
vfiles := v.v_files_from_dir(import_path)
if vfiles.len == 0 {
verror('cannot import module $mod (no .v files in "$import_path")')
}
// 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`')
for _, fit in v.table.file_imports {
if fit.file_path in done_fits { continue }
for _, mod in fit.imports {
import_path := v.find_module_path(mod)
vfiles := v.v_files_from_dir(import_path)
if vfiles.len == 0 {
verror('cannot import module $mod (no .v files in "$import_path")')
}
// Add all imports referenced by these libs
for file in vfiles {
if file in done_imports { continue }
v.parse(file, .imports)
done_imports << file
// 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) }
}
//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(' ')
target_os := get_arg(joined_args, 'os', '')
mut out_name := get_arg(joined_args, 'o', 'a.out')
mut dir := args.last()
if 'run' in args {
dir = get_all_after(joined_args, 'run', '')
@ -752,9 +753,11 @@ fn new_v(args[]string) &V {
if dir.ends_with(os.PathSeparator) {
dir = dir.all_before_last(os.PathSeparator)
}
adir := os.realpath(dir)
if args.len < 2 {
dir = ''
}
// println('new compiler "$dir"')
// build mode
mut build_mode := BuildMode.default_mode
@ -763,15 +766,15 @@ fn new_v(args[]string) &V {
if joined_args.contains('build module ') {
build_mode = .build_module
// v build module ~/v/os => os.o
//mod = os.dir(dir)
mod = if dir.contains(os.PathSeparator) {
dir.all_after(os.PathSeparator)
mod = if adir.contains(os.PathSeparator) {
adir.all_after(os.PathSeparator)
} else {
dir
adir
}
println('Building module "${mod}" (dir="$dir")...')
//out_name = '$TmpPath/vlib/${base}.o'
out_name = mod + '.o'
println('$out_name')
// Cross compiling? Use separate dirs for each os
/*
if target_os != os.user_os() {
@ -864,7 +867,7 @@ fn new_v(args[]string) &V {
//exit(1)
}
//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)
@ -906,6 +909,7 @@ fn new_v(args[]string) &V {
return &V{
os: _os
out_name: out_name
rdir: rdir
dir: dir
lang_dir: vroot
table: new_table(obfuscate)
@ -927,7 +931,7 @@ fn env_vflags_and_os_args() []string {
if os.args.len > 1 {
args << os.args.right(1)
}
}else{
} else{
args << os.args
}
return args

View File

@ -85,7 +85,7 @@ fn v_type_str(typ_ string) string {
fn (v &V) generate_vh() {
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'
if !os.dir_exists(dir) {
os.mkdir(dir)

View File

@ -7,7 +7,7 @@ module main
import os
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)
@ -33,8 +33,8 @@ pub fn(graph &DepGraph) imports() []string {
fn (v &V) module_path(mod string) string {
// submodule support
if mod.contains('.') {
//return mod.replace('.', os.PathSeparator)
return mod.replace('.', '/')
return mod.replace('.', os.PathSeparator)
// return mod.replace('.', '/')
}
return mod
}
@ -45,15 +45,15 @@ fn (v &V) module_path(mod string) string {
fn (v &V) find_module_path(mod string) string {
mod_path := v.module_path(mod)
// 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/
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')
// Finally try modules installed with vpm (~/.vmodules)
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){
verror('module "$mod" not found')
}

View File

@ -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)
p = { p|
file_path: path,
file_name: path.all_after('/'),
file_name: path.all_after(os.PathSeparator),
file_platform: path_platform,
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 {
p.scanner.should_print_relative_paths_on_error = false

View File

@ -724,7 +724,7 @@ fn (s mut Scanner) debug_tokens() {
s.pos = 0
s.debug = true
fname := s.file_path.all_after('/')
fname := s.file_path.all_after(os.PathSeparator)
println('\n===DEBUG TOKENS $fname===')
for {

View File

@ -4,6 +4,7 @@
module main
import os
import math
import strings
@ -862,7 +863,7 @@ fn (table &Table) qualify_module(mod string, file_path string) string {
for m in table.imports {
if m.contains('.') && m.contains(mod) {
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) {
return m
}