'\n' の由来
just foo コマンドを実行すると、justfile は 0x0A バイトを bar というファイルに書き込む
just は Rust で書かれており、just パーサーは cook_string という関数を通じて、エスケープシーケンスを含む just の文字列トークンを UTF-8 文字列に変換する
Rust での処理
rustc は scan_escape という関数でエスケープコードを処理する
rustc は Rust で書かれた自己ホスト型コンパイラであり、'\n' の意味を理解するために rustc 自身に委ねている
- 初期バージョンの
rustc は OCaml で書かれており、OCaml 版の rustc は lexer で文字エスケープを処理していた
OCaml での処理
- OCaml コンパイラは
\n を \010 として評価し、その結果を埋め込む
0x0A は 10 なので、OCaml コンパイラが \n を処理するときに 0x0A のバイト値が得られる
結論
justfile に \n の文字エスケープがあると、just バイナリは 0x0A バイトを含めて最終的な文字列に書き込む
- この
0x0A バイトは rustc によって埋め込まれたものであり、その起点は OCaml コンパイラが最初に rustc バイナリへ 0x0A バイトを埋め込んだことにある
GN⁺ の要約
- この記事は、
\n の文字エスケープがどのように 0x0A バイトへ変換されるのかを説明している
- Rust と OCaml コンパイラの歴史的背景を通じて、
0x0A バイトの出所をたどっている
- プログラミング言語のコンパイラが文字エスケープをどのように処理するかについて、興味深い洞察を提供している
- Rust と OCaml のコンパイラ動作を理解する助けになる記事である
1件のコメント
Hacker Newsの意見
あるユーザーは、自分がこのアイデアを最初に読んだのは "How I wrote a self-hosting C compiler in 40 days" という記事の42日目だったと述べている
EBCDIC システムでは、初期の C コンパイラが ASCII ではないシステム上で登場したことを考慮すべきだと述べている
C 標準における文字エンコーディングについての唯一の保証は、数字の '0' から '9' が連続した昇順で割り当てられていることだとしている
あるユーザーは Ken Thompson のチューリング賞講演 "Reflections on Trusting Trust" に触れ、この文章はその講演に着想を得たものではないかと推測している
clang コンパイラにも同じ性質があるのか気にしており、これは lib/Lex/LiteralSupport.cpp で明示的に 10 としてコードされていると説明している
あるユーザーは、なぜ "\n" が 10 にエンコードされている理由を理解するために調べる必要があったのか不思議だとし、それは予想どおりだと考えている
この記事は文芸的プログラミングと詩の交差点のように読めると述べ、コード生成の何百ものサイクルを通じて 0x0A バイトが生成される過程を説明しようとしているという
あるユーザーは、C 言語のせいで "\0???" を 8 進エスケープだと思っており、"\012" は "\x0a" または "0x0a"、"\010" は "0x08" だと認識していたと説明している
ASCII や文字列にエスケープコードがなかったら、私たちのコードはどう見えていたのかという興味深い問いを投げかけている
プログラミングのひとつの法則として、2 つの方法があり、どちらかが正しくどちらかが間違っている確率が五分五分なら、最初は間違っているほうを選びがちだと述べている