HyperCard tribute

電卓


 実践編〜中級〜で簡単電卓を作成しましたが、この電卓にはいくつか問題点が残ってました。例えば、以前の電卓では3+-2(四則演算記号が続くことはない)や、3...65(小数点が続くことはない)というように、電卓のルールに当たる部分を作っていなかったからです。そこで、今回の電卓はこれらの問題を解決し、今までの電卓にはなかった機能をいくつも盛り込んでみました。

電卓
 ダウンロード(84KB)


 まず簡単電卓の直すべき点を挙げていきます。
・四則演算記号は連続することはない(数値がこなくてはならない)
・「−」記号はマイナスの他に負の数値を表す場合もある
・小数点が続くことはない
・式が完結していない
・省略した「×」をつけ加える
・0の0乗はあり得ない


 次にこの電卓の新機能についてです。今までの電卓では考えられなかった機能を盛り込み、まるで紙の上で計算しているかのように気軽で、それでいて容易に計算ができるというコンセプトの元に作成しました。

・指数やルートをグラフィカルに表現することで、実際の計算式と同じ形を実現する

・過去の計算式とその答えをログとして残しておき、その答えを利用しての再計算を可能とする
 3番目の式は1番目と2番目の答えを利用しています

・答えが出た後も続けて計算をさせることができる

・一つ前の四則演算までもどるDelete、一つ前の計算結果へのUndoを実現する


 これらの点、機能別に分けて説明をしていきます。その前に画面構成と電卓の使い方を説明します。



画面構成

