マルチバイト実装 - Scheme VM を書く
マルチバイトが関わるであろう
- 文字
- 文字列
- 正規表現
- シンボル
に関して read 時のインスタンス生成のタイミングで UTF8 => Unicode に変換して保持する。
文字
まずは文字から。
UTF8 でエンコーディングされたバイト列を持つ port から Unicode 1文字を読み出すという機能を作るのが良さそうだ。
getc/ungetc を書いた。
この時点で port からの読み出し処理を入れ換えて Parser を動かしても正しく動くはずである。(ソースが ascii だけだから)
うん動いたよ。
次は実際に utf8 なものを読ませてみる。
(define a #\あ) (display a)
エラーにならず文字化けした何かになりました。
makeChar に処理系内部表現である Unicode のコードがそのまま入っているから。
次は出力が正しくなるようにしよう。
まずは Unicode のバイト列としてきちんと出力できるように。
いままでは char の外部表現を char* な文字列として stdout に fprintf していたけど port に対する fwrite であるべき。
つまりオブジェクトの外部表現文字列はいままではC言語的文字列だったけど、これからはC言語的文字列ではないバイト列になるということ。
Unicode のバイト列としては正しく出力できるようになった。
次は UTF8 のバイト列に変換して出力しよう。
よし。書いた。エラー処理などを端折っているがこれはまた今度。
(define a #\あ) (display a) => あ
うほ。来た。
考え、実装して思った通りに動くとこの年でもうれしい。
文字列
次は文字列。
基本的には自作の util::String に処理を委譲していたのだけど大幅に書き換えないとダメだ。
内部のバッファの持ちかたを char* じゃなくて uint32_t* にしたりとか。
そういえば HashMap とかも String に依存していたような。
文字列の生成は
- NULL終端の unicode のバイト列
- NULL終端の char* のバイト列
から行える必要がある。
operator+ も同様。
さてまずはコンパイルを通す。
エラー出まくりが続くがやっとOK。
画面出力を整備していなかったので画面にバイナリ列が表示されまくりフラッシュを繰り返す。
テストも通らなくなる。
つらいが今日中にとりあえず動くところまでは行きたい。
(define 名前 "ひげぽん") (display 名前) => ひげぽん
動いた〜。
String を整備すると自動的にシンボルも正しく動くようになった。
とりあえず後回しにしたことがたくさんあるので明日はそれをリストアップしてつぶしていくか。