Boolean Expressions
Interpreters, Iteration 15
This iteration required a change to the Hobbes front end. Make sure you have the latest.
User Story
User Story #15: Interpreter evaluates less than operator and equal-to operator.
A Hobbes program can be the comparison of two integers or two
strings using <
and ==
. Integers
compare naturally. Strings should be compared lexicographically
(based on Unicode order). The Hobbes program should print
true
and false
as appropriate.
Printing the true
and false
is already
taken care of for you. The Hobbes driver does this by turning the
returned ExpressionTIR
into a String
. So,
you will never need to deal with "true"
or
"false"
.
Instead, you want to deal with BooleanETIR
s. The
BooleanETIR
class is provided in the CITkit library,
and you're already set up to start interpreting them.
Interpreting <
and ==
will be a
matter of writing some more OperatorAlgorithm
s.
Interpreting Plain Booleans
It turns out that you can't write a program with just a
true
or false
in it. (The user story
doesn't specify that boolean constants are allowed, and if you ask
the client, he doesn't want it. Of course, he's welcome to change
his mind in a later iteration. Time will tell if he does or
not...)
This means that you don't have to worry about them in
HobbesInterpreter
. Booleans can only be produced from
OperatorETIR
s, and that case defers the computations
to operator algorithms. So that's where you need to do your
work.
Acceptance Tests
CIAT does allow you to put tests in subdirectories. Presently,
they're all in acceptance/ciat/hobbes
. If you want to
create subdirectories
acceptance/ciat/hobbes/comparisons
or even
acceptance/ciat/hobbes/comparisons/less-than
, feel
free. Feel free to re-organize your existing tests into
subdirectories.
Write at least twelve CIAT tests for the two new operators.
Yikes!
Where does the number 12 come from? Well, you actually have
four computations you're implementing: integer less-than,
string less-than, integer equals, and string equals. Each one of
those should be tested three different ways. For example, integer
less-than could be tested with these three programs: 3 < 5, 4 ==
4, and 5 < 3. The false
cases are just as
important as the true
ones!
Run the acceptance tests, and watch the new ones fail.
The failures should be due to NPE from interpreting the operator expressions.
Why are you getting an NPE?
Comparing Integer Expressions
Here's a test method for one of the operator algorithms:
@Test public void shouldCompareIntegers() { assertEquals(BooleanETIR.TRUE, myAlgorithm.compute(new IntegerETIR(3), new IntegerETIR(5))); assertEquals(BooleanETIR.FALSE, myAlgorithm.compute(new IntegerETIR(5), new IntegerETIR(5))); assertEquals(BooleanETIR.FALSE, myAlgorithm.compute(new IntegerETIR(12), new IntegerETIR(2))); }
The BooleanETIR
class has two constants in it:
TRUE
and FALSE
. This should make your
code more readable.
Create the appropriate test-case class, and add this test
method. Define a myAlgorithm
object, and initialize it
in a setUp()
method as you've done for the other
operator algorithms. Define the needed operator-algorithm class to
get the setUp()
to compile. Red bar.
The complaint should be that the computation class doesn't have the right method in it.
Define a compute(ExpressionTIR,ExpressionTIR)
in
the computation class which throws a "cannot process these
datatypes" exception. Red bar.
The red bar should be due to the exception that you're throwing.
Write compute(IntegerETIR,IntegerETIR)
. Green
bar.
Remember: IntegerETIR#getValue()
returns the
integer value. Java has "less than" built in. Use an
if
to return BooleanETIR
constants or
BooleanETIR#create(boolean)
(a static method) to
create the return value.
Re-run the CIAT tests. All the new tests still fail!
Actually, they error out because of NPEs. What didn't you do yet?
Fix the problem. Green bar on the unit tests; less of a red bar on the acceptance tests (three fewer).
You didn't forget to add
LESS_THAN
to the operator-algorithm map. You have
tests that tell you what to do, and they did there job. You fixed
this problem at exactly the right time!
Rinse and Repeat
Repeat this process for the three other computations.
Hint: String
s implements the
Comparable<String>
interface, so
compareTo(String)
is available. (Read the Java API for
more details.) Keep in mind that String
is different
from StringETIR
!