現在開発中のプリプロセッサについて

  • (by K, 2026.02.10)

(0) 大前提として

  • 私は同じものを作るときは同じようには作りません。
  • いきなりわかりにくい表現になってしまいましたが、つまり私がプリプロセッサを作る場合、既存の完全な互換品を目指すことはなく、何らかの拡張機能を必ず入れるということです。

(1) 多重define

  • 普通のプリプロセッサでは、マクロ Abc が定義済みの時に、さらに Abc を定義しようとすればすぐにエラーになります。
  • でも私のプリプロセッサではエラーにはならず、新しい定義が有効になります。
  • そして Abc を undef すると、定義は前の定義内容に戻ります。
  • これの何がうれしいのか?
  • 何らかのコード片があったとします。・・・C言語ではコード片を持ってきたときに、全体を { } でくくってしまえば、変数名の衝突を気にすることなく正しく動きます。
  • でも #define があるとこの限りではないのです。他とぶつかっていたら、ぶつからない名前にその都度調整しなければいけません。
  • しかし私の仕様になっていれば、ぶつかっていても気にすることはなく、最後に undef しておけば、プログラムのほかの場所に迷惑をかけることもないのです。
  • この機能は、 #define / #undef ではなく、 #.def / #.undef として実装しています。
  • #define / #undef には従来通り多重定義を認めず、また復元などの機能は持たせていません。従来のプログラムが、予期せぬ挙動のせいでバグになったら困るからです。

(2) マクロのオーバーロード

  • C → C++ での進歩点として、「同じ関数名であっても、引数の個数や型が違えば、それらは正しく区別される」という機能が追加されています。関数のオーバーロードと言われているものです。
  • それならば、プリプロセッサマクロもオーバーロード可能にしてやろうと思いました。
  • ただしプリプロセッサの引数に型はないので、マクロの識別は引数の数だけです。
  • つまり、 Abc(1,2) と Abc(1,2,3) は別のマクロです。

(3) 複数行マクロ

  • 普通のプリプロセッサでは、マクロは1行で書かなければいけません。
  • この制約から逃れるために、行末にバックスラッシュを書いて、行をつないでいました。
  • しかしこれがみっともないのです。
  • 私のプリプロセッサでは、[^ ... ^] でくくって定義することで、複数行での定義が可能になっています。また [^ ... ^] の中に、 #if や #.def などを書くことも可能です。
  • この機能によって、 C++ のテンプレートに近いこともできます。・・・つまり構造体や関数を定義するためのマクロを書いて、引数に応じて関数定義などが変わるようにすればいいのです。

(4) 追加型マクロ

  • 宣言済みのマクロに対して、 #.addTl でマクロを宣言すると、ここに書いた内容が後ろ(Tail)に付け足されて再定義されます。もし宣言済みでなかった場合は、 #define と同じ挙動になります。
  • 同様に #.addHd もあります。
  • 例えばこんな感じです。
    #.def   Counter     0
    #.def   Inc         [^
        #.addTl     Counter     +1
    ^]
    Inc Inc Inc Inc
    print Counter;
  • こうすると print 0+1+1+1+1; に展開されます。

こめんと欄


コメントお名前NameLink

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2026-02-10 (火) 21:53:57 (125d)