CPythonに機能追加してみた（ビルド&構造把握）

# 1. はじめに
ここでは、CPythonに機能追加する上で必要となるCPythonのビルドとCPythonのファイル構造について説明します。
本記事ではPython3.10を使用しています。
* この記事はEEIC(東京大学工学部 電気電子工学科/電子情報工学科)3年の後期実験「大規模ソフトウェアを手探る」のレポートとして書きました。
* 以下の記事はチームメンバーが書いたものです。

[CPythonに機能追加してみた（三項演算子）](https://qiita.com/takashi-o/items/45c8d5575605972c4ddf)
[pythonに２種類のswitch文を追加する](https://naomi-notebook.hatenablog.com/entry/2020/10/20/200733)
[Pythonに前置インクリメントを追加](https://kkti4216.hatenablog.com/entry/2020/10/30/025233)

# 2. CPythonとは
CPythonとは、C言語で書かれたPythonのことで、一般的にPythonと呼ぶ時、このPythonのことを指してることが多いです。コードは[GitHub](https://github.com/python/cpython)上で管理されておりPRを出すこともできます。

# 3. CPythonのビルド
CPythonのビルドについては[公式の記事](https://devguide.python.org/setup/)が非常に参考になります。まず、CPython3.10のリポジトリからコードをcloneします。

```bash

$ git clone https://github.com/python/cpython
```

次に、ディレクトリを移動し、configureスクリプトを実行します。ここでは、-gで実行可能ファイルに「デバッグシンボル」を含め、-O0で最適化を最低レベルにしています。また、--prefixをつけることでインストールするフォルダを指定しています。


```bash

$ cd cpython
$ CFLAGS="-O0 -g" ./configure  --with-pydebug   --prefix=（インストールするディレクトリ)
```

続いて、コンパイル&インストールを行います。

```bash
$ make -s -j2
$ make install
```

以上で、CPythonが無事インストールできます。インストールしたPythonを実行するには以下のようにします。

```
$ cd （インストールしたディレクトリ)/bin
$ ./python3
```

# 4. CPythonに機能追加
CPythonに機能追加する時の[チェックリスト](https://devguide.python.org/grammar/)が公式によりまとめられています。以下では、こちらを参考にして説明していきます。

## 4.1 CPythonのファイル構成
CPythonに機能追加を行う際に主に変更を加えるファイルで重要なのはこの4つとなります。順に見ていきます。
![スクリーンショット 2020-10-20 18.40.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481411/cc7ea005-b7ca-5619-5991-a37c3b7527b5.png)

### 4.1.1 python.gram
まず、python.gramについて説明します。
![スクリーンショット 2020-10-25 12.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481411/60c30d20-daed-6d0c-a53d-3f7731475e09.png)
[CPython](https://github.com/python/cpython)のGrammer/python.gramにあるファイルです。python.gramではPythonの文法を規定しています。追加する文法をこのファイルに記述します。


```bash

$ make regen-pegen
```

よりParserを自動生成してくれます。


### 4.1.2 python.asdl
続いて、python.asdlについて説明します。
![スクリーンショット 2020-10-25 12.00.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481411/4cdb5285-e610-355f-cc8c-acb2faefb375.png)
抽象構文木(AST)を作成するためのファイルです。python.gramで新たな関数を定義したなら、このファイルにも関数定義を記述する必要があります。

```bash

$ make regen-ast
```
よりASTが自動生成されます。


### 4.1.3 compile.c
続いて、compile.cについて説明します。
![スクリーンショット 2020-10-25 12.00.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481411/45ec37eb-c0bf-e916-10f3-c1b77e8c14b3.png)
ASTをバイトコードに変換するファイルです。構文ごとの処理をバイトコードで記述します。文法追加の際、その文法の処理をバイトコードでこちらに記述します。

### 4.1.4 ceval.c
続いて、ceval.cについて説明します。
![スクリーンショット 2020-10-25 12.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481411/1843b7dd-ae5c-d92c-fefc-abd0da6cd60e.png)
バイトコードを実行します。既存のバイトコードで実装不可能な場合、こちらに新しいバイトコードを追加します。

# 5. まとめ
以上では、CPythonのビルドと構造把握について説明しました。CPythonはコード量こそ膨大ですが、公式のチェックリストで文法変更の手順がまとまっていたので、注目する必要のあるコード量については少なく感じました。

# 参考資料
- [大規模ソフトウェアを手探る](https://doss.eidos.ic.i.u-tokyo.ac.jp/)<br>実験のサイトです

- [CPython](https://github.com/python/cpython)<br>CPythonのリポジトリです

- [24. Changing CPython’s Grammar](https://devguide.python.org/grammar/)<br>CPythonに機能追加を行う時のチェックリストが載っていてCPythonの構造理解に役立ちました

- [1. Getting Started](https://devguide.python.org/setup/)<br>CPythonのビルドに関して参考になりました