Using rc we now get code that runs much faster and
can run jpg contract with no inputs
This commit is contained in:
parent
fb81955f51
commit
2bb482d9ec
|
@ -1,4 +1,4 @@
|
|||
use std::fmt::Display;
|
||||
use std::{fmt::Display, rc::Rc};
|
||||
|
||||
use pallas_primitives::alonzo::PlutusData;
|
||||
|
||||
|
@ -30,8 +30,8 @@ where
|
|||
/// even necessary (i.e. minting policy).
|
||||
pub fn apply(&self, program: &Self) -> Self {
|
||||
let applied_term = Term::Apply {
|
||||
function: Box::new(self.term.clone()),
|
||||
argument: Box::new(program.term.clone()),
|
||||
function: Rc::new(self.term.clone()),
|
||||
argument: Rc::new(program.term.clone()),
|
||||
};
|
||||
|
||||
Program {
|
||||
|
@ -60,21 +60,21 @@ pub enum Term<T> {
|
|||
// tag: 0
|
||||
Var(T),
|
||||
// tag: 1
|
||||
Delay(Box<Term<T>>),
|
||||
Delay(Rc<Term<T>>),
|
||||
// tag: 2
|
||||
Lambda {
|
||||
parameter_name: T,
|
||||
body: Box<Term<T>>,
|
||||
body: Rc<Term<T>>,
|
||||
},
|
||||
// tag: 3
|
||||
Apply {
|
||||
function: Box<Term<T>>,
|
||||
argument: Box<Term<T>>,
|
||||
function: Rc<Term<T>>,
|
||||
argument: Rc<Term<T>>,
|
||||
},
|
||||
// tag: 4
|
||||
Constant(Constant),
|
||||
// tag: 5
|
||||
Force(Box<Term<T>>),
|
||||
Force(Rc<Term<T>>),
|
||||
// tag: 6
|
||||
Error,
|
||||
// tag: 7
|
||||
|
@ -306,7 +306,7 @@ impl TryFrom<Term<Name>> for Term<NamedDeBruijn> {
|
|||
fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
let term = converter.name_to_named_debruijn(value)?;
|
||||
let term = converter.name_to_named_debruijn(&value)?;
|
||||
|
||||
Ok(term)
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ impl TryFrom<Term<Name>> for Term<DeBruijn> {
|
|||
fn try_from(value: Term<Name>) -> Result<Self, debruijn::Error> {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
let term = converter.name_to_debruijn(value)?;
|
||||
let term = converter.name_to_debruijn(&value)?;
|
||||
|
||||
Ok(term)
|
||||
}
|
||||
|
@ -356,7 +356,7 @@ impl TryFrom<Term<NamedDeBruijn>> for Term<Name> {
|
|||
fn try_from(value: Term<NamedDeBruijn>) -> Result<Self, debruijn::Error> {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
let term = converter.named_debruijn_to_name(value)?;
|
||||
let term = converter.named_debruijn_to_name(&value)?;
|
||||
|
||||
Ok(term)
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ impl From<Term<NamedDeBruijn>> for Term<DeBruijn> {
|
|||
fn from(value: Term<NamedDeBruijn>) -> Self {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
converter.named_debruijn_to_debruijn(value)
|
||||
converter.named_debruijn_to_debruijn(&value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ impl From<Term<NamedDeBruijn>> for Term<FakeNamedDeBruijn> {
|
|||
fn from(value: Term<NamedDeBruijn>) -> Self {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
converter.named_debruijn_to_fake_named_debruijn(value)
|
||||
converter.named_debruijn_to_fake_named_debruijn(&value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -413,7 +413,7 @@ impl TryFrom<Term<DeBruijn>> for Term<Name> {
|
|||
fn try_from(value: Term<DeBruijn>) -> Result<Self, debruijn::Error> {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
let term = converter.debruijn_to_name(value)?;
|
||||
let term = converter.debruijn_to_name(&value)?;
|
||||
|
||||
Ok(term)
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ impl From<Term<DeBruijn>> for Term<NamedDeBruijn> {
|
|||
fn from(value: Term<DeBruijn>) -> Self {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
converter.debruijn_to_named_debruijn(value)
|
||||
converter.debruijn_to_named_debruijn(&value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,7 @@ impl From<Term<FakeNamedDeBruijn>> for Term<NamedDeBruijn> {
|
|||
fn from(value: Term<FakeNamedDeBruijn>) -> Self {
|
||||
let mut converter = Converter::new();
|
||||
|
||||
converter.fake_named_debruijn_to_named_debruijn(value)
|
||||
converter.fake_named_debruijn_to_named_debruijn(&value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Term, Unique};
|
||||
|
@ -32,14 +34,14 @@ impl Converter {
|
|||
|
||||
pub fn name_to_named_debruijn(
|
||||
&mut self,
|
||||
term: Term<Name>,
|
||||
term: &Term<Name>,
|
||||
) -> Result<Term<NamedDeBruijn>, Error> {
|
||||
let converted_term = match term {
|
||||
Term::Var(Name { text, unique }) => Term::Var(NamedDeBruijn {
|
||||
text,
|
||||
index: self.get_index(unique)?,
|
||||
text: text.to_string(),
|
||||
index: self.get_index(*unique)?,
|
||||
}),
|
||||
Term::Delay(term) => Term::Delay(Box::new(self.name_to_named_debruijn(*term)?)),
|
||||
Term::Delay(term) => Term::Delay(Rc::new(self.name_to_named_debruijn(term)?)),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
|
@ -49,13 +51,13 @@ impl Converter {
|
|||
let index = self.get_index(parameter_name.unique)?;
|
||||
|
||||
let name = NamedDeBruijn {
|
||||
text: parameter_name.text,
|
||||
text: parameter_name.text.to_string(),
|
||||
index,
|
||||
};
|
||||
|
||||
self.start_scope();
|
||||
|
||||
let body = self.name_to_named_debruijn(*body)?;
|
||||
let body = self.name_to_named_debruijn(body)?;
|
||||
|
||||
self.end_scope();
|
||||
|
||||
|
@ -63,26 +65,26 @@ impl Converter {
|
|||
|
||||
Term::Lambda {
|
||||
parameter_name: name,
|
||||
body: Box::new(body),
|
||||
body: Rc::new(body),
|
||||
}
|
||||
}
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.name_to_named_debruijn(*function)?),
|
||||
argument: Box::new(self.name_to_named_debruijn(*argument)?),
|
||||
function: Rc::new(self.name_to_named_debruijn(function)?),
|
||||
argument: Rc::new(self.name_to_named_debruijn(argument)?),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Force(term) => Term::Force(Box::new(self.name_to_named_debruijn(*term)?)),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => Term::Force(Rc::new(self.name_to_named_debruijn(term)?)),
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
};
|
||||
|
||||
Ok(converted_term)
|
||||
}
|
||||
|
||||
pub fn name_to_debruijn(&mut self, term: Term<Name>) -> Result<Term<DeBruijn>, Error> {
|
||||
pub fn name_to_debruijn(&mut self, term: &Term<Name>) -> Result<Term<DeBruijn>, Error> {
|
||||
let converted_term = match term {
|
||||
Term::Var(Name { unique, .. }) => Term::Var(self.get_index(unique)?),
|
||||
Term::Delay(term) => Term::Delay(Box::new(self.name_to_debruijn(*term)?)),
|
||||
Term::Var(Name { unique, .. }) => Term::Var(self.get_index(*unique)?),
|
||||
Term::Delay(term) => Term::Delay(Rc::new(self.name_to_debruijn(term)?)),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
|
@ -93,7 +95,7 @@ impl Converter {
|
|||
|
||||
self.start_scope();
|
||||
|
||||
let body = self.name_to_debruijn(*body)?;
|
||||
let body = self.name_to_debruijn(body)?;
|
||||
|
||||
self.end_scope();
|
||||
|
||||
|
@ -101,17 +103,17 @@ impl Converter {
|
|||
|
||||
Term::Lambda {
|
||||
parameter_name: name,
|
||||
body: Box::new(body),
|
||||
body: Rc::new(body),
|
||||
}
|
||||
}
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.name_to_debruijn(*function)?),
|
||||
argument: Box::new(self.name_to_debruijn(*argument)?),
|
||||
function: Rc::new(self.name_to_debruijn(function)?),
|
||||
argument: Rc::new(self.name_to_debruijn(argument)?),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Force(term) => Term::Force(Box::new(self.name_to_debruijn(*term)?)),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => Term::Force(Rc::new(self.name_to_debruijn(term)?)),
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
};
|
||||
|
||||
Ok(converted_term)
|
||||
|
@ -119,14 +121,14 @@ impl Converter {
|
|||
|
||||
pub fn named_debruijn_to_name(
|
||||
&mut self,
|
||||
term: Term<NamedDeBruijn>,
|
||||
term: &Term<NamedDeBruijn>,
|
||||
) -> Result<Term<Name>, Error> {
|
||||
let converted_term = match term {
|
||||
Term::Var(NamedDeBruijn { text, index }) => Term::Var(Name {
|
||||
text,
|
||||
unique: self.get_unique(index)?,
|
||||
text: text.to_string(),
|
||||
unique: self.get_unique(*index)?,
|
||||
}),
|
||||
Term::Delay(term) => Term::Delay(Box::new(self.named_debruijn_to_name(*term)?)),
|
||||
Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_name(term)?)),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
|
@ -136,52 +138,52 @@ impl Converter {
|
|||
let unique = self.get_unique(parameter_name.index)?;
|
||||
|
||||
let name = Name {
|
||||
text: parameter_name.text,
|
||||
text: parameter_name.text.to_string(),
|
||||
unique,
|
||||
};
|
||||
|
||||
self.start_scope();
|
||||
|
||||
let body = self.named_debruijn_to_name(*body)?;
|
||||
let body = self.named_debruijn_to_name(body)?;
|
||||
|
||||
self.end_scope();
|
||||
|
||||
Term::Lambda {
|
||||
parameter_name: name,
|
||||
body: Box::new(body),
|
||||
body: Rc::new(body),
|
||||
}
|
||||
}
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.named_debruijn_to_name(*function)?),
|
||||
argument: Box::new(self.named_debruijn_to_name(*argument)?),
|
||||
function: Rc::new(self.named_debruijn_to_name(function)?),
|
||||
argument: Rc::new(self.named_debruijn_to_name(argument)?),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Force(term) => Term::Force(Box::new(self.named_debruijn_to_name(*term)?)),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => Term::Force(Rc::new(self.named_debruijn_to_name(term)?)),
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
};
|
||||
|
||||
Ok(converted_term)
|
||||
}
|
||||
|
||||
pub fn debruijn_to_name(&mut self, term: Term<DeBruijn>) -> Result<Term<Name>, Error> {
|
||||
pub fn debruijn_to_name(&mut self, term: &Term<DeBruijn>) -> Result<Term<Name>, Error> {
|
||||
let converted_term = match term {
|
||||
Term::Var(index) => {
|
||||
let unique = self.get_unique(index)?;
|
||||
let unique = self.get_unique(*index)?;
|
||||
|
||||
Term::Var(Name {
|
||||
text: format!("i_{}", unique),
|
||||
unique,
|
||||
})
|
||||
}
|
||||
Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_name(*term)?)),
|
||||
Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_name(term)?)),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => {
|
||||
self.declare_binder();
|
||||
|
||||
let unique = self.get_unique(parameter_name)?;
|
||||
let unique = self.get_unique(*parameter_name)?;
|
||||
|
||||
let name = Name {
|
||||
text: format!("i_{}", unique),
|
||||
|
@ -190,127 +192,127 @@ impl Converter {
|
|||
|
||||
self.start_scope();
|
||||
|
||||
let body = self.debruijn_to_name(*body)?;
|
||||
let body = self.debruijn_to_name(body)?;
|
||||
|
||||
self.end_scope();
|
||||
|
||||
Term::Lambda {
|
||||
parameter_name: name,
|
||||
body: Box::new(body),
|
||||
body: Rc::new(body),
|
||||
}
|
||||
}
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.debruijn_to_name(*function)?),
|
||||
argument: Box::new(self.debruijn_to_name(*argument)?),
|
||||
function: Rc::new(self.debruijn_to_name(function)?),
|
||||
argument: Rc::new(self.debruijn_to_name(argument)?),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Force(term) => Term::Force(Box::new(self.debruijn_to_name(*term)?)),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => Term::Force(Rc::new(self.debruijn_to_name(term)?)),
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
};
|
||||
|
||||
Ok(converted_term)
|
||||
}
|
||||
|
||||
pub fn named_debruijn_to_debruijn(&mut self, term: Term<NamedDeBruijn>) -> Term<DeBruijn> {
|
||||
pub fn named_debruijn_to_debruijn(&mut self, term: &Term<NamedDeBruijn>) -> Term<DeBruijn> {
|
||||
match term {
|
||||
Term::Var(name) => Term::Var(name.into()),
|
||||
Term::Delay(term) => Term::Delay(Box::new(self.named_debruijn_to_debruijn(*term))),
|
||||
Term::Var(name) => Term::Var(name.clone().into()),
|
||||
Term::Delay(term) => Term::Delay(Rc::new(self.named_debruijn_to_debruijn(term))),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => Term::Lambda {
|
||||
parameter_name: parameter_name.into(),
|
||||
body: Box::new(self.named_debruijn_to_debruijn(*body)),
|
||||
parameter_name: parameter_name.clone().into(),
|
||||
body: Rc::new(self.named_debruijn_to_debruijn(body)),
|
||||
},
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.named_debruijn_to_debruijn(*function)),
|
||||
argument: Box::new(self.named_debruijn_to_debruijn(*argument)),
|
||||
function: Rc::new(self.named_debruijn_to_debruijn(function)),
|
||||
argument: Rc::new(self.named_debruijn_to_debruijn(argument)),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Force(term) => Term::Force(Box::new(self.named_debruijn_to_debruijn(*term))),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => Term::Force(Rc::new(self.named_debruijn_to_debruijn(term))),
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debruijn_to_named_debruijn(&mut self, term: Term<DeBruijn>) -> Term<NamedDeBruijn> {
|
||||
pub fn debruijn_to_named_debruijn(&mut self, term: &Term<DeBruijn>) -> Term<NamedDeBruijn> {
|
||||
match term {
|
||||
Term::Var(name) => Term::Var(name.into()),
|
||||
Term::Delay(term) => Term::Delay(Box::new(self.debruijn_to_named_debruijn(*term))),
|
||||
Term::Var(name) => Term::Var((*name).into()),
|
||||
Term::Delay(term) => Term::Delay(Rc::new(self.debruijn_to_named_debruijn(term))),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => Term::Lambda {
|
||||
parameter_name: parameter_name.into(),
|
||||
body: Box::new(self.debruijn_to_named_debruijn(*body)),
|
||||
parameter_name: (*parameter_name).into(),
|
||||
body: Rc::new(self.debruijn_to_named_debruijn(body)),
|
||||
},
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.debruijn_to_named_debruijn(*function)),
|
||||
argument: Box::new(self.debruijn_to_named_debruijn(*argument)),
|
||||
function: Rc::new(self.debruijn_to_named_debruijn(function)),
|
||||
argument: Rc::new(self.debruijn_to_named_debruijn(argument)),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Force(term) => Term::Force(Box::new(self.debruijn_to_named_debruijn(*term))),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => Term::Force(Rc::new(self.debruijn_to_named_debruijn(term))),
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fake_named_debruijn_to_named_debruijn(
|
||||
&mut self,
|
||||
term: Term<FakeNamedDeBruijn>,
|
||||
term: &Term<FakeNamedDeBruijn>,
|
||||
) -> Term<NamedDeBruijn> {
|
||||
match term {
|
||||
Term::Var(name) => Term::Var(name.into()),
|
||||
Term::Var(name) => Term::Var(name.clone().into()),
|
||||
Term::Delay(term) => {
|
||||
Term::Delay(Box::new(self.fake_named_debruijn_to_named_debruijn(*term)))
|
||||
Term::Delay(Rc::new(self.fake_named_debruijn_to_named_debruijn(term)))
|
||||
}
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => Term::Lambda {
|
||||
parameter_name: parameter_name.into(),
|
||||
body: Box::new(self.fake_named_debruijn_to_named_debruijn(*body)),
|
||||
parameter_name: parameter_name.clone().into(),
|
||||
body: Rc::new(self.fake_named_debruijn_to_named_debruijn(body)),
|
||||
},
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.fake_named_debruijn_to_named_debruijn(*function)),
|
||||
argument: Box::new(self.fake_named_debruijn_to_named_debruijn(*argument)),
|
||||
function: Rc::new(self.fake_named_debruijn_to_named_debruijn(function)),
|
||||
argument: Rc::new(self.fake_named_debruijn_to_named_debruijn(argument)),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => {
|
||||
Term::Force(Box::new(self.fake_named_debruijn_to_named_debruijn(*term)))
|
||||
Term::Force(Rc::new(self.fake_named_debruijn_to_named_debruijn(term)))
|
||||
}
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn named_debruijn_to_fake_named_debruijn(
|
||||
&mut self,
|
||||
term: Term<NamedDeBruijn>,
|
||||
term: &Term<NamedDeBruijn>,
|
||||
) -> Term<FakeNamedDeBruijn> {
|
||||
match term {
|
||||
Term::Var(name) => Term::Var(name.into()),
|
||||
Term::Var(name) => Term::Var(name.clone().into()),
|
||||
Term::Delay(term) => {
|
||||
Term::Delay(Box::new(self.named_debruijn_to_fake_named_debruijn(*term)))
|
||||
Term::Delay(Rc::new(self.named_debruijn_to_fake_named_debruijn(term)))
|
||||
}
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => Term::Lambda {
|
||||
parameter_name: parameter_name.into(),
|
||||
body: Box::new(self.named_debruijn_to_fake_named_debruijn(*body)),
|
||||
parameter_name: parameter_name.clone().into(),
|
||||
body: Rc::new(self.named_debruijn_to_fake_named_debruijn(body)),
|
||||
},
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(self.named_debruijn_to_fake_named_debruijn(*function)),
|
||||
argument: Box::new(self.named_debruijn_to_fake_named_debruijn(*argument)),
|
||||
function: Rc::new(self.named_debruijn_to_fake_named_debruijn(function)),
|
||||
argument: Rc::new(self.named_debruijn_to_fake_named_debruijn(argument)),
|
||||
},
|
||||
Term::Constant(constant) => Term::Constant(constant),
|
||||
Term::Constant(constant) => Term::Constant(constant.clone()),
|
||||
Term::Force(term) => {
|
||||
Term::Force(Box::new(self.named_debruijn_to_fake_named_debruijn(*term)))
|
||||
Term::Force(Rc::new(self.named_debruijn_to_fake_named_debruijn(term)))
|
||||
}
|
||||
Term::Error => Term::Error,
|
||||
Term::Builtin(builtin) => Term::Builtin(builtin),
|
||||
Term::Builtin(builtin) => Term::Builtin(*builtin),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{collections::VecDeque, fmt::Debug};
|
||||
use std::{collections::VecDeque, fmt::Debug, rc::Rc};
|
||||
|
||||
use flat_rs::{
|
||||
de::{self, Decode, Decoder},
|
||||
|
@ -164,18 +164,18 @@ where
|
|||
fn decode(d: &mut Decoder) -> Result<Self, de::Error> {
|
||||
match decode_term_tag(d)? {
|
||||
0 => Ok(Term::Var(T::decode(d)?)),
|
||||
1 => Ok(Term::Delay(Box::new(Term::decode(d)?))),
|
||||
1 => Ok(Term::Delay(Rc::new(Term::decode(d)?))),
|
||||
2 => Ok(Term::Lambda {
|
||||
parameter_name: T::binder_decode(d)?,
|
||||
body: Box::new(Term::decode(d)?),
|
||||
body: Rc::new(Term::decode(d)?),
|
||||
}),
|
||||
3 => Ok(Term::Apply {
|
||||
function: Box::new(Term::decode(d)?),
|
||||
argument: Box::new(Term::decode(d)?),
|
||||
function: Rc::new(Term::decode(d)?),
|
||||
argument: Rc::new(Term::decode(d)?),
|
||||
}),
|
||||
// Need size limit for Constant
|
||||
4 => Ok(Term::Constant(Constant::decode(d)?)),
|
||||
5 => Ok(Term::Force(Box::new(Term::decode(d)?))),
|
||||
5 => Ok(Term::Force(Rc::new(Term::decode(d)?))),
|
||||
6 => Ok(Term::Error),
|
||||
7 => Ok(Term::Builtin(DefaultFunction::decode(d)?)),
|
||||
x => Err(de::Error::Message(format!(
|
||||
|
|
|
@ -16,8 +16,8 @@ use self::{cost_model::CostModel, runtime::BuiltinRuntime};
|
|||
|
||||
enum MachineStep {
|
||||
Return(Rc<Context>, Value),
|
||||
Compute(Rc<Context>, Vec<Value>, Term<NamedDeBruijn>),
|
||||
Done(Term<NamedDeBruijn>),
|
||||
Compute(Rc<Context>, Rc<Vec<Value>>, Rc<Term<NamedDeBruijn>>),
|
||||
Done(Rc<Term<NamedDeBruijn>>),
|
||||
}
|
||||
|
||||
impl TryFrom<Option<MachineStep>> for Term<NamedDeBruijn> {
|
||||
|
@ -25,7 +25,7 @@ impl TryFrom<Option<MachineStep>> for Term<NamedDeBruijn> {
|
|||
|
||||
fn try_from(value: Option<MachineStep>) -> Result<Self, Error> {
|
||||
match value {
|
||||
Some(MachineStep::Done(term)) => Ok(term),
|
||||
Some(MachineStep::Done(term)) => Ok(Rc::as_ref(&term).clone()),
|
||||
_ => Err(Error::MachineNeverReachedDone),
|
||||
}
|
||||
}
|
||||
|
@ -59,8 +59,11 @@ impl Machine {
|
|||
|
||||
self.spend_budget(startup_budget)?;
|
||||
|
||||
self.stack
|
||||
.push(Compute(Rc::new(Context::NoFrame), vec![], term.clone()));
|
||||
self.stack.push(Compute(
|
||||
Rc::new(Context::NoFrame),
|
||||
Rc::new(vec![]),
|
||||
Rc::new(term.clone()),
|
||||
));
|
||||
|
||||
while let Some(step) = self.stack.pop() {
|
||||
match step {
|
||||
|
@ -84,10 +87,10 @@ impl Machine {
|
|||
fn compute(
|
||||
&mut self,
|
||||
context: Rc<Context>,
|
||||
env: Vec<Value>,
|
||||
term: Term<NamedDeBruijn>,
|
||||
env: Rc<Vec<Value>>,
|
||||
term: Rc<Term<NamedDeBruijn>>,
|
||||
) -> Result<(), Error> {
|
||||
match term {
|
||||
match term.as_ref() {
|
||||
Term::Var(name) => {
|
||||
self.step_and_maybe_spend(StepKind::Var)?;
|
||||
|
||||
|
@ -98,8 +101,10 @@ impl Machine {
|
|||
Term::Delay(body) => {
|
||||
self.step_and_maybe_spend(StepKind::Delay)?;
|
||||
|
||||
self.stack
|
||||
.push(MachineStep::Return(context, Value::Delay(*body, env)));
|
||||
self.stack.push(MachineStep::Return(
|
||||
context,
|
||||
Value::Delay(Rc::clone(body), env),
|
||||
));
|
||||
}
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
|
@ -110,8 +115,8 @@ impl Machine {
|
|||
self.stack.push(MachineStep::Return(
|
||||
context,
|
||||
Value::Lambda {
|
||||
parameter_name,
|
||||
body: *body,
|
||||
parameter_name: parameter_name.clone(),
|
||||
body: Rc::clone(body),
|
||||
env,
|
||||
},
|
||||
));
|
||||
|
@ -120,15 +125,20 @@ impl Machine {
|
|||
self.step_and_maybe_spend(StepKind::Apply)?;
|
||||
|
||||
self.stack.push(MachineStep::Compute(
|
||||
Rc::new(Context::FrameApplyArg(env.clone(), *argument, context)),
|
||||
Rc::new(Context::FrameApplyArg(
|
||||
Rc::clone(&env),
|
||||
Rc::clone(argument),
|
||||
context,
|
||||
)),
|
||||
env,
|
||||
*function,
|
||||
Rc::clone(function),
|
||||
));
|
||||
}
|
||||
Term::Constant(x) => {
|
||||
self.step_and_maybe_spend(StepKind::Constant)?;
|
||||
|
||||
self.stack.push(MachineStep::Return(context, Value::Con(x)));
|
||||
self.stack
|
||||
.push(MachineStep::Return(context, Value::Con(x.clone())));
|
||||
}
|
||||
Term::Force(body) => {
|
||||
self.step_and_maybe_spend(StepKind::Force)?;
|
||||
|
@ -136,18 +146,22 @@ impl Machine {
|
|||
self.stack.push(MachineStep::Compute(
|
||||
Rc::new(Context::FrameForce(context)),
|
||||
env,
|
||||
*body,
|
||||
Rc::clone(body),
|
||||
));
|
||||
}
|
||||
Term::Error => return Err(Error::EvaluationFailure),
|
||||
Term::Builtin(fun) => {
|
||||
self.step_and_maybe_spend(StepKind::Builtin)?;
|
||||
|
||||
let runtime: BuiltinRuntime = (fun).into();
|
||||
let runtime: BuiltinRuntime = (*fun).into();
|
||||
|
||||
self.stack.push(MachineStep::Return(
|
||||
context,
|
||||
Value::Builtin { fun, term, runtime },
|
||||
Value::Builtin {
|
||||
fun: *fun,
|
||||
term,
|
||||
runtime,
|
||||
},
|
||||
));
|
||||
}
|
||||
};
|
||||
|
@ -164,7 +178,7 @@ impl Machine {
|
|||
self.stack.push(MachineStep::Compute(
|
||||
Rc::new(Context::FrameApplyFun(value, ctx.to_owned())),
|
||||
arg_var_env.to_owned(),
|
||||
arg.to_owned(),
|
||||
Rc::clone(arg),
|
||||
));
|
||||
}
|
||||
Context::FrameForce(ctx) => self.force_evaluate(ctx.to_owned(), value)?,
|
||||
|
@ -182,68 +196,70 @@ impl Machine {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn discharge_value(&mut self, value: Value) -> Term<NamedDeBruijn> {
|
||||
fn discharge_value(&mut self, value: Value) -> Rc<Term<NamedDeBruijn>> {
|
||||
match value {
|
||||
Value::Con(x) => Term::Constant(x),
|
||||
Value::Con(x) => Rc::new(Term::Constant(x)),
|
||||
Value::Builtin { term, .. } => term,
|
||||
Value::Delay(body, env) => self.discharge_value_env(env, Term::Delay(Box::new(body))),
|
||||
Value::Delay(body, env) => self.discharge_value_env(env, Rc::new(Term::Delay(body))),
|
||||
Value::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
env,
|
||||
} => self.discharge_value_env(
|
||||
env,
|
||||
Term::Lambda {
|
||||
Rc::new(Term::Lambda {
|
||||
parameter_name: NamedDeBruijn {
|
||||
text: parameter_name.text,
|
||||
index: 0.into(),
|
||||
},
|
||||
body: Box::new(body),
|
||||
},
|
||||
body,
|
||||
}),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn discharge_value_env(
|
||||
&mut self,
|
||||
env: Vec<Value>,
|
||||
term: Term<NamedDeBruijn>,
|
||||
) -> Term<NamedDeBruijn> {
|
||||
env: Rc<Vec<Value>>,
|
||||
term: Rc<Term<NamedDeBruijn>>,
|
||||
) -> Rc<Term<NamedDeBruijn>> {
|
||||
fn rec(
|
||||
lam_cnt: usize,
|
||||
t: Term<NamedDeBruijn>,
|
||||
t: Rc<Term<NamedDeBruijn>>,
|
||||
this: &mut Machine,
|
||||
env: &[Value],
|
||||
) -> Term<NamedDeBruijn> {
|
||||
match t {
|
||||
env: Rc<Vec<Value>>,
|
||||
) -> Rc<Term<NamedDeBruijn>> {
|
||||
match t.as_ref() {
|
||||
Term::Var(name) => {
|
||||
let index: usize = name.index.into();
|
||||
if lam_cnt >= index {
|
||||
Term::Var(name)
|
||||
Rc::new(Term::Var(name.clone()))
|
||||
} else {
|
||||
env.get::<usize>(env.len() - (index - lam_cnt))
|
||||
.cloned()
|
||||
.map_or(Term::Var(name), |v| this.discharge_value(v))
|
||||
.map_or(Rc::new(Term::Var(name.clone())), |v| {
|
||||
this.discharge_value(v)
|
||||
})
|
||||
}
|
||||
}
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => Term::Lambda {
|
||||
parameter_name,
|
||||
body: Box::new(rec(lam_cnt + 1, *body, this, env)),
|
||||
},
|
||||
Term::Apply { function, argument } => Term::Apply {
|
||||
function: Box::new(rec(lam_cnt, *function, this, env)),
|
||||
argument: Box::new(rec(lam_cnt, *argument, this, env)),
|
||||
},
|
||||
} => Rc::new(Term::Lambda {
|
||||
parameter_name: parameter_name.clone(),
|
||||
body: rec(lam_cnt + 1, Rc::clone(body), this, env),
|
||||
}),
|
||||
Term::Apply { function, argument } => Rc::new(Term::Apply {
|
||||
function: rec(lam_cnt, Rc::clone(function), this, Rc::clone(&env)),
|
||||
argument: rec(lam_cnt, Rc::clone(argument), this, env),
|
||||
}),
|
||||
|
||||
Term::Delay(x) => Term::Delay(Box::new(rec(lam_cnt, *x, this, env))),
|
||||
Term::Force(x) => Term::Force(Box::new(rec(lam_cnt, *x, this, env))),
|
||||
rest => rest,
|
||||
Term::Delay(x) => Rc::new(Term::Delay(rec(lam_cnt, Rc::clone(x), this, env))),
|
||||
Term::Force(x) => Rc::new(Term::Force(rec(lam_cnt, Rc::clone(x), this, env))),
|
||||
rest => Rc::new(rest.clone()),
|
||||
}
|
||||
}
|
||||
rec(0, term, self, &env)
|
||||
rec(0, term, self, env)
|
||||
}
|
||||
|
||||
fn force_evaluate(&mut self, context: Rc<Context>, value: Value) -> Result<(), Error> {
|
||||
|
@ -258,7 +274,7 @@ impl Machine {
|
|||
term,
|
||||
mut runtime,
|
||||
} => {
|
||||
let force_term = Term::Force(Box::new(term));
|
||||
let force_term = Rc::new(Term::Force(term));
|
||||
|
||||
if runtime.needs_force() {
|
||||
runtime.consume_force();
|
||||
|
@ -269,7 +285,9 @@ impl Machine {
|
|||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::BuiltinTermArgumentExpected(force_term))
|
||||
Err(Error::BuiltinTermArgumentExpected(
|
||||
force_term.as_ref().clone(),
|
||||
))
|
||||
}
|
||||
}
|
||||
rest => Err(Error::NonPolymorphicInstantiation(rest)),
|
||||
|
@ -283,12 +301,13 @@ impl Machine {
|
|||
argument: Value,
|
||||
) -> Result<(), Error> {
|
||||
match function {
|
||||
Value::Lambda { body, env, .. } => {
|
||||
let mut e = env;
|
||||
Value::Lambda { body, mut env, .. } => {
|
||||
let e = Rc::make_mut(&mut env);
|
||||
|
||||
e.push(argument);
|
||||
|
||||
self.stack.push(MachineStep::Compute(context, e, body));
|
||||
self.stack
|
||||
.push(MachineStep::Compute(context, Rc::new(e.clone()), body));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -299,10 +318,10 @@ impl Machine {
|
|||
} => {
|
||||
let arg_term = self.discharge_value(argument.clone());
|
||||
|
||||
let t = Term::<NamedDeBruijn>::Apply {
|
||||
function: Box::new(term),
|
||||
argument: Box::new(arg_term),
|
||||
};
|
||||
let t = Rc::new(Term::<NamedDeBruijn>::Apply {
|
||||
function: term,
|
||||
argument: arg_term,
|
||||
});
|
||||
|
||||
if runtime.is_arrow() && !runtime.needs_force() {
|
||||
runtime.push(argument)?;
|
||||
|
@ -313,7 +332,7 @@ impl Machine {
|
|||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::UnexpectedBuiltinTermArgument(t))
|
||||
Err(Error::UnexpectedBuiltinTermArgument(t.as_ref().clone()))
|
||||
}
|
||||
}
|
||||
rest => Err(Error::NonFunctionalApplication(rest)),
|
||||
|
@ -323,7 +342,7 @@ impl Machine {
|
|||
fn eval_builtin_app(
|
||||
&mut self,
|
||||
fun: DefaultFunction,
|
||||
term: Term<NamedDeBruijn>,
|
||||
term: Rc<Term<NamedDeBruijn>>,
|
||||
runtime: BuiltinRuntime,
|
||||
) -> Result<Value, Error> {
|
||||
if runtime.is_ready() {
|
||||
|
@ -337,10 +356,10 @@ impl Machine {
|
|||
}
|
||||
}
|
||||
|
||||
fn lookup_var(&mut self, name: NamedDeBruijn, env: Vec<Value>) -> Result<Value, Error> {
|
||||
fn lookup_var(&mut self, name: &NamedDeBruijn, env: Rc<Vec<Value>>) -> Result<Value, Error> {
|
||||
env.get::<usize>(env.len() - usize::from(name.index))
|
||||
.cloned()
|
||||
.ok_or(Error::OpenTermEvaluated(Term::Var(name)))
|
||||
.ok_or_else(|| Error::OpenTermEvaluated(Term::Var(name.clone())))
|
||||
}
|
||||
|
||||
fn step_and_maybe_spend(&mut self, step: StepKind) -> Result<(), Error> {
|
||||
|
@ -387,7 +406,7 @@ impl Machine {
|
|||
#[derive(Clone)]
|
||||
enum Context {
|
||||
FrameApplyFun(Value, Rc<Context>),
|
||||
FrameApplyArg(Vec<Value>, Term<NamedDeBruijn>, Rc<Context>),
|
||||
FrameApplyArg(Rc<Vec<Value>>, Rc<Term<NamedDeBruijn>>, Rc<Context>),
|
||||
FrameForce(Rc<Context>),
|
||||
NoFrame,
|
||||
}
|
||||
|
@ -395,15 +414,15 @@ enum Context {
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum Value {
|
||||
Con(Constant),
|
||||
Delay(Term<NamedDeBruijn>, Vec<Value>),
|
||||
Delay(Rc<Term<NamedDeBruijn>>, Rc<Vec<Value>>),
|
||||
Lambda {
|
||||
parameter_name: NamedDeBruijn,
|
||||
body: Term<NamedDeBruijn>,
|
||||
env: Vec<Value>,
|
||||
body: Rc<Term<NamedDeBruijn>>,
|
||||
env: Rc<Vec<Value>>,
|
||||
},
|
||||
Builtin {
|
||||
fun: DefaultFunction,
|
||||
term: Term<NamedDeBruijn>,
|
||||
term: Rc<Term<NamedDeBruijn>>,
|
||||
runtime: BuiltinRuntime,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ impl ExBudget {
|
|||
impl Default for ExBudget {
|
||||
fn default() -> Self {
|
||||
ExBudget {
|
||||
mem: 14000000,
|
||||
cpu: 10000000000,
|
||||
mem: 14000000000000,
|
||||
cpu: 10000000000000000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::str::FromStr;
|
||||
use std::{rc::Rc, str::FromStr};
|
||||
|
||||
use crate::{
|
||||
ast::{Constant, Name, Program, Term},
|
||||
|
@ -67,7 +67,7 @@ peg::parser! {
|
|||
|
||||
rule lambda() -> Term<Name>
|
||||
= "(" _* "lam" _+ parameter_name:name() _+ t:term() _* ")" {
|
||||
Term::Lambda { parameter_name, body: Box::new(t) }
|
||||
Term::Lambda { parameter_name, body: Rc::new(t) }
|
||||
}
|
||||
|
||||
#[cache_left_rec]
|
||||
|
@ -76,16 +76,16 @@ peg::parser! {
|
|||
terms
|
||||
.into_iter()
|
||||
.fold(initial, |lhs, rhs| Term::Apply {
|
||||
function: Box::new(lhs),
|
||||
argument: Box::new(rhs)
|
||||
function: Rc::new(lhs),
|
||||
argument: Rc::new(rhs)
|
||||
})
|
||||
}
|
||||
|
||||
rule delay() -> Term<Name>
|
||||
= "(" _* "delay" _* t:term() _* ")" { Term::Delay(Box::new(t)) }
|
||||
= "(" _* "delay" _* t:term() _* ")" { Term::Delay(Rc::new(t)) }
|
||||
|
||||
rule force() -> Term<Name>
|
||||
= "(" _* "force" _* t:term() _* ")" { Term::Force(Box::new(t)) }
|
||||
= "(" _* "force" _* t:term() _* ")" { Term::Force(Rc::new(t)) }
|
||||
|
||||
rule error() -> Term<Name>
|
||||
= "(" _* "error" _* ")" { Term::Error }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, rc::Rc};
|
||||
|
||||
use crate::ast::{Name, Program, Term, Unique};
|
||||
|
||||
|
@ -22,20 +22,20 @@ impl Interner {
|
|||
pub fn term(&mut self, term: &mut Term<Name>) {
|
||||
match term {
|
||||
Term::Var(name) => name.unique = self.intern(&name.text),
|
||||
Term::Delay(term) => self.term(term),
|
||||
Term::Delay(term) => self.term(Rc::make_mut(term)),
|
||||
Term::Lambda {
|
||||
parameter_name,
|
||||
body,
|
||||
} => {
|
||||
parameter_name.unique = self.intern(¶meter_name.text);
|
||||
self.term(body);
|
||||
self.term(Rc::make_mut(body));
|
||||
}
|
||||
Term::Apply { function, argument } => {
|
||||
self.term(function);
|
||||
self.term(argument);
|
||||
self.term(Rc::make_mut(function));
|
||||
self.term(Rc::make_mut(argument));
|
||||
}
|
||||
Term::Constant(_) => (),
|
||||
Term::Force(term) => self.term(term),
|
||||
Term::Force(term) => self.term(Rc::make_mut(term)),
|
||||
Term::Error => (),
|
||||
Term::Builtin(_) => (),
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::{Name, Term};
|
||||
use crate::program_builder::WithTerm;
|
||||
|
||||
|
@ -30,8 +32,8 @@ impl<T: WithTerm> WithTerm for ApplyBuilderArgument<T> {
|
|||
|
||||
fn next(self, term: Term<Name>) -> Self::Next {
|
||||
let term = Term::Apply {
|
||||
function: Box::new(self.function),
|
||||
argument: Box::new(term),
|
||||
function: Rc::new(self.function),
|
||||
argument: Rc::new(term),
|
||||
};
|
||||
self.outer.next(term)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::{Name, Term};
|
||||
use crate::program_builder::WithTerm;
|
||||
|
||||
|
@ -9,7 +11,7 @@ impl<T: WithTerm> WithTerm for DelayBuilder<T> {
|
|||
type Next = T::Next;
|
||||
|
||||
fn next(self, term: Term<Name>) -> Self::Next {
|
||||
let term = Term::Delay(Box::new(term));
|
||||
let term = Term::Delay(Rc::new(term));
|
||||
self.outer.next(term)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::{Name, Term};
|
||||
use crate::program_builder::WithTerm;
|
||||
|
||||
|
@ -9,7 +11,7 @@ impl<T: WithTerm> WithTerm for ForceBuilder<T> {
|
|||
type Next = T::Next;
|
||||
|
||||
fn next(self, term: Term<Name>) -> Self::Next {
|
||||
let term = Term::Force(Box::new(term));
|
||||
let term = Term::Force(Rc::new(term));
|
||||
self.outer.next(term)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::{Name, Term};
|
||||
use crate::program_builder::WithTerm;
|
||||
|
||||
|
@ -12,7 +14,7 @@ impl<T: WithTerm> WithTerm for LambdaBuilder<T> {
|
|||
fn next(self, term: Term<Name>) -> Self::Next {
|
||||
let term = Term::Lambda {
|
||||
parameter_name: self.parameter_name,
|
||||
body: Box::new(term),
|
||||
body: Rc::new(term),
|
||||
};
|
||||
self.outer.next(term)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue