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