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,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use Primitive::{Bool, Empty, Float, Int, Str};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Composite {
|
pub enum Composite {
|
||||||
List(Vec<Value>),
|
List(Vec<Value>),
|
||||||
@ -45,6 +47,7 @@ pub enum Value {
|
|||||||
// Program Pointer
|
// Program Pointer
|
||||||
T(usize),
|
T(usize),
|
||||||
}
|
}
|
||||||
|
use Value::{C, P, S, T};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub enum Op {
|
pub enum Op {
|
||||||
@ -56,6 +59,12 @@ pub enum Op {
|
|||||||
Sub,
|
Sub,
|
||||||
Div,
|
Div,
|
||||||
Mul,
|
Mul,
|
||||||
|
// Comparison Ops
|
||||||
|
Equal,
|
||||||
|
Gt,
|
||||||
|
Lt,
|
||||||
|
GtEq,
|
||||||
|
LtEq,
|
||||||
// Primitive Types ops
|
// Primitive Types ops
|
||||||
Val(Primitive),
|
Val(Primitive),
|
||||||
// A bareword for use in bindings or lookups
|
// A bareword for use in bindings or lookups
|
||||||
@ -68,7 +77,6 @@ pub enum Op {
|
|||||||
// Operations
|
// Operations
|
||||||
Cp,
|
Cp,
|
||||||
// Control Flow
|
// Control Flow
|
||||||
Select,
|
|
||||||
Bang,
|
Bang,
|
||||||
Jump(usize),
|
Jump(usize),
|
||||||
Noop,
|
Noop,
|
||||||
@ -116,6 +124,11 @@ impl VM {
|
|||||||
Op::Mul => self.op_mul()?,
|
Op::Mul => self.op_mul()?,
|
||||||
Op::Div => self.op_div()?,
|
Op::Div => self.op_div()?,
|
||||||
Op::Bind => self.op_bind()?,
|
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
|
// Add a Composite list value to the stack
|
||||||
Op::InitList => self.composite_push(List(Vec::new()))?,
|
Op::InitList => self.composite_push(List(Vec::new()))?,
|
||||||
// Add a composite tuple value to the stack
|
// Add a composite tuple value to the stack
|
||||||
@ -123,7 +136,6 @@ impl VM {
|
|||||||
Op::Field => self.op_field()?,
|
Op::Field => self.op_field()?,
|
||||||
Op::Element => self.op_element()?,
|
Op::Element => self.op_element()?,
|
||||||
Op::Cp => self.op_copy()?,
|
Op::Cp => self.op_copy()?,
|
||||||
Op::Select => self.op_select()?,
|
|
||||||
Op::Bang => return Err(Error {}),
|
Op::Bang => return Err(Error {}),
|
||||||
Op::InitThunk(jp) => self.op_thunk(idx, *jp)?,
|
Op::InitThunk(jp) => self.op_thunk(idx, *jp)?,
|
||||||
Op::Noop => {
|
Op::Noop => {
|
||||||
@ -148,13 +160,70 @@ impl VM {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_select(&mut self) -> Result<(), Error> {
|
fn op_equal(&mut self) -> Result<(), Error> {
|
||||||
// first get our compare value from the stack
|
let left = self.pop()?;
|
||||||
let search_field = self.pop()?;
|
let right = self.pop()?;
|
||||||
// next get our default value from the stack
|
self.push(Value::P(Bool(left == right)))?;
|
||||||
let default_field = self.pop()?;
|
Ok(())
|
||||||
// finally get our fields from the stack
|
}
|
||||||
let fields = self.pop()?;
|
|
||||||
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
use super::Composite::{List, Tuple};
|
use super::Composite::{List, Tuple};
|
||||||
use super::Op::{
|
use super::Op::{
|
||||||
Add, Bind, Cp, Div, Element, Field, InitList, InitThunk, InitTuple, Jump, Mul, Noop, Sub, Sym,
|
Add, Bind, Cp, Div, Element, Equal, Field, InitList, InitThunk, InitTuple, Jump, JumpIfTrue,
|
||||||
Val,
|
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::Value::{C, P, T};
|
||||||
use super::VM;
|
use super::VM;
|
||||||
|
|
||||||
@ -199,3 +199,93 @@ fn test_jump_ops() {
|
|||||||
assert_eq!(vm.pop().unwrap(), case.1);
|
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