逆ポーランド記法を使った電卓プログラムだ。
操作はキーボードから。数字や演算子を打ち込んで、スペースキーでスタックにプッシュする(積む)ことになる。
入力中の値のクリアは「C」、スタックも含めた全クリアは「A」。「Q」でプログラムの終了になる。
入力できる値の範囲は-99999~99999。扱える値は-524287.999~524287.999となっている。
Odakaz
ライフゲームに続いて、再びコンピューターのイロハにかかわるプログラムを投稿してくれたOdakaz君の本職はプログラマー。仕事柄か、今回も「おそらく必要ないだろうなと思いつつ、サブルーチンが防御的なコードになっていたり」とのこと。さすがだね。
- ’┌──────────────────────────┐
- ’│RPNテ゛ンタク 2011/03/29 ODAKAz│
- ’└──────────────────────────┘
- ’┌────┐
- ’│ショキカ│
- ’└────┘
- VISIBLE 1,1,1,1,1,1
- CLEAR
- ’ бアツカエル アタイノ サイタ゛イチ
- MAX_NUM=524287.999
- ’ бスタック
- S=100:T=0:DIM ST(S)
- ’ бニュウリョク
- B$=””
- ’ бモート゛
- M_WAIT =0 ’ニュウリョクマチ
- M_NUMBER=1 ’スウシ゛ヲ イレテイル
- M_CAN_OP=2 ’エンサ゛ンシヲ イレテモ イイ
- M_OPONLY=3 ’エンサ゛ンシタ゛ケ イレテイイ
- M_OP =4 ’エンサ゛ンシヲ イレタ
- M=M_WAIT
- ’ бモート゛コ゛トノ ニュウリョク カノウ モシ゛
- DIM A_KEY$(5)
- A_KEY$(M_WAIT) =”0123456789-”
- A_KEY$(M_NUMBER)=”0123456789 ”
- A_KEY$(M_CAN_OP)=”0123456789+-*/”
- A_KEY$(M_OPONLY)=”+-*/”
- A_KEY$(M_OP) =”0123456789- ”
- ’┌────────┐
- ’│カ゛メンショキカ│
- ’└────────┘
- CLS
- LOCATE 0,0:PRINT ”┌RPN CALC──────┐”
- LOCATE 0,1:PRINT ”│>> │”
- LOCATE 0,2:PRINT ”└──────────────┘
- LOCATE 1,3:PRINT ”┌─────┐”
- LOCATE 1,4:PRINT ”│Stack│”
- LOCATE 1,5:PRINT ”└┬────┴─────┐”
- LOCATE 0,6
- FOR I=1 TO 16
- PRINT ” │ │”
- NEXT
- PRINT ” └──────────┘”
- LOCATE 16,0:PRINT ”┌KEY───────────┐”
- LOCATE 16,1:PRINT ”│C:ニュウリョク クリア │”
- LOCATE 16,2:PRINT ”│A:オール クリア │”
- LOCATE 16,3:PRINT ”│SPACE:スタックヘ │”
- LOCATE 16,4:PRINT ”│Q:シュウリョウ │”
- LOCATE 16,5:PRINT ”└──────────────┘”
- LOCATE 16,7:PRINT ”┌MESSAGE───────┐”
- LOCATE 16,8:PRINT ”│ │”
- LOCATE 16,9:PRINT ”└──────────────┘”
- ’┌───┐
- ’│メイン│
- ’└───┘
- @MAIN
- GOSUB @DISPLAY
- GOSUB @IN
- MSG$=””
- ON M GOSUB @WAIT,@NUMBER,@CAN_OP,@OPONLY,@OP
- GOTO @MAIN
- ’┌─────────┐
- ’│カ゛メンヒョウシ゛│
- ’└─────────┘
- @DISPLAY
- LOCATE 3,1:PRINT B$;” ”
- FOR Y=6 TO 21
- LOCATE 3,Y:PRINT ” ”
- NEXT
- IF T==0 THEN RETURN
- DY=T
- IF DY>16 THEN DY=16
- FOR I=1 TO DY
- LOCATE 3,21-DY+I
- D$=” ”+STR$(ST(T-I))
- PRINT MID$(D$,LEN(D$)-10,10)
- NEXT
- LOCATE 17,8:PRINT MID$(MSG$+” ”,0,14)
- RETURN
- ’┌────────┐
- ’│キーニュウリョク│
- ’└────────┘
- @IN
- ’бニュウリョクモシ゛ノ シュルイ
- IS_OP=FALSE:IS_MINUS=FALSE:IS_NUM=FALSE:IS_SP=FALSE
- K$=INKEY$()
- ’スヘ゛テノ モート゛テ゛ キョウツウ
- IF K$==”C” THEN GOSUB @COM_C:RETURN
- IF K$==”A” THEN GOSUB @COM_A:RETURN
- IF K$==”Q” THEN @PRGEND
- ’ルーフ゜ナイテ゛RETURNスルト オカシクナルノテ゛ ルーフ゜カ゛ オワッテカラ ハンテイ
- E=FALSE
- FOR I=0 TO LEN(A_KEY$(M))-1
- IF K$==MID$(A_KEY$(M),I,1) THEN E=TRUE
- NEXT
- IF E THEN GOSUB @IN_TYPE:RETURN
- GOTO @IN
- RETURN
- ’ニュウリョク クリア
- @COM_C
- K$=””
- GOSUB @CLR_BUFF
- GOSUB @NEXTBYST
- RETURN
- ’オールクリア
- @COM_A
- T=0
- GOSUB @COM_C
- RETURN
- ’┌─────────────────────────┐
- ’│ニュウリョクサレタ モシ゛ノ シュルイヲ ハンテイ│
- ’└─────────────────────────┘
- @IN_TYPE
- IF K$==”” THEN RETURN
- ’エンサ゛ンシ?
- IS_OP=K$==”+” OR K$==”-” OR K$==”*” OR K$==”/”
- IF IS_OP THEN O$=K$
- ’マイナス?
- IS_MINUS=K$==”-”
- ’スウシ゛?
- KASC=ASC(K$)
- IS_NUM=KASC>=ASC(”0”) AND KASC<=ASC(”9”)
- ’スヘ゜ース?
- IS_SP=K$==” ”
- RETURN
- ’┌─────────────┐
- ’│ニュウリョクマチ モート゛│
- ’└─────────────┘
- @WAIT
- GOSUB @ADD_BUFF
- IF IS_MINUS THEN M=M_OP:RETURN
- IF IS_NUM THEN M=M_NUMBER
- RETURN
- ’┌────────────────┐
- ’│スウシ゛ ニュウリョク モート゛│
- ’└────────────────┘
- @NUMBER
- ’スウシ゛
- IF IS_NUM THEN GOSUB @ADD_NUM:RETURN
- ’スヘ゜ース
- IF IS_SP THEN GOSUB @PUSH_NUM
- RETURN
- ’5ケタ マテ゛ナラ ニュウリョク カノウ
- @ADD_NUM
- L=LEN(B$)
- IF MID$(B$,0,1)==”-” THEN L=L-1
- IF L<5 THEN GOSUB @ADD_BUFF
- RETURN
- ’スウチヲ スタックニ PUSH
- @PUSH_NUM
- V=VAL(B$)
- GOSUB @PUSH
- GOSUB @CLR_BUFF
- GOSUB @NEXTBYST
- RETURN
- ’┌──────────────┐
- ’│エンサ゛ン カノウ モート゛│
- ’└──────────────┘
- @CAN_OP
- GOSUB @ADD_BUFF
- IF IS_NUM THEN M=M_NUMBER:RETURN
- IF IS_OP THEN M=M_OP
- RETURN
- ’┌─────────────┐
- ’│エンサ゛ン ノミ モート゛│
- ’└─────────────┘
- @OPONLY
- IF IS_OP THEN GOSUB @ADD_BUFF:M=M_OP
- RETURN
- ’┌───────────┐
- ’│エンサ゛ンシ モート゛│
- ’└───────────┘
- @OP
- IF IS_SP AND T>=2 THEN GOSUB @CALC:RETURN
- IF IS_NUM AND O$==”-” AND T<S THEN GOSUB @OPTONUM
- RETURN
- ’ケイサン
- @CALC
- GOSUB @CLR_BUFF
- ’0シ゛ョサン タイサク
- IF O$==”/” AND ST(T-1)==0 THEN GOSUB @ZERO_DIV:RETURN
- ’オーハ゛ーフロー スルナラ ケイサンヲ チュウタ゛ン
- GOSUB @CHKOVER
- IF IS_OVER THEN GOSUB @R_OVER:RETURN
- GOSUB @POP
- IF O$==”+” THEN V=L_VAL+R_VAL
- IF O$==”-” THEN V=L_VAL-R_VAL
- IF O$==”*” THEN V=L_VAL*R_VAL
- IF O$==”/” THEN V=L_VAL/R_VAL
- GOSUB @PUSH
- GOSUB @NEXTBYST
- RETURN
- ’オーハ゛ーフロー チェック
- @CHKOVER
- IS_OVER=FALSE
- R_TMP=ST(T-1):L_TMP=ST(T-2)
- IF O$==”+” AND SGN(L_TMP)==SGN(R_TMP) THEN @CHK1
- IF O$==”-” AND SGN(L_TMP)!=SGN(R_TMP) THEN @CHK1
- IF O$==”*” AND R_TMP!=0 THEN @CHK2
- RETURN
- ’タシサ゛ン or ヒキサ゛ン
- @CHK1
- IS_OVER=MAX_NUM-ABS(R_TMP)<ABS(L_TMP)
- RETURN
- ’カケサ゛ン
- @CHK2
- IS_OVER=MAX_NUM/ABS(R_TMP)<ABS(L_TMP)
- RETURN
- ’オーハ゛ーフローヲ ツウチ
- @R_OVER
- MSG$=”OVERFLOW!!”
- O$=””
- GOSUB @NEXTBYST
- RETURN
- ’スウシ゛ ニュウリョク モート゛ヘ
- @OPTONUM
- GOSUB @ADD_BUFF
- M=M_NUMBER
- RETURN
- ’0シ゛ョサンハ ムシスル
- @ZERO_DIV
- O$=””
- GOSUB @NEXTBYST
- RETURN
- ’スタックノ シ゛ョウタイニヨッテ ツキ゛ノ モート゛ヲ キメル
- @NEXTBYST
- IF T>=S THEN M=M_OPONLY:RETURN
- IF T>=2 THEN M=M_CAN_OP:RETURN
- M=M_WAIT
- RETURN
- ’┌────────────────┐
- ’│ニュウリョク ハ゛ッファ ソウサ│
- ’└────────────────┘
- @ADD_BUFF
- B$=B$+K$
- RETURN
- @CLR_BUFF
- B$=””
- RETURN
- ’┌────────┐
- ’│スタック ソウサ│
- ’└────────┘
- @PUSH
- IF T>=S THEN RETURN
- ST(T)=V:T=T+1
- RETURN
- @POP
- IF T<2 THEN RETURN
- R_VAL=ST(T-1)
- L_VAL=ST(T-2)
- T=T-2
- RETURN
- ’┌──────────────┐
- ’│フ゜ロク゛ラム シュウリョウ│
- ’└──────────────┘
- @PRGEND
- CLS:CLEAR
- END