A calculator
A calculator that reads what you type, such as rate * (hours - 0.5), has a harder job than it looks. The line is only text: the program has to find the numbers and symbols in it, know that * comes before - unless parentheses say otherwise, remember names, and say clearly what's wrong when the text isn't a calculation. In this project you build that calculator, one line at a time.
When it's finished, a session looks like this. The calculator reads these lines:
rate = 12.5
hours = 8
pay = rate * (hours - 0.5)
pay / 3
-(2 + 3) * 4
pay / (hours - 8)
2 + * 3
and answers each one:
rate = 12.5
hours = 8
pay = 93.75
31.25
-20
Error: division by zero
Error: expected a number at column 5
A line with = saves a value under a name. Every other line is calculated and its value printed. A mistake doesn't stop the program: it gets a message, and the next line is read as usual.
How it works
The calculator works in three stages. The first two are how javac reads your code too:
- The lexer splits the text into tokens:
rate,*,(,hours,-,0.5,). Each token knows its column, so a message can point at it. - The parser builds a tree from the tokens, as records. In the tree of
2 + 3 * 4, the multiplication sits under the addition, so it's calculated first. - The calculator evaluates the tree with a switch over record patterns, as in the last challenge of module 58. There the tree was written by hand; here the parser builds it from text.
What you need
Everything up to module 58: strings and charAt (module 16), lists (module 13), classes and objects (modules 17 to 19), hash maps (module 31), exceptions (module 42), recursion (module 55), records (module 56), switch expressions (module 57), and sealed interfaces with record patterns (module 58). The few library methods the project needs beyond these, such as Character.isDigit, are explained where they're used.
The milestones
- Tokens: the lexer splits a line into numbers and symbols.
- Left to right: the first calculations, one operator after another.
- Multiplication first: a parser that builds a tree with precedence.
- Parentheses and minus signs.
- Variables: saving values under names.
- Clear error messages for bad input.
Calculations use double, so 7 / 2 is 3.5, and a whole number is shown without .0.
Milestones
- Tokens
- Left to right
- Multiplication first
- Parentheses and minus signs
- Variables
- Clear error messages