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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use wast::parser::{Cursor, Parse, Parser, Peek, Result};
use crate::{Integer, Sign};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Index<'a> {
Numeric(NumericIndex<'a>),
Symbolic(SymbolicIndex<'a>),
}
impl<'a> Parse<'a> for Index<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
match parser.parse::<NumericIndex>() {
Ok(ni) => Ok(Self::Numeric(ni)),
Err(_) => match parser.parse::<SymbolicIndex>() {
Ok(si) => Ok(Self::Symbolic(si)),
Err(err) => Err(err),
},
}
}
}
impl Peek for Index<'_> {
fn peek(cursor: Cursor<'_>) -> bool {
cursor.id().is_some() || cursor.integer().is_some()
}
fn display() -> &'static str {
"an index"
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Indexes<'a> {
pub ids: Vec<Index<'a>>,
}
impl<'a> Parse<'a> for Indexes<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut ids = Vec::new();
while parser.peek::<Index>() {
ids.push(parser.parse()?);
}
Ok(Self { ids })
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NumericIndex<'a> {
i: Integer<'a>,
span: wast::Span,
}
impl<'a> NumericIndex<'a> {
pub fn span(&self) -> wast::Span {
self.span
}
pub fn sign(&self) -> Option<Sign> {
self.i.sign()
}
pub fn src(&self) -> &'a str {
self.i.src()
}
pub fn val(&self) -> (&str, u32) {
self.i.val()
}
}
impl<'a> Parse<'a> for NumericIndex<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.cur_span();
let int = parser.step(|cursor| match cursor.integer() {
Some((i, cur)) => Ok((i, cur)),
None => Err(cursor.error("not an integer")),
})?;
let sign = int.sign().map(|s| match s {
wast::lexer::SignToken::Plus => Sign::Pos,
wast::lexer::SignToken::Minus => Sign::Neg,
});
let (val, radix) = int.val();
let hex = if radix == 16 { true } else { false };
let i = Integer::new(sign, int.src(), val, hex);
Ok(Self { i, span })
}
}
impl Peek for NumericIndex<'_> {
fn peek(cursor: Cursor<'_>) -> bool {
cursor.integer().is_some()
}
fn display() -> &'static str {
"a numeric index"
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SymbolicIndex<'a>(wast::Id<'a>);
impl<'a> SymbolicIndex<'a> {
pub fn name(&self) -> &'a str {
self.0.name()
}
pub fn span(&self) -> wast::Span {
self.0.span()
}
}
impl<'a> Parse<'a> for SymbolicIndex<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let id = parser.parse::<wast::Id>()?;
Ok(Self(id))
}
}
impl Peek for SymbolicIndex<'_> {
fn peek(cursor: Cursor<'_>) -> bool {
cursor.id().is_some()
}
fn display() -> &'static str {
"a symbolic index"
}
}