pub mod token;
pub mod syntax;
pub mod parser;
pub mod printer;
pub mod loader;
pub use loader::{load_program, load_program_from_str, LoadError};
pub use parser::{parse, ParseError};
pub use printer::print_program;
pub use syntax::*;
pub use token::{lex, LexError, Token, TokenKind};
pub fn parse_source(src: &str) -> Result<Program, SyntaxError> {
let toks = lex(src).map_err(SyntaxError::Lex)?;
parse(toks).map_err(SyntaxError::Parse)
}
pub type FnPositions = std::collections::BTreeMap<String, usize>;
pub fn parse_source_with_positions(src: &str) -> Result<(Program, FnPositions), SyntaxError> {
let toks = lex(src).map_err(SyntaxError::Lex)?;
let mut fn_positions = FnPositions::new();
let mut i = 0;
while i < toks.len() {
if matches!(toks[i].kind, TokenKind::Fn) {
let fn_start = toks[i].span.start;
let mut j = i + 1;
while j < toks.len() {
match &toks[j].kind {
TokenKind::Ident(name) => {
fn_positions.insert(name.clone(), fn_start);
break;
}
TokenKind::Newline => { j += 1; }
_ => break,
}
}
}
i += 1;
}
let program = parse(toks).map_err(SyntaxError::Parse)?;
Ok((program, fn_positions))
}
#[derive(Debug, thiserror::Error)]
pub enum SyntaxError {
#[error(transparent)]
Lex(#[from] LexError),
#[error(transparent)]
Parse(#[from] ParseError),
}