Add Offset32 support to the parser.

This commit is contained in:
Jakob Stoklund Olesen
2017-04-10 13:03:46 -07:00
parent ab1e51002d
commit af2516e996
2 changed files with 33 additions and 9 deletions

View File

@@ -223,7 +223,7 @@ impl<'a> Lexer<'a> {
// - `0x0.4p-34`: Float
//
// This function does not filter out all invalid numbers. It depends in the context-sensitive
// decoding of the text for that. For example, the number of allowed digits an an Ieee32` and
// decoding of the text for that. For example, the number of allowed digits in an `Ieee32` and
// an `Ieee64` constant are different.
fn scan_number(&mut self) -> Result<LocatedToken<'a>, LocatedError> {
let begin = self.pos;
@@ -231,15 +231,21 @@ impl<'a> Lexer<'a> {
let mut is_float = false;
// Skip a leading sign.
if self.lookahead == Some('-') {
self.next_ch();
match self.lookahead {
Some('-') => {
self.next_ch();
if let Some(c) = self.lookahead {
// If the next character won't parse as a number, we return Token::Minus
if !c.is_alphanumeric() && c != '.' {
return token(Token::Minus, loc);
if let Some(c) = self.lookahead {
// If the next character won't parse as a number, we return Token::Minus
if !c.is_alphanumeric() && c != '.' {
return token(Token::Minus, loc);
}
}
}
Some('+') => {
self.next_ch();
}
_ => {}
}
// Check for NaNs with payloads.
@@ -395,6 +401,7 @@ impl<'a> Lexer<'a> {
Some('.') => Some(self.scan_char(Token::Dot)),
Some(':') => Some(self.scan_char(Token::Colon)),
Some('=') => Some(self.scan_char(Token::Equal)),
Some('+') => Some(self.scan_number()),
Some('-') => {
if self.looking_at("->") {
Some(self.scan_chars(2, Token::Arrow))
@@ -506,7 +513,7 @@ mod tests {
#[test]
fn lex_numbers() {
let mut lex = Lexer::new(" 0 2_000 -1,0xf -0x0 0.0 0x0.4p-34");
let mut lex = Lexer::new(" 0 2_000 -1,0xf -0x0 0.0 0x0.4p-34 +5");
assert_eq!(lex.next(), token(Token::Integer("0"), 1));
assert_eq!(lex.next(), token(Token::Integer("2_000"), 1));
assert_eq!(lex.next(), token(Token::Integer("-1"), 1));
@@ -515,6 +522,7 @@ mod tests {
assert_eq!(lex.next(), token(Token::Integer("-0x0"), 1));
assert_eq!(lex.next(), token(Token::Float("0.0"), 1));
assert_eq!(lex.next(), token(Token::Float("0x0.4p-34"), 1));
assert_eq!(lex.next(), token(Token::Integer("+5"), 1));
assert_eq!(lex.next(), None);
}

View File

@@ -13,7 +13,7 @@ use cretonne::ir::{Function, Ebb, Opcode, Value, Type, FunctionName, StackSlotDa
JumpTableData, Signature, ArgumentType, ArgumentExtension, ExtFuncData, SigRef,
FuncRef, ValueLoc, ArgumentLoc};
use cretonne::ir::types::VOID;
use cretonne::ir::immediates::{Imm64, Ieee32, Ieee64};
use cretonne::ir::immediates::{Imm64, Offset32, Ieee32, Ieee64};
use cretonne::ir::entities::AnyEntity;
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs};
use cretonne::isa::{self, TargetIsa, Encoding};
@@ -497,6 +497,22 @@ impl<'a> Parser<'a> {
}
}
// Match and consume an optional offset32 immediate.
//
// Note that that this will match an empty string as an empty offset, and that if an offset is
// present, it must contain a sign.
fn optional_offset32(&mut self) -> Result<Offset32> {
if let Some(Token::Integer(text)) = self.token() {
self.consume();
// Lexer just gives us raw text that looks like an integer.
// Parse it as an `Offset32` to check for overflow and other issues.
text.parse().map_err(|e| self.error(e))
} else {
// An offset32 operand can be absent.
Ok(Offset32::new(0))
}
}
// Match and consume an Ieee32 immediate.
fn match_ieee32(&mut self, err_msg: &str) -> Result<Ieee32> {
if let Some(Token::Float(text)) = self.token() {