summaryrefslogtreecommitdiff
path: root/rust/src/lambda.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/lambda.rs')
-rw-r--r--rust/src/lambda.rs35
1 files changed, 21 insertions, 14 deletions
diff --git a/rust/src/lambda.rs b/rust/src/lambda.rs
index a6da87b..41c0c26 100644
--- a/rust/src/lambda.rs
+++ b/rust/src/lambda.rs
@@ -7,12 +7,15 @@ use ast::*;
mod parser;
use parser::*;
-pub fn run(arg: &str) -> String {
- let content = read_to_string(arg).unwrap();
- let value = parse(&content.to_string());
- let result = eval(&value);
-
- result.to_string()
+pub fn eval_file(file_name: &str) -> String {
+ let content = read_to_string(file_name).unwrap();
+ let values = parse(&content.to_string());
+ values
+ .iter()
+ .map(eval)
+ .map(|v| v.to_string())
+ .collect::<Vec<String>>()
+ .join(" ")
}
fn eval(arg: &Value) -> Value {
@@ -73,27 +76,31 @@ fn gensym() -> String {
mod lambda_test {
use crate::{eval, parse, Value};
+ fn parse1(string: &str) -> Value {
+ parse(string).pop().unwrap()
+ }
+
#[test]
fn evaluating_a_non_reducible_value_yields_itself() {
- let value = parse("(foo 12)");
+ let value = parse1("(foo 12)");
assert_eq!(value, eval(&value));
}
#[test]
fn evaluating_application_on_an_abstraction_reduces_it() {
- let value = parse("((lam x x) 12)");
+ let value = parse1("((lam x x) 12)");
assert_eq!(Value::Num(12), eval(&value));
}
#[test]
fn substitution_occurs_within_abstraction_body() {
- let value = parse("(((lam x (lam y x)) 13) 12)");
+ let value = parse1("(((lam x (lam y x)) 13) 12)");
assert_eq!(Value::Num(13), eval(&value));
}
#[test]
fn substitution_occurs_within_application_body() {
- let value = parse("(((lam x (lam y (y x))) 13) 12)");
+ let value = parse1("(((lam x (lam y (y x))) 13) 12)");
assert_eq!(
Value::App(Box::new(Value::Num(12)), Box::new(Value::Num(13))),
eval(&value)
@@ -102,26 +109,26 @@ mod lambda_test {
#[test]
fn substitution_does_not_capture_free_variables() {
- let value = parse("(((lam x (lam x x)) 13) 12)");
+ let value = parse1("(((lam x (lam x x)) 13) 12)");
assert_eq!(Value::Num(12), eval(&value));
}
#[test]
fn interpretation_applies_to_both_sides_of_application() {
- let value = parse("((lam x x) ((lam x x) 12))");
+ let value = parse1("((lam x x) ((lam x x) 12))");
assert_eq!(Value::Num(12), eval(&value));
}
#[test]
fn reduction_is_applied_until_normal_form_is_reached() {
- let value = parse("((((lam y (lam x (lam y (x y)))) 13) (lam x x)) 11)");
+ let value = parse1("((((lam y (lam x (lam y (x y)))) 13) (lam x x)) 11)");
assert_eq!(Value::Num(11), eval(&value));
}
#[test]
fn reduction_always_select_leftmost_outermost_redex() {
// this should not terminate if we evaluate the rightmost redex first
- let value = parse("((lam x 1) ((lam x (x x)) (lam x (x x))))");
+ let value = parse1("((lam x 1) ((lam x (x x)) (lam x (x x))))");
assert_eq!(Value::Num(1), eval(&value));
}
}