C++ コア
コアは C++17 で書かれ、依存を小さく保ち、組み込み先で予期しない挙動を起こさない方針をとっています。同じ C++ ソースから、ネイティブライブラリ・WebAssembly モジュール・CLI バイナリをビルドできます。
用語: 予測可能な組み込み
ホストアプリにリンクしても、ホスト側のビルド設定で Formulon の挙動が変わらないようにする方針です。例外と RTTI を使わず、グローバルアロケータや未定義動作につながる近道を避けます。
用語: Expected<T, Error>
成功値かエラーコードのどちらかを返す型です。例外を送出せずに失敗を表現します。std::expected / absl::StatusOr / Rust の Result<T, E> と同じ発想です。呼び出し側は結果で分岐し、C ABI 境界を例外によるスタック巻き戻しが越えることはありません。
重要な選択
- RAII: 全リソースを所有するオブジェクトのデストラクタで解放します。
Expected<T, Error>型のエラー処理: 失敗しうる操作は値で返し、例外を送出しません。-fno-exceptionsと-fno-rtti: コード生成を予測しやすくし、バイナリを小さく保ち、隠れた制御フローをなくします。- スプレッドシート固有ロジックはリポジトリ内で実装: 数式パーサ・日付演算・OOXML の癖など、汎用ライブラリではサイズや意味論のリスクが大きい部分を自前で実装します。
miniz: ZIP コンテナを読み書きします。pugixml: XML / XPath 1.0 を扱います。pcre2:REGEX*関数で使います。double-conversion: OOXML のセルを書き出すとき、往復で値が変わらない最短の数値テキストを作ります。
この 4 つは既定では構成時に取得します。-DFM_USE_SYSTEM_DEPS=ON を指定すると、インストール済みのパッケージを使います。
コアが依存しないもの
コアは、ブラウザ・Python・CLI 固有の仕組みから独立させます。
- 公開 ABI に Emscripten 固有型を出しません。
std::filesystemでホスト側に渡せないパス表現を強制しません。- コアの挙動を環境変数や、ホストからリセットできない可変状態に依存させません。
- 変更可能なワークブック状態はワークブック内で管理します。スレッド単位の診断情報と乱数状態は実装上必要な情報としてコア内に閉じ込めます。
- 再計算の割り当てをバインディングに移しません。バインディングは並列再計算 API を公開し、処理の割り当てはコアが担当します。
制約の理由
| 制約 | 理由 |
|---|---|
| 例外なし | C ABI を例外によるスタック巻き戻しで越えられません。例外があるとバインディングごとに catch 処理が必要になります |
| RTTI なし | バイナリを小さく保てます。エンジンは型を動的に検査する必要がありません |
| 小さな依存セット | WASM サイズ上限、ビルド再現性、間接依存のライセンス確認を減らせます |
| リポジトリ内のスプレッドシートロジック | Excel の意味論は汎用数学ライブラリでは表現しきれません。手元に置く方が Oracle との整合性を管理しやすくなります |