Handle value type names in the lexer.
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
// ====--------------------------------------------------------------------------------------====//
|
// ====--------------------------------------------------------------------------------------====//
|
||||||
|
|
||||||
use std::str::CharIndices;
|
use std::str::CharIndices;
|
||||||
|
use cretonne::types;
|
||||||
|
|
||||||
/// The location of a `Token` or `Error`.
|
/// The location of a `Token` or `Error`.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@@ -33,6 +34,7 @@ pub enum Token<'a> {
|
|||||||
Entry, // 'entry'
|
Entry, // 'entry'
|
||||||
Float(&'a str), // Floating point immediate
|
Float(&'a str), // Floating point immediate
|
||||||
Integer(&'a str), // Integer immediate
|
Integer(&'a str), // Integer immediate
|
||||||
|
Type(types::Type), // i32, f32, b32x4, ...
|
||||||
ValueDirect(u32), // v12
|
ValueDirect(u32), // v12
|
||||||
ValueExtended(u32), // vx7
|
ValueExtended(u32), // vx7
|
||||||
Ebb(u32), // ebb3
|
Ebb(u32), // ebb3
|
||||||
@@ -257,7 +259,7 @@ impl<'a> Lexer<'a> {
|
|||||||
} else {
|
} else {
|
||||||
// Look for numbered well-known entities like ebb15, v45, ...
|
// Look for numbered well-known entities like ebb15, v45, ...
|
||||||
let (prefix, suffix) = text.split_at(text.len() - trailing_digits);
|
let (prefix, suffix) = text.split_at(text.len() - trailing_digits);
|
||||||
Self::numbered_entity(prefix, suffix)
|
Self::numbered_entity(prefix, suffix).or_else(|| Self::value_type(text, prefix, suffix))
|
||||||
} {
|
} {
|
||||||
Some(t) => token(t, loc),
|
Some(t) => token(t, loc),
|
||||||
None => token(Token::Identifier(text), loc),
|
None => token(Token::Identifier(text), loc),
|
||||||
@@ -295,6 +297,39 @@ impl<'a> Lexer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recognize a scalar or vector type.
|
||||||
|
fn value_type(text: &str, prefix: &str, suffix: &str) -> Option<Token<'a>> {
|
||||||
|
let is_vector = prefix.ends_with('x');
|
||||||
|
let scalar = if is_vector {
|
||||||
|
&prefix[0..prefix.len() - 1]
|
||||||
|
} else {
|
||||||
|
text
|
||||||
|
};
|
||||||
|
let base_type = match scalar {
|
||||||
|
"i8" => types::I8,
|
||||||
|
"i16" => types::I16,
|
||||||
|
"i32" => types::I32,
|
||||||
|
"i64" => types::I64,
|
||||||
|
"f32" => types::F32,
|
||||||
|
"f64" => types::F64,
|
||||||
|
"b1" => types::B1,
|
||||||
|
"b8" => types::B8,
|
||||||
|
"b16" => types::B16,
|
||||||
|
"b32" => types::B32,
|
||||||
|
"b64" => types::B64,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
if is_vector {
|
||||||
|
let lanes: u16 = match suffix.parse() {
|
||||||
|
Ok(v) => v,
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
base_type.by(lanes).map(|t| Token::Type(t))
|
||||||
|
} else {
|
||||||
|
Some(Token::Type(base_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the next token or a lexical error.
|
/// Get the next token or a lexical error.
|
||||||
///
|
///
|
||||||
/// Return None when the end of the source is encountered.
|
/// Return None when the end of the source is encountered.
|
||||||
@@ -338,6 +373,7 @@ impl<'a> Lexer<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use cretonne::types;
|
||||||
|
|
||||||
fn token<'a>(token: Token<'a>, line: usize) -> Option<Result<LocatedToken<'a>, LocatedError>> {
|
fn token<'a>(token: Token<'a>, line: usize) -> Option<Result<LocatedToken<'a>, LocatedError>> {
|
||||||
Some(super::token(token, Location { line_number: line }))
|
Some(super::token(token, Location { line_number: line }))
|
||||||
@@ -408,7 +444,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn lex_identifiers() {
|
fn lex_identifiers() {
|
||||||
let mut lex = Lexer::new("v0 v00 vx01 ebb1234567890 ebb5234567890 entry v1x vx1 vxvx4 \
|
let mut lex = Lexer::new("v0 v00 vx01 ebb1234567890 ebb5234567890 entry v1x vx1 vxvx4 \
|
||||||
function0 function");
|
function0 function b1 i32x4 f32x5");
|
||||||
assert_eq!(lex.next(), token(Token::ValueDirect(0), 1));
|
assert_eq!(lex.next(), token(Token::ValueDirect(0), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("v00"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("v00"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("vx01"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("vx01"), 1));
|
||||||
@@ -420,6 +456,9 @@ mod tests {
|
|||||||
assert_eq!(lex.next(), token(Token::Identifier("vxvx4"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("vxvx4"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Identifier("function0"), 1));
|
assert_eq!(lex.next(), token(Token::Identifier("function0"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Function, 1));
|
assert_eq!(lex.next(), token(Token::Function, 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Type(types::B1), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Type(types::I32.by(4).unwrap()), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Identifier("f32x5"), 1));
|
||||||
assert_eq!(lex.next(), None);
|
assert_eq!(lex.next(), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user