aboutsummaryrefslogtreecommitdiff
path: root/src/sexp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sexp')
-rw-r--r--src/sexp/step.rs141
-rw-r--r--src/sexp/util.rs6
2 files changed, 139 insertions, 8 deletions
diff --git a/src/sexp/step.rs b/src/sexp/step.rs
index bb3ada5..f09c014 100644
--- a/src/sexp/step.rs
+++ b/src/sexp/step.rs
@@ -110,28 +110,28 @@ impl SExp {
///
/// assert_eq!(
/// scons(Le, scons(1, scons(2, Nil))).step(),
- /// Ok(Atom(True))
+ /// Ok(Atom(True)), "le 1"
/// );
/// assert_eq!(
/// scons(Le, scons(2, scons(2, Nil))).step(),
- /// Ok(Atom(True))
+ /// Ok(Atom(True)), "le 2"
/// );
/// assert_eq!(
- /// scons(Lt, scons(2, scons(1, Nil))).step(),
- /// Ok(Atom(False))
+ /// scons(Le, scons(2, scons(1, Nil))).step(),
+ /// Ok(Atom(False)), "le 3"
/// );
///
/// assert_eq!(
/// scons(Ge, scons(2, scons(1, Nil))).step(),
- /// Ok(Atom(True))
+ /// Ok(Atom(True)), "ge 1"
/// );
/// assert_eq!(
/// scons(Ge, scons(1, scons(1, Nil))).step(),
- /// Ok(Atom(True))
+ /// Ok(Atom(True)), "ge 2"
/// );
/// assert_eq!(
- /// scons(Lt, scons(1, scons(2, Nil))).step(),
- /// Ok(Atom(False))
+ /// scons(Ge, scons(1, scons(2, Nil))).step(),
+ /// Ok(Atom(False)), "ge 3"
/// );
///
/// assert_eq!(
@@ -315,6 +315,131 @@ impl SExp {
}
},
+
+ // t1,t2 booleans
+ // -----------------------
+ // (and t1 t2) -> t1 && t2
+ SCons(op, l) if *op == Atom(And) => {
+ let ls = l.into_vec()?;
+ if ls.len() == 2 {
+ match (ls[0].clone(), ls[1].clone()) {
+ (True, True) => Ok(Atom(True)),
+ (True | False, True | False) => Ok(Atom(False)),
+ _ => Err("'and' should be only given booleans".to_string())
+ }
+ } else {
+ Err(format!("'and' should be given 2 arguments, found {}", ls.len()))
+ }
+ },
+
+ // t1,t2 booleans
+ // -----------------------
+ // (or t1 t2) -> t1 || t2
+ SCons(op, l) if *op == Atom(Or) => {
+ let ls = l.into_vec()?;
+ if ls.len() == 2 {
+ match (ls[0].clone(), ls[1].clone()) {
+ (False, False) => Ok(Atom(False)),
+ (True | False, True | False) => Ok(Atom(True)),
+ _ => Err("'or' should be only given booleans".to_string())
+ }
+ } else {
+ Err(format!("'or' should be given 2 arguments, found {}", ls.len()))
+ }
+ },
+
+ // t1,t2 booleans
+ // --------------
+ // (xor t1 t2) -> t1 ^ t2
+ SCons(op, l) if *op == Atom(Xor) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (True, False) => Ok(Atom(True)),
+ (False, True) => Ok(Atom(True)),
+ (True | False, True | False) => Ok(Atom(False)),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Not
+ SCons(op, l) if *op == Atom(Not) => {
+ let ls = l.into_vec()?;
+ let t1 = ls.get(0).ok_or("wrong list length".to_string())?;
+ match t1 {
+ True => Ok(Atom(False)),
+ False => Ok(Atom(True)),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Lt
+ SCons(op, l) if *op == Atom(Lt) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (Int(a), Int(b)) => Ok((a < b).into()),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Gt
+ SCons(op, l) if *op == Atom(Gt) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (Int(a), Int(b)) => Ok((a > b).into()),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Le
+ SCons(op, l) if *op == Atom(Le) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (Int(a), Int(b)) => Ok((a <= b).into()),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Ge
+ SCons(op, l) if *op == Atom(Ge) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (Int(a), Int(b)) => Ok((a >= b).into()),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Eq
+ SCons(op, l) if *op == Atom(Eq) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (Int(a), Int(b)) => Ok((a == b).into()),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
+ // Neq
+ SCons(op, l) if *op == Atom(Neq) => {
+ let ls = l.into_vec()?;
+ 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, t2) {
+ (Int(a), Int(b)) => Ok((a != b).into()),
+ _ => Err("invalid args".to_string()),
+ }
+ },
+
// t is value
// ----------
// t -> t
diff --git a/src/sexp/util.rs b/src/sexp/util.rs
index f01dab9..b3edf19 100644
--- a/src/sexp/util.rs
+++ b/src/sexp/util.rs
@@ -12,6 +12,12 @@ impl From<i32> for Box<SExp> {
}
}
+impl From<bool> for SExp {
+ fn from(bl: bool) -> Self {
+ Atom( if bl { True } else { False } )
+ }
+}
+
impl From<SLeaf> for Box<SExp> {
fn from(leaf: SLeaf) -> Self {
Box::new(Atom(leaf))