summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
Diffstat (limited to 'rust')
-rw-r--r--rust/src/lambda.rs33
-rw-r--r--rust/src/main.rs9
-rw-r--r--rust/src/parser.rs1
-rw-r--r--rust/tests/interpret_test.rs8
4 files changed, 47 insertions, 4 deletions
diff --git a/rust/src/lambda.rs b/rust/src/lambda.rs
index 97b6f08..416c31e 100644
--- a/rust/src/lambda.rs
+++ b/rust/src/lambda.rs
@@ -1,5 +1,9 @@
use rand::Rng;
-use std::{collections::HashMap, fs::read_to_string};
+use std::{
+ collections::HashMap,
+ fs::read_to_string,
+ io::{BufRead, BufReader, Read, Write},
+};
mod ast;
use ast::*;
@@ -58,6 +62,33 @@ pub fn eval_file(file_name: &str) -> 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();
+ }
+ }
+}
+
fn eval_all(values: &[Value]) -> Vec<Value> {
let mut env = Environment::new();
values.iter().map(|v| eval(v, &mut env)).collect()
diff --git a/rust/src/main.rs b/rust/src/main.rs
index ffd92f2..136e868 100644
--- a/rust/src/main.rs
+++ b/rust/src/main.rs
@@ -1,11 +1,16 @@
-use std::env::args;
+use std::{
+ env::args,
+ io::{stdin, stdout},
+};
-use lambda::eval_file;
+use lambda::{eval_file, repl};
fn main() {
if args().count() > 1 {
for file in args().skip(1) {
println!("{}", eval_file(&file));
}
+ } else {
+ repl(&mut stdin(), &mut stdout());
}
}
diff --git a/rust/src/parser.rs b/rust/src/parser.rs
index b065ec3..23a512b 100644
--- a/rust/src/parser.rs
+++ b/rust/src/parser.rs
@@ -76,7 +76,6 @@ fn parse_definition(parser: &mut Parser) -> Result<Value, String> {
parser.backtrack();
e.to_string()
})?;
- println!("parser {:?}", parser);
let var = parse_variable(parser)?;
let body = parse_expression(parser)?;
parser.expect(Token::RParen)?;
diff --git a/rust/tests/interpret_test.rs b/rust/tests/interpret_test.rs
index 61b0712..40c3ee5 100644
--- a/rust/tests/interpret_test.rs
+++ b/rust/tests/interpret_test.rs
@@ -7,3 +7,11 @@ fn interpreter_can_read_and_interpret_file() {
assert_eq!("1", eval_file("sample/test_normal.txt"));
assert_eq!("13", eval_file("sample/test_let.txt"));
}
+
+#[test]
+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);
+ assert_eq!("> true\n> 12\n> ", String::from_utf8(output).unwrap());
+}