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