Implement unary operators as syntax sugar

This commit is contained in:
Sofia 2025-07-21 15:10:39 +03:00
parent 14b6e6b2f9
commit d65b0153a1
6 changed files with 52 additions and 8 deletions

View File

@ -38,11 +38,11 @@ Currently missing big features (TODOs) are:
- ~~Extern functions~~ (DONE)
- ~~Strings~~ (DONE)
- ~~Borrows~~ (DONE)
- ~~Pointers~~
- ~~Pointers~~ (DONE)
- Unary operators
- Floats
- Loops
- Debug Information (PARTIALLY DONE)
- Floats
- Unary operators
- Ability to specify types in literals and variable definitions
Big features that I want later but are not necessary:

View File

@ -57,6 +57,13 @@ pub enum ExpressionKind {
BlockExpr(Box<Block>),
IfExpr(Box<IfExpression>),
StructExpression(StructExpression),
UnaryOperation(UnaryOperator, Box<Expression>),
}
#[derive(Debug, Clone)]
pub enum UnaryOperator {
Plus,
Minus,
}
#[derive(Debug, Clone, Copy)]

View File

@ -72,6 +72,20 @@ impl Parse for Expression {
}
}
impl Parse for UnaryOperator {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
if let Some(token) = stream.next() {
match token {
Token::Plus => Ok(UnaryOperator::Plus),
Token::Minus => Ok(UnaryOperator::Minus),
_ => Err(stream.expected_err("unary operator")?),
}
} else {
Err(stream.expected_err("unary operator")?)
}
}
}
#[derive(Debug)]
pub struct PrimaryExpression(Expression);
@ -117,6 +131,11 @@ impl Parse for PrimaryExpression {
stream.next(); // Consume Et
stream.next(); // Consume identifier
Expression(Kind::Deref(name), stream.get_range().unwrap())
} else if let Ok(unary) = stream.parse() {
Expression(
Kind::UnaryOperation(unary, Box::new(stream.parse()?)),
stream.get_range().unwrap(),
)
} else if let Some(token) = stream.next() {
match &token {
Token::Identifier(v) => {

View File

@ -238,6 +238,24 @@ impl ast::Expression {
name.clone(),
self.1.as_meta(module_id),
)),
ast::ExpressionKind::UnaryOperation(unary_operator, expr) => match unary_operator {
ast::UnaryOperator::Plus => mir::ExprKind::BinOp(
mir::BinaryOperator::Add,
Box::new(mir::Expression(
mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number(0))),
expr.1.as_meta(module_id),
)),
Box::new(expr.process(module_id)),
),
ast::UnaryOperator::Minus => mir::ExprKind::BinOp(
mir::BinaryOperator::Minus,
Box::new(mir::Expression(
mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number(0))),
expr.1.as_meta(module_id),
)),
Box::new(expr.process(module_id)),
),
},
};
mir::Expression(kind, self.1.as_meta(module_id))

View File

@ -103,10 +103,10 @@ impl<'map> Pass for LinkerPass<'map> {
modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens))));
}
// modules.insert(
// "std".to_owned(),
// Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
// );
modules.insert(
"std".to_owned(),
Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
);
let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> =
modules.values().cloned().collect();

View File

@ -5,5 +5,5 @@ fn main() -> u32 {
let value = 6;
let other = 15;
return value * other + 7 * value;
return value * other + 7 * (-value);
}