use ::slist::Stack;
use ::slist::List::{Cons,Nil};
use super::State;
use super::cell::Atom::*;
use super::cell::SVMCell::*;
use super::Inst::*;
use quickcheck::quickcheck;
use test::Bencher;
#[test]
fn prop_eval_ldc_sint () {
fn prop (x: i64) -> bool {
let state = State {
stack: Stack::empty(),
env: Stack::empty(),
control: list!(InstCell(LDC),AtomCell(SInt(x))),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
state.stack.peek() == Some(&AtomCell(SInt(x)))
}
quickcheck(prop as fn(i64) -> bool);
}
#[test]
fn prop_eval_ldc_uint () {
fn prop (x: u64) -> bool {
let state = State {
stack: Stack::empty(),
env: Stack::empty(),
control: list!(InstCell(LDC),AtomCell(UInt(x))),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
state.stack.peek() == Some(&AtomCell(UInt(x)))
}
quickcheck(prop as fn(u64) -> bool);
}
#[test]
fn prop_eval_ldc_float () {
fn prop (x: f64) -> bool {
let state = State {
stack: Stack::empty(),
env: Stack::empty(),
control: list!(InstCell(LDC),AtomCell(Float(x))),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
state.stack.peek() == Some(&AtomCell(Float(x)))
}
quickcheck(prop as fn(f64) -> bool);
}
#[test]
fn test_empty_state() {
let state = State::new();
assert_eq!(state.stack.length(), 0);
assert_eq!(state.env.length(), 0);
assert_eq!(state.control.length(), 0);
assert_eq!(state.dump.length(), 0);
}
#[test]
fn test_eval_nil () {
let mut state = State {
stack: Stack::empty(),
env: Stack::empty(),
control: list!(InstCell(NIL),AtomCell(SInt(1))),
dump: Stack::empty()
};
assert_eq!(state.stack.peek(), None);
state = state.eval(None,true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
}
#[test]
fn test_eval_ldc () {
let mut state = State::new();
assert_eq!(state.stack.peek(), None);
state = State {
stack: state.stack,
env: state.env,
control: list!(InstCell(LDC),AtomCell(SInt(1))),
dump: state.dump
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(1))));
state = State {
stack: state.stack,
env: state.env,
control: list!(InstCell(LDC),AtomCell(Char('a'))),
dump: state.dump
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Char('a'))));
state = State {
stack: state.stack,
env: state.env,
control: list!(InstCell(LDC),AtomCell(Float(1.0f64))),
dump: state.dump
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.0f64))));
}
#[test]
fn test_eval_ld () {
let state = State {
stack: Stack::empty(),
env: list!(list_cell![
AtomCell(SInt(155)),
AtomCell(UInt(388))
]),
control: list!(
InstCell(LD),
list_cell![ AtomCell(SInt(1)), AtomCell(SInt(2)) ]
),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(UInt(388))));
}
#[test]
fn test_eval_ldf () {
let state = State {
stack: Stack::empty(),
env: list!(
list_cell![ AtomCell(SInt(155)), AtomCell(UInt(388)) ],
list_cell![ AtomCell(Float(6.66)), AtomCell(SInt(666)) ]
),
control: list!(InstCell(LDF), list_cell![AtomCell(SInt(133))] ),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(
state.stack.peek(),
Some(&list_cell![
list_cell![ AtomCell(SInt(133)) ],
list_cell![ AtomCell(SInt(155)), AtomCell(UInt(388)) ]
])
);
}
#[test]
fn test_eval_join() {
let state = State {
stack: Stack::empty(),
env: Stack::empty(),
control: list!(InstCell(JOIN)),
dump: list!(list_cell![
AtomCell(SInt(1)),
AtomCell(SInt(2))
])
}.eval(None, true).unwrap().0;
assert_eq!(state.dump.peek(), None);
assert_eq!(state.control[0u64], AtomCell(SInt(1)));
assert_eq!(state.control[1u64], AtomCell(SInt(2)));
}
#[test]
fn test_eval_add () {
let mut state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(1))),
env: Stack::empty(),
control: list!(InstCell(ADD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(UInt(2))));
state = State {
stack: list!(AtomCell(SInt(-1)), AtomCell(SInt(-1))),
env: Stack::empty(),
control: list!(InstCell(ADD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(-2))));
state = State {
stack: list!(AtomCell(Float(1.5)), AtomCell(Float(1.5))),
env: Stack::empty(),
control: list!(InstCell(ADD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(3.0))));
state = State {
stack: list!(AtomCell(Float(1.5)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(ADD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(2.5))));
state = State {
stack: list!(AtomCell(Float(3.5)), AtomCell(UInt(1))),
env: Stack::empty(),
control: list!(InstCell(ADD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(4.5))));
}
#[test]
fn test_eval_sub () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(3))),
env: Stack::empty(),
control: list!(InstCell(SUB)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(UInt(0))));
state = State {
stack: list!(AtomCell(SInt(-3)), AtomCell(SInt(3))),
env: Stack::empty(),
control: list!(InstCell(SUB)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(-6))));
state = State {
stack: list!(AtomCell(Float(1.5)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(SUB)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(-0.5))));
state = State {
stack: list!(AtomCell(Float(2.5)), AtomCell(SInt(-2))),
env: Stack::empty(),
control: list!(InstCell(SUB)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(4.5))));
state = State {
stack: list!(AtomCell(Float(3.5)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(SUB)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.5))));
}
#[test]
fn test_eval_mul () {
let mut state = State {
stack: list!(AtomCell(UInt(2)), AtomCell(UInt(3))),
env: Stack::empty(),
control: list!(InstCell(MUL)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(UInt(6))));
state = State {
stack: list!(AtomCell(SInt(-2)), AtomCell(SInt(-3))),
env: Stack::empty(),
control: list!(InstCell(MUL)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(6))));
state = State {
stack: list!(AtomCell(Float(1.5)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(MUL)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(3.0))));
state = State {
stack: list!(AtomCell(Float(1.5)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(MUL)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(3.0))));
state = State {
stack: list!(AtomCell(Float(3.5)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(MUL)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(7.0))));
}
#[test]
fn test_eval_div () {
let mut state = State {
stack: list!(AtomCell(UInt(6)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(DIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(UInt(3))));
state = State {
stack: list!(AtomCell(SInt(-6)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(DIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(-3))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(DIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.5))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(DIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.5))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(DIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.5))));
}
#[test]
fn test_eval_fdiv () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(FDIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.5))));
state = State {
stack: list!(AtomCell(SInt(-3)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(FDIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(-1.5))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(FDIV)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(1.5))));
}
#[test]
fn test_eval_mod () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(MOD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(UInt(3%2))));
state = State {
stack: list!(AtomCell(SInt(-3)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(MOD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(-3%2))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(MOD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(3.0%2.0))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(MOD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(3.0%2.0))));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(MOD)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Float(3.0%2.0))));
}
#[test]
fn test_eval_eq () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(3))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(SInt(3)), AtomCell(SInt(3))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(-2)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(3.0))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(-2.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(2.11)), AtomCell(Float(2.1))),
env: Stack::empty(),
control: list!(InstCell(EQ)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
}
#[test]
fn test_eval_gt () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(SInt(3)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(-2)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(1.0))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(-2.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(2.11)), AtomCell(Float(2.1))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(GT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
}
#[test]
fn test_eval_gte () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(1))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(SInt(3)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(1)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(1)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(Float(1.0))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(GTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
}
#[test]
fn test_eval_lt () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(1))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(SInt(3)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(SInt(-2)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(2)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(1.0))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(-2.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(2.11)), AtomCell(Float(2.1))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(2.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(LT)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
}
#[test]
fn test_eval_lte () {
let mut state = State {
stack: list!(AtomCell(UInt(3)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(1))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(UInt(2))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(3)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(SInt(1)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(SInt(1)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(Float(1.0))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(3.0)), AtomCell(SInt(2))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(AtomCell(Float(1.0)), AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![])
);
state = State {
stack: list!(AtomCell(UInt(1)), AtomCell(Float(2.0))),
env: Stack::empty(),
control: list!(InstCell(LTE)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
}
#[test]
fn test_eval_ret() {
let state = State {
stack: list!(AtomCell(SInt(100)), AtomCell(SInt(320))),
env: Stack::empty(),
control: list!(InstCell(RET)),
dump: list!(
list_cell![ AtomCell(Char('S')), AtomCell(Char('L')) ],
list_cell![
list_cell![ AtomCell(Char('E')), AtomCell(Char('L')) ],
list_cell![ AtomCell(Char('E')), AtomCell(Char('D')) ]
],
list_cell![ AtomCell(Char('C')), AtomCell(Char('L')) ]
)
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(SInt(100)))); assert_eq!(state.stack[0u64], AtomCell(SInt(100)));
assert_eq!(state.stack[1u64], AtomCell(Char('S')));
assert_eq!(state.stack[2u64], AtomCell(Char('L')));
assert_eq!(
state.env.peek(),
Some(&list_cell![ AtomCell(Char('E')), AtomCell(Char('L')) ])
);
assert_eq!(
state.env[0u64],
list_cell![ AtomCell(Char('E')), AtomCell(Char('L')) ]
);
assert_eq!(
state.env[1u64],
list_cell![ AtomCell(Char('E')), AtomCell(Char('D')) ]
);
assert_eq!(state.control.peek(), Some(&AtomCell(Char('C'))));
assert_eq!(state.control[0u64], AtomCell(Char('C')));
assert_eq!(state.control[1u64], AtomCell(Char('L')));
assert_eq!(state.dump.peek(), None);
}
#[test]
fn test_eval_dum() {
let state = State {
stack: Stack::empty(),
env: list!(list_cell![ AtomCell(Char('a')) ]),
control: list!(InstCell(DUM)),
dump: Stack::empty(),
}.eval(None, true).unwrap().0;
assert_eq!(state.env.peek(), Some(&list_cell![]));
}
#[test]
fn test_eval_ap() {
let state = State {
stack: list!(list_cell![
list_cell![
InstCell(RET),
InstCell(ADD),
AtomCell(SInt(1)),
InstCell(LDC),
list_cell![
AtomCell(UInt(0)),
AtomCell(UInt(0))
],
InstCell(LD)
],
list_cell![ list_cell![ AtomCell(SInt(1)) ] ]
],
list_cell![ AtomCell(Char('Q')) ]
),
env: list!(list_cell![ AtomCell(Char('D')) ]),
control: list!(InstCell(AP), InstCell(DUM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), None );
assert_eq!(
state.control,
list!(
InstCell(RET),
InstCell(ADD),
AtomCell(SInt(1)),
InstCell(LDC),
list_cell![ AtomCell(UInt(0)), AtomCell(UInt(0)) ],
InstCell(LD)));
assert_eq!(
state.env,
list!(
list_cell![ AtomCell(Char('Q')) ],
list_cell![ AtomCell(SInt(1)) ]
)
);
}
#[test]
fn test_eval_atom() {
let mut state = State {
stack: list!(AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(UInt(0))),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Char('C'))),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Char('A'))),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(AtomCell(Float(1.23f64))),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert!(
state.stack.peek() != Some(&list_cell![]) &&
state.stack.peek() != None
);
state = State {
stack: list!(InstCell(DUM)),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
state = State {
stack: list!(list_cell![]),
env: Stack::empty(),
control: list!(InstCell(ATOM)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![]));
}
#[test]
fn test_eval_car() {
let state = State {
stack: list!(list_cell![ AtomCell(Char('A')),AtomCell(Char('B')) ]),
env: Stack::empty(),
control: list!(InstCell(CAR)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&AtomCell(Char('A'))));
}
#[test]
fn test_eval_cdr() {
let state = State {
stack:list!(list_cell![ AtomCell(Char('A')),AtomCell(Char('B')) ]),
env: Stack::empty(),
control: list!(InstCell(CDR)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), Some(&list_cell![ AtomCell(Char('B')) ]) );
}
#[test]
fn test_eval_cons() {
let state = State {
stack: list!(
AtomCell(Char('A')),
list_cell![ AtomCell(Char('B')) ,AtomCell(Char('C')) ]
),
env: Stack::empty(),
control: list!(InstCell(CONS)),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(
state.stack.peek(),
Some(&list_cell![
AtomCell(Char('A')), AtomCell(Char('B')), AtomCell(Char('C'))
])
);
}
#[test]
fn test_eval_sel_true() {
let state = State {
stack: list!(list_cell![]),
env: Stack::empty(),
control: list!(
InstCell(SEL),
list_cell![ InstCell(ATOM) ], list_cell![ InstCell(NIL) ], InstCell(JOIN) ),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), None); assert_eq!(state.control.peek(), Some(&InstCell(NIL)));
assert_eq!(state.dump.peek(), Some(&list_cell![ InstCell(JOIN) ]) ); }
#[test]
fn test_eval_sel_false() {
let state = State {
stack: list!(list_cell![ AtomCell(SInt(1)) ]),
env: Stack::empty(),
control: list!(
InstCell(SEL),
list_cell![ InstCell(ATOM) ], list_cell![ InstCell(NIL) ], InstCell(JOIN) ),
dump: Stack::empty()
}.eval(None, true).unwrap().0;
assert_eq!(state.stack.peek(), None); assert_eq!(state.control.peek(), Some(&InstCell(ATOM)));
assert_eq!(state.dump.peek(), Some(&list_cell![ InstCell(JOIN) ]) ); }
#[test]
fn test_eval_null() {
assert_eq!(
State {
stack: list!(AtomCell(SInt(1))),
env: Stack::empty(),
control: list!(InstCell(NULL)),
dump: Stack::empty(),
}.eval(None,true).unwrap().0.stack.peek(),
Some(&list_cell![])
);
assert_eq!(
State {
stack: list!(list_cell![]),
env: Stack::empty(),
control: list!(InstCell(NULL)),
dump: Stack::empty(),
}.eval(None,true).unwrap().0.stack.peek(),
Some(&list_cell![ AtomCell(SInt(1)) ])
);
}
#[bench]
fn bench_list_creation(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(NIL),
InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS)
), true)
})
}
#[bench]
fn bench_list_car(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(NIL),
InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
InstCell(CAR)
), true)
})
}
#[bench]
fn bench_list_cdr(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(NIL),
InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
InstCell(CDR)
), true)
})
}
#[bench]
fn bench_simple_add(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(LDC), AtomCell(SInt(10)),
InstCell(LDC), AtomCell(SInt(10)),
InstCell(ADD)
), true)
})
}
#[bench]
fn bench_nested_arith(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(LDC), AtomCell(SInt(5)),
InstCell(LDC), AtomCell(SInt(5)),
InstCell(ADD),
InstCell(LDC), AtomCell(SInt(20)),
InstCell(SUB)
), true)
})
}
#[bench]
fn bench_basic_branching_1(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(LDC), AtomCell(SInt(1)), InstCell(LDC), AtomCell(SInt(1)),
InstCell(SUB),
InstCell(LDC), AtomCell(SInt(0)),
InstCell(EQ),
InstCell(SEL),
list_cell![
InstCell(LDC),
AtomCell(SInt(1)),
InstCell(JOIN)
],
list_cell![
InstCell(NIL),
InstCell(JOIN)
]
), true)
})
}
#[bench]
fn bench_basic_branching_2(b: &mut Bencher) {
b.iter(|| {
super::eval_program(list!(
InstCell(NIL), InstCell(NULL),
InstCell(SEL),
list_cell![ InstCell(LDC), AtomCell(SInt(10)), InstCell(JOIN) ],
list_cell![ InstCell(LDC), AtomCell(SInt(20)), InstCell(JOIN) ],
InstCell(LDC), AtomCell(SInt(10)),
InstCell(ADD)
), true)
})
}