lisp.rs 12 KB

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