1pub mod ast;
5pub mod bms;
6pub mod copy;
7pub mod lexer;
8pub mod parser;
9pub mod source;
10pub mod system;
11
12use std::fmt;
13
14#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
16pub struct Pos {
17 pub file: u16,
19 pub line: u32,
20 pub col: u32,
21}
22
23impl fmt::Display for Pos {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 write!(f, "{}:{}", self.line, self.col)
26 }
27}
28
29#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct Error {
31 pub pos: Pos,
32 pub message: String,
33 pub file: Option<String>,
35}
36
37impl Error {
38 pub fn at(pos: Pos, message: impl Into<String>) -> Self {
39 Self { pos, message: message.into(), file: None }
40 }
41
42 pub fn in_files(mut self, files: &[String]) -> Self {
44 self.file = files.get(self.pos.file as usize).filter(|f| !f.is_empty()).cloned();
45 self
46 }
47
48 pub fn place(&self, main: &str) -> String {
50 match (&self.file, self.pos.line) {
51 (Some(f), _) => format!("{f}:{self}"),
52 (None, 0) => format!("{main}: {}", self.message),
53 (None, _) => format!("{main}:{self}"),
54 }
55 }
56}
57
58impl fmt::Display for Error {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 write!(f, "{}: {}", self.pos, self.message)
61 }
62}
63
64impl std::error::Error for Error {}
65
66pub fn parse(text: &str) -> Result<ast::Program, Error> {
68 parse_with(text, ©::Libraries::default())
69}
70
71pub fn parse_with(text: &str, libraries: ©::Libraries) -> Result<ast::Program, Error> {
73 Ok(parse_all_with(text, libraries)?.remove(0))
74}
75
76pub fn parse_all_with(text: &str, libraries: ©::Libraries) -> Result<Vec<ast::Program>, Error> {
78 let mut files = vec![String::new()];
79 let source = source::read(text).and_then(|s| copy::expand(s, libraries, &mut files)).map_err(|e| e.in_files(&files))?;
80 let tokens = lexer::lex(&source).map_err(|e| e.in_files(&files))?;
81 let mut programs = parser::parse(&tokens, source.options).map_err(|e| e.in_files(&files))?;
82 for p in &mut programs {
83 p.sources = files.clone();
84 }
85 Ok(programs)
86}