Browse Source

Merge remote-tracking branch 'upstream/master'

master
Luna 1 year ago
parent
commit
c73a730844
10 changed files with 75 additions and 32 deletions
  1. +5
    -4
      compiler/cc.v
  2. +1
    -1
      compiler/comptime.v
  3. +2
    -2
      compiler/fn.v
  4. +6
    -2
      compiler/main.v
  5. +2
    -3
      compiler/msvc.v
  6. +30
    -12
      compiler/parser.v
  7. +17
    -1
      compiler/scanner.v
  8. +6
    -1
      compiler/table.v
  9. +5
    -5
      vlib/builtin/map.v
  10. +1
    -1
      vlib/vweb/assets/assets.v

+ 5
- 4
compiler/cc.v View File

@@ -85,14 +85,14 @@ fn (v mut V) cc() {
}
// -I flags
/*
mut args := ''
mut args := ''
for flag in v.get_os_cflags() {
if !flag.starts_with('-l') {
args += flag
args += flag.value
args += ' '
}
}
*/
*/
if v.pref.sanitize {
a << '-fsanitize=leak'
}
@@ -111,7 +111,7 @@ mut args := ''
// Cross compiling windows
//
// Output executable name
a << '-o $v.out_name'
a << '-o "$v.out_name"'
if os.dir_exists(v.out_name) {
cerror('\'$v.out_name\' is a directory')
}
@@ -127,6 +127,7 @@ mut args := ''
if v.os == .mac {
a << '-mmacosx-version-min=10.7'
}
// add all flags
for flag in v.get_os_cflags() {
a << flag.format()
}


+ 1
- 1
compiler/comptime.v View File

@@ -115,7 +115,7 @@ fn (p mut Parser) comp_time() {
os.rm('.vwebtmpl.v')
}
pp.is_vweb = true
pp.cur_fn = p.cur_fn // give access too all variables in current function
pp.set_current_fn( p.cur_fn ) // give access too all variables in current function
pp.parse(.main)
tmpl_fn_body := p.cgen.lines.slice(pos + 2, p.cgen.lines.len).join('\n').clone()
end_pos := tmpl_fn_body.last_index('Builder_str( sb )') + 19 // TODO


+ 2
- 2
compiler/fn.v View File

