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