aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Newbold <bnewbold@robocracy.org>2021-10-23 20:30:31 -0700
committerBryan Newbold <bnewbold@robocracy.org>2021-10-23 20:30:31 -0700
commit2ad36af41d237f3fb4be4d8ed0c78cf227612ea3 (patch)
tree9b869a586dd726782e204253f98827330baf1424
parent410af116fe02f515a1741612721ccca41f187b45 (diff)
downloadcasual-2ad36af41d237f3fb4be4d8ed0c78cf227612ea3.tar.gz
casual-2ad36af41d237f3fb4be4d8ed0c78cf227612ea3.zip
simplify s-expr enum, to make other parsing easier as well
-rw-r--r--src/cexpr.rs20
-rw-r--r--src/sexpr.rs41
2 files changed, 17 insertions, 44 deletions
diff --git a/src/cexpr.rs b/src/cexpr.rs
index bac316c..5014f74 100644
--- a/src/cexpr.rs
+++ b/src/cexpr.rs
@@ -26,7 +26,7 @@ impl CNumber {
match self {
CNumber::Integer(v) => Ok(SExpr::SInteger(*v)),
CNumber::Rational(a, b) => Ok(SExpr::SList(vec![
- SExpr::SBuiltin("/".to_string()),
+ SExpr::SIdentifier("/".to_string()),
SExpr::SInteger(*a),
SExpr::SInteger(*b as i64),
])),
@@ -56,13 +56,11 @@ impl CExpr {
// not all cases are handled; some atoms are covered trivialy
match sexpr {
SExpr::SNull => Err("null not handled".to_string()),
- SExpr::STrue | SExpr::SFalse => Err("booleans not handled".to_string()),
+ SExpr::SBoolean(_) => Err("booleans not handled".to_string()),
SExpr::SInteger(v) => Ok(CExpr::Number(CNumber::Integer(*v))),
SExpr::SFloat(v) => Err("floats not handled".to_string()),
- SExpr::SBuiltin(v) => Ok(CExpr::Symbol(v.to_string())),
- SExpr::SSymbol(v) => Err(format!("symbols (quoted identifiers) not handled: {}", v)),
- SExpr::SIdentifier(v) => Ok(CExpr::Symbol(v.to_string())),
SExpr::SString(_) => Err("null not handled".to_string()),
+ SExpr::SIdentifier(v) => Ok(CExpr::Symbol(v.to_string())),
SExpr::SList(_) => Err("null not handled".to_string()),
//SExpr::SList(l) => CExpr::from_sexpr_list(l),
}
@@ -74,16 +72,16 @@ impl CExpr {
unimplemented!()
}
match list[0] {
- SExpr::SBuiltin("+") => {
+ SExpr::SIdentifier("+") => {
Ok(CExpr::Sum(
// XXX
None,
list[1..].iter().map(|v| CExpr::from_sexpr(v)).collect::<Result<Vec<SExpr>, String>>()?,
))
},
- SExpr::SBuiltin("*") => {
+ SExpr::SIdentifier("*") => {
},
- SExpr::SBuiltin("^") => {
+ SExpr::SIdentifier("^") => {
},
_ => {
unimplemented!()
@@ -105,17 +103,17 @@ impl CExpr {
CExpr::Symbol(s) => Ok(SExpr::SIdentifier(s.to_string())),
CExpr::Number(n) => n.to_sexpr(),
CExpr::Sum(n, l) => Ok(SExpr::SList(vec![
- SExpr::SBuiltin("+".to_string()),
+ SExpr::SIdentifier("+".to_string()),
SExpr::SList(l.iter().map(|v| v.to_sexpr()).collect::<Result<Vec<SExpr>, String>>()?),
// XXX: n
])),
CExpr::Product(n, l) => Ok(SExpr::SList(vec![
- SExpr::SBuiltin("*".to_string()),
+ SExpr::SIdentifier("*".to_string()),
SExpr::SList(l.iter().map(|v| v.to_sexpr()).collect::<Result<Vec<SExpr>, String>>()?),
// XXX: n
])),
CExpr::Power(a, b) => Ok(SExpr::SList(vec![
- SExpr::SBuiltin("^".to_string()),
+ SExpr::SIdentifier("^".to_string()),
a.to_sexpr()?,
b.to_sexpr()?,
])),
diff --git a/src/sexpr.rs b/src/sexpr.rs
index da1012e..ea07bf9 100644
--- a/src/sexpr.rs
+++ b/src/sexpr.rs
@@ -16,23 +16,14 @@ use std::path::Path;
//////////// Types and Constants
-const SEXPR_BUILTINS: [&'static str; 15] = [
- "=", ">", ">=", "<", "<=",
- "+", "-", "*", "/", "^",
- "exp", "log", "sin", "cos", "tan",
- ];
-
#[derive(Clone, PartialEq)]
pub enum SExpr {
SNull,
- STrue,
- SFalse,
+ SBoolean(bool),
SInteger(i64),
SFloat(f64),
- SBuiltin(String),
- SSymbol(String),
- SIdentifier(String),
SString(String),
+ SIdentifier(String),
SList(Vec<SExpr>),
}
@@ -130,23 +121,18 @@ fn sexpr_parse_token(token: &str) -> Result<SExpr, String> {
// Is it a constant?
match token {
- "#t" => return Ok(SExpr::STrue),
- "#f" => return Ok(SExpr::SFalse),
+ "#t" => return Ok(SExpr::SBoolean(true)),
+ "#f" => return Ok(SExpr::SBoolean(false)),
_ => ()
}
- // Is it a builtin?
- if SEXPR_BUILTINS.contains(&token) {
- return Ok(SExpr::SBuiltin(token.to_string()));
- }
-
// Try to parse as an integer
match token.parse::<i64>() {
Ok(x) => return Ok(SExpr::SInteger(x)),
Err(_) => ()
}
- // Try to parse as a number
+ // Try to parse as floating-point number
match token.parse::<f64>() {
Ok(x) => return Ok(SExpr::SFloat(x)),
Err(_) => ()
@@ -157,15 +143,6 @@ fn sexpr_parse_token(token: &str) -> Result<SExpr, String> {
return Ok(SExpr::SString(token.to_string()));
}
- // Is it a quoted literal?
- if token.starts_with("'") && token.len() > 1 {
- match sexpr_parse_token(&token[1..]) {
- Ok(SExpr::SIdentifier(t)) => return Ok(SExpr::SSymbol(t)),
- Ok(e) => return Ok(e),
- _ => {},
- }
- }
-
// Else, we'll treat it as an identifier
if is_valid_identifier(token) {
return Ok(SExpr::SIdentifier(token.to_string()));
@@ -232,14 +209,12 @@ pub fn sexpr_parse(tokens: &Vec<&str>, depth: u32) -> Result<(Vec<SExpr>, usize)
*/
pub fn sexpr_repr(ast: &SExpr) -> Result<String, String> {
return match ast {
- &SExpr::STrue => Ok("#t".to_string()),
- &SExpr::SFalse => Ok("#f".to_string()),
- &SExpr::SNull => Ok("'()".to_string()), // TODO: just () ?
+ &SExpr::SNull => Ok("()".to_string()),
+ &SExpr::SBoolean(true) => Ok("#t".to_string()),
+ &SExpr::SBoolean(false) => Ok("#f".to_string()),
&SExpr::SInteger(num) => Ok(format!("{}", num).to_string()),
&SExpr::SFloat(num) => Ok(format!("{}", num).to_string()),
- &SExpr::SBuiltin(ref b)=> Ok(b.clone()),
&SExpr::SString(ref s)=> Ok(s.clone()),
- &SExpr::SSymbol(ref s)=> Ok(s.clone()),
&SExpr::SIdentifier(ref s)=> Ok(s.to_string()),
&SExpr::SList(ref list) => {
let elements: Vec<String> = list.iter().map(|ref el| sexpr_repr(&el).unwrap()).collect();