Add Offset32 support to the parser.
This commit is contained in:
@@ -223,7 +223,7 @@ impl<'a> Lexer<'a> {
|
|||||||
// - `0x0.4p-34`: Float
|
// - `0x0.4p-34`: Float
|
||||||
//
|
//
|
||||||
// This function does not filter out all invalid numbers. It depends in the context-sensitive
|
// 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.
|
// an `Ieee64` constant are different.
|
||||||
fn scan_number(&mut self) -> Result<LocatedToken<'a>, LocatedError> {
|
fn scan_number(&mut self) -> Result<LocatedToken<'a>, LocatedError> {
|
||||||
let begin = self.pos;
|
let begin = self.pos;
|
||||||
@@ -231,15 +231,21 @@ impl<'a> Lexer<'a> {
|
|||||||
let mut is_float = false;
|
let mut is_float = false;
|
||||||
|
|
||||||
// Skip a leading sign.
|
// Skip a leading sign.
|
||||||
if self.lookahead == Some('-') {
|
match self.lookahead {
|
||||||
self.next_ch();
|
Some('-') => {
|
||||||
|
self.next_ch();
|
||||||
|
|
||||||
if let Some(c) = self.lookahead {
|
if let Some(c) = self.lookahead {
|
||||||
// If the next character won't parse as a number, we return Token::Minus
|
// If the next character won't parse as a number, we return Token::Minus
|
||||||
if !c.is_alphanumeric() && c != '.' {
|
if !c.is_alphanumeric() && c != '.' {
|
||||||
return token(Token::Minus, loc);
|
return token(Token::Minus, loc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some('+') => {
|
||||||
|
self.next_ch();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for NaNs with payloads.
|
// 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::Dot)),
|
||||||
Some(':') => Some(self.scan_char(Token::Colon)),
|
Some(':') => Some(self.scan_char(Token::Colon)),
|
||||||
Some('=') => Some(self.scan_char(Token::Equal)),
|
Some('=') => Some(self.scan_char(Token::Equal)),
|
||||||
|
Some('+') => Some(self.scan_number()),
|
||||||
Some('-') => {
|
Some('-') => {
|
||||||
if self.looking_at("->") {
|
if self.looking_at("->") {
|
||||||
Some(self.scan_chars(2, Token::Arrow))
|
Some(self.scan_chars(2, Token::Arrow))
|
||||||
@@ -506,7 +513,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lex_numbers() {
|
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("0"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Integer("2_000"), 1));
|
assert_eq!(lex.next(), token(Token::Integer("2_000"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Integer("-1"), 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::Integer("-0x0"), 1));
|
||||||
assert_eq!(lex.next(), token(Token::Float("0.0"), 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::Float("0x0.4p-34"), 1));
|
||||||
|
assert_eq!(lex.next(), token(Token::Integer("+5"), 1));
|
||||||
assert_eq!(lex.next(), None);
|
assert_eq!(lex.next(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use cretonne::ir::{Function, Ebb, Opcode, Value, Type, FunctionName, StackSlotDa
|
|||||||
JumpTableData, Signature, ArgumentType, ArgumentExtension, ExtFuncData, SigRef,
|
JumpTableData, Signature, ArgumentType, ArgumentExtension, ExtFuncData, SigRef,
|
||||||
FuncRef, ValueLoc, ArgumentLoc};
|
FuncRef, ValueLoc, ArgumentLoc};
|
||||||
use cretonne::ir::types::VOID;
|
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::entities::AnyEntity;
|
||||||
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs};
|
use cretonne::ir::instructions::{InstructionFormat, InstructionData, VariableArgs};
|
||||||
use cretonne::isa::{self, TargetIsa, Encoding};
|
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.
|
// Match and consume an Ieee32 immediate.
|
||||||
fn match_ieee32(&mut self, err_msg: &str) -> Result<Ieee32> {
|
fn match_ieee32(&mut self, err_msg: &str) -> Result<Ieee32> {
|
||||||
if let Some(Token::Float(text)) = self.token() {
|
if let Some(Token::Float(text)) = self.token() {
|
||||||
|
|||||||
Reference in New Issue
Block a user