Files
schemers/src/parser.rs

53 lines
1.3 KiB
Rust

use crate::lexer::Token;
use crate::lexer::Tokens;
#[derive(Debug, Clone)]
pub enum Datum {
Boolean(bool),
Number(i64),
Symbol(String),
List(Vec<Datum>),
Procedure(fn(Vec<Datum>) -> 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)
}