1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

v.eval: add tests and fix runtime cast crash (#13019)

This commit is contained in:
pancake 2022-01-03 17:30:42 +01:00 committed by GitHub
parent 89d92d536a
commit 4b55800ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 11 deletions

View File

@ -37,6 +37,7 @@ NB: the build flags are shared with the run command too:
Specify the backend to use while building the executable.
Current list of supported backends:
* `c` (default) - V outputs C source code which is passed to a C compiler to be compiled.
* `interpret` - Same as `v interpret` to run the V program
* `js` - V outputs JS source code which can be passed to NodeJS to be ran.
* `js_browser` - V outputs JS source code ready for the browser.
* `js_node` - V outputs JS source code to run with nodejs.

View File

@ -102,6 +102,10 @@ fn (b &Builder) exit_on_invalid_syntax() {
}
fn (mut b Builder) run_compiled_executable_and_exit() {
if b.pref.backend == .interpret {
// the interpreted code has already ran
return
}
if b.pref.skip_running {
return
}

View File

@ -0,0 +1,55 @@
import os
import rand
import term
const vexe = @VEXE
fn interpreter_wrap(a string) string {
return 'fn main() {$a}'
}
fn interp_test(expression string, expected string) ? {
tmpdir := os.join_path(os.temp_dir(), 'v_interpret_test_$rand.ulid()')
os.mkdir_all(tmpdir) or {}
defer {
os.rmdir_all(tmpdir) or {}
}
//
tmpfile := os.join_path(tmpdir, 'input.v')
outfile := os.join_path(tmpdir, 'output.txt')
os.write_file(tmpfile, interpreter_wrap(expression)) ?
if os.system('"$vexe" interpret $tmpfile > $outfile') != 0 {
eprintln('>>> Failed to interpret V expression: |$expression|')
return error('v interp')
}
res := os.read_file(outfile) ?
output := res.trim_space()
if output != expected {
eprintln('>>> The output of the V expression, is not the same as the expected one')
eprintln(' V expression: $expression')
eprintln(' output: |$output|')
eprintln(' expected: |$expected|')
return error('test')
}
println('${term.colorize(term.green, 'OK')} ${term.colorize(term.bright_blue, expression.replace('\n',
' '))}')
println(' >> ${term.colorize(term.bright_yellow, output)}')
}
struct InterpTest {
input string
output string
}
fn test_interpreter() ? {
mut tests := []InterpTest{}
tests << InterpTest{'println(3+3)', '6'}
tests << InterpTest{'println(3)', '3'}
tests << InterpTest{'println(3-4)', '-1'}
tests << InterpTest{'println(3*3)', '9'}
tests << InterpTest{'a := 3\nprintln(a*3)', '9'}
for test in tests {
interp_test(test.input, test.output) ?
assert true
}
}

View File

@ -171,19 +171,26 @@ pub fn (mut e Eval) register_symbol(stmt ast.Stmt, mod string, file string) {
for i, branch in x.branches {
mut do_if := false
println('branch:$branch')
match (branch.cond as ast.Ident).name {
'windows' {
do_if = e.pref.os == .windows
match branch.cond {
ast.Ident {
match (branch.cond as ast.Ident).name {
'windows' {
do_if = e.pref.os == .windows
}
else {
e.error('unknown compile time if')
}
}
do_if = do_if || x.branches.len == i + 1
if do_if {
e.register_symbol_stmts(branch.stmts, mod, file)
break
}
}
else {
e.error('unknown compile time if')
eprintln('unsupported expression')
}
}
do_if = do_if || x.branches.len == i + 1
if do_if {
e.register_symbol_stmts(branch.stmts, mod, file)
break
}
}
}
else {

View File

@ -133,7 +133,7 @@ fn test_parse_expr() {
mut e := []ast.Stmt{}
table := ast.new_table()
vpref := &pref.Preferences{}
mut checker := checker.new_checker(table, vpref)
mut chk := checker.new_checker(table, vpref)
scope := &ast.Scope{
start_pos: 0
parent: 0
@ -147,7 +147,7 @@ fn test_parse_expr() {
scope: scope
global_scope: scope
}
checker.check(program)
chk.check(program)
res := c.gen([program], table, vpref).after('#endif')
println('========')
println(res)