mirror of
https://github.com/urinalcaketopper/fddl.git
synced 2025-06-07 05:34:47 +00:00
logical operators, uhhh, others?
This commit is contained in:
parent
9db8be38f5
commit
6c61db4b57
@ -69,7 +69,7 @@ define $number := 5;
|
|||||||
print(`The square of $number is ${math.square($number)}`);
|
print(`The square of $number is ${math.square($number)}`);
|
||||||
```
|
```
|
||||||
|
|
||||||
(Note: This feature is under development, and string interpolation is planned for a future update.)
|
(Note: This feature is under development, and string interpolation is planned for the future.)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -84,9 +84,10 @@ fddl is very much a work in progress, with lots of planned improvements and addi
|
|||||||
|
|
||||||
- **Parser**:
|
- **Parser**:
|
||||||
- [x] Parser parsing tilde and minus successfully
|
- [x] Parser parsing tilde and minus successfully
|
||||||
- [ ] Parser parsing the rest of the operators
|
- [x] Parser parsing function calls
|
||||||
|
- [x] Parser parsing the rest of the operators (mostly complete)
|
||||||
- [ ] Working on building out functions to parse simple functionality in the language (if, while, for), and to read their expressions and values
|
- [ ] Working on building out functions to parse simple functionality in the language (if, while, for), and to read their expressions and values
|
||||||
- [ ] Implement parsing for function calls, expressions, checks, literally everything.
|
- [ ] Implement parsing for ~~~function calls,~~~ expressions, checks, literally everything.
|
||||||
|
|
||||||
- **Compiler**:
|
- **Compiler**:
|
||||||
- [ ] Currently a placeholder. Implement the compiler to compile parsed code.
|
- [ ] Currently a placeholder. Implement the compiler to compile parsed code.
|
||||||
|
@ -40,6 +40,10 @@ pub enum Operator {
|
|||||||
GreaterEqual,
|
GreaterEqual,
|
||||||
LessEqual,
|
LessEqual,
|
||||||
|
|
||||||
|
// Logical operators
|
||||||
|
And, // For logical AND e.g. true && false
|
||||||
|
Or, // For logical OR e.g. true || false
|
||||||
|
|
||||||
// Equality (we'll add these logic for these later)
|
// Equality (we'll add these logic for these later)
|
||||||
EqualEqual, // For equality e.g. 5 == 5
|
EqualEqual, // For equality e.g. 5 == 5
|
||||||
NotEqual, // For inequality e.g. 5 != 5
|
NotEqual, // For inequality e.g. 5 != 5
|
||||||
|
@ -179,11 +179,13 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expression(&mut self) -> Option<Expression> {
|
fn parse_expression(&mut self) -> Option<Expression> {
|
||||||
// self.parse_primary(); // Now redundant // Start with the simplest elements
|
// Keeping old tests here for reference until release.
|
||||||
|
// self.parse_primary(); // Start with the simplest elements
|
||||||
// self.parse_unary() // handles unary operators ('-' and '~')
|
// self.parse_unary() // handles unary operators ('-' and '~')
|
||||||
// self.parse_term() // handles binary operators ('+', '-', '*', '/')
|
// self.parse_term() // handles binary operators ('+', '-', '*', '/')
|
||||||
// self.parse_comparison() // handles comparison operators ('<', '>', '<=', '>=')
|
// self.parse_comparison() // handles comparison operators ('<', '>', '<=', '>=')
|
||||||
self.parse_equality() // handles equality operators ('==', '!=')
|
// self.parse_equality() // handles equality operators ('==', '!=')
|
||||||
|
self.parse_logical_or() // handles logical operators ('&&', '||')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each function below is fed into the function below it
|
// Each function below is fed into the function below it
|
||||||
@ -212,11 +214,9 @@ impl Parser {
|
|||||||
Some(Expression::Variable(name))
|
Some(Expression::Variable(name))
|
||||||
}
|
}
|
||||||
Token::LeftParen => {
|
Token::LeftParen => {
|
||||||
self.advance(); // Consume '('
|
self.advance();
|
||||||
// Recursively parse the expression inside the parentheses
|
let expr = self.parse_expression()?;
|
||||||
let expr = self.parse_expression()?; // Call the main expression parser
|
|
||||||
|
|
||||||
// Expect and consume the closing parenthesis
|
|
||||||
if self.match_token(Token::RightParen) {
|
if self.match_token(Token::RightParen) {
|
||||||
// Return the inner expression, wrapped in Grouping AST node
|
// Return the inner expression, wrapped in Grouping AST node
|
||||||
Some(Expression::Grouping(Box::new(expr)))
|
Some(Expression::Grouping(Box::new(expr)))
|
||||||
@ -235,24 +235,22 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_unary(&mut self) -> Option<Expression> {
|
fn parse_unary(&mut self) -> Option<Expression> {
|
||||||
let current_tok = self.current_token().clone();
|
let operator_token_snapshot = self.current_token().clone();
|
||||||
|
|
||||||
match current_tok {
|
match operator_token_snapshot {
|
||||||
Token::Minus | Token::Tilde => {
|
Token::Minus | Token::Tilde => {
|
||||||
self.advance();
|
self.advance();
|
||||||
|
let ast_operator = match operator_token_snapshot {
|
||||||
let operator = match current_tok {
|
Token::Minus => Operator::Minus,
|
||||||
Token::Minus => Operator::Minus,
|
|
||||||
Token::Tilde => Operator::Almost,
|
Token::Tilde => Operator::Almost,
|
||||||
_ => unreachable!("Lexer should not produce other tokens here if first match is minus/tilde"),
|
_ => unreachable!("Lexer should not produce other tokens here if first match is minus/tilde. Checked by matches! macro."),
|
||||||
};
|
};
|
||||||
|
|
||||||
let right_operand = self.parse_primary()?;
|
let right_operand = self.parse_unary()?;
|
||||||
Some(Expression::Unary(operator, Box::new(right_operand)))
|
Some(Expression::Unary(ast_operator, Box::new(right_operand)))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// If not a unary operator, just return the primary expression
|
self.parse_call_expression()
|
||||||
self.parse_primary()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,6 +337,82 @@ impl Parser {
|
|||||||
Some(expr)
|
Some(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_logical_or(&mut self) -> Option<Expression> {
|
||||||
|
let mut expr = self.parse_logical_and()?;
|
||||||
|
|
||||||
|
while matches!(self.current_token(), Token::Or) {
|
||||||
|
let operator_token = self.current_token().clone();
|
||||||
|
self.advance();
|
||||||
|
|
||||||
|
let ast_operator = Operator::Or;
|
||||||
|
|
||||||
|
let right_operand = self.parse_logical_and()?;
|
||||||
|
expr = Expression::Binary(Box::new(expr), ast_operator, Box::new(right_operand));
|
||||||
|
}
|
||||||
|
Some(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_logical_and(&mut self) -> Option<Expression> {
|
||||||
|
let mut expr = self.parse_equality()?;
|
||||||
|
|
||||||
|
while matches!(self.current_token(), Token::And) {
|
||||||
|
let operator_token = self.current_token().clone();
|
||||||
|
self.advance();
|
||||||
|
|
||||||
|
let ast_operator = Operator::And;
|
||||||
|
|
||||||
|
let right_operand = self.parse_equality()?;
|
||||||
|
expr = Expression::Binary(Box::new(expr), ast_operator, Box::new(right_operand));
|
||||||
|
}
|
||||||
|
Some(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_call_expression(&mut self) -> Option<Expression> {
|
||||||
|
let mut expr = self.parse_primary()?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if self.check(&Token::LeftParen) {
|
||||||
|
expr = self.finish_call(expr)?;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_call(&mut self, callee: Expression) -> Option<Expression> {
|
||||||
|
self.advance();
|
||||||
|
|
||||||
|
let arguments = self.parse_arguments()?;
|
||||||
|
|
||||||
|
if !self.match_token(Token::RightParen) {
|
||||||
|
eprintln!("Error: Expected ')' after arguments in function call.");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Expression::FunctionCall(Box::new(callee), arguments))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_arguments(&mut self) -> Option<Vec<Expression>> {
|
||||||
|
let mut arguments = Vec::new();
|
||||||
|
|
||||||
|
if self.check(&Token::RightParen) {
|
||||||
|
return Some(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.parse_expression() {
|
||||||
|
Some(arg) => arguments.push(arg),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
|
||||||
|
while self.match_token(Token::Comma) {
|
||||||
|
match self.parse_expression() {
|
||||||
|
Some(arg) => arguments.push(arg),
|
||||||
|
None => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(arguments)
|
||||||
|
}
|
||||||
|
|
||||||
fn check(&self, expected: &Token) -> bool {
|
fn check(&self, expected: &Token) -> bool {
|
||||||
if self.is_at_end() {
|
if self.is_at_end() {
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user