Implement reification from Maps.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use std::{collections::HashMap, rc::Rc};
|
||||
use uplc::KeyValuePairs;
|
||||
|
||||
use vec1::Vec1;
|
||||
|
||||
@@ -607,32 +608,38 @@ impl UntypedExpr {
|
||||
preferred_format: ByteArrayFormatPreference::HexadecimalString,
|
||||
}),
|
||||
PlutusData::Array(args) => {
|
||||
let inner;
|
||||
match tipo {
|
||||
Type::App {
|
||||
module, name, args, ..
|
||||
module,
|
||||
name,
|
||||
args: type_args,
|
||||
..
|
||||
} if module.is_empty() && name.as_str() == "List" => {
|
||||
if let [arg] = &args[..] {
|
||||
inner = arg.clone()
|
||||
if let [inner] = &type_args[..] {
|
||||
Ok(UntypedExpr::List {
|
||||
location: Span::empty(),
|
||||
elements: args
|
||||
.into_iter()
|
||||
.map(|arg| UntypedExpr::reify(data_types, arg, inner))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
tail: None,
|
||||
})
|
||||
} else {
|
||||
return Err("invalid List type annotation: the list has multiple type-parameters.".to_string());
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
return Err(format!(
|
||||
"invalid type annotation. expected List but got: {tipo:?}"
|
||||
))
|
||||
Err("invalid List type annotation: the list has multiple type-parameters.".to_string())
|
||||
}
|
||||
}
|
||||
Type::Tuple { elems } => Ok(UntypedExpr::Tuple {
|
||||
location: Span::empty(),
|
||||
elems: args
|
||||
.into_iter()
|
||||
.zip(elems)
|
||||
.map(|(arg, arg_type)| UntypedExpr::reify(data_types, arg, arg_type))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
}),
|
||||
_ => Err(format!(
|
||||
"invalid type annotation. expected List but got: {tipo:?}"
|
||||
)),
|
||||
}
|
||||
|
||||
Ok(UntypedExpr::List {
|
||||
location: Span::empty(),
|
||||
elements: args
|
||||
.into_iter()
|
||||
.map(|arg| UntypedExpr::reify(data_types, arg, &inner))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
tail: None,
|
||||
})
|
||||
}
|
||||
|
||||
PlutusData::Constr(Constr {
|
||||
@@ -716,7 +723,22 @@ impl UntypedExpr {
|
||||
))
|
||||
}
|
||||
|
||||
PlutusData::Map(..) => todo!("reify Map"),
|
||||
PlutusData::Map(indef_or_def) => {
|
||||
let kvs = match indef_or_def {
|
||||
KeyValuePairs::Def(kvs) => kvs,
|
||||
KeyValuePairs::Indef(kvs) => kvs,
|
||||
};
|
||||
|
||||
UntypedExpr::reify(
|
||||
data_types,
|
||||
PlutusData::Array(
|
||||
kvs.into_iter()
|
||||
.map(|(k, v)| PlutusData::Array(vec![k, v]))
|
||||
.collect(),
|
||||
),
|
||||
tipo,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,10 @@ pub struct CodeGenerator<'a> {
|
||||
}
|
||||
|
||||
impl<'a> CodeGenerator<'a> {
|
||||
pub fn data_types(&self) -> &IndexMap<DataTypeKey, &'a TypedDataType> {
|
||||
&self.data_types
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
functions: IndexMap<FunctionAccessKey, &'a TypedFunction>,
|
||||
data_types: IndexMap<DataTypeKey, &'a TypedDataType>,
|
||||
|
||||
@@ -57,6 +57,18 @@ pub enum Type {
|
||||
}
|
||||
|
||||
impl Type {
|
||||
pub fn qualifier(&self) -> Option<(String, String)> {
|
||||
match self {
|
||||
Type::App { module, name, .. } => Some((module.to_string(), name.to_string())),
|
||||
Type::Fn { .. } => None,
|
||||
Type::Var { ref tipo } => match &*tipo.borrow() {
|
||||
TypeVar::Link { ref tipo } => tipo.qualifier(),
|
||||
_ => None,
|
||||
},
|
||||
Type::Tuple { .. } => Some((String::new(), "Tuple".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_result_constructor(&self) -> bool {
|
||||
match self {
|
||||
Type::Fn { ret, .. } => ret.is_result(),
|
||||
|
||||
Reference in New Issue
Block a user