【Rustで作る】ターミナル関数電卓を設計する(アーキテクチャ編) #1

はじめに

以前の記事では、「ターミナルで計算する方法【Linux】 シェルで数値計算する方法」についてまとめました。標準的なツールも便利ですが、使っているうちに「もっと自分好みの関数を定義したい」「物理定数を definitions.toml で一括管理したい」「計算履歴を $1 のように変数として使い回したい」という欲求が強くなってきました。

そこで、Rustの勉強も兼ねて、理想の「ターミナル関数電卓」をゼロから自作することにしました。今回はその第1回として、全体の設計(アーキテクチャ)と、目指すべきゴールについて共有します。

RustでTUIツールを作る方法についてはこちら:Ubuntu上で Rust × ratatui の開発環境構築方法・TUI上にHelloWorld表示まで

目指すのは「ただの電卓」じゃない

既存の電卓ツールは星の数ほどありますが、今回自作するツールでは以下の要件を重視しています。

  • カスタマイズ性: toml ファイルに自分専用の計算式を書けば、即座に呼び出せる。
  • 履歴参照: 直前の計算結果を $1, $2 で変数として利用。
  • Rustによる堅牢な実装: 複雑な再帰計算も、所有権と型システムで安全に処理。

TUIプロトタイプの公開

まずは、UI部分(Ratatuiを使用)を先行して組み上げたプロトタイプがこちらです。

rustで自作電卓のTUIを仮組したサンプル

現在はUIが動いている状態ですが、肝心の「中身(計算エンジン)」はこれから実装していきます。このエンジンの設計が、今回のプロジェクトの最も面白い部分です。

入力欄と結果、および、過去の計算結果などを参照したり、挿入したりしたいので履歴欄を少し広めに作っています。

計算エンジンのアーキテクチャ

文字列として入力された数式を正しく計算するためには、プログラミング言語のコンパイラやインタプリタと同じような「処理のパイプライン」を通す必要があります。

本プロジェクトでは、以下の4つのフェーズに分けて実装を進める予定です。(あくまで予定なので変わる可能性もあります)

1. Lexer (字句解析)

入力された文字列(例:123 + conv(5))を、意味のある最小単位「トークン」に分解します。

  • 123Number
  • +Plus
  • convIdentifier

2. Parser (構文解析)

トークンの羅列を、計算の優先順位(掛け算を先にやる、など)を考慮した「木構造(AST)」に変換します。ここで「再帰構文解析」という手法を用います。

3. Validation (検証)

計算を実行する前に、その式が本当に正しいかチェックします。

  • 存在しない関数を呼んでいないか?
  • 履歴参照($5)は現在の履歴の範囲内か?
  • 関数が自分自身を無限に呼び出していないか(再帰チェック)?

4. Evaluator (評価)

最後に、出来上がった木構造を末端から順番に計算していきます。関数の展開や定数の置き換えもこのフェーズで行います。

今後の実装プラン

この電卓開発は、以下のステップで記事化していく予定です。

  1. Lexer/Parser実装編: enumBox を駆使して数式の「木」を作る。
  2. Evaluation編: 再帰処理による計算の実行と、toml からの関数読み込み。
  3. UI統合編: Ratatui と計算エンジンをドッキングさせる。

おわりに

Rustで言語処理系に近いものを作るのは少しハードルが高そうに見えますが、一歩ずつ分解していくと、非常にロジカルで面白い分野です。

次回は、最初の難所である「字句解析と構文解析」に着手します。Rust特有のメモリ管理が、木構造を扱う際にどう関わってくるのか。お楽しみに!

次回 Lexerの実装: 関連記事は、2026年4月27日に公開予定 (あと7時間)