diff --git a/Makefile b/Makefile index 71ee253e22..0a1f00eafc 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ test: v echo "Running V tests..." find . -name '*_test.v' -print0 | xargs -0 -n1 ./v echo "Building V examples..." - find examples -name '*.v' -print0 | xargs -0 -n1 ./v + find examples -name '*.v' -not -path "examples/hot_code_reloading/*" -print0 | xargs -0 -n1 ./v clean: -rm -f v.c v vprod diff --git a/compiler/main.v b/compiler/main.v index 071d147c75..277ce9e304 100644 --- a/compiler/main.v +++ b/compiler/main.v @@ -464,13 +464,13 @@ fn (c &V) cc_windows_cross() { } mut libs := '' if c.pref.build_mode == .default_mode { - libs = '$TmpPath/vlib/builtin.o' + libs = '"$TmpPath/vlib/builtin.o"' if !os.file_exists(libs) { println('`builtin.o` not found') exit(1) } for imp in c.table.imports { - libs += ' $TmpPath/vlib/${imp}.o' + libs += ' "$TmpPath/vlib/${imp}.o"' } } args += ' $c.out_name_c ' @@ -534,7 +534,7 @@ fn (v mut V) cc() { flags := v.table.flags.join(' ') //mut shared := '' if v.pref.is_so { - a << '-shared'// -Wl,-z,defs' + a << '-shared -fPIC'// -Wl,-z,defs' v.out_name = v.out_name + '.so' } if v.pref.is_prod { @@ -551,7 +551,7 @@ fn (v mut V) cc() { // } else if v.pref.build_mode == .default_mode { - libs = '$TmpPath/vlib/builtin.o' + libs = '"$TmpPath/vlib/builtin.o"' if !os.file_exists(libs) { println('`builtin.o` not found') exit(1) @@ -560,7 +560,7 @@ fn (v mut V) cc() { if imp == 'webview' { continue } - libs += ' $TmpPath/vlib/${imp}.o' + libs += ' "$TmpPath/vlib/${imp}.o"' } } // -I flags @@ -592,7 +592,7 @@ mut args := '' // else { a << '-o $v.out_name' // The C file we are compiling - a << '$TmpPath/$v.out_name_c' + a << '"$TmpPath/$v.out_name_c"' // } // Min macos version is mandatory I think? if v.os == MAC { @@ -747,7 +747,7 @@ fn (v mut V) add_user_v_files() { // Parse lib imports if v.pref.build_mode == .default_mode { for i := 0; i < v.table.imports.len; i++ { - pkg := v.table.imports[i] + pkg := v.module_path(v.table.imports[i]) vfiles := v.v_files_from_dir('$TmpPath/vlib/$pkg') // Add all imports referenced by these libs for file in vfiles { @@ -760,7 +760,7 @@ fn (v mut V) add_user_v_files() { // TODO this used to crash compiler? // for pkg in v.table.imports { for i := 0; i < v.table.imports.len; i++ { - pkg := v.table.imports[i] + pkg := v.module_path(v.table.imports[i]) idir := os.getwd() mut import_path := '$idir/$pkg' if(!os.file_exists(import_path)) { @@ -779,7 +779,8 @@ fn (v mut V) add_user_v_files() { println(v.table.imports) } // Only now add all combined lib files - for pkg in v.table.imports { + for _pkg in v.table.imports { + pkg := v.module_path(_pkg) idir := os.getwd() mut module_path := '$idir/$pkg' // If we are in default mode, we don't parse vlib .v files, but header .vh files in @@ -820,6 +821,15 @@ fn get_arg(joined_args, arg, def string) string { return res } +fn (v &V) module_path(pkg string) string { + // submodule support + if pkg.contains('.') { + //return pkg.replace('.', path_sep) + return pkg.replace('.', '/') + } + return pkg +} + fn (v &V) log(s string) { if !v.pref.is_verbose { return diff --git a/compiler/parser.v b/compiler/parser.v index 084d651ca4..a7d82bcd9c 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -294,7 +294,21 @@ fn (p mut Parser) import_statement() { if p.tok != NAME { p.error('bad import format') } - pkg := p.lit.trim_space() + mut pkg := p.lit.trim_space() + // submodule support + // limit depth to 4 for now + max_module_depth := 4 + mut depth := 1 + for p.peek() == DOT { + p.next() // SKIP DOT + p.next() // SUBMODULE + submodule := p.lit.trim_space() + pkg = pkg + '.' + submodule + depth++ + if depth > max_module_depth { + panic('Sorry. Module depth of $max_module_depth exceeded: $pkg ($submodule is too deep).') + } + } p.next() p.fgenln(' ' + pkg) // Make sure there are no duplicate imports @@ -1133,6 +1147,13 @@ fn (p mut Parser) var_decl() { p.next() p.check(LCBR) p.genln('if (!$tmp .ok) {') + p.register_var(Var { + name: 'err' + typ: 'string' + is_mut: false + is_used: true + }) + p.genln('string err = $tmp . error;') p.statements() p.genln('$typ $name = *($typ*) $tmp . data;') if !p.returns && p.prev_tok2 != CONTINUE && p.prev_tok2 != BREAK {