Add Not-Unary
This commit is contained in:
		
							parent
							
								
									bf878c02a7
								
							
						
					
					
						commit
						12e2851a8b
					
				| @ -47,13 +47,13 @@ Currently missing big features (TODOs) are: | ||||
| - ~~Intrinsic functions~~ (DONE) | ||||
| - ~~Ability to specify types in literals and variable definitions~~ (DONE) | ||||
| - ~~Debug Information~~ (DONE) | ||||
| - Fix struct initialization (wrong order and missing fields allowed now) | ||||
| - Not-Unary | ||||
| - ~~Fix struct initialization (wrong order and missing fields allowed now)~~ | ||||
| - ~~Not-Unary~~ | ||||
| - Importing types from other modules | ||||
| - Importable binops? | ||||
| - Associated functions (for e.g. sizeof) | ||||
| 
 | ||||
| Big features that I want later but are not necessary: | ||||
| - Associated functions (for e.g. sizeof) | ||||
| - ~~User-defined binary operations~~ (DONE) | ||||
| - ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE) | ||||
| - Error handling | ||||
|  | ||||
| @ -11,6 +11,8 @@ fn main() -> u32 { | ||||
|         second: 3, | ||||
|     }; | ||||
| 
 | ||||
|     value.second = 17; | ||||
| 
 | ||||
| 
 | ||||
