# 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)
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 problem statement seems to specify that do can wrap around any expression. – Raphael Oct 3 '16 at 10:07
• Just implement do exp as you would do for x = exp but don't store the result in variable x. – chi Oct 3 '16 at 11:35
• @Raphael certainly it can wrap around any expression so my solution would have a generic case for those that do not need special treatment – Rodrigo Oct 3 '16 at 12:08
• @chi you mean like in the line case Assign(id, expr) => ectx.setVariable(id.value, evalExpr(expr))? – Rodrigo Oct 3 '16 at 12:11
• Try e.g. ... => evalExpr(expr); () which calls the evaluator, discards its result and returns (): Unit anyway. I don't know Scala enough to say if there's a better (more idiomatic) way. – chi Oct 3 '16 at 12:18

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) =>
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) =>
evalExpr(expr)
()  // the Unit value