From e1d2c83ff6d6b5b9b7ad50bd56f08129cbbf5c2c Mon Sep 17 00:00:00 2001 From: Henrixounez <30901439+Henrixounez@users.noreply.github.com> Date: Sun, 18 Aug 2019 21:50:38 +0200 Subject: [PATCH] repl: functions and conditional blocks support --- compiler/main.v | 63 --------- compiler/repl.v | 148 ++++++++++++++++++++ compiler/tests/repl/conditional_blocks.repl | 18 +++ compiler/tests/repl/function.repl | 11 ++ compiler/tests/repl/repl_test.v | 2 +- 5 files changed, 178 insertions(+), 64 deletions(-) create mode 100644 compiler/repl.v create mode 100644 compiler/tests/repl/conditional_blocks.repl create mode 100644 compiler/tests/repl/function.repl diff --git a/compiler/main.v b/compiler/main.v index c2cb7026ae..03ae2b27d5 100644 --- a/compiler/main.v +++ b/compiler/main.v @@ -1323,69 +1323,6 @@ fn new_v(args[]string) *V { } } -fn run_repl() []string { - println('V $Version') - println('Use Ctrl-C or `exit` to exit') - file := '.vrepl.v' - temp_file := '.vrepl_temp.v' - defer { - os.rm(file) - os.rm(temp_file) - os.rm(file.left(file.len - 2)) - os.rm(temp_file.left(temp_file.len - 2)) - } - mut lines := []string - vexe := os.args[0] - for { - print('>>> ') - mut line := os.get_raw_line() - if line.trim_space() == '' && line.ends_with('\n') { - continue - } - line = line.trim_space() - if line.len == -1 || line == '' || line == 'exit' { - break - } - if line == '\n' { - continue - } - // Save the source only if the user is printing something, - // but don't add this print call to the `lines` array, - // so that it doesn't get called during the next print. - if line.starts_with('print') { - source_code := lines.join('\n') + '\n' + line - os.write_file(file, source_code) - s := os.exec('$vexe run $file -repl') or { - panic(err) - } - vals := s.output.split('\n') - for i:=0; i < vals.len; i++ { - println(vals[i]) - } - } - else { - mut temp_line := line - mut temp_flag := false - if !(line.contains(' ') || line.contains(':') || line.contains('=') || line.contains(',') ){ - temp_line = 'println($line)' - temp_flag = true - } - temp_source_code := lines.join('\n') + '\n' + temp_line - os.write_file(temp_file, temp_source_code) - s := os.exec('$vexe run $temp_file -repl') or { - panic(err) - } - if !s.exit_code { - lines << line - } - vals := s.output.split('\n') - for i:=0; i 0 +} + +fn (r mut Repl) function_call(line string) bool { + for function in r.functions_name { + if line.starts_with(function) { + return true + } + } + return false +} + +fn run_repl() []string { + println('V $Version') + println('Use Ctrl-C or `exit` to exit') + file := '.vrepl.v' + temp_file := '.vrepl_temp.v' + defer { + os.rm(file) + os.rm(temp_file) + os.rm(file.left(file.len - 2)) + os.rm(temp_file.left(temp_file.len - 2)) + } + mut r := Repl{} + vexe := os.args[0] + for { + if r.indent == 0 { + print('>>> ') + } + else { + print('... ') + } + mut line := os.get_raw_line() + if line.trim_space() == '' && line.ends_with('\n') { + continue + } + line = line.trim_space() + if line.len == -1 || line == '' || line == 'exit' { + break + } + if line == '\n' { + continue + } + if line.starts_with('fn') { + r.in_func = true + r.functions_name << line.all_after('fn').all_before('(').trim_space() + } + was_func := r.in_func + if r.checks(line) { + if r.in_func || was_func { + r.functions << line + } + else { + r.temp_lines << line + } + if r.indent > 0 { + continue + } + line = '' + } + // Save the source only if the user is printing something, + // but don't add this print call to the `lines` array, + // so that it doesn't get called during the next print. + if line.starts_with('print') { + source_code := r.functions.join('\n') + r.lines.join('\n') + '\n' + line + os.write_file(file, source_code) + s := os.exec('$vexe run $file -repl') or { + panic(err) + } + vals := s.output.split('\n') + for i:=0; i < vals.len; i++ { + println(vals[i]) + } + } + else { + mut temp_line := line + mut temp_flag := false + func_call := r.function_call(line) + if !(line.contains(' ') || line.contains(':') || line.contains('=') || line.contains(',') || line == '') && !func_call { + temp_line = 'println($line)' + temp_flag = true + } + temp_source_code := r.functions.join('\n') + r.lines.join('\n') + r.temp_lines.join('\n') + '\n' + temp_line + os.write_file(temp_file, temp_source_code) + s := os.exec('$vexe run $temp_file -repl') or { + panic(err) + } + if !func_call && !s.exit_code { + for r.temp_lines.len > 0 { + if !r.temp_lines[0].starts_with('print') { + r.lines << r.temp_lines[0] + } + r.temp_lines.delete(0) + } + r.lines << line + } + else { + for r.temp_lines.len > 0 { + r.temp_lines.delete(0) + } + } + vals := s.output.split('\n') + for i:=0; i>> ', '').replace('>>>', '').all_after('Use Ctrl-C or `exit` to exit\n') + result := r.output.replace('>>> ', '').replace('>>>', '').replace('... ', '').all_after('Use Ctrl-C or `exit` to exit\n') assert result == output if result != output { println(file)