summaryrefslogtreecommitdiff
path: root/rust/src/ast.rs
diff options
context:
space:
mode:
authorArnaud Bailly <arnaud.bailly@iohk.io>2025-01-25 10:45:41 +0100
committerArnaud Bailly <arnaud.bailly@iohk.io>2025-01-25 10:45:41 +0100
commit7752d73216578d5961751b5d0535088d384b4aa6 (patch)
tree786e46fe1276e93ade0a48398cd4c9ac13081707 /rust/src/ast.rs
parentd6f68e919db51d366c8ca3c1509bea12aa81d692 (diff)
downloadlambda-nantes-7752d73216578d5961751b5d0535088d384b4aa6.tar.gz
Move λ-calcul workshop code to subdirectory
Diffstat (limited to 'rust/src/ast.rs')
-rw-r--r--rust/src/ast.rs117
1 files changed, 0 insertions, 117 deletions
diff --git a/rust/src/ast.rs b/rust/src/ast.rs
deleted file mode 100644
index d0f1d6f..0000000
--- a/rust/src/ast.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-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 {
- Num(i32),
- Bool(bool),
- Sym(String),
- App(Box<Value>, Box<Value>),
- Lam(String, Box<Value>),
- Def(String, Box<Value>),
- Let(String, Box<Value>, Box<Value>),
-}
-
-use Value::*;
-
-impl Value {
- /// Return the spine of an application
- fn spine(&self) -> Vec<Value> {
- match self {
- App(l, r) => {
- let mut spine = l.spine();
- spine.push(*r.clone());
- spine
- }
- _ => vec![self.clone()],
- }
- }
-}
-
-impl Display for Value {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Value::Num(i) => write!(f, "{}", i),
- Value::Bool(b) => write!(f, "{}", b),
- Value::Sym(s) => write!(f, "{}", s),
- Value::App(_, _) => {
- let app = self
- .spine()
- .iter()
- .map(|v| v.to_string())
- .collect::<Vec<String>>()
- .join(" ");
- write!(f, "({})", app)
- }
- Value::Lam(var, body) => write!(f, "(lam {} {})", var, body),
- Value::Def(var, value) => write!(f, "(def {} {})", var, value),
- Value::Let(var, value, body) => write!(f, "(let ({} {}) {})", var, value, body),
- }
- }
-}
-
-pub const IDENTIFIER: &str = "\\pL(\\pL|\\pN)*";
-
-pub fn identifier() -> RegexGeneratorStrategy<String> {
- string_regex(IDENTIFIER).unwrap()
-}
-
-pub fn ascii_identifier() -> RegexGeneratorStrategy<String> {
- string_regex("[a-zA-Z][a-zA-Z0-9]*").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()
- }
-}
-
-#[cfg(test)]
-mod ast_tests {
-
- use super::Value::{self, *};
- use proptest::collection::vec;
- use proptest::prelude::*;
-
- proptest! {
-
- #[test]
- fn display_multiple_applications_as_a_sequence(atoms in vec("[a-z]".prop_map(Sym), 2..10)) {
- let init = atoms.first().unwrap().clone();
- let value = atoms.iter().skip(1).fold(init, |acc, expr| {
- Value::App(Box::new(acc.clone()), Box::new(expr.clone()))
- });
- assert_eq!(value.to_string(),
- format!("({})",
- atoms.iter().map(|v| v.to_string()).collect::<Vec<String>>().join(" ")));
- }
- }
-}