5 changed files with 125 additions and 124 deletions
@ -1,97 +0,0 @@
|
||||
pub mod tki; |
||||
pub mod tok; |
||||
|
||||
use self::{ |
||||
tki::TokenIter, |
||||
tok::{Token, Type::*}, |
||||
}; |
||||
use super::Cell; |
||||
use crate::types::sym; |
||||
|
||||
#[derive(thiserror::Error, Debug)] |
||||
pub enum Err { |
||||
#[error(transparent)] |
||||
Iter(#[from] tki::Err), |
||||
#[error(transparent)] |
||||
Symb(#[from] sym::SymbolOverflowError), |
||||
} |
||||
|
||||
pub fn parse( |
||||
tki: &mut TokenIter, syms: &mut sym::SymbolTable, |
||||
) -> Result<Vec<Cell>, Err> { |
||||
let mut cells = Vec::new(); |
||||
|
||||
while tki.peek().is_some() { |
||||
cells.push(cell(tki, syms)?); |
||||
} |
||||
|
||||
Ok(cells) |
||||
} |
||||
|
||||
fn cell( |
||||
tki: &mut TokenIter, syms: &mut sym::SymbolTable, |
||||
) -> Result<Cell, Err> { |
||||
match tki.err_next()? { |
||||
// atoms
|
||||
| Token { typ: Bool, cel, .. } |
||||
| Token { typ: Char, cel, .. } |
||||
| Token { typ: Numb, cel, .. } |
||||
| Token { typ: Strn, cel, .. } => Ok(cel), |
||||
| Token { typ: Symb, cel: Cell::Strn(s), .. } => { |
||||
Ok(Cell::Symb(syms.intern(s)?)) |
||||
} |
||||
|
||||
// lists
|
||||
| Token { typ: Br1O, .. } => list(tki, syms, Br1C), |
||||
| Token { typ: Br3O, .. } => list(tki, syms, Br3C), |
||||
|
||||
// abbreviations
|
||||
| Token { typ: QQuo, .. } => abbrev(tki, syms, "quasiquote"), |
||||
| Token { typ: QSyn, .. } => abbrev(tki, syms, "quasisyntax"), |
||||
| Token { typ: Quot, .. } => abbrev(tki, syms, "quote"), |
||||
| Token { typ: Synt, .. } => abbrev(tki, syms, "syntax"), |
||||
| Token { typ: UnQS, .. } => abbrev(tki, syms, "unquote-splicing"), |
||||
| Token { typ: UnQu, .. } => abbrev(tki, syms, "unquote"), |
||||
| Token { typ: UnSS, .. } => abbrev(tki, syms, "unsyntax-splicing"), |
||||
| Token { typ: UnSy, .. } => abbrev(tki, syms, "unsyntax"), |
||||
|
||||
| Token { typ, pos, .. } => Err(tki::Err::Unexpected(typ, pos).into()), |
||||
} |
||||
} |
||||
|
||||
fn abbrev( |
||||
tki: &mut TokenIter, syms: &mut sym::SymbolTable, name: &'static str, |
||||
) -> Result<Cell, Err> { |
||||
let cdr = { |
||||
let cdr = Box::new(Cell::Null); |
||||
let car = Box::new(cell(tki, syms)?); |
||||
Box::new(Cell::Cons { cdr, car }) |
||||
}; |
||||
let car = Box::new(Cell::Symb(syms.intern(name)?)); |
||||
Ok(Cell::Cons { cdr, car }) |
||||
} |
||||
|
||||
fn list( |
||||
tki: &mut TokenIter, syms: &mut sym::SymbolTable, end: tok::Type, |
||||
) -> Result<Cell, Err> { |
||||
let mut data_v = Vec::new(); |
||||
let mut cdr = Cell::Null; |
||||
|
||||
while !tki.drop(end)? { |
||||
if tki.drop(Peri)? { |
||||
cdr = cell(tki, syms)?; |
||||
tki.expect(end)?; |
||||
break; |
||||
} else { |
||||
data_v.push(cell(tki, syms)?); |
||||
} |
||||
} |
||||
|
||||
for car in data_v.into_iter().rev() { |
||||
cdr = Cell::Cons { car: Box::new(car), cdr: Box::new(cdr) }; |
||||
} |
||||
|
||||
Ok(cdr) |
||||
} |
||||
|
||||
// EOF
|
Loading…
Reference in new issue