|     return value.second; | ||||
| } | ||||
|  | ||||
| @ -298,9 +298,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error | ||||
|             '\"' | '\'' => { | ||||
|                 let mut value = String::new(); | ||||
|                 let mut escape_next = false; | ||||
|                 while cursor.first().is_some() | ||||
|                     && (cursor.first() != Some(*character) || escape_next) | ||||
|                 { | ||||
|                 while cursor.first().is_some() && (cursor.first() != Some(*character) || escape_next) { | ||||
|                     if cursor.first() == Some('\\') && !escape_next { | ||||
|                         cursor.next(); // Consume backslash and always add next character
 | ||||
|                         escape_next = true; | ||||
| @ -366,8 +364,7 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error | ||||
|                 let mut numerics = DECIMAL_NUMERICS; | ||||
|                 if let Some(second) = cursor.second() { | ||||
|                     if cursor.first() == Some('x') | ||||
|                         && HEXADECIMAL_NUMERICS | ||||
|                             .contains(&second.to_lowercase().next().unwrap_or('.')) | ||||
|                         && HEXADECIMAL_NUMERICS.contains(&second.to_lowercase().next().unwrap_or('.')) | ||||
|                     { | ||||
|                         cursor.next(); | ||||
|                         value = NumberType::Hexadecimal(String::new()); | ||||
| @ -464,9 +461,7 @@ 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()) | ||||
|             } | ||||
|             NumberType::Hexadecimal(val) => NumberType::Hexadecimal(val.to_owned() + &rhs.to_string()), | ||||
|             NumberType::Octal(val) => NumberType::Octal(val.to_owned() + &rhs.to_string()), | ||||
|             NumberType::Binary(val) => NumberType::Binary(val.to_owned() + &rhs.to_string()), | ||||
|         }; | ||||
|  | ||||
| @ -101,6 +101,7 @@ pub enum ExpressionKind { | ||||
| pub enum UnaryOperator { | ||||
|     Plus, | ||||
|     Minus, | ||||
|     Not, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
|  | ||||
| @ -87,6 +87,7 @@ impl Parse for UnaryOperator { | ||||
|             match token { | ||||
|                 Token::Plus => Ok(UnaryOperator::Plus), | ||||
|                 Token::Minus => Ok(UnaryOperator::Minus), | ||||
|                 Token::Exclamation => Ok(UnaryOperator::Not), | ||||
|                 _ => Err(stream.expected_err("unary operator")?), | ||||
|             } | ||||
|         } else { | ||||
| @ -174,20 +175,11 @@ impl Parse for PrimaryExpression { | ||||
|         use ExpressionKind as Kind; | ||||
| 
 | ||||
|         let mut expr = if let Ok(exp) = stream.parse() { | ||||
|             Expression( | ||||
|                 Kind::FunctionCall(Box::new(exp)), | ||||
|                 stream.get_range().unwrap(), | ||||
|             ) | ||||
|             Expression(Kind::FunctionCall(Box::new(exp)), stream.get_range().unwrap()) | ||||
|         } else if let Ok(block) = stream.parse() { | ||||
|             Expression( | ||||
|                 Kind::BlockExpr(Box::new(block)), | ||||
|                 stream.get_range().unwrap(), | ||||
|             ) | ||||
|             Expression(Kind::BlockExpr(Box::new(block)), stream.get_range().unwrap()) | ||||
|         } else if let Some(Token::If) = stream.peek() { | ||||
|             Expression( | ||||
|                 Kind::IfExpr(Box::new(stream.parse()?)), | ||||
|                 stream.get_range().unwrap(), | ||||
|             ) | ||||
|             Expression(Kind::IfExpr(Box::new(stream.parse()?)), stream.get_range().unwrap()) | ||||
|         } else if let (Some(Token::Et), Some(Token::MutKeyword)) = (stream.peek(), stream.peek2()) { | ||||
|             stream.next(); // Consume Et
 | ||||
|             stream.next(); // Consume mut
 | ||||
| @ -195,15 +187,11 @@ impl Parse for PrimaryExpression { | ||||
|                 return Err(stream.expected_err("identifier")?); | ||||
|             }; | ||||
|             Expression(Kind::Borrow(name, true), stream.get_range().unwrap()) | ||||
|         } else if let (Some(Token::Et), Some(Token::Identifier(name))) = | ||||
|             (stream.peek(), stream.peek2()) | ||||
|         { | ||||
|         } else if let (Some(Token::Et), Some(Token::Identifier(name))) = (stream.peek(), stream.peek2()) { | ||||
|             stream.next(); // Consume Et
 | ||||
|             stream.next(); // Consume identifier
 | ||||
|             Expression(Kind::Borrow(name, false), stream.get_range().unwrap()) | ||||
|         } else if let (Some(Token::Star), Some(Token::Identifier(name))) = | ||||
|             (stream.peek(), stream.peek2()) | ||||
|         { | ||||
|         } else if let (Some(Token::Star), Some(Token::Identifier(name))) = (stream.peek(), stream.peek2()) { | ||||
|             stream.next(); // Consume Et
 | ||||
|             stream.next(); // Consume identifier
 | ||||
|             Expression(Kind::Deref(name), stream.get_range().unwrap()) | ||||
| @ -225,49 +213,35 @@ impl Parse for PrimaryExpression { | ||||
|                 } | ||||
|                 Token::BinaryValue(v) => { | ||||
|                     stream.next(); // Consume binary
 | ||||
|                     let value = | ||||
|                         u128::from_str_radix(&v, 2).expect("Value is not parseable as u128!"); | ||||
|                     let value = u128::from_str_radix(&v, 2).expect("Value is not parseable as u128!"); | ||||
|                     if let Ok(expr) = specific_int_lit(value, &mut stream) { | ||||
|                         expr | ||||
|                     } else { | ||||
|                         Expression( | ||||
|                             Kind::Literal(Literal::Integer(value)), | ||||
|                             stream.get_range().unwrap(), | ||||
|                         ) | ||||
|                         Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap()) | ||||
|                     } | ||||
|                 } | ||||
|                 Token::OctalValue(v) => { | ||||
|                     stream.next(); // Consume octal
 | ||||
|                     let value = | ||||
|                         u128::from_str_radix(&v, 8).expect("Value is not parseable as u128!"); | ||||
|                     let value = u128::from_str_radix(&v, 8).expect("Value is not parseable as u128!"); | ||||
|                     if let Ok(expr) = specific_int_lit(value, &mut stream) { | ||||
|                         expr | ||||
|                     } else { | ||||
|                         Expression( | ||||
|                             Kind::Literal(Literal::Integer(value)), | ||||
|                             stream.get_range().unwrap(), | ||||
|                         ) | ||||
|                         Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap()) | ||||
|                     } | ||||
|                 } | ||||
|                 Token::HexadecimalValue(v) => { | ||||
|                     stream.next(); // Consume hexadecimal
 | ||||
| 
 | ||||
|                     let value = | ||||
|                         u128::from_str_radix(&v, 16).expect("Value is not parseable as u128!"); | ||||
|                     let value = u128::from_str_radix(&v, 16).expect("Value is not parseable as u128!"); | ||||
|                     if let Ok(expr) = specific_int_lit(value, &mut stream) { | ||||
|                         expr | ||||
|                     } else { | ||||
|                         Expression( | ||||
|                             Kind::Literal(Literal::Integer(value)), | ||||
|                             stream.get_range().unwrap(), | ||||
|                         ) | ||||
|                         Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap()) | ||||
|                     } | ||||
|                 } | ||||
|                 Token::DecimalValue(v) => { | ||||
|                     stream.next(); // Consume decimal
 | ||||
|                     if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) = | ||||
|                         (stream.peek(), stream.peek2()) | ||||
|                     { | ||||
|                     if let (Some(Token::Dot), Some(Token::DecimalValue(fractional))) = (stream.peek(), stream.peek2()) { | ||||
|                         stream.next(); // Consume dot
 | ||||
|                         stream.next(); // Consume fractional
 | ||||
| 
 | ||||
| @ -278,30 +252,20 @@ impl Parse for PrimaryExpression { | ||||
|                         if let Ok(expr) = specific_float_lit(value, &mut stream) { | ||||
|                             expr | ||||
|                         } else { | ||||
|                             Expression( | ||||
|                                 Kind::Literal(Literal::Decimal(value)), | ||||
|                                 stream.get_range().unwrap(), | ||||
|                             ) | ||||
|                             Expression(Kind::Literal(Literal::Decimal(value)), stream.get_range().unwrap()) | ||||
|                         } | ||||
|                     } else { | ||||
|                         let value = | ||||
|                             u128::from_str_radix(&v, 10).expect("Value is not parseable as u128!"); | ||||
|                         let value = u128::from_str_radix(&v, 10).expect("Value is not parseable as u128!"); | ||||
|                         if let Ok(expr) = specific_int_lit(value, &mut stream) { | ||||
|                             expr | ||||
|                         } else { | ||||
|                             Expression( | ||||
|                                 Kind::Literal(Literal::Integer(value)), | ||||
|                                 stream.get_range().unwrap(), | ||||
|                             ) | ||||
|                             Expression(Kind::Literal(Literal::Integer(value)), stream.get_range().unwrap()) | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 Token::StringLit(v) => { | ||||
|                     stream.next(); // Consume
 | ||||
|                     Expression( | ||||
|                         Kind::Literal(Literal::String(v.clone())), | ||||
|                         stream.get_range().unwrap(), | ||||
|                     ) | ||||
|                     Expression(Kind::Literal(Literal::String(v.clone())), stream.get_range().unwrap()) | ||||
|                 } | ||||
|                 Token::CharLit(v) => { | ||||
|                     stream.next(); // Consume
 | ||||
| @ -319,17 +283,11 @@ impl Parse for PrimaryExpression { | ||||
|                 } | ||||
|                 Token::True => { | ||||
|                     stream.next(); // Consume
 | ||||
|                     Expression( | ||||
|                         Kind::Literal(Literal::Bool(true)), | ||||
|                         stream.get_range().unwrap(), | ||||
|                     ) | ||||
|                     Expression(Kind::Literal(Literal::Bool(true)), stream.get_range().unwrap()) | ||||
|                 } | ||||
|                 Token::False => { | ||||
|                     stream.next(); // Consume
 | ||||
|                     Expression( | ||||
|                         Kind::Literal(Literal::Bool(false)), | ||||
|                         stream.get_range().unwrap(), | ||||
|                     ) | ||||
|                     Expression(Kind::Literal(Literal::Bool(false)), stream.get_range().unwrap()) | ||||
|                 } | ||||
|                 Token::ParenOpen => { | ||||
|                     stream.next(); // Consume
 | ||||
| @ -343,16 +301,14 @@ impl Parse for PrimaryExpression { | ||||
|                         if let Some(Token::Semi) = stream.peek() { | ||||
|                             stream.next(); // Consume colon
 | ||||
|                             let Some(Token::DecimalValue(val)) = stream.next() else { | ||||
|                                 return Err(stream | ||||
|                                     .expecting_err("decimal value describing array length")?); | ||||
|                                 return Err(stream.expecting_err("decimal value describing array length")?); | ||||
|                             }; | ||||
|                             stream.expect(Token::BracketClose)?; | ||||
|                             Expression( | ||||
|                                 Kind::ArrayShort( | ||||
|                                     Box::new(exp), | ||||
|                                     u64::from_str_radix(&val, 10).expect( | ||||
|                                         "Unable to parse array length to 64-bit decimal value", | ||||
|                                     ), | ||||
|                                     u64::from_str_radix(&val, 10) | ||||
|                                         .expect("Unable to parse array length to 64-bit decimal value"), | ||||
|                                 ), | ||||
|                                 stream.get_range().unwrap(), | ||||
|                             ) | ||||
| @ -514,11 +470,7 @@ impl Parse for FunctionCallExpression { | ||||
| 
 | ||||
|             stream.expect(Token::ParenClose)?; | ||||
| 
 | ||||
|             Ok(FunctionCallExpression( | ||||
|                 name, | ||||
|                 args, | ||||
|                 stream.get_range().unwrap(), | ||||
|             )) | ||||
|             Ok(FunctionCallExpression(name, args, stream.get_range().unwrap())) | ||||
|         } else { | ||||
|             Err(stream.expected_err("identifier")?) | ||||
|         } | ||||
| @ -535,12 +487,7 @@ impl Parse for IfExpression { | ||||
|         } else { | ||||
|             None | ||||
|         }; | ||||
|         Ok(IfExpression( | ||||
|             cond, | ||||
|             then_b, | ||||
|             else_b, | ||||
|             stream.get_range().unwrap(), | ||||
|         )) | ||||
|         Ok(IfExpression(cond, then_b, else_b, stream.get_range().unwrap())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -700,11 +647,7 @@ impl Parse for Block { | ||||
|             statements.push(statement); | ||||
|         } | ||||
|         stream.expect(Token::BraceClose)?; | ||||
|         Ok(Block( | ||||
|             statements, | ||||
|             return_stmt, | ||||
|             stream.get_range_prev().unwrap(), | ||||
|         )) | ||||
|         Ok(Block(statements, return_stmt, stream.get_range_prev().unwrap())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -809,9 +752,7 @@ impl Parse for BlockLevelStatement { | ||||
|         use BlockLevelStatement as Stmt; | ||||
|         Ok(match stream.peek() { | ||||
|             Some(Token::LetKeyword) => Stmt::Let(stream.parse()?), | ||||
|             Some(Token::ImportKeyword) => Stmt::Import { | ||||
|                 _i: stream.parse()?, | ||||
|             }, | ||||
|             Some(Token::ImportKeyword) => Stmt::Import { _i: stream.parse()? }, | ||||
|             Some(Token::ReturnKeyword) => { | ||||
|                 stream.next(); | ||||
|                 let exp = stream.parse().ok(); | ||||
| @ -924,9 +865,7 @@ impl Parse for TopLevelStatement { | ||||
|                 stream.expect(Token::Semi)?; | ||||
|                 extern_fn | ||||
|             } | ||||
|             Some(Token::FnKeyword) | Some(Token::PubKeyword) => { | ||||
|                 Stmt::FunctionDefinition(stream.parse()?) | ||||
|             } | ||||
|             Some(Token::FnKeyword) | Some(Token::PubKeyword) => Stmt::FunctionDefinition(stream.parse()?), | ||||
|             Some(Token::Struct) => { | ||||
|                 let StructDefinition(name, fields, range) = stream.parse::<StructDefinition>()?; | ||||
|                 Stmt::TypeDefinition(TypeDefinition { | ||||
|  | ||||
| @ -366,6 +366,15 @@ impl ast::Expression { | ||||
|                     Box::new(expr.process(module_id)), | ||||
|                     mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||
|                 ), | ||||
|                 ast::UnaryOperator::Not => mir::ExprKind::BinOp( | ||||
|                     mir::BinaryOperator::Cmp(mir::CmpOperator::EQ), | ||||
|                     Box::new(expr.process(module_id)), | ||||
|                     Box::new(mir::Expression( | ||||
|                         mir::ExprKind::Literal(mir::Literal::Bool(false)), | ||||
|                         expr.1.as_meta(module_id), | ||||
|                     )), | ||||
|                     mir::TypeKind::Bool, | ||||
|                 ), | ||||
|             }, | ||||
|             ast::ExpressionKind::CastTo(expression, ty) => mir::ExprKind::CastTo( | ||||
|                 Box::new(expression.process(module_id)), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user