Scenario: I am parsing an IL and want to convert from a stackbased representation to a CFG for instance.
My IL consists of multiple operations like PushInt(value), Pop etc. The question is now which implementation would be correct in terms of Scala. I would love to use case classes/objects or extractors so that I can write code alà
op match {
case PushInt(x) => doSomethingWith x
case Pop => ...
}
Now the problem exists with a sequence like PushInt(1) :: PushInt(1) :: Pop :: Pop
since PushInt(1) is equal to PushInt(1) and I can not add multiple (equal) operations into a collection. However I know I am throwing some information away which is the position in the flow, but this is implicitly stored as te index in the sequence.
One possible solution is to override the hashCode method and break the rules of equal/hashCode. I am not really happy with that.
Another option is to have a "creation time" counter that is stored in the abstract base so that
case class PushInt(value: Int) extends AbstractOp(AbstractOp.nextIndex)
Use extractors but in that case I will miss nice features like the implementation of hashCode, equals, toString and more important the check for an exhaustive match.
So my question is now how to model my structure according to my requirements. Is any of the possible solutions "correct" in terms of Scala?