35 lines
954 B
Rust
35 lines
954 B
Rust
|
use std::mem::{discriminant, Discriminant};
|
||
|
|
||
|
use crate::{token::Token, cons};
|
||
|
|
||
|
use super::{ParseError, Parsable, WrappedLexer, declaration::Declaration};
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Program(pub Vec<Declaration>);
|
||
|
|
||
|
impl Parsable for Program {
|
||
|
fn expected() -> (Vec<Discriminant<Token>>, bool) {
|
||
|
(
|
||
|
cons(Declaration::expected().0, discriminant(&Token::DeclarationStart)),
|
||
|
true
|
||
|
)
|
||
|
}
|
||
|
|
||
|
fn parse(l: &mut WrappedLexer) -> Result<Self, ParseError> {
|
||
|
parse_program_inner(l, Vec::with_capacity(10)).map(Program)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn parse_program_inner(l: &mut WrappedLexer, acc: Vec<Declaration>) -> Result<Vec<Declaration>, ParseError> {
|
||
|
if *l.curtok() == Token::DeclarationStart {
|
||
|
l.monch();
|
||
|
parse_program_inner(l, acc)
|
||
|
} else if Declaration::matches(l.curtok()) {
|
||
|
let acc = cons(acc, Declaration::parse(l)?);
|
||
|
parse_program_inner(l, acc)
|
||
|
} else {
|
||
|
eprintln!("Looking for a declaration but got {:?} at {:?}", *l.curtok(), l.span());
|
||
|
Ok(acc)
|
||
|
}
|
||
|
}
|