(1)フィールド「hyouji」
(2)ボタン「0」「1」・・・「9」
(3)ボタン「.」
(4)ボタン「delete」
(5)ボタン「Undo」
(6)ボタン「AC」
(7)ボタン(左上から)「+」「-」「*」「/」「^(」「sqrt(」
(8)ボタン「=」
(9)ボタン「消去」
(10)フィールド「result」


電卓の使い方
 基本の動作は実際の計算式に準拠します。式をそのまま画面上で表現するつもりで式を入力して下さい。

  • 加減乗除計算
     「+」「-」「×」「÷」ボタンを押します
  • 指数
     指数ボタンを押すと指数の肩を入力する状態になります。
     例:「」の入力方法
       1.「3」
       2.「(指数ボタン)」
       3.「5」
  • ルート
     ルートボタンを押すとルート記号が出ます
  • メモリー
     画面右下の過去の計算ログをクリックすることでその答えを現在の式に反映することができます
  • 消しゴム
     一つ前の四則演算記号まで消去します
  • Undo
     一つ前の計算式まで消去します
  • AC
     御破算にして計算をやり直します



    四則演算記号は連続することはない

     四則演算である「+」「*」「/」には共通のハンドラを持たせてあります。「-」には特別なルールがあるため、他の演算記号とは違うハンドラを持たせています。


    「+」「*」「/」のスクリプト
     1 
     2 
     3 
     4 
    
    on mouseDown
      btnDown
      sisoku
    end mouseDown
    
     ハンドラ「btnDown」は、ボタンを押し下げたときに右下へ移動する画面効果です。このスタックのボタンには全てこのハンドラ「btnDown」を呼び出すようにしてあります。


    ハンドラ「btnDown」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
    
    on btnDown
      put the loc of target into old
      set the loc of target to item 1 of old+3,item 2 of old+3
      wait while the mouse is down
      set the loc of target to old
    end btnDown
    
     ボタンの座標を取り出しその位置を移動させ、マウスボタンが上がったら元の位置に戻します。


    ハンドラ「sisoku」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    16 
    17 
    18 
    19 
    20 
    21 
    
    on sisoku
      global shousuu,con
      lock screen
      put char (the number of chars in cd fld "hyouji"-1) of cd fld "hyouji" into lc2
      put last char of cd fld "hyouji" into lc
      if cd fld "hyouji"=empty or lc="(" or cd fld "hyouji"="." then
        play "error"
      else if ( lc="-" and lc2="(" ) or ( lc="-" and lc2=empty ) then
        play "click2"
        put empty into last char of cd fld "hyouji"
      else if lc is a number or lc=")" then
        play "click2"
        put short name of target after cd fld "hyouji"
      else
        play "click2"
        put short name of target into last char of cd fld "hyouji"
      end if
      font_c
      put 0 into shousuu
      put 0 into con
    end sisoku
    
    このハンドラでは以下の条件をチェックしています。(例には間違い例を紹介しています)

    ・式が、空っぽの時、一つ前の文字が「(」、「.」の時には四則演算を入力することはできない
       例:+
       例:(+
       例:.*
    ・「 ( - 」と続いた後の場合は、マイナスを消去する
       例:(-+
    ・一つ前の文字が数字、あるいは終わりかっこの場合はその四則演算をつけ加える
    ・それ以外の場合は最後の文字に四則演算を上書き代入する

     これらの条件をチェックしそれぞれの処理を行います。その後、ハンドラ「font_c」を呼び出し、変数shousuuに0を代入します。
     変数shousuuの値が1であれば、現在少数以下の数字を入力している状態で、0であればそうでないときです。言い換えれば1の時には小数点を入力することができなく、0の時には小数点が入力できるということになります。



    「−」記号はマイナスの他に負の数値を表す場合もある

     「-」は四則演算記号の中でも特別な存在です。というのは、「-」は負の数字を表す場合もあるからです。例えば、-3+6、4+(-1)などの場合です。そのため「-」には専用のハンドラを持たせています。


    「-」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    
    on mouseDown
      global sisuu,ruto
      btnDown
      lock screen
      play "click2"
      put last char of cd fld "hyouji" into lc
      if lc is a number or lc="(" or lc=")" then
        put "-" after cd fld "hyouji"
      else
        put "-" into last char of cd fld "hyouji"
      end if
      font_c
    end mouseDown
    
    ・最後の文字が数字、あるいは、「(」、「)」であれば、「-」を最後尾につけ加える
    ・そうでないとき(「+」など)は最後の文字に上書き代入する



    小数点が続くことはない

     小数点というのは1よりも小さな値との区切りに使います。そのため、小数点が2つも3つもあるという状態はおかしいわけです。この小数点をチェックするハンドラが以下のスクリプトです。


    「.」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    
    on mouseDown
      global sisuu,ruto,shousuu
      btnDown  
      lock screen
      put the number of chars in cd fld "hyouji" into i
      if last char of cd fld "hyouji" is a number and shousuu=0 then
        play "click"
        put 1 into shousuu
        put short name of target after cd fld "hyouji"
      else
        play "error"
      end if
    end mouseDown
    
    ・最後の文字が数字であり、かつ変数shousuuが0であれば小数点をつけ加える

     変数shousuuは、現在、小数点以下の数字を入力することができるかどうかを示しています。現在小数点以下の数字を入力しているなら、変数shousuuは1となり、その値は四則演算記号か指数記号を入力するまで続きます。



    式が完結していない

     指数の肩のみを入力したり、四則演算で式が終わったりという絶対に必要な物が足りない式というのは実際の計算式でも間違いになります。しかし、この間違いを放っておくとエラーになりますので何らかの対処法が必要となります。例えば以下のような場合です。
     例:?の何乗=
     例:3+=
     例:sqrt()=
     今回はこの対処法として0をつけ加えることにしました。0を付けることで式を完結させることができるからです。  これらの間違いは、この電卓のルール、数式のルール、スクリプト上でのルールといった具合にそれぞれ原因が異なります。しかし、これらの間違いをユーザーに直してもらうのではなく、電卓が自動で処理しなくてはユーザーフレンドリーとは言えません。なぜなら、ユーザーにとって必要なのは計算する過程でなく結果だからです。


    「^(」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    16 
    17 
    18 
    19 
    20 
    21 
    22 
    23 
    24 
    25 
    26 
    27 
    28 
    29 
    30 
    31 
    
    on mouseDown
      global sisuu,shousuu
      btnDown
      lock screen
      add0
      if sisuu>0 then
        play "click2"
        put the number of chars of cd fld "hyouji" into i
        put cd fld "hyouji" into f
        if char i of f="0" and char (i-2) of f="^" and char (i-3) of f="0" then
          send "mouseDown" to cd btn "delete"
        end if   
        repeat with i=1 to sisuu
          put ")" after cd fld "hyouji"
          set the textfont of last char of cd fld "hyouji" to "sisuu"
        end repeat
        set the textfont of last char of cd fld "hyouji" to "empty()"
        put 0 into sisuu
        state
      else
        play "click2"
        put 1 into sisuu
        state
        put "^" after cd fld "hyouji"
        font_c
        put 0 into shousuu
        put "(" after cd fld "hyouji"
        set the textfont of last char of cd fld "hyouji" to "empty()"
      end if
      state
    end mouseDown
    
     7行目から19行目は、指数の肩を入力していた時の処理です。8〜12行目で0の0乗でないかどうかを調べ、13〜17行目で必要な分だけの終わりかっこを付けます。


    ハンドラ「add0」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    
    on add0
      put last char of cd fld "hyouji" into lc
      if lc is not a number and lc<>")" then
        put 0 after cd fld "hyouji"
        font_c
      end if
      put the number of chars of cd fld "hyouji" into i
      if char (i-2) of cd fld "hyouji"="^" then send "mouseDown" to cd btn "delete"
    end add0
    
     最後の文字が数字でなく、かつ「)」でない場合に、0を追加してハンドラ「font_c」を呼び出します。


    ボタン「=」のスクリプト
     ボタン「=」は計算結果を求めるハンドラです。
     1 
     2 
     3 
    
     4 
     5 
     6 
    
     7 
     8 
     9 
    10 
    11 
    
    12 
    13 
    14 
    15 
    16 
    17 
    18 
    19 
    20 
    21 
    22 
    23 
    24 
    25 
    26 
    27 
    28 
    29 
    30 
    31 
    32 
    33 
    34 
    35 
    36 
    37 
    38 
    
    39 
    40 
    41 
    42 
    43 
    44 
    45 
    
    46 
    47 
    48 
    49 
    50 
    51 
    52 
    
    53 
    54 
    55 
    56 
    57 
    58 
    59 
    60 
    
    61 
    62 
    63 
    64 
    65 
    66 
    
    on mouseDown
      global sisuu,ruto,shousuu
      btnDown
      
      lock screen
      play "sum"
      add0
      
      put the number of chars of cd fld "hyouji" into i
      if char (i-1) of cd fld "hyouji"="0" then
        put the number of chars of cd fld "hyouji" into i
        if char (i-3) of cd fld "hyouji"="^" then send "mouseDown" to cd btn "delete"
      end if
      
      if sisuu>0 then
        repeat with i=sisuu down to 1
          put ")" after cd fld "hyouji"
          if i>1 then set the textfont of last char of cd fld "hyouji" to "sisuu"
          else set the textfont of last char of cd fld "hyouji" to "empty()"
        end repeat
      end if
      if ruto>0 then
        repeat with i=ruto down to 1
          put ")" after cd fld "hyouji"
          if i>1 then set the textfont of last char of cd fld "hyouji" to "ru-to"
          else set the textfont of last char of cd fld "hyouji" to "empty()"
        end repeat
      end if
      put 0 into kakko
      repeat with i=1 to the number of chars of exp
        if char i of exp="(" then put kakko+1 into kakko
        else if char i of exp=")" then put kakko-1 into kakko
      end repeat
      if kakko>0 then
        repeat with i=kakko down to 1
          put ")" after exp
          put ")" after cd fld "hyouji"
          if kakko>1 then set the textFont of last char of cd fld "hyouji" to "empty()"
          else set the textFont of last char of cd fld "hyouji" to "f12"
        end repeat
      end if
      
      put cd fld "hyouji" into exp
      if exp is empty then exit mouseDown
      repeat with j=(the number of chars in exp) down to 1
        if char j of exp="=" then exit repeat
      end repeat
      if j<>1 then put empty into char 1 to j of exp
      else put 0 into j
      
      select text of cd fld "hyouji"
      domenu "コピー テキスト"
      set the lockText of cd fld "result" to false
      select after text of cd fld "result"
      domenu "ペースト テキスト"
      if j<>1 then put empty into char 1 to j of last line of cd fld "result"
      set the lockText of cd fld "result" to true
      
      put exp
      returnkey
      put "=" after cd fld "hyouji"
      set the textfont of last char of cd fld "hyouji" to "f12"
      put msg after cd fld "hyouji"
      put "=" after cd fld "result"
      set the textfont of last char of cd fld "result" to "f12"
      put msg&return after cd fld "result"
      
      if the number of lines of cd fld "result">=10 then delete line 1 of cd fld "result"
      put 0 into sisuu
      put 0 into ruto
      put 0 into sisuu
      state
    end mouseDown
    
     6行目でハンドラ「add0」を呼び出し、式が完結していなければ0をつけ加えます。
     0の0乗が入力されていたら、ボタン「delete」に「mouseDown」メッセージを送り、四則演算記号までさかのぼって式を消去する。
     12〜18行目で指数、19〜25行目でルート、26〜38行目で通常のかっこの付け忘れを調べ、その分だけ終わりかっこを付けます。そのかっこの内、1コは指数、ルート表現に必要なかっこですので、画面上では見えないようにしておきます。
     この電卓は連続計算機能を持っていますので、フィールド「hyouji」にある計算式の全てが計算すべき式であるとは限りません。そのため、39行目から45行目で必要のない式、すなわち前回までの式と結果を消去しています。
     46〜52行目で、フィールド「result」へ計算式を追加しています。この時フィールド「hyouji」の計算式をそのまま利用するために、フィールド「hyouji」の計算式をコピーテキストし、フィールド「result」へペーストテキストします。
     まず、フィールド「hyouji」の式全てをコピーし、次にフィールド「result」のロックを外します。そしてカーソルをフィールド「result」の最後の位置に持ってきてペーストをします。追加した式に前回の計算式などが残っていたら、その部分を消去してもう一度ロックをかけておきます。
     put文を用いたコピーだとフォントの情報が含まれなためこのような複雑な処理をすることになりました。
     53〜60行目では結果を求めています。HyperCardでは、計算式をメッセージボックスに代入しリターンキーを入力することで結果を求められますので、その機能を用いて計算をするのです。



    省略した「×」をつけ加える

     実際の計算式には、「」や「3(」というような式が多く使われます。しかし、この式も特別な処理をしなければエラーとなってしまいます。なぜなら、我々は頭の中で「」、「3×(ハ」という式に置き換えて計算をしているからです。
     そのためルートの処理と前かっこの処理のハンドラに、必要であれば「×」をつけ加えるというスクリプトを用意しておきます。


    「sqrt(」のスクリプト
     1 
     2 
     3 
    
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    16 
    17 
    18 
    
    19 
    20 
    21 
    22 
    23 
    24 
    25 
    26 
    27 
    28 
    29 
    30 
    31 
    32 
    33 
    34 
    35 
    36 
    37 
    38 
    39 
    40 
    41 
    42 
    43 
    44 
    45 
    46 
    47 
    48 
    49 
    
    on mouseDown
      global sisuu,ruto,shousuu
      btnDown
      
      lock screen
      if sisuu>0 then
        play "click2"
        add0
        repeat with i=sisuu+ruto down to 1
          put ")" after cd fld "hyouji"
          if i>2 then set the textfont of last char of cd fld "hyouji" to "r_s"
          else set the textfont of last char of cd fld "hyouji" to "empty()"
        end repeat
        put 0 into sisuu
        put 0 into ruto
        state
        add0
        exit mouseDown
      end if
      
      if ruto>0 then
        play "click2"
        add0
        repeat with i=1 to ruto
          put ")" after cd fld "hyouji"
          set the textfont of last char of cd fld "hyouji" to "ru-to"
        end repeat
        set the textfont of last char of cd fld "hyouji" to "empty()"
        if last char of cd fld "hyouji" is not a number then add0
        put 0 into ruto
        state
      else
        put last char of cd fld "hyouji" into lc
        if lc is a number or lc=")" then
          put "*" after cd fld "hyouji"
          set the textfont of last char of cd fld "hyouji" to "empty()"
        end if
        put last char of cd fld "hyouji" into lc
        play "click2"
        put 1 into ruto
        state
        put "s" after cd fld "hyouji"
        set the textfont of last char of cd fld "hyouji" to "ru-to"
        put "q" after cd fld "hyouji"
        put "r" after cd fld "hyouji"
        put "t" after cd fld "hyouji"
        put "(" after cd fld "hyouji"
        set the textfont of last char of cd fld "hyouji" to "empty()"
        put 0 into shousuu
      end if
    end mouseDown
    
     5行目から18行目の処理は、ルート内に指数を使った場合の処理です。現在、ルート内に指数を使っている場合に、ルートボタンを押したら(解除したら)、ルートと指数の処理を終わらせるという事です。スクリプト上では変数sisuuの値しかチェックしていませんが、この電卓の機能の制限により、指数の肩の部分にはルートを用いることができませんので結果は同じ事になります。
     必要であれば31〜35行目で「×」を付けます。その後、sqrt(を追加します。


    ボタン「(」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    
    on mouseDown
      global sisuu,ruto
      btnDown
      lock screen
      put last char of cd fld "hyouji" into lc  
      if sisuu>0 then put sisuu+1 into sisuu
      else if ruto>0 then put ruto+1 into ruto  
      if lc is a number then
        put "*" after cd fld "hyouji"
        set the textfont of last char of cd fld "hyouji" to "empty()"
      end if
      play "click2"
      put "(" after last char of cd fld "hyouji"
      font_c
    end mouseDown
    

     6〜7行目で、現在の指数、ルートの状態を調べ、それぞれのかっこの個数を増加させています。そして、それぞれのかっこの個数分だけの終わりかっこを付けています。
     このハンドラでは、8〜11行目で「×」のチェックをしています。



    0の0乗はあり得ない

     HyperCardでは0の0乗を計算したときに、NAN(037)という答えを返します。そのため0の0乗を計算したときの対処法が必要となります。
     0の0乗が入力される場合を考えてみます。わかりやすくするためにHyperCard内での計算式を用いて説明します。
     0の0乗はHyperCard内では「0^(0)」と表現されます。ですので、0が入力されたときに2つ前の文字が「^」であるかどうかの判断をして、もしそうであればボタン「delete」に「mouseDown」メッセージを送って消去すればいいわけです。この処理が必要な場所は、終わりかっこを付けた時、計算結果を求めるボタン「=」の2カ所となります。ボタン「=」は、式が完結していない場合にハンドラ「add0」を呼び出しますので0の0乗になる可能性があります。


     8 
     9 
    10 
    11 
    12 
    
        put the number of chars of cd fld "hyouji" into i
        put cd fld "hyouji" into f
        if char i of f="0" and char (i-2) of f="^" and char (i-3) of f="0" then
          send "mouseDown" to cd btn "delete"
        end if
    
     0の0乗は、HyperCardでは「0^(0)」と表示されます。そこで、指数の肩に0が入力された時に、その2つ前の文字が「^」で、かつ3つ前の文字が「0」であれば消去します。



    指数やルートをグラフィカルに表現することで、実際の計算式と同じ形を実現する

     実はHyperCardには簡単に計算ができる機能が備わっています。その機能はメッセージボックスに式を代入しリターンキーを打つだけという至ってシンプルな物です。そこで、このスタックではこの機能を活用するため、計算式には手を加えないという事を条件として作成しました。
     しかし、計算式に手を加えないためには同じ数字が、ある状態では指数の肩であったり、ルート内の数字であったりする必要があります。そこで、このスタックでは指数フォント、ルートフォント、ルート内の指数フォントという特別な状態で使用する3フォントを用意することでこの問題を解決しました。現在の状態を見て、それにより入力された数字のフォントを切り替えていくのです。
     このフォント切り替え処理をしているのが、ハンドラ「font_c」です。


    ハンドラ「font_c」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    
    on font_c
      global ruto,sisuu
      if ruto>0 and sisuu>0 then
        set the textfont of last char of cd fld "hyouji" to "r_s"
      else if sisuu>0 then
        set the textfont of last char of cd fld "hyouji" to "sisuu"
      else if ruto>0 then
        set the textfont of last char of cd fld "hyouji" to "ru-to"
      else
        set the textfont of last char of cd fld "hyouji" to "f12"
      end if
    end font_c
    

     それぞれの変数の状態を見て、最後に入力された文字のフォントを切り替えます。

     フォントを切り替えるこの方法は、難しいことを考える必要がないという利点がありますがその反面、問題点もいくつかあります。まず、第1にフィールド内のフォント切り替えは時間がかかるためスピード遅いという事、第2に延々と指数を続けたり、ルートを続けたりといった計算はできないということです。
     第2の問題点である延々と続く指数、ルートを防ぐためのハンドラが「state」です。


    ハンドラ「state」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    16 
    
    on state
      global sisuu,ruto
      if sisuu=0 and ruto=0 then
        set the hilite of cd btn "^(" to false
        set the hilite of cd btn "sqrt(" to false
        set the enabled of cd btn "sqrt(" to true
      else if sisuu=1 and ruto=1 then
        set the hilite of cd btn "^(" to true
        set the hilite of cd btn "sqrt(" to true
      else if sisuu=1 then
        set the hilite of cd btn "^(" to true
        set the enabled of cd btn "sqrt(" to false
      else if ruto=1 then set the hilite of cd btn "sqrt(" to true
      else if ruto=0 then set the hilite of cd btn "sqrt(" to false
      else if sisuu=0 then set the hilite of cd btn "^(" to false
    end state
    

     指数の肩にルートが入力できないようにするため10行目でルートのボタンを押せないようにしています。本来HyperCardでは、指数部分にルートを付けることはできます。しかし、この電卓では使用するグラフィックデータを最初から用意しておくという方法を用いて、指数やルートを表現していますので延々と続く指数、ルートの連続には対応できないのです。



    過去の計算式とその答えをログとして残しておき、その答えを利用しての再計算を可能とする

     フィールド「result」には過去の計算式とその答えが入っており、その答えを利用して計算をすることができます。フィールド「result」には答えだけでなく、計算式も入っていますので必要な計算式を簡単に探し出すことができます。


    フィールド「result」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    
    on mouseUp
      lock screen
      put the value of the clickLine into exp
      if exp is empty then exit mouseUp
      repeat with i=(the number of chars in exp) down to 1
        if char i of exp="=" then exit repeat
      end repeat
      put empty into char 1 to i of exp
      send "mouseDown" to cd btn (char 1 of exp)
      put empty into char 1 of exp
      put exp after cd fld "hyouji"
    end mouseUp
    

     クリックされた行がemptyでなければ、その式の答えを取り出します。次にその1文字目の数字ボタンにメッセージ「mouseDown」を送ります。答えの桁数分だけメッセージを送っていると、入力に時間がかかりますので、2文字目以降はフィールドに直接追加しています。



    答えが出た後も続けて計算をさせることができる

     連続計算機能は使い方によっては、大変使い勝手のいいサポート機能となります。短い計算をする方には毎回「AC」ボタンを押さないといけないため逆に使いづらいかもしれませんが、続けて計算をする場合、例えば商品の合計額を計算し、その消費税分を計算して、(過去のログを利用して)合計額を出すといった計算などの場合は大変使いやすくなります。
     この機能はボタン「=」の39〜45行目で処理しています。


    39 
    40 
    41 
    42 
    43 
    44 
    45 
    
      put cd fld "hyouji" into exp
      if exp is empty then exit mouseDown
      repeat with j=(the number of chars in exp) down to 1
        if char j of exp="=" then exit repeat
      end repeat
      if j<>1 then put empty into char 1 to j of exp
      else put 0 into j
    
     計算式を最後の文字からたどり「=」の位置を探し、1文字目からその文字までemptyを代入します。すなわち、前回までの計算式は削除されることになります。



    一つ前の四則演算までもどるDelete、一つ前の計算結果へのUndoを実現する

     ボタン「delete」は、一つ前の四則演算記号までを削除します。本来ならば入力された文字単位で消去するべきなのですが、かっこの数、現在の状態を調べることが困難になるため、このような方法をとりました。四則演算記号まで戻ることで、変数の状態がクリアーされ通常の数字入力の状態になります。
     もう一つのボタン「Undo」では、式単位で一つ前の状態へと戻ります。これは先の「答えが出た後も続けて計算をさせることができる」で説明したスクリプトを用いて処理しています。


    ボタン「Delete」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    16 
    17 
    18 
    19 
    20 
    
    on mouseDown
      global sisuu,ruto,shousuu
      btnDown  
      lock screen
      play "clear"
      put cd fld "hyouji" into exp
      if exp is empty then exit mouseDown
      put 0 into sisuu
      put 0 into ruto
      put 1 into shousuu
      state
      repeat with j=(the number of chars in exp) down to 1
        put char j of exp into jc
        put the textFont of char j of cd fld "hyouji" into jf
        if (jc="+" or jc="-" or jc="*" or jc="/") and (jf="f12") then exit repeat
        else if jc="=" then exit mouseDown
      end repeat
      put empty into char j to the number of chars of cd fld "hyouji" of cd fld "hyouji"
      exit to HyperCard
    end mouseDown
    
     計算式を最後の文字からたどって通常状態の四則演算記号を探し、その文字以降を消去します。


    ボタン「Undo」のスクリプト
     1 
     2 
     3 
    
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    15 
    
    16 
    17 
    18 
    19 
    
    20 
    21 
    22 
    23 
    24 
    25 
    26 
    27 
    28 
    
    29 
    30 
    31 
    32 
    33 
    
    on mouseDown
      global sisuu,ruto
      btnDown
      
      lock screen
      play "clear"  
      put cd fld "hyouji" into exp
      if exp is empty then exit mouseDown
      repeat with i=1 to 2
        repeat with j=(the number of chars in exp) down to 1
          if char j of exp="=" then exit repeat
        end repeat
        put empty into char j to (the number of chars in exp) of cd fld "hyouji"
        put empty into char j to (the number of chars in exp) of exp
      end repeat  
      if cd fld "hyouji" is empty then exit mouseDown
      
      repeat with j=(the number of chars in exp) down to 1
        if char j of exp="=" then exit repeat
      end repeat
      if j<>1 then put empty into char 1 to j of exp
      
      put exp
      returnkey
      put "=" after cd fld "hyouji"
      set the textfont of last char of cd fld "hyouji" to "f12"
      put msg after cd fld "hyouji"
      put "=" after cd fld "result"
      set the textfont of last char of cd fld "result" to "f12"
      put msg&return after cd fld "result"
      put exp&"="&msg&return after cd fld "result"
      
      put 0 into sisuu
      put 0 into ruto
      put 0 into kakko
      set the textfont of last char of cd fld "hyouji" to "f12"
    end mouseDown
    
     4〜15行目で一つ前の「=」の位置までさかのぼります。16〜19行目で必要な部分だけを取り出し、20〜28行目で再計算をします。


     最後に数字ボタンのスクリプトです。



     数字ボタンが押されるとハンドラ「num」が、四則演算ボタンが押されたらハンドラ「sisoku」が呼び出されます。


    ハンドラ「num」のスクリプト
     1 
     2 
     3 
     4 
     5 
     6 
     7 
     8 
     9 
    10 
    11 
    12 
    13 
    14 
    
    on num
      global shousuu,con
      if last char of cd fld "hyouji"=")" then
        put "*" after cd fld "hyouji"
        set the textfont of last char of cd fld "hyouji" to "empty()"
      else if (last char of cd fld "hyouji"="0" and con=0 and shousuu=0) then
        play "error"
        exit num
      end if
      play "click"
      put short name of target after cd fld "hyouji"
      if (last char of cd fld "hyouji"<>"0") then put 1 into con
      font_c
    end num
    
     6行目では、0が続く場合の処理をしています。0が続いても良い場合は、小数点以下の場合、100などの0以上の数値の場合ですので、この6行目でチェックをしています。変数conには0以外の文字が入った時に1が代入されます。つまり00と続く場合は、変数conの値が0であり、変数shousuuの値も0ですのでエラーになります。


     これで電卓の重要なスクリプトの紹介は終わりです。電卓というのは簡単なようですがこのように、あらゆる場面が起こりその場面場面の処理がそれぞれ違うというのが多いですから、処理はどうしても複雑になってしまいます。
     できるかぎり完璧な電卓を作成したつもりですが、まだまだ不十分なところが多いのが残念です。この電卓の特徴的な機能は誇れる物に仕上がっていると思いますが、電卓というのは私たちの周りにいっぱい転がっている物ですから、それだけに最低クリアしなければいけないラインが高くなってしまうのが一つの原因かもしれません。