sv_parser_parser/expressions/
primaries.rs

1use crate::*;
2
3// -----------------------------------------------------------------------------
4
5#[tracable_parser]
6#[packrat_parser]
7pub(crate) fn constant_primary(s: Span) -> IResult<Span, ConstantPrimary> {
8    alt((
9        // BNF-WA
10        map(keyword("$"), |x| ConstantPrimary::Dollar(Box::new(x))),
11        map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))),
12        map(constant_assignment_pattern_expression, |x| {
13            ConstantPrimary::ConstantAssignmentPatternExpression(Box::new(x))
14        }),
15        map(constant_cast, |x| {
16            ConstantPrimary::ConstantCast(Box::new(x))
17        }),
18        map(primary_literal, |x| {
19            ConstantPrimary::PrimaryLiteral(Box::new(x))
20        }),
21        constant_primary_mintypmax_expression,
22        map(
23            terminated(constant_function_call, peek(not(one_of("[.")))),
24            |x| ConstantPrimary::ConstantFunctionCall(Box::new(x)),
25        ),
26        constant_primary_ps_parameter,
27        constant_primary_specparam,
28        map(genvar_identifier, |x| {
29            ConstantPrimary::GenvarIdentifier(Box::new(x))
30        }),
31        constant_primary_formal_port,
32        constant_primary_enum,
33        constant_primary_concatenation,
34        constant_primary_multiple_concatenation,
35        map(constant_let_expression, |x| {
36            ConstantPrimary::ConstantLetExpression(Box::new(x))
37        }),
38        map(type_reference, |x| {
39            ConstantPrimary::TypeReference(Box::new(x))
40        }),
41    ))(s)
42}
43
44#[tracable_parser]
45#[packrat_parser]
46pub(crate) fn constant_primary_no_function(s: Span) -> IResult<Span, ConstantPrimary> {
47    alt((
48        // BNF-WA
49        map(keyword("$"), |x| ConstantPrimary::Dollar(Box::new(x))),
50        map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))),
51        map(constant_assignment_pattern_expression, |x| {
52            ConstantPrimary::ConstantAssignmentPatternExpression(Box::new(x))
53        }),
54        map(constant_cast, |x| {
55            ConstantPrimary::ConstantCast(Box::new(x))
56        }),
57        map(primary_literal, |x| {
58            ConstantPrimary::PrimaryLiteral(Box::new(x))
59        }),
60        constant_primary_mintypmax_expression,
61        constant_primary_ps_parameter,
62        constant_primary_specparam,
63        map(genvar_identifier, |x| {
64            ConstantPrimary::GenvarIdentifier(Box::new(x))
65        }),
66        constant_primary_formal_port,
67        constant_primary_enum,
68        constant_primary_concatenation,
69        constant_primary_multiple_concatenation,
70        map(constant_let_expression, |x| {
71            ConstantPrimary::ConstantLetExpression(Box::new(x))
72        }),
73        map(type_reference, |x| {
74            ConstantPrimary::TypeReference(Box::new(x))
75        }),
76    ))(s)
77}
78
79#[tracable_parser]
80#[packrat_parser]
81pub(crate) fn constant_primary_without_cast(s: Span) -> IResult<Span, ConstantPrimary> {
82    alt((
83        // BNF-WA
84        map(keyword("$"), |x| ConstantPrimary::Dollar(Box::new(x))),
85        map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))),
86        map(constant_assignment_pattern_expression, |x| {
87            ConstantPrimary::ConstantAssignmentPatternExpression(Box::new(x))
88        }),
89        map(primary_literal, |x| {
90            ConstantPrimary::PrimaryLiteral(Box::new(x))
91        }),
92        constant_primary_mintypmax_expression,
93        map(
94            terminated(constant_function_call, peek(not(one_of("[.")))),
95            |x| ConstantPrimary::ConstantFunctionCall(Box::new(x)),
96        ),
97        constant_primary_ps_parameter,
98        constant_primary_specparam,
99        map(genvar_identifier, |x| {
100            ConstantPrimary::GenvarIdentifier(Box::new(x))
101        }),
102        constant_primary_formal_port,
103        constant_primary_enum,
104        constant_primary_concatenation,
105        constant_primary_multiple_concatenation,
106        map(constant_let_expression, |x| {
107            ConstantPrimary::ConstantLetExpression(Box::new(x))
108        }),
109        map(type_reference, |x| {
110            ConstantPrimary::TypeReference(Box::new(x))
111        }),
112    ))(s)
113}
114
115#[tracable_parser]
116#[packrat_parser]
117pub(crate) fn constant_primary_ps_parameter(s: Span) -> IResult<Span, ConstantPrimary> {
118    let (s, a) = ps_parameter_identifier(s)?;
119    let (s, b) = constant_select(s)?;
120    Ok((
121        s,
122        ConstantPrimary::PsParameter(Box::new(ConstantPrimaryPsParameter { nodes: (a, b) })),
123    ))
124}
125
126#[tracable_parser]
127#[packrat_parser]
128pub(crate) fn constant_primary_specparam(s: Span) -> IResult<Span, ConstantPrimary> {
129    let (s, a) = specparam_identifier(s)?;
130    let (s, b) = opt(bracket(constant_range_expression))(s)?;
131    Ok((
132        s,
133        ConstantPrimary::Specparam(Box::new(ConstantPrimarySpecparam { nodes: (a, b) })),
134    ))
135}
136
137#[tracable_parser]
138#[packrat_parser]
139pub(crate) fn constant_primary_formal_port(s: Span) -> IResult<Span, ConstantPrimary> {
140    let (s, a) = formal_port_identifier(s)?;
141    let (s, b) = constant_select(s)?;
142    Ok((
143        s,
144        ConstantPrimary::FormalPort(Box::new(ConstantPrimaryFormalPort { nodes: (a, b) })),
145    ))
146}
147
148#[tracable_parser]
149#[packrat_parser]
150pub(crate) fn constant_primary_enum(s: Span) -> IResult<Span, ConstantPrimary> {
151    let (s, a) = package_scope_or_class_scope(s)?;
152    let (s, b) = enum_identifier(s)?;
153    Ok((
154        s,
155        ConstantPrimary::Enum(Box::new(ConstantPrimaryEnum { nodes: (a, b) })),
156    ))
157}
158
159#[tracable_parser]
160#[packrat_parser]
161pub(crate) fn constant_primary_concatenation(s: Span) -> IResult<Span, ConstantPrimary> {
162    let (s, a) = constant_concatenation(s)?;
163    let (s, b) = opt(bracket(constant_range_expression))(s)?;
164    Ok((
165        s,
166        ConstantPrimary::Concatenation(Box::new(ConstantPrimaryConcatenation { nodes: (a, b) })),
167    ))
168}
169
170#[tracable_parser]
171#[packrat_parser]
172pub(crate) fn constant_primary_multiple_concatenation(s: Span) -> IResult<Span, ConstantPrimary> {
173    let (s, a) = constant_multiple_concatenation(s)?;
174    let (s, b) = opt(bracket(constant_range_expression))(s)?;
175    Ok((
176        s,
177        ConstantPrimary::MultipleConcatenation(Box::new(ConstantPrimaryMultipleConcatenation {
178            nodes: (a, b),
179        })),
180    ))
181}
182
183#[tracable_parser]
184#[packrat_parser]
185pub(crate) fn constant_primary_mintypmax_expression(s: Span) -> IResult<Span, ConstantPrimary> {
186    let (s, a) = paren(constant_mintypmax_expression)(s)?;
187    Ok((
188        s,
189        ConstantPrimary::MintypmaxExpression(Box::new(ConstantPrimaryMintypmaxExpression {
190            nodes: (a,),
191        })),
192    ))
193}
194
195#[tracable_parser]
196#[packrat_parser]
197pub(crate) fn module_path_primary(s: Span) -> IResult<Span, ModulePathPrimary> {
198    alt((
199        map(number, |x| ModulePathPrimary::Number(Box::new(x))),
200        map(identifier, |x| ModulePathPrimary::Identifier(Box::new(x))),
201        map(module_path_concatenation, |x| {
202            ModulePathPrimary::ModulePathConcatenation(Box::new(x))
203        }),
204        map(module_path_multiple_concatenation, |x| {
205            ModulePathPrimary::ModulePathMultipleConcatenation(Box::new(x))
206        }),
207        map(function_subroutine_call, |x| {
208            ModulePathPrimary::FunctionSubroutineCall(Box::new(x))
209        }),
210        module_path_primary_mintypmax_expression,
211    ))(s)
212}
213
214#[tracable_parser]
215#[packrat_parser]
216pub(crate) fn module_path_primary_mintypmax_expression(
217    s: Span,
218) -> IResult<Span, ModulePathPrimary> {
219    let (s, a) = paren(module_path_mintypmax_expression)(s)?;
220    Ok((
221        s,
222        ModulePathPrimary::Mintypmax(Box::new(ModulePathPrimaryMintypmax { nodes: (a,) })),
223    ))
224}
225
226#[tracable_parser]
227#[packrat_parser]
228pub(crate) fn primary(s: Span) -> IResult<Span, Primary> {
229    alt((
230        terminated(
231            primary_hierarchical,
232            peek(not(alt((
233                map(one_of("(.'"), |_| ()),
234                map(keyword("with"), |_| ()),
235            )))),
236        ),
237        map(assignment_pattern_expression, |x| {
238            Primary::AssignmentPatternExpression(Box::new(x))
239        }),
240        map(cast, |x| Primary::Cast(Box::new(x))),
241        map(primary_literal, |x| Primary::PrimaryLiteral(Box::new(x))),
242        map(empty_unpacked_array_concatenation, |x| {
243            Primary::EmptyUnpackedArrayConcatenation(Box::new(x))
244        }),
245        primary_concatenation,
246        primary_multiple_concatenation,
247        map(function_subroutine_call, |x| {
248            Primary::FunctionSubroutineCall(Box::new(x))
249        }),
250        map(let_expression, |x| Primary::LetExpression(Box::new(x))),
251        primary_mintypmax_expression,
252        map(streaming_concatenation, |x| {
253            Primary::StreamingConcatenation(Box::new(x))
254        }),
255        map(sequence_method_call, |x| {
256            Primary::SequenceMethodCall(Box::new(x))
257        }),
258        map(keyword("this"), |x| Primary::This(Box::new(x))),
259        map(keyword("$"), |x| Primary::Dollar(Box::new(x))),
260        map(keyword("null"), |x| Primary::Null(Box::new(x))),
261    ))(s)
262}
263
264#[tracable_parser]
265#[packrat_parser]
266pub(crate) fn primary_hierarchical(s: Span) -> IResult<Span, Primary> {
267    let (s, a) = opt(class_qualifier_or_package_scope)(s)?;
268    let (s, b) = hierarchical_identifier(s)?;
269    let (s, c) = select(s)?;
270    Ok((
271        s,
272        Primary::Hierarchical(Box::new(PrimaryHierarchical { nodes: (a, b, c) })),
273    ))
274}
275
276#[tracable_parser]
277#[packrat_parser]
278pub(crate) fn primary_concatenation(s: Span) -> IResult<Span, Primary> {
279    let (s, a) = concatenation(s)?;
280    let (s, b) = opt(bracket(range_expression))(s)?;
281    Ok((
282        s,
283        Primary::Concatenation(Box::new(PrimaryConcatenation { nodes: (a, b) })),
284    ))
285}
286
287#[tracable_parser]
288#[packrat_parser]
289pub(crate) fn primary_multiple_concatenation(s: Span) -> IResult<Span, Primary> {
290    let (s, a) = multiple_concatenation(s)?;
291    let (s, b) = opt(bracket(range_expression))(s)?;
292    Ok((
293        s,
294        Primary::MultipleConcatenation(Box::new(PrimaryMultipleConcatenation { nodes: (a, b) })),
295    ))
296}
297
298#[tracable_parser]
299#[packrat_parser]
300pub(crate) fn primary_mintypmax_expression(s: Span) -> IResult<Span, Primary> {
301    let (s, a) = paren(mintypmax_expression)(s)?;
302    Ok((
303        s,
304        Primary::MintypmaxExpression(Box::new(PrimaryMintypmaxExpression { nodes: (a,) })),
305    ))
306}
307
308#[tracable_parser]
309#[packrat_parser]
310pub(crate) fn class_qualifier_or_package_scope(
311    s: Span,
312) -> IResult<Span, ClassQualifierOrPackageScope> {
313    alt((
314        map(class_qualifier, |x| {
315            ClassQualifierOrPackageScope::ClassQualifier(Box::new(x))
316        }),
317        map(package_scope, |x| {
318            ClassQualifierOrPackageScope::PackageScope(Box::new(x))
319        }),
320    ))(s)
321}
322
323#[recursive_parser]
324#[tracable_parser]
325#[packrat_parser]
326pub(crate) fn class_qualifier(s: Span) -> IResult<Span, ClassQualifier> {
327    let (s, a) = opt(local)(s)?;
328    let (s, b) = opt(implicit_class_handle_or_class_scope)(s)?;
329    Ok((s, ClassQualifier { nodes: (a, b) }))
330}
331
332#[tracable_parser]
333#[packrat_parser]
334pub(crate) fn range_expression(s: Span) -> IResult<Span, RangeExpression> {
335    alt((
336        map(part_select_range, |x| {
337            RangeExpression::PartSelectRange(Box::new(x))
338        }),
339        map(expression, |x| RangeExpression::Expression(Box::new(x))),
340    ))(s)
341}
342
343#[tracable_parser]
344#[packrat_parser]
345pub(crate) fn primary_literal(s: Span) -> IResult<Span, PrimaryLiteral> {
346    alt((
347        map(time_literal, |x| PrimaryLiteral::TimeLiteral(Box::new(x))),
348        map(number, |x| PrimaryLiteral::Number(Box::new(x))),
349        map(unbased_unsized_literal, |x| {
350            PrimaryLiteral::UnbasedUnsizedLiteral(Box::new(x))
351        }),
352        map(string_literal, |x| {
353            PrimaryLiteral::StringLiteral(Box::new(x))
354        }),
355    ))(s)
356}
357
358#[tracable_parser]
359#[packrat_parser]
360pub(crate) fn time_literal(s: Span) -> IResult<Span, TimeLiteral> {
361    alt((time_literal_unsigned, time_literal_fixed_point))(s)
362}
363
364#[tracable_parser]
365#[packrat_parser]
366pub(crate) fn time_literal_unsigned(s: Span) -> IResult<Span, TimeLiteral> {
367    let (s, a) = unsigned_number_exact(s)?;
368    let (s, b) = time_unit(s)?;
369    Ok((
370        s,
371        TimeLiteral::Unsigned(Box::new(TimeLiteralUnsigned { nodes: (a, b) })),
372    ))
373}
374
375#[tracable_parser]
376#[packrat_parser]
377pub(crate) fn time_literal_fixed_point(s: Span) -> IResult<Span, TimeLiteral> {
378    let (s, a) = fixed_point_number_exact(s)?;
379    let (s, b) = time_unit(s)?;
380    Ok((
381        s,
382        TimeLiteral::FixedPoint(Box::new(TimeLiteralFixedPoint { nodes: (a, b) })),
383    ))
384}
385
386#[tracable_parser]
387#[packrat_parser]
388pub(crate) fn time_unit(s: Span) -> IResult<Span, TimeUnit> {
389    alt((
390        map(keyword("s"), |x| TimeUnit::S(Box::new(x))),
391        map(keyword("ms"), |x| TimeUnit::MS(Box::new(x))),
392        map(keyword("us"), |x| TimeUnit::US(Box::new(x))),
393        map(keyword("ns"), |x| TimeUnit::NS(Box::new(x))),
394        map(keyword("ps"), |x| TimeUnit::PS(Box::new(x))),
395        map(keyword("fs"), |x| TimeUnit::FS(Box::new(x))),
396    ))(s)
397}
398
399#[tracable_parser]
400#[packrat_parser]
401pub(crate) fn implicit_class_handle(s: Span) -> IResult<Span, ImplicitClassHandle> {
402    alt((
403        map(
404            triple(keyword("this"), symbol("."), keyword("super")),
405            |(x, y, z)| ImplicitClassHandle::ThisSuper(Box::new((x, y, z))),
406        ),
407        map(keyword("this"), |x| ImplicitClassHandle::This(Box::new(x))),
408        map(keyword("super"), |x| {
409            ImplicitClassHandle::Super(Box::new(x))
410        }),
411    ))(s)
412}
413
414#[tracable_parser]
415#[packrat_parser]
416pub(crate) fn bit_select(s: Span) -> IResult<Span, BitSelect> {
417    let (s, a) = many0(bracket(expression))(s)?;
418    Ok((s, BitSelect { nodes: (a,) }))
419}
420
421#[tracable_parser]
422#[packrat_parser]
423pub(crate) fn select(s: Span) -> IResult<Span, Select> {
424    let (s, a) = opt(triple(
425        many0(terminated(
426            triple(symbol("."), member_identifier, bit_select),
427            peek(symbol(".")),
428        )),
429        symbol("."),
430        member_identifier,
431    ))(s)?;
432    let (s, b) = bit_select(s)?;
433    let (s, c) = opt(bracket(part_select_range))(s)?;
434    Ok((s, Select { nodes: (a, b, c) }))
435}
436
437#[tracable_parser]
438#[packrat_parser]
439pub(crate) fn nonrange_select(s: Span) -> IResult<Span, NonrangeSelect> {
440    let (s, a) = opt(triple(
441        many0(triple(symbol("."), member_identifier, bit_select)),
442        symbol("."),
443        member_identifier,
444    ))(s)?;
445    let (s, b) = bit_select(s)?;
446    Ok((s, NonrangeSelect { nodes: (a, b) }))
447}
448
449#[tracable_parser]
450#[packrat_parser]
451pub(crate) fn constant_bit_select(s: Span) -> IResult<Span, ConstantBitSelect> {
452    let (s, a) = many0(bracket(constant_expression))(s)?;
453    Ok((s, ConstantBitSelect { nodes: (a,) }))
454}
455
456#[tracable_parser]
457#[packrat_parser]
458pub(crate) fn constant_select(s: Span) -> IResult<Span, ConstantSelect> {
459    let (s, a) = opt(triple(
460        many0(terminated(
461            triple(symbol("."), member_identifier, constant_bit_select),
462            peek(symbol(".")),
463        )),
464        symbol("."),
465        member_identifier,
466    ))(s)?;
467    let (s, b) = constant_bit_select(s)?;
468    let (s, c) = opt(bracket(constant_part_select_range))(s)?;
469    Ok((s, ConstantSelect { nodes: (a, b, c) }))
470}
471
472#[recursive_parser]
473#[tracable_parser]
474#[packrat_parser]
475pub(crate) fn constant_cast(s: Span) -> IResult<Span, ConstantCast> {
476    let (s, a) = constant_casting_type(s)?;
477    let (s, b) = symbol("'")(s)?;
478    let (s, c) = paren(constant_expression)(s)?;
479    Ok((s, ConstantCast { nodes: (a, b, c) }))
480}
481
482#[tracable_parser]
483#[packrat_parser]
484pub(crate) fn constant_let_expression(s: Span) -> IResult<Span, ConstantLetExpression> {
485    let (s, a) = let_expression(s)?;
486    Ok((s, ConstantLetExpression { nodes: (a,) }))
487}
488
489#[recursive_parser]
490#[tracable_parser]
491#[packrat_parser]
492pub(crate) fn cast(s: Span) -> IResult<Span, Cast> {
493    let (s, a) = casting_type(s)?;
494    let (s, b) = symbol("'")(s)?;
495    let (s, c) = paren(expression)(s)?;
496    Ok((s, Cast { nodes: (a, b, c) }))
497}