Skip to content
YOKOTA Yuki edited this page Mar 25, 2019 · 10 revisions

仕様 (stub)

storage-class の実装

auto
lexical に bind. ポインタが取られていた場合は、 progv で dynamic に bind しなおす。(auto の意味的には、 dynamic-extent が欲しいが、警告が出まくるので保留。)
register
auto と同様だが、ポインタが取られていると 警告 を出す。 (現状、エラーにはしてない)。 dynamic-extent が付く。
extern
何にも展開しない。 自然にサポートされてるはず。
(global)
with-c-syntax form が評価される度に、その時の初期値 で defparameter される。
static (translation-unit)
local dynamic bind
static (statement)
一度だけ初期化される。(内部の記憶域として、 gensym を使う。)

関数の宣言は、 extern と同様の扱いとする。つまり、何もしない。

qualifier の実装

const
状況に応じて実装中。
構造体メンバ
未実装。slot の writer 関数を定義しないことで行っていたが、 slot-value にしたために出来なくなった。
普通の変数
未実装。なんとかして、コンパイル時検査で発見 するか、 closure に symbol-macrolet するか。
ポインタの指す先
未実装。 writer 関数を与えないように?
volatile
何もしていない。意味を再現するなら、処理系拡張に潜る必要 がある。そこまでする価値が見い出せない。

Lisp 型との対応

一番左 (decl-specs) に出てくる型

処理関数: finalize-type-spec

  • 整数
    char, signed char
    (signed-byte 8)
    unsigned char
    (unsigned-byte 8)
    int, signed int, unsigned int
    fixnum
    short, signed short
    (signed-byte 16)
    unsigned short
    (unsigned-byte 16)
    long, signed long
    (signed-byte 32)
    unsigned long
    (unsigned-byte 32)
    long long, signed long long
    (signed-byte 64)
    unsigned long long
    (unsigned-byte 64)
  • 浮動小数点数
    short float
    short-float (拡張)
    float
    single-float
    double
    double-float
    long double
    long-float
void
nil
enum
wcs-enum (fixnumdeftype)
struct, union
wcs-struct (wcs-struct.lisp で定義)

declarator としての型

処理関数: expand-init-declarator-init

ポインタ
psendo-pointer (fixnum の deftype)
関数
function
配列
(simple-array t (次元数))

sizeof の仕様

配列についてのみ、 要素数 (array-total-size と同等) を返す。 その他は、 1 を返す。

展開による副作用一覧

  • make-psendo-pointer による、ポインタ環境の変更
  • 関数定義すると defun される。
  • global な変数を作ると defvar される。
  • 構造体定義すると、外の関数を見に行こうとする。

Documentation

  • 変数や定数には (internal でも) 書く
  • export する function には頑張って書く
  • export しない 変数への副作用などは、とりあえず書かない。

Toplevel form としてのコンパイル

現状の方針: 必要なら自分で eval-when を付けてもらう。

static な関数や変数の実装に、 lexical な binding を使っているの で、 letlabels が現われることが原因。

static な定義を gensym への global な定義にし、それの同義語を symbol-macroletmacrolet で定義するという手もあり、そうすると相 当の部分を compile-file が食える toplevel form に持っていける。しかし、 気軽に quotefunction ができなくなりそうなので断念。

with-c-syntax では quote はしないと思うが、関数ポインタの 代替として function (#') を使うことを想定している。そうなると、 macrolet で張った同義語からは、元の関数が取れなくなってしまう。

その不可解さと、 eval-when で囲う手間なら、不可解さを削るべきだろう。

static 関連

暗黙のうちに、translation-unit == 一つの with-c-syntax form と想定して いた。そのため、以下の方針だった

extern
package internal symbol.
static
lexical in with-c-syntax form.

だから、 static のサポートが大変だった。

ただ、こういう考え方もある。

extern
package external symbol.
static
package internal symbol.

static 関連のクソコードが大分減らせそう。勝手に export されると気持ち悪 いので嫌だけれど、 option で制御すればいいのかも。