use std::mem::{discriminant, Discriminant}; use crate::{token::Token, cons, ir::{self, BindingScope, Identifier}}; use super::{ParseError, Parsable, WrappedLexer, declaration::Declaration}; #[derive(Debug)] pub struct Program(pub Vec); impl Parsable for Program { fn expected() -> (Vec>, bool) { ( cons(Declaration::expected().0, discriminant(&Token::DeclarationStart)), true ) } fn parse(l: &mut WrappedLexer) -> Result { parse_program_inner(l, Vec::with_capacity(10)).map(Program) } } fn parse_program_inner(l: &mut WrappedLexer, acc: Vec) -> Result, 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) } } impl Program { pub fn gen_ir(self) -> ir::Result> { // We need a first pass to generate a list of all of the identifiers let root_scope = self.0.iter() .enumerate() .filter_map(|(i, decl)| decl.get_identifier(&Identifier::ROOT, i as u32)) .fold(BindingScope::builtins(), |scope, ident| scope.bind_single(ident)); println!("DEBUG {root_scope:?}"); self.0.into_iter() .enumerate() .filter_map(|(i, decl)| decl.gen_ir(&root_scope, i as u32, Identifier::ROOT).transpose()) .collect() } }