Implemented built-in functios

- Missing coercions and operations
This commit is contained in:
Erin 2022-02-12 21:14:55 +01:00 committed by ondra05
parent 09617b2a89
commit 405f88e394
2 changed files with 55 additions and 0 deletions

View file

@ -407,6 +407,7 @@ impl ExecEnv {
self.stack.pop(); self.stack.pop();
res?; res?;
} }
Functio::Builtin(b) => b.call(args).map_err(|e| Error::new(e, span.clone()))?,
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (left_functio, right_functio) = *functios; let (left_functio, right_functio) = *functios;
match kind { match kind {

View file

@ -44,6 +44,7 @@ pub enum Functio {
params: Vec<String>, params: Vec<String>,
body: Vec<Stmt>, body: Vec<Stmt>,
}, },
Builtin(BuiltinFunctio),
Chain { Chain {
functios: Box<(Functio, Functio)>, functios: Box<(Functio, Functio)>,
kind: FunctioChainKind, kind: FunctioChainKind,
@ -59,12 +60,57 @@ impl Functio {
tape_len: _, tape_len: _,
} => 0, } => 0,
Functio::Able { params, body: _ } => params.len(), Functio::Able { params, body: _ } => params.len(),
Functio::Builtin(b) => b.arity,
Functio::Chain { functios, kind: _ } => functios.0.arity() + functios.1.arity(), Functio::Chain { functios, kind: _ } => functios.0.arity() + functios.1.arity(),
Functio::Eval(_) => 0, Functio::Eval(_) => 0,
} }
} }
} }
#[derive(Clone)]
pub struct BuiltinFunctio {
function: Rc<dyn Fn(&[Rc<RefCell<Value>>]) -> Result<(), crate::error::ErrorKind>>,
arity: usize,
}
impl BuiltinFunctio {
pub fn new<F>(f: F, arity: usize) -> Self
where
F: Fn(&[Rc<RefCell<Value>>]) -> Result<(), crate::error::ErrorKind> + 'static,
{
Self {
function: Rc::new(f),
arity,
}
}
pub fn call(&self, args: &[Rc<RefCell<Value>>]) -> 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<H: std::hash::Hasher>(&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)] #[derive(Debug, PartialEq, Copy, Clone, Hash)]
pub enum FunctioChainKind { pub enum FunctioChainKind {
Equal, Equal,
@ -134,6 +180,7 @@ impl Value {
.sum::<i32>() .sum::<i32>()
+ body.len() as i32 + body.len() as i32
} }
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (lf, rf) = *functios; let (lf, rf) = *functios;
Value::Functio(lf).into_i32() Value::Functio(lf).into_i32()
@ -222,6 +269,7 @@ impl Value {
Value::Int((params + body) % 3 - 1).into_abool() Value::Int((params + body) % 3 - 1).into_abool()
} }
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (lhs, rhs) = *functios; let (lhs, rhs) = *functios;
match kind { match kind {
@ -391,6 +439,7 @@ impl Value {
); );
cart cart
} }
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (lhs, rhs) = *functios; let (lhs, rhs) = *functios;
match kind { match kind {
@ -440,6 +489,7 @@ impl Value {
tape_len, tape_len,
} => (instructions.len() + tape_len) as _, } => (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::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (lhs, rhs) = *functios.clone(); let (lhs, rhs) = *functios.clone();
match kind { match kind {
@ -564,6 +614,7 @@ impl ops::Sub for Value {
) )
.into_functio(), .into_functio(),
}, },
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, .. } => { Functio::Chain { functios, .. } => {
let rhs = rhs.into_functio(); let rhs = rhs.into_functio();
let (a, b) = *functios; let (a, b) = *functios;
@ -692,6 +743,7 @@ impl ops::Div for Value {
.collect(), .collect(),
} }
} }
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let functios = *functios; let functios = *functios;
Functio::Chain { Functio::Chain {
@ -765,6 +817,7 @@ impl ops::Not for Value {
Functio::Able { params, body } Functio::Able { params, body }
} }
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (a, b) = *functios; let (a, b) = *functios;
Functio::Chain { Functio::Chain {
@ -858,6 +911,7 @@ impl Display for Value {
body, body,
) )
} }
Functio::Builtin(_) => todo!(),
Functio::Chain { functios, kind } => { Functio::Chain { functios, kind } => {
let (a, b) = *functios.clone(); let (a, b) = *functios.clone();
write!( write!(