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) | ||||
| - ~~Loops~~ (DONE) | ||||
| - ~~Intrinsic functions~~ (DONE) | ||||
| - ~~Ability to specify types in literals~~ (DONE) | ||||
| - Debug Information (PARTIALLY DONE) | ||||
| - Ability to specify types in literals and variable definitions | ||||
| - 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: | ||||
| - Associated functions | ||||
|  | ||||
| @ -45,6 +45,28 @@ pub enum Literal { | ||||
|     Bool(bool), | ||||
|     String(String), | ||||
|     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)] | ||||
|  | ||||
| @ -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)] | ||||
| pub struct PrimaryExpression(Expression); | ||||
| 
 | ||||
| @ -154,32 +194,26 @@ impl Parse for PrimaryExpression { | ||||
|                     } | ||||
|                 } | ||||
|                 Token::BinaryValue(v) => { | ||||
|                     stream.next(); // Consume octal
 | ||||
|                     Expression( | ||||
|                         Kind::Literal(Literal::Integer( | ||||
|                             u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"), | ||||
|                         )), | ||||
|                         stream.get_range().unwrap(), | ||||
|                     ) | ||||
|                     stream.next(); // Consume binary
 | ||||
|                     specific_int_lit( | ||||
|                         u128::from_str_radix(&v, 2).expect("Binary is not parseable as u128!"), | ||||
|                         &mut stream, | ||||
|                     )? | ||||
|                 } | ||||
|                 Token::OctalValue(v) => { | ||||
|                     stream.next(); // Consume octal
 | ||||
|                     Expression( | ||||
|                         Kind::Literal(Literal::Integer( | ||||
|                             u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"), | ||||
|                         )), | ||||
|                         stream.get_range().unwrap(), | ||||
|                     ) | ||||
|                     specific_int_lit( | ||||
|                         u128::from_str_radix(&v, 8).expect("Octal is not parseable as u128!"), | ||||
|                         &mut stream, | ||||
|                     )? | ||||
|                 } | ||||
|                 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(), | ||||
|                     ) | ||||
|                     specific_int_lit( | ||||
|                         u128::from_str_radix(&v, 16) | ||||
|                             .expect("Hexadecimal is not parseable as u128!"), | ||||
|                         &mut stream, | ||||
|                     )? | ||||
|                 } | ||||
|                 Token::DecimalValue(v) => { | ||||
|                     stream.next(); // Consume decimal
 | ||||
| @ -189,22 +223,41 @@ impl Parse for PrimaryExpression { | ||||
|                         stream.next(); // Consume dot
 | ||||
|                         stream.next(); // Consume fractional
 | ||||
| 
 | ||||
|                         Expression( | ||||
|                             Kind::Literal(Literal::Decimal( | ||||
|                                 format!("{}.{}", v, fractional) | ||||
|                                     .parse() | ||||
|                                     .expect("Decimal is not parseable as f64!"), | ||||
|                             )), | ||||
|                             stream.get_range().unwrap(), | ||||
|                         ) | ||||
|                         let value = format!("{}.{}", v, fractional) | ||||
|                             .parse() | ||||
|                             .expect("Decimal is not parseable as f64!"); | ||||
| 
 | ||||
|                         let specific_lit = if let Ok(ty) = stream.parse::<Type>() { | ||||
|                             Some(match ty.0 { | ||||
|                                 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 { | ||||
|                         Expression( | ||||
|                             Kind::Literal(Literal::Integer( | ||||
|                                 u128::from_str_radix(&v, 10) | ||||
|                                     .expect("Integer is not parseable as u128!"), | ||||
|                             )), | ||||
|                             stream.get_range().unwrap(), | ||||
|                         ) | ||||
|                         specific_int_lit( | ||||
|                             u128::from_str_radix(&v, 10) | ||||
|                                 .expect("Integer is not parseable as u128!"), | ||||
|                             &mut stream, | ||||
|                         )? | ||||
|                     } | ||||
|                 } | ||||
|                 Token::StringLit(v) => { | ||||
|  | ||||
| @ -8,6 +8,8 @@ use crate::{ | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
| use super::TypeKind; | ||||
| 
 | ||||
| impl mir::Context { | ||||
|     pub fn from(modules: Vec<mir::Module>, base: PathBuf) -> mir::Context { | ||||
|         let mut map = ModuleMap::new(); | ||||
| @ -417,6 +419,25 @@ impl ast::Literal { | ||||
|             ast::Literal::String(val) => mir::Literal::String(val.clone()), | ||||
|             ast::Literal::Decimal(v) => mir::Literal::Vague(mir::VagueLiteral::Decimal(*v)), | ||||
|             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) | ||||
|                 } 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 | ||||
|                         .from_type( | ||||
|                             &typeref | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user