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 pub fn sign(&self) -> Option<Sign> {
27 self.sign
28 }
29
30 pub fn src(&self) -> &str {
32 &self.src
33 }
34
35 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}