Add hexadecimal numerics
This commit is contained in:
parent
a3d923da12
commit
a09bccb255
@ -1,6 +1,6 @@
|
||||
// Main
|
||||
fn main() -> bool {
|
||||
return 5 == fibonacci(5);
|
||||
return 144 == fibonacci(0xc);
|
||||
}
|
||||
|
||||
// Fibonacci
|
||||
|
@ -153,6 +153,16 @@ impl Parse for PrimaryExpression {
|
||||
Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
|
||||
}
|
||||
}
|
||||
Token::HexadecimalValue(v) => {
|
||||
stream.next(); // Consume hexadecimal
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
u128::from_str_radix(&v, 16)
|
||||
.expect("Hexadecimal is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
}
|
||||
Token::DecimalValue(v) => {
|
||||
stream.next(); // Consume decimal
|
||||
if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) =
|
||||
@ -172,7 +182,8 @@ impl Parse for PrimaryExpression {
|
||||
} else {
|
||||
Expression(
|
||||
Kind::Literal(Literal::Integer(
|
||||
v.parse().expect("Integer is not parseable as u128!"),
|
||||
u128::from_str_radix(&v, 10)
|
||||
.expect("Integer is not parseable as u128!"),
|
||||
)),
|
||||
stream.get_range().unwrap(),
|
||||
)
|
||||
|
@ -1,13 +1,24 @@
|
||||
use std::{fmt::Debug, str::Chars};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
ops::{Add, AddAssign},
|
||||
str::Chars,
|
||||
};
|
||||
|
||||
static BINARY_NUMERICS: &[char] = &['0', '1'];
|
||||
static OCTAL_NUMERICS: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7'];
|
||||
static DECIMAL_NUMERICS: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
static HEXADECIMAL_NUMERICS: &[char] = &[
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
];
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, PartialOrd, Ord)]
|
||||
pub enum Token {
|
||||
/// Values
|
||||
Identifier(String),
|
||||
/// Number with at most one decimal point
|
||||
/// Number in the decimal base
|
||||
DecimalValue(String),
|
||||
/// Integer number in the hexadecimal base
|
||||
HexadecimalValue(String),
|
||||
/// Some character literal that was surrounded by 'single-quotes'.
|
||||
CharLit(String),
|
||||
/// Some string literal that was surrounded by "double-quotes".
|
||||
@ -130,6 +141,7 @@ impl ToString for Token {
|
||||
match &self {
|
||||
Token::Identifier(ident) => ident.clone(),
|
||||
Token::DecimalValue(val) => val.to_string(),
|
||||
Token::HexadecimalValue(val) => val.to_string(),
|
||||
Token::CharLit(lit) => format!("\'{}\'", lit),
|
||||
Token::StringLit(lit) => format!("\"{}\"", lit),
|
||||
Token::LetKeyword => String::from("let"),
|
||||
@ -348,15 +360,26 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
||||
}
|
||||
// Decimals
|
||||
c if DECIMAL_NUMERICS.contains(c) => {
|
||||
let mut value = character.to_string();
|
||||
let mut value = NumberType::Decimal(character.to_string());
|
||||
let mut numerics = DECIMAL_NUMERICS;
|
||||
if let Some(second) = cursor.second() {
|
||||
if cursor.first() == Some('x') && HEXADECIMAL_NUMERICS.contains(&second) {
|
||||
cursor.next();
|
||||
value = NumberType::Hexadecimal(String::new());
|
||||
numerics = HEXADECIMAL_NUMERICS;
|
||||
}
|
||||
}
|
||||
while let Some(c) = cursor.first() {
|
||||
if !DECIMAL_NUMERICS.contains(&c) {
|
||||
if !numerics.contains(&c) {
|
||||
break;
|
||||
}
|
||||
value += &c.to_string();
|
||||
value += c;
|
||||
cursor.next();
|
||||
}
|
||||
Token::DecimalValue(value)
|
||||
match value {
|
||||
NumberType::Decimal(value) => Token::DecimalValue(value),
|
||||
NumberType::Hexadecimal(hex) => Token::HexadecimalValue(hex),
|
||||
}
|
||||
}
|
||||
'-' if cursor.first() == Some('>') => {
|
||||
cursor.next(); // Eat `>`
|
||||
@ -411,6 +434,22 @@ fn escape_char(c: &char) -> char {
|
||||
}
|
||||
}
|
||||
|
||||
enum NumberType {
|
||||
Decimal(String),
|
||||
Hexadecimal(String),
|
||||
}
|
||||
|
||||
impl AddAssign<char> for NumberType {
|
||||
fn add_assign(&mut self, rhs: char) {
|
||||
*self = match self {
|
||||
NumberType::Decimal(val) => NumberType::Decimal(val.to_owned() + &rhs.to_string()),
|
||||
NumberType::Hexadecimal(val) => {
|
||||
NumberType::Hexadecimal(val.to_owned() + &rhs.to_string())
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Error {
|
||||
#[error("Invalid token '{}' ", .0)]
|
||||
|
@ -78,7 +78,7 @@ pub fn parse_module<'map, T: Into<String>>(
|
||||
map.set_tokens(id, tokens.clone());
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
dbg!(&tokens);
|
||||
println!("{:#?}", &tokens);
|
||||
|
||||
Ok((id, tokens))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user