From 405f88e3944ec838df5b90f7603b58ad9d41ef72 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 12 Feb 2022 21:14:55 +0100 Subject: [PATCH 1/7] Implemented built-in functios - Missing coercions and operations --- ablescript/src/interpret.rs | 1 + ablescript/src/variables.rs | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index bb79d335..af679d4b 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -407,6 +407,7 @@ impl ExecEnv { self.stack.pop(); res?; } + Functio::Builtin(b) => b.call(args).map_err(|e| Error::new(e, span.clone()))?, Functio::Chain { functios, kind } => { let (left_functio, right_functio) = *functios; match kind { diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 545f2d45..05157d46 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -44,6 +44,7 @@ pub enum Functio { params: Vec, body: Vec, }, + Builtin(BuiltinFunctio), Chain { functios: Box<(Functio, Functio)>, kind: FunctioChainKind, @@ -59,12 +60,57 @@ impl Functio { tape_len: _, } => 0, Functio::Able { params, body: _ } => params.len(), + Functio::Builtin(b) => b.arity, Functio::Chain { functios, kind: _ } => functios.0.arity() + functios.1.arity(), Functio::Eval(_) => 0, } } } +#[derive(Clone)] +pub struct BuiltinFunctio { + function: Rc>]) -> Result<(), crate::error::ErrorKind>>, + arity: usize, +} + +impl BuiltinFunctio { + pub fn new(f: F, arity: usize) -> Self + where + F: Fn(&[Rc>]) -> Result<(), crate::error::ErrorKind> + 'static, + { + Self { + function: Rc::new(f), + arity, + } + } + + pub fn call(&self, args: &[Rc>]) -> Result<(), crate::error::ErrorKind> { + (self.function)(args) + } +} + +impl std::fmt::Debug for BuiltinFunctio { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("BuiltinFunctio") + .field("function", &"built-in") + .field("arity", &self.arity) + .finish() + } +} + +impl PartialEq for BuiltinFunctio { + fn eq(&self, other: &Self) -> bool { + Rc::ptr_eq(&self.function, &other.function) && self.arity == other.arity + } +} + +impl Hash for BuiltinFunctio { + fn hash(&self, state: &mut H) { + (Rc::as_ptr(&self.function) as *const () as usize).hash(state); + self.arity.hash(state); + } +} + #[derive(Debug, PartialEq, Copy, Clone, Hash)] pub enum FunctioChainKind { Equal, @@ -134,6 +180,7 @@ impl Value { .sum::() + body.len() as i32 } + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let (lf, rf) = *functios; Value::Functio(lf).into_i32() @@ -222,6 +269,7 @@ impl Value { Value::Int((params + body) % 3 - 1).into_abool() } + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { @@ -391,6 +439,7 @@ impl Value { ); cart } + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { @@ -440,6 +489,7 @@ impl Value { tape_len, } => (instructions.len() + tape_len) as _, Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios.clone(); match kind { @@ -564,6 +614,7 @@ impl ops::Sub for Value { ) .into_functio(), }, + Functio::Builtin(_) => todo!(), Functio::Chain { functios, .. } => { let rhs = rhs.into_functio(); let (a, b) = *functios; @@ -692,6 +743,7 @@ impl ops::Div for Value { .collect(), } } + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let functios = *functios; Functio::Chain { @@ -765,6 +817,7 @@ impl ops::Not for Value { Functio::Able { params, body } } + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let (a, b) = *functios; Functio::Chain { @@ -858,6 +911,7 @@ impl Display for Value { body, ) } + Functio::Builtin(_) => todo!(), Functio::Chain { functios, kind } => { let (a, b) = *functios.clone(); write!( From 06ec25e717ee6113c1b0fa1207e16c1584831690 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 12 Feb 2022 22:10:30 +0100 Subject: [PATCH 2/7] Implemented coercions for built-in functios --- ablescript/src/variables.rs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index 05157d46..cebd1024 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -87,6 +87,10 @@ impl BuiltinFunctio { pub fn call(&self, args: &[Rc>]) -> Result<(), crate::error::ErrorKind> { (self.function)(args) } + + pub fn fn_addr(&self) -> usize { + Rc::as_ptr(&self.function) as *const () as _ + } } impl std::fmt::Debug for BuiltinFunctio { @@ -106,7 +110,7 @@ impl PartialEq for BuiltinFunctio { impl Hash for BuiltinFunctio { fn hash(&self, state: &mut H) { - (Rc::as_ptr(&self.function) as *const () as usize).hash(state); + self.fn_addr().hash(state); self.arity.hash(state); } } @@ -180,7 +184,7 @@ impl Value { .sum::() + body.len() as i32 } - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => b.fn_addr() as _, Functio::Chain { functios, kind } => { let (lf, rf) = *functios; Value::Functio(lf).into_i32() @@ -269,7 +273,7 @@ impl Value { Value::Int((params + body) % 3 - 1).into_abool() } - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => Value::Bool(b.fn_addr() % b.arity == 0).into_abool(), Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { @@ -439,7 +443,22 @@ impl Value { ); cart } - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => { + let mut cart = HashMap::new(); + cart.insert( + Value::Str("addr".to_owned()), + Rc::new(RefCell::new(Value::Cart( + Value::Int(b.fn_addr() as _).into_cart(), + ))), + ); + + cart.insert( + Value::Str("arity".to_owned()), + Rc::new(RefCell::new(Value::Int(b.arity as _))), + ); + + cart + } Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios; match kind { @@ -489,7 +508,9 @@ impl Value { tape_len, } => (instructions.len() + tape_len) as _, Functio::Able { params, body } => (params.len() + format!("{:?}", body).len()) as _, - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => { + (std::mem::size_of_val(b.function.as_ref()) + b.arity) as i32 + } Functio::Chain { functios, kind } => { let (lhs, rhs) = *functios.clone(); match kind { From a1f6d1ae5f1a994e3dfdca0a41b054fc2fab4147 Mon Sep 17 00:00:00 2001 From: Erin Date: Sat, 12 Feb 2022 22:52:14 +0100 Subject: [PATCH 3/7] Implemented Display for built-ins --- 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 cebd1024..e9dec5b3 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -932,7 +932,7 @@ impl Display for Value { body, ) } - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => write!(f, "builtin @ {}", b.fn_addr()), Functio::Chain { functios, kind } => { let (a, b) = *functios.clone(); write!( From d634692f12ea713c87572f643a1a41a1f88d9e2c Mon Sep 17 00:00:00 2001 From: Erin Date: Sun, 13 Feb 2022 00:07:23 +0100 Subject: [PATCH 4/7] Implemented not for built-in functios --- ablescript/src/variables.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index e9dec5b3..66c3ffcf 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -838,7 +838,13 @@ impl ops::Not for Value { Functio::Able { params, body } } - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => { + let arity = b.arity; + Functio::Builtin(BuiltinFunctio::new( + move |args| b.call(&args.iter().cloned().rev().collect::>()), + arity, + )) + } Functio::Chain { functios, kind } => { let (a, b) = *functios; Functio::Chain { From 3338ec94c25ad28926af4dda97a49061d4878403 Mon Sep 17 00:00:00 2001 From: Erin Date: Sun, 13 Feb 2022 00:25:56 +0100 Subject: [PATCH 5/7] implemented subtraction for built-in functios --- 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 66c3ffcf..dbe6c285 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -635,7 +635,27 @@ impl ops::Sub for Value { ) .into_functio(), }, - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => { + let arity = b.arity; + let resulting_arity = arity.saturating_sub(rhs.into_i32() as usize); + + Functio::Builtin(BuiltinFunctio::new( + move |args| { + b.call( + &args + .iter() + .cloned() + .take(resulting_arity) + .chain(std::iter::repeat_with(|| { + Rc::new(RefCell::new(Value::Nul)) + })) + .take(arity) + .collect::>(), + ) + }, + resulting_arity, + )) + } Functio::Chain { functios, .. } => { let rhs = rhs.into_functio(); let (a, b) = *functios; From a9a9cc71e11fd7e7c02371180dfe6d545f558bcc Mon Sep 17 00:00:00 2001 From: Erin Date: Sun, 13 Feb 2022 00:30:40 +0100 Subject: [PATCH 6/7] Implemented builtin functio division --- ablescript/src/variables.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ablescript/src/variables.rs b/ablescript/src/variables.rs index dbe6c285..60487dfe 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -784,7 +784,10 @@ impl ops::Div for Value { .collect(), } } - Functio::Builtin(_) => todo!(), + Functio::Builtin(b) => Functio::Builtin(BuiltinFunctio { + arity: b.arity + rhs.into_i32() as usize, + ..b + }), Functio::Chain { functios, kind } => { let functios = *functios; Functio::Chain { From 5b320259f62ade73b60ca093b3a22779cb7ef492 Mon Sep 17 00:00:00 2001 From: Erin Date: Sun, 13 Feb 2022 00:37:17 +0100 Subject: [PATCH 7/7] Changed Built-in functio -> integer coercion --- 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 60487dfe..805c54ef 100644 --- a/ablescript/src/variables.rs +++ b/ablescript/src/variables.rs @@ -184,7 +184,7 @@ impl Value { .sum::() + body.len() as i32 } - Functio::Builtin(b) => b.fn_addr() as _, + Functio::Builtin(b) => (b.fn_addr() + b.arity) as _, Functio::Chain { functios, kind } => { let (lf, rf) = *functios; Value::Functio(lf).into_i32()