aboutsummaryrefslogtreecommitdiff
path: root/src/sexp/step.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sexp/step.rs')
-rw-r--r--src/sexp/step.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/sexp/step.rs b/src/sexp/step.rs
index 11df257..c26dce9 100644
--- a/src/sexp/step.rs
+++ b/src/sexp/step.rs
@@ -1,5 +1,6 @@
use crate::sexp::{SExp, SExp::*, SLeaf::*, util::*};
+use crate::r#type::{Type::*, util::*};
impl SExp {
@@ -521,6 +522,29 @@ impl SExp {
}
},
+ // Type arrow
+ SCons(op, l) if *op == Atom(Arr) => {
+ let ls = l.parts();
+ let t1 = ls.get(0).ok_or("wrong list length".to_string())?;
+ let t2 = ls.get(1).ok_or("wrong list length".to_string())?;
+ match (t1.clone().multistep()?, t2.clone().multistep()?) {
+ (Atom(Ty(a)), Atom(Ty(b))) => Ok(Atom(Ty(arr(a.clone(), b.clone())))),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Type list
+ SCons(op, l) if (*op).is_type_lit() => {
+ let mut res = vec![];
+ for exp in std::iter::once(*op).chain(l.parts()) {
+ res.push(match exp.multistep()? {
+ Atom(Ty(t)) => Ok(t),
+ e => Err(format!("not a type: {e}")),
+ }?);
+ }
+ Ok(Atom(Ty(List(res))))
+ },
+
// Print
SCons(op, l) if *op == Atom(Print) => {
println!("{}", *l);