summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/Cargo.toml2
-rw-r--r--rust/sample/test_let.txt1
-rw-r--r--rust/src/io.rs47
-rw-r--r--rust/src/lambda.rs61
-rw-r--r--rust/src/lib.rs4
-rw-r--r--rust/src/main.rs2
-rw-r--r--rust/src/parser.rs2
-rw-r--r--rust/tests/interpret_test.rs4
8 files changed, 69 insertions, 54 deletions
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index bb52045..442a9ac 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -11,7 +11,7 @@ proptest = "1.0.0"
[lib]
name = "lambda"
-path = "src/lambda.rs"
+path = "src/lib.rs"
[[bin]]
name = "lambda"
diff --git a/rust/sample/test_let.txt b/rust/sample/test_let.txt
new file mode 100644
index 0000000..6027cd0
--- /dev/null
+++ b/rust/sample/test_let.txt
@@ -0,0 +1 @@
+(let (foo (lam x x)) ((let (foo foo) foo) 13))
diff --git a/rust/src/io.rs b/rust/src/io.rs
new file mode 100644
index 0000000..33d8c4e
--- /dev/null
+++ b/rust/src/io.rs
@@ -0,0 +1,47 @@
+use std::{
+ fs::read_to_string,
+ io::{BufRead, BufReader, Read, Write},
+};
+
+use crate::{
+ ast::Value,
+ lambda::{eval, eval_all, Environment},
+ parser::parse,
+};
+
+pub fn eval_file(file_name: &str) -> String {
+ let content = read_to_string(file_name).unwrap();
+ let values = parse(&content.to_string());
+ eval_all(&values)
+ .iter()
+ .map(|v| v.to_string())
+ .collect::<Vec<String>>()
+ .join(" ")
+}
+
+pub fn repl<I: Read, O: Write>(inp: &mut I, outp: &mut O) {
+ let mut env = Environment::new();
+ let mut reader = BufReader::new(inp);
+ loop {
+ let mut input = String::new();
+ write!(outp, "> ").unwrap();
+ outp.flush().unwrap();
+ match reader.read_line(&mut input) {
+ Ok(0) => break,
+ Ok(_) => (),
+ Err(e) => {
+ writeln!(outp, "{}", e).unwrap();
+ break;
+ }
+ }
+ let values = parse(&input);
+ let results = values
+ .iter()
+ .map(|v| eval(v, &mut env))
+ .collect::<Vec<Value>>();
+ for result in results {
+ writeln!(outp, "{}", result).unwrap();
+ outp.flush().unwrap();
+ }
+ }
+}
diff --git a/rust/src/lambda.rs b/rust/src/lambda.rs
index 5dbcdb2..2586de6 100644
--- a/rust/src/lambda.rs
+++ b/rust/src/lambda.rs
@@ -1,24 +1,16 @@
use rand::Rng;
-use std::{
- collections::HashMap,
- fs::read_to_string,
- io::{BufRead, BufReader, Read, Write},
-};
+use std::collections::HashMap;
-mod ast;
-use ast::*;
-
-mod parser;
-use parser::*;
+use crate::ast::*;
#[derive(Debug, PartialEq)]
-struct Environment<'a> {
+pub struct Environment<'a> {
parent: Box<Option<&'a Environment<'a>>>,
bindings: HashMap<String, Value>,
}
impl<'a> Environment<'a> {
- fn new() -> Self {
+ pub fn new() -> Self {
Environment {
parent: Box::new(None),
bindings: HashMap::new(),
@@ -52,49 +44,18 @@ impl<'a> Environment<'a> {
}
}
-pub fn eval_file(file_name: &str) -> String {
- let content = read_to_string(file_name).unwrap();
- let values = parse(&content.to_string());
- eval_all(&values)
- .iter()
- .map(|v| v.to_string())
- .collect::<Vec<String>>()
- .join(" ")
-}
-
-pub fn repl<I: Read, O: Write>(inp: &mut I, outp: &mut O) {
- let mut env = Environment::new();
- let mut reader = BufReader::new(inp);
- loop {
- let mut input = String::new();
- write!(outp, "> ").unwrap();
- outp.flush().unwrap();
- match reader.read_line(&mut input) {
- Ok(0) => break,
- Ok(_) => (),
- Err(e) => {
- writeln!(outp, "{}", e).unwrap();
- break;
- }
- }
- let values = parse(&input);
- let results = values
- .iter()
- .map(|v| eval(v, &mut env))
- .collect::<Vec<Value>>();
- for result in results {
- writeln!(outp, "{}", result).unwrap();
- outp.flush().unwrap();
- }
+impl<'a> Default for Environment<'a> {
+ fn default() -> Self {
+ Self::new()
}
}
-fn eval_all(values: &[Value]) -> Vec<Value> {
+pub fn eval_all(values: &[Value]) -> Vec<Value> {
let mut env = Environment::new();
values.iter().map(|v| eval(v, &mut env)).collect()
}
-fn eval(arg: &Value, env: &mut Environment) -> Value {
+pub fn eval(arg: &Value, env: &mut Environment) -> Value {
match arg {
Value::Def(var, value) => {
env.bind(var, value);
@@ -162,7 +123,9 @@ fn gensym() -> String {
#[cfg(test)]
mod lambda_test {
- use crate::{eval, eval_all, parse, Environment, Value};
+ use crate::parser::parse;
+
+ use super::{eval, eval_all, Environment, Value};
fn parse1(string: &str) -> Value {
parse(string).pop().unwrap()
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
new file mode 100644
index 0000000..a8cf18e
--- /dev/null
+++ b/rust/src/lib.rs
@@ -0,0 +1,4 @@
+pub mod ast;
+pub mod io;
+pub mod lambda;
+pub mod parser;
diff --git a/rust/src/main.rs b/rust/src/main.rs
index 136e868..b0e8ed9 100644
--- a/rust/src/main.rs
+++ b/rust/src/main.rs
@@ -3,7 +3,7 @@ use std::{
io::{stdin, stdout},
};
-use lambda::{eval_file, repl};
+use lambda::io::{eval_file, repl};
fn main() {
if args().count() > 1 {
diff --git a/rust/src/parser.rs b/rust/src/parser.rs
index 121a10f..2a5fef4 100644
--- a/rust/src/parser.rs
+++ b/rust/src/parser.rs
@@ -235,7 +235,7 @@ fn parse_number(token: &Token) -> Result<Value, String> {
#[cfg(test)]
mod tests {
- use crate::parse_total;
+ use super::parse_total;
use super::Token::*;
use super::Value;
diff --git a/rust/tests/interpret_test.rs b/rust/tests/interpret_test.rs
index 40c3ee5..0ca3356 100644
--- a/rust/tests/interpret_test.rs
+++ b/rust/tests/interpret_test.rs
@@ -1,4 +1,4 @@
-use lambda::eval_file;
+use lambda::io::{eval_file, repl};
#[test]
fn interpreter_can_read_and_interpret_file() {
@@ -12,6 +12,6 @@ fn interpreter_can_read_and_interpret_file() {
fn repl_can_read_and_interpret_input() {
let input = "(def id (lam x x))\n(id 12)";
let mut output = Vec::new();
- lambda::repl(&mut input.as_bytes(), &mut output);
+ repl(&mut input.as_bytes(), &mut output);
assert_eq!("> true\n> 12\n> ", String::from_utf8(output).unwrap());
}