wat_ast/
integer.rs

1use std::fmt;
2
3use wast::parser::{Cursor, Parse, Parser, Peek, Result};
4
5use crate::{AsAtoms, Atom};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub struct Integer {
9    pub(crate) sign: Option<Sign>,
10    pub(crate) src:  String,
11    pub(crate) val:  Option<String>,
12    pub(crate) hex:  Option<bool>,
13}
14
15impl Integer {
16    pub fn new(src: String) -> Self {
17        Self {
18            sign: None,
19            src,
20            val: None,
21            hex: None,
22        }
23    }
24
25    /// Returns the sign token for this integer.
26    pub fn sign(&self) -> Option<Sign> {
27        self.sign
28    }
29
30    /// Returns the original source text for this integer.
31    pub fn src(&self) -> &str {
32        &self.src
33    }
34
35    /// Returns the value string that can be parsed for this integer, as well as
36    /// the base that it should be parsed in
37    pub fn val(&self) -> (Option<&String>, Option<u32>) {
38        let hex = if let Some(h) = self.hex {
39            Some(if h { 16 } else { 10 })
40        } else {
41            None
42        };
43
44        (self.val.as_ref(), hex)
45    }
46}
47
48impl AsAtoms for Integer {
49    fn as_atoms(&self) -> Vec<Atom> {
50        vec![Atom::new(self.src.to_owned())]
51    }
52}
53
54impl fmt::Display for Integer {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        write!(f, "{}", self.src)
57    }
58}
59
60impl Parse<'_> for Integer {
61    fn parse(parser: Parser<'_>) -> Result<Self> {
62        parser.step(|cursor| match cursor.integer() {
63            Some((s, cur)) => {
64                let src = s.src().to_owned();
65                let mut sign = None;
66                let (val_ref, base) = s.val();
67                let val = Some(val_ref.to_owned());
68                let hex = Some(if base == 16 { true } else { false });
69
70                if let Some(si) = s.sign() {
71                    match si {
72                        wast::lexer::SignToken::Plus => sign = Some(Sign::Pos),
73                        wast::lexer::SignToken::Minus => sign = Some(Sign::Neg),
74                    }
75                }
76
77                Ok((
78                    Self {
79                        sign,
80                        src,
81                        val,
82                        hex,
83                    },
84                    cur,
85                ))
86            },
87            None => Err(parser.error("could not parse integer")),
88        })
89    }
90}
91
92impl Peek for Integer {
93    fn peek(cursor: Cursor<'_>) -> bool {
94        cursor.integer().is_some()
95    }
96
97    fn display() -> &'static str {
98        "integer"
99    }
100}
101
102impl From<i32> for Integer {
103    fn from(i: i32) -> Self {
104        Self::new(i.to_string())
105    }
106}
107
108#[derive(Copy, Debug, Clone, PartialEq, Eq, Hash)]
109pub enum Sign {
110    Pos,
111    Neg,
112}