parser: disallow statements after a return, branch check $if, $else, switch, and loops correctly
parent
58b52aa9fb
commit
1864e92ff4
|
@ -263,7 +263,6 @@ fn build_thirdparty_obj_file(flag string) {
|
||||||
cc := if os.user_os() == 'windows' { 'gcc' } else { 'cc' } // TODO clang support on Windows
|
cc := if os.user_os() == 'windows' { 'gcc' } else { 'cc' } // TODO clang support on Windows
|
||||||
res := os.exec('$cc -fPIC -c -o $obj_path $cfiles') or {
|
res := os.exec('$cc -fPIC -c -o $obj_path $cfiles') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
println(res)
|
println(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,20 @@ fn (p mut Parser) comp_time() {
|
||||||
println(SupportedPlatforms)
|
println(SupportedPlatforms)
|
||||||
p.error('unknown platform `$name`')
|
p.error('unknown platform `$name`')
|
||||||
}
|
}
|
||||||
|
if_returns := p.returns
|
||||||
|
p.returns = false
|
||||||
|
p.gen('/* returns $p.returns */')
|
||||||
|
if p.tok == .dollar && p.peek() == .key_else {
|
||||||
|
p.next()
|
||||||
|
p.next()
|
||||||
|
p.check(.lcbr)
|
||||||
|
p.genln('#else')
|
||||||
|
p.statements_no_rcbr()
|
||||||
|
p.genln('#endif')
|
||||||
|
else_returns := p.returns
|
||||||
|
p.returns = if_returns && else_returns
|
||||||
|
p.gen('/* returns $p.returns */')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if p.tok == .key_for {
|
else if p.tok == .key_for {
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -65,13 +79,6 @@ fn (p mut Parser) comp_time() {
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else if p.tok == .key_else {
|
|
||||||
p.next()
|
|
||||||
p.check(.lcbr)
|
|
||||||
p.genln('#else')
|
|
||||||
p.statements_no_rcbr()
|
|
||||||
p.genln('#endif')
|
|
||||||
}
|
|
||||||
// $vweb.html()
|
// $vweb.html()
|
||||||
// Compile vweb html template to V code, parse that V code and embed the resulting V functions
|
// Compile vweb html template to V code, parse that V code and embed the resulting V functions
|
||||||
// that returns an html string
|
// that returns an html string
|
||||||
|
|
|
@ -124,6 +124,7 @@ fn (p mut Parser) fn_decl() {
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
p.returns = false
|
p.returns = false
|
||||||
|
p.gen('/* returns $p.returns */')
|
||||||
p.next()
|
p.next()
|
||||||
mut f := new_fn(p.mod, is_pub)
|
mut f := new_fn(p.mod, is_pub)
|
||||||
// Method receiver
|
// Method receiver
|
||||||
|
|
|
@ -139,14 +139,12 @@ fn main() {
|
||||||
vexec := os.args[0]
|
vexec := os.args[0]
|
||||||
_ := os.exec('$vexec vget.v') or {
|
_ := os.exec('$vexec vget.v') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
//println('Done.')
|
//println('Done.')
|
||||||
}
|
}
|
||||||
println('Installing module ${mod}...')
|
println('Installing module ${mod}...')
|
||||||
_ := os.exec('$vget $mod') or {
|
_ := os.exec('$vget $mod') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -891,7 +889,6 @@ mut args := ''
|
||||||
}
|
}
|
||||||
panic('C error. This should never happen. ' +
|
panic('C error. This should never happen. ' +
|
||||||
'Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose')
|
'Please create a GitHub issue: https://github.com/vlang/v/issues/new/choose')
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
diff := time.ticks() - ticks
|
diff := time.ticks() - ticks
|
||||||
// Print the C command
|
// Print the C command
|
||||||
|
@ -914,7 +911,6 @@ mut args := ''
|
||||||
' /usr/lib/x86_64-linux-gnu/libc.so ' +
|
' /usr/lib/x86_64-linux-gnu/libc.so ' +
|
||||||
'/usr/lib/x86_64-linux-gnu/crtn.o') or {
|
'/usr/lib/x86_64-linux-gnu/crtn.o') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
println(ress)
|
println(ress)
|
||||||
println('linux cross compilation done. resulting binary: "$v.out_name"')
|
println('linux cross compilation done. resulting binary: "$v.out_name"')
|
||||||
|
@ -1226,7 +1222,7 @@ fn new_v(args[]string) *V {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
println('vlib not found. It should be next to the V executable. ')
|
println('vlib not found. It should be next to the V executable. ')
|
||||||
println('Go to https://vlang.io to install V.')
|
println('Go to https://vlang.io to install V.')
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
mut out_name_c := out_name.all_after('/') + '.c'
|
mut out_name_c := out_name.all_after('/') + '.c'
|
||||||
|
@ -1327,7 +1323,6 @@ fn run_repl() []string {
|
||||||
os.write_file(file, source_code)
|
os.write_file(file, source_code)
|
||||||
s := os.exec('$vexe run $file -repl') or {
|
s := os.exec('$vexe run $file -repl') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
break // TODO remove break
|
|
||||||
}
|
}
|
||||||
vals := s.split('\n')
|
vals := s.split('\n')
|
||||||
for i:=0; i < vals.len; i++ {
|
for i:=0; i < vals.len; i++ {
|
||||||
|
@ -1345,7 +1340,6 @@ fn run_repl() []string {
|
||||||
os.write_file(temp_file, temp_source_code)
|
os.write_file(temp_file, temp_source_code)
|
||||||
s := os.exec('$vexe run $temp_file -repl') or {
|
s := os.exec('$vexe run $temp_file -repl') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
break // TODO remove break
|
|
||||||
}
|
}
|
||||||
lines << line
|
lines << line
|
||||||
vals := s.split('\n')
|
vals := s.split('\n')
|
||||||
|
@ -1411,20 +1405,17 @@ fn update_v() {
|
||||||
vroot := os.dir(os.executable())
|
vroot := os.dir(os.executable())
|
||||||
s := os.exec('git -C "$vroot" pull --rebase origin master') or {
|
s := os.exec('git -C "$vroot" pull --rebase origin master') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
println(s)
|
println(s)
|
||||||
$if windows {
|
$if windows {
|
||||||
os.mv('$vroot/v.exe', '$vroot/v_old.exe')
|
os.mv('$vroot/v.exe', '$vroot/v_old.exe')
|
||||||
s2 := os.exec('$vroot/make.bat') or {
|
s2 := os.exec('$vroot/make.bat') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
println(s2)
|
println(s2)
|
||||||
} $else {
|
} $else {
|
||||||
s2 := os.exec('make -C "$vroot"') or {
|
s2 := os.exec('make -C "$vroot"') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
println(s2)
|
println(s2)
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,37 +28,40 @@ const (
|
||||||
KEY_ENUMERATE_SUB_KEYS = (0x0008)
|
KEY_ENUMERATE_SUB_KEYS = (0x0008)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Given a root key look for the subkey 'version' and get the path
|
// Given a root key look for one of the subkeys in 'versions' and get the path
|
||||||
fn find_windows_kit_internal(key RegKey, version string) ?string {
|
fn find_windows_kit_internal(key RegKey, versions []string) ?string {
|
||||||
required_bytes := 0 // TODO mut
|
for version in versions {
|
||||||
result := C.RegQueryValueExW(key, version.to_wide(), 0, 0, 0, &required_bytes)
|
required_bytes := 0 // TODO mut
|
||||||
|
result := C.RegQueryValueExW(key, version.to_wide(), 0, 0, 0, &required_bytes)
|
||||||
|
|
||||||
length := required_bytes / 2
|
length := required_bytes / 2
|
||||||
|
|
||||||
if result != 0 {
|
if result != 0 {
|
||||||
return error('')
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc_length := (required_bytes + 2)
|
||||||
|
|
||||||
|
mut value := &u16(malloc(alloc_length))
|
||||||
|
if !value {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
result2 := C.RegQueryValueExW(key, version.to_wide(), 0, 0, value, &alloc_length)
|
||||||
|
|
||||||
|
if result2 != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// We might need to manually null terminate this thing
|
||||||
|
// So just make sure that we do that
|
||||||
|
if (value[length - 1] != u16(0)) {
|
||||||
|
value[length] = u16(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string_from_wide(value)
|
||||||
}
|
}
|
||||||
|
return error('windows kit not found')
|
||||||
alloc_length := (required_bytes + 2)
|
|
||||||
|
|
||||||
mut value := &u16(malloc(alloc_length))
|
|
||||||
if !value {
|
|
||||||
return error('')
|
|
||||||
}
|
|
||||||
|
|
||||||
result2 := C.RegQueryValueExW(key, version.to_wide(), 0, 0, value, &alloc_length)
|
|
||||||
|
|
||||||
if result2 != 0 {
|
|
||||||
return error('')
|
|
||||||
}
|
|
||||||
|
|
||||||
// We might need to manually null terminate this thing
|
|
||||||
// So just make sure that we do that
|
|
||||||
if (value[length - 1] != u16(0)) {
|
|
||||||
value[length] = u16(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string_from_wide(value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WindowsKit {
|
struct WindowsKit {
|
||||||
|
@ -82,13 +85,8 @@ fn find_windows_kit_root() ?WindowsKit {
|
||||||
return error('Unable to open root key')
|
return error('Unable to open root key')
|
||||||
}
|
}
|
||||||
// Try and find win10 kit
|
// Try and find win10 kit
|
||||||
kit_root := find_windows_kit_internal(root_key, 'KitsRoot10') or {
|
kit_root := find_windows_kit_internal(root_key, ['KitsRoot10', 'KitsRoot81']) or {
|
||||||
// Fallback to windows 8
|
return error('Unable to find a windows kit')
|
||||||
k := find_windows_kit_internal(root_key, 'KitsRoot81') or {
|
|
||||||
println('Unable to find windows sdk')
|
|
||||||
return error('Unable to find a windows kit')
|
|
||||||
}
|
|
||||||
k
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kit_lib := kit_root + 'Lib'
|
kit_lib := kit_root + 'Lib'
|
||||||
|
@ -135,8 +133,7 @@ fn find_vs() ?VsInstallation {
|
||||||
// If its not there then end user needs to update their visual studio
|
// If its not there then end user needs to update their visual studio
|
||||||
// installation!
|
// installation!
|
||||||
res := os.exec('""%ProgramFiles(x86)%\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath"') or {
|
res := os.exec('""%ProgramFiles(x86)%\\Microsoft Visual Studio\\Installer\\vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath"') or {
|
||||||
panic(err)
|
return error(err)
|
||||||
return error(err)// TODO remove return
|
|
||||||
}
|
}
|
||||||
// println('res: "$res"')
|
// println('res: "$res"')
|
||||||
|
|
||||||
|
@ -347,7 +344,6 @@ pub fn (v mut V) cc_msvc() {
|
||||||
_ := os.exec(cmd) or {
|
_ := os.exec(cmd) or {
|
||||||
println(err)
|
println(err)
|
||||||
panic('msvc error')
|
panic('msvc error')
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
// println(res)
|
// println(res)
|
||||||
// println('C OUTPUT:')
|
// println('C OUTPUT:')
|
||||||
|
@ -391,7 +387,6 @@ fn build_thirdparty_obj_file_with_msvc(flag string) {
|
||||||
|
|
||||||
res := os.exec('""$msvc.exe_path\\cl.exe" /volatile:ms /Z7 $include_string /c $cfiles /Fo"$obj_path" /D_UNICODE /DUNICODE"') or {
|
res := os.exec('""$msvc.exe_path\\cl.exe" /volatile:ms /Z7 $include_string /c $cfiles /Fo"$obj_path" /D_UNICODE /DUNICODE"') or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
println(res)
|
println(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,6 @@ fn platform_postfix_to_ifdefguard(name string) string {
|
||||||
case '_mac.v': return '#ifdef __APPLE__'
|
case '_mac.v': return '#ifdef __APPLE__'
|
||||||
}
|
}
|
||||||
panic('bad platform_postfix "$name"')
|
panic('bad platform_postfix "$name"')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (v mut V) new_parser(path string, pass Pass) Parser {
|
fn (v mut V) new_parser(path string, pass Pass) Parser {
|
||||||
|
@ -296,7 +295,6 @@ fn (p mut Parser) parse() {
|
||||||
if false && !p.first_pass() && p.fileis('main.v') {
|
if false && !p.first_pass() && p.fileis('main.v') {
|
||||||
out := os.create('/var/tmp/fmt.v') or {
|
out := os.create('/var/tmp/fmt.v') or {
|
||||||
panic('failed to create fmt.v')
|
panic('failed to create fmt.v')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
out.writeln(p.scanner.fmt_out.str())
|
out.writeln(p.scanner.fmt_out.str())
|
||||||
out.close()
|
out.close()
|
||||||
|
@ -1103,6 +1101,9 @@ fn (p mut Parser) vh_genln(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) statement(add_semi bool) string {
|
fn (p mut Parser) statement(add_semi bool) string {
|
||||||
|
if(p.returns) {
|
||||||
|
p.error('unreachable code')
|
||||||
|
}
|
||||||
p.cgen.is_tmp = false
|
p.cgen.is_tmp = false
|
||||||
tok := p.tok
|
tok := p.tok
|
||||||
mut q := ''
|
mut q := ''
|
||||||
|
@ -1321,6 +1322,7 @@ fn (p mut Parser) var_decl() {
|
||||||
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
|
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
|
||||||
p.error('`or` block must return/continue/break/panic')
|
p.error('`or` block must return/continue/break/panic')
|
||||||
}
|
}
|
||||||
|
p.returns = false
|
||||||
}
|
}
|
||||||
p.register_var(Var {
|
p.register_var(Var {
|
||||||
name: name
|
name: name
|
||||||
|
@ -1983,7 +1985,6 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||||
p.cgen.insert_before('$typ $tmp = $tmp_val;')
|
p.cgen.insert_before('$typ $tmp = $tmp_val;')
|
||||||
}
|
}
|
||||||
return typ
|
return typ
|
||||||
return 'void'
|
|
||||||
}
|
}
|
||||||
// else if p.pref.is_verbose && p.assigned_var != '' {
|
// else if p.pref.is_verbose && p.assigned_var != '' {
|
||||||
// p.error('didnt assign')
|
// p.error('didnt assign')
|
||||||
|
@ -2905,7 +2906,6 @@ fn os_name_to_ifdef(name string) string {
|
||||||
case 'msvc': return '_MSC_VER'
|
case 'msvc': return '_MSC_VER'
|
||||||
}
|
}
|
||||||
panic('bad os ifdef name "$name"')
|
panic('bad os ifdef name "$name"')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) if_st(is_expr bool, elif_depth int) string {
|
fn (p mut Parser) if_st(is_expr bool, elif_depth int) string {
|
||||||
|
@ -3167,6 +3167,7 @@ fn (p mut Parser) for_st() {
|
||||||
p.statements()
|
p.statements()
|
||||||
p.close_scope()
|
p.close_scope()
|
||||||
p.for_expr_cnt--
|
p.for_expr_cnt--
|
||||||
|
p.returns = false // TODO handle loops that are guaranteed to return
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) switch_statement() {
|
fn (p mut Parser) switch_statement() {
|
||||||
|
@ -3180,7 +3181,9 @@ fn (p mut Parser) switch_statement() {
|
||||||
expr := p.cgen.end_tmp()
|
expr := p.cgen.end_tmp()
|
||||||
p.check(.lcbr)
|
p.check(.lcbr)
|
||||||
mut i := 0
|
mut i := 0
|
||||||
|
mut all_cases_return := true
|
||||||
for p.tok == .key_case || p.tok == .key_default || p.peek() == .arrow || p.tok == .key_else {
|
for p.tok == .key_case || p.tok == .key_default || p.peek() == .arrow || p.tok == .key_else {
|
||||||
|
p.returns = false
|
||||||
if p.tok == .key_default || p.tok == .key_else {
|
if p.tok == .key_default || p.tok == .key_else {
|
||||||
p.genln('else { // default:')
|
p.genln('else { // default:')
|
||||||
if p.tok == .key_default {
|
if p.tok == .key_default {
|
||||||
|
@ -3191,7 +3194,8 @@ fn (p mut Parser) switch_statement() {
|
||||||
p.check(.arrow)
|
p.check(.arrow)
|
||||||
}
|
}
|
||||||
p.statements()
|
p.statements()
|
||||||
break
|
p.returns = all_cases_return && p.returns
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
p.gen('else ')
|
p.gen('else ')
|
||||||
|
@ -3228,8 +3232,10 @@ fn (p mut Parser) switch_statement() {
|
||||||
p.gen(')) {')
|
p.gen(')) {')
|
||||||
p.genln('/* case */')
|
p.genln('/* case */')
|
||||||
p.statements()
|
p.statements()
|
||||||
|
all_cases_return = all_cases_return && p.returns
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
p.returns = false // only get here when no default, so return is not guaranteed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) assert_statement() {
|
fn (p mut Parser) assert_statement() {
|
||||||
|
|
|
@ -33,7 +33,6 @@ fn new_scanner(file_path string) *Scanner {
|
||||||
|
|
||||||
mut raw_text := os.read_file(file_path) or {
|
mut raw_text := os.read_file(file_path) or {
|
||||||
panic('scanner: failed to open "$file_path"')
|
panic('scanner: failed to open "$file_path"')
|
||||||
return &Scanner{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOM check
|
// BOM check
|
||||||
|
|
|
@ -739,8 +739,7 @@ fn (t mut Table) fn_gen_types(fn_name string) []string {
|
||||||
return f.types
|
return f.types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
panic('function $fn_name not found') // TODO panic or return []?
|
panic('function $fn_name not found')
|
||||||
return []string // TODO remove return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// `foo<Bar>()`
|
// `foo<Bar>()`
|
||||||
|
@ -830,7 +829,6 @@ fn (fit mut FileImportTable) register_import(mod string) {
|
||||||
fn (fit mut FileImportTable) register_alias(alias string, mod string) {
|
fn (fit mut FileImportTable) register_alias(alias string, mod string) {
|
||||||
if alias in fit.imports {
|
if alias in fit.imports {
|
||||||
panic('cannot import $mod as $alias: import name $alias already in use in "${fit.file_path}".')
|
panic('cannot import $mod as $alias: import name $alias already in use in "${fit.file_path}".')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if mod.contains('.internal.') {
|
if mod.contains('.internal.') {
|
||||||
mod_parts := mod.split('.')
|
mod_parts := mod.split('.')
|
||||||
|
|
|
@ -19,7 +19,6 @@ fn err_call(ok bool) ?int {
|
||||||
fn test_option_for_base_type_without_variable() {
|
fn test_option_for_base_type_without_variable() {
|
||||||
val := err_call(true) or {
|
val := err_call(true) or {
|
||||||
panic(err)
|
panic(err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
assert val == 42
|
assert val == 42
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,10 @@ fn (f mut Fetcher) fetch() {
|
||||||
resp := http.get('https://hacker-news.firebaseio.com/v0/item/${id}.json') or {
|
resp := http.get('https://hacker-news.firebaseio.com/v0/item/${id}.json') or {
|
||||||
println('failed to fetch data from /v0/item/${id}.json')
|
println('failed to fetch data from /v0/item/${id}.json')
|
||||||
exit(1)
|
exit(1)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
story := json.decode(Story, resp.text) or {
|
story := json.decode(Story, resp.text) or {
|
||||||
println('failed to decode a story')
|
println('failed to decode a story')
|
||||||
exit(1)
|
exit(1)
|
||||||
return // TODO remove return
|
|
||||||
}
|
}
|
||||||
f.wg.done()
|
f.wg.done()
|
||||||
println('#$cursor) $story.title | $story.url')
|
println('#$cursor) $story.title | $story.url')
|
||||||
|
|
|
@ -1,29 +1,49 @@
|
||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
|
echo fetch v.c
|
||||||
curl -O https://raw.githubusercontent.com/vlang/vc/master/v.c
|
curl -O https://raw.githubusercontent.com/vlang/vc/master/v.c
|
||||||
|
if %ERRORLEVEL% NEQ 0 goto :fail
|
||||||
|
|
||||||
|
echo build vc using gcc
|
||||||
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
|
||||||
|
if %ERRORLEVEL% NEQ 0 goto :fail
|
||||||
|
|
||||||
|
echo build v using vc
|
||||||
vc.exe -o v.exe compiler
|
vc.exe -o v.exe compiler
|
||||||
|
if %ERRORLEVEL% NEQ 0 goto :fail
|
||||||
|
|
||||||
|
echo build v.msvc using v
|
||||||
v.exe -os msvc -o v.msvc.exe compiler
|
v.exe -os msvc -o v.msvc.exe compiler
|
||||||
|
if %ERRORLEVEL% NEQ 0 goto :fail
|
||||||
|
|
||||||
|
echo build v.msvc.2 using v.msvc
|
||||||
v.msvc.exe -os msvc -o v.msvc.2.exe compiler
|
v.msvc.exe -os msvc -o v.msvc.2.exe compiler
|
||||||
|
if %ERRORLEVEL% NEQ 0 goto :fail
|
||||||
|
|
||||||
|
echo build v.gcc using v.msvc
|
||||||
v.msvc.exe -o v.gcc.exe compiler
|
v.msvc.exe -o v.gcc.exe compiler
|
||||||
|
if %ERRORLEVEL% NEQ 0 goto :fail
|
||||||
|
|
||||||
setlocal EnableDelayedExpansion
|
setlocal EnableDelayedExpansion
|
||||||
|
echo testing v
|
||||||
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
|
||||||
if !ERRORLEVEL! NEQ 0 goto :fail
|
if !ERRORLEVEL! NEQ 0 goto :fail
|
||||||
)
|
)
|
||||||
|
echo testing v.msvc
|
||||||
for /r . %%x in (*_test.v) do (
|
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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
echo testing v -os msvc
|
||||||
for /r . %%x in (*_test.v) do (
|
for /r . %%x in (*_test.v) do (
|
||||||
v -os msvc -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
echo testing v.msvc -os msvc
|
||||||
for /r . %%x in (*_test.v) do (
|
for /r . %%x in (*_test.v) do (
|
||||||
v.msvc.exe -os msvc -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
|
||||||
|
@ -36,3 +56,4 @@ echo fail
|
||||||
exit /b 1
|
exit /b 1
|
||||||
|
|
||||||
:done
|
:done
|
||||||
|
echo pass
|
|
@ -77,7 +77,6 @@ pub fn (a mut array) sort_with_compare(compare voidptr) {
|
||||||
pub fn (a mut array) insert(i int, val voidptr) {
|
pub fn (a mut array) insert(i int, val voidptr) {
|
||||||
if i >= a.len {
|
if i >= a.len {
|
||||||
panic('array.insert: index larger than length')
|
panic('array.insert: index larger than length')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
a._push(val)
|
a._push(val)
|
||||||
size := a.element_size
|
size := a.element_size
|
||||||
|
|
|
@ -18,7 +18,9 @@ fn on_panic(f fn (int) int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_backtrace() {
|
pub fn print_backtrace() {
|
||||||
return
|
if true {
|
||||||
|
return // TODO
|
||||||
|
}
|
||||||
$if mac {
|
$if mac {
|
||||||
buffer := [100]voidptr
|
buffer := [100]voidptr
|
||||||
nr_ptrs := C.backtrace(buffer, 100)
|
nr_ptrs := C.backtrace(buffer, 100)
|
||||||
|
|
|
@ -94,8 +94,7 @@ fn (n & Node) find(key string, out voidptr, element_size int) bool{
|
||||||
} else {
|
} else {
|
||||||
return n.right.find(key, out, element_size)
|
return n.right.find(key, out, element_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// same as `find`, but doesn't return a value. Used by `exists`
|
// same as `find`, but doesn't return a value. Used by `exists`
|
||||||
|
@ -116,8 +115,7 @@ fn (n & Node) find2(key string, element_size int) bool{
|
||||||
} else {
|
} else {
|
||||||
return n.right.find2(key, element_size)
|
return n.right.find2(key, element_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (m mut map) _set(key string, val voidptr) {
|
fn (m mut map) _set(key string, val voidptr) {
|
||||||
|
@ -215,7 +213,6 @@ pub fn (m mut map) delete(key string) {
|
||||||
|
|
||||||
pub fn (m map) exists(key string) bool {
|
pub fn (m map) exists(key string) bool {
|
||||||
panic('map.exists(key) was removed from the language. Use `key in map` instead.')
|
panic('map.exists(key) was removed from the language. Use `key in map` instead.')
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (m map) _exists(key string) bool {
|
fn (m map) _exists(key string) bool {
|
||||||
|
|
|
@ -40,7 +40,6 @@ pub fn tos(s byteptr, len int) string {
|
||||||
pub fn tos_clone(s byteptr) string {
|
pub fn tos_clone(s byteptr) string {
|
||||||
if isnil(s) {
|
if isnil(s) {
|
||||||
panic('tos: nil string')
|
panic('tos: nil string')
|
||||||
return string{}
|
|
||||||
}
|
}
|
||||||
len := strlen(s)
|
len := strlen(s)
|
||||||
res := tos(s, len)
|
res := tos(s, len)
|
||||||
|
@ -52,7 +51,6 @@ pub fn tos_clone(s byteptr) string {
|
||||||
fn tos2(s byteptr) string {
|
fn tos2(s byteptr) string {
|
||||||
if isnil(s) {
|
if isnil(s) {
|
||||||
panic('tos2: nil string')
|
panic('tos2: nil string')
|
||||||
return string{}
|
|
||||||
}
|
}
|
||||||
len := C.strlen(s)
|
len := C.strlen(s)
|
||||||
res := tos(s, len)
|
res := tos(s, len)
|
||||||
|
@ -337,7 +335,6 @@ pub fn (s string) right(n int) string {
|
||||||
pub fn (s string) substr(start, end int) string {
|
pub fn (s string) substr(start, end int) string {
|
||||||
if start > end || start > s.len || end > s.len || start < 0 || end < 0 {
|
if start > end || start > s.len || end > s.len || start < 0 || end < 0 {
|
||||||
panic('substr($start, $end) out of bounds (len=$s.len)')
|
panic('substr($start, $end) out of bounds (len=$s.len)')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
len := end - start
|
len := end - start
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,8 @@ struct Cfg {
|
||||||
fn ft_load_char(_face Face, code i64) Character {
|
fn ft_load_char(_face Face, code i64) Character {
|
||||||
// #FT_Face face = *(FT_Face*)(_face); FT_ULong code = *(FT_ULong*)(code);
|
// #FT_Face face = *(FT_Face*)(_face); FT_ULong code = *(FT_ULong*)(code);
|
||||||
# FT_Face face = *((FT_Face*)_face.cobj);
|
# FT_Face face = *((FT_Face*)_face.cobj);
|
||||||
# if (FT_Load_Char(face, code, FT_LOAD_RENDER))
|
# int condition = FT_Load_Char(face, code, FT_LOAD_RENDER);
|
||||||
|
if (C.condition != 0)
|
||||||
{
|
{
|
||||||
println('freetype: Failed to load Glyph')
|
println('freetype: Failed to load Glyph')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
@ -170,7 +171,8 @@ pub fn new_context(cfg gg.Cfg) *Context {
|
||||||
}
|
}
|
||||||
println('Trying to load font from $font_path')
|
println('Trying to load font from $font_path')
|
||||||
# FT_Face face;
|
# FT_Face face;
|
||||||
# if (FT_New_Face(ft, font_path.str, 0, &face))
|
# int condition = FT_New_Face(ft, font_path.str, 0, &face);
|
||||||
|
if (C.condition != 0)
|
||||||
// # if (FT_New_Face(ft, "/Library/Fonts/Courier New.ttf", 0, &face))
|
// # if (FT_New_Face(ft, "/Library/Fonts/Courier New.ttf", 0, &face))
|
||||||
// # if (FT_New_Face(ft, "/System/Library/Fonts/Apple Color Emoji.ttc", 0, &face))
|
// # if (FT_New_Face(ft, "/System/Library/Fonts/Apple Color Emoji.ttc", 0, &face))
|
||||||
{
|
{
|
||||||
|
|
|
@ -274,7 +274,7 @@ pub fn (ctx &GG) draw_rect2(x, y, w, h f32, c gx.Color) {
|
||||||
fn todo_remove_me(cfg Cfg, scale int) {
|
fn todo_remove_me(cfg Cfg, scale int) {
|
||||||
// Can only have text in ortho mode
|
// Can only have text in ortho mode
|
||||||
if !cfg.use_ortho {
|
if !cfg.use_ortho {
|
||||||
return &GG{}
|
return
|
||||||
}
|
}
|
||||||
mut width := cfg.width * scale
|
mut width := cfg.width * scale
|
||||||
mut height := cfg.height * scale
|
mut height := cfg.height * scale
|
||||||
|
|
|
@ -169,22 +169,18 @@ fn build_request_headers(user_agent, method, host_name, path string) string {
|
||||||
|
|
||||||
pub fn unescape_url(s string) string {
|
pub fn unescape_url(s string) string {
|
||||||
panic('http.unescape_url() was replaced with urllib.query_unescape()')
|
panic('http.unescape_url() was replaced with urllib.query_unescape()')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn escape_url(s string) string {
|
pub fn escape_url(s string) string {
|
||||||
panic('http.escape_url() was replaced with urllib.query_escape()')
|
panic('http.escape_url() was replaced with urllib.query_escape()')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unescape(s string) string {
|
pub fn unescape(s string) string {
|
||||||
panic('http.unescape() was replaced with http.unescape_url()')
|
panic('http.unescape() was replaced with http.unescape_url()')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn escape(s string) string {
|
pub fn escape(s string) string {
|
||||||
panic('http.escape() was replaced with http.escape_url()')
|
panic('http.escape() was replaced with http.escape_url()')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type wsfn fn (s string, ptr voidptr)
|
type wsfn fn (s string, ptr voidptr)
|
||||||
|
|
|
@ -9,7 +9,6 @@ fn test_parse_user() {
|
||||||
s := '{"age": 10, "nums": [1,2,3]}'
|
s := '{"age": 10, "nums": [1,2,3]}'
|
||||||
u := json.decode(User, s) or {
|
u := json.decode(User, s) or {
|
||||||
exit(1)
|
exit(1)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
assert u.age == 10
|
assert u.age == 10
|
||||||
assert u.nums.len == 3
|
assert u.nums.len == 3
|
||||||
|
|
|
@ -39,7 +39,6 @@ fn (l Log) log_file(s string, e string) {
|
||||||
filename := l.output
|
filename := l.output
|
||||||
f := os.open_append(l.output) or {
|
f := os.open_append(l.output) or {
|
||||||
panic('error reading file $filename')
|
panic('error reading file $filename')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
timestamp := time.now().format_ss()
|
timestamp := time.now().format_ss()
|
||||||
f.writeln('$timestamp [$e] $s')
|
f.writeln('$timestamp [$e] $s')
|
||||||
|
|
|
@ -19,7 +19,6 @@ pub fn fraction(n i64, d i64) Fraction{
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('Denominator cannot be zero')
|
panic('Denominator cannot be zero')
|
||||||
return Fraction{} // TODO remove return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -870,6 +870,7 @@ pub fn fork() int {
|
||||||
pid := C.fork()
|
pid := C.fork()
|
||||||
return pid
|
return pid
|
||||||
}
|
}
|
||||||
|
panic('os.fork not supported in windows') // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait() int {
|
pub fn wait() int {
|
||||||
|
@ -877,6 +878,7 @@ pub fn wait() int {
|
||||||
pid := C.wait(0)
|
pid := C.wait(0)
|
||||||
return pid
|
return pid
|
||||||
}
|
}
|
||||||
|
panic('os.wait not supported in windows') // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_last_mod_unix(path string) int {
|
pub fn file_last_mod_unix(path string) int {
|
||||||
|
|
|
@ -27,7 +27,6 @@ fn test_write_and_read_string_to_file() {
|
||||||
|
|
||||||
read_hello := os.read_file(filename) or {
|
read_hello := os.read_file(filename) or {
|
||||||
panic('error reading file $filename')
|
panic('error reading file $filename')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
assert hello == read_hello
|
assert hello == read_hello
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub fn get_module_filename(handle HANDLE) ?string {
|
||||||
return error('Cannot get file name from handle.')
|
return error('Cannot get file name from handle.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
panic('this should be unreachable') // TODO remove unreachable after loop
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ref - https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagea#parameters
|
// Ref - https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessagea#parameters
|
||||||
|
|
|
@ -17,13 +17,11 @@ pub fn compile_template(path string) string {
|
||||||
//lines := os.read_lines(path)
|
//lines := os.read_lines(path)
|
||||||
mut html := os.read_file(path) or {
|
mut html := os.read_file(path) or {
|
||||||
panic('html failed')
|
panic('html failed')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
mut header := ''
|
mut header := ''
|
||||||
if os.file_exists('header.html') {
|
if os.file_exists('header.html') {
|
||||||
h := os.read_file('header.html') or {
|
h := os.read_file('header.html') or {
|
||||||
panic('html failed')
|
panic('html failed')
|
||||||
return ''
|
|
||||||
}
|
}
|
||||||
header = h.replace('\'', '"')
|
header = h.replace('\'', '"')
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,13 +85,12 @@ $html
|
||||||
|
|
||||||
pub fn run<T>(port int) {
|
pub fn run<T>(port int) {
|
||||||
println('Running vweb app on http://localhost:$port ...')
|
println('Running vweb app on http://localhost:$port ...')
|
||||||
l := net.listen(port) or { panic('failed to listen') return }
|
l := net.listen(port) or { panic('failed to listen') }
|
||||||
mut app := T{}
|
mut app := T{}
|
||||||
app.init()
|
app.init()
|
||||||
for {
|
for {
|
||||||
conn := l.accept() or {
|
conn := l.accept() or {
|
||||||
panic('accept() failed')
|
panic('accept() failed')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// TODO move this to handle_conn<T>(conn, app)
|
// TODO move this to handle_conn<T>(conn, app)
|
||||||
s := conn.read_line()
|
s := conn.read_line()
|
||||||
|
|
Loading…
Reference in New Issue