1pub mod token;
6pub mod syntax;
7pub mod parser;
8pub mod printer;
9pub mod loader;
10
11pub use loader::{load_program, load_program_from_str, LoadError};
12pub use parser::{parse, ParseError};
13pub use printer::print_program;
14pub use syntax::*;
15pub use token::{lex, LexError, Token, TokenKind};
16
17pub fn parse_source(src: &str) -> Result<Program, SyntaxError> {
19 let toks = lex(src).map_err(SyntaxError::Lex)?;
20 parse(toks).map_err(SyntaxError::Parse)
21}
22
23pub type FnPositions = std::collections::BTreeMap<String, usize>;
27
28pub fn parse_source_with_positions(src: &str) -> Result<(Program, FnPositions), SyntaxError> {
33 let toks = lex(src).map_err(SyntaxError::Lex)?;
34 let mut fn_positions = FnPositions::new();
40 let mut i = 0;
41 while i < toks.len() {
42 if matches!(toks[i].kind, TokenKind::Fn) {
43 let fn_start = toks[i].span.start;
44 let mut j = i + 1;
46 while j < toks.len() {
47 match &toks[j].kind {
48 TokenKind::Ident(name) => {
49 fn_positions.insert(name.clone(), fn_start);
50 break;
51 }
52 TokenKind::Newline => { j += 1; }
53 _ => break,
54 }
55 }
56 }
57 i += 1;
58 }
59 let program = parse(toks).map_err(SyntaxError::Parse)?;
60 Ok((program, fn_positions))
61}
62
63#[derive(Debug, thiserror::Error)]
64pub enum SyntaxError {
65 #[error(transparent)]
66 Lex(#[from] LexError),
67 #[error(transparent)]
68 Parse(#[from] ParseError),
69}