1
$\begingroup$

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.

$\endgroup$
8
  • 2
    $\begingroup$ The problem statement seems to specify that do can wrap around any expression. $\endgroup$
    – Raphael
    Commented Oct 3, 2016 at 10:07
  • 3
    $\begingroup$ Just implement do exp as you would do for x = exp but don't store the result in variable x. $\endgroup$
    – chi
    Commented Oct 3, 2016 at 11:35
  • $\begingroup$ @Raphael certainly it can wrap around any expression so my solution would have a generic case for those that do not need special treatment $\endgroup$ Commented Oct 3, 2016 at 12:08
  • $\begingroup$ @chi you mean like in the line case Assign(id, expr) => ectx.setVariable(id.value, evalExpr(expr))? $\endgroup$ Commented Oct 3, 2016 at 12:11
  • 1
    $\begingroup$ 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. $\endgroup$
    – chi
    Commented Oct 3, 2016 at 12:18

1 Answer 1

1
$\begingroup$

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
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.