Home > Mobile >  How does a missing boolean operator still compile?
How does a missing boolean operator still compile?

Time:02-23

I have code like this:

val pop: Bool = (
  (fsm === Fsm.None && canPop) ||
  (fsm === Fsm.Some && canPop && fooBar)
  (fsm === Fsm.Other && canPop && dragonFruit) ||
  (fsm === Fsm.Mom && canPop))

fsm is a ChiselEnum based state machine and the other signals are just Bools. There is a missing || on the second statement line (after fooBar). This compiles and runs, although causes a bug in the behavior. My question is... why does this compile? This doesn't seem like valid syntax. Is it?

Please help me understand this. I just spent numerous days debugging a large circuit to find this issue.

CodePudding user response:

Correct Answer

The problem is that this is a bit extract. Chisel lets you do foo(bar) to extract the bit at index bar out of foo. The above code, as written, is a bit extract even though the user wants it to be a mistake.

Unfortunately, this is a known gotcha and it's not reasonable to error on this without false positives while still allowing users to use the () syntax for bit extracts.

Incorrect Original Answer

It's valid syntax per Scala rules. What's going on here is that the code is really two statements, but the indentation is confusing. It's equivalent to:

val foo = a   b  // Create an immutable value equal to "a   b".
  c   d          // A bare statement that adds "c   d", but doesn't use the result.

Or infamous C bugs like:

if (cond)
  foo();
  bar(); // bar() is always executed, but the indentation is confusing.

Usually this is the type of thing that you'd notice due to a code formatter or via linting. However, the problem is common to almost every language.

Setting up Scalafmt for your project may help.

  • Related