1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 character::complete::{multispace0, u64},
5 sequence::delimited,
6 IResult,
7};
8
9use crate::typ::RustType;
10use crate::{labelling::Label, typ::CIntegralSize};
11
12pub fn ws<'a, F: 'a, O, E: nom::error::ParseError<&'a str>>(
15 inner: F,
16) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
17where
18 F: Fn(&'a str) -> IResult<&'a str, O, E>,
19{
20 delimited(multispace0, inner, multispace0)
21}
22
23pub fn rust_type(s: &str) -> IResult<&str, RustType> {
24 fn int(s: &str) -> IResult<&str, RustType> {
25 tag("c_int")(s).map(|(rest, _)| {
26 (
27 rest,
28 RustType::CInt {
29 unsigned: false,
30 size: CIntegralSize::Int,
31 },
32 )
33 })
34 }
35 fn ulong(s: &str) -> IResult<&str, RustType> {
36 tag("c_ulong")(s).map(|(rest, _)| {
37 (
38 rest,
39 RustType::CInt {
40 unsigned: true,
41 size: CIntegralSize::Long,
42 },
43 )
44 })
45 }
46 fn void(s: &str) -> IResult<&str, RustType> {
47 tag("c_void")(s).map(|(rest, _)| (rest, RustType::CVoid))
48 }
49 fn i32_ty(s: &str) -> IResult<&str, RustType> {
50 tag("i32")(s).map(|(rest, _)| (rest, RustType::I32))
51 }
52 fn isize(s: &str) -> IResult<&str, RustType> {
53 tag("isize")(s).map(|(rest, _)| (rest, RustType::Isize))
54 }
55 fn usize(s: &str) -> IResult<&str, RustType> {
56 tag("usize")(s).map(|(rest, _)| (rest, RustType::Usize))
57 }
58 fn size_t(s: &str) -> IResult<&str, RustType> {
59 tag("size_t")(s).map(|(rest, _)| (rest, RustType::Usize))
60 }
61 fn uint(s: &str) -> IResult<&str, RustType> {
62 tag("c_uint")(s).map(|(rest, _)| {
63 (
64 rest,
65 RustType::CInt {
66 unsigned: true,
67 size: CIntegralSize::Int,
68 },
69 )
70 })
71 }
72 fn uchar(s: &str) -> IResult<&str, RustType> {
73 tag("c_uchar")(s).map(|(rest, _)| {
74 (
75 rest,
76 RustType::CInt {
77 unsigned: true,
78 size: CIntegralSize::Char,
79 },
80 )
81 })
82 }
83 fn int_ptr(s: &str) -> IResult<&str, RustType> {
84 tag("mut_ptr_c_int")(s).map(|(rest, _)| {
85 (
86 rest,
87 RustType::Pointer(Box::new(RustType::CInt {
88 unsigned: false,
89 size: CIntegralSize::Int,
90 })),
91 )
92 })
93 }
94 fn uint_ptr(s: &str) -> IResult<&str, RustType> {
95 tag("mut_ptr_c_uint")(s).map(|(rest, _)| {
96 (
97 rest,
98 RustType::Pointer(Box::new(RustType::CInt {
99 unsigned: true,
100 size: CIntegralSize::Int,
101 })),
102 )
103 })
104 }
105 fn uchar_ptr(s: &str) -> IResult<&str, RustType> {
106 tag("mut_ptr_c_uchar")(s).map(|(rest, _)| {
107 (
108 rest,
109 RustType::Pointer(Box::new(RustType::CInt {
110 unsigned: true,
111 size: CIntegralSize::Char,
112 })),
113 )
114 })
115 }
116 fn void_ptr(s: &str) -> IResult<&str, RustType> {
117 tag("mut_ptr_c_void")(s)
118 .map(|(rest, _)| (rest, RustType::Pointer(Box::new(RustType::CVoid))))
119 }
120 fn nested_int_ptr(s: &str) -> IResult<&str, RustType> {
122 tag("mut_ptr_mut_ptr_c_int")(s).map(|(rest, _)| {
123 (
124 rest,
125 RustType::Pointer(Box::new(RustType::Pointer(Box::new(RustType::CInt {
126 unsigned: true,
127 size: CIntegralSize::Int,
128 })))),
129 )
130 })
131 }
132 fn nested_uint_ptr(s: &str) -> IResult<&str, RustType> {
133 tag("mut_ptr_mut_ptr_c_uint")(s).map(|(rest, _)| {
134 (
135 rest,
136 RustType::Pointer(Box::new(RustType::Pointer(Box::new(RustType::CInt {
137 unsigned: true,
138 size: CIntegralSize::Int,
139 })))),
140 )
141 })
142 }
143
144 alt((
145 nested_int_ptr,
146 nested_uint_ptr,
147 uint_ptr,
148 uchar_ptr,
149 void_ptr,
150 int_ptr,
151 uint,
152 size_t,
153 uchar,
154 int,
155 ulong,
156 void,
157 i32_ty,
158 isize,
159 usize,
160 ))(s)
161}
162
163pub fn label(s: &str) -> IResult<&str, Label> {
164 let (s, _) = tag("A")(s)?;
165 let (s, digits) = u64(s)?;
166 Ok((s, Label::of_raw(digits as usize)))
167}