diff --git a/crates/uplc/src/lib.rs b/crates/uplc/src/lib.rs index ba0be0b5..a1800b90 100644 --- a/crates/uplc/src/lib.rs +++ b/crates/uplc/src/lib.rs @@ -13,3 +13,7 @@ use pallas_primitives::Fragment; pub fn plutus_data(bytes: &[u8]) -> PlutusData { PlutusData::decode_fragment(bytes).unwrap() } + +pub fn plutus_data_to_bytes(data: &PlutusData) -> Vec { + PlutusData::encode_fragment(data).unwrap() +} diff --git a/crates/uplc/src/machine/cost_model.rs b/crates/uplc/src/machine/cost_model.rs index f75dd61b..03e12753 100644 --- a/crates/uplc/src/machine/cost_model.rs +++ b/crates/uplc/src/machine/cost_model.rs @@ -829,10 +829,19 @@ impl BuiltinCosts { mem: self.un_constr_data.mem.cost(args[0].to_ex_mem()), cpu: self.un_constr_data.cpu.cost(args[0].to_ex_mem()), }, - DefaultFunction::UnMapData => todo!(), - DefaultFunction::UnListData => todo!(), + DefaultFunction::UnMapData => ExBudget { + mem: self.un_map_data.mem.cost(args[0].to_ex_mem()), + cpu: self.un_map_data.cpu.cost(args[0].to_ex_mem()), + }, + DefaultFunction::UnListData => ExBudget { + mem: self.un_list_data.mem.cost(args[0].to_ex_mem()), + cpu: self.un_list_data.cpu.cost(args[0].to_ex_mem()), + }, DefaultFunction::UnIData => todo!(), - DefaultFunction::UnBData => todo!(), + DefaultFunction::UnBData => ExBudget { + mem: self.un_b_data.mem.cost(args[0].to_ex_mem()), + cpu: self.un_b_data.cpu.cost(args[0].to_ex_mem()), + }, DefaultFunction::EqualsData => todo!(), DefaultFunction::SerialiseData => todo!(), DefaultFunction::MkPairData => todo!(), diff --git a/crates/uplc/src/machine/runtime.rs b/crates/uplc/src/machine/runtime.rs index 694984fa..c828b025 100644 --- a/crates/uplc/src/machine/runtime.rs +++ b/crates/uplc/src/machine/runtime.rs @@ -121,10 +121,10 @@ impl DefaultFunction { DefaultFunction::IData => todo!(), DefaultFunction::BData => todo!(), DefaultFunction::UnConstrData => 1, - DefaultFunction::UnMapData => todo!(), - DefaultFunction::UnListData => todo!(), + DefaultFunction::UnMapData => 1, + DefaultFunction::UnListData => 1, DefaultFunction::UnIData => todo!(), - DefaultFunction::UnBData => todo!(), + DefaultFunction::UnBData => 1, DefaultFunction::EqualsData => todo!(), DefaultFunction::SerialiseData => todo!(), DefaultFunction::MkPairData => todo!(), @@ -180,10 +180,10 @@ impl DefaultFunction { DefaultFunction::IData => todo!(), DefaultFunction::BData => todo!(), DefaultFunction::UnConstrData => 0, - DefaultFunction::UnMapData => todo!(), - DefaultFunction::UnListData => todo!(), + DefaultFunction::UnMapData => 0, + DefaultFunction::UnListData => 0, DefaultFunction::UnIData => todo!(), - DefaultFunction::UnBData => todo!(), + DefaultFunction::UnBData => 0, DefaultFunction::EqualsData => todo!(), DefaultFunction::SerialiseData => todo!(), DefaultFunction::MkPairData => todo!(), @@ -283,10 +283,10 @@ impl DefaultFunction { DefaultFunction::IData => todo!(), DefaultFunction::BData => todo!(), DefaultFunction::UnConstrData => arg.expect_type(Type::Data), - DefaultFunction::UnMapData => todo!(), - DefaultFunction::UnListData => todo!(), + DefaultFunction::UnMapData => arg.expect_type(Type::Data), + DefaultFunction::UnListData => arg.expect_type(Type::Data), DefaultFunction::UnIData => todo!(), - DefaultFunction::UnBData => todo!(), + DefaultFunction::UnBData => arg.expect_type(Type::Data), DefaultFunction::EqualsData => todo!(), DefaultFunction::SerialiseData => todo!(), DefaultFunction::MkPairData => todo!(), @@ -634,7 +634,8 @@ impl DefaultFunction { Ok(Value::Con(Constant::ProtoPair( Type::Integer, Type::List(Box::new(Type::Data)), - Box::new(Constant::Integer(c.tag as isize)), + // TODO: handle other types of constructor tags + Box::new(Constant::Integer(c.tag as isize - 121)), Box::new(Constant::ProtoList( Type::Data, c.fields @@ -647,10 +648,45 @@ impl DefaultFunction { } _ => unreachable!(), }, - DefaultFunction::UnMapData => todo!(), - DefaultFunction::UnListData => todo!(), + DefaultFunction::UnMapData => match &args[0] { + Value::Con(Constant::Data(PlutusData::Map(m))) => { + Ok(Value::Con(Constant::ProtoList( + Type::Pair(Box::new(Type::Data), Box::new(Type::Data)), + m.deref() + .iter() + .map(|p| -> Constant { + Constant::ProtoPair( + Type::Data, + Type::Data, + Box::new(Constant::Data(p.0.clone())), + Box::new(Constant::Data(p.1.clone())), + ) + }) + .collect(), + ))) + } + _ => unreachable!(), + }, + DefaultFunction::UnListData => match &args[0] { + Value::Con(Constant::Data(PlutusData::Array(l))) + | Value::Con(Constant::Data(PlutusData::ArrayIndef(l))) => { + Ok(Value::Con(Constant::ProtoList( + Type::Data, + l.deref() + .iter() + .map(|d| Constant::Data(d.clone())) + .collect(), + ))) + } + _ => unreachable!(), + }, DefaultFunction::UnIData => todo!(), - DefaultFunction::UnBData => todo!(), + DefaultFunction::UnBData => match &args[0] { + Value::Con(Constant::Data(PlutusData::BoundedBytes(b))) => { + Ok(Value::Con(Constant::ByteString(b.to_vec()))) + } + _ => unreachable!(), + }, DefaultFunction::EqualsData => todo!(), DefaultFunction::SerialiseData => todo!(), DefaultFunction::MkPairData => todo!(), diff --git a/crates/uplc/src/pretty.rs b/crates/uplc/src/pretty.rs index b3ace6cb..a374dc42 100644 --- a/crates/uplc/src/pretty.rs +++ b/crates/uplc/src/pretty.rs @@ -3,6 +3,7 @@ use pretty::RcDoc; use crate::{ ast::{Constant, Program, Term, Type}, flat::Binder, + plutus_data_to_bytes, }; impl<'a, T> Program @@ -220,8 +221,15 @@ impl Constant { RcDoc::text(","), )) .append(RcDoc::text("]")), - Constant::ProtoPair(_, _, _, _) => todo!(), - Constant::Data(data) => RcDoc::text("todo"), + Constant::ProtoPair(_, _, left, right) => RcDoc::text("(") + .append((*left).to_doc_list()) + .append(RcDoc::text(", ")) + .append((*right).to_doc_list()) + .append(RcDoc::text(")")), + + Constant::Data(data) => { + RcDoc::text("#").append(RcDoc::text(hex::encode(plutus_data_to_bytes(data)))) + } } } } @@ -242,7 +250,16 @@ impl Type { ) .append(RcDoc::line_()) .append(RcDoc::text(")")), - Type::Pair(_, _) => todo!(), + Type::Pair(r#type1, r#type2) => RcDoc::text("(") + .append( + RcDoc::text("list") + .append(RcDoc::line()) + .append(r#type1.to_doc()) + .append(RcDoc::line()) + .append(r#type2.to_doc()), + ) + .append(RcDoc::line_()) + .append(RcDoc::text(")")), Type::Data => RcDoc::text("data"), } }