Implement SimpleExpr logic for configuration parsing

We can now use boolean, lists & all in configuration.
This commit is contained in:
microproofs 2024-08-16 22:04:20 -04:00 committed by KtorZ
parent f674f9ee97
commit f35afe8d65
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
2 changed files with 69 additions and 21 deletions

View File

@ -1259,6 +1259,19 @@ impl Annotation {
} }
} }
pub fn list(inner: Annotation, location: Span) -> Self {
Annotation::Constructor {
name: "List".to_string(),
module: None,
arguments: vec![inner],
location,
}
}
pub fn tuple(elems: Vec<Annotation>, location: Span) -> Self {
Annotation::Tuple { elems, location }
}
pub fn is_logically_equal(&self, other: &Annotation) -> bool { pub fn is_logically_equal(&self, other: &Annotation) -> bool {
match self { match self {
Annotation::Constructor { Annotation::Constructor {

View File

@ -45,7 +45,7 @@ pub enum SimpleExpr {
} }
impl SimpleExpr { impl SimpleExpr {
pub fn as_untyped_expr(&self) -> UntypedExpr { pub fn as_untyped_expr(&self, annotation: &Annotation) -> UntypedExpr {
match self { match self {
SimpleExpr::Bool(b) => UntypedExpr::Var { SimpleExpr::Bool(b) => UntypedExpr::Var {
location: Span::empty(), location: Span::empty(),
@ -63,38 +63,73 @@ impl SimpleExpr {
bytes: bs.to_vec(), bytes: bs.to_vec(),
preferred_format: *preferred_format, preferred_format: *preferred_format,
}, },
SimpleExpr::List(es) => UntypedExpr::List { SimpleExpr::List(es) => match annotation {
Annotation::Tuple { elems, .. } => UntypedExpr::Tuple {
location: Span::empty(), location: Span::empty(),
elements: es.iter().map(|e| e.as_untyped_expr()).collect(), elems: es
.iter()
.zip(elems)
.map(|(e, ann)| e.as_untyped_expr(ann))
.collect(),
},
Annotation::Constructor {
module,
name,
arguments,
..
} if name == "List" && module.is_none() => UntypedExpr::List {
location: Span::empty(),
elements: es
.iter()
.map(|e| e.as_untyped_expr(arguments.first().unwrap()))
.collect(),
tail: None, tail: None,
}, },
_ => unreachable!(
"unexpected annotation for simple list expression: {annotation:#?}"
),
},
} }
} }
pub fn as_definition(&self, identifier: &str) -> UntypedDefinition { pub fn as_annotation(&self) -> Annotation {
let location = Span::empty(); let location = Span::empty();
match self {
SimpleExpr::Bool(..) => Annotation::boolean(location),
SimpleExpr::Int(_) => Annotation::int(location),
SimpleExpr::ByteArray(_, _) => Annotation::bytearray(location),
SimpleExpr::List(elems) => {
let elems = elems.iter().map(|e| e.as_annotation()).collect::<Vec<_>>();
let (value, annotation) = match self { let (is_uniform, inner) =
SimpleExpr::Bool(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"), elems
SimpleExpr::Int(_) => ( .iter()
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992 .fold((true, None), |(matches, ann), a| match ann {
self.as_untyped_expr(), None => (matches, Some(a)),
Some(Annotation::int(location)), Some(b) => (matches && a == b, ann),
), });
SimpleExpr::ByteArray(_, _) => (
// TODO: Replace with 'self.as_untyped_expr()' after https://github.com/aiken-lang/aiken/pull/992
self.as_untyped_expr(),
Some(Annotation::bytearray(location)),
),
SimpleExpr::List(..) => todo!("requires https://github.com/aiken-lang/aiken/pull/992"),
};
if is_uniform {
Annotation::list(
inner.cloned().unwrap_or_else(|| Annotation::data(location)),
location,
)
} else {
Annotation::tuple(elems, location)
}
}
}
}
pub fn as_definition(&self, identifier: &str) -> UntypedDefinition {
let annotation = self.as_annotation();
let value = self.as_untyped_expr(&annotation);
UntypedDefinition::ModuleConstant(ModuleConstant { UntypedDefinition::ModuleConstant(ModuleConstant {
location: Span::empty(), location: Span::empty(),
doc: None, doc: None,
public: true, public: true,
name: identifier.to_string(), name: identifier.to_string(),
annotation, annotation: Some(annotation),
value, value,
}) })
} }