lisp.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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)
  64. .lines()
  65. .map(|s| s.ok().unwrap().to_string())
  66. .collect();
  67. InPort {
  68. line: String::new(),
  69. lines: reader,
  70. cur_line: 0,
  71. }
  72. }
  73. pub fn next_token(&mut self) -> String {
  74. loop {
  75. if self.line.is_empty() {
  76. self.line = self
  77. .lines
  78. .get(self.cur_line)
  79. .unwrap_or(&"#<eof-object>".to_string())
  80. .to_string();
  81. self.cur_line = self.cur_line + 1;
  82. }
  83. if self.line.is_empty() {
  84. return "#<eof-object>".to_string();
  85. }
  86. let (token, rest) = InPort::tokenize(self.line.clone());
  87. self.line = rest;
  88. if !token.is_empty() {
  89. return token;
  90. }
  91. }
  92. }
  93. fn tokenize(expr: String) -> (String, String) {
  94. let re =
  95. Regex::new(r#"\s*(,@|[('`,)]|"(?:[\\].|[^\\"])*"|;.*|[^\s('"`,;)]*)(.*)"#).unwrap();
  96. let result = re.captures(&expr);
  97. let captures = result
  98. .expect("Error running regex")
  99. .expect("No match found");
  100. // println!("{}", captures.get(0).unwrap().as_str().to_string());
  101. (
  102. captures.get(1).unwrap().as_str().to_string(),
  103. captures.get(2).unwrap().as_str().to_string(),
  104. )
  105. }
  106. }
  107. fn read_ahead(inport: &InPort, token: String) -> String {
  108. match token.as_str() {
  109. "(" => {
  110. let mut L = Vec::new();
  111. loop {
  112. let t = &inport.next_token();
  113. if t.to_string() == ")" {
  114. return L.into_iter().collect();
  115. } else {
  116. L.push(read_ahead(&inport, t.to_string()));
  117. }
  118. }
  119. }
  120. _ => {
  121. println!("{}", token);
  122. return token;
  123. }
  124. }
  125. }
  126. fn read_seq<'a>(tokens: &'a [String]) -> Result<(RispExp, &'a [String]), RispErr> {
  127. let mut res: Vec<RispExp> = vec![];
  128. let mut xs = tokens;
  129. loop {
  130. let (next_token, rest) = xs
  131. .split_first()
  132. .ok_or(RispErr::Reason("could not find closing `)`".to_string()))?;
  133. if next_token == ")" {
  134. return Ok((RispExp::List(res), rest)); // skip `)`, head to the token after
  135. }
  136. let (exp, new_xs) = parse(&xs)?;
  137. res.push(exp);
  138. xs = new_xs;
  139. }
  140. }
  141. // TODO change return type to Symbol
  142. fn read(inport: &InPort) -> String {
  143. let token1 = &inport.next_token().as_str();
  144. if token1.to_string() == "#<eof-object>".to_string() {
  145. return "#<eof-object>".to_string();
  146. } else {
  147. return read_ahead(&inport, token1.to_string());
  148. }
  149. }
  150. fn parse_atom(token: &str) -> RispExp {
  151. match token.as_ref() {
  152. "true" => RispExp::Bool(true),
  153. "false" => RispExp::Bool(false),
  154. _ => {
  155. let potential_float: Result<f64, ParseFloatError> = token.parse();
  156. match potential_float {
  157. Ok(v) => RispExp::Number(v),
  158. Err(_) => RispExp::Symbol(token.to_string().clone()),
  159. }
  160. }
  161. }
  162. }
  163. /*
  164. Env
  165. */
  166. macro_rules! ensure_tonicity {
  167. ($check_fn:expr) => {{
  168. |args: &[RispExp]| -> Result<RispExp, RispErr> {
  169. let floats = parse_list_of_floats(args)?;
  170. let first = floats
  171. .first()
  172. .ok_or(RispErr::Reason("expected at least one number".to_string()))?;
  173. let rest = &floats[1..];
  174. fn f(prev: &f64, xs: &[f64]) -> bool {
  175. match xs.first() {
  176. Some(x) => $check_fn(prev, x) && f(x, &xs[1..]),
  177. None => true,
  178. }
  179. };
  180. Ok(RispExp::Bool(f(first, rest)))
  181. }
  182. }};
  183. }
  184. fn default_env<'a>() -> RispEnv<'a> {
  185. let mut data: HashMap<String, RispExp> = HashMap::new();
  186. data.insert(
  187. "+".to_string(),
  188. RispExp::Func(|args: &[RispExp]| -> Result<RispExp, RispErr> {
  189. let sum = parse_list_of_floats(args)?
  190. .iter()
  191. .fold(0.0, |sum, a| sum + a);
  192. Ok(RispExp::Number(sum))
  193. }),
  194. );
  195. data.insert(
  196. "-".to_string(),
  197. RispExp::Func(|args: &[RispExp]| -> Result<RispExp, RispErr> {
  198. let floats = parse_list_of_floats(args)?;
  199. let first = *floats
  200. .first()
  201. .ok_or(RispErr::Reason("expected at least one number".to_string()))?;
  202. let sum_of_rest = floats[1..].iter().fold(0.0, |sum, a| sum + a);
  203. Ok(RispExp::Number(first - sum_of_rest))
  204. }),
  205. );
  206. data.insert(
  207. "=".to_string(),
  208. RispExp::Func(ensure_tonicity!(|a, b| a == b)),
  209. );
  210. data.insert(
  211. ">".to_string(),
  212. RispExp::Func(ensure_tonicity!(|a, b| a > b)),
  213. );
  214. data.insert(
  215. ">=".to_string(),
  216. RispExp::Func(ensure_tonicity!(|a, b| a >= b)),
  217. );
  218. data.insert(
  219. "<".to_string(),
  220. RispExp::Func(ensure_tonicity!(|a, b| a < b)),
  221. );
  222. data.insert(
  223. "<=".to_string(),
  224. RispExp::Func(ensure_tonicity!(|a, b| a <= b)),
  225. );
  226. RispEnv { data, outer: None }
  227. }
  228. fn parse_list_of_floats(args: &[RispExp]) -> Result<Vec<f64>, RispErr> {
  229. args.iter().map(|x| parse_single_float(x)).collect()
  230. }
  231. fn parse_single_float(exp: &RispExp) -> Result<f64, RispErr> {
  232. match exp {
  233. RispExp::Number(num) => Ok(*num),
  234. _ => Err(RispErr::Reason("expected a number".to_string())),
  235. }
  236. }
  237. /*
  238. Eval
  239. */
  240. fn eval_if_args(arg_forms: &[RispExp], env: &mut RispEnv) -> Result<RispExp, RispErr> {
  241. let test_form = arg_forms
  242. .first()
  243. .ok_or(RispErr::Reason("expected test form".to_string()))?;
  244. let test_eval = eval(test_form, env)?;
  245. match test_eval {
  246. RispExp::Bool(b) => {
  247. let form_idx = if b { 1 } else { 2 };
  248. let res_form = arg_forms
  249. .get(form_idx)
  250. .ok_or(RispErr::Reason(format!("expected form idx={}", form_idx)))?;
  251. let res_eval = eval(res_form, env);
  252. res_eval
  253. }
  254. _ => Err(RispErr::Reason(format!(
  255. "unexpected test form='{}'",
  256. test_form.to_string()
  257. ))),
  258. }
  259. }
  260. fn eval_def_args(arg_forms: &[RispExp], env: &mut RispEnv) -> Result<RispExp, RispErr> {
  261. let first_form = arg_forms
  262. .first()
  263. .ok_or(RispErr::Reason("expected first form".to_string()))?;
  264. let first_str = match first_form {
  265. RispExp::Symbol(s) => Ok(s.clone()),
  266. _ => Err(RispErr::Reason(
  267. "expected first form to be a symbol".to_string(),
  268. )),
  269. }?;
  270. let second_form = arg_forms
  271. .get(1)
  272. .ok_or(RispErr::Reason("expected second form".to_string()))?;
  273. if arg_forms.len() > 2 {
  274. return Err(RispErr::Reason("def can only have two forms ".to_string()));
  275. }
  276. let second_eval = eval(second_form, env)?;
  277. env.data.insert(first_str, second_eval);
  278. Ok(first_form.clone())
  279. }
  280. fn eval_lambda_args(arg_forms: &[RispExp]) -> Result<RispExp, RispErr> {
  281. let params_exp = arg_forms
  282. .first()
  283. .ok_or(RispErr::Reason("expected args form".to_string()))?;
  284. let body_exp = arg_forms
  285. .get(1)
  286. .ok_or(RispErr::Reason("expected second form".to_string()))?;
  287. if arg_forms.len() > 2 {
  288. return Err(RispErr::Reason(
  289. "fn definition can only have two forms ".to_string(),
  290. ));
  291. }
  292. Ok(RispExp::Lambda(RispLambda {
  293. body_exp: Rc::new(body_exp.clone()),
  294. params_exp: Rc::new(params_exp.clone()),
  295. }))
  296. }
  297. fn eval_built_in_form(
  298. exp: &RispExp,
  299. arg_forms: &[RispExp],
  300. env: &mut RispEnv,
  301. ) -> Option<Result<RispExp, RispErr>> {
  302. match exp {
  303. RispExp::Symbol(s) => match s.as_ref() {
  304. "if" => Some(eval_if_args(arg_forms, env)),
  305. "def" => Some(eval_def_args(arg_forms, env)),
  306. "fn" => Some(eval_lambda_args(arg_forms)),
  307. _ => None,
  308. },
  309. _ => None,
  310. }
  311. }
  312. fn env_get(k: &str, env: &RispEnv) -> Option<RispExp> {
  313. match env.data.get(k) {
  314. Some(exp) => Some(exp.clone()),
  315. None => match &env.outer {
  316. Some(outer_env) => env_get(k, &outer_env),
  317. None => None,
  318. },
  319. }
  320. }
  321. fn parse_list_of_symbol_strings(form: Rc<RispExp>) -> Result<Vec<String>, RispErr> {
  322. let list = match form.as_ref() {
  323. RispExp::List(s) => Ok(s.clone()),
  324. _ => Err(RispErr::Reason(
  325. "expected args form to be a list".to_string(),
  326. )),
  327. }?;
  328. list.iter()
  329. .map(|x| match x {
  330. RispExp::Symbol(s) => Ok(s.clone()),
  331. _ => Err(RispErr::Reason(
  332. "expected symbols in the argument list".to_string(),
  333. )),
  334. })
  335. .collect()
  336. }
  337. fn env_for_lambda<'a>(
  338. params: Rc<RispExp>,
  339. arg_forms: &[RispExp],
  340. outer_env: &'a mut RispEnv,
  341. ) -> Result<RispEnv<'a>, RispErr> {
  342. let ks = parse_list_of_symbol_strings(params)?;
  343. if ks.len() != arg_forms.len() {
  344. return Err(RispErr::Reason(format!(
  345. "expected {} arguments, got {}",
  346. ks.len(),
  347. arg_forms.len()
  348. )));
  349. }
  350. let vs = eval_forms(arg_forms, outer_env)?;
  351. let mut data: HashMap<String, RispExp> = HashMap::new();
  352. for (k, v) in ks.iter().zip(vs.iter()) {
  353. data.insert(k.clone(), v.clone());
  354. }
  355. Ok(RispEnv {
  356. data,
  357. outer: Some(outer_env),
  358. })
  359. }
  360. fn eval_forms(arg_forms: &[RispExp], env: &mut RispEnv) -> Result<Vec<RispExp>, RispErr> {
  361. arg_forms.iter().map(|x| eval(x, env)).collect()
  362. }
  363. fn eval(exp: &RispExp, env: &mut RispEnv) -> Result<RispExp, RispErr> {
  364. match exp {
  365. RispExp::Symbol(k) => {
  366. env_get(k, env).ok_or(RispErr::Reason(format!("unexpected symbol k='{}'", k)))
  367. }
  368. RispExp::Bool(_a) => Ok(exp.clone()),
  369. RispExp::Number(_a) => Ok(exp.clone()),
  370. RispExp::List(list) => {
  371. let first_form = list
  372. .first()
  373. .ok_or(RispErr::Reason("expected a non-empty list".to_string()))?;
  374. let arg_forms = &list[1..];
  375. match eval_built_in_form(first_form, arg_forms, env) {
  376. Some(res) => res,
  377. None => {
  378. let first_eval = eval(first_form, env)?;
  379. match first_eval {
  380. RispExp::Func(f) => f(&eval_forms(arg_forms, env)?),
  381. RispExp::Lambda(lambda) => {
  382. let new_env = &mut env_for_lambda(lambda.params_exp, arg_forms, env)?;
  383. eval(&lambda.body_exp, new_env)
  384. }
  385. _ => Err(RispErr::Reason("first form must be a function".to_string())),
  386. }
  387. }
  388. }
  389. }
  390. RispExp::Func(_) => Err(RispErr::Reason("unexpected form".to_string())),
  391. RispExp::Lambda(_) => Err(RispErr::Reason("unexpected form".to_string())),
  392. }
  393. }
  394. fn main() {
  395. let env = &mut default_env();
  396. let mut reader = InPort::init("new.lisp".to_string());
  397. let mut token = String::new();
  398. read(&reader);
  399. // read from file
  400. // let file = File::open("new.lisp").unwrap();
  401. // let lines = io::BufReader::new(file).lines();
  402. // let mut cur_line = String::new();
  403. // let mut token = String::new();
  404. // for line in lines {
  405. // let (token, cur_line) = tokenize(line.ok().unwrap().as_str().to_string());
  406. // println!("token {:?}", token);
  407. // println!("line {:?}", cur_line);
  408. // }
  409. /*
  410. loop {
  411. println!("risp >");
  412. let expr = slurp_expr();
  413. match parse_eval(expr, env) {
  414. Ok(res) => println!("// 🔥 => {}", res),
  415. Err(e) => match e {
  416. RispErr::Reason(msg) => println!("// 🙀 => {}", msg),
  417. },
  418. }
  419. }
  420. */
  421. }