From 2ad36af41d237f3fb4be4d8ed0c78cf227612ea3 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Sat, 23 Oct 2021 20:30:31 -0700 Subject: simplify s-expr enum, to make other parsing easier as well --- src/cexpr.rs | 20 +++++++++----------- src/sexpr.rs | 41 ++++++++--------------------------------- 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::, 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::, 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::, 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), } @@ -130,23 +121,18 @@ fn sexpr_parse_token(token: &str) -> Result { // 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::() { Ok(x) => return Ok(SExpr::SInteger(x)), Err(_) => () } - // Try to parse as a number + // Try to parse as floating-point number match token.parse::() { Ok(x) => return Ok(SExpr::SFloat(x)), Err(_) => () @@ -157,15 +143,6 @@ fn sexpr_parse_token(token: &str) -> Result { 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, usize) */ pub fn sexpr_repr(ast: &SExpr) -> Result { 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 = list.iter().map(|ref el| sexpr_repr(&el).unwrap()).collect(); -- cgit v1.2.3