1use std::ops::Range;
6
7use dyn_clone::DynClone;
8use intern_all::Tok;
9
10use super::context::ParseCtx;
11use super::errors::{expect, expect_block, expect_name};
12use super::facade::parse_entries;
13use super::frag::Frag;
14use super::lexer::{Entry, Lexeme};
15use super::parsed::{Constant, Expr, ModuleBlock, PType, Rule, SourceLine, SourceLineKind};
16use super::sourcefile::{
17 exprv_to_single, parse_const, parse_exprv, parse_line, parse_module, parse_module_body,
18 parse_nsname, parse_rule, split_lines,
19};
20use crate::error::{ProjectErrorObj, ProjectResult};
21use crate::location::SourceRange;
22use crate::name::VName;
23use crate::utils::boxed_iter::BoxedIter;
24
25pub trait ParsePluginReq<'t> {
29 fn frag(&self) -> Frag;
33 fn frag_loc(&self, f: Frag) -> SourceRange;
35 fn range_loc(&self, r: Range<usize>) -> SourceRange;
37 fn pop<'a>(&self, f: Frag<'a>) -> ProjectResult<(&'a Entry, Frag<'a>)>;
39 fn pop_back<'a>(&self, f: Frag<'a>) -> ProjectResult<(&'a Entry, Frag<'a>)>;
41
42 fn split_lines<'a: 'b, 'b>(&'b self, f: Frag<'a>) -> BoxedIter<'b, Frag<'a>>
47 where 't: 'b + 'a;
48 fn parse_module_body(&self, frag: Frag) -> ProjectResult<Vec<SourceLine>>;
50 fn parse_line(&self, frag: Frag) -> ProjectResult<Vec<SourceLineKind>>;
53 fn parse_rule(&self, frag: Frag) -> ProjectResult<Rule>;
55 fn parse_const(&self, frag: Frag) -> ProjectResult<Constant>;
57 fn parse_nsname<'a>(&self, f: Frag<'a>) -> ProjectResult<(VName, Frag<'a>)>;
59 fn parse_module(&self, frag: Frag) -> ProjectResult<ModuleBlock>;
61 fn parse_exprv<'a>(&self, f: Frag<'a>, p: Option<PType>) -> ProjectResult<(Vec<Expr>, Frag<'a>)>;
64 fn parse_entries(&self, t: &'static str, r: SourceRange) -> Vec<SourceLine>;
66 fn vec_to_single(&self, fallback: &Entry, v: Vec<Expr>) -> ProjectResult<Expr>;
69
70 fn expect_name(&self, entry: &Entry) -> ProjectResult<Tok<String>>;
74 fn expect(&self, l: Lexeme, e: &Entry) -> ProjectResult<()>;
76 fn expect_block<'a>(&self, f: Frag<'a>, p: PType) -> ProjectResult<Frag<'a>>;
78 fn expect_empty(&self, f: Frag) -> ProjectResult<()>;
80 fn report_err(&self, e: ProjectErrorObj);
83}
84
85pub trait ParseLinePlugin: Sync + Send + DynClone {
88 fn parse(&self, req: &dyn ParsePluginReq) -> Option<ProjectResult<Vec<SourceLineKind>>>;
91}
92
93pub struct ParsePlugReqImpl<'a, TCtx: ParseCtx + ?Sized> {
96 pub frag: Frag<'a>,
98 pub ctx: &'a TCtx,
100}
101impl<'ty, TCtx: ParseCtx + ?Sized> ParsePluginReq<'ty> for ParsePlugReqImpl<'ty, TCtx> {
102 fn frag(&self) -> Frag { self.frag }
103 fn frag_loc(&self, f: Frag) -> SourceRange { self.range_loc(f.range()) }
104 fn range_loc(&self, r: Range<usize>) -> SourceRange { self.ctx.range_loc(&r) }
105 fn pop<'a>(&self, f: Frag<'a>) -> ProjectResult<(&'a Entry, Frag<'a>)> { f.pop(self.ctx) }
106 fn pop_back<'a>(&self, f: Frag<'a>) -> ProjectResult<(&'a Entry, Frag<'a>)> {
107 f.pop_back(self.ctx)
108 }
109 fn split_lines<'a: 'b, 'b>(&'b self, f: Frag<'a>) -> BoxedIter<'b, Frag<'a>>
110 where
111 'ty: 'b,
112 'ty: 'a,
113 {
114 Box::new(split_lines(f, self.ctx))
115 }
116 fn parse_module_body(&self, f: Frag) -> ProjectResult<Vec<SourceLine>> {
117 Ok(parse_module_body(f, self.ctx))
118 }
119 fn parse_line(&self, f: Frag) -> ProjectResult<Vec<SourceLineKind>> { parse_line(f, self.ctx) }
120 fn parse_rule(&self, f: Frag) -> ProjectResult<Rule> { parse_rule(f, self.ctx) }
121 fn parse_const(&self, f: Frag) -> ProjectResult<Constant> { parse_const(f, self.ctx) }
122 fn parse_nsname<'a>(&self, f: Frag<'a>) -> ProjectResult<(VName, Frag<'a>)> {
123 parse_nsname(f, self.ctx)
124 }
125 fn parse_module(&self, f: Frag) -> ProjectResult<ModuleBlock> { parse_module(f, self.ctx) }
126 fn parse_exprv<'a>(&self, f: Frag<'a>, p: Option<PType>) -> ProjectResult<(Vec<Expr>, Frag<'a>)> {
127 parse_exprv(f, p, self.ctx)
128 }
129 fn parse_entries(&self, s: &'static str, r: SourceRange) -> Vec<SourceLine> {
130 parse_entries(&self.ctx, s, r)
131 }
132 fn vec_to_single(&self, fb: &Entry, v: Vec<Expr>) -> ProjectResult<Expr> {
133 exprv_to_single(fb, v, self.ctx)
134 }
135 fn expect_name(&self, e: &Entry) -> ProjectResult<Tok<String>> { expect_name(e, self.ctx) }
136 fn expect(&self, l: Lexeme, e: &Entry) -> ProjectResult<()> { expect(l, e, self.ctx) }
137 fn expect_block<'a>(&self, f: Frag<'a>, t: PType) -> ProjectResult<Frag<'a>> {
138 expect_block(f, t, self.ctx)
139 }
140 fn expect_empty(&self, f: Frag) -> ProjectResult<()> { f.expect_empty(self.ctx) }
141 fn report_err(&self, e: ProjectErrorObj) { self.ctx.reporter().report(e) }
142}