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