v.eval: add tests and fix runtime cast crash (#13019)
							parent
							
								
									89d92d536a
								
							
						
					
					
						commit
						4b55800ffd
					
				|  | @ -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. | ||||
|  |  | |||
|  | @ -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 | ||||
| 	} | ||||
|  |  | |||
|  | @ -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 | ||||
| 	} | ||||
| } | ||||
|  | @ -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 { | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue