2024-05-05 13:21:45 +00:00
|
|
|
use clap::{Parser, Subcommand};
|
2024-05-05 12:36:57 +00:00
|
|
|
use rustyline::{error::ReadlineError, DefaultEditor};
|
2023-09-12 11:21:51 +00:00
|
|
|
|
2024-05-07 01:51:22 +00:00
|
|
|
use mute_interpreter::{eval, Environment};
|
|
|
|
use mute_parser::parse_str;
|
2023-09-13 12:47:24 +00:00
|
|
|
|
2024-05-05 13:21:45 +00:00
|
|
|
#[derive(Debug, Parser)]
|
|
|
|
#[clap(version, author, about)]
|
|
|
|
struct Args {
|
|
|
|
#[clap(subcommand)]
|
|
|
|
command: Command,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Subcommand)]
|
|
|
|
enum Command {
|
2024-05-05 13:49:12 +00:00
|
|
|
#[clap(name = "-c", about = "Run a program passed in as a string")]
|
2024-05-06 12:01:18 +00:00
|
|
|
RunCmd { command: String },
|
2024-05-05 13:21:45 +00:00
|
|
|
|
2024-05-05 13:49:12 +00:00
|
|
|
#[clap(about = "Run a Mute file")]
|
|
|
|
Run { file: String },
|
|
|
|
|
|
|
|
#[clap(about = "Start a REPL")]
|
|
|
|
Repl,
|
2024-05-05 13:21:45 +00:00
|
|
|
}
|
|
|
|
|
2023-09-12 11:21:51 +00:00
|
|
|
fn main() {
|
2024-05-05 13:21:45 +00:00
|
|
|
let args = Args::parse();
|
|
|
|
|
|
|
|
match args.command {
|
2024-05-05 13:49:12 +00:00
|
|
|
Command::Run { file } => {
|
|
|
|
let input = std::fs::read_to_string(file).unwrap();
|
2024-05-06 12:01:18 +00:00
|
|
|
let env = Environment::default();
|
2024-05-07 01:51:22 +00:00
|
|
|
let ast = match parse_str(&input) {
|
|
|
|
Ok(ast) => ast,
|
|
|
|
Err(err) => {
|
|
|
|
println!("error: {}", err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let res = eval(&env, ast);
|
2024-05-05 13:49:12 +00:00
|
|
|
match res {
|
|
|
|
Ok(expressions) => expressions.into_iter().for_each(|expr| println!("{expr}")),
|
|
|
|
Err(err) => println!("{}", err),
|
|
|
|
}
|
|
|
|
}
|
2024-05-06 12:01:18 +00:00
|
|
|
Command::RunCmd { command } => {
|
|
|
|
let env = Environment::default();
|
2024-05-07 01:51:22 +00:00
|
|
|
let ast = match parse_str(&command) {
|
|
|
|
Ok(ast) => ast,
|
|
|
|
Err(err) => {
|
|
|
|
println!("error: {}", err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let res = eval(&env, ast);
|
2024-05-05 13:21:45 +00:00
|
|
|
match res {
|
|
|
|
Ok(expressions) => expressions.into_iter().for_each(|expr| println!("{expr}")),
|
|
|
|
Err(err) => println!("{}", err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Command::Repl => repl(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn repl() {
|
2024-05-06 12:01:18 +00:00
|
|
|
let env = Environment::default();
|
2024-05-05 12:36:57 +00:00
|
|
|
let mut rl = DefaultEditor::new().unwrap();
|
2023-09-12 11:21:51 +00:00
|
|
|
|
2024-03-09 12:55:17 +00:00
|
|
|
println!("Mute -- REPL");
|
2023-09-12 11:21:51 +00:00
|
|
|
|
|
|
|
loop {
|
2024-05-05 12:36:57 +00:00
|
|
|
let readline = rl.readline("> ");
|
|
|
|
|
|
|
|
match readline {
|
|
|
|
Ok(line) => {
|
|
|
|
rl.add_history_entry(line.as_str()).unwrap();
|
|
|
|
|
2024-05-07 01:51:22 +00:00
|
|
|
let ast = match parse_str(&line) {
|
|
|
|
Ok(ast) => ast,
|
|
|
|
Err(err) => {
|
|
|
|
println!("error: {}", err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let res = eval(&env, ast);
|
|
|
|
match res {
|
2024-05-05 12:36:57 +00:00
|
|
|
Ok(expressions) => expressions.into_iter().for_each(|expr| println!("{expr}")),
|
2024-05-05 15:16:18 +00:00
|
|
|
Err(err) => println!("error: {}", err),
|
2024-05-05 12:36:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(ReadlineError::Interrupted) => {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Err(ReadlineError::Eof) => {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
println!("Error: {:?}", err);
|
|
|
|
break;
|
|
|
|
}
|
2023-09-19 12:17:13 +00:00
|
|
|
}
|
2023-09-12 11:21:51 +00:00
|
|
|
}
|
|
|
|
}
|