mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: CLI REPL 支持符号表与多行输入
This commit is contained in:
@@ -211,6 +211,18 @@ fn compile(expr: Option<String>, file: Option<String>) -> ExitCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bracket_balance(line: &str) -> i32 {
|
||||||
|
let mut count = 0i32;
|
||||||
|
for ch in line.chars() {
|
||||||
|
match ch {
|
||||||
|
'(' | '[' | '{' => count += 1,
|
||||||
|
')' | ']' | '}' => count -= 1,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
fn repl() -> ExitCode {
|
fn repl() -> ExitCode {
|
||||||
use rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
use rustyline::DefaultEditor;
|
use rustyline::DefaultEditor;
|
||||||
@@ -225,9 +237,16 @@ fn repl() -> ExitCode {
|
|||||||
|
|
||||||
let kernel = make_kernel();
|
let kernel = make_kernel();
|
||||||
let pool = make_pool(&kernel);
|
let pool = make_pool(&kernel);
|
||||||
|
let mut source = String::new();
|
||||||
|
let mut input_buf = String::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match rl.readline("oxide> ") {
|
let prompt = if input_buf.is_empty() {
|
||||||
|
"oxide> "
|
||||||
|
} else {
|
||||||
|
"...> "
|
||||||
|
};
|
||||||
|
match rl.readline(prompt) {
|
||||||
Ok(line) => {
|
Ok(line) => {
|
||||||
let trimmed = line.trim();
|
let trimmed = line.trim();
|
||||||
if trimmed.is_empty() {
|
if trimmed.is_empty() {
|
||||||
@@ -238,7 +257,29 @@ fn repl() -> ExitCode {
|
|||||||
return ExitCode::SUCCESS;
|
return ExitCode::SUCCESS;
|
||||||
}
|
}
|
||||||
rl.add_history_entry(trimmed).ok();
|
rl.add_history_entry(trimmed).ok();
|
||||||
eval(trimmed, &kernel, &pool);
|
|
||||||
|
if !input_buf.is_empty() {
|
||||||
|
input_buf.push('\n');
|
||||||
|
}
|
||||||
|
input_buf.push_str(trimmed);
|
||||||
|
|
||||||
|
let balance = bracket_balance(&input_buf);
|
||||||
|
if balance > 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut full_code = source.clone();
|
||||||
|
if !full_code.is_empty() {
|
||||||
|
full_code.push(';');
|
||||||
|
}
|
||||||
|
full_code.push_str(&input_buf);
|
||||||
|
|
||||||
|
let result = eval(&full_code, &kernel, &pool);
|
||||||
|
input_buf.clear();
|
||||||
|
|
||||||
|
if result == ExitCode::SUCCESS {
|
||||||
|
source = full_code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(ReadlineError::Interrupted) => {
|
Err(ReadlineError::Interrupted) => {
|
||||||
println!("^C");
|
println!("^C");
|
||||||
@@ -255,7 +296,6 @@ fn repl() -> ExitCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn not_implemented(command: &str) -> ExitCode {
|
fn not_implemented(command: &str) -> ExitCode {
|
||||||
use ansi_term::Colour::Yellow;
|
use ansi_term::Colour::Yellow;
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|||||||
Reference in New Issue
Block a user