From 07432dabd3fbc7fcaaec01d50f4036868dca88dd Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 20 Mar 2021 21:34:44 +0530 Subject: factor out types into expr.rs --- src/lisp/expr.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lisp/mod.rs | 43 ++-------------------------- 2 files changed, 90 insertions(+), 40 deletions(-) create mode 100644 src/lisp/expr.rs (limited to 'src') diff --git a/src/lisp/expr.rs b/src/lisp/expr.rs new file mode 100644 index 0000000..94e778f --- /dev/null +++ b/src/lisp/expr.rs @@ -0,0 +1,87 @@ +use std::fmt; + +use crate::lisp::number::LispNumber; + +#[derive(Debug, PartialEq, Clone)] +pub enum LispExpr { + Number(LispNumber), + List(Vec), + StringLit(String), + BoolLit(bool), + Ident(String), + Function(LispFunction), + + // none of these depths should be zero + Quasiquote(Box, u32), + Comma(Box, u32), + CommaAt(Box, u32), + Quote(Box, u32), +} + +impl LispExpr { + pub fn comma(self, n: u32) -> LispExpr { + match self { + LispExpr::Comma(v, i) => LispExpr::Comma(v, i.checked_add(n).expect("comma overflow")), + LispExpr::CommaAt(v, i) => LispExpr::CommaAt(v, i + n), + v => LispExpr::Comma(Box::new(v), n), + } + } + + pub fn comma_at(self, n: u32) -> LispExpr { + match self { + LispExpr::CommaAt(v, i) => { + LispExpr::CommaAt(v, i.checked_add(n).expect("comma_at overflow")) + } + v => LispExpr::CommaAt(Box::new(v), n), + } + } + + pub fn quote(self, n: u32) -> LispExpr { + match self { + LispExpr::Quote(v, i) => LispExpr::Quote(v, i.checked_add(n).expect("quote overflow")), + v => LispExpr::Quote(Box::new(v), n), + } + } + + pub fn quasiquote(self, n: u32) -> LispExpr { + match self { + LispExpr::Quasiquote(v, i) => { + LispExpr::Quasiquote(v, i.checked_add(n).expect("quasiquote overflow")) + } + v => LispExpr::Quasiquote(Box::new(v), n), + } + } +} + +impl fmt::Display for LispExpr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + LispExpr::Number(n) => write!(f, "{}", n)?, + LispExpr::List(l) => { + for expr in l.iter() { + write!(f, " {} ", expr)? + } + } + LispExpr::StringLit(s) => write!(f, "{:?}", s)?, + LispExpr::BoolLit(b) => { + if *b { + write!(f, "#t")? + } else { + write!(f, "#f")? + } + } + LispExpr::Ident(s) => write!(f, "{}", s)?, + LispExpr::Function(_) => write!(f, "<#procedure>")?, + LispExpr::Quasiquote(val, depth) => { + write!(f, "{}{}", "`".repeat(*depth as usize), val)? + } + LispExpr::Comma(val, depth) => write!(f, "{}{}", ",".repeat(*depth as usize), val)?, + LispExpr::CommaAt(val, depth) => write!(f, "{}@{}", ",".repeat(*depth as usize), val)?, + LispExpr::Quote(val, depth) => write!(f, "{}{}", "'".repeat(*depth as usize), val)?, + }; + Ok(()) + } +} + +#[derive(Debug, PartialEq, Clone)] +struct LispFunction {} diff --git a/src/lisp/mod.rs b/src/lisp/mod.rs index 5d8965f..b863bba 100644 --- a/src/lisp/mod.rs +++ b/src/lisp/mod.rs @@ -1,46 +1,9 @@ -use std::fmt; - -use number::LispNumber; - mod error; +mod expr; mod lex; mod number; +mod parse; -#[derive(Debug, PartialEq)] -pub enum LispExpr { - Number(LispNumber), - List(Vec), - StringLit(String), - BoolLit(bool), - Ident(String), - Function(LispFunction), -} - -impl fmt::Display for LispExpr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - LispExpr::Number(n) => write!(f, "{}", n)?, - LispExpr::List(l) => { - for expr in l.iter() { - write!(f, " {} ", expr)? - } - } - LispExpr::StringLit(s) => write!(f, "{:?}", s)?, - LispExpr::BoolLit(b) => { - if *b { - write!(f, "#t")? - } else { - write!(f, "#f")? - } - } - LispExpr::Ident(s) => write!(f, "{}", s)?, - LispExpr::Function(_) => write!(f, "<#procedure>")?, - }; - Ok(()) - } -} +use expr::LispExpr; pub type Environment = Vec<(String, LispExpr)>; - -#[derive(Debug, PartialEq)] -struct LispFunction {} -- cgit v1.2.3