sv_parser_parser/expressions/
subroutine_calls.rs

1use crate::*;
2
3// -----------------------------------------------------------------------------
4
5#[tracable_parser]
6#[packrat_parser]
7pub(crate) fn constant_function_call(s: Span) -> IResult<Span, ConstantFunctionCall> {
8    let (s, a) = function_subroutine_call(s)?;
9    Ok((s, ConstantFunctionCall { nodes: (a,) }))
10}
11
12#[tracable_parser]
13#[packrat_parser]
14pub(crate) fn tf_call(s: Span) -> IResult<Span, TfCall> {
15    let (s, a) = ps_or_hierarchical_tf_identifier(s)?;
16    let (s, b) = many0(attribute_instance)(s)?;
17    let (s, c) = opt(paren(list_of_arguments))(s)?;
18    Ok((s, TfCall { nodes: (a, b, c) }))
19}
20
21#[tracable_parser]
22#[packrat_parser]
23pub(crate) fn system_tf_call(s: Span) -> IResult<Span, SystemTfCall> {
24    alt((
25        system_tf_call_arg_expression,
26        system_tf_call_arg_data_type,
27        system_tf_call_arg_optional,
28    ))(s)
29}
30
31#[tracable_parser]
32#[packrat_parser]
33pub(crate) fn system_tf_call_arg_optional(s: Span) -> IResult<Span, SystemTfCall> {
34    let (s, a) = system_tf_identifier(s)?;
35    let (s, b) = opt(paren(list_of_arguments))(s)?;
36    Ok((
37        s,
38        SystemTfCall::ArgOptionl(Box::new(SystemTfCallArgOptional { nodes: (a, b) })),
39    ))
40}
41
42#[tracable_parser]
43#[packrat_parser]
44pub(crate) fn system_tf_call_arg_data_type(s: Span) -> IResult<Span, SystemTfCall> {
45    let (s, a) = system_tf_identifier(s)?;
46    let (s, b) = paren(pair(data_type, opt(pair(symbol(","), expression))))(s)?;
47    Ok((
48        s,
49        SystemTfCall::ArgDataType(Box::new(SystemTfCallArgDataType { nodes: (a, b) })),
50    ))
51}
52
53#[tracable_parser]
54#[packrat_parser]
55pub(crate) fn system_tf_call_arg_expression(s: Span) -> IResult<Span, SystemTfCall> {
56    let (s, a) = system_tf_identifier(s)?;
57    let (s, b) = paren(pair(
58        list(
59            terminated(symbol(","), peek(not(clocking_event))),
60            opt(expression),
61        ),
62        opt(pair(symbol(","), opt(clocking_event))),
63    ))(s)?;
64    Ok((
65        s,
66        SystemTfCall::ArgExpression(Box::new(SystemTfCallArgExpression { nodes: (a, b) })),
67    ))
68}
69
70#[tracable_parser]
71#[packrat_parser]
72pub(crate) fn subroutine_call(s: Span) -> IResult<Span, SubroutineCall> {
73    alt((
74        subroutine_call_randomize,
75        map(method_call, |x| SubroutineCall::MethodCall(Box::new(x))),
76        map(tf_call, |x| SubroutineCall::TfCall(Box::new(x))),
77        map(system_tf_call, |x| {
78            SubroutineCall::SystemTfCall(Box::new(x))
79        }),
80    ))(s)
81}
82
83#[tracable_parser]
84#[packrat_parser]
85pub(crate) fn subroutine_call_randomize(s: Span) -> IResult<Span, SubroutineCall> {
86    let (s, a) = opt(pair(keyword("std"), symbol("::")))(s)?;
87    let (s, b) = randomize_call(s)?;
88    Ok((
89        s,
90        SubroutineCall::Randomize(Box::new(SubroutineCallRandomize { nodes: (a, b) })),
91    ))
92}
93
94#[tracable_parser]
95#[packrat_parser]
96pub(crate) fn function_subroutine_call(s: Span) -> IResult<Span, FunctionSubroutineCall> {
97    map(subroutine_call, |x| FunctionSubroutineCall { nodes: (x,) })(s)
98}
99
100#[tracable_parser]
101#[packrat_parser]
102pub(crate) fn list_of_arguments(s: Span) -> IResult<Span, ListOfArguments> {
103    alt((list_of_arguments_named, list_of_arguments_ordered))(s)
104}
105
106#[recursive_parser]
107#[tracable_parser]
108#[packrat_parser]
109pub(crate) fn list_of_arguments_ordered(s: Span) -> IResult<Span, ListOfArguments> {
110    let (s, a) = list(
111        terminated(symbol(","), peek(not(symbol(".")))),
112        opt(expression),
113    )(s)?;
114    let (s, b) = many0(tuple((
115        symbol(","),
116        symbol("."),
117        identifier,
118        paren(opt(expression)),
119    )))(s)?;
120    Ok((
121        s,
122        ListOfArguments::Ordered(Box::new(ListOfArgumentsOrdered { nodes: (a, b) })),
123    ))
124}
125
126#[tracable_parser]
127#[packrat_parser]
128pub(crate) fn list_of_arguments_named(s: Span) -> IResult<Span, ListOfArguments> {
129    let (s, a) = symbol(".")(s)?;
130    let (s, b) = identifier(s)?;
131    let (s, c) = paren(opt(expression))(s)?;
132    let (s, d) = many0(tuple((
133        symbol(","),
134        symbol("."),
135        identifier,
136        paren(opt(expression)),
137    )))(s)?;
138    Ok((
139        s,
140        ListOfArguments::Named(Box::new(ListOfArgumentsNamed {
141            nodes: (a, b, c, d),
142        })),
143    ))
144}
145
146#[recursive_parser]
147#[tracable_parser]
148#[packrat_parser]
149pub(crate) fn method_call(s: Span) -> IResult<Span, MethodCall> {
150    let (s, a) = method_call_root(s)?;
151    let (s, b) = symbol(".")(s)?;
152    let (s, c) = method_call_body(s)?;
153    let mut init_method_call = MethodCall { nodes: (a, b, c) };
154
155    // check for chained method
156    let (s, sub_calls) = many0(pair(symbol("."), method_call_body))(s)?;
157    for (dot, body) in sub_calls {
158        let fun_sub_call = Primary::FunctionSubroutineCall(Box::new(FunctionSubroutineCall {
159            nodes: (SubroutineCall::MethodCall(Box::new(init_method_call)),),
160        }));
161        init_method_call = MethodCall {
162            nodes: (MethodCallRoot::Primary(Box::new(fun_sub_call)), dot, body),
163        };
164    }
165
166    Ok((s, init_method_call))
167}
168
169#[tracable_parser]
170#[packrat_parser]
171pub(crate) fn method_call_body(s: Span) -> IResult<Span, MethodCallBody> {
172    alt((
173        map(built_in_method_call, |x| {
174            MethodCallBody::BuiltInMethodCall(Box::new(x))
175        }),
176        method_call_body_user,
177    ))(s)
178}
179
180#[tracable_parser]
181#[packrat_parser]
182pub(crate) fn method_call_body_user(s: Span) -> IResult<Span, MethodCallBody> {
183    let (s, a) = method_identifier(s)?;
184    let (s, b) = many0(attribute_instance)(s)?;
185    let (s, c) = opt(paren(list_of_arguments))(s)?;
186    Ok((
187        s,
188        MethodCallBody::User(Box::new(MethodCallBodyUser { nodes: (a, b, c) })),
189    ))
190}
191
192#[tracable_parser]
193#[packrat_parser]
194pub(crate) fn built_in_method_call(s: Span) -> IResult<Span, BuiltInMethodCall> {
195    alt((
196        map(randomize_call, |x| {
197            BuiltInMethodCall::RandomizeCall(Box::new(x))
198        }),
199        map(array_manipulation_call, |x| {
200            BuiltInMethodCall::ArrayManipulationCall(Box::new(x))
201        }),
202    ))(s)
203}
204
205#[tracable_parser]
206#[packrat_parser]
207pub(crate) fn array_manipulation_call(s: Span) -> IResult<Span, ArrayManipulationCall> {
208    let (s, a) = array_method_name(s)?;
209    let (s, b) = many0(attribute_instance)(s)?;
210    let (s, c) = opt(paren(list_of_arguments))(s)?;
211    let (s, d) = opt(pair(keyword("with"), paren(expression)))(s)?;
212    Ok((
213        s,
214        ArrayManipulationCall {
215            nodes: (a, b, c, d),
216        },
217    ))
218}
219
220#[tracable_parser]
221#[packrat_parser]
222pub(crate) fn randomize_call(s: Span) -> IResult<Span, RandomizeCall> {
223    let (s, a) = keyword("randomize")(s)?;
224    let (s, b) = many0(attribute_instance)(s)?;
225    let (s, c) = opt(paren(opt(variable_identifier_list_or_null)))(s)?;
226    let (s, d) = opt(triple(
227        keyword("with"),
228        opt(paren(opt(identifier_list))),
229        constraint_block,
230    ))(s)?;
231    Ok((
232        s,
233        RandomizeCall {
234            nodes: (a, b, c, d),
235        },
236    ))
237}
238
239#[tracable_parser]
240#[packrat_parser]
241pub(crate) fn variable_identifier_list_or_null(
242    s: Span,
243) -> IResult<Span, VariableIdentifierListOrNull> {
244    alt((
245        map(variable_identifier_list, |x| {
246            VariableIdentifierListOrNull::VariableIdentifierList(Box::new(x))
247        }),
248        map(keyword("null"), |x| {
249            VariableIdentifierListOrNull::Null(Box::new(x))
250        }),
251    ))(s)
252}
253
254#[tracable_parser]
255#[packrat_parser]
256pub(crate) fn method_call_root(s: Span) -> IResult<Span, MethodCallRoot> {
257    alt((
258        map(primary_method_call_root, |x| {
259            MethodCallRoot::Primary(Box::new(x))
260        }),
261        map(implicit_class_handle, |x| {
262            MethodCallRoot::ImplicitClassHandle(Box::new(x))
263        }),
264    ))(s)
265}
266
267#[tracable_parser]
268#[packrat_parser]
269pub(crate) fn primary_method_call_root(s: Span) -> IResult<Span, Primary> {
270    alt((
271        map(keyword("$"), |x| Primary::Dollar(Box::new(x))),
272        map(keyword("null"), |x| Primary::Null(Box::new(x))),
273        map(assignment_pattern_expression, |x| {
274            Primary::AssignmentPatternExpression(Box::new(x))
275        }),
276        map(primary_literal, |x| Primary::PrimaryLiteral(Box::new(x))),
277        map(cast, |x| Primary::Cast(Box::new(x))),
278        terminated(primary_hierarchical_method_call_root, peek(none_of("("))),
279        map(keyword("this"), |x| Primary::This(Box::new(x))),
280        map(empty_unpacked_array_concatenation, |x| {
281            Primary::EmptyUnpackedArrayConcatenation(Box::new(x))
282        }),
283        primary_concatenation,
284        primary_multiple_concatenation,
285        map(function_subroutine_call, |x| {
286            Primary::FunctionSubroutineCall(Box::new(x))
287        }),
288        map(let_expression, |x| Primary::LetExpression(Box::new(x))),
289        primary_mintypmax_expression,
290        map(streaming_concatenation, |x| {
291            Primary::StreamingConcatenation(Box::new(x))
292        }),
293        map(sequence_method_call, |x| {
294            Primary::SequenceMethodCall(Box::new(x))
295        }),
296    ))(s)
297}
298
299#[tracable_parser]
300#[packrat_parser]
301pub(crate) fn primary_hierarchical_method_call_root(s: Span) -> IResult<Span, Primary> {
302    let (s, a) = opt(class_qualifier_or_package_scope)(s)?;
303    let (s, b) = hierarchical_identifier_method_call_root(s)?;
304    let (s, c) = select_method_call_root(s)?;
305    Ok((
306        s,
307        Primary::Hierarchical(Box::new(PrimaryHierarchical { nodes: (a, b, c) })),
308    ))
309}
310
311#[tracable_parser]
312#[packrat_parser]
313pub(crate) fn hierarchical_identifier_method_call_root(
314    s: Span,
315) -> IResult<Span, HierarchicalIdentifier> {
316    let (s, a) = opt(root)(s)?;
317    let (s, b) = many0(terminated(
318        triple(identifier, constant_bit_select, symbol(".")),
319        peek(pair(identifier, symbol("."))),
320    ))(s)?;
321    let (s, c) = identifier(s)?;
322    Ok((s, HierarchicalIdentifier { nodes: (a, b, c) }))
323}
324
325#[tracable_parser]
326#[packrat_parser]
327pub(crate) fn select_method_call_root(s: Span) -> IResult<Span, Select> {
328    let (s, a) = opt(terminated(
329        triple(
330            many0(terminated(
331                triple(symbol("."), member_identifier, bit_select),
332                peek(triple(symbol("."), member_identifier, symbol("."))),
333            )),
334            symbol("."),
335            member_identifier,
336        ),
337        peek(one_of(".[")),
338    ))(s)?;
339    let (s, b) = bit_select(s)?;
340    let (s, c) = opt(bracket(part_select_range))(s)?;
341    Ok((s, Select { nodes: (a, b, c) }))
342}
343
344#[tracable_parser]
345#[packrat_parser]
346pub(crate) fn array_method_name(s: Span) -> IResult<Span, ArrayMethodName> {
347    alt((
348        map(keyword("unique"), |x| ArrayMethodName::Unique(Box::new(x))),
349        map(keyword("and"), |x| ArrayMethodName::And(Box::new(x))),
350        map(keyword("or"), |x| ArrayMethodName::Or(Box::new(x))),
351        map(keyword("xor"), |x| ArrayMethodName::Xor(Box::new(x))),
352        map(method_identifier, |x| {
353            ArrayMethodName::MethodIdentifier(Box::new(x))
354        }),
355    ))(s)
356}