Implement reification from Maps.

This commit is contained in:
KtorZ
2024-03-01 16:14:23 +01:00
parent 5272f5ecee
commit bfcfc5c41b
9 changed files with 257 additions and 184 deletions

View File

@@ -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,
)
}
}
}

View File

@@ -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>,

View File

@@ -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(),