0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RPN.K2 - RPNを拡張しGUI連携・行列・複素数・オブジェクト対応させる

Last updated at Posted at 2025-06-29

はじめに

店先で洗剤のグラム単価を比べたり、消費税や源泉徴収金額計算など、ちょっとした計算アプリを作ることにしました。
このためにGUIとの入出力機能を追加したRPNインタプリタを開発しました。
SigBoxView(RPN.K2)(サイトの起動まで時間がかかるかも)
RPN.K2 解説

RPNの基本と使いにくい点

RPNでは、数値が入力されるとスタックに積み上げ、演算子が入力されると積み上げられたスタックの上の数値を取り出し、演算を適用し、その結果をスタックに積み上げます。例えば、「2,3,+」が入力されると、2+3の演算結果である「5」がスタックに残ります。

2 3 +
結果: 5

RPN電卓では、スタックの数値を入れ替えたり(SWAP)、複製(DUP)。削除(DROP)する、スタック操作コマンドが用意されています。これらを利用することで、やや込み入った計算も可能になります。

1 2 3 SWAP DUMP
//DUMP: 1,3,2
1 2 3 DUP DUMP
//DUMP: 1,2,3,3
1 2 3 DROP DUMP
//DUMP: 1,2

改善したいところ

  • パラメータや計算結果に名前をつけて格納/参照したい。
  • 手計算が大変な、行列演算や複素数演算を手軽に扱いたい。
  • 配列や複素数の傾向を把握するために簡単に可視化したい。

RPNの独自拡張RPN.K2の概要

そこで、RPNの計算機能や制御機能の独自に拡張したRPN.K2のインタプリタを作っています。

拡張1 行列の導入

(配列、行ベクトル、列ベクトル、2次元行列への対応)

  • インデックスは0から始める。2次元行列の1次元配列への格納はカラムメジャーオーダーとする。
  • ベクトルと行列に対応し、テンソルには対応しない。
例)[ 1 2 ; 3 4 ] [ 1 4 ] RESHAPE
結果:[ 1 2 3 4 ]
  • 同型のベクトル及び行列の要素間のスカラー処理(ドット演算)に対応。
例) 二項演算 [ 1 2 3 ] [ 2 1 0 ] .*
結果: [ 2 2 0 ]
例) 単項演算 [ 0 0.5 1 1.5 ] #PI * .sin 
結果: [ 0 1 0 -1 ]

拡張2 複素数の導入

行列演算、四則演算、極座標変換、対数、FFTなど実装

[ 1 2 ] 1+1i *        // 行ベクトル (1,2)に 1+iを掛ける
1.00+1.00i 2.00+2.00i
1+1i arg #PI /       // 1+iの偏角を求めπで割る
0.250

拡張3 文字列への対応

  • 数字や予約語以外は文字列として扱う。
  • 空白は区切り文字として扱われるため、空白を含む文字列は、バックスラッシュでエスケープするか、ダブルクオート若しくはシングルクォートで囲む。
  • 文字列は「+」演算子で連結できる。
例) "前半" " 後半" +
結果:"前半 後半"

拡張4 ユーザー定義処理(サブルーチン)呼び出し

  • CALLにて、スタックトップに積まれた文字列を実行する。
2 “2 *” CALL
結果: 4

拡張5 GUI変数の導入

パラメータの入力や、計算結果の表示や一時保存のため、GUI部品とのインターフェースを行うGUI変数を導入した。

1 2 + SET.%X   //計算結果をテキストボックス(X)に書き込む
2 3 + \%X SET  //同上
%X 2 *        // テキストボックス(X)の文字を数値に変換しスタックに積み2倍する

拡張6 グローバル変数

RPNでは、スタックに積まれた数値は、スタックTOPから何番目か指定することで数値を取り出したり、数値を挿入することができる。しかし、スタックの深さは、計算処理の途中で動的に深さが変化するため、スタックのどこにどのような数字が格納されているか管理することが大変困難になる。

そこで、計算のパラメータを名前の付けられた変数に格納することができれば、変数名でパラメータを取り出したり、格納できるため管理が簡単になる。
そこで、「$」で始まる文字列をグローバル変数に対応させる。

  • スタックトップの数値の変数への書き込み
    SET.$変数名
  • 変数を読み出してスタックに積む
     $変数名
  • 変数を読み出して、文字列をコマンドとして実行する
     $変数名.call
  • 変数の削除
    $変数名.delete
“2 *" SET.$W   //2倍するプログラムを$Wにセット
3 $W.call    // 3を積んて$Wを呼び出す
結果:6

拡張7 ローカル変数

変数名の干渉を避けるためローカル変数を導入。ローカル変数は、サブルーチン内及び、呼び出したサブルーチンの中で使用できる。プレフィックスは$$。

10 SET.$$a            // $$aに10をセット 
[ 1 2 3 ] "$$a *" MAP // 配列1,2,3の各要素に$$aを掛ける
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?