remaining buitlins for list and integer
Co-authored-by: rvcas <x@rvcas.dev>
This commit is contained in:
parent
3f6ad6be60
commit
09ae98065c
|
@ -1,5 +1,5 @@
|
||||||
(program
|
(program
|
||||||
1.0.0
|
1.0.0
|
||||||
[ (builtin divideInteger) (con integer 5) (con integer 2) ]
|
[ (builtin remainderInteger) (con integer 5) (con integer 2)]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -450,7 +450,9 @@ impl Value {
|
||||||
Constant::String(s) => s.chars().count() as i64,
|
Constant::String(s) => s.chars().count() as i64,
|
||||||
Constant::Unit => 1,
|
Constant::Unit => 1,
|
||||||
Constant::Bool(_) => 1,
|
Constant::Bool(_) => 1,
|
||||||
Constant::ProtoList(_, _) => todo!(),
|
Constant::ProtoList(_, items) => items.iter().fold(0, |acc, constant| {
|
||||||
|
acc + Value::Con(constant.clone()).to_ex_mem()
|
||||||
|
}),
|
||||||
Constant::ProtoPair(_, _, _, _) => todo!(),
|
Constant::ProtoPair(_, _, _, _) => todo!(),
|
||||||
Constant::Data(_) => todo!(),
|
Constant::Data(_) => todo!(),
|
||||||
},
|
},
|
||||||
|
@ -461,17 +463,49 @@ impl Value {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_type(&self, r#type: Type) -> Result<(), Error> {
|
pub fn expect_type(&self, r#type: Type) -> Result<(), Error> {
|
||||||
match self {
|
let constant: Constant = self.clone().try_into()?;
|
||||||
Value::Con(constant) => {
|
|
||||||
let constant_type = Type::from(constant);
|
|
||||||
|
|
||||||
if constant_type == r#type {
|
let constant_type = Type::from(&constant);
|
||||||
Ok(())
|
|
||||||
} else {
|
if constant_type == r#type {
|
||||||
Err(Error::TypeMismatch(r#type, constant_type))
|
Ok(())
|
||||||
}
|
} else {
|
||||||
}
|
Err(Error::TypeMismatch(r#type, constant_type))
|
||||||
rest => Err(Error::NotAConstant(rest.clone())),
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expect_list(&self) -> Result<(), Error> {
|
||||||
|
let constant: Constant = self.clone().try_into()?;
|
||||||
|
|
||||||
|
let constant_type = Type::from(&constant);
|
||||||
|
|
||||||
|
if matches!(constant_type, Type::List(_)) {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::ListTypeMismatch(constant_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Value> for Type {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(value: Value) -> Result<Self, Self::Error> {
|
||||||
|
let constant: Constant = value.try_into()?;
|
||||||
|
|
||||||
|
let constant_type = Type::from(&constant);
|
||||||
|
|
||||||
|
Ok(constant_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Value> for Constant {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(value: Value) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::Con(constant) => Ok(constant),
|
||||||
|
rest => Err(Error::NotAConstant(rest)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -572,9 +572,36 @@ impl BuiltinCosts {
|
||||||
.cpu
|
.cpu
|
||||||
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
},
|
},
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => ExBudget {
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
mem: self
|
||||||
DefaultFunction::ModInteger => todo!(),
|
.quotient_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.quotient_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::RemainderInteger => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.remainder_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.remainder_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::ModInteger => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.mod_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.mod_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::EqualsInteger => ExBudget {
|
DefaultFunction::EqualsInteger => ExBudget {
|
||||||
mem: self
|
mem: self
|
||||||
.equals_integer
|
.equals_integer
|
||||||
|
@ -770,10 +797,28 @@ impl BuiltinCosts {
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
DefaultFunction::MkCons => todo!(),
|
DefaultFunction::MkCons => ExBudget {
|
||||||
DefaultFunction::HeadList => todo!(),
|
mem: self
|
||||||
DefaultFunction::TailList => todo!(),
|
.mk_cons
|
||||||
DefaultFunction::NullList => todo!(),
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.mk_cons
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::HeadList => ExBudget {
|
||||||
|
mem: self.head_list.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.head_list.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::TailList => ExBudget {
|
||||||
|
mem: self.tail_list.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.tail_list.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::NullList => ExBudget {
|
||||||
|
mem: self.null_list.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.null_list.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::ChooseData => todo!(),
|
DefaultFunction::ChooseData => todo!(),
|
||||||
DefaultFunction::ConstrData => todo!(),
|
DefaultFunction::ConstrData => todo!(),
|
||||||
DefaultFunction::MapData => todo!(),
|
DefaultFunction::MapData => todo!(),
|
||||||
|
|
|
@ -22,6 +22,10 @@ pub enum Error {
|
||||||
NonFunctionalApplication(Value),
|
NonFunctionalApplication(Value),
|
||||||
#[error("Type mismatch expected '{0}' got '{1}'")]
|
#[error("Type mismatch expected '{0}' got '{1}'")]
|
||||||
TypeMismatch(Type, Type),
|
TypeMismatch(Type, Type),
|
||||||
|
#[error("Type mismatch expected '(list a)' got '{0}'")]
|
||||||
|
ListTypeMismatch(Type),
|
||||||
|
#[error("Empty List:\n\n{0:#?}")]
|
||||||
|
EmptyList(Value),
|
||||||
#[error("A builtin received a term argument when something else was expected:\n\n{0}\n\nYou probably forgot to wrap the builtin with a force.")]
|
#[error("A builtin received a term argument when something else was expected:\n\n{0}\n\nYou probably forgot to wrap the builtin with a force.")]
|
||||||
UnexpectedBuiltinTermArgument(Term<NamedDeBruijn>),
|
UnexpectedBuiltinTermArgument(Term<NamedDeBruijn>),
|
||||||
#[error("A builtin expected a term argument, but something else was received:\n\n{0}\n\nYou probably have an extra force wrapped around a builtin")]
|
#[error("A builtin expected a term argument, but something else was received:\n\n{0}\n\nYou probably have an extra force wrapped around a builtin")]
|
||||||
|
@ -36,4 +40,8 @@ pub enum Error {
|
||||||
ByteStringOutOfBounds(isize, Vec<u8>),
|
ByteStringOutOfBounds(isize, Vec<u8>),
|
||||||
#[error("Divide By Zero\n\n{0} / {1}")]
|
#[error("Divide By Zero\n\n{0} / {1}")]
|
||||||
DivideByZero(isize, isize),
|
DivideByZero(isize, isize),
|
||||||
|
#[error("Ed25519S PublicKey should be 32 bytes but it was {0}")]
|
||||||
|
UnexpectedEd25519PublicKeyLength(usize),
|
||||||
|
#[error("Ed25519S Signature should be 64 bytes but it was {0}")]
|
||||||
|
UnexpectedEd25519SignatureLength(usize),
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,9 +76,9 @@ impl DefaultFunction {
|
||||||
DefaultFunction::SubtractInteger => 2,
|
DefaultFunction::SubtractInteger => 2,
|
||||||
DefaultFunction::MultiplyInteger => 2,
|
DefaultFunction::MultiplyInteger => 2,
|
||||||
DefaultFunction::DivideInteger => 2,
|
DefaultFunction::DivideInteger => 2,
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => 2,
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => 2,
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => 2,
|
||||||
DefaultFunction::EqualsInteger => 2,
|
DefaultFunction::EqualsInteger => 2,
|
||||||
DefaultFunction::LessThanInteger => 2,
|
DefaultFunction::LessThanInteger => 2,
|
||||||
DefaultFunction::LessThanEqualsInteger => 2,
|
DefaultFunction::LessThanEqualsInteger => 2,
|
||||||
|
@ -106,10 +106,10 @@ impl DefaultFunction {
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
DefaultFunction::MkCons => todo!(),
|
DefaultFunction::MkCons => 2,
|
||||||
DefaultFunction::HeadList => todo!(),
|
DefaultFunction::HeadList => 1,
|
||||||
DefaultFunction::TailList => todo!(),
|
DefaultFunction::TailList => 1,
|
||||||
DefaultFunction::NullList => todo!(),
|
DefaultFunction::NullList => 1,
|
||||||
DefaultFunction::ChooseData => todo!(),
|
DefaultFunction::ChooseData => todo!(),
|
||||||
DefaultFunction::ConstrData => todo!(),
|
DefaultFunction::ConstrData => todo!(),
|
||||||
DefaultFunction::MapData => todo!(),
|
DefaultFunction::MapData => todo!(),
|
||||||
|
@ -135,9 +135,9 @@ impl DefaultFunction {
|
||||||
DefaultFunction::SubtractInteger => 0,
|
DefaultFunction::SubtractInteger => 0,
|
||||||
DefaultFunction::MultiplyInteger => 0,
|
DefaultFunction::MultiplyInteger => 0,
|
||||||
DefaultFunction::DivideInteger => 0,
|
DefaultFunction::DivideInteger => 0,
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => 0,
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => 0,
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => 0,
|
||||||
DefaultFunction::EqualsInteger => 0,
|
DefaultFunction::EqualsInteger => 0,
|
||||||
DefaultFunction::LessThanInteger => 0,
|
DefaultFunction::LessThanInteger => 0,
|
||||||
DefaultFunction::LessThanEqualsInteger => 0,
|
DefaultFunction::LessThanEqualsInteger => 0,
|
||||||
|
@ -165,10 +165,10 @@ impl DefaultFunction {
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
DefaultFunction::MkCons => todo!(),
|
DefaultFunction::MkCons => 1,
|
||||||
DefaultFunction::HeadList => todo!(),
|
DefaultFunction::HeadList => 1,
|
||||||
DefaultFunction::TailList => todo!(),
|
DefaultFunction::TailList => 1,
|
||||||
DefaultFunction::NullList => todo!(),
|
DefaultFunction::NullList => 1,
|
||||||
DefaultFunction::ChooseData => todo!(),
|
DefaultFunction::ChooseData => todo!(),
|
||||||
DefaultFunction::ConstrData => todo!(),
|
DefaultFunction::ConstrData => todo!(),
|
||||||
DefaultFunction::MapData => todo!(),
|
DefaultFunction::MapData => todo!(),
|
||||||
|
@ -194,9 +194,9 @@ impl DefaultFunction {
|
||||||
DefaultFunction::SubtractInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::SubtractInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::MultiplyInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::MultiplyInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::DivideInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::DivideInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::EqualsInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::EqualsInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::LessThanInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::LessThanInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
||||||
|
@ -260,10 +260,18 @@ impl DefaultFunction {
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
DefaultFunction::MkCons => todo!(),
|
DefaultFunction::MkCons => {
|
||||||
DefaultFunction::HeadList => todo!(),
|
if args.is_empty() {
|
||||||
DefaultFunction::TailList => todo!(),
|
Ok(())
|
||||||
DefaultFunction::NullList => todo!(),
|
} else {
|
||||||
|
let first = args[0].clone();
|
||||||
|
|
||||||
|
arg.expect_type(Type::List(Box::new(first.try_into()?)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::HeadList => arg.expect_list(),
|
||||||
|
DefaultFunction::TailList => arg.expect_list(),
|
||||||
|
DefaultFunction::NullList => arg.expect_list(),
|
||||||
DefaultFunction::ChooseData => todo!(),
|
DefaultFunction::ChooseData => todo!(),
|
||||||
DefaultFunction::ConstrData => todo!(),
|
DefaultFunction::ConstrData => todo!(),
|
||||||
DefaultFunction::MapData => todo!(),
|
DefaultFunction::MapData => todo!(),
|
||||||
|
@ -318,9 +326,44 @@ impl DefaultFunction {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
DefaultFunction::ModInteger => todo!(),
|
if *arg2 != 0 {
|
||||||
|
let ret = (*arg1 as f64) / (*arg2 as f64);
|
||||||
|
|
||||||
|
let ret = if ret < 0. { ret.ceil() } else { ret.floor() };
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::Integer(ret as isize)))
|
||||||
|
} else {
|
||||||
|
Err(Error::DivideByZero(*arg1, *arg2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::RemainderInteger => match (&args[0], &args[1]) {
|
||||||
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
if *arg2 != 0 {
|
||||||
|
let ret = arg1 % arg2;
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::Integer(ret)))
|
||||||
|
} else {
|
||||||
|
Err(Error::DivideByZero(*arg1, *arg2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::ModInteger => match (&args[0], &args[1]) {
|
||||||
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
if *arg2 != 0 {
|
||||||
|
let ret = arg1 % arg2;
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::Integer(ret.abs())))
|
||||||
|
} else {
|
||||||
|
Err(Error::DivideByZero(*arg1, *arg2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::EqualsInteger => match (&args[0], &args[1]) {
|
DefaultFunction::EqualsInteger => match (&args[0], &args[1]) {
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
||||||
|
@ -461,11 +504,25 @@ impl DefaultFunction {
|
||||||
},
|
},
|
||||||
DefaultFunction::VerifyEd25519Signature => match (&args[0], &args[1], &args[2]) {
|
DefaultFunction::VerifyEd25519Signature => match (&args[0], &args[1], &args[2]) {
|
||||||
(
|
(
|
||||||
Value::Con(Constant::ByteString(_arg1)),
|
Value::Con(Constant::ByteString(public_key)),
|
||||||
Value::Con(Constant::ByteString(_arg2)),
|
Value::Con(Constant::ByteString(message)),
|
||||||
Value::Con(Constant::ByteString(_arg3)),
|
Value::Con(Constant::ByteString(signature)),
|
||||||
) => {
|
) => {
|
||||||
todo!()
|
use cryptoxide::ed25519;
|
||||||
|
|
||||||
|
let public_key: [u8; 32] = public_key
|
||||||
|
.clone()
|
||||||
|
.try_into()
|
||||||
|
.map_err(|e: Vec<u8>| Error::UnexpectedEd25519PublicKeyLength(e.len()))?;
|
||||||
|
|
||||||
|
let signature: [u8; 64] = signature
|
||||||
|
.clone()
|
||||||
|
.try_into()
|
||||||
|
.map_err(|e: Vec<u8>| Error::UnexpectedEd25519SignatureLength(e.len()))?;
|
||||||
|
|
||||||
|
let valid = ed25519::verify(message, &public_key, &signature);
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::Bool(valid)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
|
@ -524,10 +581,44 @@ impl DefaultFunction {
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
DefaultFunction::MkCons => todo!(),
|
DefaultFunction::MkCons => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::HeadList => todo!(),
|
(Value::Con(item), Value::Con(Constant::ProtoList(r#type, list))) => {
|
||||||
DefaultFunction::TailList => todo!(),
|
let mut ret = vec![item.clone()];
|
||||||
DefaultFunction::NullList => todo!(),
|
ret.extend(list.clone());
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::ProtoList(r#type.clone(), ret)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::HeadList => match &args[0] {
|
||||||
|
c @ Value::Con(Constant::ProtoList(_, list)) => {
|
||||||
|
if list.is_empty() {
|
||||||
|
Err(Error::EmptyList(c.clone()))
|
||||||
|
} else {
|
||||||
|
Ok(Value::Con(list[0].clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::TailList => match &args[0] {
|
||||||
|
c @ Value::Con(Constant::ProtoList(r#type, list)) => {
|
||||||
|
if list.is_empty() {
|
||||||
|
Err(Error::EmptyList(c.clone()))
|
||||||
|
} else {
|
||||||
|
Ok(Value::Con(Constant::ProtoList(
|
||||||
|
r#type.clone(),
|
||||||
|
list[1..].to_vec(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::NullList => match &args[0] {
|
||||||
|
Value::Con(Constant::ProtoList(_, list)) => {
|
||||||
|
Ok(Value::Con(Constant::Bool(list.is_empty())))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::ChooseData => todo!(),
|
DefaultFunction::ChooseData => todo!(),
|
||||||
DefaultFunction::ConstrData => todo!(),
|
DefaultFunction::ConstrData => todo!(),
|
||||||
DefaultFunction::MapData => todo!(),
|
DefaultFunction::MapData => todo!(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use pretty::RcDoc;
|
use pretty::RcDoc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Constant, Program, Term},
|
ast::{Constant, Program, Term, Type},
|
||||||
flat::Binder,
|
flat::Binder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,9 +170,65 @@ impl Constant {
|
||||||
Constant::Bool(b) => RcDoc::text("bool")
|
Constant::Bool(b) => RcDoc::text("bool")
|
||||||
.append(RcDoc::line())
|
.append(RcDoc::line())
|
||||||
.append(RcDoc::text(if *b { "True" } else { "False" })),
|
.append(RcDoc::text(if *b { "True" } else { "False" })),
|
||||||
Constant::ProtoList(_, _) => todo!(),
|
Constant::ProtoList(r#type, items) => RcDoc::text("(")
|
||||||
|
.append(
|
||||||
|
RcDoc::text("list")
|
||||||
|
.append(RcDoc::line())
|
||||||
|
.append(r#type.to_doc()),
|
||||||
|
)
|
||||||
|
.append(RcDoc::line_())
|
||||||
|
.append(RcDoc::text(")"))
|
||||||
|
.append(RcDoc::line())
|
||||||
|
.append(RcDoc::text("["))
|
||||||
|
.append(RcDoc::intersperse(
|
||||||
|
items.iter().map(|c| c.to_doc_list()),
|
||||||
|
RcDoc::text(","),
|
||||||
|
))
|
||||||
|
.append(RcDoc::text("]")),
|
||||||
|
Constant::ProtoPair(_, _, _, _) => todo!(),
|
||||||
|
Constant::Data(_) => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_doc_list(&self) -> RcDoc<()> {
|
||||||
|
match self {
|
||||||
|
Constant::Integer(i) => RcDoc::as_string(i),
|
||||||
|
Constant::ByteString(bs) => RcDoc::text("#").append(RcDoc::text(hex::encode(bs))),
|
||||||
|
Constant::String(s) => RcDoc::text("\"")
|
||||||
|
.append(RcDoc::text(s))
|
||||||
|
.append(RcDoc::text("\"")),
|
||||||
|
Constant::Unit => RcDoc::text("()"),
|
||||||
|
Constant::Bool(b) => RcDoc::text(if *b { "True" } else { "False" }),
|
||||||
|
Constant::ProtoList(_, items) => RcDoc::text("[")
|
||||||
|
.append(RcDoc::intersperse(
|
||||||
|
items.iter().map(|c| c.to_doc_list()),
|
||||||
|
RcDoc::text(","),
|
||||||
|
))
|
||||||
|
.append(RcDoc::text("]")),
|
||||||
Constant::ProtoPair(_, _, _, _) => todo!(),
|
Constant::ProtoPair(_, _, _, _) => todo!(),
|
||||||
Constant::Data(_) => todo!(),
|
Constant::Data(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type {
|
||||||
|
fn to_doc(&self) -> RcDoc<()> {
|
||||||
|
match self {
|
||||||
|
Type::Bool => RcDoc::text("bool"),
|
||||||
|
Type::Integer => RcDoc::text("integer"),
|
||||||
|
Type::String => RcDoc::text("string"),
|
||||||
|
Type::ByteString => RcDoc::text("bytestring"),
|
||||||
|
Type::Unit => RcDoc::text("unit"),
|
||||||
|
Type::List(r#type) => RcDoc::text("(")
|
||||||
|
.append(
|
||||||
|
RcDoc::text("list")
|
||||||
|
.append(RcDoc::line())
|
||||||
|
.append(r#type.to_doc()),
|
||||||
|
)
|
||||||
|
.append(RcDoc::line_())
|
||||||
|
.append(RcDoc::text(")")),
|
||||||
|
Type::Pair(_, _) => todo!(),
|
||||||
|
Type::Data => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue