# 第11章: TinyPython — マイコンで動くPythonを作る マイコンの上で動く小さな Python 処理系を作ります。 ## サンプルコード - ディレクトリ: `docs/os-on-arduino/code/11_tiny_python` - ビルドと書き込み: ```bash uv run pio run -d 11_tiny_python -t upload uv run pio device monitor -b 115200 ``` コードを見る: [docs/os-on-arduino/code/11_tiny_python](https://github.com/iory/learning-os-from-arduino/tree/main/docs/os-on-arduino/code/11_tiny_python) ## ソースコード この章のスケッチです。ファイル名をクリックすると開きます。コードは原稿リポジトリから自動で同期されているので、ここに出ているものが常に最新です。 :::{dropdown} `src/main.cpp` — 262 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/main.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/main.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `include/tp_config.h` — 43 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/include/tp_config.h) ```{literalinclude} ../../../../code/11_tiny_python/include/tp_config.h :language: cpp :linenos: ``` ::: :::{dropdown} `include/tp_env.h` — 60 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/include/tp_env.h) ```{literalinclude} ../../../../code/11_tiny_python/include/tp_env.h :language: cpp :linenos: ``` ::: :::{dropdown} `include/tp_eval.h` — 58 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/include/tp_eval.h) ```{literalinclude} ../../../../code/11_tiny_python/include/tp_eval.h :language: cpp :linenos: ``` ::: :::{dropdown} `include/tp_module.h` — 69 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/include/tp_module.h) ```{literalinclude} ../../../../code/11_tiny_python/include/tp_module.h :language: cpp :linenos: ``` ::: :::{dropdown} `include/tp_value.h` — 72 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/include/tp_value.h) ```{literalinclude} ../../../../code/11_tiny_python/include/tp_value.h :language: cpp :linenos: ``` ::: :::{dropdown} `src/tp_env.cpp` — 161 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/tp_env.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/tp_env.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/tp_eval.cpp` — 774 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/tp_eval.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/tp_eval.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/tp_mod_gpio.cpp` — 77 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/tp_mod_gpio.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/tp_mod_gpio.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/tp_mod_led.cpp` — 59 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/tp_mod_led.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/tp_mod_led.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/tp_mod_matrix.cpp` — 88 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/tp_mod_matrix.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/tp_mod_matrix.cpp :language: cpp :linenos: ``` ::: :::{dropdown} `src/tp_module.cpp` — 72 行 :icon: code [GitHub で開く](https://github.com/iory/learning-os-from-arduino/blob/main/docs/os-on-arduino/code/11_tiny_python/src/tp_module.cpp) ```{literalinclude} ../../../../code/11_tiny_python/src/tp_module.cpp :language: cpp :linenos: ``` ::: ## 実機での出力 Arduino UNO R4 WiFi の実機で実際に取得した出力です(macOS / Windows の 両方で同じ結果を確認しています)。手元の出力と見比べてください。 REPL に `print(1 + 2)` と再帰関数を打ち込んだところです。`TP_MAX_SCOPES`(8)を超える深さの再帰は `RecursionError` になります。 ```{figure} ../_static/ch11_repl.gif :name: fig-ch11-repl :width: 100% ボード上の REPL に関数を定義して呼ぶところ。`fact(7)` は 5040 を返し、 `fact(30)` は `RecursionError` で止まります ``` ```text print(1 + 2) 3 >>> def fact(n): ... if n < 2: ... return 1 ... return n * fact(n - 1) ... >>> print(fact(7)) 5040 >>> print(fact(30)) RecursionError: maximum recursion depth exceeded 0 >>> print(42) 42 >>> ``` 実機ではこう光ります。 ```{figure} ../_static/ch11_led_matrix.gif :name: fig-ch11-board :width: 70% `led.on()` / `led.off()` で L LED が点いて消え、`matrix.fill(1)` でマトリクスの 96 個が全部点き、`matrix.clear()` で消えます。(UNO R4 WiFi を Web カメラで撮影) ``` ### シミュレータで見る 実機が無くても、同じファームウェアを {doc}`シミュレータ <../getting-started/simulator>` で動かすとこう見えます。 ```{figure} ../_static/sim_ch11_repl.gif :name: fig-ch11-sim :width: 80% TinyPython の REPL で `led.on()` を打つと L が点き、`matrix.fill(1)` でマトリクスが全点灯、`led.off()` で L が消えます。(シミュレータで撮影) ``` ## つまずきやすいポイント (読者からの質問に応じて随時追記します。質問は [GitHub Issues](https://github.com/iory/build-your-own-arduino-rtos/issues) へどうぞ)