You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.3 KiB
48 lines
1.3 KiB
use std::path::PathBuf;
|
|
|
|
use clap::Parser;
|
|
|
|
mod repl;
|
|
mod sandbox;
|
|
mod stdlib;
|
|
|
|
/// Runs a Lua script in a customized environment, or an interactive REPL when
|
|
/// no script path is given.
|
|
#[derive(Parser, Debug)]
|
|
#[command(version, about)]
|
|
struct Args {
|
|
/// Path to the Lua script to execute. Omit to start an interactive REPL.
|
|
filepath: Option<PathBuf>,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
|
|
|
|
let args = Args::parse();
|
|
|
|
let lua = sandbox::create_sandboxed_lua()?;
|
|
|
|
let Some(filepath) = args.filepath else {
|
|
return repl::run(&lua).await;
|
|
};
|
|
|
|
let source = tokio::fs::read_to_string(&filepath).await?;
|
|
|
|
// Skip a leading shebang line like stock Lua's luaL_loadfilex does (it
|
|
// skips any first line starting with '#'). The newline is kept so error
|
|
// messages still report correct line numbers.
|
|
let chunk = if source.starts_with('#') {
|
|
&source[source.find('\n').unwrap_or(source.len())..]
|
|
} else {
|
|
source.as_str()
|
|
};
|
|
|
|
lua.load(chunk)
|
|
// "@" marks the chunk name as a file path in error messages / tracebacks
|
|
.set_name(format!("@{}", filepath.display()))
|
|
.exec_async()
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|