Implementing Do keyword in a compiler I'm writting a compiler implementation for a language that you can see defined here. I having problems designing how the do keyword should be handled. You can find the code I'm referring to in here. 

Let me delve a little bit into the problem. According to the documentation:


  The do keyword is used to call an expression (normally, a method call)
  just for its side-effect, and discards the result.


Now according to the list of possible expressions in the file I referred to before:

IntLit(value) 
StringLit(value)
True()
False() 
And(lhs, rhs) 
Or(lhs, rhs)  
Plus(lhs, rhs) 
Minus(lhs, rhs) 
Times(lhs, rhs) 
Div(lhs, rhs) 
LessThan(lhs, rhs) 
Not(expr)
Equals(lhs, rhs)  
ArrayRead(arr, index) 
ArrayLength(arr) 
MethodCall(obj, meth, args)
Variable(Identifier(name))
New(tpe)      
This()
NewIntArray(size)


I want to figure out first in which cases should do act. Clearly, it should act with MethodCall as it provides a result but also with expressions that contain operators (And,Or,Plus,Minus,Times,Div,LessThan,Not,Equals,...). What would be the complete list of cases I should consider?

My second question is how can I implement Do behaviour for MethodCall, that is, not getting the result but getting the side effects.
The general idea is that do ( expression ) is a statement that evaluates any expression and throws away the result.

A first attempt could be

  def evalExpr(e: ExprTree)(implicit ectx: EvaluationContext): Value =
    // ...

  def evalStatement(stmt: StatTree)(implicit ectx: EvaluationContext): Unit =
    stmt match {
      // ...
      case DoExpr(expr) =&gt; 
        evalExpr(expr)
    }
  }


but in this way, we return a Value and not a Unit, so the compiler raises a type error. We can fix that by using

      case DoExpr(expr) =&gt; 
        evalExpr(expr)
        ()  // the Unit value