2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

以下の本を読んでいた時のこと…。

もし 価格>100: 表示(価格)

???まじ???そういう感じ???知ってるPythonの話でいいんだよね???
といった記述が出てきました。

というわけで実際にやってみます。

概要

標準のPythonインタプリタはC言語で書かれており、これを改造してソースコードからビルドすることで実現可能。

今回はWindowsを使用し、VisualStudioのビルドツールを使用して検証しています。

Pythonのソースコードをダウンロード

Pythonの公式サイトからダウンロードする。

今回は本に倣って「Python-3.11.3.tgz」をダウンロードしました。
以下のコマンドで解凍:

$ tar -xf Python-3.11.3.tgz

ソースコードの改造

Python-3.11.3\Parser\tokenizer.cを改造する:
tok_get関数のreturn NAME;の上に以下を追加する。

        if (memcap(tok->start, "もし", 6) == 0){
            return MOSHI;
        }
        if (memcap(tok->start, "ならば", 9) == 0){
            return NARABA;
        }
        if (memcap(tok->start, "ではなくて", 15) == 0){
            return DEHANAKUTE;
        }
        if (memcap(tok->start, "でなければ", 15) == 0){
            return DENAKEREBA;
        }
        return NAME; // ここは元からある行

Python-3.11.3\Grammar\Tokensの先頭に以下を追加する:

MOSHI
NARABA
DEHANAKUTE
DENAKEREBA

ENDMARKER // 元からある行
…

python.gramを編集(2か所)
1か所目:
(変更前)

if_stmt[stmt_ty]:
    | invalid_if_stmt
    | 'if' a=named_expression ':' b=block c=elif_stmt {
        _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
    | 'if' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
elif_stmt[stmt_ty]:
    | invalid_elif_stmt
    | 'elif' a=named_expression ':' b=block c=elif_stmt {
        _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
    | 'elif' a=named_expression ':' b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
else_block[asdl_stmt_seq*]:
    | invalid_else_stmt
    | 'else' &&':' b=block { b }

(変更後)

if_stmt[stmt_ty]:
    | invalid_if_stmt
    | ('if' | MOSHI) a=named_expression (':' | NARABA) b=block c=elif_stmt {
        _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
    | ('if' | MOSHI) a=named_expression (':' | NARABA) b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
elif_stmt[stmt_ty]:
    | invalid_elif_stmt
    | ('elif' | DEHANAKUTE) a=named_expression (':' | NARABA) b=block c=elif_stmt {
        _PyAST_If(a, b, CHECK(asdl_stmt_seq*, _PyPegen_singleton_seq(p, c)), EXTRA) }
    | ('elif' | DEHANAKUTE) a=named_expression (':' | NARABA) b=block c=[else_block] { _PyAST_If(a, b, c, EXTRA) }
else_block[asdl_stmt_seq*]:
    | invalid_else_stmt
    | (('else' &&':') | DENAKEREBA) b=block { b }

2か所目:
(変更前)

compound_stmt[stmt_ty]:
    | &('def' | '@' | ASYNC) function_def
    | &'if' if_stmt

(変更後)

compound_stmt[stmt_ty]:
    | &('def' | '@' | ASYNC) function_def
    | &('if' | MOSHI) if_stmt

CPythonの再ビルド

$ cd Python-3.11.3\PCbuild
$ build --regen
# ビルドに成功しました。
$ build
# ビルドに成功しました。

うまくいっていればPCbuild/amd64/pythonに生成されます。

動作

以下をtest.pyとしてPCbuild内に保存し、
amd64\python test.py
で実行しました。

表示, 入力, 整数 = print, input, int

温度 = 整数(入力("温度:")) # 仮に温度=11とする

もし 温度 > 25 ならば
    表示("冷房")
ではなくて 温度 < 20 ならば
    表示("暖房")
でなければ
    表示("停止")
# 暖房
    
if 温度 > 25:
    print("冷房")
elif 温度 < 20:
    print("暖房")
else:
    print("停止")
# 暖房、ifもそのまま使える

ちゃんと使えました。ヤバすぎ!!!

本を読むとなぜこれで良いのかがわかります。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?