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

View File

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

View File

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

View File

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

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

View File

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

View File

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