352 lines
15 KiB
Rust
352 lines
15 KiB
Rust
use crate::{ast::Constant, builtins::DefaultFunction};
|
|
|
|
use super::{
|
|
cost_model::{BuiltinCosts, ExBudget},
|
|
error::Type,
|
|
Error, Value,
|
|
};
|
|
|
|
//#[derive(std::cmp::PartialEq)]
|
|
//pub enum EvalMode {
|
|
// Immediate,
|
|
// Deferred,
|
|
//}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct BuiltinRuntime {
|
|
args: Vec<Value>,
|
|
fun: DefaultFunction,
|
|
forces: u32,
|
|
}
|
|
|
|
impl BuiltinRuntime {
|
|
pub fn new(fun: DefaultFunction) -> BuiltinRuntime {
|
|
Self {
|
|
args: vec![],
|
|
fun,
|
|
forces: 0,
|
|
}
|
|
}
|
|
|
|
pub fn is_arrow(&self) -> bool {
|
|
self.args.len() != self.fun.arity()
|
|
}
|
|
|
|
pub fn is_ready(&self) -> bool {
|
|
self.args.len() == self.fun.arity()
|
|
}
|
|
|
|
pub fn needs_force(&self) -> bool {
|
|
self.forces < self.fun.force_count()
|
|
}
|
|
|
|
pub fn consume_force(&mut self) {
|
|
self.forces += 1;
|
|
}
|
|
|
|
pub fn call(&self) -> Result<Value, Error> {
|
|
self.fun.call(&self.args)
|
|
}
|
|
|
|
pub fn push(&mut self, arg: Value) -> Result<(), Error> {
|
|
self.fun.check_type(&arg, &self.args)?;
|
|
|
|
self.args.push(arg);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn to_ex_budget(&self, costs: &BuiltinCosts) -> ExBudget {
|
|
costs.to_ex_budget(self.fun, &self.args)
|
|
}
|
|
}
|
|
|
|
impl From<DefaultFunction> for BuiltinRuntime {
|
|
fn from(fun: DefaultFunction) -> Self {
|
|
BuiltinRuntime::new(fun)
|
|
}
|
|
}
|
|
|
|
impl DefaultFunction {
|
|
pub fn arity(&self) -> usize {
|
|
match self {
|
|
DefaultFunction::AddInteger => 2,
|
|
DefaultFunction::SubtractInteger => 2,
|
|
DefaultFunction::MultiplyInteger => todo!(),
|
|
DefaultFunction::DivideInteger => todo!(),
|
|
DefaultFunction::QuotientInteger => todo!(),
|
|
DefaultFunction::RemainderInteger => todo!(),
|
|
DefaultFunction::ModInteger => todo!(),
|
|
DefaultFunction::EqualsInteger => todo!(),
|
|
DefaultFunction::LessThanInteger => todo!(),
|
|
DefaultFunction::LessThanEqualsInteger => 2,
|
|
DefaultFunction::AppendByteString => todo!(),
|
|
DefaultFunction::ConsByteString => todo!(),
|
|
DefaultFunction::SliceByteString => todo!(),
|
|
DefaultFunction::LengthOfByteString => todo!(),
|
|
DefaultFunction::IndexByteString => todo!(),
|
|
DefaultFunction::EqualsByteString => todo!(),
|
|
DefaultFunction::LessThanByteString => todo!(),
|
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
|
DefaultFunction::Sha2_256 => todo!(),
|
|
DefaultFunction::Sha3_256 => todo!(),
|
|
DefaultFunction::Blake2b_256 => todo!(),
|
|
DefaultFunction::VerifySignature => todo!(),
|
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
|
DefaultFunction::AppendString => todo!(),
|
|
DefaultFunction::EqualsString => todo!(),
|
|
DefaultFunction::EncodeUtf8 => todo!(),
|
|
DefaultFunction::DecodeUtf8 => todo!(),
|
|
DefaultFunction::IfThenElse => 3,
|
|
DefaultFunction::ChooseUnit => todo!(),
|
|
DefaultFunction::Trace => todo!(),
|
|
DefaultFunction::FstPair => todo!(),
|
|
DefaultFunction::SndPair => todo!(),
|
|
DefaultFunction::ChooseList => todo!(),
|
|
DefaultFunction::MkCons => todo!(),
|
|
DefaultFunction::HeadList => todo!(),
|
|
DefaultFunction::TailList => todo!(),
|
|
DefaultFunction::NullList => todo!(),
|
|
DefaultFunction::ChooseData => todo!(),
|
|
DefaultFunction::ConstrData => todo!(),
|
|
DefaultFunction::MapData => todo!(),
|
|
DefaultFunction::ListData => todo!(),
|
|
DefaultFunction::IData => todo!(),
|
|
DefaultFunction::BData => todo!(),
|
|
DefaultFunction::UnConstrData => todo!(),
|
|
DefaultFunction::UnMapData => todo!(),
|
|
DefaultFunction::UnListData => todo!(),
|
|
DefaultFunction::UnIData => todo!(),
|
|
DefaultFunction::UnBData => todo!(),
|
|
DefaultFunction::EqualsData => todo!(),
|
|
DefaultFunction::SerialiseData => todo!(),
|
|
DefaultFunction::MkPairData => todo!(),
|
|
DefaultFunction::MkNilData => todo!(),
|
|
DefaultFunction::MkNilPairData => todo!(),
|
|
}
|
|
}
|
|
|
|
pub fn force_count(&self) -> u32 {
|
|
match self {
|
|
DefaultFunction::AddInteger => 0,
|
|
DefaultFunction::SubtractInteger => 0,
|
|
DefaultFunction::MultiplyInteger => todo!(),
|
|
DefaultFunction::DivideInteger => todo!(),
|
|
DefaultFunction::QuotientInteger => todo!(),
|
|
DefaultFunction::RemainderInteger => todo!(),
|
|
DefaultFunction::ModInteger => todo!(),
|
|
DefaultFunction::EqualsInteger => todo!(),
|
|
DefaultFunction::LessThanInteger => todo!(),
|
|
DefaultFunction::LessThanEqualsInteger => 0,
|
|
DefaultFunction::AppendByteString => todo!(),
|
|
DefaultFunction::ConsByteString => todo!(),
|
|
DefaultFunction::SliceByteString => todo!(),
|
|
DefaultFunction::LengthOfByteString => todo!(),
|
|
DefaultFunction::IndexByteString => todo!(),
|
|
DefaultFunction::EqualsByteString => todo!(),
|
|
DefaultFunction::LessThanByteString => todo!(),
|
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
|
DefaultFunction::Sha2_256 => todo!(),
|
|
DefaultFunction::Sha3_256 => todo!(),
|
|
DefaultFunction::Blake2b_256 => todo!(),
|
|
DefaultFunction::VerifySignature => todo!(),
|
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
|
DefaultFunction::AppendString => todo!(),
|
|
DefaultFunction::EqualsString => todo!(),
|
|
DefaultFunction::EncodeUtf8 => todo!(),
|
|
DefaultFunction::DecodeUtf8 => todo!(),
|
|
DefaultFunction::IfThenElse => 1,
|
|
DefaultFunction::ChooseUnit => 1,
|
|
DefaultFunction::Trace => todo!(),
|
|
DefaultFunction::FstPair => todo!(),
|
|
DefaultFunction::SndPair => todo!(),
|
|
DefaultFunction::ChooseList => todo!(),
|
|
DefaultFunction::MkCons => todo!(),
|
|
DefaultFunction::HeadList => todo!(),
|
|
DefaultFunction::TailList => todo!(),
|
|
DefaultFunction::NullList => todo!(),
|
|
DefaultFunction::ChooseData => todo!(),
|
|
DefaultFunction::ConstrData => todo!(),
|
|
DefaultFunction::MapData => todo!(),
|
|
DefaultFunction::ListData => todo!(),
|
|
DefaultFunction::IData => todo!(),
|
|
DefaultFunction::BData => todo!(),
|
|
DefaultFunction::UnConstrData => todo!(),
|
|
DefaultFunction::UnMapData => todo!(),
|
|
DefaultFunction::UnListData => todo!(),
|
|
DefaultFunction::UnIData => todo!(),
|
|
DefaultFunction::UnBData => todo!(),
|
|
DefaultFunction::EqualsData => todo!(),
|
|
DefaultFunction::SerialiseData => todo!(),
|
|
DefaultFunction::MkPairData => todo!(),
|
|
DefaultFunction::MkNilData => todo!(),
|
|
DefaultFunction::MkNilPairData => todo!(),
|
|
}
|
|
}
|
|
|
|
pub fn check_type(&self, arg: &Value, args: &[Value]) -> Result<(), Error> {
|
|
match self {
|
|
DefaultFunction::AddInteger => arg.expect_type(Type::Integer),
|
|
DefaultFunction::SubtractInteger => arg.expect_type(Type::Integer),
|
|
DefaultFunction::MultiplyInteger => todo!(),
|
|
DefaultFunction::DivideInteger => todo!(),
|
|
DefaultFunction::QuotientInteger => todo!(),
|
|
DefaultFunction::RemainderInteger => todo!(),
|
|
DefaultFunction::ModInteger => todo!(),
|
|
DefaultFunction::EqualsInteger => todo!(),
|
|
DefaultFunction::LessThanInteger => todo!(),
|
|
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
|
DefaultFunction::AppendByteString => todo!(),
|
|
DefaultFunction::ConsByteString => todo!(),
|
|
DefaultFunction::SliceByteString => todo!(),
|
|
DefaultFunction::LengthOfByteString => todo!(),
|
|
DefaultFunction::IndexByteString => todo!(),
|
|
DefaultFunction::EqualsByteString => todo!(),
|
|
DefaultFunction::LessThanByteString => todo!(),
|
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
|
DefaultFunction::Sha2_256 => todo!(),
|
|
DefaultFunction::Sha3_256 => todo!(),
|
|
DefaultFunction::Blake2b_256 => todo!(),
|
|
DefaultFunction::VerifySignature => todo!(),
|
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
|
DefaultFunction::AppendString => todo!(),
|
|
DefaultFunction::EqualsString => todo!(),
|
|
DefaultFunction::EncodeUtf8 => todo!(),
|
|
DefaultFunction::DecodeUtf8 => todo!(),
|
|
DefaultFunction::IfThenElse => {
|
|
if args.is_empty() && !arg.is_bool() {
|
|
arg.expect_type(Type::Bool)
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
DefaultFunction::ChooseUnit => todo!(),
|
|
DefaultFunction::Trace => todo!(),
|
|
DefaultFunction::FstPair => todo!(),
|
|
DefaultFunction::SndPair => todo!(),
|
|
DefaultFunction::ChooseList => todo!(),
|
|
DefaultFunction::MkCons => todo!(),
|
|
DefaultFunction::HeadList => todo!(),
|
|
DefaultFunction::TailList => todo!(),
|
|
DefaultFunction::NullList => todo!(),
|
|
DefaultFunction::ChooseData => todo!(),
|
|
DefaultFunction::ConstrData => todo!(),
|
|
DefaultFunction::MapData => todo!(),
|
|
DefaultFunction::ListData => todo!(),
|
|
DefaultFunction::IData => todo!(),
|
|
DefaultFunction::BData => todo!(),
|
|
DefaultFunction::UnConstrData => todo!(),
|
|
DefaultFunction::UnMapData => todo!(),
|
|
DefaultFunction::UnListData => todo!(),
|
|
DefaultFunction::UnIData => todo!(),
|
|
DefaultFunction::UnBData => todo!(),
|
|
DefaultFunction::EqualsData => todo!(),
|
|
DefaultFunction::SerialiseData => todo!(),
|
|
DefaultFunction::MkPairData => todo!(),
|
|
DefaultFunction::MkNilData => todo!(),
|
|
DefaultFunction::MkNilPairData => todo!(),
|
|
}
|
|
}
|
|
|
|
// This should be safe because we've already checked
|
|
// the types of the args as they were pushed. Although
|
|
// the unreachables look ugly, it's the reality of the situation.
|
|
pub fn call(&self, args: &[Value]) -> Result<Value, Error> {
|
|
match self {
|
|
DefaultFunction::AddInteger => {
|
|
let args = (&args[0], &args[1]);
|
|
|
|
match args {
|
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
|
Ok(Value::Con(Constant::Integer(arg1 + arg2)))
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
DefaultFunction::SubtractInteger => {
|
|
let args = (&args[0], &args[1]);
|
|
|
|
match args {
|
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
|
Ok(Value::Con(Constant::Integer(arg1 - arg2)))
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
DefaultFunction::MultiplyInteger => todo!(),
|
|
DefaultFunction::DivideInteger => todo!(),
|
|
DefaultFunction::QuotientInteger => todo!(),
|
|
DefaultFunction::RemainderInteger => todo!(),
|
|
DefaultFunction::ModInteger => todo!(),
|
|
DefaultFunction::EqualsInteger => todo!(),
|
|
DefaultFunction::LessThanInteger => todo!(),
|
|
DefaultFunction::LessThanEqualsInteger => {
|
|
let args = (&args[0], &args[1]);
|
|
|
|
match args {
|
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
|
Ok(Value::Con(Constant::Bool(arg1 <= arg2)))
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
DefaultFunction::AppendByteString => todo!(),
|
|
DefaultFunction::ConsByteString => todo!(),
|
|
DefaultFunction::SliceByteString => todo!(),
|
|
DefaultFunction::LengthOfByteString => todo!(),
|
|
DefaultFunction::IndexByteString => todo!(),
|
|
DefaultFunction::EqualsByteString => todo!(),
|
|
DefaultFunction::LessThanByteString => todo!(),
|
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
|
DefaultFunction::Sha2_256 => todo!(),
|
|
DefaultFunction::Sha3_256 => todo!(),
|
|
DefaultFunction::Blake2b_256 => todo!(),
|
|
DefaultFunction::VerifySignature => todo!(),
|
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
|
DefaultFunction::AppendString => todo!(),
|
|
DefaultFunction::EqualsString => todo!(),
|
|
DefaultFunction::EncodeUtf8 => todo!(),
|
|
DefaultFunction::DecodeUtf8 => todo!(),
|
|
DefaultFunction::IfThenElse => match args[0] {
|
|
Value::Con(Constant::Bool(condition)) => {
|
|
if condition {
|
|
Ok(args[1].clone())
|
|
} else {
|
|
Ok(args[2].clone())
|
|
}
|
|
}
|
|
_ => unreachable!(),
|
|
},
|
|
DefaultFunction::ChooseUnit => todo!(),
|
|
DefaultFunction::Trace => todo!(),
|
|
DefaultFunction::FstPair => todo!(),
|
|
DefaultFunction::SndPair => todo!(),
|
|
DefaultFunction::ChooseList => todo!(),
|
|
DefaultFunction::MkCons => todo!(),
|
|
DefaultFunction::HeadList => todo!(),
|
|
DefaultFunction::TailList => todo!(),
|
|
DefaultFunction::NullList => todo!(),
|
|
DefaultFunction::ChooseData => todo!(),
|
|
DefaultFunction::ConstrData => todo!(),
|
|
DefaultFunction::MapData => todo!(),
|
|
DefaultFunction::ListData => todo!(),
|
|
DefaultFunction::IData => todo!(),
|
|
DefaultFunction::BData => todo!(),
|
|
DefaultFunction::UnConstrData => todo!(),
|
|
DefaultFunction::UnMapData => todo!(),
|
|
DefaultFunction::UnListData => todo!(),
|
|
DefaultFunction::UnIData => todo!(),
|
|
DefaultFunction::UnBData => todo!(),
|
|
DefaultFunction::EqualsData => todo!(),
|
|
DefaultFunction::SerialiseData => todo!(),
|
|
DefaultFunction::MkPairData => todo!(),
|
|
DefaultFunction::MkNilData => todo!(),
|
|
DefaultFunction::MkNilPairData => todo!(),
|
|
}
|
|
}
|
|
}
|