1use crate::{
2 ast::{
3 Ast, AstAlloc,
4 compat::{FromAst, ToMainline},
5 },
6 eval::value::NickelValue,
7 position::PosTable,
8};
9
10use nickel_lang_parser::{
11 error::{ParseError, ParseErrors},
12 files::FileId,
13 identifier::LocIdent,
14 metrics,
15 position::RawSpan,
16};
17
18pub use nickel_lang_parser::{
19 ErrorTolerantParser, ExtendedTerm, FullyErrorTolerantParser, grammar,
20 grammar::{
21 CliFieldAssignmentParser, ExtendedTermParser, FixedTypeParser, StaticFieldPathParser,
22 TermParser,
23 },
24 lexer,
25};
26
27pub trait ErrorTolerantParserCompat<T> {
34 fn parse_tolerant_compat(
37 &self,
38 pos_table: &mut PosTable,
39 file_id: FileId,
40 lexer: lexer::Lexer,
41 ) -> Result<(T, ParseErrors), ParseError>;
42
43 fn parse_strict_compat(
46 &self,
47 pos_table: &mut PosTable,
48 file_id: FileId,
49 lexer: lexer::Lexer,
50 ) -> Result<T, ParseErrors>;
51}
52
53impl<'ast> FromAst<ExtendedTerm<Ast<'ast>>> for ExtendedTerm<NickelValue> {
54 fn from_ast(ast: &ExtendedTerm<Ast<'ast>>, pos_table: &mut PosTable) -> Self {
55 match ast {
56 ExtendedTerm::Term(t) => ExtendedTerm::Term(t.to_mainline(pos_table)),
57 ExtendedTerm::ToplevelLet(ident, t) => {
58 ExtendedTerm::ToplevelLet(*ident, t.to_mainline(pos_table))
59 }
60 }
61 }
62}
63
64macro_rules! generate_compat_impl {
66 ($parser:ty, $output:ty) => {
67 impl ErrorTolerantParserCompat<$output> for $parser {
68 fn parse_tolerant_compat(
69 &self,
70 pos_table: &mut PosTable,
71 file_id: FileId,
72 lexer: lexer::Lexer,
73 ) -> Result<($output, ParseErrors), ParseError> {
74 let alloc = AstAlloc::new();
75 self.parse_tolerant(&alloc, file_id, lexer).map(|(t, e)| {
76 (
77 metrics::measure_runtime!(
78 "runtime:ast_conversion",
79 t.to_mainline(pos_table)
80 ),
81 e,
82 )
83 })
84 }
85
86 fn parse_strict_compat(
87 &self,
88 pos_table: &mut PosTable,
89 file_id: FileId,
90 lexer: lexer::Lexer,
91 ) -> Result<$output, ParseErrors> {
92 let alloc = AstAlloc::new();
93 self.parse_strict(&alloc, file_id, lexer).map(|t| {
94 metrics::measure_runtime!("runtime:ast_conversion", t.to_mainline(pos_table))
95 })
96 }
97 }
98 };
99}
100
101generate_compat_impl!(ExtendedTermParser, ExtendedTerm<NickelValue>);
102generate_compat_impl!(TermParser, NickelValue);
103generate_compat_impl!(FixedTypeParser, crate::typ::Type);
104
105impl ErrorTolerantParserCompat<(Vec<LocIdent>, NickelValue, RawSpan)> for CliFieldAssignmentParser {
106 fn parse_tolerant_compat(
107 &self,
108 pos_table: &mut PosTable,
109 file_id: FileId,
110 lexer: lexer::Lexer,
111 ) -> Result<((Vec<LocIdent>, NickelValue, RawSpan), ParseErrors), ParseError> {
112 self.parse_tolerant(&AstAlloc::new(), file_id, lexer)
113 .map(|((path, term, span), e)| ((path, term.to_mainline(pos_table), span), e))
114 }
115
116 fn parse_strict_compat(
117 &self,
118 pos_table: &mut PosTable,
119 file_id: FileId,
120 lexer: lexer::Lexer,
121 ) -> Result<(Vec<LocIdent>, NickelValue, RawSpan), ParseErrors> {
122 self.parse_strict(&AstAlloc::new(), file_id, lexer)
123 .map(|(path, term, span)| (path, term.to_mainline(pos_table), span))
124 }
125}
126
127impl ErrorTolerantParserCompat<Vec<LocIdent>> for StaticFieldPathParser {
130 fn parse_tolerant_compat(
131 &self,
132 _pos_table: &mut PosTable,
133 file_id: FileId,
134 lexer: lexer::Lexer,
135 ) -> Result<(Vec<LocIdent>, ParseErrors), ParseError> {
136 self.parse_tolerant(&AstAlloc::new(), file_id, lexer)
137 }
138
139 fn parse_strict_compat(
140 &self,
141 _pos_table: &mut PosTable,
142 file_id: FileId,
143 lexer: lexer::Lexer,
144 ) -> Result<Vec<LocIdent>, ParseErrors> {
145 self.parse_strict(&AstAlloc::new(), file_id, lexer)
146 }
147}