summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src')
-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
5 files changed, 65 insertions, 51 deletions
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;