use crate::lexer::Token; use crate::lexer::Tokens; #[derive(Debug, Clone)] pub enum Datum { Boolean(bool), Number(i64), Symbol(String), List(Vec), Procedure(fn(Vec) -> Datum), Unspecified, } pub fn make_symbol(s: &str) -> Datum { Datum::Symbol(s.to_string()) } impl Default for Datum { fn default() -> Self { Datum::Unspecified } } pub fn parse(tokens: Tokens) -> Datum { let (datum, _) = parse_datum(&tokens, 0); datum } fn parse_datum(tokens: &Tokens, ix: usize) -> (Datum, usize) { match &tokens[ix] { Token::Identifier(s) => (Datum::Symbol(s.to_string()), ix + 1), Token::Boolean(b) => (Datum::Boolean(*b), ix + 1), Token::Number(n) => (Datum::Number(*n), ix + 1), Token::LeftRoundBracket => parse_list(tokens, ix + 1), _ => panic!("Unexpected token {:?}", tokens[ix]), } } pub fn parse_list(tokens: &Tokens, mut ix: usize) -> (Datum, usize) { let mut datums = vec![]; while ix < tokens.len() && tokens[ix] != Token::RightRoundBracket { let (datum, new_ix) = parse_datum(tokens, ix); datums.push(datum); ix = new_ix; } if ix == tokens.len() { panic!("PARSE_LIST -- missing closing bracket {:?}", tokens) } (Datum::List(datums), ix + 1) }