Skip to content

Commit aeef226

Browse files
committed
section_mangler: Add parsing of mangled functions
1 parent 2314f66 commit aeef226

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

compiler/section_mangler/src/parser.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use crate::{SectionMangler, Type};
1+
use crate::{FunctionArgument, SectionMangler, Type};
22

33
use std::str;
44

55
use nom::branch::alt;
66
use nom::bytes::complete::{tag, take_until1};
77
use nom::character::complete::{char, digit1};
88
use nom::combinator::map_res;
9-
use nom::multi::many_m_n;
9+
use nom::multi::{many0, many_m_n};
1010
use nom::sequence::delimited;
1111
use nom::{IResult, Parser};
1212

@@ -85,6 +85,23 @@ fn parse_var_content<'i>(input: &'i str, name: &str) -> ParseResult<'i, SectionM
8585
Ok((input, SectionMangler::variable(name, ty)))
8686
}
8787

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+
88105
// We don't need to handle any kind of errors, because an invalid mangled string can only be
89106
// caused by a programming error or a mismatch in versions
90107
impl From<&str> for SectionMangler {
@@ -94,7 +111,7 @@ impl From<&str> for SectionMangler {
94111

95112
match prefix {
96113
Prefix::Var => parse_var_content(input, name).unwrap().1,
97-
Prefix::Fn => todo!(),
114+
Prefix::Fn => parse_fn_content(input, name).unwrap().1,
98115
}
99116
}
100117
}
@@ -191,4 +208,24 @@ mod tests {
191208
fn parse_variable() {
192209
let _ = SectionMangler::from("$RUSTY$var-name:u8");
193210
}
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+
}
194231
}

0 commit comments

Comments
 (0)