CPythonに機能追加してみた(三項演算子)


はじめに

ここでは、CPythonに三項演算子を追加する手順ついて説明します。
本記事ではPython3.10を使用しています。CPythonのビルド、ファイル構造の説明はこちらでしているので併せてご参照ください。
* この記事はEEIC(東京大学工学部 電気電子工学科/電子情報工学科)3年の後期実験「大規模ソフトウェアを手探る」のレポートとして書きました。
* 以下の記事はチームメンバーが書いたものです。
CPythonに機能追加してみた(ビルド&構造把握)
pythonに2種類のswitch文を追加する
Pythonに前置インクリメントを追加

2. 三項演算子の追加

2.1 Pythonの三項演算子

Pythonの三項演算子は以下です。Pythonでは(条件がTrueのときの値)が先に来て、(条件)がその次、最後に(条件がFalseのときの値)が来ます。三項演算子の文法で(条件)が真ん中に来るのは一般的ではありません。

(条件がTrueのときの値) if (条件) else (条件がFalseのときの値)

2.2 変更後の三項演算子

変更後の三項演算子は以下です。(条件)が先に来て、その後に、(条件がTrueのときの値)、最後に、(条件がFalseの値)が来るようにしました。C言語などはこの順番で三項演算子を記述します。


if (条件) then (条件がTrueのときの値) else (条件がFalseのときの値)

2.3 コード変更

それでは、Pythonの三項演算子を2.2で示したものに変更していきます。Pythonには既に三項演算子が存在します。なので、これを流用して、if then elseが来た時に同じ処理を呼ぶようにすれば良いです。ここで、変更するのはpython.gramだけです。Grammer/python.gramのL341に以下の記述があります。

Grammer/python.gram
a = disjunction 'if' b=disjunction 'else' c=expression { _Py_IfExp(b, a, c, EXTRA) }

これは、元のPythonの三項演算子の記述です。これを真似して、下の行に変更後の三項演算子を記述します。

Grammer/python.gram
'if' a = disjunction 'then' b=disjunction 'else' c=expression { _Py_IfExp(a, b, c, EXTRA) }

ここで、_Py_IfExpを呼ぶときの変数の順番に注意します。以上の変更で

$ make regen-pegen

を実行し、再ビルドを行えば、三項演算子の追加ができます。もちろん、元の三項演算子の文法を使うこともできます。

3. デモ

以上の変更で実装された三項演算子は以下のように動作します。

参考資料