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