summaryrefslogtreecommitdiff
path: root/rust/src/ast.rs
diff options
context:
space:
mode:
authorArnaud Bailly <arnaud.bailly@iohk.io>2024-10-06 21:11:04 +0200
committerArnaud Bailly <arnaud.bailly@iohk.io>2024-10-06 21:11:04 +0200
commita2220cd6ca103b636567b557d21ab345c6ab99e0 (patch)
tree6bb4e35c3921d4918a0c7995762bc0b720e40d78 /rust/src/ast.rs
parentaaaee7bdc476f5f0631dc0d2f367c54bdfe03d12 (diff)
downloadlambda-nantes-a2220cd6ca103b636567b557d21ab345c6ab99e0.tar.gz
Use proptest's Strategy to generate expressions
Diffstat (limited to 'rust/src/ast.rs')
-rw-r--r--rust/src/ast.rs45
1 files changed, 43 insertions, 2 deletions
diff --git a/rust/src/ast.rs b/rust/src/ast.rs
index dfb6862..3f8b772 100644
--- a/rust/src/ast.rs
+++ b/rust/src/ast.rs
@@ -1,6 +1,9 @@
-use std::fmt::{self, Display};
-
+use proptest::{
+ prelude::*,
+ string::{string_regex, RegexGeneratorStrategy},
+};
use serde::{Deserialize, Serialize};
+use std::fmt::{self, Display};
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub enum Value {
@@ -26,3 +29,41 @@ impl Display for Value {
}
}
}
+
+use Value::*;
+
+pub const IDENTIFIER: &str = "\\pL(\\pL|\\pN)*";
+
+pub fn identifier() -> RegexGeneratorStrategy<String> {
+ string_regex(IDENTIFIER).unwrap()
+}
+
+impl Arbitrary for Value {
+ type Parameters = ();
+ type Strategy = BoxedStrategy<Self>;
+
+ fn arbitrary_with(_args: ()) -> Self::Strategy {
+ let any_num = any::<i32>().prop_map(Num);
+ let any_bool = any::<bool>().prop_map(Bool);
+ let leaf = prop_oneof![
+ any_num,
+ any_bool,
+ // see https://unicode.org/reports/tr18/#General_Category_Property for one letter unicode categories
+ identifier().prop_map(Sym),
+ ];
+ let expr = leaf.prop_recursive(4, 128, 5, move |inner| {
+ prop_oneof![
+ (inner.clone(), inner.clone()).prop_map(|(l, r)| App(Box::new(l), Box::new(r))),
+ (identifier(), inner.clone()).prop_map(|(var, body)| Lam(var, Box::new(body))),
+ (identifier(), inner.clone(), inner.clone()).prop_map(|(var, body, expr)| {
+ Value::Let(var, Box::new(body), Box::new(expr))
+ }),
+ ]
+ });
+ prop_oneof![
+ expr.clone(),
+ (identifier(), expr).prop_map(|(var, body)| Def(var, Box::new(body)))
+ ]
+ .boxed()
+ }
+}