mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
compiler: scoped defer + build tests with msvc
This commit is contained in:
parent
c924a6cf00
commit
802ff1d012
@ -29,7 +29,7 @@ mut:
|
|||||||
is_method bool
|
is_method bool
|
||||||
returns_error bool
|
returns_error bool
|
||||||
is_decl bool // type myfn fn(int, int)
|
is_decl bool // type myfn fn(int, int)
|
||||||
defer_text string
|
defer_text []string
|
||||||
//gen_types []string
|
//gen_types []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,9 +44,15 @@ fn (f &Fn) find_var(name string) Var {
|
|||||||
|
|
||||||
|
|
||||||
fn (f mut Fn) open_scope() {
|
fn (f mut Fn) open_scope() {
|
||||||
|
f.defer_text << ''
|
||||||
f.scope_level++
|
f.scope_level++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (f mut Fn) close_scope() {
|
||||||
|
f.scope_level--
|
||||||
|
f.defer_text = f.defer_text.left(f.scope_level + 1)
|
||||||
|
}
|
||||||
|
|
||||||
fn (f &Fn) mark_var_used(v Var) {
|
fn (f &Fn) mark_var_used(v Var) {
|
||||||
for i, vv in f.local_vars {
|
for i, vv in f.local_vars {
|
||||||
if vv.name == v.name {
|
if vv.name == v.name {
|
||||||
@ -442,7 +448,7 @@ _thread_so = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&reload_so, 0, 0, 0);
|
|||||||
if p.pref.is_prof && f.name != 'main' && f.name != 'time__ticks' {
|
if p.pref.is_prof && f.name != 'main' && f.name != 'time__ticks' {
|
||||||
p.genln('double _PROF_START = time__ticks();//$f.name')
|
p.genln('double _PROF_START = time__ticks();//$f.name')
|
||||||
cgen_name := p.table.cgen_name(f)
|
cgen_name := p.table.cgen_name(f)
|
||||||
f.defer_text = ' ${cgen_name}_time += time__ticks() - _PROF_START;'
|
f.defer_text[f.scope_level] = ' ${cgen_name}_time += time__ticks() - _PROF_START;'
|
||||||
}
|
}
|
||||||
if is_generic {
|
if is_generic {
|
||||||
// Don't need to generate body for the actual generic definition
|
// Don't need to generate body for the actual generic definition
|
||||||
@ -455,7 +461,7 @@ _thread_so = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&reload_so, 0, 0, 0);
|
|||||||
p.genln(p.print_prof_counters())
|
p.genln(p.print_prof_counters())
|
||||||
}
|
}
|
||||||
// Counting or not, always need to add defer before the end
|
// Counting or not, always need to add defer before the end
|
||||||
p.genln(f.defer_text)
|
p.genln(f.defer_text[f.scope_level])
|
||||||
if typ != 'void' && !p.returns && f.name != 'main' && f.name != 'WinMain' {
|
if typ != 'void' && !p.returns && f.name != 'main' && f.name != 'WinMain' {
|
||||||
p.error('$f.name must return "$typ"')
|
p.error('$f.name must return "$typ"')
|
||||||
}
|
}
|
||||||
|
@ -1069,13 +1069,18 @@ fn (p mut Parser) close_scope() {
|
|||||||
else if v.ptr {
|
else if v.ptr {
|
||||||
//p.genln('free($v.name); // close_scope free')
|
//p.genln('free($v.name); // close_scope free')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if p.cur_fn.defer_text.last() != '' {
|
||||||
|
p.genln(p.cur_fn.defer_text.last())
|
||||||
|
//p.cur_fn.defer_text[f] = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
p.cur_fn.close_scope()
|
||||||
p.cur_fn.var_idx = i + 1
|
p.cur_fn.var_idx = i + 1
|
||||||
// println('close_scope new var_idx=$f.var_idx\n')
|
// println('close_scope new var_idx=$f.var_idx\n')
|
||||||
p.cur_fn.scope_level--
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn (p mut Parser) genln(s string) {
|
fn (p mut Parser) genln(s string) {
|
||||||
p.cgen.genln(s)
|
p.cgen.genln(s)
|
||||||
@ -3237,13 +3242,27 @@ fn (p mut Parser) return_st() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret := p.cgen.cur_line.right(ph)
|
ret := p.cgen.cur_line.right(ph)
|
||||||
p.cgen(p.cur_fn.defer_text)
|
|
||||||
if p.cur_fn.defer_text == '' || expr_type == 'void*' {
|
// @emily33901: Scoped defer
|
||||||
|
// Check all of our defer texts to see if there is one at a higher scope level
|
||||||
|
// The one for our current scope would be the last so any before that need to be
|
||||||
|
// added.
|
||||||
|
|
||||||
|
mut total_text := ''
|
||||||
|
|
||||||
|
for text in p.cur_fn.defer_text {
|
||||||
|
if text != '' {
|
||||||
|
// In reverse order
|
||||||
|
total_text = text + total_text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if total_text == '' || expr_type == 'void*' {
|
||||||
p.cgen.resetln('return $ret')
|
p.cgen.resetln('return $ret')
|
||||||
} else {
|
} else {
|
||||||
tmp := p.get_tmp()
|
tmp := p.get_tmp()
|
||||||
p.cgen.resetln('$expr_type $tmp = $ret;\n')
|
p.cgen.resetln('$expr_type $tmp = $ret;\n')
|
||||||
p.genln(p.cur_fn.defer_text)
|
p.genln(total_text)
|
||||||
p.genln('return $tmp;')
|
p.genln('return $tmp;')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3397,9 +3416,14 @@ fn (p mut Parser) defer_st() {
|
|||||||
|
|
||||||
// Save everything inside the defer block to `defer_text`.
|
// Save everything inside the defer block to `defer_text`.
|
||||||
// It will be inserted before every `return`
|
// It will be inserted before every `return`
|
||||||
|
|
||||||
|
// Emily: TODO: all variables that are used in this defer statement need to be evaluated when the block
|
||||||
|
// is defined otherwise they could change over the course of the function
|
||||||
|
// (make temps out of them)
|
||||||
|
|
||||||
p.genln('{')
|
p.genln('{')
|
||||||
p.statements()
|
p.statements()
|
||||||
p.cur_fn.defer_text = p.cgen.lines.right(pos).join('\n') + p.cur_fn.defer_text
|
p.cur_fn.defer_text.last() = p.cgen.lines.right(pos).join('\n') + p.cur_fn.defer_text.last()
|
||||||
|
|
||||||
// Rollback p.cgen.lines
|
// Rollback p.cgen.lines
|
||||||
p.cgen.lines = p.cgen.lines.left(pos)
|
p.cgen.lines = p.cgen.lines.left(pos)
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
curl -O https://raw.githubusercontent.com/vlang/vc/master/v.c
|
curl -O https://raw.githubusercontent.com/vlang/vc/master/v.c
|
||||||
gcc -std=gnu11 -DUNICODE -D_UNICODE -w -o vc.exe v.c
|
gcc -std=gnu11 -DUNICODE -D_UNICODE -w -o vc.exe v.c
|
||||||
del v.c
|
del v.c
|
||||||
|
|
||||||
vc.exe -o v.exe compiler
|
vc.exe -o v.exe compiler
|
||||||
v.exe -os msvc -o v.msvc.exe compiler
|
v.exe -os msvc -o v.msvc.exe compiler
|
||||||
v.msvc.exe -os msvc -o v.msvc.2.exe compiler
|
v.msvc.exe -os msvc -o v.msvc.2.exe compiler
|
||||||
v.msvc.exe -o v.gcc.exe compiler
|
v.msvc.exe -o v.gcc.exe compiler
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
for /r . %%x in (*_test.v) do (
|
for /r . %%x in (*_test.v) do (
|
||||||
v -o test.exe -debug %%x
|
v -o test.exe -debug %%x
|
||||||
@ -15,14 +18,16 @@ for /r . %%x in (*_test.v) do (
|
|||||||
v.msvc.exe -o test.exe -debug %%x
|
v.msvc.exe -o test.exe -debug %%x
|
||||||
if !ERRORLEVEL! NEQ 0 goto :fail
|
if !ERRORLEVEL! NEQ 0 goto :fail
|
||||||
)
|
)
|
||||||
|
|
||||||
for /r . %%x in (*_test.v) do (
|
for /r . %%x in (*_test.v) do (
|
||||||
v.msvc.2.exe -o test.exe -debug %%x
|
v -os msvc -o test.exe -debug %%x
|
||||||
if !ERRORLEVEL! NEQ 0 goto :fail
|
if !ERRORLEVEL! NEQ 0 goto :fail
|
||||||
)
|
)
|
||||||
for /r . %%x in (*_test.v) do (
|
for /r . %%x in (*_test.v) do (
|
||||||
v.gcc.exe -o test.exe -debug %%x
|
v.msvc.exe -os msvc -o test.exe -debug %%x
|
||||||
if !ERRORLEVEL! NEQ 0 goto :fail
|
if !ERRORLEVEL! NEQ 0 goto :fail
|
||||||
)
|
)
|
||||||
|
|
||||||
goto :done
|
goto :done
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
module rand
|
module rand
|
||||||
|
|
||||||
#flag windows -Llibraries/bcrypt -lbcrypt
|
#flag windows -Llibraries/bcrypt
|
||||||
|
#flag windows -lbcrypt
|
||||||
#include <bcrypt.h>
|
#include <bcrypt.h>
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -37,7 +37,7 @@ fn test_geometric_mean() {
|
|||||||
o = stats.geometric_mean(data)
|
o = stats.geometric_mean(data)
|
||||||
println(o)
|
println(o)
|
||||||
// Some issue with precision comparison in f64 using == operator hence serializing to string
|
// Some issue with precision comparison in f64 using == operator hence serializing to string
|
||||||
assert o.str().eq('nan') || o.str().eq('-nan') || o.str().eq('-1.#IND00') || o == f64(0) // Because in math it yields a complex number
|
assert o.str().eq('nan') || o.str().eq('-nan') || o.str().eq('-1.#IND00') || o == f64(0) || o.str().eq('-nan(ind)') // Because in math it yields a complex number
|
||||||
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)]
|
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)]
|
||||||
o = stats.geometric_mean(data)
|
o = stats.geometric_mean(data)
|
||||||
// Some issue with precision comparison in f64 using == operator hence serializing to string
|
// Some issue with precision comparison in f64 using == operator hence serializing to string
|
||||||
|
Loading…
Reference in New Issue
Block a user