1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use idents::symbol;
use numbers::number;
use whitespace::opt_space;

#[derive(Debug, PartialEq)]
pub struct Region {
    pub name: String,
    pub origin: u64,
    pub length: u64,
}

named!(attributes<&str, &str>, delimited!(
    tag!("("),
    take_until!(")"),
    tag!(")")
));

named!(origin<&str, &str>, alt_complete!(
    tag!("ORIGIN") | tag!("org") | tag!("o")
));

named!(length<&str, &str>, alt_complete!(
    tag!("LENGTH") | tag!("len") | tag!("l")
));

named!(pub region<&str, Region>, do_parse!(
    name: symbol
    >>
    opt_space
    >>
    opt!(attributes)
    >>
    wsc!(tag!(":"))
    >>
    origin
    >>
    wsc!(tag!("="))
    >>
    org: number
    >>
    wsc!(tag!(","))
    >>
    length
    >>
    wsc!(tag!("="))
    >>
    len: number
    >>
    (Region {
        name: name.into(),
        origin: org,
        length: len
    })
));

#[cfg(test)]
mod tests {
    use memory::*;

    #[test]
    fn test_region() {
        assert_done!(region("rom (rx)  : ORIGIN = 0, LENGTH = 256K"),
                     Region {
                         name: "rom".into(),
                         origin: 0,
                         length: 256 * 1024,
                     });
        assert_done!(region("ram (!rx) : org = 0x40000000, l = 4M"),
                     Region {
                         name: "ram".into(),
                         origin: 0x40000000,
                         length: 4 * 1024 * 1024,
                     });
    }
}