-
Notifications
You must be signed in to change notification settings - Fork 7
Translation Phases との対応
https://en.cppreference.com/w/c/language/translation_phases とどれを対応させるか?
現在 (2021-5-26) は下記のようになっていないが、こうなるように修正したい。
このcommit で導入した。
以下の二つを read-char
で透過的に行う。
なぜ gray stream にしたかは以下に書く。
???=
のような文字列が問題で、これは最初の ? を残して ?#
に変換されないといけない。
2文字の先読みが必要と思うが、 unread-char
を2回呼ぶのも、 peek-char
後に unread-char
するのも unspecified になってしまう。
このバッファリングを行うために gray stream を使いたくなった。
\
をリーダマクロで発見して次の文字を見て、というのでは全然だめ。
\\\n
の前のトークンと結合しなければならず、 リーダマクロで文字を引っ掛けても「直前に読んだトークン」に触れる手段はない。
当初、ソースにあらかじめ phase1, phase2 だけを適用し、 phase 3 は Lisp リーダを使おうと考えたが、 backquote で Lisp 文法に戻せるようにしてたのが問題に。
Lisp 文法の中ではこれらの変換を抑制したい、 どちらかの文法のコメント中は }#
や backquote を抑制したい、と考えてしまう。(実際 test はそれを前提にしていた。)
すると、各時点での文法を追跡してコメントの文法を把握しなければならない。つまり結局 phase1,2,3 を同時に処理しないといけなかった。
Lisp リーダをできる限り使い回すためには、 gray stream で phase1, phase2 を read-char
に押し込めることが必要だった。
現状は reader macro で行っている。
一部の数値 (0x
表記と、 Reader Level 2 の数値) は pp-number で留められる。
preprocess ブランチで実装中。
#include
するファイルの発見を asdf:system-relative-pathname
でやろうとすると、なぜか Github Actions ではコケる。
asdf:find-component
なら大丈夫。
やる必要があるのかな?
プリプロセスの一部として行っている。
- C keyword の intern. readtable-case 関連処理のためにここで行なっている。
- (Libc の intern) 削除済。 これは
#include
で代替されるべき
- backslash による escape を保存できない。 Lisp リーダは特に escape されるべきではない文字に backslash がついていてもよく、単純に backslash が無くなってしまう。この仕様が、 C99仕様 「6.10.3.5 Scope of macro definitions」の Example 4 の
str(: @\n)
の箇所と競合する。 -
#include
元と先とで readtable-case が違う場合の処理が整理されてない。この無理矢理な commit に問題が現れている。 → その後、#pragma
で readtable-case を指定できるようにして整理。何もしないと current readtable に従い、 pragma で任意に切り替えられる。 この例 を参照。 - mcpp の 「u.1.23. # 演算子によって不正な pp-token が生成された」 の形式が受け取れない。この例 (
puts( str( \""));
)、文字列リテラルとは一体なんなのかわからなくなる・・。
pp-number の Lisp 数値への変換と、 typedef hack も行う。
がんばる。
macroexpand
して展開することこそが Link である、と定義しよう。