From 3ed60f7306cf7e3a9236cf9a70c1eb2b2bafc5b9 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 7 Dec 2021 21:18:45 +0100 Subject: [PATCH 01/23] Function negation --- ablescript/src/variables.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 5ee99cb6..0e0a1685 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -443,7 +443,27 @@ impl ops::Not for Value { Abool::Sometimes => Abool::Sometimes, Abool::Always => Abool::Never, }), - Value::Functio(_) => todo!(), + Value::Functio(f) => Value::Functio(match f { + Functio::BfFunctio { + mut instructions, + tape_len, + } => { + instructions.reverse(); + Functio::BfFunctio { + instructions, + tape_len, + } + } + Functio::AbleFunctio { + mut params, + mut body, + } => { + params.reverse(); + body.reverse(); + Functio::AbleFunctio { params, body } + } + Functio::Eval(code) => Functio::Eval(code.chars().rev().collect()), + }), Value::Cart(c) => Value::Cart( c.into_iter() .map(|(k, v)| (v.borrow().clone(), Rc::new(RefCell::new(k)))) From 6b5b8998c93acca275d1460bc9e2989c48c52155 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 7 Dec 2021 21:20:16 +0100 Subject: [PATCH 02/23] Fmt! --- ablescript/src/variables.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 0e0a1685..571a53d3 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -449,6 +449,7 @@ impl ops::Not for Value { tape_len, } => { instructions.reverse(); + Functio::BfFunctio { instructions, tape_len, @@ -460,6 +461,7 @@ impl ops::Not for Value { } => { params.reverse(); body.reverse(); + Functio::AbleFunctio { params, body } } Functio::Eval(code) => Functio::Eval(code.chars().rev().collect()), From 1a78eaf8c333ffc43823fdd31fd429ced15f5fed Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 7 Dec 2021 21:20:24 +0100 Subject: [PATCH 03/23] huh??? --- ablescript/src/variables.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 571a53d3..2cce2b56 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -461,7 +461,7 @@ impl ops::Not for Value { } => { params.reverse(); body.reverse(); - + Functio::AbleFunctio { params, body } } Functio::Eval(code) => Functio::Eval(code.chars().rev().collect()), From 07d021f61035a7031a1c230cd0466c62c36a48c1 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 7 Dec 2021 21:57:37 +0100 Subject: [PATCH 04/23] Implemented Functio to Aboolean --- ablescript/src/variables.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 2cce2b56..1a7af9e7 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -165,7 +165,29 @@ impl Value { } } Value::Abool(a) => a, - Value::Functio(_) => todo!(), + Value::Functio(f) => match f { + Functio::BfFunctio { + instructions, + tape_len, + } => Value::Int( + (instructions.iter().map(|x| *x as usize).sum::() * tape_len) as _, + ) + .into_abool(), + Functio::AbleFunctio { params, body } => { + let str_to_i32 = + |x: String| -> i32 { x.as_bytes().into_iter().map(|x| *x as i32).sum() }; + + let params: i32 = params.into_iter().map(str_to_i32).sum(); + let body: i32 = body + .into_iter() + .map(|x| format!("{:?}", x)) + .map(str_to_i32) + .sum(); + + Value::Int((params + body) % 3 - 1).into_abool() + } + Functio::Eval(code) => Value::Str(code).into_abool(), + }, Value::Cart(c) => { if c.is_empty() { Abool::Never From 8824633aaef01a7dba72a5e23192bd3f40cf60b2 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Tue, 7 Dec 2021 14:24:58 -0700 Subject: [PATCH 05/23] =?UTF-8?q?I=20made=20a=20cursed=20thing=20?= =?UTF-8?q?=F0=9F=98=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ablescript/src/variables.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 1a7af9e7..47a3a1d3 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -206,7 +206,16 @@ impl Value { params: vec![], }, Value::Str(s) => Functio::Eval(s), - Value::Int(_) => todo!(), + Value::Int(i) => Functio::BfFunctio { + instructions: { + let instruction_mappings = [b'[', b']', b'+', b'-', b',', b'.', b'<', b'>']; + std::iter::successors(Some(i), |i| Some(i >> 3)) + .take_while(|&i| i != 0) + .map(|i| instruction_mappings[(i & 0x07) as usize]) + .collect() + }, + tape_len: crate::brian::DEFAULT_TAPE_SIZE_LIMIT, + }, Value::Bool(_) => todo!(), Value::Abool(_) => todo!(), Value::Functio(f) => f, From 7812058fbf8bbc03eb5b6e1633482183cc1ef252 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Tue, 7 Dec 2021 14:27:45 -0700 Subject: [PATCH 06/23] Better BF function conversions --- ablescript/src/variables.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 47a3a1d3..11e2d6a5 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -209,10 +209,12 @@ impl Value { Value::Int(i) => Functio::BfFunctio { instructions: { let instruction_mappings = [b'[', b']', b'+', b'-', b',', b'.', b'<', b'>']; - std::iter::successors(Some(i), |i| Some(i >> 3)) - .take_while(|&i| i != 0) - .map(|i| instruction_mappings[(i & 0x07) as usize]) - .collect() + std::iter::successors(Some(i as usize), |i| { + Some(i / instruction_mappings.len()) + }) + .take_while(|&i| i != 0) + .map(|i| instruction_mappings[i % instruction_mappings.len()]) + .collect() }, tape_len: crate::brian::DEFAULT_TAPE_SIZE_LIMIT, }, From 66ceb8f8c62738465f325f6f543e9e2a78661b53 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 7 Dec 2021 22:58:41 +0100 Subject: [PATCH 07/23] Implemented Abool -> Functio --- ablescript/src/variables.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 11e2d6a5..241654b5 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -218,8 +218,25 @@ impl Value { }, tape_len: crate::brian::DEFAULT_TAPE_SIZE_LIMIT, }, - Value::Bool(_) => todo!(), - Value::Abool(_) => todo!(), + Value::Bool(b) => Functio::Eval( + if b { + r#"loop{"Buy Able products!"print;}"# + } else { + "" + } + .to_owned(), + ), + Value::Abool(a) => Functio::Eval(match a { + Abool::Never => "".to_owned(), + Abool::Sometimes => { + use rand::seq::SliceRandom; + let mut str_chars: Vec<_> = "Buy Able Products!".chars().collect(); + str_chars.shuffle(&mut rand::thread_rng()); + + format!(r#""{}"print;"#, str_chars.iter().collect::()) + } + Abool::Always => r#"loop{"Buy Able products!"print;}"#.to_owned(), + }), Value::Functio(f) => f, Value::Cart(_) => todo!(), } From 8993e78ee65e99d6a34ab1541f7d11163768611f Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Wed, 8 Dec 2021 14:39:04 -0700 Subject: [PATCH 08/23] Use b-string instead of array of b-chars --- ablescript/src/variables.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 241654b5..a34f3cba 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -208,7 +208,7 @@ impl Value { Value::Str(s) => Functio::Eval(s), Value::Int(i) => Functio::BfFunctio { instructions: { - let instruction_mappings = [b'[', b']', b'+', b'-', b',', b'.', b'<', b'>']; + let instruction_mappings = b"[]+-,.<>"; std::iter::successors(Some(i as usize), |i| { Some(i / instruction_mappings.len()) }) From 920ff99a7f012d3b1e72804f234d8a0d2ee88cef Mon Sep 17 00:00:00 2001 From: Erin Date: Wed, 8 Dec 2021 22:56:12 +0100 Subject: [PATCH 09/23] Made Clippy happy (so he will not kill us in sleep) --- ablescript/src/interpret.rs | 8 ++++---- ablescript/src/variables.rs | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 5c9cae6c..23fc846e 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -205,7 +205,7 @@ impl ExecEnv { } => { self.decl_var( &ident.ident, - Value::Functio(Functio::AbleFunctio { + Value::Functio(Functio::Able { params: params.iter().map(|ident| ident.ident.to_owned()).collect(), body: body.block.to_owned(), }), @@ -218,7 +218,7 @@ impl ExecEnv { } => { self.decl_var( &ident.ident, - Value::Functio(Functio::BfFunctio { + Value::Functio(Functio::Bf { instructions: code.to_owned(), tape_len: tape_len .as_ref() @@ -351,7 +351,7 @@ impl ExecEnv { .collect::, Error>>()?; match func { - Functio::BfFunctio { + Functio::Bf { instructions, tape_len, } => { @@ -377,7 +377,7 @@ impl ExecEnv { .write_all(&output) .expect("Failed to write to stdout"); } - Functio::AbleFunctio { params, body } => { + Functio::Able { params, body } => { if params.len() != args.len() { return Err(Error { kind: ErrorKind::MismatchedArgumentError, diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index a34f3cba..e1f44597 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -36,11 +36,11 @@ impl From for bool { #[derive(Debug, PartialEq, Clone, Hash)] pub enum Functio { - BfFunctio { + Bf { instructions: Vec, tape_len: usize, }, - AbleFunctio { + Able { params: Vec, body: Vec, }, @@ -103,11 +103,11 @@ impl Value { // BfFunctio - Sum of lengths of instructions and length of tape // AbleFunctio - Sum of argument count and body length // Eval - Length of input code - Functio::BfFunctio { + Functio::Bf { instructions, tape_len, } => (instructions.len() + tape_len) as _, - Functio::AbleFunctio { params, body } => { + Functio::Able { params, body } => { (params.len() + format!("{:?}", body).len()) as _ } Functio::Eval(s) => s.len() as _, @@ -166,14 +166,14 @@ impl Value { } Value::Abool(a) => a, Value::Functio(f) => match f { - Functio::BfFunctio { + Functio::Bf { instructions, tape_len, } => Value::Int( (instructions.iter().map(|x| *x as usize).sum::() * tape_len) as _, ) .into_abool(), - Functio::AbleFunctio { params, body } => { + Functio::Able { params, body } => { let str_to_i32 = |x: String| -> i32 { x.as_bytes().into_iter().map(|x| *x as i32).sum() }; @@ -201,12 +201,12 @@ impl Value { /// Coerce a value to a functio. pub fn into_functio(self) -> Functio { match self { - Value::Nul => Functio::AbleFunctio { + Value::Nul => Functio::Able { body: vec![], params: vec![], }, Value::Str(s) => Functio::Eval(s), - Value::Int(i) => Functio::BfFunctio { + Value::Int(i) => Functio::Bf { instructions: { let instruction_mappings = b"[]+-,.<>"; std::iter::successors(Some(i as usize), |i| { @@ -260,7 +260,7 @@ impl Value { Value::Bool(b) => Value::Str(b.to_string()).into_cart(), Value::Abool(a) => Value::Str(a.to_string()).into_cart(), Value::Functio(f) => match f { - Functio::AbleFunctio { params, body } => { + Functio::Able { params, body } => { let params: Cart = params .into_iter() .enumerate() @@ -296,7 +296,7 @@ impl Value { cart } - Functio::BfFunctio { + Functio::Bf { instructions, tape_len, } => { @@ -494,25 +494,25 @@ impl ops::Not for Value { Abool::Always => Abool::Never, }), Value::Functio(f) => Value::Functio(match f { - Functio::BfFunctio { + Functio::Bf { mut instructions, tape_len, } => { instructions.reverse(); - Functio::BfFunctio { + Functio::Bf { instructions, tape_len, } } - Functio::AbleFunctio { + Functio::Able { mut params, mut body, } => { params.reverse(); body.reverse(); - Functio::AbleFunctio { params, body } + Functio::Able { params, body } } Functio::Eval(code) => Functio::Eval(code.chars().rev().collect()), }), @@ -575,7 +575,7 @@ impl Display for Value { Value::Bool(v) => write!(f, "{}", v), Value::Abool(v) => write!(f, "{}", v), Value::Functio(v) => match v { - Functio::BfFunctio { + Functio::Bf { instructions, tape_len, } => { @@ -587,7 +587,7 @@ impl Display for Value { .expect("Brainfuck functio source should be UTF-8") ) } - Functio::AbleFunctio { params, body } => { + Functio::Able { params, body } => { write!( f, "({}) -> {:?}", From 7225bd30044a5864aefb29e1286e115ede524431 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Wed, 8 Dec 2021 16:33:06 -0700 Subject: [PATCH 10/23] Function division --- ablescript/src/variables.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index e1f44597..4787f35d 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -107,9 +107,7 @@ impl Value { instructions, tape_len, } => (instructions.len() + tape_len) as _, - Functio::Able { params, body } => { - (params.len() + format!("{:?}", body).len()) as _ - } + Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, Functio::Eval(s) => s.len() as _, }, Value::Int(i) => i, @@ -456,7 +454,38 @@ impl ops::Div for Value { })), Value::Bool(b) => Value::Bool(!b || rhs.into_bool()), Value::Abool(_) => !self + rhs, - Value::Functio(_) => todo!(), + Value::Functio(f) => { + let fraction = 1.0 / rhs.into_i32() as f64; + Value::Functio(match f { + Functio::Bf { + instructions, + tape_len, + } => { + let len = instructions.len(); + Functio::Bf { + instructions: instructions + .into_iter() + .take((len as f64 * fraction) as usize) + .collect(), + tape_len, + } + } + Functio::Able { params, body } => { + let len = body.len(); + Functio::Able { + params, + body: body + .into_iter() + .take((len as f64 * fraction) as usize) + .collect(), + } + } + Functio::Eval(s) => { + let len = s.len(); + Functio::Eval(s.chars().take((len as f64 * fraction) as usize).collect()) + } + }) + } Value::Cart(c) => { let cart_len = c.len(); let chunk_len = rhs.into_i32() as usize; From 656926387b7df34909edefed7adc4d3158802b48 Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 9 Dec 2021 00:33:45 +0100 Subject: [PATCH 11/23] Implemented halfway of functio sub --- ablescript/src/brian.rs | 3 +- ablescript/src/interpret.rs | 1 + ablescript/src/variables.rs | 153 +++++++++++++++++++++++++++++++++--- 3 files changed, 146 insertions(+), 11 deletions(-) diff --git a/ablescript/src/brian.rs b/ablescript/src/brian.rs index 91c7d2e4..a9151567 100644 --- a/ablescript/src/brian.rs +++ b/ablescript/src/brian.rs @@ -17,7 +17,6 @@ //! [`interpret_with_output`]: Interpreter::interpret_with_output #![deny(missing_docs)] - // Putting this here because we still don't use the entire capabilities of this module. ~~Alex #![allow(dead_code)] @@ -33,6 +32,8 @@ use std::{ /// The default limit for the tape size. This is the value used by methods that don't take it as a parameter pub const DEFAULT_TAPE_SIZE_LIMIT: usize = 30_000; +/// Mappings from integers to BF instructions +pub const INSTRUCTION_MAPPINGS: &[u8] = b"[]+-,.<>"; #[derive(Debug, Clone, PartialEq, Eq)] /// A brainfuck interpreter. Read the [module level documentation](self) for more pub struct Interpreter<'a, I> { diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 23fc846e..8aad7abc 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -396,6 +396,7 @@ impl ExecEnv { self.stack.pop(); res?; } + Functio::Chain { .. } => todo!(), Functio::Eval(code) => { if !args.is_empty() { return Err(Error { diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index e1f44597..ffe4cbfa 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -5,7 +5,7 @@ use std::{ use rand::Rng; -use crate::{ast::Stmt, consts}; +use crate::{ast::Stmt, brian::INSTRUCTION_MAPPINGS, consts}; #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] pub enum Abool { @@ -44,9 +44,19 @@ pub enum Functio { params: Vec, body: Vec, }, + Chain { + functios: Box<(Functio, Functio)>, + kind: FunctioChainKind, + }, Eval(String), } +#[derive(Debug, PartialEq, Copy, Clone, Hash)] +pub enum FunctioChainKind { + Ordered, + Interlaced, +} + pub type Cart = HashMap>>; #[derive(Debug, Clone)] @@ -107,8 +117,20 @@ impl Value { instructions, tape_len, } => (instructions.len() + tape_len) as _, - Functio::Able { params, body } => { - (params.len() + format!("{:?}", body).len()) as _ + Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, + Functio::Chain { functios, kind } => { + let (lhs, rhs) = *functios; + match kind { + FunctioChainKind::Ordered => { + Value::Int(Value::Functio(lhs).into_i32()) + + Value::Int(Value::Functio(rhs).into_i32()) + } + FunctioChainKind::Interlaced => { + Value::Int(Value::Functio(lhs).into_i32()) + * Value::Int(Value::Functio(rhs).into_i32()) + } + } + .into_i32() } Functio::Eval(s) => s.len() as _, }, @@ -186,6 +208,20 @@ impl Value { Value::Int((params + body) % 3 - 1).into_abool() } + Functio::Chain { functios, kind } => { + let (lhs, rhs) = *functios; + match kind { + FunctioChainKind::Ordered => { + Value::Abool(Value::Functio(lhs).into_abool()) + + Value::Abool(Value::Functio(rhs).into_abool()) + } + FunctioChainKind::Interlaced => { + Value::Abool(Value::Functio(lhs).into_abool()) + * Value::Abool(Value::Functio(rhs).into_abool()) + } + } + .into_abool() + } Functio::Eval(code) => Value::Str(code).into_abool(), }, Value::Cart(c) => { @@ -208,12 +244,11 @@ impl Value { Value::Str(s) => Functio::Eval(s), Value::Int(i) => Functio::Bf { instructions: { - let instruction_mappings = b"[]+-,.<>"; std::iter::successors(Some(i as usize), |i| { - Some(i / instruction_mappings.len()) + Some(i / INSTRUCTION_MAPPINGS.len()) }) .take_while(|&i| i != 0) - .map(|i| instruction_mappings[i % instruction_mappings.len()]) + .map(|i| INSTRUCTION_MAPPINGS[i % INSTRUCTION_MAPPINGS.len()]) .collect() }, tape_len: crate::brian::DEFAULT_TAPE_SIZE_LIMIT, @@ -238,7 +273,28 @@ impl Value { Abool::Always => r#"loop{"Buy Able products!"print;}"#.to_owned(), }), Value::Functio(f) => f, - Value::Cart(_) => todo!(), + Value::Cart(c) => { + let kind = if let Some(114514) = c + .get(&Value::Str("1452251871514141792252515212116".to_owned())) + .map(|x| x.borrow().to_owned().into_i32()) + { + FunctioChainKind::Ordered + } else { + FunctioChainKind::Interlaced + }; + + let mut cart_vec = c.iter().collect::>(); + cart_vec.sort_by(|x, y| x.0.partial_cmp(y.0).unwrap_or(std::cmp::Ordering::Less)); + + cart_vec + .into_iter() + .map(|(_, x)| x.borrow().to_owned().into_functio()) + .reduce(|acc, x| Functio::Chain { + functios: Box::new((acc, x)), + kind, + }) + .unwrap_or_else(|| Functio::Eval(r#""Buy Able Products!"print;"#.to_owned())) + } } } @@ -321,6 +377,20 @@ impl Value { ); cart } + Functio::Chain { functios, kind } => { + let (lhs, rhs) = *functios; + match kind { + FunctioChainKind::Ordered => { + Value::Cart(Value::Functio(lhs).into_cart()) + + Value::Cart(Value::Functio(rhs).into_cart()) + } + FunctioChainKind::Interlaced => { + Value::Cart(Value::Functio(lhs).into_cart()) + * Value::Cart(Value::Functio(rhs).into_cart()) + } + } + .into_cart() + } Functio::Eval(s) => Value::Str(s).into_cart(), }, Value::Cart(c) => c, @@ -348,7 +418,10 @@ impl ops::Add for Value { Value::Abool(_) => { Value::Abool(Value::Int(self.into_i32().max(rhs.into_i32())).into_abool()) } - Value::Functio(_) => todo!(), + Value::Functio(f) => Value::Functio(Functio::Chain { + functios: Box::new((f, rhs.into_functio())), + kind: FunctioChainKind::Ordered, + }), Value::Cart(c) => { Value::Cart(c.into_iter().chain(rhs.into_cart().into_iter()).collect()) } @@ -374,7 +447,41 @@ impl ops::Sub for Value { Value::Int(i) => Value::Int(i.wrapping_sub(rhs.into_i32())), Value::Bool(b) => Value::Bool(b ^ rhs.into_bool()), Value::Abool(_) => (self.clone() + rhs.clone()) * !(self * rhs), - Value::Functio(_) => todo!(), + Value::Functio(f) => Value::Functio(match f { + Functio::Bf { + instructions: lhs_ins, + tape_len: lhs_tl, + } => match rhs.into_functio() { + Functio::Bf { + instructions: rhs_ins, + tape_len: rhs_tl, + } => Functio::Bf { + instructions: lhs_ins + .into_iter() + .zip(rhs_ins.into_iter()) + .filter_map(|(l, r)| if l != r { Some(l) } else { None }) + .collect(), + tape_len: lhs_tl - rhs_tl, + }, + rhs => Functio::Bf { + instructions: lhs_ins + .into_iter() + .zip(Value::Functio(rhs).to_string().bytes()) + .filter_map(|(l, r)| if l != r { Some(l) } else { None }) + .collect(), + tape_len: lhs_tl, + }, + }, + Functio::Able { params, body } => todo!(), + Functio::Chain { functios, kind } => todo!(), + Functio::Eval(lhs_code) => Functio::Eval(lhs_code.replace( + &match rhs.into_functio() { + Functio::Eval(code) => code, + rhs => Value::Functio(rhs).to_string(), + }, + "", + )), + }), Value::Cart(c) => Value::Cart({ let rhs_cart = rhs.into_cart(); c.into_iter() @@ -405,7 +512,10 @@ impl ops::Mul for Value { Value::Abool(_) => { Value::Abool(Value::Int(self.into_i32().min(rhs.into_i32())).into_abool()) } - Value::Functio(_) => todo!(), + Value::Functio(f) => Value::Functio(Functio::Chain { + functios: Box::new((f, rhs.into_functio())), + kind: FunctioChainKind::Interlaced, + }), Value::Cart(c) => { let rhsc = rhs.into_cart(); @@ -514,6 +624,16 @@ impl ops::Not for Value { Functio::Able { params, body } } + Functio::Chain { functios, kind } => { + let (a, b) = *functios; + Functio::Chain { + functios: Box::new(( + (!Value::Functio(b)).into_functio(), + (!Value::Functio(a)).into_functio(), + )), + kind, + } + } Functio::Eval(code) => Functio::Eval(code.chars().rev().collect()), }), Value::Cart(c) => Value::Cart( @@ -597,6 +717,19 @@ impl Display for Value { body, ) } + Functio::Chain { functios, kind } => { + let (a, b) = *functios.clone(); + write!( + f, + "{} {} {} ", + Value::Functio(a), + match kind { + FunctioChainKind::Ordered => '+', + FunctioChainKind::Interlaced => '*', + }, + Value::Functio(b) + ) + } Functio::Eval(s) => write!(f, "{}", s), }, Value::Cart(c) => { From d7725b0db70b3db89943b2241e67e8574f3129a1 Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 9 Dec 2021 00:35:43 +0100 Subject: [PATCH 12/23] sync --- ablescript/src/variables.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index a6e4848f..cd0bd3a5 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -578,6 +578,7 @@ impl ops::Div for Value { .collect(), } } + Functio::Chain { .. } => todo!(":P"), Functio::Eval(s) => { let len = s.len(); Functio::Eval(s.chars().take((len as f64 * fraction) as usize).collect()) From d570dfcb6ff415219e0c34f4a89c502b1dde0c97 Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 9 Dec 2021 00:38:36 +0100 Subject: [PATCH 13/23] Who cares about the content, we have 256 commits! And I readded a thing --- ablescript/src/variables.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index cd0bd3a5..96c963dc 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -118,6 +118,20 @@ impl Value { tape_len, } => (instructions.len() + tape_len) as _, Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, + Functio::Chain { functios, kind } => { + let (lhs, rhs) = *functios; + match kind { + FunctioChainKind::Ordered => { + Value::Int(Value::Functio(lhs).into_i32()) + + Value::Int(Value::Functio(rhs).into_i32()) + } + FunctioChainKind::Interlaced => { + Value::Int(Value::Functio(lhs).into_i32()) + * Value::Int(Value::Functio(rhs).into_i32()) + } + } + .into_i32() + } Functio::Eval(s) => s.len() as _, }, Value::Int(i) => i, From 7aeb9d525d79924bb52e6b1f86139412e153ce1e Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 9 Dec 2021 17:18:37 +0100 Subject: [PATCH 14/23] Implemented coercions when subtracting able functios --- ablescript/src/variables.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 96c963dc..f16f94c4 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -472,7 +472,35 @@ impl ops::Sub for Value { tape_len: lhs_tl, }, }, - Functio::Able { params, body } => todo!(), + Functio::Able { + params: lhs_params, + body: lhs_body, + } => match rhs.into_functio() { + Functio::Able { + params: rhs_params, + body: rhs_body, + } => Functio::Able { + params: lhs_params + .into_iter() + .zip(rhs_params.into_iter()) + .filter_map(|(l, r)| if l != r { Some(l) } else { None }) + .collect(), + body: lhs_body + .into_iter() + .zip(rhs_body.into_iter()) + .filter_map(|(l, r)| if l != r { Some(l) } else { None }) + .collect(), + }, + rhs => Value::Int( + Value::Functio(Functio::Able { + params: lhs_params, + body: lhs_body, + }) + .into_i32() + - Value::Functio(rhs).into_i32(), + ) + .into_functio(), + }, Functio::Chain { functios, kind } => todo!(), Functio::Eval(lhs_code) => Functio::Eval(lhs_code.replace( &match rhs.into_functio() { From 6f193577ab8bb8d9dd7f8661d7fd121e53b490a3 Mon Sep 17 00:00:00 2001 From: Erin Date: Thu, 9 Dec 2021 17:51:03 +0100 Subject: [PATCH 15/23] Implemented subtraction for functio chains... maybe? --- ablescript/src/variables.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index f16f94c4..11782976 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -501,7 +501,16 @@ impl ops::Sub for Value { ) .into_functio(), }, - Functio::Chain { functios, kind } => todo!(), + Functio::Chain { functios, .. } => { + let rhs = rhs.into_functio(); + let (a, b) = *functios; + + match (a == rhs, b == rhs) { + (_, true) => a, + (true, _) => b, + (_, _) => (Value::Functio(a) - Value::Functio(rhs)).into_functio(), + } + } Functio::Eval(lhs_code) => Functio::Eval(lhs_code.replace( &match rhs.into_functio() { Functio::Eval(code) => code, From 690c78c9c0c405ebe9abe6721511545d8b8816b4 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 14 Dec 2021 21:10:58 +0100 Subject: [PATCH 16/23] Removed a feature which disallowed comments in functios --- ablescript/src/parser.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ablescript/src/parser.rs b/ablescript/src/parser.rs index 4f8bf235..19c39268 100644 --- a/ablescript/src/parser.rs +++ b/ablescript/src/parser.rs @@ -53,9 +53,16 @@ impl<'source> Parser<'source> { /// /// If EOF, return Error instead of None fn checked_next(&mut self) -> Result { - self.lexer - .next() - .ok_or_else(|| Error::unexpected_eof(self.lexer.span().start)) + loop { + match self + .lexer + .next() + .ok_or_else(|| Error::unexpected_eof(self.lexer.span().start))? + { + Token::Comment => (), + token => break Ok(token), + } + } } /// Parse a token From cd902e00363a1753615c607b4cf94490b3200e54 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 14 Dec 2021 21:45:44 +0100 Subject: [PATCH 17/23] =?UTF-8?q?=F0=9F=9A=97=20Implemented=20ordered=20fu?= =?UTF-8?q?nctio=20chaining?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ablescript/src/interpret.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 8aad7abc..0d234812 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -350,6 +350,15 @@ impl ExecEnv { }) .collect::, Error>>()?; + self.fn_call_with_values(func, &args, span) + } + + fn fn_call_with_values( + &mut self, + func: Functio, + args: &[Rc>], + span: &Range, + ) -> Result<(), Error> { match func { Functio::Bf { instructions, @@ -396,7 +405,16 @@ impl ExecEnv { self.stack.pop(); res?; } - Functio::Chain { .. } => todo!(), + Functio::Chain { functios, kind } => { + let (left_functio, right_functio) = *functios; + let (left_args, right_args) = match kind { + crate::variables::FunctioChainKind::Ordered => args.split_at(args.len() / 2), + crate::variables::FunctioChainKind::Interlaced => todo!(), + }; + + self.fn_call_with_values(left_functio, left_args, span)?; + self.fn_call_with_values(right_functio, right_args, span)?; + } Functio::Eval(code) => { if !args.is_empty() { return Err(Error { From f890d6248b37248c1dea5466bb68a8cfd51841a4 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Tue, 14 Dec 2021 15:56:40 -0600 Subject: [PATCH 18/23] Arity-based functio deinterlacing --- able-script-test/interlace.able | 44 +++++++++++++++++++++++++++++ ablescript/src/interpret.rs | 50 ++++++++++++++++++++++++++++++--- ablescript/src/variables.rs | 16 ++++++++++- 3 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 able-script-test/interlace.able diff --git a/able-script-test/interlace.able b/able-script-test/interlace.able new file mode 100644 index 00000000..2dca191c --- /dev/null +++ b/able-script-test/interlace.able @@ -0,0 +1,44 @@ +functio arity_0() { + "this function has arity 0" print; +} + +functio arity_1(arg1) { + "this function has arity 1" print; + arg1 print; +} + +functio arity_2(arg1, arg2) { + "this function has arity 2" print; + arg1 print; + arg2 print; +} + +functio arity_3(arg1, arg2, arg3) { + "this function has arity 3" print; + arg1 print; + arg2 print; + arg3 print; +} + +owo arity_0(); +owo arity_1("foo"); +owo arity_2("foo", "bar"); +owo arity_3("foo", "bar", "baz"); + +var i1 = arity_0 * arity_1; +i1("second"); + +"----" print; + +var i2 = arity_1 * arity_0; +i2("first"); + +"----" print; + +var ifancy = arity_3 * arity_3; +ifancy("left1", "right1", "left2", "right2", "left3", "right3"); + +"----" print; + +var another = arity_0 * arity_3; +another("right1", "right2", "right3"); diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 0d234812..40c26369 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -9,6 +9,7 @@ #![deny(missing_docs)] use std::{ cell::RefCell, + cmp::Ordering, collections::{HashMap, VecDeque}, io::{stdin, stdout, Read, Write}, mem::take, @@ -408,12 +409,18 @@ impl ExecEnv { Functio::Chain { functios, kind } => { let (left_functio, right_functio) = *functios; let (left_args, right_args) = match kind { - crate::variables::FunctioChainKind::Ordered => args.split_at(args.len() / 2), - crate::variables::FunctioChainKind::Interlaced => todo!(), + crate::variables::FunctioChainKind::Ordered => { + let (l, r) = args.split_at(args.len() / 2); + // TODO: avoid this clone + (l.to_owned(), r.to_owned()) + } + crate::variables::FunctioChainKind::Interlaced => { + Self::deinterlace(args, (left_functio.arity(), right_functio.arity())) + } }; - self.fn_call_with_values(left_functio, left_args, span)?; - self.fn_call_with_values(right_functio, right_args, span)?; + self.fn_call_with_values(left_functio, &left_args, span)?; + self.fn_call_with_values(right_functio, &right_args, span)?; } Functio::Eval(code) => { if !args.is_empty() { @@ -430,6 +437,41 @@ impl ExecEnv { Ok(()) } + fn deinterlace( + args: &[Rc>], + arities: (usize, usize), + ) -> (Vec>>, Vec>>) { + let n_alternations = usize::min(arities.0, arities.1); + let (extra_l, extra_r) = match Ord::cmp(&arities.0, &arities.1) { + Ordering::Less => (0, arities.1 - arities.0), + Ordering::Equal => (0, 0), + Ordering::Greater => (arities.0 - arities.1, 0), + }; + + ( + args.chunks(2) + .take(n_alternations) + .map(|chunk| Rc::clone(&chunk[0])) + .chain( + args[2 * n_alternations..] + .iter() + .map(|r| Rc::clone(r)) + .take(extra_l), + ) + .collect(), + args.chunks(2) + .take(n_alternations) + .map(|chunk| Rc::clone(&chunk[1])) + .chain( + args[2 * n_alternations..] + .iter() + .map(|r| Rc::clone(r)) + .take(extra_r), + ) + .collect(), + ) + } + /// Get a single bit from the bit buffer, or refill it from /// standard input if it is empty. fn get_bit(&mut self) -> Result { diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 11782976..c5b933f8 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -51,6 +51,20 @@ pub enum Functio { Eval(String), } +impl Functio { + pub fn arity(&self) -> usize { + match self { + Functio::Bf { + instructions: _, + tape_len: _, + } => 0, + Functio::Able { params, body: _ } => params.len(), + Functio::Chain { functios, kind: _ } => functios.0.arity() + functios.1.arity(), + Functio::Eval(_) => 0, + } + } +} + #[derive(Debug, PartialEq, Copy, Clone, Hash)] pub enum FunctioChainKind { Ordered, @@ -504,7 +518,7 @@ impl ops::Sub for Value { Functio::Chain { functios, .. } => { let rhs = rhs.into_functio(); let (a, b) = *functios; - + match (a == rhs, b == rhs) { (_, true) => a, (true, _) => b, From b93333262cf702026d63369f09bc4b771355dd64 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Tue, 14 Dec 2021 15:57:04 -0600 Subject: [PATCH 19/23] Fix carts.able formatting --- able-script-test/carts.able | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/able-script-test/carts.able b/able-script-test/carts.able index 21b5a0d0..b12ef8dc 100644 --- a/able-script-test/carts.able +++ b/able-script-test/carts.able @@ -1,8 +1,8 @@ functio helloable() { - "Hello, Able!" print; + "Hello, Able!" print; } var cart = ["able" <= 42, helloable <= "hello"]; cart[42] print; -cart["hello"](); \ No newline at end of file +cart["hello"](); From 0da3d587186cdc7eee9b6d0a3398c9cfaf08c879 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 14 Dec 2021 23:02:55 +0100 Subject: [PATCH 20/23] Renamed stuff --- .../{interlace.able => by-arity-chain.able} | 0 ablescript/src/interpret.rs | 4 +-- ablescript/src/variables.rs | 28 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) rename able-script-test/{interlace.able => by-arity-chain.able} (100%) diff --git a/able-script-test/interlace.able b/able-script-test/by-arity-chain.able similarity index 100% rename from able-script-test/interlace.able rename to able-script-test/by-arity-chain.able diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 40c26369..bcf0cff5 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -409,12 +409,12 @@ impl ExecEnv { Functio::Chain { functios, kind } => { let (left_functio, right_functio) = *functios; let (left_args, right_args) = match kind { - crate::variables::FunctioChainKind::Ordered => { + crate::variables::FunctioChainKind::Equal => { let (l, r) = args.split_at(args.len() / 2); // TODO: avoid this clone (l.to_owned(), r.to_owned()) } - crate::variables::FunctioChainKind::Interlaced => { + crate::variables::FunctioChainKind::ByArity => { Self::deinterlace(args, (left_functio.arity(), right_functio.arity())) } }; diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index c5b933f8..90d00b6f 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -67,8 +67,8 @@ impl Functio { #[derive(Debug, PartialEq, Copy, Clone, Hash)] pub enum FunctioChainKind { - Ordered, - Interlaced, + Equal, + ByArity, } pub type Cart = HashMap>>; @@ -135,11 +135,11 @@ impl Value { Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { - FunctioChainKind::Ordered => { + FunctioChainKind::Equal => { Value::Int(Value::Functio(lhs).into_i32()) + Value::Int(Value::Functio(rhs).into_i32()) } - FunctioChainKind::Interlaced => { + FunctioChainKind::ByArity => { Value::Int(Value::Functio(lhs).into_i32()) * Value::Int(Value::Functio(rhs).into_i32()) } @@ -225,11 +225,11 @@ impl Value { Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { - FunctioChainKind::Ordered => { + FunctioChainKind::Equal => { Value::Abool(Value::Functio(lhs).into_abool()) + Value::Abool(Value::Functio(rhs).into_abool()) } - FunctioChainKind::Interlaced => { + FunctioChainKind::ByArity => { Value::Abool(Value::Functio(lhs).into_abool()) * Value::Abool(Value::Functio(rhs).into_abool()) } @@ -292,9 +292,9 @@ impl Value { .get(&Value::Str("1452251871514141792252515212116".to_owned())) .map(|x| x.borrow().to_owned().into_i32()) { - FunctioChainKind::Ordered + FunctioChainKind::Equal } else { - FunctioChainKind::Interlaced + FunctioChainKind::ByArity }; let mut cart_vec = c.iter().collect::>(); @@ -394,11 +394,11 @@ impl Value { Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { - FunctioChainKind::Ordered => { + FunctioChainKind::Equal => { Value::Cart(Value::Functio(lhs).into_cart()) + Value::Cart(Value::Functio(rhs).into_cart()) } - FunctioChainKind::Interlaced => { + FunctioChainKind::ByArity => { Value::Cart(Value::Functio(lhs).into_cart()) * Value::Cart(Value::Functio(rhs).into_cart()) } @@ -434,7 +434,7 @@ impl ops::Add for Value { } Value::Functio(f) => Value::Functio(Functio::Chain { functios: Box::new((f, rhs.into_functio())), - kind: FunctioChainKind::Ordered, + kind: FunctioChainKind::Equal, }), Value::Cart(c) => { Value::Cart(c.into_iter().chain(rhs.into_cart().into_iter()).collect()) @@ -565,7 +565,7 @@ impl ops::Mul for Value { } Value::Functio(f) => Value::Functio(Functio::Chain { functios: Box::new((f, rhs.into_functio())), - kind: FunctioChainKind::Interlaced, + kind: FunctioChainKind::ByArity, }), Value::Cart(c) => { let rhsc = rhs.into_cart(); @@ -807,8 +807,8 @@ impl Display for Value { "{} {} {} ", Value::Functio(a), match kind { - FunctioChainKind::Ordered => '+', - FunctioChainKind::Interlaced => '*', + FunctioChainKind::Equal => '+', + FunctioChainKind::ByArity => '*', }, Value::Functio(b) ) From 183f26f415dd420a325b3cc99c15f19eac645828 Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 14 Dec 2021 23:05:21 +0100 Subject: [PATCH 21/23] Removed clone --- ablescript/src/interpret.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index bcf0cff5..183eb9ff 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -408,19 +408,21 @@ impl ExecEnv { } Functio::Chain { functios, kind } => { let (left_functio, right_functio) = *functios; - let (left_args, right_args) = match kind { + match kind { crate::variables::FunctioChainKind::Equal => { let (l, r) = args.split_at(args.len() / 2); - // TODO: avoid this clone - (l.to_owned(), r.to_owned()) + + self.fn_call_with_values(left_functio, l, span)?; + self.fn_call_with_values(right_functio, r, span)?; } crate::variables::FunctioChainKind::ByArity => { - Self::deinterlace(args, (left_functio.arity(), right_functio.arity())) + let (l, r) = + Self::deinterlace(args, (left_functio.arity(), right_functio.arity())); + + self.fn_call_with_values(left_functio, &l, span)?; + self.fn_call_with_values(right_functio, &r, span)?; } }; - - self.fn_call_with_values(left_functio, &left_args, span)?; - self.fn_call_with_values(right_functio, &right_args, span)?; } Functio::Eval(code) => { if !args.is_empty() { From 007917a217dd8508ef0d53846cf1cb6a2318db9d Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 14 Dec 2021 23:16:19 +0100 Subject: [PATCH 22/23] Fixed T-Dark blocks in blocks --- ablescript/src/parser.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ablescript/src/parser.rs b/ablescript/src/parser.rs index 19c39268..6f7ebb66 100644 --- a/ablescript/src/parser.rs +++ b/ablescript/src/parser.rs @@ -37,12 +37,7 @@ impl<'source> Parser<'source> { Token::Comment => continue, // T-Dark block (replace `lang` with `script`) - Token::TDark => { - self.tdark = true; - let mut block = self.get_block()?; - ast.append(&mut block.block); - self.tdark = false; - } + Token::TDark => ast.extend(self.tdark_flow()?.block), token => ast.push(self.parse(token)?), } } @@ -329,12 +324,21 @@ impl<'source> Parser<'source> { loop { match self.checked_next()? { Token::RightCurly => break, + Token::TDark => block.extend(self.tdark_flow()?.block), t => block.push(self.parse(t)?), } } Ok(Block { block }) } + /// Parse T-Dark block + fn tdark_flow(&mut self) -> Result { + self.tdark = true; + let block = self.get_block(); + self.tdark = false; + block + } + /// If Statement parser gets any kind of value (Identifier or Literal) /// It cannot parse it as it do not parse expressions. Instead of it it /// will parse it to function call or print statement. From ec4a7e2447c1f58ce4c9d772cdbde20695080238 Mon Sep 17 00:00:00 2001 From: Alex Bethel Date: Tue, 14 Dec 2021 16:16:28 -0600 Subject: [PATCH 23/23] Implement function chain division --- ablescript/src/variables.rs | 65 +++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 90d00b6f..5d42a198 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -617,39 +617,48 @@ impl ops::Div for Value { })), Value::Bool(b) => Value::Bool(!b || rhs.into_bool()), Value::Abool(_) => !self + rhs, - Value::Functio(f) => { - let fraction = 1.0 / rhs.into_i32() as f64; - Value::Functio(match f { + Value::Functio(f) => Value::Functio(match f { + Functio::Bf { + instructions, + tape_len, + } => { + let fraction = 1.0 / rhs.into_i32() as f64; + let len = instructions.len(); Functio::Bf { - instructions, + instructions: instructions + .into_iter() + .take((len as f64 * fraction) as usize) + .collect(), tape_len, - } => { - let len = instructions.len(); - Functio::Bf { - instructions: instructions - .into_iter() - .take((len as f64 * fraction) as usize) - .collect(), - tape_len, - } } - Functio::Able { params, body } => { - let len = body.len(); - Functio::Able { - params, - body: body - .into_iter() - .take((len as f64 * fraction) as usize) - .collect(), - } + } + Functio::Able { params, body } => { + let fraction = 1.0 / rhs.into_i32() as f64; + let len = body.len(); + Functio::Able { + params, + body: body + .into_iter() + .take((len as f64 * fraction) as usize) + .collect(), } - Functio::Chain { .. } => todo!(":P"), - Functio::Eval(s) => { - let len = s.len(); - Functio::Eval(s.chars().take((len as f64 * fraction) as usize).collect()) + } + Functio::Chain { functios, kind } => { + let functios = *functios; + Functio::Chain { + functios: Box::new(( + (Value::Functio(functios.0) / rhs.clone()).into_functio(), + (Value::Functio(functios.1) / rhs).into_functio(), + )), + kind, } - }) - } + } + Functio::Eval(s) => { + let fraction = 1.0 / rhs.into_i32() as f64; + let len = s.len(); + Functio::Eval(s.chars().take((len as f64 * fraction) as usize).collect()) + } + }), Value::Cart(c) => { let cart_len = c.len(); let chunk_len = rhs.into_i32() as usize;