Add types to number-literals
This commit is contained in:
		
							parent
							
								
									211cca50b8
								
							
						
					
					
						commit
						5b46e973d4
					
				| @ -45,9 +45,12 @@ Currently missing big features (TODOs) are: | |||||||
| - ~~Built-in Int/Float division and modulo~~ (DONE) | - ~~Built-in Int/Float division and modulo~~ (DONE) | ||||||
| - ~~Loops~~ (DONE) | - ~~Loops~~ (DONE) | ||||||
| - ~~Intrinsic functions~~ (DONE) | - ~~Intrinsic functions~~ (DONE) | ||||||
|  | - ~~Ability to specify types in literals~~ (DONE) | ||||||
| - Debug Information (PARTIALLY DONE) | - Debug Information (PARTIALLY DONE) | ||||||
| - Ability to specify types in literals and variable definitions |  | ||||||
| - Not-Unary | - Not-Unary | ||||||
|  | - Importing types from other modules | ||||||
|  | - Importable binops? | ||||||
|  | - Ability to specify types in variable definitions | ||||||
| 
 | 
 | ||||||
| Big features that I want later but are not necessary: | Big features that I want later but are not necessary: | ||||||
| - Associated functions | - Associated functions | ||||||
|  | |||||||
| @ -45,6 +45,28 @@ pub enum Literal { | |||||||
|     Bool(bool), |     Bool(bool), | ||||||
|     String(String), |     String(String), | ||||||
|     Char(char), |     Char(char), | ||||||
|  |     Specific(SpecificLiteral), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub enum SpecificLiteral { | ||||||
|  |     I8(i8), | ||||||
|  |     I16(i16), | ||||||
|  |     I32(i32), | ||||||
|  |     I64(i64), | ||||||
|  |     I128(i128), | ||||||
|  |     U8(u8), | ||||||
|  |     U16(u16), | ||||||
|  |     U32(u32), | ||||||
|  |     U64(u64), | ||||||
|  |     U128(u128), | ||||||
|  |     F16(f32), | ||||||
|  |     F32(f32), | ||||||
|  |     F32B(f32), | ||||||
|  |     F64(f64), | ||||||
|  |     F80(f64), | ||||||
|  |     F128(f64), | ||||||
|  |     F128PPC(f64), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
|  | |||||||
| @ -96,6 +96,46 @@ impl Parse for UnaryOperator { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn specific_int_lit(value: u128, stream: &mut TokenStream) -> Result<Expression, Error> { | ||||||
|  |     use ExpressionKind as Kind; | ||||||
|  | 
 | ||||||
|  |     let specific_lit = if let Ok(ty) = stream.parse::<Type>() { | ||||||
|  |         Some(match ty.0 { | ||||||
|  |             TypeKind::I8 => SpecificLiteral::I8(value as i8), | ||||||
|  |             TypeKind::I16 => SpecificLiteral::I16(value as i16), | ||||||
|  |             TypeKind::I32 => SpecificLiteral::I32(value as i32), | ||||||
|  |             TypeKind::I64 => SpecificLiteral::I64(value as i64), | ||||||
|  |             TypeKind::I128 => SpecificLiteral::I128(value as i128), | ||||||
|  |             TypeKind::U8 => SpecificLiteral::U8(value as u8), | ||||||
|  |             TypeKind::U16 => SpecificLiteral::U16(value as u16), | ||||||
|  |             TypeKind::U32 => SpecificLiteral::U32(value as u32), | ||||||
|  |             TypeKind::U64 => SpecificLiteral::U64(value as u64), | ||||||
|  |             TypeKind::U128 => SpecificLiteral::U128(value as u128), | ||||||
|  |             TypeKind::F16 => SpecificLiteral::F16(value as f32), | ||||||
|  |             TypeKind::F32 => SpecificLiteral::F32(value as f32), | ||||||
|  |             TypeKind::F32B => SpecificLiteral::F32B(value as f32), | ||||||
|  |             TypeKind::F64 => SpecificLiteral::F64(value as f64), | ||||||
|  |             TypeKind::F128 => SpecificLiteral::F128(value as f64), | ||||||
|  |             TypeKind::F80 => SpecificLiteral::F80(value as f64), | ||||||
|  |             TypeKind::F128PPC => SpecificLiteral::F128PPC(value as f64), | ||||||
|  |             _ => return Err(stream.expected_err("integer-compatible type")?), | ||||||
|  |         }) | ||||||
|  |     } else { | ||||||
|  |         None | ||||||
|  |     }; | ||||||
|  |     Ok(if let Some(lit) = specific_lit { | ||||||
|  |         Expression( | ||||||
|  |             Kind::Literal(Literal::Specific(lit)), | ||||||
|  |             stream.get_range().unwrap(), | ||||||
|  |         ) | ||||||
|  |     } else { | ||||||
|  |         Expression( | ||||||
|  |             Kind::Literal(Literal::Integer(value)), | ||||||
|  |             stream.get_range().unwrap(), | ||||||
|  |         ) | ||||||
|  |     }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct PrimaryExpression(Expression); | pub struct PrimaryExpression(Expression); | ||||||
| 
 | 
 | ||||||
| @ -154,32 +194,26 @@ impl Parse for PrimaryExpression { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Token::BinaryValue(v) => { |                 Token::BinaryValue(v) => { | ||||||
|                     stream.next(); // Consume octal
 |                     stream.next(); // Consume binary
 | ||||||
|                     Expression( |                     specific_int_lit( | ||||||
|                         Kind::Literal(Literal::Integer( |                         u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"), | ||||||
|                             u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"), |                         &mut stream, | ||||||
|                         )), |                     )? | ||||||
|                         stream.get_range().unwrap(), |  | ||||||
|                     ) |  | ||||||
|                 } |                 } | ||||||
|                 Token::OctalValue(v) => { |                 Token::OctalValue(v) => { | ||||||
|                     stream.next(); // Consume octal
 |                     stream.next(); // Consume octal
 | ||||||
|                     Expression( |                     specific_int_lit( | ||||||
|                         Kind::Literal(Literal::Integer( |                         u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"), | ||||||
|                             u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"), |                         &mut stream, | ||||||
|                         )), |                     )? | ||||||
|                         stream.get_range().unwrap(), |  | ||||||
|                     ) |  | ||||||
|                 } |                 } | ||||||
|                 Token::HexadecimalValue(v) => { |                 Token::HexadecimalValue(v) => { | ||||||
|                     stream.next(); // Consume hexadecimal
 |                     stream.next(); // Consume hexadecimal
 | ||||||
|                     Expression( |                     specific_int_lit( | ||||||
|                         Kind::Literal(Literal::Integer( |                         u128::from_str_radix(&v, 16) | ||||||
|                             u128::from_str_radix(&v, 16) |                             .expect("Hexadecimal is not parseable as u128!"), | ||||||
|                                 .expect("Hexadecimal is not parseable as u128!"), |                         &mut stream, | ||||||
|                         )), |                     )? | ||||||
|                         stream.get_range().unwrap(), |  | ||||||
|                     ) |  | ||||||
|                 } |                 } | ||||||
|                 Token::DecimalValue(v) => { |                 Token::DecimalValue(v) => { | ||||||
|                     stream.next(); // Consume decimal
 |                     stream.next(); // Consume decimal
 | ||||||
| @ -189,22 +223,41 @@ impl Parse for PrimaryExpression { | |||||||
|                         stream.next(); // Consume dot
 |                         stream.next(); // Consume dot
 | ||||||
|                         stream.next(); // Consume fractional
 |                         stream.next(); // Consume fractional
 | ||||||
| 
 | 
 | ||||||
|                         Expression( |                         let value = format!("{}.{}", v, fractional) | ||||||
|                             Kind::Literal(Literal::Decimal( |                             .parse() | ||||||
|                                 format!("{}.{}", v, fractional) |                             .expect("Decimal is not parseable as f64!"); | ||||||
|                                     .parse() | 
 | ||||||
|                                     .expect("Decimal is not parseable as f64!"), |                         let specific_lit = if let Ok(ty) = stream.parse::<Type>() { | ||||||
|                             )), |                             Some(match ty.0 { | ||||||
|                             stream.get_range().unwrap(), |                                 TypeKind::F16 => SpecificLiteral::F16(value as f32), | ||||||
|                         ) |                                 TypeKind::F32B => SpecificLiteral::F32B(value as f32), | ||||||
|  |                                 TypeKind::F32 => SpecificLiteral::F32(value as f32), | ||||||
|  |                                 TypeKind::F64 => SpecificLiteral::F64(value), | ||||||
|  |                                 TypeKind::F80 => SpecificLiteral::F80(value), | ||||||
|  |                                 TypeKind::F128 => SpecificLiteral::F128(value), | ||||||
|  |                                 TypeKind::F128PPC => SpecificLiteral::F128PPC(value), | ||||||
|  |                                 _ => return Err(stream.expected_err("float-compatible type")?), | ||||||
|  |                             }) | ||||||
|  |                         } else { | ||||||
|  |                             None | ||||||
|  |                         }; | ||||||
|  |                         if let Some(lit) = specific_lit { | ||||||
|  |                             Expression( | ||||||
|  |                                 Kind::Literal(Literal::Specific(lit)), | ||||||
|  |                                 stream.get_range().unwrap(), | ||||||
|  |                             ) | ||||||
|  |                         } else { | ||||||
|  |                             Expression( | ||||||
|  |                                 Kind::Literal(Literal::Decimal(value)), | ||||||
|  |                                 stream.get_range().unwrap(), | ||||||
|  |                             ) | ||||||
|  |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         Expression( |                         specific_int_lit( | ||||||
|                             Kind::Literal(Literal::Integer( |                             u128::from_str_radix(&v, 10) | ||||||
|                                 u128::from_str_radix(&v, 10) |                                 .expect("Integer is not parseable as u128!"), | ||||||
|                                     .expect("Integer is not parseable as u128!"), |                             &mut stream, | ||||||
|                             )), |                         )? | ||||||
|                             stream.get_range().unwrap(), |  | ||||||
|                         ) |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Token::StringLit(v) => { |                 Token::StringLit(v) => { | ||||||
|  | |||||||
| @ -8,6 +8,8 @@ use crate::{ | |||||||
|     }, |     }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | use super::TypeKind; | ||||||
|  | 
 | ||||||
| impl mir::Context { | impl mir::Context { | ||||||
|     pub fn from(modules: Vec<mir::Module>, base: PathBuf) -> mir::Context { |     pub fn from(modules: Vec<mir::Module>, base: PathBuf) -> mir::Context { | ||||||
|         let mut map = ModuleMap::new(); |         let mut map = ModuleMap::new(); | ||||||
| @ -417,6 +419,25 @@ impl ast::Literal { | |||||||
|             ast::Literal::String(val) => mir::Literal::String(val.clone()), |             ast::Literal::String(val) => mir::Literal::String(val.clone()), | ||||||
|             ast::Literal::Decimal(v) => mir::Literal::Vague(mir::VagueLiteral::Decimal(*v)), |             ast::Literal::Decimal(v) => mir::Literal::Vague(mir::VagueLiteral::Decimal(*v)), | ||||||
|             ast::Literal::Char(inner) => mir::Literal::Char(*inner), |             ast::Literal::Char(inner) => mir::Literal::Char(*inner), | ||||||
|  |             ast::Literal::Specific(specific_literal) => match specific_literal { | ||||||
|  |                 ast::SpecificLiteral::I8(val) => mir::Literal::I8(*val), | ||||||
|  |                 ast::SpecificLiteral::I16(val) => mir::Literal::I16(*val), | ||||||
|  |                 ast::SpecificLiteral::I32(val) => mir::Literal::I32(*val), | ||||||
|  |                 ast::SpecificLiteral::I64(val) => mir::Literal::I64(*val), | ||||||
|  |                 ast::SpecificLiteral::I128(val) => mir::Literal::I128(*val), | ||||||
|  |                 ast::SpecificLiteral::U8(val) => mir::Literal::U8(*val), | ||||||
|  |                 ast::SpecificLiteral::U16(val) => mir::Literal::U16(*val), | ||||||
|  |                 ast::SpecificLiteral::U32(val) => mir::Literal::U32(*val), | ||||||
|  |                 ast::SpecificLiteral::U64(val) => mir::Literal::U64(*val), | ||||||
|  |                 ast::SpecificLiteral::U128(val) => mir::Literal::U128(*val), | ||||||
|  |                 ast::SpecificLiteral::F16(val) => mir::Literal::F16(*val), | ||||||
|  |                 ast::SpecificLiteral::F32(val) => mir::Literal::F32(*val), | ||||||
|  |                 ast::SpecificLiteral::F32B(val) => mir::Literal::F32B(*val), | ||||||
|  |                 ast::SpecificLiteral::F64(val) => mir::Literal::F64(*val), | ||||||
|  |                 ast::SpecificLiteral::F80(val) => mir::Literal::F80(*val), | ||||||
|  |                 ast::SpecificLiteral::F128(val) => mir::Literal::F128(*val), | ||||||
|  |                 ast::SpecificLiteral::F128PPC(val) => mir::Literal::F128PPC(*val), | ||||||
|  |             }, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -326,7 +326,15 @@ impl Expression { | |||||||
|                 { |                 { | ||||||
|                     Ok(binop) |                     Ok(binop) | ||||||
|                 } else { |                 } else { | ||||||
|                     let typeref = lhs_ref.narrow(&rhs_ref).unwrap(); |                     let typeref = state.or_else( | ||||||
|  |                         lhs_ref.narrow(&rhs_ref).ok_or(ErrorKind::InvalidBinop( | ||||||
|  |                             *op, | ||||||
|  |                             lhs_ref.resolve_deep().unwrap(), | ||||||
|  |                             rhs_ref.resolve_deep().unwrap(), | ||||||
|  |                         )), | ||||||
|  |                         type_refs.from_type(&Vague(Unknown)).unwrap(), | ||||||
|  |                         self.1, | ||||||
|  |                     ); | ||||||
|                     Ok(type_refs |                     Ok(type_refs | ||||||
|                         .from_type( |                         .from_type( | ||||||
|                             &typeref |                             &typeref | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user