0

I have a flatmap that's going through a Sequence, and I'm using case in order to identify different elements in the Sequence, and replace the elements with something else. However, in some of those cases, I also want to increase a counter variable. Can I put an instruction inside a case? It seems that I can't, since what goes inside the case is what's going to replace the element of the Sequence. Is this possible at all? Here's the code that I tried, and it didn't work:

var location = 0
code.flatMap {
        case Define(label) => Word("")                            // Return an empty Word, don't increase location
        case CodeWord(word) => word; location = location + 4    // Return the Word and increase location by 4
        case Use(label) => Word(Assembler.encodeUnsigned(labelToValue(label))); location = location + 4
                                                                  // Convert label into Seq, then into Word. Increase location.
        case BeqBne(bits, label) =>{ // Are brackets necessary?
            Word(bits ++ encodeUnsigned(labelToValue(label) - (location + 4))); location = location + 4 }
        case _ => require(false, s"Encountered unsupported code $code.");
      }

It's important that I update the location variable because as you can see, in case BeqBne(bits, label) I need to use the current value of location. Should I create a function outside of flatmap which does all of that stuff and then just call the function and pass the values in each case inside of flatmap? Any advice is appreciated.

GeleiaDeMocoto
  • 151
  • 1
  • 10
  • I might be helpful to provide some context for this code. From what I can glean from the above code snippet, I suspect that `flatMap`, or at least the way you're applying it, is not the most natural approach. Maybe I'm being picky, but the combination of `flatMap` with side effects sets off my spidey sense. – Jason Scott Lenderman Oct 08 '15 at 02:22

1 Answers1

2

When specifying multiple statements in a block of code the last statement is used as the return value. So you will need to increase the location variable first and then create the Word result.

E.g., change:

case Use(label) => {
  Word(Assembler.encodeUnsigned(labelToValue(label)));
  location = location + 4
}

To:

case Use(label) => {
  location = location + 4;
  Word(Assembler.encodeUnsigned(labelToValue(label)));
}

Or if you need to increment location after creating the result then store the result in a variable:

case BeqBne(bits, label) => {
  val result = Word(bits ++ encodeUnsigned(labelToValue(label) - (location + 4)));
  location = location + 4;
  result
}
Chris P.
  • 116
  • 1
  • 6