@@ -284,7 +284,7 @@ fn (p mut Parser) fn_decl() {
''
}
if !p.is_vweb {
p.cur_fn = f
p.set_current_fn( f )
}
// Generate `User_register()` instead of `register()`
// Internally it's still stored as "register" in type User
@@ -492,7 +492,7 @@ _thread_so = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&reload_so, 0, 0, 0);
return
}
p.check_unused_variables()
p.cur_fn = EmptyFn
p.set_current_fn( EmptyFn )
p.returns = false
if !is_generic {
p.genln('}')


+ 6
- 2
compiler/main.v View File

@@ -912,7 +912,9 @@ fn test_v() {
file := os.realpath( relative_file )
tmpcfilepath := file.replace('_test.v', '_test.tmp.c')
print(relative_file + ' ')
r := os.exec('$vexe $joined_args -debug $file') or {
mut cmd := '"$vexe" $joined_args -debug "$file"'
if os.user_os() == 'windows' { cmd = '"$cmd"' }
r := os.exec(cmd) or {
failed = true
println('FAIL')
continue
@@ -931,7 +933,9 @@ fn test_v() {
file := os.realpath( relative_file )
tmpcfilepath := file.replace('.v', '.tmp.c')
print(relative_file + ' ')
r := os.exec('$vexe $joined_args -debug $file') or {
mut cmd := '"$vexe" $joined_args -debug "$file"'
if os.user_os() == 'windows' { cmd = '"$cmd"' }
r := os.exec(cmd) or {
failed = true
println('FAIL')
continue


+ 2
- 3
compiler/msvc.v View File

@@ -320,9 +320,8 @@ pub fn (v mut V) cc_msvc() {
inc_paths << ' ' + flag.format() + ' '
}
else if flag.name == '-L' {
lpath := flag.value
lib_paths << '"' + lpath + '"'
lib_paths << '"' + lpath + os.PathSeparator + 'msvc' + '"'
lib_paths << flag.value
lib_paths << flag.value + os.PathSeparator + 'msvc'
// The above allows putting msvc specific .lib files in a subfolder msvc/ ,
// where gcc will NOT find them, but cl will do...
// NB: gcc is smart enough to not need .lib files at all in most cases, the .dll is enough.


+ 30
- 12
compiler/parser.v View File

@@ -119,6 +119,11 @@ fn (v mut V) new_parser(path string) Parser {
return p
}

fn (p mut Parser) set_current_fn(f &Fn) {
p.cur_fn = f
p.scanner.fn_name = '${f.mod}.${f.name}'
}

fn (p mut Parser) next() {
p.prev_tok2 = p.prev_tok
p.prev_tok = p.tok
@@ -262,7 +267,7 @@ fn (p mut Parser) parse(pass Pass) {
case Token.eof:
p.log('end of parse()')
if p.is_script && !p.pref.is_test {
p.cur_fn = MainFn
p.set_current_fn( MainFn )
p.check_unused_variables()
}
if false && !p.first_pass() && p.fileis('main.v') {
@@ -281,12 +286,12 @@ fn (p mut Parser) parse(pass Pass) {
// we need to set it to save and find variables
if p.first_pass() {
if p.cur_fn.name == '' {
p.cur_fn = MainFn
p.set_current_fn( MainFn )
}
return
}
if p.cur_fn.name == '' {
p.cur_fn = MainFn
p.set_current_fn( MainFn )
if p.pref.is_repl {
p.cur_fn.clear_vars()
}
@@ -511,7 +516,8 @@ fn (p mut Parser) struct_decl() {
if !is_c && !p.builtin_mod && p.mod != 'main' {
name = p.prepend_mod(name)
}
if p.pass == .decl && p.table.known_type(name) {
mut typ := p.table.find_type(name)
if p.pass == .decl && p.table.known_type_fast(typ) {
p.error('`$name` redeclared')
}
if !is_c {
@@ -519,7 +525,6 @@ fn (p mut Parser) struct_decl() {
p.gen_typedef('typedef $kind $name $name;')
}
// Register the type
mut typ := p.table.find_type(name)
mut is_ph := false
if typ.is_placeholder {
// Update the placeholder
@@ -1472,8 +1477,8 @@ fn (p mut Parser) name_expr() string {
}
// //////////////////////////
// module ?
// Allow shadowing (gg = gg.newcontext(); gg.draw_triangle())
if ((name == p.mod && p.table.known_mod(name)) || p.import_table.known_alias(name))
// (Allow shadowing `gg = gg.newcontext(); gg.draw_triangle();` )
if p.peek() == .dot && ((name == p.mod && p.table.known_mod(name)) || p.import_table.known_alias(name))
&& !p.cur_fn.known_var(name) && !is_c {
mut mod := name
// must be aliased module
@@ -2532,16 +2537,28 @@ fn (p mut Parser) string_expr() {
// Custom format? ${t.hour:02d}
custom := p.tok == .colon
if custom {
format += '%'
mut cformat := ''
p.next()
if p.tok == .dot {
format += '.'
cformat += '.'
p.next()
}
format += p.lit// 02
if p.tok == .minus { // support for left aligned formatting
cformat += '-'
p.next()
}
cformat += p.lit// 02
p.next()
format += p.lit// f
// println('custom str F=$format')
fspec := p.lit // f
cformat += fspec
if fspec == 's' {
//println('custom str F=$cformat | format_specifier: "$fspec" | typ: $typ ')
if typ != 'string' {
p.error('only v strings can be formatted with a :${cformat} format, but you have given "${val}", which has type ${typ}.')
}
args = args.all_before_last('${val}.len, ${val}.str') + '${val}.str'
}
format += '%$cformat'
p.next()
}
else {
@@ -2563,6 +2580,7 @@ fn (p mut Parser) string_expr() {
}
format += f
}
//println('interpolation format is: |${format}| args are: |${args}| ')
}
if complex_inter {
p.fgen('}')


+ 17
- 1
compiler/scanner.v View File

@@ -24,6 +24,7 @@ mut:
fmt_indent int
fmt_line_empty bool
prev_tok Token
fn_name string // needed for @FN
}

fn new_scanner(file_path string) &Scanner {
@@ -394,6 +395,17 @@ fn (s mut Scanner) scan() ScanRes {
case `@`:
s.pos++
name := s.ident_name()
// @FN => will be substituted with the name of the current V function
// @FILE => will be substituted with the path of the V source file
// @LINE => will be substituted with the V line number where it appears (as a string).
// @COLUMN => will be substituted with the column where it appears (as a string).
// This allows things like this:
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
// ... which is useful while debugging/tracing
if name == 'FN' { return scan_res(.str, s.fn_name) }
if name == 'FILE' { return scan_res(.str, os.realpath(s.file_path)) }
if name == 'LINE' { return scan_res(.str, (s.line_nr+1).str()) }
if name == 'COLUMN' { return scan_res(.str, (s.current_column()).str()) }
if !is_key(name) {
s.error('@ must be used before keywords (e.g. `@type string`)')
}
@@ -580,9 +592,13 @@ fn (s &Scanner) find_current_line_start_position() int {
return linestart
}

fn (s &Scanner) current_column() int {
return s.pos - s.find_current_line_start_position()
}

fn (s &Scanner) error(msg string) {
fullpath := os.realpath( s.file_path )
column := s.pos - s.find_current_line_start_position()
column := s.current_column()
// The filepath:line:col: format is the default C compiler
// error output format. It allows editors and IDE's like
// emacs to quickly find the errors in the output


+ 6
- 1
compiler/table.v View File

@@ -320,6 +320,10 @@ fn (table &Table) known_type(typ_ string) bool {
return t.name.len > 0 && !t.is_placeholder
}

fn (table &Table) known_type_fast(t &Type) bool {
return t.name.len > 0 && !t.is_placeholder
}

fn (t &Table) find_fn(name string) Fn {
f := t.fns[name]
if !isnil(f.name.str) {
@@ -345,7 +349,7 @@ fn (t mut Table) register_type(typ string) {
}
if typ in t.typesmap {
return
}
}
t.typesmap[typ] = Type{name:typ}
}

@@ -684,6 +688,7 @@ fn (t &Table) main_exists() bool {

// TODO use `?Var`
fn (t &Table) find_const(name string) Var {
//println('find const l=$t.consts.len')
for c in t.consts {
if c.name == name {
return c


+ 5
- 5
vlib/builtin/map.v View File

@@ -58,7 +58,7 @@ fn (m mut map) insert(n mut mapnode, key string, val voidptr) {
return
}
if n.key > key {
if isnil(n.left) {
if n.left == 0 {
n.left = new_node(key, val, m.element_size)
m.size++
} else {
@@ -66,7 +66,7 @@ fn (m mut map) insert(n mut mapnode, key string, val voidptr) {
}
return
}
if isnil(n.right) {
if n.right == 0 {
n.right = new_node(key, val, m.element_size)
m.size++
} else {
@@ -80,14 +80,14 @@ fn (n & mapnode) find(key string, out voidptr, element_size int) bool{
return true
}
else if n.key > key {
if isnil(n.left) {
if n.left == 0 {
return false
} else {
return n.left.find(key, out, element_size)
}
}
else {
if isnil(n.right) {
if n.right == 0 {
return false
} else {
return n.right.find(key, out, element_size)
@@ -178,7 +178,7 @@ pub fn (m mut map) keys() []string {
}

fn (m map) get(key string, out voidptr) bool {
if isnil(m.root) {
if m.root == 0 {
return false
}
return m.root.find(key, out, m.element_size)


+ 1
- 1
vlib/vweb/assets/assets.v View File

@@ -34,7 +34,7 @@ pub fn new_manager() *AssetManager {
return &AssetManager{}
}

// add_js adds a css asset
// add_css adds a css asset
pub fn (am mut AssetManager) add_css(file string) bool {
return am.add('css', file)
}


Loading…
Cancel
Save