Newer
Older
** 2017-01-26 design data structure for the calculator.
- this can be written and tested independently from the web UI.
- basic data:
- stack of numbers.
- current state and data in finite state machine (fsm).
- data for undo. I think I can just take a snapshot of the fsm.
- how many states are there?
| this state | event | next state |
|------------------------------+---------------------------+--------------------------------------------------|
| idle | press num keys or dot key | modify number, then waiting for number or action |
| idle | press +-*/ swap | do op, then idle |
| waiting for number or action | press num keys or dot key | modify number, then waiting for number or action |
| waiting for number or action | press return key | commit number, then idle |
| waiting for number or action | press +-*/ | commit number, do op, then idle |
| waiting for number or action | press < key | modify number, then waiting for number or action |
| idle | press return key | dup number, then idle |
| idle | press < key | drop number on stack, then idle |
There is no ending state, the machine can always accept new keyboard events.
- a few display and error handling.
- when number is "0", press more num0 will just show error and not modify the number.
- when number is "", press dot will change number to "0."
- when number already has a dot in it, future dot will just show error and
not modify the number.
* later :entry:
** 2017-01-26 make the whole thing a polymer web component
<rpn-calculator trail="true"></rpn-calculator>
User can also set height and width on the element, which will resize the
elements inside. When there is no room, show a scrollbar.
shadow dom should make all HTML/CSS/Javascript work together without affecting
the parent DOM.
* current :entry:
**
** 2017-01-27 add a reset button. browser refresh button is not always easily accessible, esp on mobile.
** 2017-01-27 make trail work
- when is trail being updated?
- when a number is committed to number stack. return.
- when a new number is pushed to stack as an op result. plus, change-sign.
- this should be part of the FSM.
what data should I store?
it's a queue of [(Maybe op, number)].
as mentioned previously, this data can be made persistent across
pages/sessions.
- load persistent data for trails when init the FSM.
// is updating local storage a heavy operation? I hope it doesn't sync to
disk everytime I update a key.
- implementation notes
- show last 10 entries in UI. allow user to use scrollbar to scroll to
earlier entries.
leave this UI optimization later. for now, just show last 10 or 20 entries.
- use table to show trail in HTML.
trailOp right align.
trailNum left align.
mark last entry using color highlight. there is no need for > marker.
- grep for "this.numberStack.push" to push elements to this.trail.
- change-sign op is not shown in trait. why?
it's because shortKeyNames key should be key name string literal, not the
js constant identifier.
trail is a bounded fifo queue, it just store recent 1k entries.
when multiple instances of calculator is working. they all write to a single
trail cache. it's not a problem.
** 2017-01-26 make it work offline, add sw.js
** 2017-01-26 make undo work
** 2017-01-26 make basic things work.
- DONE make basic number input and arithmetic work
- DONE make DUP and SWP work
** 2017-01-27 stack, trail: overflow problem.
- when there is not enough room, show scrollbar.
- always show the title section.
- auto scroll to bottom when content overflow.
TODO how to scroll to bottom?
$('#stack-content').scroll
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
** 2017-01-26 make < (backspace) work.
** 2017-01-26 make stack auto numbering work
** 2017-01-26 handle error for every this.numberStack.pop()
- handle error for every this.numberStack.pop()
- show lastError in web UI.
RPNCalculator should clear lastError when it processed another sendKey()
successfully.
maybe do early return whenever I called this.setErrorMsg(errMsg).
- implementation notes
- [].pop() return undefined when array is empty.
- when fetch 2 values, if only 1 fail. the pop() number should be put back
to the stack. add a unit test for this.
- about division by 0. js just return infinity.
I will show error instead and do not consume any number on stack.
** 2017-01-27 feature: backspace key, when idle, should delete number on stack.
** 2017-01-27 bug: press number-display button trigger an error.
it is treated as a num key.
the FSM should only accept known keys.
update isNumberKey().
** 2017-01-26 make basic number input and arithmetic work
- DONE make event work.
- TODO add some visual feedback when clicking a button. like in material design.
- DONE design data structure for the calculator.
- DONE add unit test for the data structure and functions.
- DONE make number input and simple calculation work.
** 2017-01-27 make RPNCalculator work with web UI.
- make event handler work with RPNCalculator.
- sync this.numberStack and this.currentNumber with the web UI.
** 2017-01-26 what to do with negate operator?
emacs use n (change sign)
add this button. move divide button to somewhere else.
** 2017-01-26 how to write a fsm simulator in javascript.
- try write an easier example before writing the real thing.
- easy example:
check whether a string has substring "abb".
states:
| this state | event | next state |
|------------------+-----------------------+-----------------------------------------------------------------------------------------------|
| wait for "a" | read new character ch | if ch is "a", wait for 1st "b"; otherwise, wait for "a" |
| wait for 1st "b" | read new character ch | if ch is "b" => wait for 2nd "b"; if ch is "a" => wait for 1st "b"; otherwise => wait for "a" |
| wait for 2nd "b" | read new character ch | if ch is "b" => succeed; if ch is "a" => wait for 1st "b"; otherwise => wait for "a" |
| succeed | ∅ | ∅ |
- it works.
** 2017-01-26 draw the keyboard using HTML and CSS