use luna_jit::Lua;
use luna_jit::runtime::Value;
use std::io::{BufRead, Write};
fn render(v: Value) -> String {
match v {
Value::Nil => "nil".into(),
Value::Bool(b) => b.to_string(),
Value::Int(i) => i.to_string(),
Value::Float(f) => format!("{f}"),
Value::Str(s) => format!("{:?}", String::from_utf8_lossy(s.as_bytes())),
Value::Table(_) => "<table>".into(),
Value::Closure(_) | Value::Native(_) => "<function>".into(),
Value::Coro(_) => "<thread>".into(),
Value::Userdata(_) => "<userdata>".into(),
Value::LightUserdata(_) => "<lightuserdata>".into(),
}
}
fn main() {
let mut lua = Lua::new();
lua.open_base();
lua.open_math();
lua.open_string();
let stdin = std::io::stdin();
let mut stdout = std::io::stdout();
let mut buf = String::new();
println!("repl_lite: embedded Lua REPL. Ctrl-D to exit.");
loop {
print!("lite> ");
let _ = stdout.flush();
buf.clear();
match stdin.lock().read_line(&mut buf) {
Ok(0) => {
println!();
return;
}
Ok(_) => {
let line = buf.trim();
if line.is_empty() {
continue;
}
let as_expr = format!("return {line}");
let result = match lua.vm().eval(&as_expr) {
Ok(vs) => Ok(vs),
Err(_) => lua.vm().eval(line),
};
match result {
Ok(vs) => {
for v in vs {
println!("{}", render(v));
}
}
Err(e) => {
eprintln!("error: {}", lua.vm().error_text(&e));
}
}
}
Err(e) => {
eprintln!("io error: {e}");
return;
}
}
}
}