Add hexadecimal numerics
This commit is contained in:
parent
a3d923da12
commit
a09bccb255
@ -1,6 +1,6 @@
|
|||||||
// Main
|
// Main
|
||||||
fn main() -> bool {
|
fn main() -> bool {
|
||||||
return 5 == fibonacci(5);
|
return 144 == fibonacci(0xc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fibonacci
|
// Fibonacci
|
||||||
|
@ -153,6 +153,16 @@ impl Parse for PrimaryExpression {
|
|||||||
Expression(Kind::VariableName(v.clone()), stream.get_range().unwrap())
|
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) => {
|
Token::DecimalValue(v) => {
|
||||||
stream.next(); // Consume decimal
|
stream.next(); // Consume decimal
|
||||||
if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) =
|
if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) =
|
||||||
@ -172,7 +182,8 @@ impl Parse for PrimaryExpression {
|
|||||||
} else {
|
} else {
|
||||||
Expression(
|
Expression(
|
||||||
Kind::Literal(Literal::Integer(
|
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(),
|
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 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)]
|
#[derive(Eq, PartialEq, Clone, PartialOrd, Ord)]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
/// Values
|
/// Values
|
||||||
Identifier(String),
|
Identifier(String),
|
||||||
/// Number with at most one decimal point
|
/// Number in the decimal base
|
||||||
DecimalValue(String),
|
DecimalValue(String),
|
||||||
|
/// Integer number in the hexadecimal base
|
||||||
|
HexadecimalValue(String),
|
||||||
/// Some character literal that was surrounded by 'single-quotes'.
|
/// Some character literal that was surrounded by 'single-quotes'.
|
||||||
CharLit(String),
|
CharLit(String),
|
||||||
/// Some string literal that was surrounded by "double-quotes".
|
/// Some string literal that was surrounded by "double-quotes".
|
||||||
@ -130,6 +141,7 @@ impl ToString for Token {
|
|||||||
match &self {
|
match &self {
|
||||||
Token::Identifier(ident) => ident.clone(),
|
Token::Identifier(ident) => ident.clone(),
|
||||||
Token::DecimalValue(val) => val.to_string(),
|
Token::DecimalValue(val) => val.to_string(),
|
||||||
|
Token::HexadecimalValue(val) => val.to_string(),
|
||||||
Token::CharLit(lit) => format!("\'{}\'", lit),
|
Token::CharLit(lit) => format!("\'{}\'", lit),
|
||||||
Token::StringLit(lit) => format!("\"{}\"", lit),
|
Token::StringLit(lit) => format!("\"{}\"", lit),
|
||||||
Token::LetKeyword => String::from("let"),
|
Token::LetKeyword => String::from("let"),
|
||||||
@ -348,15 +360,26 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
|||||||
}
|
}
|
||||||
// Decimals
|
// Decimals
|
||||||
c if DECIMAL_NUMERICS.contains(c) => {
|
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() {
|
while let Some(c) = cursor.first() {
|
||||||
if !DECIMAL_NUMERICS.contains(&c) {
|
if !numerics.contains(&c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
value += &c.to_string();
|
value += c;
|
||||||
cursor.next();
|
cursor.next();
|
||||||
}
|
}
|
||||||
Token::DecimalValue(value)
|
match value {
|
||||||
|
NumberType::Decimal(value) => Token::DecimalValue(value),
|
||||||
|
NumberType::Hexadecimal(hex) => Token::HexadecimalValue(hex),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'-' if cursor.first() == Some('>') => {
|
'-' if cursor.first() == Some('>') => {
|
||||||
cursor.next(); // Eat `>`
|
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)]
|
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("Invalid token '{}' ", .0)]
|
#[error("Invalid token '{}' ", .0)]
|
||||||
|
@ -78,7 +78,7 @@ pub fn parse_module<'map, T: Into<String>>(
|
|||||||
map.set_tokens(id, tokens.clone());
|
map.set_tokens(id, tokens.clone());
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
dbg!(&tokens);
|
println!("{:#?}", &tokens);
|
||||||
|
|
||||||
Ok((id, tokens))
|
Ok((id, tokens))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user