Skip to content

Commit c970cda

Browse files
Add native boolean operators
1 parent df2c7c1 commit c970cda

2 files changed

Lines changed: 102 additions & 14 deletions

File tree

‎native/src/parser.rs‎

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ pub enum Expression {
5252
operator: BinaryOperator,
5353
right: Box<Expression>,
5454
},
55+
Unary {
56+
operator: UnaryOperator,
57+
operand: Box<Expression>,
58+
},
5559
Call(Call),
5660
}
5761

@@ -63,6 +67,13 @@ pub enum BinaryOperator {
6367
Divide,
6468
Greater,
6569
Equal,
70+
And,
71+
Or,
72+
}
73+
74+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75+
pub enum UnaryOperator {
76+
Not,
6677
}
6778

6879
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -212,41 +223,81 @@ impl Parser {
212223
}
213224

214225
fn expression(&mut self) -> Result<Expression, ParseError> {
215-
let mut expression = self.factor()?;
216-
while self.check(TokenKind::Plus) || self.check(TokenKind::Minus) {
217-
let operator = if self.check(TokenKind::Plus) {
218-
BinaryOperator::Add
219-
} else {
220-
BinaryOperator::Subtract
226+
self.or()
227+
}
228+
229+
fn or(&mut self) -> Result<Expression, ParseError> {
230+
let mut expression = self.and()?;
231+
while self.check(TokenKind::Or) {
232+
self.position += 1;
233+
expression = Expression::Binary {
234+
left: Box::new(expression),
235+
operator: BinaryOperator::Or,
236+
right: Box::new(self.and()?),
221237
};
238+
}
239+
Ok(expression)
240+
}
241+
242+
fn and(&mut self) -> Result<Expression, ParseError> {
243+
let mut expression = self.equality()?;
244+
while self.check(TokenKind::And) {
222245
self.position += 1;
223246
expression = Expression::Binary {
224247
left: Box::new(expression),
225-
operator,
226-
right: Box::new(self.factor()?),
248+
operator: BinaryOperator::And,
249+
right: Box::new(self.equality()?),
227250
};
228251
}
229-
if self.check(TokenKind::Greater) {
252+
Ok(expression)
253+
}
254+
255+
fn equality(&mut self) -> Result<Expression, ParseError> {
256+
let mut expression = self.comparison()?;
257+
while self.check(TokenKind::EqualEqual) {
258+
self.position += 1;
259+
expression = Expression::Binary {
260+
left: Box::new(expression),
261+
operator: BinaryOperator::Equal,
262+
right: Box::new(self.comparison()?),
263+
};
264+
}
265+
Ok(expression)
266+
}
267+
268+
fn comparison(&mut self) -> Result<Expression, ParseError> {
269+
let mut expression = self.term()?;
270+
while self.check(TokenKind::Greater) {
230271
self.position += 1;
231272
expression = Expression::Binary {
232273
left: Box::new(expression),
233274
operator: BinaryOperator::Greater,
234-
right: Box::new(self.factor()?),
275+
right: Box::new(self.term()?),
235276
};
236277
}
237-
if self.check(TokenKind::EqualEqual) {
278+
Ok(expression)
279+
}
280+
281+
fn term(&mut self) -> Result<Expression, ParseError> {
282+
let mut expression = self.factor()?;
283+
while self.check(TokenKind::Plus) || self.check(TokenKind::Minus) {
284+
let operator = if self.check(TokenKind::Plus) {
285+
BinaryOperator::Add
286+
} else {
287+
BinaryOperator::Subtract
288+
};
238289
self.position += 1;
239290
expression = Expression::Binary {
240291
left: Box::new(expression),
241-
operator: BinaryOperator::Equal,
292+
operator,
242293
right: Box::new(self.factor()?),
243294
};
244295
}
245296
Ok(expression)
246297
}
247298

248299
fn factor(&mut self) -> Result<Expression, ParseError> {
249-
let mut expression = self.primary()?;
300+
let mut expression = self.unary()?;
250301
while self.check(TokenKind::Star) || self.check(TokenKind::Slash) {
251302
let operator = if self.check(TokenKind::Star) {
252303
BinaryOperator::Multiply
@@ -257,12 +308,23 @@ impl Parser {
257308
expression = Expression::Binary {
258309
left: Box::new(expression),
259310
operator,
260-
right: Box::new(self.primary()?),
311+
right: Box::new(self.unary()?),
261312
};
262313
}
263314
Ok(expression)
264315
}
265316

317+
fn unary(&mut self) -> Result<Expression, ParseError> {
318+
if self.check(TokenKind::Bang) {
319+
self.position += 1;
320+
return Ok(Expression::Unary {
321+
operator: UnaryOperator::Not,
322+
operand: Box::new(self.unary()?),
323+
});
324+
}
325+
self.primary()
326+
}
327+
266328
fn primary(&mut self) -> Result<Expression, ParseError> {
267329
let token = self.current().clone();
268330
match token.kind {

‎native/src/runtime.rs‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,24 @@ fn evaluate(
230230
} => Ok((evaluate(left, variables, functions, output)?
231231
== evaluate(right, variables, functions, output)?)
232232
.to_string()),
233+
Expression::Binary {
234+
left,
235+
right,
236+
operator: crate::parser::BinaryOperator::And,
237+
} => Ok((evaluate(left, variables, functions, output)? == "true"
238+
&& evaluate(right, variables, functions, output)? == "true")
239+
.to_string()),
240+
Expression::Binary {
241+
left,
242+
right,
243+
operator: crate::parser::BinaryOperator::Or,
244+
} => Ok((evaluate(left, variables, functions, output)? == "true"
245+
|| evaluate(right, variables, functions, output)? == "true")
246+
.to_string()),
247+
Expression::Unary {
248+
operator: crate::parser::UnaryOperator::Not,
249+
operand,
250+
} => Ok((evaluate(operand, variables, functions, output)? != "true").to_string()),
233251
Expression::Call(call) => {
234252
let arguments = call
235253
.arguments
@@ -323,4 +341,12 @@ mod tests {
323341
"division by zero"
324342
);
325343
}
344+
345+
#[test]
346+
fn runs_boolean_operators() {
347+
assert_eq!(
348+
run("fn main() { print(!false && true || false) }").unwrap(),
349+
"true\n"
350+
);
351+
}
326352
}

0 commit comments

Comments
 (0)