1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
use crate::*;

// -----------------------------------------------------------------------------

#[tracable_parser]
#[packrat_parser]
pub(crate) fn inc_or_dec_expression(s: Span) -> IResult<Span, IncOrDecExpression> {
    alt((inc_or_dec_expression_prefix, inc_or_dec_expression_suffix))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn inc_or_dec_expression_prefix(s: Span) -> IResult<Span, IncOrDecExpression> {
    let (s, a) = inc_or_dec_operator(s)?;
    let (s, b) = many0(attribute_instance)(s)?;
    let (s, c) = variable_lvalue(s)?;
    Ok((
        s,
        IncOrDecExpression::Prefix(Box::new(IncOrDecExpressionPrefix { nodes: (a, b, c) })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn inc_or_dec_expression_suffix(s: Span) -> IResult<Span, IncOrDecExpression> {
    let (s, a) = variable_lvalue(s)?;
    let (s, b) = many0(attribute_instance)(s)?;
    let (s, c) = inc_or_dec_operator(s)?;
    Ok((
        s,
        IncOrDecExpression::Suffix(Box::new(IncOrDecExpressionSuffix { nodes: (a, b, c) })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn conditional_expression(s: Span) -> IResult<Span, ConditionalExpression> {
    let (s, a) = cond_predicate_ternary(s)?;
    let (s, b) = symbol("?")(s)?;
    let (s, c) = many0(attribute_instance)(s)?;
    let (s, d) = expression(s)?;
    let (s, e) = symbol(":")(s)?;
    let (s, f) = expression(s)?;
    Ok((
        s,
        ConditionalExpression {
            nodes: (a, b, c, d, e, f),
        },
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn cond_predicate_ternary(s: Span) -> IResult<Span, CondPredicate> {
    let (s, a) = list(symbol("&&&"), expression_or_cond_pattern_ternary)(s)?;
    Ok((s, CondPredicate { nodes: (a,) }))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn expression_or_cond_pattern_ternary(
    s: Span,
) -> IResult<Span, ExpressionOrCondPattern> {
    alt((
        map(cond_pattern, |x| {
            ExpressionOrCondPattern::CondPattern(Box::new(x))
        }),
        map(expression, |x| {
            ExpressionOrCondPattern::Expression(Box::new(x))
        }),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_expression(s: Span) -> IResult<Span, ConstantExpression> {
    alt((
        constant_expression_binary,
        constant_expression_ternary,
        constant_expression_unary,
        map(constant_primary, |x| {
            ConstantExpression::ConstantPrimary(Box::new(x))
        }),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_expression_unary(s: Span) -> IResult<Span, ConstantExpression> {
    let (s, a) = unary_operator(s)?;
    let (s, b) = many0(attribute_instance)(s)?;
    let (s, c) = constant_primary(s)?;
    Ok((
        s,
        ConstantExpression::Unary(Box::new(ConstantExpressionUnary { nodes: (a, b, c) })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_expression_binary(s: Span) -> IResult<Span, ConstantExpression> {
    let (s, a) = constant_expression(s)?;
    let (s, b) = binary_operator(s)?;
    let (s, c) = many0(attribute_instance)(s)?;
    let (s, d) = constant_expression(s)?;
    Ok((
        s,
        ConstantExpression::Binary(Box::new(ConstantExpressionBinary {
            nodes: (a, b, c, d),
        })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_expression_ternary(s: Span) -> IResult<Span, ConstantExpression> {
    let (s, a) = constant_expression(s)?;
    let (s, b) = symbol("?")(s)?;
    let (s, c) = many0(attribute_instance)(s)?;
    let (s, d) = constant_expression(s)?;
    let (s, e) = symbol(":")(s)?;
    let (s, f) = constant_expression(s)?;
    Ok((
        s,
        ConstantExpression::Ternary(Box::new(ConstantExpressionTernary {
            nodes: (a, b, c, d, e, f),
        })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_mintypmax_expression(s: Span) -> IResult<Span, ConstantMintypmaxExpression> {
    alt((
        constant_mintypmax_expression_ternary,
        map(constant_expression, |x| {
            ConstantMintypmaxExpression::Unary(Box::new(x))
        }),
    ))(s)
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_mintypmax_expression_ternary(
    s: Span,
) -> IResult<Span, ConstantMintypmaxExpression> {
    let (s, a) = constant_expression(s)?;
    let (s, b) = symbol(":")(s)?;
    let (s, c) = constant_expression(s)?;
    let (s, d) = symbol(":")(s)?;
    let (s, e) = constant_expression(s)?;
    Ok((
        s,
        ConstantMintypmaxExpression::Ternary(Box::new(ConstantMintypmaxExpressionTernary {
            nodes: (a, b, c, d, e),
        })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_param_expression(s: Span) -> IResult<Span, ConstantParamExpression> {
    alt((
        map(constant_mintypmax_expression, |x| {
            ConstantParamExpression::ConstantMintypmaxExpression(Box::new(x))
        }),
        map(data_type, |x| {
            ConstantParamExpression::DataType(Box::new(x))
        }),
        map(symbol("$"), |x| {
            ConstantParamExpression::Dollar(Box::new(x))
        }),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn param_expression(s: Span) -> IResult<Span, ParamExpression> {
    alt((
        map(terminated(mintypmax_expression, peek(none_of("#"))), |x| {
            ParamExpression::MintypmaxExpression(Box::new(x))
        }),
        map(data_type, |x| ParamExpression::DataType(Box::new(x))),
        map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_range_expression(s: Span) -> IResult<Span, ConstantRangeExpression> {
    alt((
        map(constant_part_select_range, |x| {
            ConstantRangeExpression::ConstantPartSelectRange(Box::new(x))
        }),
        map(constant_expression, |x| {
            ConstantRangeExpression::ConstantExpression(Box::new(x))
        }),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_part_select_range(s: Span) -> IResult<Span, ConstantPartSelectRange> {
    alt((
        map(constant_range, |x| {
            ConstantPartSelectRange::ConstantRange(Box::new(x))
        }),
        map(constant_indexed_range, |x| {
            ConstantPartSelectRange::ConstantIndexedRange(Box::new(x))
        }),
    ))(s)
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_range(s: Span) -> IResult<Span, ConstantRange> {
    let (s, a) = constant_expression(s)?;
    let (s, b) = symbol(":")(s)?;
    let (s, c) = constant_expression(s)?;
    Ok((s, ConstantRange { nodes: (a, b, c) }))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn constant_indexed_range(s: Span) -> IResult<Span, ConstantIndexedRange> {
    let (s, a) = constant_expression(s)?;
    let (s, b) = alt((symbol("+:"), symbol("-:")))(s)?;
    let (s, c) = constant_expression(s)?;
    Ok((s, ConstantIndexedRange { nodes: (a, b, c) }))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn expression(s: Span) -> IResult<Span, Expression> {
    alt((
        map(terminated(primary, peek(one_of(",();"))), |x| {
            Expression::Primary(Box::new(x))
        }),
        expression_binary,
        map(conditional_expression, |x| {
            Expression::ConditionalExpression(Box::new(x))
        }),
        map(inside_expression, |x| {
            Expression::InsideExpression(Box::new(x))
        }),
        expression_unary,
        map(inc_or_dec_expression, |x| {
            Expression::IncOrDecExpression(Box::new(x))
        }),
        expression_operator_assignment,
        map(tagged_union_expression, |x| {
            Expression::TaggedUnionExpression(Box::new(x))
        }),
        map(primary, |x| Expression::Primary(Box::new(x))),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn expression_unary(s: Span) -> IResult<Span, Expression> {
    let (s, x) = unary_operator(s)?;
    let (s, y) = many0(attribute_instance)(s)?;
    let (s, z) = primary(s)?;
    Ok((
        s,
        Expression::Unary(Box::new(ExpressionUnary { nodes: (x, y, z) })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn expression_operator_assignment(s: Span) -> IResult<Span, Expression> {
    let (s, a) = paren(operator_assignment)(s)?;
    Ok((
        s,
        Expression::OperatorAssignment(Box::new(ExpressionOperatorAssignment { nodes: (a,) })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn expression_binary(s: Span) -> IResult<Span, Expression> {
    let (s, a) = expression(s)?;
    let (s, b) = binary_operator(s)?;
    let (s, c) = many0(attribute_instance)(s)?;
    let (s, d) = expression(s)?;
    Ok((
        s,
        Expression::Binary(Box::new(ExpressionBinary {
            nodes: (a, b, c, d),
        })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn tagged_union_expression(s: Span) -> IResult<Span, TaggedUnionExpression> {
    let (s, a) = keyword("tagged")(s)?;
    let (s, b) = member_identifier(s)?;
    let (s, c) = opt(expression)(s)?;
    Ok((s, TaggedUnionExpression { nodes: (a, b, c) }))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn inside_expression(s: Span) -> IResult<Span, InsideExpression> {
    let (s, a) = expression(s)?;
    let (s, b) = keyword("inside")(s)?;
    let (s, c) = brace(open_range_list)(s)?;
    Ok((s, InsideExpression { nodes: (a, b, c) }))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn value_range(s: Span) -> IResult<Span, ValueRange> {
    alt((
        value_range_binary,
        map(expression, |x| ValueRange::Expression(Box::new(x))),
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn value_range_binary(s: Span) -> IResult<Span, ValueRange> {
    let (s, a) = bracket(triple(expression, symbol(":"), expression))(s)?;
    Ok((
        s,
        ValueRange::Binary(Box::new(ValueRangeBinary { nodes: (a,) })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn mintypmax_expression(s: Span) -> IResult<Span, MintypmaxExpression> {
    alt((
        mintypmax_expression_ternary,
        map(expression, |x| MintypmaxExpression::Expression(Box::new(x))),
    ))(s)
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn mintypmax_expression_ternary(s: Span) -> IResult<Span, MintypmaxExpression> {
    let (s, a) = expression(s)?;
    let (s, b) = symbol(":")(s)?;
    let (s, c) = expression(s)?;
    let (s, d) = symbol(":")(s)?;
    let (s, e) = expression(s)?;
    Ok((
        s,
        MintypmaxExpression::Ternary(Box::new(MintypmaxExpressionTernary {
            nodes: (a, b, c, d, e),
        })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn module_path_conditional_expression(
    s: Span,
) -> IResult<Span, ModulePathConditionalExpression> {
    let (s, a) = module_path_expression(s)?;
    let (s, b) = symbol("?")(s)?;
    let (s, c) = many0(attribute_instance)(s)?;
    let (s, d) = module_path_expression(s)?;
    let (s, e) = symbol(":")(s)?;
    let (s, f) = module_path_expression(s)?;
    Ok((
        s,
        ModulePathConditionalExpression {
            nodes: (a, b, c, d, e, f),
        },
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn module_path_expression(s: Span) -> IResult<Span, ModulePathExpression> {
    alt((
        module_path_expression_binary,
        map(module_path_conditional_expression, |x| {
            ModulePathExpression::ModulePathConditionalExpression(Box::new(x))
        }),
        map(module_path_primary, |x| {
            ModulePathExpression::ModulePathPrimary(Box::new(x))
        }),
        module_path_expression_unary,
    ))(s)
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn module_path_expression_unary(s: Span) -> IResult<Span, ModulePathExpression> {
    let (s, a) = unary_module_path_operator(s)?;
    let (s, b) = many0(attribute_instance)(s)?;
    let (s, c) = module_path_primary(s)?;
    Ok((
        s,
        ModulePathExpression::Unary(Box::new(ModulePathExpressionUnary { nodes: (a, b, c) })),
    ))
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn module_path_expression_binary(s: Span) -> IResult<Span, ModulePathExpression> {
    let (s, a) = module_path_expression(s)?;
    let (s, b) = binary_module_path_operator(s)?;
    let (s, c) = many0(attribute_instance)(s)?;
    let (s, d) = module_path_expression(s)?;
    Ok((
        s,
        ModulePathExpression::Binary(Box::new(ModulePathExpressionBinary {
            nodes: (a, b, c, d),
        })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn module_path_mintypmax_expression(
    s: Span,
) -> IResult<Span, ModulePathMintypmaxExpression> {
    alt((
        module_path_mintypmax_expression_ternary,
        map(module_path_expression, |x| {
            ModulePathMintypmaxExpression::ModulePathExpression(Box::new(x))
        }),
    ))(s)
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn module_path_mintypmax_expression_ternary(
    s: Span,
) -> IResult<Span, ModulePathMintypmaxExpression> {
    let (s, a) = module_path_expression(s)?;
    let (s, b) = symbol(":")(s)?;
    let (s, c) = module_path_expression(s)?;
    let (s, d) = symbol(":")(s)?;
    let (s, e) = module_path_expression(s)?;
    Ok((
        s,
        ModulePathMintypmaxExpression::Ternary(Box::new(ModulePathMintypmaxExpressionTernary {
            nodes: (a, b, c, d, e),
        })),
    ))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn part_select_range(s: Span) -> IResult<Span, PartSelectRange> {
    alt((
        map(constant_range, |x| {
            PartSelectRange::ConstantRange(Box::new(x))
        }),
        map(indexed_range, |x| {
            PartSelectRange::IndexedRange(Box::new(x))
        }),
    ))(s)
}

#[recursive_parser]
#[tracable_parser]
#[packrat_parser]
pub(crate) fn indexed_range(s: Span) -> IResult<Span, IndexedRange> {
    let (s, a) = expression(s)?;
    let (s, b) = alt((symbol("+:"), symbol("-:")))(s)?;
    let (s, c) = constant_expression(s)?;
    Ok((s, IndexedRange { nodes: (a, b, c) }))
}

#[tracable_parser]
#[packrat_parser]
pub(crate) fn genvar_expression(s: Span) -> IResult<Span, GenvarExpression> {
    let (s, a) = constant_expression(s)?;
    Ok((s, GenvarExpression { nodes: (a,) }))
}