reader: lex UserRefs and parse ExternalName::Users
This commit is contained in:
committed by
Jakob Stoklund Olesen
parent
894268233e
commit
2dfc78dbcd
@@ -38,6 +38,7 @@ pub enum Token<'a> {
|
|||||||
JumpTable(u32), // jt2
|
JumpTable(u32), // jt2
|
||||||
FuncRef(u32), // fn2
|
FuncRef(u32), // fn2
|
||||||
SigRef(u32), // sig2
|
SigRef(u32), // sig2
|
||||||
|
UserRef(u32), // u345
|
||||||
Name(&'a str), // %9arbitrary_alphanum, %x3, %0, %function ...
|
Name(&'a str), // %9arbitrary_alphanum, %x3, %0, %function ...
|
||||||
HexSequence(&'a str), // #89AF
|
HexSequence(&'a str), // #89AF
|
||||||
Identifier(&'a str), // Unrecognized identifier (opcode, enumerator, ...)
|
Identifier(&'a str), // Unrecognized identifier (opcode, enumerator, ...)
|
||||||
@@ -320,6 +321,7 @@ impl<'a> Lexer<'a> {
|
|||||||
"jt" => Some(Token::JumpTable(number)),
|
"jt" => Some(Token::JumpTable(number)),
|
||||||
"fn" => Some(Token::FuncRef(number)),
|
"fn" => Some(Token::FuncRef(number)),
|
||||||
"sig" => Some(Token::SigRef(number)),
|
"sig" => Some(Token::SigRef(number)),
|
||||||
|
"u" => Some(Token::UserRef(number)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,4 +606,17 @@ mod tests {
|
|||||||
assert_eq!(lex.next(), token(Token::Name("ebb11"), 1));
|
assert_eq!(lex.next(), token(Token::Name("ebb11"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Name("_"), 1));
|
assert_eq!(lex.next(), token(Token::Name("_"), 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lex_userrefs() {
|
||||||
|
let mut lex = Lexer::new("u0 u1 u234567890 u9:8765");
|
||||||
|
|
||||||
|
assert_eq!(lex.next(), token(Token::UserRef(0), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::UserRef(1), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::UserRef(234567890), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::UserRef(9), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Colon, 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Integer("8765"), 1));
|
||||||
|
assert_eq!(lex.next(), None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -890,24 +890,26 @@ impl<'a> Parser<'a> {
|
|||||||
match self.token() {
|
match self.token() {
|
||||||
Some(Token::Name(s)) => {
|
Some(Token::Name(s)) => {
|
||||||
self.consume();
|
self.consume();
|
||||||
Ok(ExternalName::new(s))
|
Ok(ExternalName::testcase(s))
|
||||||
}
|
}
|
||||||
Some(Token::HexSequence(s)) => {
|
Some(Token::UserRef(namespace)) => {
|
||||||
if s.len() % 2 != 0 {
|
|
||||||
return err!(
|
|
||||||
self.loc,
|
|
||||||
"expected binary external name to have length multiple of two"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let mut bin_name = Vec::with_capacity(s.len() / 2);
|
|
||||||
let mut i = 0;
|
|
||||||
while i + 2 <= s.len() {
|
|
||||||
let byte = u8::from_str_radix(&s[i..i + 2], 16).unwrap();
|
|
||||||
bin_name.push(byte);
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
self.consume();
|
self.consume();
|
||||||
Ok(ExternalName::new(bin_name))
|
match self.token() {
|
||||||
|
Some(Token::Colon) => {
|
||||||
|
self.consume();
|
||||||
|
match self.token() {
|
||||||
|
Some(Token::Integer(index_str)) => {
|
||||||
|
let index: u32 = u32::from_str_radix(index_str, 10).map_err(|_| {
|
||||||
|
self.error("the integer given overflows the u32 type")
|
||||||
|
})?;
|
||||||
|
self.consume();
|
||||||
|
Ok(ExternalName::user(namespace, index))
|
||||||
|
}
|
||||||
|
_ => err!(self.loc, "expected integer"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => err!(self.loc, "expected colon"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => err!(self.loc, "expected external name"),
|
_ => err!(self.loc, "expected external name"),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user