orchidlang/parse/
facade.rs

1//! Entrypoints to the parser that combine lexing and parsing
2
3use never::Never;
4
5use super::context::{FlatLocContext, ParseCtx, ReporterContext};
6use super::frag::Frag;
7use super::lexer::lex;
8use super::sourcefile::parse_module_body;
9use crate::error::Reporter;
10use crate::location::SourceRange;
11use crate::parse::parsed::SourceLine;
12use crate::parse::sourcefile::{parse_line, split_lines};
13
14/// Parse a file
15pub fn parse_file(ctx: &impl ParseCtx) -> Vec<SourceLine> {
16  let tokens = lex(vec![], ctx.source().as_str(), ctx, |_| Ok::<_, Never>(false))
17    .unwrap_or_else(|e| match e {})
18    .tokens;
19  if tokens.is_empty() { Vec::new() } else { parse_module_body(Frag::from_slice(&tokens), ctx) }
20}
21
22/// Parse a statically defined line sequence
23///
24/// # Panics
25///
26/// On any parse error, which is why it only accepts a string literal
27pub fn parse_entries(
28  ctx: &dyn ParseCtx,
29  text: &'static str,
30  range: SourceRange,
31) -> Vec<SourceLine> {
32  let reporter = Reporter::new();
33  let flctx = FlatLocContext::new(ctx, &range);
34  let ctx = ReporterContext::new(&flctx, &reporter);
35  let res = lex(vec![], text, &ctx, |_| Ok::<_, Never>(false)).unwrap_or_else(|e| match e {});
36  let out = split_lines(Frag::from_slice(&res.tokens), &ctx)
37    .flat_map(|tokens| parse_line(tokens, &ctx).expect("pre-specified source"))
38    .map(|kind| kind.wrap(range.clone()))
39    .collect();
40  reporter.assert();
41  out
42}