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