【Rust】計算機:過去の計算を再利用!履歴参照($n)の実装とファイルの永続化 #8

前回まで、抽象構文木(AST)だのイプシロンだの、かなり「計算機の深淵」に近い話が続きました。正直、筆者も読者の皆さんも少し知恵熱が出ている頃かと思います。

そこで今回は、ちょっと実装の難易度を下げて、ターミナル電卓をグッと「道具」として使いやすくする履歴参照($)機能を実装していこうと思います。

演算と比較を評価するEvaluatorの実装: 【Rust】計算機自作:演算と比較を評価するEvaluatorの実装(式指向の設計) #7

計算機のコア部分、評価機を実装していきます

今回は評価(計算部分)のうち過去履歴評価の実装です。

1. 過去の結果を使い回す「$n」の設計

計算をしていると、「さっきの答えにこれを足したい」という場面が多々あります。 そこで、$1(1番目の結果)のように過去の結果を直接変数として使えるようにしました。
操作方法は、 $1を直書きするか、Tabで結果リストに移動してEnterで挿入する。といった使い方を想定して実装しています。

現在の実装では、結果をvector構造体にして保持しており、これを参照させられるようにしつつ、計算結果が記録に残せるように .calc_historyファイルに書き出していくように実装していこうと思います。

# .calc_history のイメージ
1|1+1|2.0
2|pi*2|6.283185
3|invalid_func|NaN

使い勝手が悪かったら変えるかもしれませんが、とりあえずこの インデックス | 計算式 | 計算結果という形式で保持していこうと思います。

記録書き出し用スクリプトを作る

Rustは「お節介なほど安全」な言語ですが、ファイル操作が混ざるとコードが複雑になりがちです。今回は機能を history.rs としてモジュール化し、メインロジックを汚さないように設計しました。

履歴管理のhistory.rsの開発中の画面

history.rs

詳細は略しますが、機能としては、計算結果を受け取りそれを記録用のフォーマット {} | {} | {} | {}に変換。記録を行い、記録が成功したかどうかをフィードバックする機能があります。

最終的にはルートディレクトリ(~/)に .calc_historyというファイルを作る予定ですが、とりあえず現在のフォルダに生成するように実装しています。

calc historyのフォルダ構成

実行結果

適当に計算し、一度プログラムを落とし、再度立ち上げて記録を読みだせるかテストしてみました。

計算記録の履歴を保存している。

計算結果の記録

一度、終了して再度立ち上げてみた。

計算記録の履歴をファイルから読み出せたことの確認

前回の計算結果の履歴を参照できる

過去の記録を参照して計算できるかテストしました。

過去の履歴を $n形式で参照し、計算できるかテストした

$1 + 2 のように、1番目の結果+2という計算ができていることが確認できます。

次回は関数のパース

「履歴」という外部データが扱えるようになり、電卓としての実用性が一気に高まりました。

さて、脳の休憩はここまでです。 次回は、いよいよ今回積み残した「関数の評価(Evaluation)」に戻ります。ついに、関数のParse後放置していたフィボナッチ関数が動く(はず)です!

次回 関数の評価 : 関連記事は、2026年5月8日に公開予定 (あと1日)

ここまで読んでいただきありがとうございます。

では、次の記事で。 lumenHero

関連記事

第1回 構想編【Rustで作る】ターミナル関数電卓を設計する(アーキテクチャ編) #1
第2回 Lexer実装:【Rust】自作計算機エンジンへの道:Lexer(字句解析)で数式をトークンに分解する #2
第3回 tomlの読み込み:【Rust】TOMLで関数を自由に追加!自作電卓に設定読み込みとホットリロードを実装する #3
第4回 Parserの実装(基礎):【Rust】数式を「計算の木」へ:ASTと再帰下降構文解析で電卓エンジンの心臓部を作る #4
第5回 Parserの実装(関数):【Rust】関数の「事前パース」で電卓を高速化!AST管理とデバッグ出力の実装 #5
第6回 比較演算子の実装 :【Rust】電卓に「論理」を。比較演算子の実装と優先順位の階層設計 #6
第7回 Evaluatorの実装 :【Rust】計算機自作:演算と比較を評価するEvaluatorの実装(式指向の設計) #7