diff --git a/vlib/compiler/repl.v b/tools/vrepl.v similarity index 83% rename from vlib/compiler/repl.v rename to tools/vrepl.v index 75e27d33da..eda08e0d46 100644 --- a/vlib/compiler/repl.v +++ b/tools/vrepl.v @@ -2,10 +2,14 @@ // Use of this source code is governed by an MIT license // that can be found in the LICENSE file. -module compiler +module main -import os -import term +import ( + compiler + os + term + readline +) struct Repl { mut: @@ -59,9 +63,9 @@ fn (r &Repl) function_call(line string) bool { } pub fn repl_help() { -version_hash := vhash() +version_hash := compiler.vhash() println(' -V $Version $version_hash +V ${compiler.Version} $version_hash help Displays this information. Ctrl-C, Ctrl-D, exit Exits the REPL. clear Clears the screen. @@ -69,11 +73,12 @@ V $Version $version_hash } pub fn run_repl() []string { - version_hash := vhash() - println('V $Version $version_hash') + version_hash := compiler.vhash() + println('V ${compiler.Version} $version_hash') println('Use Ctrl-C or `exit` to exit') file := '.vrepl.v' temp_file := '.vrepl_temp.v' + mut prompt := '>>> ' defer { os.rm(file) os.rm(temp_file) @@ -81,22 +86,26 @@ pub fn run_repl() []string { os.rm(temp_file[..temp_file.len - 2]) } mut r := Repl{} - vexe := os.args[0] + mut readline := readline.Readline{} + vexe := os.args[1] for { if r.indent == 0 { - print('>>> ') + prompt = '>>> ' } else { - print('... ') + prompt = '... ' } - r.line = os.get_raw_line() - if r.line.trim_space() == '' && r.line.ends_with('\n') { - continue - } - r.line = r.line.trim_space() - if r.line.len == -1 || r.line == '' || r.line == 'exit' { + mut line := readline.read_line(prompt) or { break } + if line.trim_space() == '' && line.ends_with('\n') { + continue + } + line = line.trim_space() + if line.len <= -1 || line == '' || line == 'exit' { + break + } + r.line = line if r.line == '\n' { continue } @@ -134,7 +143,7 @@ pub fn run_repl() []string { source_code := r.functions.join('\n') + r.lines.join('\n') + '\n' + r.line os.write_file(file, source_code) s := os.exec('"$vexe" run $file -repl') or { - verror(err) + compiler.verror(err) return []string } vals := s.output.split('\n') @@ -153,7 +162,7 @@ pub fn run_repl() []string { temp_source_code := r.functions.join('\n') + r.lines.join('\n') + '\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 { - verror(err) + compiler.verror(err) return []string } if !func_call && s.exit_code == 0 && !temp_flag { @@ -178,3 +187,12 @@ pub fn run_repl() []string { } return r.lines } + +fn main() { + if os.args.len != 2 || !os.file_exists(os.args[1]) { + println('Usage: vrepl [vexe]\n') + println('vexe: v binary file') + return + } + run_repl() +} diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index cf7c78b52c..ac5cf38a0b 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -1048,6 +1048,23 @@ pub fn install_v(args[]string) { } } +pub fn run_repl() { + vexec := vexe_path() + vroot := os.dir(vexec) + vrepl := '$vroot/tools/vrepl' + + os.chdir(vroot + '/tools') + vrepl_compilation := os.exec('"$vexec" -o $vrepl vrepl.v') or { + verror(err) + return + } + if vrepl_compilation.exit_code != 0 { + verror(vrepl_compilation.output) + return + } + vreplresult := os.system('$vrepl "$vexec"') +} + pub fn create_symlink() { vexe := vexe_path() link_path := '/usr/local/bin/v' diff --git a/vlib/readline/readline.v b/vlib/readline/readline.v index 6e1ed2cf4d..b7f478e8ef 100644 --- a/vlib/readline/readline.v +++ b/vlib/readline/readline.v @@ -27,7 +27,7 @@ struct Winsize { ws_ypixel u16 } -struct Readline { +pub struct Readline { mut: is_raw bool orig_termios Termios // Linux diff --git a/vlib/readline/readline_lin.v b/vlib/readline/readline_linux.v similarity index 86% rename from vlib/readline/readline_lin.v rename to vlib/readline/readline_linux.v index 9c3233d745..0ab8b07c66 100644 --- a/vlib/readline/readline_lin.v +++ b/vlib/readline/readline_linux.v @@ -164,7 +164,7 @@ fn (r Readline) analyse(c int) Action { 1 { return .move_cursor_begining } // ^A 5 { return .move_cursor_end } // ^E 26 { return .suspend } // CTRL + Z, SUB - else { return if c >= ` ` { .insert_character } else { Action.nothing } } + else { return if c >= ` ` { Action.insert_character } else { Action.nothing } } } } @@ -174,17 +174,17 @@ fn (r Readline) analyse_control() Action { `[` { sequence := r.read_char() match sequence { - `C` { return Action.move_cursor_right } - `D` { return Action.move_cursor_left } - `B` { return Action.history_next } - `A` { return Action.history_previous } + `C` { return .move_cursor_right } + `D` { return .move_cursor_left } + `B` { return .history_next } + `A` { return .history_previous } `1` { return r.analyse_extended_control() } `2` { return r.analyse_extended_control_no_eat(sequence) } `3` { return r.analyse_extended_control_no_eat(sequence) } } } } - return Action.nothing + return .nothing } fn (r Readline) analyse_extended_control() Action { @@ -194,12 +194,12 @@ fn (r Readline) analyse_extended_control() Action { `5` { direction := r.read_char() match direction { - `C` { return Action.move_cursor_word_right } - `D` { return Action.move_cursor_word_left } + `C` { return .move_cursor_word_right } + `D` { return .move_cursor_word_left } } } } - return Action.nothing + return .nothing } fn (r Readline) analyse_extended_control_no_eat(last_c byte) Action { @@ -207,32 +207,32 @@ fn (r Readline) analyse_extended_control_no_eat(last_c byte) Action { match c { `~` { match last_c { - `3` { return Action.delete_right } // Suppr key - `2` { return Action.overwrite } + `3` { return .delete_right } // Suppr key + `2` { return .overwrite } } } } - return Action.nothing + return .nothing } fn (r mut Readline) execute(a Action, c int) bool { match a { - Action.eof { return r.eof() } - Action.insert_character { r.insert_character(c) } - Action.commit_line { return r.commit_line() } - Action.delete_left { r.delete_character() } - Action.delete_right { r.suppr_character() } - Action.move_cursor_left { r.move_cursor_left() } - Action.move_cursor_right { r.move_cursor_right() } - Action.move_cursor_begining { r.move_cursor_begining() } - Action.move_cursor_end { r.move_cursor_end() } - Action.move_cursor_word_left { r.move_cursor_word_left() } - Action.move_cursor_word_right { r.move_cursor_word_right() } - Action.history_previous { r.history_previous() } - Action.history_next { r.history_next() } - Action.overwrite { r.switch_overwrite() } - Action.clear_screen { r.clear_screen() } - Action.suspend { r.suspend() } + .eof { return r.eof() } + .insert_character { r.insert_character(c) } + .commit_line { return r.commit_line() } + .delete_left { r.delete_character() } + .delete_right { r.suppr_character() } + .move_cursor_left { r.move_cursor_left() } + .move_cursor_right { r.move_cursor_right() } + .move_cursor_begining { r.move_cursor_begining() } + .move_cursor_end { r.move_cursor_end() } + .move_cursor_word_left { r.move_cursor_word_left() } + .move_cursor_word_right { r.move_cursor_word_right() } + .history_previous { r.history_previous() } + .history_next { r.history_next() } + .overwrite { r.switch_overwrite() } + .clear_screen { r.clear_screen() } + .suspend { r.suspend() } } return false }