1use crate::*;
2
3#[tracable_parser]
6#[packrat_parser]
7pub(crate) fn function_data_type_or_implicit(s: Span) -> IResult<Span, FunctionDataTypeOrImplicit> {
8 alt((
9 map(
10 terminated(
11 data_type_or_void,
12 peek(pair(
13 opt(interface_identifier_or_class_scope),
14 function_identifier,
15 )),
16 ),
17 |x| FunctionDataTypeOrImplicit::DataTypeOrVoid(Box::new(x)),
18 ),
19 map(
20 terminated(
21 implicit_data_type,
22 peek(pair(
23 opt(interface_identifier_or_class_scope),
24 function_identifier,
25 )),
26 ),
27 |x| FunctionDataTypeOrImplicit::ImplicitDataType(Box::new(x)),
28 ),
29 ))(s)
30}
31
32#[tracable_parser]
33#[packrat_parser]
34pub(crate) fn function_declaration(s: Span) -> IResult<Span, FunctionDeclaration> {
35 let (s, a) = keyword("function")(s)?;
36 let (s, b) = opt(lifetime)(s)?;
37 let (s, c) = function_body_declaration(s)?;
38 Ok((s, FunctionDeclaration { nodes: (a, b, c) }))
39}
40
41#[tracable_parser]
42#[packrat_parser]
43pub(crate) fn function_body_declaration(s: Span) -> IResult<Span, FunctionBodyDeclaration> {
44 alt((
45 function_body_declaration_without_port,
46 function_body_declaration_with_port,
47 ))(s)
48}
49
50#[tracable_parser]
51#[packrat_parser]
52pub(crate) fn function_body_declaration_without_port(
53 s: Span,
54) -> IResult<Span, FunctionBodyDeclaration> {
55 let (s, a) = function_data_type_or_implicit(s)?;
56 let (s, b) = opt(interface_identifier_or_class_scope)(s)?;
57 let (s, c) = function_identifier(s)?;
58 let (s, d) = symbol(";")(s)?;
59 let (s, e) = many0(tf_item_declaration)(s)?;
60 let (s, (f, g)) = many_till(function_statement_or_null, keyword("endfunction"))(s)?;
61 let (s, h) = opt(pair(symbol(":"), function_identifier))(s)?;
62 Ok((
63 s,
64 FunctionBodyDeclaration::WithoutPort(Box::new(FunctionBodyDeclarationWithoutPort {
65 nodes: (a, b, c, d, e, f, g, h),
66 })),
67 ))
68}
69
70#[tracable_parser]
71#[packrat_parser]
72pub(crate) fn function_body_declaration_with_port(
73 s: Span,
74) -> IResult<Span, FunctionBodyDeclaration> {
75 let (s, a) = function_data_type_or_implicit(s)?;
76 let (s, b) = opt(interface_identifier_or_class_scope)(s)?;
77 let (s, c) = function_identifier(s)?;
78 let (s, d) = paren(opt(tf_port_list))(s)?;
79 let (s, e) = symbol(";")(s)?;
80 let (s, f) = many0(block_item_declaration)(s)?;
81 let (s, (g, h)) = many_till(function_statement_or_null, keyword("endfunction"))(s)?;
82 let (s, i) = opt(pair(symbol(":"), function_identifier))(s)?;
83 Ok((
84 s,
85 FunctionBodyDeclaration::WithPort(Box::new(FunctionBodyDeclarationWithPort {
86 nodes: (a, b, c, d, e, f, g, h, i),
87 })),
88 ))
89}
90
91#[tracable_parser]
92#[packrat_parser]
93pub(crate) fn interface_identifier_or_class_scope(
94 s: Span,
95) -> IResult<Span, InterfaceIdentifierOrClassScope> {
96 alt((
97 map(pair(interface_identifier, symbol(".")), |x| {
98 InterfaceIdentifierOrClassScope::InterfaceIdentifier(Box::new(x))
99 }),
100 map(class_scope, |x| {
101 InterfaceIdentifierOrClassScope::ClassScope(Box::new(x))
102 }),
103 ))(s)
104}
105
106#[tracable_parser]
107#[packrat_parser]
108pub(crate) fn function_prototype(s: Span) -> IResult<Span, FunctionPrototype> {
109 let (s, a) = keyword("function")(s)?;
110 let (s, b) = data_type_or_void(s)?;
111 let (s, c) = function_identifier(s)?;
112 let (s, d) = opt(paren(opt(tf_port_list)))(s)?;
113 Ok((
114 s,
115 FunctionPrototype {
116 nodes: (a, b, c, d),
117 },
118 ))
119}
120
121#[tracable_parser]
122#[packrat_parser]
123pub(crate) fn dpi_import_export(s: Span) -> IResult<Span, DpiImportExport> {
124 alt((
125 dpi_import_export_import_function,
126 dpi_import_export_import_task,
127 dpi_import_export_export_function,
128 dpi_import_export_export_task,
129 ))(s)
130}
131
132#[tracable_parser]
133#[packrat_parser]
134pub(crate) fn dpi_import_export_import_function(s: Span) -> IResult<Span, DpiImportExport> {
135 let (s, a) = keyword("import")(s)?;
136 let (s, b) = dpi_spec_string(s)?;
137 let (s, c) = opt(dpi_function_import_property)(s)?;
138 let (s, d) = opt(pair(c_identifier, symbol("=")))(s)?;
139 let (s, e) = dpi_function_proto(s)?;
140 let (s, f) = symbol(";")(s)?;
141 Ok((
142 s,
143 DpiImportExport::ImportFunction(Box::new(DpiImportExportImportFunction {
144 nodes: (a, b, c, d, e, f),
145 })),
146 ))
147}
148
149#[tracable_parser]
150#[packrat_parser]
151pub(crate) fn dpi_import_export_import_task(s: Span) -> IResult<Span, DpiImportExport> {
152 let (s, a) = keyword("import")(s)?;
153 let (s, b) = dpi_spec_string(s)?;
154 let (s, c) = opt(dpi_task_import_property)(s)?;
155 let (s, d) = opt(pair(c_identifier, symbol("=")))(s)?;
156 let (s, e) = dpi_task_proto(s)?;
157 let (s, f) = symbol(";")(s)?;
158 Ok((
159 s,
160 DpiImportExport::ImportTask(Box::new(DpiImportExportImportTask {
161 nodes: (a, b, c, d, e, f),
162 })),
163 ))
164}
165
166#[tracable_parser]
167#[packrat_parser]
168pub(crate) fn dpi_import_export_export_function(s: Span) -> IResult<Span, DpiImportExport> {
169 let (s, a) = keyword("export")(s)?;
170 let (s, b) = dpi_spec_string(s)?;
171 let (s, c) = opt(pair(c_identifier, symbol("=")))(s)?;
172 let (s, d) = keyword("function")(s)?;
173 let (s, e) = function_identifier(s)?;
174 let (s, f) = symbol(";")(s)?;
175 Ok((
176 s,
177 DpiImportExport::ExportFunction(Box::new(DpiImportExportExportFunction {
178 nodes: (a, b, c, d, e, f),
179 })),
180 ))
181}
182
183#[tracable_parser]
184#[packrat_parser]
185pub(crate) fn dpi_import_export_export_task(s: Span) -> IResult<Span, DpiImportExport> {
186 let (s, a) = keyword("export")(s)?;
187 let (s, b) = dpi_spec_string(s)?;
188 let (s, c) = opt(pair(c_identifier, symbol("=")))(s)?;
189 let (s, d) = keyword("task")(s)?;
190 let (s, e) = task_identifier(s)?;
191 let (s, f) = symbol(";")(s)?;
192 Ok((
193 s,
194 DpiImportExport::ExportTask(Box::new(DpiImportExportExportTask {
195 nodes: (a, b, c, d, e, f),
196 })),
197 ))
198}
199
200#[tracable_parser]
201#[packrat_parser]
202pub(crate) fn dpi_spec_string(s: Span) -> IResult<Span, DpiSpecString> {
203 alt((
204 map(keyword("\"DPI-C\""), |x| DpiSpecString::DpiC(Box::new(x))),
205 map(keyword("\"DPI\""), |x| DpiSpecString::Dpi(Box::new(x))),
206 ))(s)
207}
208
209#[tracable_parser]
210#[packrat_parser]
211pub(crate) fn dpi_function_import_property(s: Span) -> IResult<Span, DpiFunctionImportProperty> {
212 alt((
213 map(keyword("context"), |x| {
214 DpiFunctionImportProperty::Context(Box::new(x))
215 }),
216 map(keyword("pure"), |x| {
217 DpiFunctionImportProperty::Pure(Box::new(x))
218 }),
219 ))(s)
220}
221
222#[tracable_parser]
223#[packrat_parser]
224pub(crate) fn dpi_task_import_property(s: Span) -> IResult<Span, DpiTaskImportProperty> {
225 let (s, a) = keyword("context")(s)?;
226 Ok((s, DpiTaskImportProperty::Context(Box::new(a))))
227}
228
229#[tracable_parser]
230#[packrat_parser]
231pub(crate) fn dpi_function_proto(s: Span) -> IResult<Span, DpiFunctionProto> {
232 let (s, a) = function_prototype(s)?;
233 Ok((s, DpiFunctionProto { nodes: (a,) }))
234}
235
236#[tracable_parser]
237#[packrat_parser]
238pub(crate) fn dpi_task_proto(s: Span) -> IResult<Span, DpiTaskProto> {
239 let (s, a) = task_prototype(s)?;
240 Ok((s, DpiTaskProto { nodes: (a,) }))
241}