SBCLメモ: 実装
read
ストリームからオブジェクトを読みんで返す
- src/code/reader.lisp
- 処理は基本的に%read-preserving-whitespaceに委譲
%read-preserving-whitespace
- 1文字だけ読んでwith-char-macro-resultに委譲
with-char-macro-result
- その名の通り、character-macroに関する処理をしている。
- 引数で最初の文字が来るので、それがcharacter macroのentryなら該当処理を実行する。
- get-raw-cmt-entryの返り値で判断
- 実行は、!cmt-entry-to-functionに委譲。read-token関数もfallbackに渡している。
- cmtってcharacter macro なんとか、みたいな感じかな。
!cmt-entry-to-function
- マクロ
- 最終的にはsb!sys:%primitive sb!c:safe-fdefn-funに委譲
- 引数はget-raw-cmt-entryの返り値
safe-fdefn-fun
- src/compiler/x64-64/cell.lisp
- vopみたい。define-vopで定義されている。
- よくわかんないけどjmpしてる。
%primitive
- def-ir1-translatorで定義されている
- よくわからないけど、%%primitiveをopにもつS式に展開されて、それをさらにir1-convertに渡している
read-token
- src/code/reader.lisp
- 状態遷移機械によるtokenizer。nginxのrequest line parserみたいな感じか。
- read-charを繰り返し呼んでる。
- たとえば、最終的にread結果がシンボルだということが分かった場合、RETURN-SYMBOLタグにgoし、シンボルを返却する。具体的にはinternしたりfind-symbolしたりする。
- なんかよくわかんないけどすごい。
read-char
- 一文字読む。
- ansi-stream-read-charかstream-read-charに委譲している。
- stream-read-charはGray stream用っぽい。
ansi-stream-read-char
- first-read-char
fast-read-char
- src/code/sysmacs.lisp
- ansi-stream-cin-bufferの現在のインデックスの値を返し、インデックスの値をインクリメントしている。
- ansi-streamをどうやって作るのかを知る必要がありそう
- bufferの限界まで読んだらfast-read-char-refillを呼んでbufferをリセットしてる感じ。
fast-read-char-refill
- src/code/stream.lisp
- UB~D-BASH-COPYを呼んでbufferからまとめて読むっぽい
- まとめて読むのはansi-stream-n-binを使う
- 見た感じub8-bash-copyしかない
ub8-bash-copy
- src/compiler/seqtran.lisp
- マクロで定義されていて見つけづらい
- vectorに入った数値をエンディアンとかをすり合わせてとってくるような感じ
fd-stream-read-n-bytes
- fd-stream用のansi-stream-n-bin
- fd-streamはunixのファイルを読むstream
- fd-stream-ibuf (実態はsap) 経由でbufferに数値を突っ込み、それをub8-bash-copyにコピーさせる感じ?
- bufferに数値を突っ込むのは%byte-blt
%byte-blt
- genericな関数
- fd-streamのsapからn個分読むのに使える
- src/code/target-miscに再起定義あり
- src/compiler/generic/vm-tranにdeftransformあり
list
- src/compiler/x86-64/alloc.lisp
- define-vopによるlistもしくはlist*の実装。二つまとめて実装している。
- listはstarがnil, list*はstarがt