Most of operations are implemented

This commit is contained in:
Erin 2021-08-30 22:14:13 +02:00 committed by ondra05
parent e2c7a33a59
commit 539989e2d0

View file

@ -1,6 +1,14 @@
use std::{ use std::{
cell::RefCell, collections::HashMap, convert::TryFrom, fmt::Display, hash::Hash, io::Write, cell::RefCell,
mem::discriminant, ops, rc::Rc, vec, collections::HashMap,
convert::{TryFrom, TryInto},
fmt::Display,
hash::Hash,
io::Write,
mem::discriminant,
ops,
rc::Rc,
vec,
}; };
use rand::Rng; use rand::Rng;
@ -203,31 +211,6 @@ impl Value {
Value::Bool(b) => Value::Str(b.to_string()).into_cart(), Value::Bool(b) => Value::Str(b.to_string()).into_cart(),
Value::Abool(a) => Value::Str(a.to_string()).into_cart(), Value::Abool(a) => Value::Str(a.to_string()).into_cart(),
Value::Functio(f) => match f { Value::Functio(f) => match f {
Functio::BfFunctio {
instructions,
tape_len,
} => {
let mut cart: Cart = instructions
.into_iter()
.enumerate()
.map(|(i, x)| {
(
Value::Int(i as i32 + 1),
Rc::new(RefCell::new(
char::from_u32(x as u32)
.map(|x| Value::Str(x.to_string()))
.unwrap_or(Value::Nul),
)),
)
})
.collect();
cart.insert(
Value::Str("tapelen".to_owned()),
Rc::new(RefCell::new(Value::Int(tape_len as _))),
);
cart
}
Functio::AbleFunctio { params, body } => { Functio::AbleFunctio { params, body } => {
let params: Cart = params let params: Cart = params
.into_iter() .into_iter()
@ -264,6 +247,31 @@ impl Value {
cart cart
} }
Functio::BfFunctio {
instructions,
tape_len,
} => {
let mut cart: Cart = instructions
.into_iter()
.enumerate()
.map(|(i, x)| {
(
Value::Int(i as i32 + 1),
Rc::new(RefCell::new(
char::from_u32(x as u32)
.map(|x| Value::Str(x.to_string()))
.unwrap_or(Value::Nul),
)),
)
})
.collect();
cart.insert(
Value::Str("tapelen".to_owned()),
Rc::new(RefCell::new(Value::Int(tape_len as _))),
);
cart
}
Functio::Eval(s) => Value::Str(s).into_cart(), Functio::Eval(s) => Value::Str(s).into_cart(),
}, },
Value::Cart(c) => c, Value::Cart(c) => c,
@ -276,10 +284,18 @@ impl ops::Add for Value {
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
match self { match self {
Value::Nul => todo!(), Value::Nul => match rhs {
Value::Nul => Value::Nul,
Value::Str(_) => Value::Str(self.to_string()) + rhs,
Value::Int(_) => Value::Int(self.into_i32()) + rhs,
Value::Bool(_) => Value::Bool(self.into_bool()) + rhs,
Value::Abool(_) => Value::Abool(self.into_abool()) + rhs,
Value::Functio(_) => Value::Functio(self.into_functio()) + rhs,
Value::Cart(_) => Value::Cart(self.into_cart()) + rhs,
},
Value::Str(s) => Value::Str(format!("{}{}", s, rhs.to_string())), Value::Str(s) => Value::Str(format!("{}{}", s, rhs.to_string())),
Value::Int(i) => Value::Int(i.checked_add(rhs.into_i32()).unwrap_or(consts::ANSWER)), Value::Int(i) => Value::Int(i.wrapping_add(rhs.into_i32())),
Value::Bool(b) => Value::Bool(b ^ rhs.into_bool()), Value::Bool(b) => Value::Bool(b || rhs.into_bool()),
Value::Abool(a) => Value::Abool({ Value::Abool(a) => Value::Abool({
let rhs = rhs.into_abool(); let rhs = rhs.into_abool();
if a == rhs { if a == rhs {
@ -312,7 +328,28 @@ impl ops::Sub for Value {
type Output = Value; type Output = Value;
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {
todo!() match self {
Value::Nul => match rhs {
Value::Nul => Value::Nul,
Value::Str(_) => Value::Str(self.to_string()) - rhs,
Value::Int(_) => Value::Int(self.into_i32()) - rhs,
Value::Bool(_) => Value::Bool(self.into_bool()) - rhs,
Value::Abool(_) => Value::Abool(self.into_abool()) - rhs,
Value::Functio(_) => Value::Functio(self.into_functio()) - rhs,
Value::Cart(_) => Value::Cart(self.into_cart()) - rhs,
},
Value::Str(s) => Value::Str(s.replace(&rhs.to_string(), "")),
Value::Int(i) => Value::Int(i.wrapping_sub(rhs.into_i32())),
Value::Bool(b) => Value::Bool(b ^ rhs.into_bool()),
Value::Abool(_) => todo!(),
Value::Functio(_) => todo!(),
Value::Cart(c) => Value::Cart({
let rhs_cart = rhs.into_cart();
c.into_iter()
.filter(|(k, v)| rhs_cart.get(k) != Some(v))
.collect()
}),
}
} }
} }
@ -320,7 +357,23 @@ impl ops::Mul for Value {
type Output = Value; type Output = Value;
fn mul(self, rhs: Self) -> Self::Output { fn mul(self, rhs: Self) -> Self::Output {
todo!() match self {
Value::Nul => match rhs {
Value::Nul => Value::Nul,
Value::Str(_) => Value::Str(self.to_string()) * rhs,
Value::Int(_) => Value::Int(self.into_i32()) * rhs,
Value::Bool(_) => Value::Bool(self.into_bool()) * rhs,
Value::Abool(_) => Value::Abool(self.into_abool()) * rhs,
Value::Functio(_) => Value::Functio(self.into_functio()) * rhs,
Value::Cart(_) => Value::Cart(self.into_cart()) * rhs,
},
Value::Str(s) => Value::Str(s.repeat(rhs.into_i32() as usize)),
Value::Int(i) => Value::Int(i.wrapping_mul(rhs.into_i32())),
Value::Bool(b) => Value::Bool(b && rhs.into_bool()),
Value::Abool(_) => todo!(),
Value::Functio(_) => todo!(),
Value::Cart(_) => todo!(),
}
} }
} }
@ -328,7 +381,40 @@ impl ops::Div for Value {
type Output = Value; type Output = Value;
fn div(self, rhs: Self) -> Self::Output { fn div(self, rhs: Self) -> Self::Output {
todo!() match self {
Value::Nul => match rhs {
Value::Nul => Value::Nul,
Value::Str(_) => Value::Str(self.to_string()) / rhs,
Value::Int(_) => Value::Int(self.into_i32()) / rhs,
Value::Bool(_) => Value::Bool(self.into_bool()) / rhs,
Value::Abool(_) => Value::Abool(self.into_abool()) / rhs,
Value::Functio(_) => Value::Functio(self.into_functio()) / rhs,
Value::Cart(_) => Value::Cart(self.into_cart()) / rhs,
},
Value::Str(s) => Value::Cart(
s.split(&rhs.to_string())
.enumerate()
.map(|(i, x)| {
(
Value::Int(i as i32 + 1),
Rc::new(RefCell::new(Value::Str(x.to_owned()))),
)
})
.collect(),
),
Value::Int(i) => Value::Int({
let rhsi = rhs.into_i32();
if rhsi == 0 {
consts::ANSWER
} else {
i.wrapping_div(rhsi)
}
}),
Value::Bool(b) => Value::Bool(!(b && rhs.into_bool())),
Value::Abool(_) => todo!(),
Value::Functio(_) => todo!(),
Value::Cart(_) => todo!(),
}
} }
} }