summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/src/ast.rs18
-rw-r--r--rust/src/lambda.rs36
-rw-r--r--rust/src/main.rs2
-rw-r--r--rust/src/parser.rs27
4 files changed, 54 insertions, 29 deletions
diff --git a/rust/src/ast.rs b/rust/src/ast.rs
new file mode 100644
index 0000000..b179704
--- /dev/null
+++ b/rust/src/ast.rs
@@ -0,0 +1,18 @@
+use std::fmt::{self, Display};
+
+#[derive(Debug, PartialEq)]
+pub enum Value {
+ Num(i32),
+ Bool(bool),
+ Sym(String),
+}
+
+impl Display for Value {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Value::Num(i) => write!(f, "{}", i),
+ Value::Bool(b) => write!(f, "{}", b),
+ Value::Sym(s) => write!(f, "{}", s),
+ }
+ }
+}
diff --git a/rust/src/lambda.rs b/rust/src/lambda.rs
index 8c4c640..18568d7 100644
--- a/rust/src/lambda.rs
+++ b/rust/src/lambda.rs
@@ -1,7 +1,10 @@
-use std::{
- fmt::{self, Display},
- fs::read_to_string,
-};
+use std::fs::read_to_string;
+
+mod ast;
+use ast::*;
+
+mod parser;
+use parser::*;
pub fn run(arg: &str) -> String {
let content = read_to_string(arg).unwrap();
@@ -10,30 +13,9 @@ pub fn run(arg: &str) -> String {
result.to_string()
}
-#[derive(Debug, PartialEq)]
-pub enum Value {
- Num(i32),
- Bool(bool),
- Sym(String),
-}
-
-impl Display for Value {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Value::Num(i) => write!(f, "{}", i),
- Value::Bool(b) => write!(f, "{}", b),
- Value::Sym(s) => write!(f, "{}", s),
- }
- }
-}
-
fn interpret(arg: &str) -> Value {
- let token = arg.trim();
- token
- .parse::<i32>()
- .map(Value::Num)
- .or(token.parse::<bool>().map(Value::Bool))
- .unwrap_or(Value::Sym(token.to_string()))
+ // interpreting a value is the value itself
+ parse(arg)
}
#[cfg(test)]
diff --git a/rust/src/main.rs b/rust/src/main.rs
index b6cc9bf..f401886 100644
--- a/rust/src/main.rs
+++ b/rust/src/main.rs
@@ -2,8 +2,6 @@ use std::env::args;
use lambda::run;
-mod lambda;
-
fn main() {
run(&args().nth(1).unwrap());
}
diff --git a/rust/src/parser.rs b/rust/src/parser.rs
new file mode 100644
index 0000000..d5d4c30
--- /dev/null
+++ b/rust/src/parser.rs
@@ -0,0 +1,27 @@
+use crate::ast::*;
+
+pub fn parse(arg: &str) -> Value {
+ let token = arg.trim();
+ parse_number(token)
+ .or(parse_bool(token))
+ .or(parse_symbol(token))
+ .unwrap()
+}
+
+fn parse_symbol(token: &str) -> Result<Value, String> {
+ Ok(Value::Sym(token.to_string()))
+}
+
+fn parse_bool(token: &str) -> Result<Value, String> {
+ token
+ .parse::<bool>()
+ .map(Value::Bool)
+ .map_err(|e| e.to_string())
+}
+
+fn parse_number(token: &str) -> Result<Value, String> {
+ token
+ .parse::<i32>()
+ .map(Value::Num)
+ .map_err(|e| e.to_string())
+}