Gauche:Bugs:log3

Gauche:Bugs:log3

最新のもの:Gauche:Bugs


quote、quasiquote(0.8.1)

結果が、長さ ちょうど2のリストになるような式で、そのリストの先頭に quoteかquasiquoteをシンボルとして入れようとすると、 おかしなことになってしまいます。(2004/11/26 22:27:11 PST)

(list 'quote 'quasiquote) ;; => 'quasiquote
(list 'quasiquote 'quote) ;; => `quote
(cons 'quote '(hoge))     ;; => 'hoge

マニュアル(reduce)

GaucheRefj:reduceの使い方がよくわからなかったので、 SRFI 1のreduceの説明を 見てみたのですが、引数ridentityは「(f x ridentity) == ridentity」ではなく、 「(f x ridentity) == x」ではないでしょうか。

また、fの適用を省略するのは、「ひとつしか要素をもたない場合」ではなく、listが空の場合ではないでしょうか。(2004/11/20 04:24:29 PST)

mingw-compat.hがインストールされない (0.8.1)

MinGWではgauche.hからインクルードされますが、インストールされません。 src/Makefile.inのINSTALL_SUBHEADERSに追加するのだと思いますが。

それから、mingw-compat.hではgid_t, uid_tをtypedefしていますが、 MinGWにそれらが存在しないことを知っている他のライブラリではこれらを #defineしている場合があり、そちらを先に#includeしているとエラーになります。 そこで、typedefを #ifndef uid_t〜#endif, #ifndef gid_t〜#endif で囲んでもらえないでしょうか。

src/Makefile.inのINSTALL_BINS (0.8.1)

MinGWでビルドできるようになってて嬉しいです。 一箇所、EXEEXTのつけ忘れを発見しました。 (2004/11/12 12:47:28 PST)

--- src/Makefile.in.orig        Mon Sep 20 21:16:39 2004
+++ src/Makefile.in     Sat Nov 13 05:34:39 2004
@@ -93,7 +93,7 @@
                      gauche/builtin-syms.h                            \
                      gauche/pthread.h gauche/uthread.h gauche/arch.h
 INSTALL_LIBS = libgauche.$(SOEXT)
-INSTALL_BINS = gosh gauche-config gauche-install gauche-package \
+INSTALL_BINS = gosh$(EXEEXT) gauche-config gauche-install gauche-package \
                gauche-cesconv
 INSTALL_SCMS = gauche-init.scm genstub cesconv
 

ところでつくったgoshを使って後の処理をしていますが、クロスコンパイルだと当然うごかないので困ってしまいます。ホスト環境(UNIX)のgoshを使うようにMakefileの変数を変えてやってしまいましたが、問題ないでしょうか? 問題なければ、できればホスト環境のgoshを代わりに使うようなconfigureオプションを追加してもらえると嬉しいです。

syntax-rules内のlet-keywords*(0.8.1)

syntax-rules内でlet-keywords*がうまく動いてくれません。(2004/11/08 21:47:13 PST)

--- Gauche-0.8.1.orig/lib/gauche/procedure.scm  2004-08-03 06:50:47.000000000 +0900
+++ Gauche-0.8.1/lib/gauche/procedure.scm       2004-11-09 13:54:45.000000000 +0900
@@ -134,11 +134,11 @@
                                 (var (unwrap-syntax (car var&default)))
                                 ((symbol? var)))
                        (case (length var&default)
-                         ((2) `(,var
+                         ((2) `(,(car var&default)
                                 ,(make-keyword var)
                                 ,(cadr var&default)))
-                         ((3) `(,var ,(unwrap-syntax (cadr var&default))
+                         ((3) `(,(car var&default) ,(unwrap-syntax (cadr var&default))
                                      ,(caddr var&default)))
                          (else #f)))
                      (error "bad binding form in let-keywords*" var&default)))
                vars)))

date->julian-dayがzone-offsetを解さない(0.8.1)

下のコードがゼロになって欲しいところです。

(use srfi-19)
(let1 jd (current-julian-day)
  (- jd (date->julian-day (julian-day->date jd))))

こんな感じでしょうか。(2004/10/27 13:28:39 PDT)

--- Gauche-0.8.1.orig/lib/srfi-19.scm   2004-08-03 06:50:47.000000000 +0900
+++ Gauche-0.8.1/lib/srfi-19.scm        2004-10-28 05:17:16.000000000 +0900
@@ -655,13 +655,15 @@
         (hour (date-hour date))
         (day (date-day date))
         (month (date-month date))
-        (year (date-year date)) )
+        (year (date-year date))
+        (offset (date-zone-offset date)) )
     (+ (tm:encode-julian-day-number day month year)
        (- 1/2)
        (+ (/ (+ (* hour 60 60)
                (* minute 60)
                second
-               (/ nanosecond tm:nano))
+               (/ nanosecond tm:nano)
+               (- offset))
             tm:sid)))))
 
 (define (date->modified-julian-day date)

マニュアルの誤植 (0.8.1)

誤植をみつけたので報告します。文字列関連で"less than"を"以下"としてしまっているところ、sortの説明がおかしいところのふたつです。(2004/10/20 08:54:12 PDT)

--- Gauche-0.8.1.orig/doc/corelib.texi  2004-08-03 06:50:46.000000000 +0900
+++ Gauche-0.8.1/doc/corelib.texi       2004-10-21 00:38:15.000000000 +0900
@@ -2830,7 +2830,7 @@
 @c JP
 (多分、不完全な)文字列@var{string}の@var{k番目}のバイトを返します。
 戻り値は、0から255の範囲の整数です。@var{k}は0以上、
-@code{(string-size @var{string})}以下でなければなりません。
+@code{(string-size @var{string})}より小でなければなりません。
 @c COMMON
 @end defun
 
@@ -2847,7 +2847,7 @@
 See the notes in @code{make-string} about performance consideration.
 @c JP
 [R5RS] @var{string}の@var{k}番目の文字を@var{char}で置き換えます。
-@var{k}は0以上、@code{(string-length @var{string})}以下でなければ
+@var{k}は0以上、@code{(string-length @var{string})}より小でなければ
 なりません。戻り値は未定義です。
 
 @var{string}が不完全文字列の場合、@var{char}の下位8ビットの整数値は、
@@ -2869,7 +2869,7 @@
 @c JP
 @var{string}の@var{k}番目のバイトを整数@var{byte}で置き換えます。
 @var{byte}は0から255の範囲(255を含む)でなければなりません。
-@var{k}は0以上、@code{(string-size @var{string})}以下である必要があります。
+@var{k}は0以上、@code{(string-size @var{string})}より小である必要があります。
 @var{string}が完全文字列の場合、この操作により不完全文字列になります。
 戻り値は未定義です。
 @c COMMON
@@ -8966,15 +8966,15 @@
 in ascending order and returns the sorted sequence.
 @code{sort!} destructively reuses the original sequence.
 The sorting order is specified by @code{cmpfn}, which is
-a procedure takes two elements of @var{list}, and returns @code{#t}
+a procedure takes two elements of @var{seq}, and returns @code{#t}
 if the first argument strictly precedes the second.
 @c JP
 シーケンス@var{seq}(リストかベクタ)の要素を昇順にソートし、
 ソートされたシーケンスを返します。
 @code{sort!}は、オリジナルのシーケンスを破壊的に再利用します。
-ソート順は@code{cmpfn}で指定されます。@code{cmpfn}は2要素の@var{list}を
+ソート順は@code{cmpfn}で指定されます。@code{cmpfn}は@var{seq}のふたつの要素を
 引数に取り、最初の要素が厳密に2番目の要素より先行するものの場合は
-@code{#f}を返す手続きです。
+@code{#t}を返す手続きです。
 @c COMMON
 
 @example

directory-listでfilter-add-path?を指定するとchildren?が無効に(0.8.1)

filter-add-path?を指定すると、children?を#tにしても返り値に"."と".."が含まれてしまいます。(2004/10/19 23:55:14 PDT)

(use file.util)
(directory-list "/home"
                :children? #t
                :filter identity
                :filter-add-path? #t)

マニュアルの間違い (0.8.1)

GaucheRefj:define-classにおける:allocationオプションの説明と実装に食い違いがあります。

マニュアルには、「スロットアロケーションが virtualと指定されていれば、`:slot-ref' および `:slot-set!'オプションが同様に指定されていなければなりません。さもなければ、`define-class'は エラーを発生させます。」とあります。しかし実際には、:slot-set!オプションは指定する必要はなく、必須なのは:slot-refのみです。マニュアルの間違いではないでしょうか。

同様の記述は、同じページの下のほうの:slot-set!の説明にもあります。(2004/10/17 23:38:21 PDT)

C++予約語 template がgauche.hに入っている (0.8.1)

*** /Users/nel/Software/gauche/Gauche/src/gauche.h      Wed Oct 13 14:35:14 2004
--- gauche.h    Wed Oct 13 14:29:16 2004
***************
*** 2447,2453 ****
  #endif /*!HAVE_SELECT*/
  
  /* other stuff */
! SCM_EXTERN ScmObj Scm_SysMkstemp(ScmString *template);
  
  /*---------------------------------------------------
   * LOAD AND DYNAMIC LINK
--- 2447,2453 ----
  #endif /*!HAVE_SELECT*/
  
  /* other stuff */
! SCM_EXTERN ScmObj Scm_SysMkstemp(ScmString *temp);
  
  /*---------------------------------------------------
   * LOAD AND DYNAMIC LINK

マニュアルの不整合(bit-field)(0.8.1)

GaucheRefj:bit-fieldの説明でのインデックスの数えかたが、前後の手続きの説明での数えかたと異なっています。bit-fieldの説明では最初のビットを1番目と数えていますが、logbit?などでは0番目としています。「整数nのstart+1ビット目からendビット目(両端含む)までを」は「整数nのstartビット目(含む)からendビット目(含まない)までを」としたほうがわかりやすいのではないでしょうか。(2004/10/04 11:38:40 PDT)

rfc.822のrfc822-parse-dateが一月ずれる(0.8.1)

コレが正しい?何か間違ってたらすいません(2004/09/30 14:23:03 PDT)

--- 822.scm.orig        2004-10-01 06:12:06.000000000 +0900
+++ 822.scm     2004-10-01 06:19:07.000000000 +0900
@@ -196,9 +196,10 @@
     (list-index (cut string=? <> dow)
                 '("Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat")))
   (define (mon->number mon)
-    (list-index (cut string=? <> mon)
-                '("Jan" "Feb" "Mar" "Apr" "May" "Jun"
-                  "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")))
+    (+ 1
+       (list-index (cut string=? <> mon)
+                   '("Jan" "Feb" "Mar" "Apr" "May" "Jun"
+                     "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))))
   (define (year->number year) ;; see obs-year definition of RFC2822
     (let ((y (string->number year)))
       (and y

コンパイラの警告(0.8.1-newgc)

guess.cをコンパイルすると、型の不一致によりgccが警告を出力します。具体的にどこが不一致なのか正直わからないのですが、以下のように素直に書くと警告は出ません。

--- ext/charconv/guess.c        14 Mar 2004 05:30:37 -0000      1.3
+++ ext/charconv/guess.c        20 Sep 2004 18:58:34 -0000
@@ -43,20 +43,20 @@
 } guess_arc;

 typedef struct guess_dfa_rec {
-    signed char (*states)[][256];
+    signed char (*states)[256];
     guess_arc *arcs;
     int state;
     double score;
 } guess_dfa;

 #define DFA_INIT(st, ar) ?
-    { &st, ar, 0, 1.0 }
+    { st, ar, 0, 1.0 }

 #define DFA_NEXT(dfa, ch)                               ?
     do {                                                ?
         int arc__;                                      ?
         if (dfa.state >= 0) {                           ?
-            arc__ = (*dfa.states)[dfa.state][ch];       ?
+            arc__ = dfa.states[dfa.state][ch];          ?
             if (arc__ < 0) {                            ?
                 dfa.state = -1;                         ?
             } else {                                    ?

(2004/09/26 02:55:28 PDT) なぜ警告されるのかを調べてみました。 型の不一致の警告が出ているのは以下の行です(マクロは展開)。

 guess_dfa eucj = { &guess_eucj_st, guess_eucj_ar, 0, 1.0 };

guess_eucj_ar以降の初期化子は警告の原因になっていないので、ここではguess_eucj_stのみに注目します。

まず初期化するほうのguess_eucj_stの型は、「signed charの配列256の配列4」です。(定義では、guess_eucj_st[][256]というように不完全な配列として定義されていますが、「不完全な配列型のオブジェクトの型は、(略)それを初期化することによって(略)、完全なものとなる」(K&R付録A8.6.2)ことにより、guess_eucj_stは長さの指定された完全な型になります。) したがって&guess_eucj_stの型は、「signed charの配列256の配列4へのポインタ」です。&をつけずにguess_eucj_stと書いたとき、それが配列の最初の要素へのポインタすなわち「signed charの配列256へのポインタ」になることとの違いに注意してください。

そして初期化されるほうですが、構造体guess_dfaの最初のメンバstatesは「signed char (*states)[][256]」と宣言されており、その型は「signed charの配列256の不完全な配列へのポインタ」です。

  1. signed charの配列256の配列4へのポインタ
  2. signed charの配列256の不完全な配列へのポインタ

この違いが警告の原因です。

初期値式の値はオブジェクトに代入するのに適当な型でなければならず、代入演算子では、「両被演算数が関数あるいはオブジェクトへのポインタで、このオブジェクトは右被演算数にconstあるいはvolatileがないこともある点を除けば、その型が同じ」(A7.17)でなければなりません。「型が同じ」であるためには、「配列のサイズ(略)も一致する必要がある」(A8.10)。したがって上記の違いは許されず、警告が出力されるというわけです。

guess_sjis_st, guess_utf8_stも同様です。

roundeven in number.c(0.8.1)

困っているわけではありませんが、こうなのかなと思いました。(2004/09/17 06:41:11 PDT)

--- Gauche-0.8.1.orig/src/number.c      2004-08-03 06:50:47.000000000 +0900
+++ Gauche-0.8.1/src/number.c   2004-09-17 22:25:13.000000000 +0900
@@ -1655,12 +1655,12 @@
     if (v > 0.0) {
         if (frac > 0.5) r += 1.0;
         else if (frac == 0.5) {
-            if (r/2.0 != 0.0) r += 1.0;
+            if (fmod(r, 2.0) != 0.0) r += 1.0;
         }
     } else {
         if (frac < -0.5) r -= 1.0;
-        else if (frac == 0.5) {
-            if (r/2.0 != 0.0) r -= 1.0;
+        else if (frac == -0.5) {
+            if (fmod(r, 2.0) != 0.0) r -= 1.0;
         }
     }
     return r;

rational?(0.8.1)

有理数を判定するところが、実数の判定になってしまっています。まだ有理数のサポートはなく、マニュアルに有理数の集合と整数の集合は同一とあるので、integer?の中身をコピペしてみました↓。(2004/09/11 20:34:26 PDT)

--- Gauche-0.8.1.orig/src/stdlib.stub   2004-08-03 06:50:47.000000000 +0900
+++ Gauche-0.8.1/src/stdlib.stub        2004-09-12 12:18:53.000000000 +0900
@@ -66,7 +66,9 @@
 (define-cproc number? (obj)   (return <boolean> "SCM_NUMBERP"))
 (define-cproc complex? (obj)  (return <boolean> "SCM_NUMBERP"))
 (define-cproc real? (obj)     (return <boolean> "SCM_REALP"))
-(define-cproc rational? (obj) (return <boolean> "SCM_REALP"))
+(define-cproc rational? (obj)
+  "  if (!SCM_NUMBERP(obj)) SCM_RETURN(SCM_FALSE);
+  else SCM_RETURN(SCM_MAKE_BOOL(Scm_IntegerP(obj)));")
 (define-cproc integer? (obj)
   "  if (!SCM_NUMBERP(obj)) SCM_RETURN(SCM_FALSE);
   else SCM_RETURN(SCM_MAKE_BOOL(Scm_IntegerP(obj)));")

(symbol-bound? 'syntax-rules) => #f (0.8.1)

問題がおきているわけではありませんが、気になったもので。(2004/09/06 14:19:53 PDT)

と、書いたものの、R5RSではsyntax-rulesそのものがシンタックスであるとは書いていないのか。とすると、Gaucheでsyntax-rulesが#<syntax syntax-rules>と評価されなくてもいいわけですね。すみませんでした(あ、でも%syntax-rulesというのは評価できるなあ。)いったいsyntax-rulesって何なんでしょうか。(2004/09/06 18:03:11 PDT)

(symbol-bound? 'syntax-rules) ;; => #f

マニュアルのタイポ(0.8.1)

リファレンスマニュアル内cuteの例に括弧の対応がおかしくなっている箇所があったので報告しておきます(2004/09/05 20:46:15 PDT)。

gauche.arrayに未exportなクラス(0.8.1)

gauche.arrayを使おうとして、いくつかのクラスがexportされていないのに気づい たので報告します。あと、クラスの定義が重なっている部分があったのでそれもついでに 削っています。(2004/09/02 13:40:41 PDT)

getter-with-setterでsetterがロックされない(0.8.1)

マニュアルではgetter-with-setterはsetterをロックするとあるのですが、下のコードがエラーになってくれません。直すにはgauche-init.scm内のgetter-with-setterをCレベルまでもっていかなくてはいけないのでしょうか。(2004/08/25 04:19:57 PDT)

(define cdr2 (getter-with-setter cdr set-cdr!))
(set! (setter cdr2) set-car!)

regexp-replace-allで文字列の最初を置換すると無限ループ(0.8.1)

そんなことするなよっていわれちゃいそうですが。無限ループにはいってしまいました。(2004/08/20 02:34:40 PDT)

(use gauche.regexp)
(regexp-replace-all #/^/ "some string" "any string")

Cで書かれたクラスのwrite-object

例えば以下のようなwrite-objectを書いても、(write (current-time))は意図したようには動作せず、#<time-utc 1092983327.991697000>といった出力のままとなります。

(define-method write-object
  ((t <time>) port)
  (format port "#,(<time> ~s ~s ~s ~s ~s ~s)"
          :type (ref t 'type)
          :second (ref t 'second)
          :nanosecond (ref t 'nanosecond)))

当たり前ですが、(write-object (current-time) (current-output-port))とすれば意図通り#,(<time> :type time-utc :second 1092983274 :nanosecond 878720000)といった出力になります。 これはこういうものなのでしょうか。 ; 読み込み時コンストラクタも併せて書いて、<time>を読み書きしたかったのです。

Shiro (2004/08/20 02:10:53 PDT): 現状では、そういうものです。 writeに限らず、現在のgaucheでは、システム組み込みの型に関しては 動作が固定されており、ユーザ定義型に関してはgeneric functionを使って ディスパッチする、というものがいくつかあります。(hash vs object-hash, equal? vs object-equal? 等)。OO界にあわせるなら全てをgeneric functionに した方が綺麗なのですが(GOOはそういう方針だったと思います、確か)、 そうすると何をするにもメソッドディスパッチが入り、性能面だけでなく いろんなところに問題を引き起こすので。

ただ、この例のようにwriteをカスタマイズしたいという要求は よくあります。writeのユーザ定義メソッドを呼ぶ際に、再帰的に呼ばれる writerも渡して行くようにすればうまくいくかなと思っています。 名前もwrite-objectからobject-writeに変えたいし (前者はSTk由来なんですが、 今ではobject-xxxという名前の方で統一しつつあるので)。

libgaucheのSONAME

Debianのパッケージを作っていて見つけたのですが、libgauche.so.0.x.xにSONAMEがありません(Debianではusr/libにインストールされる.soにSONAMEがないと、パッケージチェッカに怒られてしまうのです)。DebianにおけるSONAMEはhttp://www.netfort.gr.jp/~dancer/column/libpkg-guide/libpkg-guide.html が参考になると思います。(2004/08/11 08:29:50 PDT)

util.matchのorの挙動について

(A)も(B)'aが返ることを期待したのですが、(B)は'bが返ります。 これはどちらも'aを返すべきですよね? (2004/07/28 16:30:58 PDT)

(use util.match)

;;(A)
(match '(:key 1 "hoge" 2 "fuga")
  [ ((? keyword?) (or                (? string?) (? number?)  ) ...)      'a]
  [ ((? keyword?) (? (lambda (x) (or (string? x) (number? x)))) ...)      'b]
  ) ;=> a

;;(B)
(match '((:key 1 "hoge" 2 "fuga") (:key2 1 "hoge" 2 "fuga"))
  [(((? keyword?) (or                (? string?) (? number?)  ) ...) ...) 'a]
  [(((? keyword?) (? (lambda (x) (or (string? x) (number? x)))) ...) ...) 'b]
  ) ;=> b

Typo (CVS_HEAD)

単なるタイポだと思いますが。(2004/07/27 21:03:06 PDT)

Index: lib/srfi-0.scm
===================================================================
RCS file: /cvsroot/gauche/Gauche/lib/srfi-0.scm,v
retrieving revision 1.21
diff -u -r1.21 srfi-0.scm
--- lib/srfi-0.scm      26 Jul 2004 09:51:41 -0000      1.21
+++ lib/srfi-0.scm      28 Jul 2004 03:58:18 -0000
@@ -37,7 +37,7 @@
               '((srfi-0)
                 (srfi-1 srfi-1)
                 (srfi-2 srfi-2)
-                (srfi-4 gauche.vector)
+                (srfi-4 gauche.uvector)
                 (srfi-5 srfi-5)
                 (srfi-6)
                 (srfi-7)
Index: src/load.c
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/load.c,v
retrieving revision 1.90
diff -u -r1.90 load.c
--- src/load.c  26 Jul 2004 09:51:41 -0000      1.90
+++ src/load.c  28 Jul 2004 03:58:19 -0000
@@ -1088,7 +1088,7 @@
     SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_EUCJP));
 #elif defined(GAUCHE_CHAR_ENCODING_SJIS)
     SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_SJIS));
-#elif defnied(GAUCHE_CHAR_ENCODING_UTF8)
+#elif defined(GAUCHE_CHAR_ENCODING_UTF8)
     SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_UTF8));
 #else
     SCM_APPEND1(init_cond_features, t, SCM_LIST1(SCM_SYM_GAUCHE_NONE));

sys-glob (0.8)

POSIXによると、gl_pathcとgl_pathvはglobが失敗したときでも意味をもち、それによりglobは部分的な結果を返すことができるとなっています。したがってエラー時にもglobfreeする必要がありますが、現在のGaucheはそれを行っていません。以下はそれを修正するパッチです。(2004/07/26 21:47:38 PDT)

--- src/system.c        21 Jul 2004 07:25:17 -0000      1.59
+++ src/system.c        27 Jul 2004 05:04:10 -0000
@@ -191,12 +191,13 @@
     ScmObj head = SCM_NIL, tail = SCM_NIL;
     int i, r;
     SCM_SYSCALL(r, glob(Scm_GetStringConst(pattern), 0, NULL, &globbed));
+    if (r) {
+        globfree(&globbed);
 #ifdef GLOB_NOMATCH
-    if (r == GLOB_NOMATCH) return SCM_NIL;
-#else  /*!GLOB_NOMATCH*/
-    if (r == 0 && globbed.gl_pathc == 0) return SCM_NIL;
-#endif /*!GLOB_NOMATCH*/
-    if (r) Scm_Error("Couldn't glob %S", pattern);
+        if (r == GLOB_NOMATCH) return SCM_NIL;
+#endif
+        Scm_Error("Couldn't glob %S", pattern);
+    }
     for (i = 0; i < globbed.gl_pathc; i++) {
         ScmObj path = SCM_MAKE_STR_COPYING(globbed.gl_pathv[i]);
         SCM_APPEND1(head, tail, path);

Scm_FindBinding (0.8)

実害はないですが、修正前のifは意図したものと違っていると思います。(2004/07/26 04:14:05 PDT)

--- src/module.c        22 May 2004 07:21:42 -0000      1.50
+++ src/module.c        26 Jul 2004 11:07:27 -0000
@@ -210,7 +210,7 @@
                 for (i=0; i<num_searched; i++) {
                     if (SCM_EQ(SCM_CAR(mp), searched[i])) goto skip;
                 }
-                if (i == num_searched) {
+                if (!SCM_NULLP(more_searched)) {
                     if (!SCM_FALSEP(Scm_Memq(SCM_CAR(mp), more_searched))) {
                         goto skip;
                     }

Typo in fetch.scm (0.8)

タイポをみつけました.assq-ref 内の 'ncftpget の部分です.2004/07/15 06:16:33 PDT

--- lib/gauche/package/fetch.scm.orig   2004-07-15 22:07:52.000000000 +0900
+++ lib/gauche/package/fetch.scm        2004-07-15 22:08:16.000000000 +0900
@@ -59,7 +59,7 @@
   (let-keywords* opts ((config '()))
     (let* ((build-dir (assq-ref config 'build-dir "."))
            (wget      (assq-ref config 'wget *wget-program*))
-           (ncftpget  (assq-ref config 'ncfptget *ncftpget-program*))
+           (ncftpget  (assq-ref config 'ncftpget *ncftpget-program*))
            (dest      (build-path build-dir (sys-basename uri))))
       (rxmatch-case uri
         (#/^https?:/ (#f)

マクロ内のcase(0.8)

マクロ内にcaseがある場合に、シンボルの判定に失敗します

gosh> (define-syntax foo (syntax-rules () ((_ x) (case x ((a) #t) (else #f)))))
#<syntax foo>
gosh> (foo 'a)
#f

とりあえずこれで動きました。--teranishi (2004/07/11 06:25:20 PDT)

--- Gauche-0.8.orig/src/compile.c       Fri May 21 20:40:21 2004
+++ Gauche-0.8/src/compile.c    Sun Jul 11 21:48:55 2004
@@ -1336,7 +1336,7 @@
             Scm_Error("badly formed clause in case form: %S", clause);
         /* the value of the key is on top of the stack.  */
         SCM_APPEND1(testcode, testtail, SCM_VM_INSN(SCM_VM_DUP));
-        SCM_APPEND1(testcode, testtail, test);
+        SCM_APPEND1(testcode, testtail, unwrap_identifier(test));
         SCM_APPEND1(testcode, testtail, SCM_VM_INSN(SCM_VM_MEMV));
         test = testcode;
     } else {

multibyte string の判定 (0.8)

内部エンコーディングを euc-jp にした場合に、 write が文字列を正しくエスケープできないことがあります。(2004/07/01 10:15:06 PDT)

$ gosh -V
Gauche scheme interpreter, version 0.8 [euc-jp,pthreads]
$ gosh
gosh> (define str (with-output-to-string
                    (lambda () (for-each (lambda (v) (write-byte v))
                                         '(#xe3 #x81 #x82 #x22)))))
gosh> str
"?343?201?202""
gosh> (string-size str)
4
gosh> (string-length str)
2
Index: src/gauche/char_euc_jp.h
===================================================================
RCS file: /cvsroot/gauche/Gauche/src/gauche/char_euc_jp.h,v
retrieving revision 1.14
diff -u -3 -p -r1.14 char_euc_jp.h
--- src/gauche/char_euc_jp.h    9 Jan 2004 11:03:58 -0000       1.14
+++ src/gauche/char_euc_jp.h    1 Jul 2004 16:39:30 -0000
@@ -69,12 +69,23 @@
 #define SCM_CHAR_GET(cp, ch)                                    ?
     do {                                                        ?
         if (((ch) = (unsigned char)*(cp)) >= 0x80) {            ?
-            if ((ch) == 0x8f) {                                 ?
+            if ((ch) == 0x8f &&                                 ?
+                (unsigned char)(cp)[1] >= 0xa1 &&               ?
+                (unsigned char)(cp)[1] <= 0xfe &&               ?
+                (unsigned char)(cp)[2] >= 0xa1 &&               ?
+                (unsigned char)(cp)[2] <= 0xfe) {               ?
                  (ch) = ((ch) << 16)                            ?
                      + ((unsigned char)(cp)[1] << 8)            ?
                      + (unsigned char)(cp)[2];                  ?
-            } else {                                            ?
+            } else if(((ch) >= 0xa1 && (ch) <= 0xfe &&          ?
+                       (unsigned char)(cp)[1] >= 0xa1 &&        ?
+                       (unsigned char)(cp)[1] <= 0xfe) ||       ?
+                      ((ch) == 0x8e &&                          ?
+                       (unsigned char)(cp)[1] >= 0xa1 &&        ?
+                       (unsigned char)(cp)[1] <= 0xdf)) {       ?
                 (ch) = ((ch) << 8) + (unsigned char)(cp)[1];    ?
+            } else {                                            ?
+                (ch) = SCM_CHAR_INVALID;                        ?
             }                                                   ?
         }                                                       ?
     } while (0)

複素数で,複数の引数がある場合の割り算(0.8)

複素数の割り算で引数が複数ある場合,途中で虚数部分の初期化に失敗しているようです.(2004/06/27 11:32:18 PDT)

(let ((a 3)
      (b 4+3i)
      (c 7.3))
  (- (/ a b c)
     (/ (/ a b) c)))
=> -0.026838671085532312-0.01599236448164463i
--- src/number.c.orig   2004-06-28 03:03:51.000000000 +0900
+++ src/number.c        2004-06-28 03:11:22.000000000 +0900
@@ -1216,9 +1216,9 @@
         double d, r, i;
         result_real = SCM_COMPLEX_REAL(arg0);
         result_imag = SCM_COMPLEX_IMAG(arg0);
-        div_imag = 0.0;
       DO_COMPLEX:
         for (;;) {
+          div_imag = 0.0;
             if (SCM_INTP(arg1)) {
                 div_real = (double)SCM_INT_VALUE(arg1);
             } else if (SCM_BIGNUMP(arg1)) {

gauche-cesconv の help (0.8)

gauche-cesconv --help が動きません。(2004/06/23 09:20:51 PDT)

--- src/gauche-cesconv.in.orig  2004-06-24 01:16:14.000000000 +0900
+++ src/gauche-cesconv.in       2004-06-24 01:09:02.000000000 +0900
@@ -28,7 +28,7 @@
   (let-args (cdr args) ((ices "f|from-code=s" (gauche-character-encoding))
                         (oces "t|to-code=s" (gauche-character-encoding))
                         (outfile "o|output=s" #f)
-                        (#f   "h|help" (usage))
+                        (#f   "h|help" => (pa$ usage))
                         . files)
     (file-filter (lambda (in out)
                    (let ((inp  (wrap-with-input-conversion in ices))

カレントモジュールでの apropos (0.8)

gauche.sequence は gauche.collection を extend しているので,

(use gauche.sequence)
(symbol-bound? 'call-with-iterator)
#t

となります.apropos は引数のモジュールを省略すると,カレントモジュールから見える変数を表示するはずなのですが,

(apropos 'call-with-iterator)

では何も表示されません.一応の対処↓(2004/06/22 00:22:41 PDT) ↓をちょっと修正。2004/06/23 07:50:52 PDT

--- lib/gauche/interactive.scm.orig     2004-06-22 15:04:41.000000000 +0900
+++ lib/gauche/interactive.scm  2004-06-22 16:03:25.000000000 +0900
@@ -95,7 +95,9 @@
     (if stay-in-module
         (search module)
         (begin
-          (for-each search (module-imports module))
+          (for-each (compose (for-each$ search)
+                             module-precedence-list)
+                    (module-imports module))
           (for-each search (module-precedence-list module))))
     (for-each display (sort result))
     (values)

割り算(0.8)

(/ (exact->inexact (expt 10 10)) (expt 10 9) 1)
10.0

となりますが,次の様にするとエラーとなってしまいます.

(/ (expt 10 10) (expt 10 9) 1)
ERROR: operation / is not defined between (10 . 0) and 1

(2004/06/11 13:38:19 PDT)

bignum同士の割り算で結果が整数、かつ残りの引数がある場合におかしくなっているんですね。これで直ります。(2004/06/16 02:57:09 PDT)

--- gauche.orig/src/number.c    2004-06-16 18:46:51.000000000 +0900
+++ gauche/src/number.c 2004-06-16 18:39:32.000000000 +0900
@@ -1171,7 +1171,7 @@
                 goto DO_FLONUM;
             }
             if (SCM_NULLP(args)) return SCM_CAR(divrem);
-            return Scm_Divide(divrem, SCM_CAR(args), SCM_CDR(args));
+            return Scm_Divide(SCM_CAR(divrem), SCM_CAR(args), SCM_CDR(args));
         }
         if (SCM_FLONUMP(arg1)) {
             exact = FALSE;

quote内のvectorの展開(0.8)

quote内のvectorにidentifierが含まれると位置がずれます

gosh> (define-syntax foo (syntax-rules () ((_) '#(a b))))
#<syntax foo>
gosh> (foo)
#(b #<class <pair>>)

以下の修正でなおると思います。--teranishi (2004/05/28 15:58:56 PDT)

--- Gauche-0.8.orig/src/compile.c       Fri May 21 20:40:21 2004
+++ Gauche-0.8/src/compile.c    Sat May 29 07:44:07 2004
@@ -773,7 +773,7 @@
                     SCM_VECTOR_ELEMENT(newvec, j) = *pelt;
                 }
                 SCM_VECTOR_ELEMENT(newvec, i) = elt;
-                for (pelt++; j<len; j++, pelt++) {
+                for (; j<len; j++, pelt++) {
                     SCM_VECTOR_ELEMENT(newvec, j) = unwrap_identifier(*pelt);
                 }
                 return newvec;

defineと内部define (0.7.4.2とか0.8とか)

2004/05/25 02:41:54 PDT

(define (a)
  1
  (define b #f))

だとエラーにならないのに

(define (a)
  (+ 1)
  (define b #f))

だとエラーになるのは,最適化とかの絡みかしら. - kou

Shiro(2004/05/25 03:24:14 PDT): ああそうか。本当は上もエラーにすべきですね。 今は、値が使われないリテラルが最適化で捨てられているため、 その次のdefineが内部defineとされてしまってるんだと思います。

Shiro(2004/07/13 14:16:15 PDT): 直しました。

SRFI-13 の string-take-right, string-drop-right の例 (0.8)

2004/05/23 20:11:58 PDT

modsrfi.texi で

(string-take-right "abcde" 2) => "cde"
(string-drop-right "abcde" 2) => "ab"

になっていますが

(string-take-right "abcde" 2) => "de"
(string-drop-right "abcde" 2) => "abc"

ではないでしょうか。

macroexpandを実行してもマクロがautoloadされない(0.7.4.1, 0.8)

gosh起動直後に (macroexpand '(push! x 1)) を実行しても展開されません。--teranishi (2004/05/19 03:43:18 PDT)

More ...