diff --git a/README.md b/README.md index 8aa0d2b..43ed18c 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/examples/struct.reid b/examples/struct.reid index 412e125..da02cbe 100644 --- a/examples/struct.reid +++ b/examples/struct.reid @@ -11,6 +11,8 @@ fn main() -> u32 { second: 3, }; + value.second = 17; + return value.second; } diff --git a/reid/src/ast/lexer.rs b/reid/src/ast/lexer.rs index 777f5a8..c520362 100644 --- a/reid/src/ast/lexer.rs +++ b/reid/src/ast/lexer.rs @@ -298,9 +298,7 @@ pub fn tokenize>(to_tokenize: T) -> Result, 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>(to_tokenize: T) -> Result, 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 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()), }; diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 71afdd0..d821953 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -101,6 +101,7 @@ pub enum ExpressionKind { pub enum UnaryOperator { Plus, Minus, + Not, } #[derive(Debug, Clone, Copy)] diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 6cf43b5..604c955 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -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::()?; Stmt::TypeDefinition(TypeDefinition { diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 2d8c114..5f670c4 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -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)),