mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
DEV: Equality Ops
This commit is contained in:
parent
dc7437a8c1
commit
7de2e1c349
@ -26,6 +26,8 @@ pub enum Primitive {
|
||||
Empty,
|
||||
}
|
||||
|
||||
use Primitive::{Bool, Empty, Float, Int, Str};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Composite {
|
||||
List(Vec<Value>),
|
||||
@ -45,6 +47,7 @@ pub enum Value {
|
||||
// Program Pointer
|
||||
T(usize),
|
||||
}
|
||||
use Value::{C, P, S, T};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Op {
|
||||
@ -56,6 +59,12 @@ pub enum Op {
|
||||
Sub,
|
||||
Div,
|
||||
Mul,
|
||||
// Comparison Ops
|
||||
Equal,
|
||||
Gt,
|
||||
Lt,
|
||||
GtEq,
|
||||
LtEq,
|
||||
// Primitive Types ops
|
||||
Val(Primitive),
|
||||
// A bareword for use in bindings or lookups
|
||||
@ -68,7 +77,6 @@ pub enum Op {
|
||||
// Operations
|
||||
Cp,
|
||||
// Control Flow
|
||||
Select,
|
||||
Bang,
|
||||
Jump(usize),
|
||||
Noop,
|
||||
@ -116,6 +124,11 @@ impl VM {
|
||||
Op::Mul => self.op_mul()?,
|
||||
Op::Div => self.op_div()?,
|
||||
Op::Bind => self.op_bind()?,
|
||||
Op::Equal => self.op_equal()?,
|
||||
Op::Gt => self.op_gt()?,
|
||||
Op::Lt => self.op_lt()?,
|
||||
Op::GtEq => self.op_gteq()?,
|
||||
Op::LtEq => self.op_lteq()?,
|
||||
// Add a Composite list value to the stack
|
||||
Op::InitList => self.composite_push(List(Vec::new()))?,
|
||||
// Add a composite tuple value to the stack
|
||||
@ -123,7 +136,6 @@ impl VM {
|
||||
Op::Field => self.op_field()?,
|
||||
Op::Element => self.op_element()?,
|
||||
Op::Cp => self.op_copy()?,
|
||||
Op::Select => self.op_select()?,
|
||||
Op::Bang => return Err(Error {}),
|
||||
Op::InitThunk(jp) => self.op_thunk(idx, *jp)?,
|
||||
Op::Noop => {
|
||||
@ -148,13 +160,70 @@ impl VM {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_select(&mut self) -> Result<(), Error> {
|
||||
// first get our compare value from the stack
|
||||
let search_field = self.pop()?;
|
||||
// next get our default value from the stack
|
||||
let default_field = self.pop()?;
|
||||
// finally get our fields from the stack
|
||||
let fields = self.pop()?;
|
||||
fn op_equal(&mut self) -> Result<(), Error> {
|
||||
let left = self.pop()?;
|
||||
let right = self.pop()?;
|
||||
self.push(Value::P(Bool(left == right)))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_gt(&mut self) -> Result<(), Error> {
|
||||
let left = self.pop()?;
|
||||
let right = self.pop()?;
|
||||
match (left, right) {
|
||||
(P(Int(i)), P(Int(ii))) => {
|
||||
self.push(Value::P(Bool(i > ii)))?;
|
||||
}
|
||||
(P(Float(f)), P(Float(ff))) => {
|
||||
self.push(Value::P(Bool(f > ff)))?;
|
||||
}
|
||||
_ => return Err(Error {}),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_lt(&mut self) -> Result<(), Error> {
|
||||
let left = self.pop()?;
|
||||
let right = self.pop()?;
|
||||
match (left, right) {
|
||||
(P(Int(i)), P(Int(ii))) => {
|
||||
self.push(Value::P(Bool(i < ii)))?;
|
||||
}
|
||||
(P(Float(f)), P(Float(ff))) => {
|
||||
self.push(Value::P(Bool(f < ff)))?;
|
||||
}
|
||||
_ => return Err(Error {}),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_lteq(&mut self) -> Result<(), Error> {
|
||||
let left = self.pop()?;
|
||||
let right = self.pop()?;
|
||||
match (left, right) {
|
||||
(P(Int(i)), P(Int(ii))) => {
|
||||
self.push(Value::P(Bool(i <= ii)))?;
|
||||
}
|
||||
(P(Float(f)), P(Float(ff))) => {
|
||||
self.push(Value::P(Bool(f <= ff)))?;
|
||||
}
|
||||
_ => return Err(Error {}),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn op_gteq(&mut self) -> Result<(), Error> {
|
||||
let left = self.pop()?;
|
||||
let right = self.pop()?;
|
||||
match (left, right) {
|
||||
(P(Int(i)), P(Int(ii))) => {
|
||||
self.push(Value::P(Bool(i >= ii)))?;
|
||||
}
|
||||
(P(Float(f)), P(Float(ff))) => {
|
||||
self.push(Value::P(Bool(f >= ff)))?;
|
||||
}
|
||||
_ => return Err(Error {}),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@
|
||||
|
||||
use super::Composite::{List, Tuple};
|
||||
use super::Op::{
|
||||
Add, Bind, Cp, Div, Element, Field, InitList, InitThunk, InitTuple, Jump, Mul, Noop, Sub, Sym,
|
||||
Val,
|
||||
Add, Bind, Cp, Div, Element, Equal, Field, InitList, InitThunk, InitTuple, Jump, JumpIfTrue,
|
||||
Mul, Noop, Sub, Sym, Val,
|
||||
};
|
||||
use super::Primitive::{Float, Int, Str};
|
||||
use super::Primitive::{Bool, Float, Int, Str};
|
||||
use super::Value::{C, P, T};
|
||||
use super::VM;
|
||||
|
||||
@ -199,3 +199,93 @@ fn test_jump_ops() {
|
||||
assert_eq!(vm.pop().unwrap(), case.1);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_equality_ops() {
|
||||
let mut cases = vec![
|
||||
(
|
||||
vec![
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Str("foo".to_owned())),
|
||||
Equal,
|
||||
],
|
||||
P(Bool(true)),
|
||||
),
|
||||
(
|
||||
vec![
|
||||
Val(Str("bar".to_owned())),
|
||||
Val(Str("foo".to_owned())),
|
||||
Equal,
|
||||
],
|
||||
P(Bool(false)),
|
||||
),
|
||||
(vec![Val(Int(1)), Val(Int(1)), Equal], P(Bool(true))),
|
||||
(vec![Val(Int(1)), Val(Int(2)), Equal], P(Bool(false))),
|
||||
(vec![Val(Bool(true)), Val(Bool(true)), Equal], P(Bool(true))),
|
||||
(
|
||||
vec![Val(Bool(false)), Val(Bool(false)), Equal],
|
||||
P(Bool(true)),
|
||||
),
|
||||
(
|
||||
vec![Val(Bool(true)), Val(Bool(false)), Equal],
|
||||
P(Bool(false)),
|
||||
),
|
||||
(
|
||||
vec![
|
||||
InitTuple,
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Int(1)),
|
||||
Field,
|
||||
InitTuple,
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Int(1)),
|
||||
Field,
|
||||
Equal,
|
||||
],
|
||||
P(Bool(true)),
|
||||
),
|
||||
(
|
||||
vec![
|
||||
InitTuple,
|
||||
Val(Str("foo".to_owned())),
|
||||
Val(Int(1)),
|
||||
Field,
|
||||
InitTuple,
|
||||
Val(Str("bar".to_owned())),
|
||||
Val(Int(1)),
|
||||
Field,
|
||||
Equal,
|
||||
],
|
||||
P(Bool(false)),
|
||||
),
|
||||
(
|
||||
vec![
|
||||
InitList,
|
||||
Val(Str("foo".to_owned())),
|
||||
Element,
|
||||
InitList,
|
||||
Val(Str("foo".to_owned())),
|
||||
Element,
|
||||
Equal,
|
||||
],
|
||||
P(Bool(true)),
|
||||
),
|
||||
(
|
||||
vec![
|
||||
InitList,
|
||||
Val(Str("foo".to_owned())),
|
||||
Element,
|
||||
InitList,
|
||||
Val(Str("bar".to_owned())),
|
||||
Element,
|
||||
Equal,
|
||||
],
|
||||
P(Bool(false)),
|
||||
),
|
||||
];
|
||||
for case in cases.drain(0..) {
|
||||
let mut vm = VM::new(case.0);
|
||||
vm.run().unwrap();
|
||||
assert_eq!(vm.pop().unwrap(), case.1);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user