| <?xml version="1.0" ?> |
| <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" |
| initial="wrapper" datamodel="ecmascript" name="CalculatorStateMachine"> |
| <datamodel> |
| <data id="long_expr" /> |
| <data id="short_expr" /> |
| <data id="res" /> |
| </datamodel> |
| <state id="wrapper" initial="on"> |
| <state id="on" initial="ready"> |
| <onentry> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| <state id="ready" initial="begin"> |
| <state id="begin"> |
| <transition event="OPER.MINUS" target="negated1" /> |
| <onentry> |
| <assign location="long_expr" expr="''" /> |
| <assign location="short_expr" expr="0" /> |
| <assign location="res" expr="0" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| </state> |
| <state id="result"> |
| </state> |
| <transition event="OPER" target="opEntered" /> |
| <transition event="DIGIT.0" target="zero1"> |
| <assign location="short_expr" expr="''" /> |
| </transition> |
| <transition event="DIGIT" target="int1"> |
| <assign location="short_expr" expr="''" /> |
| </transition> |
| <transition event="POINT" target="frac1"> |
| <assign location="short_expr" expr="''" /> |
| </transition> |
| </state> |
| <state id="negated1"> |
| <onentry> |
| <assign location="short_expr" expr="'-'" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| <transition event="DIGIT.0" target="zero1" /> |
| <transition event="DIGIT" target="int1" /> |
| <transition event="POINT" target="frac1" /> |
| </state> |
| <state id="operand1"> |
| <state id="zero1"> |
| <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int1" /> |
| <transition event="POINT" target="frac1" /> |
| </state> |
| <state id="int1"> |
| <transition event="POINT" target="frac1" /> |
| <transition event="DIGIT"> |
| <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> |
| <send event="DISPLAY.UPDATE" /> |
| </transition> |
| <onentry> |
| <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| </state> |
| <state id="frac1"> |
| <onentry> |
| <assign location="short_expr" expr="short_expr+'.'" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| <transition event="DIGIT"> |
| <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> |
| <send event="DISPLAY.UPDATE" /> |
| </transition> |
| </state> |
| <transition event="OPER" target="opEntered" /> |
| </state> |
| <state id="opEntered"> |
| <transition event="OPER.MINUS" target="negated2" /> |
| <transition event="POINT" target="frac2" /> |
| <transition event="DIGIT.0" target="zero2" /> |
| <transition event="DIGIT" target="int2" /> |
| <onentry> |
| <raise event="CALC.SUB" /> |
| <send target="#_internal" event="OP.INSERT"> |
| <param name="operator" expr="_event.name" /> |
| </send> |
| </onentry> |
| </state> |
| <state id="negated2"> |
| <onentry> |
| <assign location="short_expr" expr="'-'" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| <transition event="DIGIT.0" target="zero2" /> |
| <transition event="DIGIT" target="int2" /> |
| <transition event="POINT" target="frac2" /> |
| </state> |
| <state id="operand2"> |
| <state id="zero2"> |
| <transition event="DIGIT" cond="_event.name != 'DIGIT.0'" target="int2" /> |
| <transition event="POINT" target="frac2" /> |
| </state> |
| <state id="int2"> |
| <transition event="DIGIT"> |
| <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> |
| <send event="DISPLAY.UPDATE" /> |
| </transition> |
| <onentry> |
| <assign location="short_expr" expr="short_expr+_event.name.substr(_event.name.lastIndexOf('.')+1)" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| <transition event="POINT" target="frac2" /> |
| </state> |
| <state id="frac2"> |
| <onentry> |
| <assign location="short_expr" expr="short_expr +'.'" /> |
| <send event="DISPLAY.UPDATE" /> |
| </onentry> |
| <transition event="DIGIT"> |
| <assign location="short_expr" expr="short_expr +_event.name.substr(_event.name.lastIndexOf('.')+1)" /> |
| <send event="DISPLAY.UPDATE" /> |
| </transition> |
| </state> |
| <transition event="OPER" target="opEntered"> |
| <raise event="CALC.SUB" /> |
| <raise event="OP.INSERT" /> |
| </transition> |
| <transition event="EQUALS" target="result"> |
| <raise event="CALC.SUB" /> |
| <raise event="CALC.DO" /> |
| </transition> |
| </state> |
| <transition event="C" target="on" /> |
| </state> |
| <transition event="CALC.DO"> |
| <assign location="short_expr" expr="''+ res" /> |
| <assign location="long_expr" expr="''" /> |
| <assign location="res" expr="0" /> |
| </transition> |
| <transition event="CALC.SUB"> |
| <if cond="short_expr!=''"> |
| <assign location="long_expr" expr="long_expr+'('+short_expr+')'" /> |
| </if> |
| <assign location="res" expr="eval(long_expr)" /> |
| <assign location="short_expr" expr="''" /> |
| <send event="DISPLAY.UPDATE" /> |
| </transition> |
| <transition event="DISPLAY.UPDATE"> |
| <log label="'result'" expr="short_expr==''?res:short_expr" /> |
| <send event="updateDisplay"> |
| <param name="display" expr="short_expr==''?res:short_expr"/> |
| </send> |
| </transition> |
| <transition event="OP.INSERT"> |
| <log expr="_event.data.operator" /> |
| <if cond="_event.data.operator == 'OPER.PLUS'"> |
| <assign location="long_expr" expr="long_expr+'+'" /> |
| <elseif cond="_event.data.operator=='OPER.MINUS'" /> |
| <assign location="long_expr" expr="long_expr+'-'" /> |
| <elseif cond="_event.data.operator=='OPER.STAR'" /> |
| <assign location="long_expr" expr="long_expr+'*'" /> |
| <elseif cond="_event.data.operator=='OPER.DIV'" /> |
| <assign location="long_expr" expr="long_expr+'/'" /> |
| </if> |
| </transition> |
| </state> |
| </scxml> |