aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bin/casual.rs (renamed from src/main.rs)35
-rw-r--r--src/cexpr.rs4
-rw-r--r--src/lib.rs34
-rw-r--r--tests/canonicalize.rs26
-rw-r--r--tests/things.txt35
5 files changed, 99 insertions, 35 deletions
diff --git a/src/main.rs b/src/bin/casual.rs
index f09e0f0..828c4b6 100644
--- a/src/main.rs
+++ b/src/bin/casual.rs
@@ -1,38 +1,7 @@
use std::env;
-use std::io;
-use std::io::Write;
use std::path::Path;
-mod cexpr;
-mod sexpr;
-
-use cexpr::CExpr;
-
-fn repl(_verbose: bool) {
- let stdin = io::stdin();
- let mut stdout = io::stdout();
-
- loop {
- let raw_input = &mut String::new();
- stdout.write(b"\ncasual> ").unwrap();
- stdout.flush().unwrap();
- stdin.read_line(raw_input).unwrap();
- let raw_input = raw_input; // mutable to immutable reference
- if raw_input.len() == 0 {
- // end-of-line, aka Ctrl-D. Blank line will still have newline char
- stdout.write(b"\nCiao!\n").unwrap();
- return;
- }
- let expr = match CExpr::from_str(&raw_input) {
- Ok(expr) => expr,
- Err(e) => {
- println!("error: {}", e);
- continue;
- }
- };
- println!("{}", expr);
- }
-}
+use casual::{repl, sexpr_parse_file};
fn usage() {
println!("usage:\tcasual [-h] [-v] [--no-repl] [<files>]");
@@ -81,7 +50,7 @@ fn main() {
return;
}
println!("Loading {}...", fname);
- match sexpr::sexpr_parse_file(&fpath) {
+ match sexpr_parse_file(&fpath) {
Err(e) => {
println!("Error loading file: {}\n {}", fname, e);
return;
diff --git a/src/cexpr.rs b/src/cexpr.rs
index b183c4a..357caff 100644
--- a/src/cexpr.rs
+++ b/src/cexpr.rs
@@ -37,7 +37,7 @@ impl NumericConstant {
}
}
-#[derive(Clone, PartialEq, PartialOrd)]
+#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub enum CNumber {
// order here is important for sorting, etc
Integer(i64),
@@ -99,7 +99,7 @@ impl CNumber {
}
}
-#[derive(Clone, PartialEq, PartialOrd)]
+#[derive(Clone, PartialEq, PartialOrd, Debug)]
pub enum CExpr {
// order here is important for sorting, etc
Number(CNumber),
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..950329b
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,34 @@
+use std::io;
+use std::io::Write;
+
+mod cexpr;
+mod sexpr;
+
+pub use cexpr::{CExpr, CNumber};
+pub use sexpr::{sexpr_parse_file, SExpr};
+
+pub fn repl(_verbose: bool) {
+ let stdin = io::stdin();
+ let mut stdout = io::stdout();
+
+ loop {
+ let raw_input = &mut String::new();
+ stdout.write(b"\ncasual> ").unwrap();
+ stdout.flush().unwrap();
+ stdin.read_line(raw_input).unwrap();
+ let raw_input = raw_input; // mutable to immutable reference
+ if raw_input.len() == 0 {
+ // end-of-line, aka Ctrl-D. Blank line will still have newline char
+ stdout.write(b"\nCiao!\n").unwrap();
+ return;
+ }
+ let expr = match CExpr::from_str(&raw_input) {
+ Ok(expr) => expr,
+ Err(e) => {
+ println!("error: {}", e);
+ continue;
+ }
+ };
+ println!("{}", expr);
+ }
+}
diff --git a/tests/canonicalize.rs b/tests/canonicalize.rs
new file mode 100644
index 0000000..3ef088a
--- /dev/null
+++ b/tests/canonicalize.rs
@@ -0,0 +1,26 @@
+use casual::{CExpr, CNumber};
+
+#[test]
+fn basics() {
+ assert_eq!(
+ CExpr::from_str("(+ 1 2 3)").unwrap(),
+ CExpr::Number(CNumber::Integer(6)),
+ );
+}
+
+#[test]
+fn canonicalization() {
+ let cases = vec![
+ ("(+ (+ a 2) (+ b 2))", "(+ 4 a b)"),
+ ("(+ (+ a 2) (+ b 2))", "(+ 4 a b)"),
+ ("(+ 1 2 b)", "(+ 3 b)"),
+ ("(+ 1 2 3)", "6"),
+ ("(* (/ 2 3) (/ 3 2))", "1"),
+ ];
+
+ for (input, output) in cases.iter() {
+ assert_eq!(CExpr::from_str(input).unwrap().to_string(), *output);
+ }
+}
+
+// TODO: helper to read an examples file, as pairs of rows
diff --git a/tests/things.txt b/tests/things.txt
new file mode 100644
index 0000000..f525f6e
--- /dev/null
+++ b/tests/things.txt
@@ -0,0 +1,35 @@
+
+(+ (+ a 2) (+ b 2))
+(+ 4 a b)
+
+(+ 1 2 b)
+(+ 3 b)
+
+(+ 1 2 3)
+6
+
+(* (/ 2 3) (/ 3 2))
+1
+
+# TODO
+(* (/ -2 3) (/ 3 2))
+-1
+
+
+(* (* a b 1) (* c d))
+(* a b c d)
+
+(+ (+ a b) (+ c d))
+(+ a b c d)
+
+(+ (+ a b 1) (+ c d 3))
+(+ 4 a b c d)
+
+(^ 4 -1)
+(/ 1 4)
+
+(^ (/ 2 3) -1)
+(/ 3 2)
+
+(^ (/ 1 3) -1)
+3