/* relish: versatile lisp shell * Copyright (C) 2021 Aidan Hahn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ use rustyline::error::ReadlineError; use rustyline::Editor; use dirs::home_dir; use std::rc::Rc; use std::cell::RefCell; use relish::ast::{VTable, FTable, Ctr, lex, eval, ast_to_string}; use relish::stdlib::{get_stdlib}; fn main() { let mut rl = Editor::<()>::new(); const HIST_FILE: &str = ".relish_hist"; //const CONFIG_FILE: &str = ".relishrc"; let mut hist: String = "".to_owned(); if let Some(home) = home_dir() { if let Some(h) = home.to_str() { hist = h.to_owned() + HIST_FILE; } } if hist != "" { // ignore result. it loads or it doesnt. let _ = rl.load_history(&hist); } let vt = Rc::new(RefCell::new(VTable::new())); // if we fail to get stdlib we can just use this one let mut ft = Rc::new(RefCell::new(FTable::new())); match get_stdlib() { Ok(f) => ft = f, Err(s) => println!("{}", s) } loop { // TODO: configurable prompt let readline = rl.readline("λ "); match readline { Ok(line) => { rl.add_history_entry(line.as_str()); let mut l = line.as_str().to_owned(); if !l.starts_with("(") { l = "(".to_owned() + &l; } if !l.ends_with(")") { l = l + ")"; } match lex(l) { Ok(a) => { match eval(a.clone(), vt.clone(), ft.clone(), false) { Ok(a) => { match a { Ctr::Symbol(s) => println!("{}", s), Ctr::String(s) => println!("{}", s), Ctr::Integer(i) => println!("{}", i), Ctr::Float(f) => println!("{}", f), Ctr::Bool(b) => println!("{}", b), Ctr::Seg(c) => println!("{}", ast_to_string(c.clone())), Ctr::None => () } }, Err(s) => { println!("{}", s); } } }, Err(s) => { println!("{}", s); } } }, Err(ReadlineError::Interrupted) => { break }, Err(ReadlineError::Eof) => { return }, Err(err) => { eprintln!("Prompt error: {:?}", err); break } } } if hist != "" { rl.save_history(&hist).unwrap(); } }