Skip to main content

aver/
source.rs

1use std::path::{Path, PathBuf};
2
3use crate::ast::TopLevel;
4use crate::lexer::Lexer;
5use crate::parser::Parser;
6
7pub fn parse_source(source: &str) -> Result<Vec<TopLevel>, String> {
8    let mut lexer = Lexer::new(source);
9    let tokens = lexer.tokenize().map_err(|e| e.to_string())?;
10    let mut parser = Parser::new(tokens);
11    parser.parse().map_err(|e| e.to_string())
12}
13
14pub fn find_module_file(name: &str, module_root: &str) -> Option<PathBuf> {
15    let root = Path::new(module_root);
16    let parts: Vec<&str> = name.split('.').filter(|s| !s.is_empty()).collect();
17    if parts.is_empty() {
18        return None;
19    }
20
21    let lower_rel = format!(
22        "{}.av",
23        parts
24            .iter()
25            .map(|p| p.to_lowercase())
26            .collect::<Vec<_>>()
27            .join("/")
28    );
29    let exact_rel = format!("{}.av", parts.join("/"));
30
31    let lower = root.join(&lower_rel);
32    if lower.exists() {
33        return Some(lower);
34    }
35
36    let exact = root.join(&exact_rel);
37    if exact.exists() {
38        return Some(exact);
39    }
40
41    None
42}
43
44pub fn canonicalize_path(path: &Path) -> PathBuf {
45    std::fs::canonicalize(path).unwrap_or_else(|_| path.to_path_buf())
46}