DEV Community

Lahari Tenneti
Lahari Tenneti

Posted on

Logical Operators & Control Flow

After statements, we will now be adding support for logical operators and control flow statements - conditional (if-else) and looping (while, for).

What I built: Commit 089ad4d


What I understood:

1) If Statements

  • We extend the statement rule to accomodate ifStmt, which leads to expression(). The thenBranch calls statement() again.
  • Also, we avoid the dangling-else problem, wherein nesting-if conditions cause uncertainty about which if statement an else clause belongs to - inner or outer?
  • This is by checking for the existence of an else branch which is assumed to belong to the innermost if statement.

2) Logical Operators

  • We modify the grammar to have assignment() call or() (which calls and()) instead of equality(). equality() is called by and()
  • We use short-circuiting while using logical-operators, which makes decisions basis the state of the left-operand.
  • Ex: In OR, if the left operand is truthy (evaluates to true), the interpreter skips the right operand, and returns the left operand itself.
  • But if the left-operand is false, it has to check the right operand and compute the result based on it.
var greet = greeting or "Hello";
//defaults to Hello if greeting is null/false.
Enter fullscreen mode Exit fullscreen mode
  • In AND, if the left-operand is false, the entire expression results in false, and thus the second operand needn't be evaluated.
//LOGIC  
public Object visitLogicalExpr(Expr.Logical expr) {
    Object left = evaluate(expr.left);

    if (expr.operator.type == TokenType.OR) {
      if (isTruthy(left)) return left;
    } else {
      if (!isTruthy(left)) return left;
    }

    return evaluate(expr.right);
  }
Enter fullscreen mode Exit fullscreen mode

3) While Loops

  • The statement rule is further extended to call whileStmt, which basically executes the body of statements if the given condition evaluates to ‘true’
//LOGIC
public Void visitWhileStmt(Stmt.While stmt) {
    while (isTruthy(evaluate(stmt.condition))) {
      execute(stmt.body);
    }
    return null;
  }
Enter fullscreen mode Exit fullscreen mode

4) For Loops

  • forStmt is added to the statement rule. A for condition is supposed to have three parts - initialiser, the condition, and the action (increment/decrement). Variables are created to hold these three parts.
  • Interestingly, we don’t evaluate a for loop as a for loop, and actually convert it into a while loop
  • We first check for the initialiser by looking for VAR and call varDeclaration() if it’s present.
  • Then, the interpreter looks for a ;, after which it calls expression(). Finally, we call expression() again on encountering an increment/decrement.
  • The statements are wrapped inside a block, as a list.
  • We also append the increment condition to the body of statements.
  • When then wrap this body into a while loop, that is executed after the initialiser statement runs exactly once.
for (var i = 0; i < 10; i = i + 1) print i;
Enter fullscreen mode Exit fullscreen mode

is converted to

var i = 0; // Initialiser runs once 
while (i < 10) {
// the parser here groups the original body of statements and the
increment into a single unit for the while loop’s body
    {
        print i;
        i = i + 1; 
    }
}
Enter fullscreen mode Exit fullscreen mode


What's next:
Functions! This takes the interpreter ahead significantly by introducing concepts like lexical scope, closures, call stack management, and a return mechanism.


Musings:
Coffee Cold is a song I deeply love. For some reason, it feels like both a dig at and a celebration of life’s strangeness. Like it’s trying to tell me that at the end of the day, there are things way beyond my control that shape my world. I can either choose to get upset due to them or smile and walk on, towards my next adventure. “Life is neither a Tempest, nor a Midsummer Night’s Dream. It’s more like a Comedy of Errors and you take it As You Like It.” As the Tao Te Ching says, it's alllll about the flow. 😉

Top comments (0)