@@ -29,8 +29,8 @@ use std::ops::{
29
29
use crate :: literal:: { self , CChar } ;
30
30
use crate :: token:: { Kind as TokenKind , Token } ;
31
31
use crate :: ToCexprResult ;
32
- use nom:: branch:: alt;
33
- use nom:: combinator:: { complete, map, map_opt} ;
32
+ use nom:: branch:: { alt, permutation } ;
33
+ use nom:: combinator:: { complete, map, map_opt, opt } ;
34
34
use nom:: multi:: { fold_many0, many0, separated_list0} ;
35
35
use nom:: sequence:: { delimited, pair, preceded} ;
36
36
use nom:: * ;
@@ -54,6 +54,7 @@ pub enum EvalResult {
54
54
Float ( f64 ) ,
55
55
Char ( CChar ) ,
56
56
Str ( Vec < u8 > ) ,
57
+ Cast ( Vec < Vec < u8 > > , Box < Self > ) ,
57
58
Invalid ,
58
59
}
59
60
@@ -126,6 +127,10 @@ fn identifier_token(input: &[Token]) -> CResult<'_, &[u8]> {
126
127
}
127
128
}
128
129
130
+ fn keyword ( c : & ' static str ) -> impl Fn ( & [ Token ] ) -> CResult < ' _ , & [ u8 ] > {
131
+ exact_token ! ( Keyword , c. as_bytes( ) )
132
+ }
133
+
129
134
fn p ( c : & ' static str ) -> impl Fn ( & [ Token ] ) -> CResult < ' _ , & [ u8 ] > {
130
135
exact_token ! ( Punctuation , c. as_bytes( ) )
131
136
}
@@ -289,6 +294,10 @@ where
289
294
nom:: combinator:: map_opt ( f, EvalResult :: as_numeric)
290
295
}
291
296
297
+ fn expr_cast ( input : ( Vec < Vec < u8 > > , EvalResult ) ) -> EvalResult {
298
+ EvalResult :: Cast ( input. 0 , Box :: new ( input. 1 ) )
299
+ }
300
+
292
301
impl < ' a > PRef < ' a > {
293
302
fn unary ( self , input : & ' _ [ Token ] ) -> CResult < ' _ , EvalResult > {
294
303
alt ( (
@@ -473,6 +482,10 @@ impl<'a> PRef<'a> {
473
482
474
483
fn expr ( self , input : & ' _ [ Token ] ) -> CResult < ' _ , EvalResult > {
475
484
alt ( (
485
+ map (
486
+ pair ( |i| self . cast ( i) , |i| self . expr ( i) ) ,
487
+ expr_cast
488
+ ) ,
476
489
|i| self . numeric_expr ( i) ,
477
490
delimited ( p ( "(" ) , |i| self . expr ( i) , p ( ")" ) ) ,
478
491
|i| self . concat_str ( i) ,
@@ -482,6 +495,88 @@ impl<'a> PRef<'a> {
482
495
. to_cexpr_result ( )
483
496
}
484
497
498
+ fn cast ( self , input : & ' _ [ Token ] ) -> CResult < ' _ , Vec < Vec < u8 > > > {
499
+ delimited ( p ( "(" ) , |i| self . ty ( i) , p ( ")" ) ) ( input)
500
+ }
501
+
502
+ fn int_ty ( input : & ' _ [ Token ] ) -> CResult < ' _ , Vec < & [ u8 ] > > {
503
+ fn int_signedness ( input : & ' _ [ Token ] ) -> CResult < ' _ , & [ u8 ] > {
504
+ alt ( (
505
+ keyword ( "unsigned" ) ,
506
+ keyword ( "signed" ) ,
507
+ ) ) ( input)
508
+ }
509
+
510
+ fn int_longness ( input : & ' _ [ Token ] ) -> CResult < ' _ , & [ u8 ] > {
511
+ alt ( (
512
+ keyword ( "short" ) ,
513
+ keyword ( "long" ) ,
514
+ ) ) ( input)
515
+ }
516
+
517
+ alt ( (
518
+ // [const] [(un)signed] long long [int]
519
+ map (
520
+ permutation ( ( opt ( keyword ( "const" ) ) , opt ( int_signedness) , keyword ( "long" ) , keyword ( "long" ) , opt ( keyword ( "int" ) ) ) ) ,
521
+ |( _, s, i1, i2, _) | if let Some ( s) = s {
522
+ if s == b"signed" {
523
+ vec ! [ i1, i2]
524
+ } else {
525
+ vec ! [ s, i1, i2]
526
+ }
527
+ } else {
528
+ vec ! [ i1, i2]
529
+ } ,
530
+ ) ,
531
+ // [const] [(un)signed] long/short [int]
532
+ map (
533
+ permutation ( ( opt ( keyword ( "const" ) ) , opt ( int_signedness) , int_longness, opt ( keyword ( "int" ) ) ) ) ,
534
+ |( _, s, i, _) | if let Some ( s) = s {
535
+ if s == b"signed" {
536
+ vec ! [ i]
537
+ } else {
538
+ vec ! [ s, i]
539
+ }
540
+ } else {
541
+ vec ! [ i]
542
+ } ,
543
+ ) ,
544
+ // [const] [(un)signed] char/int
545
+ map (
546
+ permutation ( ( opt ( keyword ( "const" ) ) , opt ( int_signedness) , alt ( ( keyword ( "char" ) , keyword ( "int" ) ) ) ) ) ,
547
+ |( _, s, i) | if let Some ( s) = s {
548
+ if s == b"signed" && i == b"int" {
549
+ vec ! [ i]
550
+ } else {
551
+ vec ! [ s, i]
552
+ }
553
+ } else {
554
+ vec ! [ i]
555
+ } ,
556
+ ) ,
557
+ ) ) ( input)
558
+ }
559
+
560
+ fn ty ( self , input : & ' _ [ Token ] ) -> CResult < ' _ , Vec < Vec < u8 > > > {
561
+ map (
562
+ alt ( (
563
+ // [const] <identifier>
564
+ map (
565
+ permutation ( ( opt ( keyword ( "const" ) ) , identifier_token) ) ,
566
+ |( _, id) | vec ! [ id] ,
567
+ ) ,
568
+ // [const] bool
569
+ map (
570
+ permutation ( ( opt ( keyword ( "const" ) ) , keyword ( "bool" ) ) ) ,
571
+ |( _, b) | vec ! [ b] ,
572
+ ) ,
573
+ Self :: int_ty,
574
+ ) ) ,
575
+ |v| v. into_iter ( ) . map ( |t| t. to_vec ( ) ) . collect ( ) ,
576
+ ) ( input)
577
+ . to_cexpr_result ( )
578
+ }
579
+
485
580
fn macro_definition ( self , input : & ' _ [ Token ] ) -> CResult < ' _ , ( & ' _ [ u8 ] , EvalResult ) > {
486
581
pair ( identifier_token, |i| self . expr ( i) ) ( input)
487
582
}
0 commit comments