#VirtualBoxにUbuntu 10.4 64bit版入れてみた。aptでGauche入れたら0.8.13だった。64bit版Gaucheだったけど。SRWare Iron Linux(64)の日本語フォントがしょぼいけど我慢する。
#char-set-complement を二回適用した結果がもとの char-set にならないみたいです
#gosh> (gauche-version)
"0.9.1_pre1"
gosh> (use srfi-14)
#<undef>
gosh> char-set:empty
#[]
gosh> (char-set-complement (char-set-complement char-set:empty))
#[-�]
#化けている部分は #[\200-\370\277\277\277\277] のような値でした
#試しに 0.8.9 まで戻ってみたら期待通りの動作でした
#gosh> (gauche-version)
"0.8.9"
gosh> (use srfi-14)
#<undef>
gosh> char-set:empty
#[]
gosh> (char-set-complement (char-set-complement char-set:empty))
#[]
#その頃にchar-setの実装をレンジのリストからtreemapに入れ替えたような気がする
#今試してみたら 0.8.10 から今の動作みたいです
#Scm_TreeCoreNextEntryの動作を自分で勘違いしてるかな
#多分直った
#--- src/char.c (revision 7121)
+++ src/char.c (working copy)
@@ -460,17 +460,23 @@
Scm_BitsOperate(cs->small, SCM_BIT_NOT1, cs->small, NULL,
0, SCM_CHAR_SET_SMALL_CHARS);
- last = SCM_CHAR_SET_SMALL_CHARS;
+ last = SCM_CHAR_SET_SMALL_CHARS-1;
/* we can't use treeiter, since we modify the tree while traversing it. */
while ((e = Scm_TreeCoreNextEntry(&cs->large, last)) != NULL) {
Scm_TreeCoreSearch(&cs->large, e->key, SCM_DICT_DELETE);
if (last < e->key-1) {
+ if (last < SCM_CHAR_SET_SMALL_CHARS) {
+ last = SCM_CHAR_SET_SMALL_CHARS;
+ }
n = Scm_TreeCoreSearch(&cs->large, last, SCM_DICT_CREATE);
n->value = e->key-1;
}
last = (int)e->value+1;
}
if (last < SCM_CHAR_MAX) {
+ if (last < SCM_CHAR_SET_SMALL_CHARS) {
+ last = SCM_CHAR_SET_SMALL_CHARS;
+ }
n = Scm_TreeCoreSearch(&cs->large, last, SCM_DICT_CREATE);
n->value = SCM_CHAR_MAX;
}
#あれ、でもTreeCoreSearchは下限一致でもエントリを返すように見えるな…自分で書いててわからなくなったぞ。
#あ、違う違う。やっぱり最初の予想が正しい。キーが一致するエントリがあった場合、NextEntryはそのエントリの次のエントリを返しちゃうから、SCM_CHAR_SET_SMALL_CHARSから始まるエントリがあるとそいついがヒットしないんだ。
#lastを調整してるとこがちょっとアレだな。lastをレンジの開始点ではなく空隙の終了点として扱えばいいのか。
#これでどうだ。えい。
#--- src/char.c (revision 7121)
+++ src/char.c (working copy)
@@ -460,18 +460,18 @@
Scm_BitsOperate(cs->small, SCM_BIT_NOT1, cs->small, NULL,
0, SCM_CHAR_SET_SMALL_CHARS);
- last = SCM_CHAR_SET_SMALL_CHARS;
+ last = SCM_CHAR_SET_SMALL_CHARS-1;
/* we can't use treeiter, since we modify the tree while traversing it. */
while ((e = Scm_TreeCoreNextEntry(&cs->large, last)) != NULL) {
Scm_TreeCoreSearch(&cs->large, e->key, SCM_DICT_DELETE);
if (last < e->key-1) {
- n = Scm_TreeCoreSearch(&cs->large, last, SCM_DICT_CREATE);
+ n = Scm_TreeCoreSearch(&cs->large, last+1, SCM_DICT_CREATE);
n->value = e->key-1;
}
- last = (int)e->value+1;
+ last = (int)e->value;
}
if (last < SCM_CHAR_MAX) {
- n = Scm_TreeCoreSearch(&cs->large, last, SCM_DICT_CREATE);
+ n = Scm_TreeCoreSearch(&cs->large, last+1, SCM_DICT_CREATE);
n->value = SCM_CHAR_MAX;
}
return SCM_OBJ(cs);
#なんか前のコードだと空隙が1の場合にうまく動かなかったような気がしないでもないのだが、とりあえずテスト書いてみよう。
#やっぱそうだ。前のやつはギャップが1のsetでもしくじってた。
#こみっと。