lisp.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. use std::collections::HashMap;
  2. use fancy_regex::Regex;
  3. use std::fmt;
  4. use std::fs::File;
  5. use std::io;
  6. use std::io::{BufRead, BufReader};
  7. use std::num::ParseFloatError;
  8. use std::rc::Rc;
  9. /*
  10. Types
  11. */
  12. #[derive(Clone)]
  13. enum RispExp {
  14. Bool(bool),
  15. Symbol(String),
  16. Number(f64),
  17. List(Vec<RispExp>),
  18. Func(fn(&[RispExp]) -> Result<RispExp, RispErr>),
  19. Lambda(RispLambda),
  20. }
  21. #[derive(Clone)]
  22. struct RispLambda {
  23. params_exp: Rc<RispExp>,
  24. body_exp: Rc<RispExp>,
  25. }
  26. impl fmt::Display for RispExp {
  27. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  28. let str = match self {
  29. RispExp::Bool(a) => a.to_string(),
  30. RispExp::Symbol(s) => s.clone(),
  31. RispExp::Number(n) => n.to_string(),
  32. RispExp::List(list) => {
  33. let xs: Vec<String> = list.iter().map(|x| x.to_string()).collect();
  34. format!("({})", xs.join(","))
  35. }
  36. RispExp::Func(_) => "Function {}".to_string(),
  37. RispExp::Lambda(_) => "Lambda {}".to_string(),
  38. };
  39. write!(f, "{}", str)
  40. }
  41. }
  42. #[derive(Debug)]
  43. enum RispErr {
  44. Reason(String),
  45. }
  46. #[derive(Clone)]
  47. struct RispEnv<'a> {
  48. data: HashMap<String, RispExp>,
  49. outer: Option<&'a RispEnv<'a>>,
  50. }
  51. /*
  52. InPort
  53. */
  54. // TODO change to symbol(eof)
  55. struct InPort {
  56. line: String,
  57. lines: Vec<String>,
  58. cur_line: usize
  59. }
  60. impl InPort {
  61. fn init(filename: String) -> InPort {
  62. let file = File::open(filename).unwrap();
  63. let reader = io::BufReader::new(file).lines().map(|s| s.ok().unwrap().to_string()).collect();
  64. InPort {
  65. line : String::new(),
  66. lines: reader,
  67. cur_line: 0
  68. }
  69. }
  70. pub fn next_token(&mut self) -> String {
  71. loop {
  72. if self.line.is_empty() || self.line == "#<eof-object>".to_string() {
  73. // TODO add match
  74. self.line = self.lines.get(self.cur_line).unwrap_or(&"#<eof-object>".to_string()).to_string();
  75. self.cur_line = self.cur_line + 1;
  76. }
  77. if self.line.is_empty() {
  78. self.cur_line = self.cur_line + 1;
  79. return "#<eof-object>".to_string();
  80. }
  81. let (token, rest) = InPort::tokenize(self.line.clone());
  82. self.line = rest;
  83. self.cur_line = self.cur_line + 1;
  84. if !token.is_empty() {
  85. return token;
  86. }
  87. }
  88. }
  89. fn tokenize(expr: String) -> (String, String) {
  90. let re =
  91. Regex::new(r#"\s*(,@|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,;)]*)(.*)"#).unwrap();
  92. let result = re.captures(&expr);
  93. let captures = result
  94. .expect("Error running regex")
  95. .expect("No match found");
  96. // println!("{}", captures.get(0).unwrap().as_str().to_string());
  97. (
  98. captures.get(1).unwrap().as_str().to_string(),
  99. captures.get(2).unwrap().as_str().to_string(),
  100. )
  101. }
  102. }
  103. fn parse_atom(token: &str) -> RispExp {
  104. match token.as_ref() {
  105. "true" => RispExp::Bool(true),
  106. "false" => RispExp::Bool(false),
  107. _ => {
  108. let potential_float: Result<f64, ParseFloatError> = token.parse();
  109. match potential_float {
  110. Ok(v) => RispExp::Number(v),
  111. Err(_) => RispExp::Symbol(token.to_string().clone()),
  112. }
  113. }
  114. }
  115. }
  116. /*
  117. Env
  118. */
  119. macro_rules! ensure_tonicity {
  120. ($check_fn:expr) => {{
  121. |args: &[RispExp]| -> Result<RispExp, RispErr> {
  122. let floats = parse_list_of_floats(args)?;
  123. let first = floats
  124. .first()
  125. .ok_or(RispErr::Reason("expected at least one number".to_string()))?;
  126. let rest = &floats[1..];
  127. fn f(prev: &f64, xs: &[f64]) -> bool {
  128. match xs.first() {
  129. Some(x) => $check_fn(prev, x) && f(x, &xs[1..]),
  130. None => true,
  131. }
  132. };
  133. Ok(RispExp::Bool(f(first, rest)))
  134. }
  135. }};
  136. }
  137. fn default_env<'a>() -> RispEnv<'a> {
  138. let mut data: HashMap<String, RispExp> = HashMap::new();
  139. data.insert(
  140. "+".to_string(),
  141. RispExp::Func(|args: &[RispExp]| -> Result<RispExp, RispErr> {
  142. let sum = parse_list_of_floats(args)?
  143. .iter()
  144. .fold(0.0, |sum, a| sum + a);
  145. Ok(RispExp::Number(sum))
  146. }),
  147. );
  148. data.insert(
  149. "-".to_string(),
  150. RispExp::Func(|args: &[RispExp]| -> Result<RispExp, RispErr> {
  151. let floats = parse_list_of_floats(args)?;
  152. let first = *floats
  153. .first()
  154. .ok_or(RispErr::Reason("expected at least one number".to_string()))?;
  155. let sum_of_rest = floats[1..].iter().fold(0.0, |sum, a| sum + a);
  156. Ok(RispExp::Number(first - sum_of_rest))
  157. }),
  158. );
  159. data.insert(
  160. "=".to_string(),
  161. RispExp::Func(ensure_tonicity!(|a, b| a == b)),
  162. );
  163. data.insert(
  164. ">".to_string(),
  165. RispExp::Func(ensure_tonicity!(|a, b| a > b)),
  166. );
  167. data.insert(
  168. ">=".to_string(),
  169. RispExp::Func(ensure_tonicity!(|a, b| a >= b)),
  170. );
  171. data.insert(
  172. "<".to_string(),
  173. RispExp::Func(ensure_tonicity!(|a, b| a < b)),
  174. );
  175. data.insert(
  176. "<=".to_string(),
  177. RispExp::Func(ensure_tonicity!(|a, b| a <= b)),
  178. );
  179. RispEnv { data, outer: None }
  180. }
  181. fn parse_list_of_floats(args: &[RispExp]) -> Result<Vec<f64>, RispErr> {
  182. args.iter().map(|x| parse_single_float(x)).collect()
  183. }
  184. fn parse_single_float(exp: &RispExp) -> Result<f64, RispErr> {
  185. match exp {
  186. RispExp::Number(num) => Ok(*num),
  187. _ => Err(RispErr::Reason("expected a number".to_string())),
  188. }
  189. }
  190. /*
  191. Eval
  192. */
  193. fn eval_if_args(arg_forms: &[RispExp], env: &mut RispEnv) -> Result<RispExp, RispErr> {
  194. let test_form = arg_forms
  195. .first()
  196. .ok_or(RispErr::Reason("expected test form".to_string()))?;
  197. let test_eval = eval(test_form, env)?;
  198. match test_eval {
  199. RispExp::Bool(b) => {
  200. let form_idx = if b { 1 } else { 2 };
  201. let res_form = arg_forms
  202. .get(form_idx)
  203. .ok_or(RispErr::Reason(format!("expected form idx={}", form_idx)))?;
  204. let res_eval = eval(res_form, env);
  205. res_eval
  206. }
  207. _ => Err(RispErr::Reason(format!(
  208. "unexpected test form='{}'",
  209. test_form.to_string()
  210. ))),
  211. }
  212. }
  213. fn eval_def_args(arg_forms: &[RispExp], env: &mut RispEnv) -> Result<RispExp, RispErr> {
  214. let first_form = arg_forms
  215. .first()
  216. .ok_or(RispErr::Reason("expected first form".to_string()))?;
  217. let first_str = match first_form {
  218. RispExp::Symbol(s) => Ok(s.clone()),
  219. _ => Err(RispErr::Reason(
  220. "expected first form to be a symbol".to_string(),
  221. )),
  222. }?;
  223. let second_form = arg_forms
  224. .get(1)
  225. .ok_or(RispErr::Reason("expected second form".to_string()))?;
  226. if arg_forms.len() > 2 {
  227. return Err(RispErr::Reason("def can only have two forms ".to_string()));
  228. }
  229. let second_eval = eval(second_form, env)?;
  230. env.data.insert(first_str, second_eval);
  231. Ok(first_form.clone())
  232. }
  233. fn eval_lambda_args(arg_forms: &[RispExp]) -> Result<RispExp, RispErr> {
  234. let params_exp = arg_forms
  235. .first()
  236. .ok_or(RispErr::Reason("expected args form".to_string()))?;
  237. let body_exp = arg_forms
  238. .get(1)
  239. .ok_or(RispErr::Reason("expected second form".to_string()))?;
  240. if arg_forms.len() > 2 {
  241. return Err(RispErr::Reason(
  242. "fn definition can only have two forms ".to_string(),
  243. ));
  244. }
  245. Ok(RispExp::Lambda(RispLambda {
  246. body_exp: Rc::new(body_exp.clone()),
  247. params_exp: Rc::new(params_exp.clone()),
  248. }))
  249. }
  250. fn eval_built_in_form(
  251. exp: &RispExp,
  252. arg_forms: &[RispExp],
  253. env: &mut RispEnv,
  254. ) -> Option<Result<RispExp, RispErr>> {
  255. match exp {
  256. RispExp::Symbol(s) => match s.as_ref() {
  257. "if" => Some(eval_if_args(arg_forms, env)),
  258. "def" => Some(eval_def_args(arg_forms, env)),
  259. "fn" => Some(eval_lambda_args(arg_forms)),
  260. _ => None,
  261. },
  262. _ => None,
  263. }
  264. }
  265. fn env_get(k: &str, env: &RispEnv) -> Option<RispExp> {
  266. match env.data.get(k) {
  267. Some(exp) => Some(exp.clone()),
  268. None => match &env.outer {
  269. Some(outer_env) => env_get(k, &outer_env),
  270. None => None,
  271. },
  272. }
  273. }
  274. fn parse_list_of_symbol_strings(form: Rc<RispExp>) -> Result<Vec<String>, RispErr> {
  275. let list = match form.as_ref() {
  276. RispExp::List(s) => Ok(s.clone()),
  277. _ => Err(RispErr::Reason(
  278. "expected args form to be a list".to_string(),
  279. )),
  280. }?;
  281. list.iter()
  282. .map(|x| match x {
  283. RispExp::Symbol(s) => Ok(s.clone()),
  284. _ => Err(RispErr::Reason(
  285. "expected symbols in the argument list".to_string(),
  286. )),
  287. })
  288. .collect()
  289. }
  290. fn env_for_lambda<'a>(
  291. params: Rc<RispExp>,
  292. arg_forms: &[RispExp],
  293. outer_env: &'a mut RispEnv,
  294. ) -> Result<RispEnv<'a>, RispErr> {
  295. let ks = parse_list_of_symbol_strings(params)?;
  296. if ks.len() != arg_forms.len() {
  297. return Err(RispErr::Reason(format!(
  298. "expected {} arguments, got {}",
  299. ks.len(),
  300. arg_forms.len()
  301. )));
  302. }
  303. let vs = eval_forms(arg_forms, outer_env)?;
  304. let mut data: HashMap<String, RispExp> = HashMap::new();
  305. for (k, v) in ks.iter().zip(vs.iter()) {
  306. data.insert(k.clone(), v.clone());
  307. }
  308. Ok(RispEnv {
  309. data,
  310. outer: Some(outer_env),
  311. })
  312. }
  313. fn eval_forms(arg_forms: &[RispExp], env: &mut RispEnv) -> Result<Vec<RispExp>, RispErr> {
  314. arg_forms.iter().map(|x| eval(x, env)).collect()
  315. }
  316. fn eval(exp: &RispExp, env: &mut RispEnv) -> Result<RispExp, RispErr> {
  317. match exp {
  318. RispExp::Symbol(k) => {
  319. env_get(k, env).ok_or(RispErr::Reason(format!("unexpected symbol k='{}'", k)))
  320. }
  321. RispExp::Bool(_a) => Ok(exp.clone()),
  322. RispExp::Number(_a) => Ok(exp.clone()),
  323. RispExp::List(list) => {
  324. let first_form = list
  325. .first()
  326. .ok_or(RispErr::Reason("expected a non-empty list".to_string()))?;
  327. let arg_forms = &list[1..];
  328. match eval_built_in_form(first_form, arg_forms, env) {
  329. Some(res) => res,
  330. None => {
  331. let first_eval = eval(first_form, env)?;
  332. match first_eval {
  333. RispExp::Func(f) => f(&eval_forms(arg_forms, env)?),
  334. RispExp::Lambda(lambda) => {
  335. let new_env = &mut env_for_lambda(lambda.params_exp, arg_forms, env)?;
  336. eval(&lambda.body_exp, new_env)
  337. }
  338. _ => Err(RispErr::Reason("first form must be a function".to_string())),
  339. }
  340. }
  341. }
  342. }
  343. RispExp::Func(_) => Err(RispErr::Reason("unexpected form".to_string())),
  344. RispExp::Lambda(_) => Err(RispErr::Reason("unexpected form".to_string())),
  345. }
  346. }
  347. fn main() {
  348. let env = &mut default_env();
  349. let mut reader = InPort::init("new.lisp".to_string());
  350. let mut token = String::new();
  351. loop {
  352. if token == "#<eof-object>".to_string() {
  353. println!("EOF");
  354. break;
  355. }
  356. token = reader.next_token().as_str().to_string();
  357. println!("{}", token);
  358. }
  359. // read from file
  360. // let file = File::open("new.lisp").unwrap();
  361. // let lines = io::BufReader::new(file).lines();
  362. // let mut cur_line = String::new();
  363. // let mut token = String::new();
  364. // for line in lines {
  365. // let (token, cur_line) = tokenize(line.ok().unwrap().as_str().to_string());
  366. // println!("token {:?}", token);
  367. // println!("line {:?}", cur_line);
  368. // }
  369. /*
  370. loop {
  371. println!("risp >");
  372. let expr = slurp_expr();
  373. match parse_eval(expr, env) {
  374. Ok(res) => println!("// 🔥 => {}", res),
  375. Err(e) => match e {
  376. RispErr::Reason(msg) => println!("// 🙀 => {}", msg),
  377. },
  378. }
  379. }
  380. */
  381. }