1
- use crate :: { SectionMangler , Type } ;
1
+ use crate :: { FunctionArgument , SectionMangler , Type } ;
2
2
3
3
use std:: str;
4
4
5
5
use nom:: branch:: alt;
6
6
use nom:: bytes:: complete:: { tag, take_until1} ;
7
7
use nom:: character:: complete:: { char, digit1} ;
8
8
use nom:: combinator:: map_res;
9
- use nom:: multi:: many_m_n;
9
+ use nom:: multi:: { many0 , many_m_n} ;
10
10
use nom:: sequence:: delimited;
11
11
use nom:: { IResult , Parser } ;
12
12
@@ -85,6 +85,23 @@ fn parse_var_content<'i>(input: &'i str, name: &str) -> ParseResult<'i, SectionM
85
85
Ok ( ( input, SectionMangler :: variable ( name, ty) ) )
86
86
}
87
87
88
+ fn parse_fn_content < ' i > ( input : & ' i str , name : & str ) -> ParseResult < ' i , SectionMangler > {
89
+ let ( input, return_type) = parse_type ( input) ?;
90
+ let ( input, parameters) = delimited ( char ( '[' ) , many0 ( parse_type) , char ( ']' ) ) ( input) ?;
91
+
92
+ // TODO: Do not always encode parameters as ByValue
93
+ let mangler = parameters
94
+ . into_iter ( )
95
+ . fold ( SectionMangler :: function ( name) . with_return_type ( Some ( return_type) ) , |mangler, param| {
96
+ mangler. with_parameter ( FunctionArgument :: ByValue ( param) )
97
+ } ) ;
98
+
99
+ // TODO: Would it be better for the function to encode the number of arguments it has?
100
+ // or just parse what is in between `[]` like we do currently?
101
+
102
+ Ok ( ( input, mangler) )
103
+ }
104
+
88
105
// We don't need to handle any kind of errors, because an invalid mangled string can only be
89
106
// caused by a programming error or a mismatch in versions
90
107
impl From < & str > for SectionMangler {
@@ -94,7 +111,7 @@ impl From<&str> for SectionMangler {
94
111
95
112
match prefix {
96
113
Prefix :: Var => parse_var_content ( input, name) . unwrap ( ) . 1 ,
97
- Prefix :: Fn => todo ! ( ) ,
114
+ Prefix :: Fn => parse_fn_content ( input , name ) . unwrap ( ) . 1 ,
98
115
}
99
116
}
100
117
}
@@ -191,4 +208,24 @@ mod tests {
191
208
fn parse_variable ( ) {
192
209
let _ = SectionMangler :: from ( "$RUSTY$var-name:u8" ) ;
193
210
}
211
+
212
+ #[ test]
213
+ fn parse_function ( ) {
214
+ let _ = SectionMangler :: from ( "$RUSTY$fn-foo:u8[]" ) ;
215
+ let _ = SectionMangler :: from ( "$RUSTY$fn-foo:v[]" ) ;
216
+ let _ = SectionMangler :: from ( "$RUSTY$fn-foo:v[pvu8]" ) ;
217
+ let _ = SectionMangler :: from ( "$RUSTY$fn-foo:e156u394[pvu8r1e12u8]" ) ;
218
+ }
219
+
220
+ #[ test]
221
+ #[ should_panic]
222
+ fn parse_function_invalid_no_return_type ( ) {
223
+ let _ = SectionMangler :: from ( "$RUSTY$fn-no_return_type:[]" ) ;
224
+ }
225
+
226
+ #[ test]
227
+ #[ should_panic]
228
+ fn parse_function_invalid_no_arguments ( ) {
229
+ let _ = SectionMangler :: from ( "$RUSTY$fn-no_arguments:u16u8" ) ;
230
+ }
194
231
}
0 commit comments