mute/src/main.rs
Roman Godmaire 02463197c3 misc: Chesterton's Fence
Everything is a list in lisp for a reason 🙃
2024-05-12 08:11:12 -04:00

103 lines
2.8 KiB
Rust

use clap::{Parser, Subcommand};
use rustyline::{error::ReadlineError, DefaultEditor};
use mute_interpreter::{eval, Environment};
use mute_parser::parse_str;
#[derive(Debug, Parser)]
#[clap(version, author, about)]
struct Args {
#[clap(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {
#[clap(name = "-c", about = "Run a program passed in as a string")]
RunCmd { command: String },
#[clap(about = "Run a Mute file")]
Run { file: String },
#[clap(about = "Start a REPL")]
Repl,
}
fn main() {
let args = Args::parse();
match args.command {
Command::Run { file } => {
let input = std::fs::read_to_string(file).unwrap();
let env = Environment::default();
let ast = match parse_str(&input) {
Ok(ast) => ast,
Err(err) => {
println!("error: {}", err);
return;
}
};
let res = eval(&env, ast);
match res {
Ok(expressions) => expressions.into_iter().for_each(|expr| println!("{expr}")),
Err(err) => println!("{}", err),
}
}
Command::RunCmd { command } => {
let env = Environment::default();
let ast = match parse_str(&command) {
Ok(ast) => ast,
Err(err) => {
println!("error: {}", err);
return;
}
};
let res = eval(&env, ast);
match res {
Ok(expressions) => expressions.into_iter().for_each(|expr| println!("{expr}")),
Err(err) => println!("{}", err),
}
}
Command::Repl => repl(),
}
}
fn repl() {
let env = Environment::default();
let mut rl = DefaultEditor::new().unwrap();
println!("Mute -- REPL");
loop {
let readline = rl.readline("> ");
match readline {
Ok(line) => {
rl.add_history_entry(line.as_str()).unwrap();
let ast = match parse_str(&line) {
Ok(ast) => ast,
Err(err) => {
println!("error: {}", err);
continue;
}
};
let res = eval(&env, ast);
match res {
Ok(expressions) => expressions.into_iter().for_each(|expr| println!("{expr}")),
Err(err) => println!("error: {}", err),
}
}
Err(ReadlineError::Interrupted) => {
continue;
}
Err(ReadlineError::Eof) => {
break;
}
Err(err) => {
println!("Error: {:?}", err);
break;
}
}
}
}