vicis_core/ir/module/global_variable/
parser.rs1use crate::ir::{
2 module::{global_variable::GlobalVariable, linkage, name, unnamed_addr},
3 types,
4 types::Types,
5 util::spaces,
6 value,
7};
8use nom::{
9 branch::alt,
10 bytes::complete::tag,
11 character::complete::{char, digit1},
12 combinator::opt,
13 error::VerboseError,
14 sequence::preceded,
15 IResult,
16};
17
18pub fn parse<'a>(
27 source: &'a str,
28 types: &Types,
29) -> IResult<&'a str, GlobalVariable, VerboseError<&'a str>> {
30 let (source, name) = preceded(spaces, preceded(char('@'), name::parse))(source)?;
31 let (source, _) = preceded(spaces, char('='))(source)?;
32 let (source, linkage) = opt(preceded(spaces, linkage::parse))(source)?;
33 let (source, unnamed_addr) = opt(preceded(spaces, unnamed_addr::parse))(source)?;
34 let (source, kind) = preceded(spaces, alt((tag("global"), tag("constant"))))(source)?;
35 let (source, ty) = types::parse(source, types)?;
36 let (source, init) = parse_init(source, types, ty)?;
37 let (source, align) = opt(preceded(
38 spaces,
39 preceded(
40 char(','),
41 preceded(spaces, preceded(tag("align"), preceded(spaces, digit1))),
42 ),
43 ))(source)?;
44 Ok((
45 source,
46 GlobalVariable {
47 name,
48 linkage,
49 unnamed_addr,
50 is_constant: kind == "constant",
51 ty,
52 init,
53 align: align.map_or(0, |align| align.parse::<u32>().unwrap()),
54 },
55 ))
56}
57
58pub fn parse_init<'a>(
59 source: &'a str,
60 types: &Types,
61 ty: types::Type,
62) -> IResult<&'a str, Option<value::ConstantData>, VerboseError<&'a str>> {
63 if let Ok((source, init)) = value::parser::parse_constant(source, types, ty) {
64 return Ok((source, Some(init)));
65 }
66 Ok((source, None))
67}
68
69pub fn parse_global_type_and_const<'a>(
70 source: &'a str,
71 types: &Types,
72) -> IResult<&'a str, (types::Type, value::ConstantData), VerboseError<&'a str>> {
73 let (source, ty) = types::parse(source, types)?;
74 let (source, konst) = value::parser::parse_constant(source, types, ty)?;
75 Ok((source, (ty, konst)))
76}