diff options
author | Yukihiro Matsumoto <matz@ruby-lang.org> | 1994-08-10 15:54:46 +0900 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2019-08-17 22:09:30 +0900 |
commit | 6e3090413652b6592346556149fed1e9aec5495d (patch) | |
tree | bac97139bbeedc8cb67cb2e451a22ed4ddb2b2d4 | |
parent | 200e0ee2fd3c1c006c528874a88f684447215524 (diff) | |
download | ruby-6e3090413652b6592346556149fed1e9aec5495d.tar.gz |
version 0.50v0_50
http://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.50.tar.gz
Wed Aug 10 15:54:46 1994 Yukihiro Matsumoto (matz@ix-02)
* variable.c: -vオプションが指定されている時は初期化されていない,
大域変数, インスタンス変数, ローカル変数を参照した時点でwarning
を出すようにした.
Tue Aug 9 11:50:48 1994 Yukihiro Matsumoto (matz@ix-02)
* bignum.c: 冪乗に関しても多倍長演算を行なうように. 特に浮動小数点
数の範囲を越えた時の処理を的確に行なうように.
* eval.c: メソッド定義後は構文木から, メソッド定義部分を外す. 無駄
な再定義が起こらないようにするためと2重にfree()されないため.
* array.c(Fary_aref): 引数が1つでFixnumの時, Range checkを行なわな
いように修正.
* eval.c: 引数の数をコンパイル時に計算して若干の高速化.
Mon Aug 8 13:06:24 1994 Yukihiro Matsumoto (matz@ix-02)
* object.c: nilによる比較連鎖をなくした.
* parse.y: bit演算子の優先順位を比較演算子よりも強くした. Cとは異
なることになるが, 直観には合致する.
* gc.c: クラスを解放する時, 個々のメソッド毎にキャッシュをクリアす
るのではなく, クラス単位でクリアするように.
Thu Aug 4 18:45:09 1994 Yukihiro Matsumoto (matz@ix-02)
* methods.c(method_free): 解放されたメソッドに関してキャッシュをク
リアしておく必要があった.
* gc.c: Dataクラスのデータ部分をfree()し忘れていた.
Wed Aug 3 09:58:14 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y: def func .. end形式による関数メソッドの定義はなくなった.
* methods.c: func形式のメソッドをなくした. あっても, あまり意味が
ないので.
* eval.c: $0への代入でps(1)の出力が変化するように.
* io.c(Fsyscall): syscall()を実現.
Mon Aug 1 13:41:11 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y: ダブルクォートで囲まれた文字列や正規表現中で"#{変数名}"
または"#変数名"という形式で変数の内容を埋め込むことができるよう
になった.
* io.c: 関数メソッドsystem2()はなくなった. 今はバッククォートがあ
るからね.
* parse.y: `cmd`によってコマンドを文字列に展開することができるよう
になった.
* parse.y: __FILE__, __LINE__を追加. それぞれファイル名(文字列),
行番号(整数)を値とする疑似変数.
Fri Jul 29 13:16:07 1994 Yukihiro Matsumoto (matz@ix-02)
* methods.h: メソッドをオブジェクトとして扱うのをやめる. メソッド
のメモリ管理にはリファレンスカウントを使うことにした. これでオブ
ジェクトの数が減ってほんの少しだけGCが速くなる(かな).
* purifyによってメモリ関係のバグを検査した(見つかる,見つかる…).
* gc.c: GCをプログラマが変数をマークする形式から, スタックとレジス
タからマークする方法に変更. 移植性が下がるような気もするが, siod
やscmでも採用されているから多分大丈夫だろう. Linux on i486でも動
作を確認した.
Wed Jul 27 16:13:13 1994 Yukihiro Matsumoto (matz@ix-02)
* eval.c(Eval): トップレベルでは構造木をfreeしないように. どうせ解
放されるから時間の無駄である.
* array.c, dict.c: "=="を構造一致に変更.
Fri Jul 22 10:14:09 1994 Yukihiro Matsumoto (matz@ix-02)
* error.c: 組み込みタイプの名前を登録し忘れていた.
Thu Jul 21 14:06:48 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y(freenode),eval.c(Eval): 解析木を解放し忘れていた.
Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y: 多重代入を処理するルールにバグがあって, 3要素以上の多重
代入に失敗していた.
* eval.c(rb_eval): 多重代入で, 右辺が配列でない時には`to_a'メソッ
ドで配列に変換して代入するようにした. 今までの仕様だと右辺値が第
1要素にそのまま代入されていたが, structなど配列に変換できるもの
は変換した方が嬉しい気がする.
* dbm.c,dict.c(delete_if): メソッド追加.
* process.c(wait,waitpid): システムコールwaitpidまたはwait4がある
時はそちらを使うように. configureもそれらをチェックするように変更.
* dbm.c, dict.c(clear): メソッド追加.
-rw-r--r-- | C-IF | 181 | ||||
-rw-r--r-- | CVS/Entries | 51 | ||||
-rw-r--r-- | CVS/Repository | 1 | ||||
-rw-r--r-- | ChangeLog | 131 | ||||
-rw-r--r-- | Makefile | 206 | ||||
-rw-r--r-- | Makefile.in | 10 | ||||
-rw-r--r-- | README | 51 | ||||
-rw-r--r-- | ToDo | 2 | ||||
-rw-r--r-- | array.c | 51 | ||||
-rw-r--r-- | bignum.c | 107 | ||||
-rw-r--r-- | bring | 57 | ||||
-rw-r--r-- | class.c | 61 | ||||
-rwxr-xr-x | config.status | 72 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | dbm.c | 25 | ||||
-rw-r--r-- | defines.h | 4 | ||||
-rw-r--r-- | dict.c | 87 | ||||
-rw-r--r-- | dir.c | 13 | ||||
-rw-r--r-- | enum.c | 43 | ||||
-rw-r--r-- | error.c | 3 | ||||
-rw-r--r-- | etc.c | 76 | ||||
-rw-r--r-- | eval.c | 257 | ||||
-rw-r--r-- | file.c | 26 | ||||
-rw-r--r-- | gc.c | 522 | ||||
-rw-r--r-- | io.c | 166 | ||||
-rw-r--r-- | math.c | 3 | ||||
-rw-r--r-- | methods.c | 59 | ||||
-rw-r--r-- | methods.h | 22 | ||||
-rw-r--r-- | missing/strftime.c | 4 | ||||
-rwxr-xr-x | newver.rb | 2 | ||||
-rw-r--r-- | node.h | 13 | ||||
-rw-r--r-- | numeric.c | 58 | ||||
-rw-r--r-- | object.c | 36 | ||||
-rw-r--r-- | pack.c | 9 | ||||
-rw-r--r-- | parse.y | 388 | ||||
-rw-r--r-- | process.c | 27 | ||||
-rw-r--r-- | random.c | 4 | ||||
-rw-r--r-- | range.c | 8 | ||||
-rw-r--r-- | re.c | 18 | ||||
-rw-r--r-- | regex.c | 2 | ||||
-rw-r--r-- | ruby.1 | 22 | ||||
-rw-r--r-- | ruby.c | 28 | ||||
-rw-r--r-- | ruby.h | 52 | ||||
-rw-r--r-- | sample/cbreak.rb | 6 | ||||
-rw-r--r-- | sample/fullpath.rb | 1 | ||||
-rw-r--r-- | sample/gctest.rb | 3 | ||||
-rwxr-xr-x | sample/getopts.test | 4 | ||||
-rw-r--r-- | sample/newver.rb | 13 | ||||
-rw-r--r-- | sample/opt_s.rb | 4 | ||||
-rw-r--r-- | sample/rcs.rb | 2 | ||||
-rw-r--r-- | sample/ruby-mode.el | 296 | ||||
-rw-r--r-- | sample/system.rb | 2 | ||||
-rw-r--r-- | sample/t1.rb | 8 | ||||
-rw-r--r-- | sample/trojan.pl | 12 | ||||
-rw-r--r-- | sample/trojan.rb | 12 | ||||
-rw-r--r-- | socket.c | 53 | ||||
-rw-r--r-- | spec | 192 | ||||
-rw-r--r-- | sprintf.c | 9 | ||||
-rw-r--r-- | string.c | 25 | ||||
-rw-r--r-- | struct.c | 23 | ||||
-rw-r--r-- | time.c | 34 | ||||
-rw-r--r-- | variable.c | 15 | ||||
-rw-r--r-- | version.h | 4 |
63 files changed, 1998 insertions, 1682 deletions
@@ -2,131 +2,164 @@ Ruby-C ե -VALUE + - Ruby֥Ȥɽ뷿. ɬפ˱ƥ㥹ȤѤ. + VALUE -Qnil + Ruby֥Ȥɽ뷿. ɬפ˱ƥ㥹ȤѤ. Ȥ + ߷ɽCηruby.h˵ҤƤRǻϤޤ빽¤ΤǤ. + VALUE˥㥹Ȥ뤿RǻϤޤ빽¤̾ʸ + ̾ΥޥѰդƤ. - : nil֥ +ѿ -Qself + Qnil - ѿ: ߤself֥Ȥ. ѿͤѹϰʸ - selfͤΤΤѤäƤޤΤ, Ť˹Ԥʤ. + : nil֥ -VALUE rb_define_class(char *name, VALUE super) + Qself - Ruby饹. + ѿ: ߤself֥Ȥ. ̤˥åɤˤselfؤ + ͿΤ, ѿ˥ɬפϤʤ. ѿͤ + ѹϰʸselfͤΤΤѤäƤޤΤ, Ť˹Ԥ + . -VALUE rb_define_module(char *name) +饹⥸塼 - Ruby⥸塼. + VALUE rb_define_class(char *name, VALUE super) -rb_include_module(VALUE class, VALUE module) + superΥ֥饹ȤƿRuby饹. - ⥸塼롼ɤ. classǤmodule롼ɤƤ - ˤϲ⤷ʤ(¿ť롼ɤζػ). + VALUE rb_define_module(char *name) -void rb_define_variable(char *name, VALUE *var, - VALUE (*get_hook), VALUE (*set+hook)()) + Ruby⥸塼. - RubyCȤǶͭ륰Хѿ. Ruby֥Ȥؤ - ѿƤδؿˤäʤФʤʤ(GCݸ뤿 - ). get_hookQnilǤʤ, ѿȤκݤget_hook˥åȤ줿ؿ - ƤФ. set_hookQnilǤʤˤλset_hookƤФ. + void rb_include_module(VALUE class, VALUE module) - ѿ̾`$'ǻϤޤʤˤϼưŪɲä. ѿ̾Ȥrubyμ - ̻ҤȤƵʤʸ(㤨` ')ޤˤrubyץफ饢 - Ǥʤʤ. + ⥸塼롼ɤ. classǤmodule롼ɤ + ˤϲ⤷ʤ(¿ť롼ɤζػ). -void rb_global_variable(VALUE *var) +ѿ - GCRubyϥʤ, Ruby֥Ȥޤѿޡ - . + void rb_define_variable(char *name, VALUE *var, + VALUE (*get_hook), VALUE (*set_hook)()) -void rb_read_only_hook() + RubyCȤǶͭ륰Хѿ. get_hookQnilǤʤ, + ѿȤκݤget_hook˥åȤ줿ؿƤФ. set_hookQnil + Ǥʤˤλset_hookƤФ. - ɤ߽ФѤѿΤset_hookؿ. + ѿ̾`$'ǻϤޤʤˤϼưŪɲä. ѿ̾Ȥruby + ̻ҤȤƵʤʸ(㤨` ')ޤˤrubyץफ + 饢Ǥʤʤ. -rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) + void rb_global_variable(VALUE *var) - åɤ. argc-1λ, argc, argvͿ. + GCRubyϥʤ, Ruby֥Ȥޤѿ + ޡ. -rb_define_single_method(VALUE class, char *name, VALUE (*func)(), int argc) + void rb_read_only_hook() - ðۥåɤ. rb_define_method()Ʊ. + ɤ߽ФѤѿΤset_hookؿ. ͤꤷ褦Ȥ㳰 + ȯ. -ID rb_intern(char *name) +饹 - ʸбID֤. + void rb_define_const(VALUE class, char *name, VALUE val) -char *rb_id2name(ID id) + 饹. - IDбʸ֤(ǥХå). +å -VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) + rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) - åɸƤӽФ. ʸmid뤿ˤrb_intern()Ȥ. + åɤ. argcselfο. argc-1λ, + argc, argvͿ. argc-2λ, self, args(args + ޤruby)ȤͿ. -rb_iv_get(VALUE obj, char *name) + rb_define_single_method(VALUE class, char *name, VALUE (*func)(), int argc) - objΥѿ. @ϤޤʤѿRuby - फ饢Ǥʤ. + ðۥåɤ. rb_define_method()Ʊ. -rb_iv_set(VALUE obj, char *name, VALUE val) + rb_scan_args(VALUE args, char *fmt, ...) - objΥѿval˥åȤ. + argsͿ줿ʬ. fmtɬܰο, ղðο, + Ĥΰ뤫ꤹʸ, "*"ȤǤ. + 2 ܤο"*"ϾάǽǤ. 3ʹߤѿؤΥݥ, + Ǥѿ˳Ǽ. ղðͿʤ + Qnil. -rb_call_super(VALUE args) +RubyåɸƤӽФ - ѡ饹ΥåɤƤӽФ. argsϰꥹȤȤʤ. args - QnilλϰΤޤްѤ. + VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) -rb_iterate(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + åɸƤӽФ. ʸmid뤿ˤrb_intern()Ȥ. - func2֥åȤꤷ, func1ƥ졼ȤƸƤ. func1ˤ - arg1ȤϤ, func2ˤ1˥ƥ졼ȤͿ줿 - , 2arg2Ϥ. - -rb_yield(VALUE val) + rb_call_super(VALUE args) + + ѡ饹ΥåɤƤӽФ. argsϰꥹȤȤʤ. + args QnilλϸߤΥåɤΰΤޤްѤ. + +ʸ <-> IDѴ + + ID rb_intern(char *name) + + ʸбID֤. + + char *rb_id2name(ID id) + + IDбʸ֤(ǥХå). - valͤȤƥƥ졼֥åƤӽФ. +ѿ -rb_resque(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + VALUE rb_iv_get(VALUE obj, char *name) - ؿfunc1arg1˸ƤӽФ. func1μ¹㳰ȯˤ - func2arg2ȤƸƤ. ͤ㳰ȯʤäfunc1 - , 㳰ȯˤfunc2ͤǤ. + objΥѿͤ. `@'ǻϤޤʤѿ + Rubyץफ饢Ǥʤ. + + VALUE rb_iv_set(VALUE obj, char *name, VALUE val) + + objΥѿval˥åȤ. + +湽¤ + + VALUE rb_iterate(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + + func2֥åȤꤷ, func1ƥ졼ȤƸƤ. func1 + arg1ȤϤ, func2ˤ1˥ƥ졼ȤͿ + 줿, 2arg2Ϥ. + + VALUE rb_yield(VALUE val) -rb_ensure(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) + valͤȤƥƥ졼֥åƤӽФ. - ؿfunc1arg1ȤƼ¹Ԥ, ¹Խλ(Ȥ㳰ȯƤ) - func2arg2ȤƼ¹Ԥ. ͤfunc1ͤǤ(㳰ȯ - nil). + VALUE rb_resque(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) -GC_LINK + ؿfunc1arg1˸ƤӽФ. func1μ¹㳰ȯ + func2arg2ȤƸƤ. ͤ㳰ȯʤä + func1, 㳰ȯˤfunc2ͤǤ. - ѿGCݸԤʤ. + VALUE rb_ensure(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2) -GC_PRO(var) + ؿfunc1arg1ȤƼ¹Ԥ, ¹Խλ(Ȥ㳰ȯ + ) func2arg2ȤƼ¹Ԥ. ͤfunc1ͤǤ( + ȯnil). - ѿGCݸ. ѿݸƤʤǽ - Ruby֥ȤؤƤˤGC_PRO()Ȥäݸɬפ - . GC_PRO()ݸѿɬƤɬפ(̤ - ΥߤäƤGC). +㳰顼 -GC_PRO2(var) + void Fail(char *fmt, ...) - GCݸ, varnilǽ뤳ȰʳGC_PRO(var)Ʊ. + 㳰ȯ. printf()Ʊ. -GC_PRO2(var, init) + void Fatal(char *fmt, ...) - GCݸ, varinit˽뤳ȰʳGC_PRO(var)Ʊ. + ̿Ū㳰ȯ. ̾㳰ϹԤʤ줺, ץ + λ(ensureǻꤵ줿ɤϽλ˼¹Ԥ). -GC_UNLINK + void Bug(char *fmt, ...) - GCݸλ. + ץʤɥץΥХǤȯϤΤʤλ + Ƥ. ץϥפľ˽λ. 㳰ϰڹ + ʤʤ. /* * Local variables: diff --git a/CVS/Entries b/CVS/Entries deleted file mode 100644 index 067e16dd65..0000000000 --- a/CVS/Entries +++ /dev/null @@ -1,51 +0,0 @@ -/autoexec.c/0.15/Wed Jun 1 23:40:54 1994 Thu Mar 17 18:49:43 1994// -/class.c/0.22/Wed Jun 1 23:40:54 1994 Fri Mar 25 13:12:36 1994// -/compar.c/0.15/Wed Jun 1 23:40:54 1994 Thu Mar 17 18:49:43 1994// -/dln.h/0.14/Wed Jun 1 23:40:57 1994 Thu Mar 17 15:55:00 1994// -/error.c/0.15/Wed Jun 1 23:40:57 1994 Thu Mar 17 18:49:43 1994// -/etc.c/0.22/Wed Jun 1 23:40:58 1994 Fri Mar 25 13:12:36 1994// -/ident.h/0.17/Wed Jun 1 23:41:00 1994 Wed May 25 00:56:16 1994// -/inits.c/0.27/Wed Jun 1 23:41:00 1994 Mon Apr 25 23:30:29 1994// -/io.h/0.14/Wed Jun 1 23:41:01 1994 Thu Mar 17 15:55:00 1994// -/methods.c/0.20/Wed Jun 1 23:41:01 1994 Tue Mar 22 16:58:31 1994// -/missing.c/0.29/Wed Jun 1 23:41:01 1994 Wed Jun 1 23:36:26 1994// -/parse.y/0.35/Wed Jun 1 23:41:08 1994 Wed Jun 1 23:36:30 1994// -/random.c/0.15/Wed Jun 1 23:41:09 1994 Thu Mar 17 18:49:43 1994// -/range.c/0.15/Wed Jun 1 23:41:09 1994 Thu Mar 17 18:49:43 1994// -/re.h/0.15/Wed Jun 1 23:41:10 1994 Thu May 26 00:41:30 1994// -/regex.c/0.15/Wed Jun 1 23:41:12 1994 Wed Jun 1 23:36:35 1994// -/regex.h/0.14/Wed Jun 1 23:41:12 1994 Thu Mar 17 15:55:00 1994// -/st.h/0.14/Wed Jun 1 23:41:14 1994 Thu Mar 17 15:55:00 1994// -/variable.c/0.29/Wed Jun 1 23:41:16 1994 Wed May 25 00:56:35 1994// -/version.c/0.27/Wed Jun 1 23:41:16 1994 Mon Apr 25 23:30:35 1994// -/Makefile/0.32/Fri Jun 3 00:15:00 1994 Fri Jun 3 00:15:00 1994// -/Makefile.in/1.3/Fri Jun 3 00:15:01 1994 Fri Jun 3 00:15:01 1994// -/array.c/0.29/Fri Jun 3 00:15:02 1994 Fri Jun 3 00:15:02 1994// -/configure/1.3/Fri Jun 3 00:15:04 1994 Fri Jun 3 00:15:03 1994// -/configure.in/1.3/Fri Jun 3 00:15:04 1994 Fri Jun 3 00:15:04 1994// -/dbm.c/0.28/Fri Jun 3 00:15:05 1994 Fri Jun 3 00:15:05 1994// -/defines.h/1.4/Fri Jun 3 00:15:06 1994 Fri Jun 3 00:15:06 1994// -/dict.c/0.28/Fri Jun 3 00:15:06 1994 Fri Jun 3 00:15:06 1994// -/dir.c/0.18/Fri Jun 3 00:15:07 1994 Fri Jun 3 00:15:07 1994// -/dln.c/0.29/Fri Jun 3 00:15:08 1994 Fri Jun 3 00:15:08 1994// -/enum.c/0.16/Fri Jun 3 00:15:09 1994 Fri Jun 3 00:15:08 1994// -/eval.c/0.35/Fri Jun 3 00:15:10 1994 Fri Jun 3 00:15:09 1994// -/file.c/0.29/Fri Jun 3 00:15:11 1994 Fri Jun 3 00:15:11 1994// -/gc.c/0.30/Fri Jun 3 00:15:12 1994 Fri Jun 3 00:15:12 1994// -/io.c/0.29/Fri Jun 3 00:15:13 1994 Fri Jun 3 00:15:13 1994// -/math.c/0.28/Fri Jun 3 00:15:14 1994 Fri Jun 3 00:15:14 1994// -/node.h/0.32/Fri Jun 3 00:15:15 1994 Fri Jun 3 00:15:14 1994// -/numeric.c/0.19/Fri Jun 3 00:15:15 1994 Fri Jun 3 00:15:15 1994// -/object.c/0.32/Fri Jun 3 00:15:16 1994 Fri Jun 3 00:15:16 1994// -/pack.c/0.18/Fri Jun 3 00:15:17 1994 Fri Jun 3 00:15:17 1994// -/process.c/0.30/Fri Jun 3 00:15:18 1994 Fri Jun 3 00:15:17 1994// -/re.c/0.32/Fri Jun 3 00:15:19 1994 Fri Jun 3 00:15:18 1994// -/ruby.c/0.34/Fri Jun 3 00:15:19 1994 Fri Jun 3 00:15:19 1994// -/ruby.h/0.30/Fri Jun 3 00:15:20 1994 Fri Jun 3 00:15:20 1994// -/socket.c/0.27/Fri Jun 3 00:15:21 1994 Fri Jun 3 00:15:21 1994// -/sprintf.c/0.23/Fri Jun 3 00:15:22 1994 Fri Jun 3 00:15:21 1994// -/st.c/0.15/Fri Jun 3 00:15:22 1994 Fri Jun 3 00:15:22 1994// -/string.c/0.29/Fri Jun 3 00:15:23 1994 Fri Jun 3 00:15:23 1994// -/struct.c/0.26/Fri Jun 3 00:15:25 1994 Fri Jun 3 00:15:24 1994// -/time.c/0.29/Fri Jun 3 00:15:26 1994 Fri Jun 3 00:15:26 1994// -/version.h/1.7/Fri Jun 3 00:15:27 1994 Fri Jun 3 00:15:27 1994// diff --git a/CVS/Repository b/CVS/Repository deleted file mode 100644 index b98482fac9..0000000000 --- a/CVS/Repository +++ /dev/null @@ -1 +0,0 @@ -/work/cvsroot/ruby @@ -1,3 +1,110 @@ +Wed Aug 10 15:54:46 1994 Yukihiro Matsumoto (matz@ix-02) + + * variable.c: -vץꤵƤϽƤʤ, + ѿ, ѿ, ѿȤwarning + Ф褦ˤ. + +Tue Aug 9 11:50:48 1994 Yukihiro Matsumoto (matz@ix-02) + + * bignum.c: Ѿ˴ؤƤ¿Ĺ黻Ԥʤ褦. äư + ϰϤۤνŪΤ˹Ԥʤ褦. + + * eval.c: åϹʸڤ, åʬ. ̵ + ʺʤ褦ˤ뤿2Ťfree()ʤ. + + * array.c(Fary_aref): 1ĤFixnumλ, Range checkԤʤ + 褦˽. + + * eval.c: οѥ˷Ƽ㴳ι®. + +Mon Aug 8 13:06:24 1994 Yukihiro Matsumoto (matz@ix-02) + + * object.c: nilˤϢʤ. + + * parse.y: bit黻Ҥ̤ͥӱ黻Ҥ. CȤϰ + ʤ뤳Ȥˤʤ뤬, ľѤˤϹפ. + + * gc.c: 饹, ġΥå˥åꥢ + ΤǤϤʤ, 饹ñ̤ǥꥢ褦. + +Thu Aug 4 18:45:09 1994 Yukihiro Matsumoto (matz@ix-02) + + * methods.c(method_free): 줿åɤ˴ؤƥå + ꥢƤɬפä. + + * gc.c: Data饹Υǡʬfree()˺Ƥ. + +Wed Aug 3 09:58:14 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: def func .. endˤؿåɤϤʤʤä. + + * methods.c: funcΥåɤʤ. äƤ, ޤ̣ + ʤΤ. + + * eval.c: $0ؤps(1)νϤѲ褦. + + * io.c(Fsyscall): syscall()¸. + +Mon Aug 1 13:41:11 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: ֥륯ȤǰϤޤ줿ʸɽ"#{ѿ̾}" + ޤ"#ѿ̾"ȤѿƤळȤǤ褦 + ˤʤä. + + * io.c: ؿåsystem2()Ϥʤʤä. ϥХåȤ + 뤫. + + * parse.y: `cmd`ˤäƥޥɤʸŸ뤳ȤǤ褦 + ˤʤä. + + * parse.y: __FILE__, __LINE__ɲ. 줾ե̾(ʸ), + ֹ()ͤȤ뵿ѿ. + +Fri Jul 29 13:16:07 1994 Yukihiro Matsumoto (matz@ix-02) + + * methods.h: åɤ֥ȤȤưΤ. å + ΥˤϥեȤȤȤˤ. ǥ + ȤοäƤۤξGC®ʤ(). + + * purifyˤäƥطΥХ(Ĥ,Ĥ). + + * gc.c: GCץޤѿޡ, åȥ쥸 + ޡˡѹ. ܿ褦ʵ⤹뤬, siod + scmǤѤƤ뤫¿ʬפ. Linux on i486Ǥư + ǧ. + +Wed Jul 27 16:13:13 1994 Yukihiro Matsumoto (matz@ix-02) + + * eval.c(Eval): ȥåץ٥ǤϹ¤ڤfreeʤ褦. ɤ + 뤫̵֤̤Ǥ. + + * array.c, dict.c: "=="¤פѹ. + +Fri Jul 22 10:14:09 1994 Yukihiro Matsumoto (matz@ix-02) + + * error.c: Ȥ߹ߥפ̾Ͽ˺Ƥ. + +Thu Jul 21 14:06:48 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y(freenode),eval.c(Eval): ڤ˺Ƥ. + +Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: ¿롼˥Хä, 3ǰʾ¿ + ˼ԤƤ. + + * eval.c(rb_eval): ¿, դǤʤˤ`to_a' + ɤѴ褦ˤ. ޤǤλͤȱͤ + 1ǤˤΤޤƤ, structʤѴǤ + Ѵ. + + * dbm.c,dict.c(delete_if): åɲ. + + * process.c(wait,waitpid): ƥॳwaitpidޤwait4 + ϤȤ褦. configure⤽å褦ѹ. + + * dbm.c, dict.c(clear): åɲ. + Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y: ¿롼˥Хä, 3ǰʾ¿ @@ -34,27 +141,6 @@ Fri Jul 15 10:54:45 1994 Yukihiro Matsumoto (matz@ix-02) Thu Jul 14 11:18:07 1994 Yukihiro Matsumoto (matz@ix-02) - * autoexec.c: . autoloadطεǽϺ帡Ƥ褦. - - * dict.c: 饹̾ΤDictѹ. ̾ȤHash - դ. ޤDictionaryʤɤĹ̾ˤƤïȤäƤ - ä. *BACKWARD INCOMPATIBILITY* - - * parse.y: Dict빽ʸɲ. {..}ˤ. - - * parse.y: 빽ʸ[..]ѹ. Ruby - ȤȤθߴݤƤʤ, Dict빽ʸƳ, - perl5˹碌(ռ), ѹϺʤȹͤ. - *BACKWARD INCOMPATIBILITY* - - * eval.c(Feval): eval()ǥåɤ, 륯饹 - åɤν°륯饹ˤ. ޤǤObject饹 - . - - * parse.y: ʤeval()Ƥ. - -Thu Jul 14 11:18:07 1994 Yukihiro Matsumoto (matz@ix-02) - * eval.c: åɤ¸ߤʤˤKernel:_undefined(id)ƤФ 褦. , rubyǤϸġΥåν, 饹 ñ̤νɬפʵ⤹ʤ. @@ -511,9 +597,6 @@ Sat May 28 23:08:18 1994 Yukihiro Matsumoto (matz@dyna) Fri May 27 11:42:00 1994 Yukihiro Matsumoto (matz@ix-02) - * ɽʸɤΥǥեȤбˤ. ˤä - 㴳ι®ޤ. - * trʸ(delete), ʸ(squeeze)ʬΥ. ˤȤ ʤtrΥץϤʤʤä. @@ -1,202 +1,6 @@ -# Generated automatically from Makefile.in by configure. -# Main Makefile for GNU m4. -# Copyright (C) 1992 Free Software Foundation, Inc. +# +# Makefile - +# +# created at: Wed Aug 10 15:21:29 JST 1994 -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -SHELL = /bin/sh - -#### Start of system configuration section. #### - -srcdir = . -VPATH = . - -CC = gcc -traditional -DBM = -fpcc-struct-return -YACC = bison -y -INSTALL = /usr/bin/install -c -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 -MAKEINFO = makeinfo - -CFLAGS = -g -LDFLAGS = -static $(CFLAGS) -LIBS = -lm -ldbm -DEFS = -DHAVE_UNISTD_H=1 -DHAVE_SYSCALL_H=1 -DHAVE_A_OUT_H=1 -DDIRENT=1 -DGETGROUPS_T=int -DRETSIGTYPE=void -DHAVE_STRTOL=1 -DHAVE_STRDUP=1 -DHAVE_KILLPG=1 -DHAVE_MKDIR=1 -DHAVE_STRFTIME=1 -DHAVE_PUTENV=1 -DHAVE_ALLOCA_H=1 -DPW_AGE=1 -DPW_COMMENT=1 - -prefix = /usr/local -binprefix = -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin -infodir = $(prefix)/info - -#### End of system configuration section. #### - -.c.o: - $(CC) -c $(CFLAGS) $(CPPFLAGS) $(DEFS) -I$(srcdir) -I$(srcdir)/lib $< - -HDRS = defines.h \ - dln.h \ - ident.h \ - io.h \ - node.h \ - re.h \ - regex.h \ - ruby.h \ - st.h \ - version.h - -SRCS = array.c \ - autoexec.c \ - class.c \ - compar.c \ - dbm.c \ - dict.c \ - dir.c \ - dln.c \ - enum.c \ - error.c \ - etc.c \ - eval.c \ - file.c \ - gc.c \ - inits.c \ - io.c \ - math.c \ - methods.c \ - missing.c \ - numeric.c \ - object.c \ - pack.c \ - parse.y \ - process.c \ - random.c \ - range.c \ - re.c \ - regex.c \ - ruby.c \ - socket.c \ - sprintf.c \ - st.c \ - string.c \ - struct.c \ - time.c \ - variable.c \ - version.c - -OBJS = array.o \ - autoexec.o \ - class.o \ - compar.o \ - dbm.o \ - dict.o \ - dir.o \ - dln.o \ - enum.o \ - error.o \ - etc.o \ - eval.o \ - file.o \ - gc.o \ - inits.o \ - io.o \ - math.o \ - methods.o \ - missing.o \ - numeric.o \ - object.o \ - pack.o \ - parse.o \ - process.o \ - random.o \ - range.o \ - re.o \ - regex.o \ - ruby.o \ - socket.o \ - sprintf.o \ - st.o \ - string.o \ - struct.o \ - time.o \ - variable.o \ - version.o - -DISTFILES = README NEWS TODO THANKS COPYING INSTALL \ -ChangeLog Makefile.in configure.in \ -$(HDRS) $(SRCS) configure - -PROGRAM = ruby - -all: $(PROGRAM) - -$(PROGRAM): $(OBJS) - @echo -n "Loading $(PROGRAM) ... " - @rm -f $(PROGRAM) - @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) - @echo "done" - -install: $(PROGMAM) - $(INSTALL_PROGRAM) $(PROGRAM) $(bindir)/$(PROGRAM) - -clean:; @rm -f $(OBJS) - -realclean:; @rm -f $(OBJS) - @rm -f core ruby *~ - -dbm.o:dbm.c - $(CC) -c $(DBM) $(CFLAGS) $(CPPFLAGS) $(DEFS) -I$(srcdir) -I$(srcdir)/lib dbm.c - -# Prevent GNU make v3 from overflowing arg limit on SysV. -.NOEXPORT: -### -array.o : array.c ruby.h defines.h -autoexec.o : autoexec.c ruby.h defines.h -class.o : class.c ruby.h defines.h node.h st.h -compar.o : compar.c ruby.h defines.h -dbm.o : dbm.c ruby.h defines.h -dict.o : dict.c ruby.h defines.h st.h -dir.o : dir.c ruby.h defines.h -dln.o : dln.c defines.h dln.h -enum.o : enum.c ruby.h defines.h -error.o : error.c ruby.h defines.h -etc.o : etc.c ruby.h defines.h -eval.o : eval.c ruby.h defines.h node.h ident.h st.h -file.o : file.c ruby.h defines.h io.h -gc.o : gc.c ruby.h defines.h st.h -inits.o : inits.c -io.o : io.c ruby.h defines.h io.h -math.o : math.c ruby.h defines.h -methods.o : methods.c ruby.h defines.h node.h -missing.o : missing.c ruby.h defines.h missing/memmove.c missing/strerror.c \ - missing/strtoul.c missing/strftime.c missing/getopt.h missing/getopt.c missing/getopt1.c -numeric.o : numeric.c ruby.h defines.h -object.o : object.c ruby.h defines.h -pack.o : pack.c ruby.h defines.h -process.o : process.c ruby.h defines.h st.h -random.o : random.c ruby.h defines.h -range.o : range.c ruby.h defines.h -re.o : re.c ruby.h defines.h re.h regex.h -regex.o : regex.c regex.h -ruby.o : ruby.c ruby.h defines.h re.h regex.h missing/getopt.h -socket.o : socket.c ruby.h defines.h io.h -sprintf.o : sprintf.c ruby.h defines.h -st.o : st.c st.h -string.o : string.c ruby.h defines.h re.h regex.h -struct.o : struct.c ruby.h defines.h -time.o : time.c ruby.h defines.h -variable.o : variable.c ruby.h defines.h st.h ident.h -version.o : version.c ruby.h defines.h \ - version.h +all:; @echo "You must run configure first." diff --git a/Makefile.in b/Makefile.in index 33338c9e61..66b3689260 100644 --- a/Makefile.in +++ b/Makefile.in @@ -125,10 +125,8 @@ PROGRAM = ruby all: $(PROGRAM) $(PROGRAM): $(OBJS) - @echo -n "Loading $(PROGRAM) ... " @rm -f $(PROGRAM) - @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) - @echo "done" + $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) install: $(PROGMAM) $(INSTALL_PROGRAM) $(PROGRAM) $(bindir)/$(PROGRAM) @@ -148,7 +146,7 @@ parse.o : parse.y ruby.h defines.h env.h ident.h node.h st.h regex.h ### array.o : array.c ruby.h defines.h bignum.o : bignum.c ruby.h defines.h -class.o : class.c ruby.h defines.h env.h node.h st.h +class.o : class.c ruby.h defines.h env.h node.h st.h methods.h compar.o : compar.c ruby.h defines.h dbm.o : dbm.c ruby.h defines.h dict.o : dict.c ruby.h defines.h st.h @@ -160,10 +158,10 @@ etc.o : etc.c ruby.h defines.h eval.o : eval.c ruby.h defines.h env.h node.h ident.h st.h file.o : file.c ruby.h defines.h io.h gc.o : gc.c ruby.h defines.h env.h st.h -inits.o : inits.c +inits.o : inits.c ruby.h defines.h io.o : io.c ruby.h defines.h io.h math.o : math.c ruby.h defines.h -methods.o : methods.c ruby.h defines.h env.h node.h +methods.o : methods.c ruby.h defines.h ident.h env.h node.h methods.h missing.o : missing.c ruby.h defines.h missing/memmove.c missing/strerror.c \ missing/strtoul.c missing/strftime.c missing/strstr.c missing/getopt.h missing/getopt.c \ missing/getopt1.c missing/mkdir.c diff --git a/README b/README new file mode 100644 index 0000000000..3ca523bdde --- /dev/null +++ b/README @@ -0,0 +1,51 @@ +.\" README - -*- Text -*- created at: Wed Aug 3 11:57:36 JST 1994 + +ѥ롦ȡ + + 1. configure¹ԤMakefile. + 2. (ɬפʤ)defines.hԽ. + 3. make¹Ԥƥѥ뤹 + 4. make install + + ⤷, ѥ˥顼ȯˤϥ顼Υȥ + , OSμޤǤܤݡȤԤäƤ + . + +ǽɲ + + CɤȤˤä, ñruby˵ǽɲäǤ. + Τޤʼϰʲ̤Ǥ. + + * ؿŪåɤɲä + + (1) CǴؿ + (2) rb_define_method()ǥͥ륯饹ΥåɤȤƴ + rubyϿؿ + (3) init.cԽ, ϿؿƤӽФ + + * 饹ɲä + + (1) 饹߷פ + (2) åɤCǵҤ + (3) rb_define_class()ǥ饹륳ɤ + (4) rb_define_method()ǥåɤϿ륳ɤ + (5) init.cԽ, ؿƤӽФ + + ܤC-IF. + +ܿ + + UNIXǤconfigureۤȤɤκۤۼƤϤ + , פ̸Ȥä(˰㤤ʤ), Ԥ˥ + ݡȤ, Ǥ뤫Τʤ. + + ƥˤäȤ¸ΤGCǤ. rubyGC + оݤΥƥ㤬setjmp()ˤä, ƤΥ쥸 + jmp_buf˳Ǽ뤳Ȥ, jmp_bufȥå32bit饤 + ȤƤ뤳ȤꤷƤ. Ԥ¤Ǥʤ + ܿϺˤ. Ԥϳȴñ˲Ǥ. gc.c + Υåޡʬ˥饤ȤΥХȿ + 餷ƥޡ륳ɤɲäǺѤ. + + sparcʳΥ쥸ɥCPUǤ, 쥸 + ɥեå夹륳ɤɲäɬפ뤫Τʤ. @@ -1,6 +1,4 @@ -* $0ؤpsνϤѲ褦 * rubyѿhookμ¸ -* FUNCΥåɤɬפ * write debugger for ruby * re-write regex code for speeding * byte code interpretor @@ -24,12 +24,9 @@ ary_new2(len) NEWOBJ(ary, struct RArray); OBJSETUP(ary, C_Array, T_ARRAY); - GC_LINK; - GC_PRO(ary); ary->len = 0; ary->capa = len; ary->ptr = ALLOC_N(VALUE, len); - GC_UNLINK; return (VALUE)ary; } @@ -73,12 +70,9 @@ ary_new4(n, elts) { struct RArray* ary; - GC_LINK; - GC_PRO4(elts, n); ary = (struct RArray*)ary_new2(n); memcpy(ary->ptr, elts, sizeof(VALUE)*n); ary->len = n; - GC_UNLINK; return (VALUE)ary; } @@ -89,13 +83,10 @@ assoc_new(elm1, elm2) { struct RArray *ary; - GC_LINK; - GC_PRO(elm1); GC_PRO(elm2); ary = (struct RArray*)ary_new2(2); ary->ptr[0] = elm1; ary->ptr[1] = elm2; ary->len = 2; - GC_UNLINK; return (VALUE)ary; } @@ -107,12 +98,9 @@ Fary_new(class) NEWOBJ(ary, struct RArray); OBJSETUP(ary, class, T_ARRAY); - GC_LINK; - GC_PRO(ary); ary->len = 0; ary->capa = ARY_DEFAULT_SIZE; ary->ptr = ALLOC_N(VALUE, ARY_DEFAULT_SIZE); - GC_UNLINK; return (VALUE)ary; } @@ -131,10 +119,8 @@ astore(ary, idx, val) max = idx + 1; if (idx >= ary->capa) { - GC_LINK; GC_PRO(val); ary->capa = max; REALLOC_N(ary->ptr, VALUE, max); - GC_UNLINK; } if (idx >= ary->len) { bzero(ary->ptr+ary->len, sizeof(VALUE)*(max-ary->len)); @@ -302,6 +288,11 @@ Fary_aref(ary, args) return ary_subseq(ary, beg, len); } + /* special case - speeding up */ + if (FIXNUM_P(arg1)) { + return ary_entry(ary, NUM2INT(arg1)); + } + /* check if idx is Range */ if (obj_is_kind_of(arg1, C_Range)) { int beg, len; @@ -462,10 +453,6 @@ ary_join(ary, sep) else result = obj_as_string(ary->ptr[0]); - GC_LINK; - GC_PRO(result); - GC_PRO2(tmp); - for (i=1; i<ary->len; i++) { int need_free = 1; tmp = ary->ptr[i]; @@ -484,8 +471,6 @@ ary_join(ary, sep) if (need_free == 1) obj_free(tmp); } - GC_UNLINK; - return result; } @@ -523,15 +508,13 @@ Fary_inspect(ary) char *p; ary = (struct RArray*)Fary_clone(ary); - GC_LINK; - GC_PRO(ary); len = ary->len; for (i=0; i<len; i++) { ary->ptr[i] = rb_funcall(ary->ptr[i], rb_intern("_inspect"), 0, Qnil); } - GC_PRO3(str, str_new2(", ")); + str = str_new2(", "); str = ary_join(ary, str); if (str == Qnil) return str_new2("[]"); len = RSTRING(str)->len; @@ -541,8 +524,6 @@ Fary_inspect(ary) p[0] = '['; p[len+1] = ']'; - GC_UNLINK; - return str; } @@ -699,10 +680,8 @@ Fary_plus(x, y) break; default: - GC_LINK; - GC_PRO3(z, (struct RArray*)Fary_clone(x)); + z = (struct RArray*)Fary_clone(x); Fary_push(z, y); - GC_UNLINK; break; } return (VALUE)z; @@ -761,6 +740,21 @@ Fary_rassoc(ary, value) return Qnil; } +static VALUE +Fary_equal(ary1, ary2) + struct RArray *ary1, *ary2; +{ + int i; + + if (TYPE(ary2) != T_ARRAY) return FALSE; + if (ary1->len != ary2->len) return FALSE; + for (i=0; i<ary1->len; i++) { + if (!rb_funcall(ary1->ptr[i], eq, 1, ary2->ptr[i])) + return FALSE; + } + return TRUE; +} + extern VALUE C_Kernel; extern VALUE M_Enumerable; @@ -774,6 +768,7 @@ Init_Array() rb_define_method(C_Array, "_inspect", Fary_inspect, 0); rb_define_method(C_Array, "to_a", Fary_to_a, 0); + rb_define_method(C_Array, "==", Fary_equal, 1); rb_define_method(C_Array, "[]", Fary_aref, -2); rb_define_method(C_Array, "[]=", Fary_aset, -2); rb_define_method(C_Array, "<<", Fary_append, 1); @@ -10,6 +10,7 @@ #include "ruby.h" #include <ctype.h> +#include <math.h> extern VALUE C_Integer; VALUE C_Bignum; @@ -87,7 +88,10 @@ bignorm(x) while (len-- && !ds[len]) ; x->len = ++len; - if (len*sizeof(USHORT) <= sizeof(VALUE)) { + + if (len*sizeof(USHORT) < sizeof(VALUE) || + (len*sizeof(USHORT) == sizeof(VALUE) && + ds[sizeof(VALUE)/sizeof(USHORT)-1] <= 0x3fff)) { long num = 0; while (len--) { num = BIGUP(num) + ds[len]; @@ -282,10 +286,9 @@ big2str(x, base) Fail("bignum cannot treat base %d", base); } - GC_LINK; - GC_PRO3(t, Fbig_clone(x)); + t = Fbig_clone(x); ds = BDIGITS(t); - GC_PRO3(ss, str_new(0, j)); + ss = str_new(0, j); s = RSTRING(ss)->ptr; s[0] = x->sign ? '+' : '-'; @@ -310,7 +313,7 @@ big2str(x, base) RSTRING(ss)->len -= x->sign?j:j-1; memmove(x->sign?s:s+1, s+j, RSTRING(ss)->len); s[RSTRING(ss)->len] = '\0'; - GC_UNLINK; + return ss; } @@ -363,20 +366,19 @@ dbl2big(d) VALUE z; double u = (d < 0)?-d:d; - while (0 != floor(u)) { + while (0 != (long)u) { u /= BIGRAD; i++; } - GC_LINK; - GC_PRO3(z, bignew(i, d>=0)); + z = bignew(i, d>=0); digits = BDIGITS(z); while (i--) { u *= BIGRAD; - c = floor(u); + c = (long)u; u -= c; digits[i] = c; } - GC_UNLINK; + return bignorm(z); } @@ -430,8 +432,6 @@ bigadd(x, y, sign) i = y->len; while (i--) zds[i] = BDIGITS(y)[i]; - GC_LINK; - GC_PRO(z); i = 0; num = 0; if (x->sign == z->sign) { do { @@ -481,7 +481,7 @@ bigadd(x, y, sign) } } } - GC_UNLINK; + return bignorm(z); } @@ -491,14 +491,12 @@ Fbig_plus(x, y) { VALUE z; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(x, T_BIGNUM); } z = bigadd(x, y, 1); - GC_UNLINK; + return z; } @@ -506,14 +504,11 @@ VALUE Fbig_minus(x, y) VALUE x, y; { - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } x = bigadd(x, y, 0); - GC_UNLINK; return x; } @@ -527,8 +522,7 @@ Fbig_mul(x, y) VALUE z; USHORT *zds; - GC_LINK; - GC_PRO(y); + if (FIXNUM_P(x)) x = (struct RBignum*)int2big(FIX2INT(x)); if (FIXNUM_P(y)) y = (struct RBignum*)int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); @@ -552,7 +546,6 @@ Fbig_mul(x, y) } } } while (++i < x->len); - GC_UNLINK; return bignorm(z); } @@ -579,8 +572,7 @@ bigdivmod(x, y, div, mod) xds = BDIGITS(x); if (ny == 1) { dd = yds[0]; - GC_LINK; - GC_PRO3(z, Fbig_clone(x)); + z = Fbig_clone(x); zds = BDIGITS(z); t2 = 0; i = nx; while(i--) { @@ -593,16 +585,14 @@ bigdivmod(x, y, div, mod) if (!y->sign) t2 = -t2; *mod = FIX2INT(t2); } - GC_UNLINK; return; } - GC_LINK; - GC_PRO3(z, bignew(nx==ny?nx+2:nx+1, x->sign==y->sign)); + z = bignew(nx==ny?nx+2:nx+1, x->sign==y->sign); zds = BDIGITS(z); if (nx==ny) zds[nx+1] = 0; while (!yds[ny-1]) ny--; if ((dd = BIGRAD/(yds[ny-1]+1)) != 1) { - GC_PRO3(y, (struct RBignum*)Fbig_clone(y)); + y = (struct RBignum*)Fbig_clone(y); tds = BDIGITS(y); j = 0; num = 0; @@ -681,7 +671,6 @@ bigdivmod(x, y, div, mod) RBIGNUM(*mod)->sign = y->sign; *mod = bignorm(*mod); } - GC_UNLINK; } static VALUE @@ -690,14 +679,12 @@ Fbig_div(x, y) { VALUE z; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } bigdivmod(x, y, &z, Qnil); - GC_UNLINK; + return z; } @@ -707,14 +694,12 @@ Fbig_mod(x, y) { VALUE z; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } bigdivmod(x, y, Qnil, &z); - GC_UNLINK; + return z; } @@ -724,38 +709,41 @@ Fbig_divmod(x, y) { VALUE div, mod; - GC_LINK; - GC_PRO(y); if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); else { Check_Type(y, T_BIGNUM); } bigdivmod(x, y, &div, &mod); - GC_UNLINK; return assoc_new(div, mod);; } -static VALUE +VALUE Fbig_pow(x, y) VALUE x, y; { - extern double pow(); double d1, d2; + VALUE z; + int n; - GC_LINK; - GC_PRO(y); - if (FIXNUM_P(y)) y = int2big(FIX2INT(y)); - else { - Check_Type(y, T_BIGNUM); + if (TYPE(y) == T_FLOAT) { + return float_new(pow(big2dbl(x), RFLOAT(y)->value)); + } + n = NUM2INT(y); + if (n == 0) return INT2FIX(1); + if (n < 0) { + return float_new(pow(big2dbl(x), (double)n)); } - d1 = big2dbl(x); - d2 = big2dbl(y); - d1 = pow(d1, d2); - GC_UNLINK; - - return dbl2big(d1); + z = x; + while (--n) { + while (!(n % 2)) { + n = n /2; + x = Fbig_mul(x, x); + } + z = Fbig_mul(z, x); + } + return z; } VALUE @@ -774,14 +762,12 @@ Fbig_and(x, y) Check_Type(y, T_BIGNUM); } - GC_LINK; - GC_PRO(y); if (!y->sign) { y = (struct RBignum*)Fbig_clone(y); big_2comp(y); } if (!x->sign) { - GC_PRO3(x, (struct RBignum*)Fbig_clone(x)); + x = (struct RBignum*)Fbig_clone(x); big_2comp(x); } if (x->len > y->len) { @@ -808,7 +794,6 @@ Fbig_and(x, y) zds[i] = sign?0:ds2[i]; } if (!RBIGNUM(z)->sign) big_2comp(z); - GC_UNLINK; return bignorm(z); } @@ -828,14 +813,12 @@ Fbig_or(x, y) Check_Type(y, T_BIGNUM); } - GC_LINK; - GC_PRO(y); if (!y->sign) { y = (struct RBignum*)Fbig_clone(y); big_2comp(y); } if (!x->sign) { - GC_PRO3(x, (struct RBignum*)Fbig_clone(x)); + x = (struct RBignum*)Fbig_clone(x); big_2comp(x); } if (x->len > y->len) { @@ -862,7 +845,7 @@ Fbig_or(x, y) zds[i] = sign?ds2[i]:(BIGRAD-1); } if (!RBIGNUM(z)->sign) big_2comp(z); - GC_UNLINK; + return bignorm(z); } @@ -882,14 +865,12 @@ Fbig_xor(x, y) Check_Type(y, T_BIGNUM); } - GC_LINK; - GC_PRO(y); if (!y->sign) { y = (struct RBignum*)Fbig_clone(y); big_2comp(y); } if (!x->sign) { - GC_PRO3(x, (struct RBignum*)Fbig_clone(x)); + x = (struct RBignum*)Fbig_clone(x); big_2comp(x); } if (x->len > y->len) { @@ -918,7 +899,7 @@ Fbig_xor(x, y) zds[i] = sign?ds2[i]:~ds2[i]; } if (!RBIGNUM(z)->sign) big_2comp(z); - GC_UNLINK; + return bignorm(z); } diff --git a/bring b/bring deleted file mode 100644 index 771cd04542..0000000000 --- a/bring +++ /dev/null @@ -1,57 +0,0 @@ -#! /usr/bin/bash - -function fdeject() { - if type eject > /dev/null 2>&1; then - eject - fi -} - -function copyfiles() { - for d in . missing sample; do - if [ ! -d $1/$d ];then mkdir $1/$d; fi - for i in $d/*;do - case $i in - */ruby|*.o|*~|*.sav|*.bak|*.orig|*/core|"#"*);; - */Change*|*/config.status|*/Makefile);; - *) - if [ -f $i ]; then - if [ $i -nt $1/$i -o ! -f $1/$i ];then - echo copying $i - cp -p $i $1/$i - fi - fi;; - esac - done - done -} - -if [ ! -d exchange ]; then mkdir exchange; fi - -if [ "$1" = "in" ]; then - - cd exchange - - mread ruby.tgz ruby.tgz - fdeject - tar zxf ruby.tgz - rm -f ruby.tgz - cd ruby - - cp ChangeLog ../../Changes - copyfiles ../.. - -else -# bring out - if [ ! -d exchange/ruby ]; then mkdir exchange/ruby; fi - - cp -p ChangeLog exchange/ruby - copyfiles exchange/ruby - - cd exchange - (cd ruby; make realclean) - - tar zcf ruby.tgz ruby - mwrite ruby.tgz ruby.tgz - fdeject - rm -f ruby.tgz -fi @@ -14,12 +14,12 @@ #include "env.h" #include "node.h" #include "st.h" +#include "methods.h" struct st_table *new_idhash(); extern VALUE C_Class; extern VALUE C_Module; -extern VALUE C_Method; VALUE class_new(super) @@ -140,6 +140,7 @@ rb_include_module(class, module) struct RClass *class, *module; { struct RClass *p; + int added = FALSE; Check_Type(module, T_MODULE); @@ -151,41 +152,43 @@ rb_include_module(class, module) } class->super = include_class_new(module, class->super); + added = TRUE; class = class->super; ignore_module: module = module->super; } - rb_clear_cache2(class); + if (added) { + rb_clear_cache2(class); + } } void -rb_add_method(class, mid, node, scope) +rb_add_method(class, mid, node, undef) struct RClass *class; ID mid; NODE *node; - enum mth_scope scope; + int undef; { - struct RMethod *body; - NEWOBJ(mth, struct RMethod); - OBJSETUP(mth, C_Method, T_METHOD); + struct SMethod *body; if (class == Qnil) class = (struct RClass*)C_Object; if (st_lookup(class->m_tbl, mid, &body)) { if (verbose) { Warning("redefine %s", rb_id2name(mid)); } - unliteralize(body); rb_clear_cache(body); + method_free(body); } - mth->node = node; + body = ALLOC(struct SMethod); + body->node = node; if (BUILTIN_TYPE(class) == T_MODULE) - mth->origin = Qnil; + body->origin = Qnil; else - mth->origin = class; - mth->id = mid; - mth->scope = scope; - literalize(mth); - st_insert(class->m_tbl, mid, mth); + body->origin = class; + body->id = mid; + body->undef = undef; + body->count = 1; + st_insert(class->m_tbl, mid, body); } void @@ -197,19 +200,7 @@ rb_define_method(class, name, func, argc) { NODE *temp = NEW_CFUNC(func, argc); - rb_add_method(class, rb_intern(name), temp, MTH_METHOD); -} - -void -rb_define_func(class, name, func, argc) - struct RClass *class; - char *name; - VALUE (*func)(); - int argc; -{ - NODE *temp = NEW_CFUNC(func, argc); - - rb_add_method(class, rb_intern(name), temp, MTH_FUNC); + rb_add_method(class, rb_intern(name), temp, FALSE); } void @@ -217,7 +208,7 @@ rb_undef_method(class, name) struct RClass *class; char *name; { - rb_add_method(class, rb_intern(name), Qnil, MTH_UNDEF); + rb_add_method(class, rb_intern(name), Qnil, TRUE); } VALUE @@ -248,7 +239,7 @@ rb_define_single_method(obj, name, func, argc) VALUE (*func)(); int argc; { - rb_define_method(rb_single_class(obj), name, func, argc, MTH_METHOD); + rb_define_method(rb_single_class(obj), name, func, argc, FALSE); } void @@ -258,7 +249,7 @@ rb_define_mfunc(class, name, func, argc) VALUE (*func)(); int argc; { - rb_define_func(class, name, func, argc); + rb_define_method(class, name, func, argc); rb_define_single_method(class, name, func, argc); } @@ -285,11 +276,11 @@ rb_define_attr(class, name, pub) attreq = rb_intern(buf); sprintf(buf, "@%s", name); attriv = rb_intern(buf); - if (rb_get_method_body(class, attr, 0, MTH_METHOD) == Qnil) { - rb_add_method(class, attr, NEW_IVAR(attriv), MTH_METHOD); + if (rb_get_method_body(class, attr, 0) == Qnil) { + rb_add_method(class, attr, NEW_IVAR(attriv), TRUE); } - if (pub && rb_get_method_body(class, attreq, 0, MTH_METHOD) == Qnil) { - rb_add_method(class, attreq, NEW_ATTRSET(attriv), MTH_METHOD); + if (pub && rb_get_method_body(class, attreq, 0) == Qnil) { + rb_add_method(class, attreq, NEW_ATTRSET(attriv), TRUE); } } diff --git a/config.status b/config.status deleted file mode 100755 index 7bdc7b26ed..0000000000 --- a/config.status +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh -# Generated automatically by configure. -# Run this file to recreate the current configuration. -# This directory was configured as follows, -# on host dyna: -# -# ./configure - -for arg -do - case "$arg" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo running ${CONFIG_SHELL-/bin/sh} ./configure - exec ${CONFIG_SHELL-/bin/sh} ./configure ;; - *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; - esac -done - -trap 'rm -f Makefile; exit 1' 1 3 15 -PROGS='ruby' -CC='gcc' -CPP='gcc -E' -DBM='-fpcc-struct-return' -STATIC='' -YACC='bison -y' -INSTALL='/usr/bin/install -c' -INSTALL_PROGRAM='$(INSTALL)' -INSTALL_DATA='$(INSTALL) -m 644' -ALLOCA='' -LIBS=' -lm -ldbm' -srcdir='.' -DEFS=' -DHAVE_UNISTD_H=1 -DHAVE_SYSCALL_H=1 -DHAVE_A_OUT_H=1 -DDIRENT=1 -DGETGROUPS_T=gid_t -DRETSIGTYPE=void -DHAVE_GETOPT_LONG=1 -DHAVE_MEMMOVE=1 -DHAVE_STRERROR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 -DHAVE_STRDUP=1 -DHAVE_SETENV=1 -DHAVE_KILLPG=1 -DHAVE_MKDIR=1 -DHAVE_STRFTIME=1 -DHAVE_ALLOCA_H=1' -prefix='' -exec_prefix='' -prsub='' -extrasub='' - -top_srcdir=$srcdir - -CONFIG_FILES=${CONFIG_FILES-"Makefile"} -for file in .. ${CONFIG_FILES}; do if test "x$file" != x..; then - srcdir=$top_srcdir - # Remove last slash and all that follows it. Not all systems have dirname. - dir=`echo $file|sed 's%/[^/][^/]*$%%'` - if test "$dir" != "$file"; then - test "$top_srcdir" != . && srcdir=$top_srcdir/$dir - test ! -d $dir && mkdir $dir - fi - echo creating $file - rm -f $file - echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file - sed -e " -$prsub -$extrasub -s%@PROGS@%$PROGS%g -s%@CC@%$CC%g -s%@CPP@%$CPP%g -s%@DBM@%$DBM%g -s%@STATIC@%$STATIC%g -s%@YACC@%$YACC%g -s%@INSTALL@%$INSTALL%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@ALLOCA@%$ALLOCA%g -s%@LIBS@%$LIBS%g -s%@srcdir@%$srcdir%g -s%@DEFS@%$DEFS% -" $top_srcdir/${file}.in >> $file -fi; done - - -exit 0 diff --git a/configure.in b/configure.in index 0acb17eae5..041018e0d2 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ AC_GETGROUPS_T AC_RETSIGTYPE AC_HAVE_FUNCS(getopt_long memmove strerror strtoul strdup strstr) AC_HAVE_FUNCS(setenv fmod killpg mkdir strftime socket random) -AC_HAVE_FUNCS(wait4 waitpid) +AC_HAVE_FUNCS(wait4 waitpid syscall) if echo $DEFS | grep "HAVE_SETENV" 2>&1 > /dev/null; then : else @@ -38,7 +38,7 @@ if echo $DEFS | grep "HAVE_STRFTIME" 2>&1 > /dev/null; then else AC_TIMEZONE AC_COMPILE_CHECK([daylight], [], - [extern int daylight; daylight;], AC_DEFINE(HAVE_DAYLIGHT)) + [extern int daylight; int i; i = daylight;], AC_DEFINE(HAVE_DAYLIGHT)) fi AC_ALLOCA AC_WORDS_BIGENDIAN @@ -81,10 +81,8 @@ Fdbm_open(class, args) rb_sys_fail(RSTRING(file)->ptr); } - GC_LINK; - GC_PRO3(obj, obj_alloc(class)); + obj = obj_alloc(class); MakeDBM(obj, dbm); - GC_UNLINK; return obj; } @@ -149,8 +147,6 @@ Fdbm_delete_if(obj) VALUE keystr, valstr; GetDBM(obj, dbm); - GC_LINK; - GC_PRO2(keystr); GC_PRO2(valstr); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); keystr = str_new(key.dptr, key.dsize); @@ -160,7 +156,6 @@ Fdbm_delete_if(obj) Fail("DBM delete failed"); } } - GC_UNLINK; return obj; } @@ -261,8 +256,6 @@ Fdbm_each_pair(obj) VALUE keystr, valstr; GetDBM(obj, dbm); - GC_LINK; - GC_PRO2(keystr); GC_PRO2(valstr); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); @@ -270,7 +263,6 @@ Fdbm_each_pair(obj) valstr = str_new(val.dptr, val.dsize); rb_yield(assoc_new(keystr, valstr)); } - GC_UNLINK; return obj; } @@ -283,13 +275,12 @@ Fdbm_keys(obj) DBM *dbm; VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); GetDBM(obj, dbm); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { Fary_push(ary, str_new(key.dptr, key.dsize)); } - GC_UNLINK; + return ary; } @@ -301,14 +292,13 @@ Fdbm_values(obj) DBM *dbm; VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); GetDBM(obj, dbm); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); Fary_push(ary, str_new(val.dptr, val.dsize)); } - GC_UNLINK; + return ary; } @@ -360,16 +350,13 @@ Fdbm_to_a(obj) GetDBM(obj, dbm); - GC_LINK; - GC_PRO3(ary, ary_new()); - + ary = ary_new(); for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { val = dbm_fetch(dbm, key); Fary_push(ary, assoc_new(str_new(key.dptr, key.dsize), str_new(val.dptr, val.dsize))); } - GC_UNLINK; return ary; } @@ -12,7 +12,9 @@ #define RUBY -/* #include "config.h" */ +/* define EUC/SJIS for default kanji-code */ +#define EUC +#undef SJIS /* define USE_DLN to load object file(.o). */ #ifdef HAVE_A_OUT_H @@ -43,11 +43,7 @@ Fdic_new(class) NEWOBJ(dic, struct RDict); OBJSETUP(dic, class, T_DICT); - GC_LINK; - GC_PRO(dic); - dic->tbl = st_init_table(rb_cmp, rb_hash); - GC_UNLINK; return (VALUE)dic; } @@ -59,13 +55,8 @@ Fdic_clone(dic) NEWOBJ(dic2, struct RDict); CLONESETUP(dic2, dic); - GC_LINK; - GC_PRO(dic2); - dic2->tbl = (st_table*)st_copy(dic->tbl); - GC_UNLINK; - return (VALUE)dic2; } @@ -210,10 +201,8 @@ Fdic_to_a(dic) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); st_foreach(dic->tbl, dic_to_a, ary); - GC_UNLINK; return ary; } @@ -229,13 +218,11 @@ dic_inspect(key, value, str) if (str->len > 1) { str_cat(str, ", ", 2); } - GC_LINK; - GC_PRO3(str2, rb_funcall(key, inspect, 0, Qnil)); + str2 = rb_funcall(key, inspect, 0, Qnil); str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); str_cat(str, "=>", 2); str2 = rb_funcall(value, inspect, 0, Qnil); str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); - GC_UNLINK; return ST_CONTINUE; } @@ -246,11 +233,9 @@ Fdic_inspect(dic) { VALUE str; - GC_LINK; - GC_PRO3(str, str_new2("{")); + str = str_new2("{"); st_foreach(dic->tbl, dic_inspect, str); str_cat(str, "}", 1); - GC_UNLINK; return str; } @@ -261,11 +246,8 @@ Fdic_to_s(dic) { VALUE str; - GC_LINK; - GC_PRO(dic); dic = Fdic_to_a(dic); str = Fary_to_s(dic); - GC_UNLINK; return str; } @@ -284,10 +266,9 @@ Fdic_keys(dic) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); st_foreach(dic->tbl, dic_keys, ary); - GC_UNLINK; + return ary; } @@ -305,10 +286,9 @@ Fdic_values(dic) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); st_foreach(dic->tbl, dic_values, ary); - GC_UNLINK; + return ary; } @@ -326,7 +306,7 @@ Fdic_has_key(dic, key) static VALUE value_found; -static +static int dic_search_value(key, value, arg) VALUE key, value, arg; { @@ -347,6 +327,46 @@ Fdic_has_value(dic, val) return value_found; } +struct equal_data { + int result; + st_table *tbl; +}; + +static int +dic_equal(key, val1, data) + VALUE key, val1; + struct equal_data *data; +{ + VALUE val2; + + if (!st_lookup(data->tbl, key, &val2)) { + data->result = FALSE; + return ST_STOP; + } + if (!rb_funcall(val1, eq, 1, val2)) { + data->result = FALSE; + return ST_STOP; + } + return ST_CONTINUE; +} + +static VALUE +Fdic_equal(dic1, dic2) + struct RDict *dic1, *dic2; +{ + struct equal_data data; + + if (TYPE(dic2) != T_DICT) return FALSE; + if (dic1->tbl->num_entries != dic2->tbl->num_entries) + return FALSE; + + data.tbl = dic2->tbl; + data.result = TRUE; + st_foreach(dic1->tbl, dic_equal, &data); + + return data.result; +} + char *index(); extern VALUE rb_readonly_hook(); @@ -363,11 +383,9 @@ Fenv_each(dic) VALUE var, val; char *s = index(*env, '='); - GC_LINK; - GC_PRO3(var, str_new(*env, s-*env)); - GC_PRO3(val, str_new2(s+1)); + var = str_new(*env, s-*env); + val = str_new2(s+1); rb_yield(assoc_new(var, val)); - GC_UNLINK; env++; } return dic; @@ -481,6 +499,7 @@ Init_Dict() rb_define_method(C_Dict,"to_s", Fdic_to_s, 0); rb_define_method(C_Dict,"_inspect", Fdic_inspect, 0); + rb_define_method(C_Dict,"==", Fdic_equal, 1); rb_define_method(C_Dict,"[]", Fdic_aref, 1); rb_define_method(C_Dict,"[]=", Fdic_aset, 2); rb_define_method(C_Dict,"length", Fdic_length, 0); @@ -512,6 +531,6 @@ Init_Dict() envtbl = obj_alloc(C_EnvDict); rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook); - rb_define_func(C_Kernel, "getenv", Fgetenv, 1); - rb_define_func(C_Kernel, "setenv", Fsetenv, 2); + rb_define_method(C_Kernel, "getenv", Fgetenv, 1); + rb_define_method(C_Kernel, "setenv", Fsetenv, 2); } @@ -42,7 +42,7 @@ static void free_dir(dir) DIR **dir; { - if (dir) closedir(*dir); + if (dir && *dir) closedir(*dir); } static VALUE @@ -58,12 +58,9 @@ Fdir_open(dir_class, dirname) dirp = opendir(dirname->ptr); if (dirp == NULL) Fail("Can't open directory %s", dirname->ptr); - GC_LINK; - GC_PRO3(obj, obj_alloc(dir_class)); + obj = obj_alloc(dir_class); Make_Data_Struct(obj, "dir", DIR*, Qnil, free_dir, d); *d = dirp; - /* use memcpy(d, dirp, sizeof(DIR)) if needed.*/ - GC_UNLINK; return obj; } @@ -248,10 +245,10 @@ Init_Dir() rb_define_single_method(C_Dir,"chdir", Fdir_chdir, -2); rb_define_single_method(C_Dir,"getwd", Fdir_getwd, 0); - rb_define_alias(C_Dir, "pwd", "getwd"); + rb_define_single_method(C_Dir,"pwd", Fdir_getwd, 0); rb_define_single_method(C_Dir,"chroot", Fdir_chroot, 1); rb_define_single_method(C_Dir,"mkdir", Fdir_mkdir, -2); rb_define_single_method(C_Dir,"rmdir", Fdir_rmdir, 1); - rb_define_alias(C_Dir, "delete", "rmdir"); - rb_define_alias(C_Dir, "unlink", "rmdir"); + rb_define_single_method(C_Dir,"delete", Fdir_rmdir, 1); + rb_define_single_method(C_Dir,"unlink", Fdir_rmdir, 1); } @@ -52,12 +52,8 @@ Fenum_grep(obj, pat) VALUE tmp, arg[2]; arg[0] = pat; arg[1] = tmp = ary_new(); - GC_LINK; - GC_PRO(tmp); - rb_iterate(rb_each, obj, enum_grep, arg); - GC_UNLINK; return tmp; } } @@ -99,12 +95,9 @@ Fenum_find_all(obj) { VALUE tmp; - GC_LINK; - GC_PRO3(tmp, ary_new()); - + tmp = ary_new(); rb_iterate(rb_each, obj, enum_find_all, Qnil); - GC_UNLINK; return tmp; } @@ -114,14 +107,10 @@ enum_collect(i, tmp) { VALUE retval; - GC_LINK; - GC_PRO3(retval, rb_yield(i)); - + retval = rb_yield(i); if (retval) { Fary_push(tmp, retval); } - - GC_UNLINK; } static VALUE @@ -130,12 +119,9 @@ Fenum_collect(obj) { VALUE tmp; - GC_LINK; - GC_PRO3(tmp, ary_new()); - + tmp = ary_new(); rb_iterate(rb_each, obj, enum_collect, tmp); - GC_UNLINK; return tmp; } @@ -152,12 +138,9 @@ Fenum_reverse(obj) { VALUE tmp; - GC_LINK; - GC_PRO3(tmp, ary_new()); - + tmp = ary_new(); rb_iterate(rb_each, obj, enum_reverse, tmp); - GC_UNLINK; return tmp; } @@ -174,10 +157,8 @@ Fenum_to_a(obj) { VALUE ary; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); rb_iterate(rb_each, obj, enum_all, ary); - GC_UNLINK; return ary; } @@ -188,10 +169,8 @@ Fenum_sort(obj) { VALUE ary; - GC_LINK; - GC_PRO3(ary, Fenum_to_a(obj)); + ary = Fenum_to_a(obj); Fary_sort(ary); - GC_UNLINK; return ary; } @@ -214,12 +193,9 @@ static VALUE Fenum_min(obj) VALUE obj; { - VALUE min; + VALUE min = Qnil; - GC_LINK; - GC_PRO2(min); rb_iterate(rb_each, obj, enum_min, &min); - GC_UNLINK; return min; } @@ -242,12 +218,9 @@ static VALUE Fenum_max(obj) VALUE obj; { - VALUE max; + VALUE max = Qnil; - GC_LINK; - GC_PRO2(max); rb_iterate(rb_each, obj, enum_max, &max); - GC_UNLINK; return max; } @@ -154,6 +154,9 @@ static char *builtin_types[] = { "Fixnum", "Dictionary", "Data", + "Method", + "Struct", + "Bignum", }; WrongType(x, t) @@ -29,58 +29,34 @@ static VALUE setup_passwd(pwd) struct passwd *pwd; { - VALUE pw, name, passwd, gecos, dir, shell; -#ifdef PW_CLASS - VALUE class; -#endif -#ifdef PW_COMMENT - VALUE comment; -#endif - if (pwd == Qnil) rb_sys_fail("/etc/passwd"); - GC_LINK; - GC_PRO3(pw, str_new2(pwd->pw_name)); - GC_PRO3(passwd, str_new2(pwd->pw_passwd)); - GC_PRO3(gecos, str_new2(pwd->pw_gecos)); - GC_PRO3(dir, str_new2(pwd->pw_dir)); - GC_PRO3(shell, str_new2(pwd->pw_shell)); -#ifdef PW_CLASS - GC_PRO3(class, str_new2(pwd->pw_class)); -#endif -#ifdef PW_COMMENT - GC_PRO3(comment, str_new2(pwd->pw_comment)); -#endif - - pw = struct_new("passwd", - "name", name, - "passwd", passwd, - "uid", INT2FIX(pwd->pw_uid), - "gid", INT2FIX(pwd->pw_gid), - "gecos", gecos, - "dir", dir, - "shell", shell, + return struct_new("passwd", + "name", str_new2(pwd->pw_name), + "passwd", str_new2(pwd->pw_passwd), + "uid", INT2FIX(pwd->pw_uid), + "gid", INT2FIX(pwd->pw_gid), + "gecos", str_new2(pwd->pw_gecos), + "dir", str_new2(pwd->pw_dir), + "shell", str_new2(pwd->pw_shell), #ifdef PW_CHANGE - "change", INT2FIX(pwd->pw_change), + "change", INT2FIX(pwd->pw_change), #endif #ifdef PW_QUOTA - "quota", INT2FIX(pwd->pw_quota), + "quota", INT2FIX(pwd->pw_quota), #endif #ifdef PW_AGE - "age", INT2FIX(pwd->pw_age), + "age", INT2FIX(pwd->pw_age), #endif #ifdef PW_CLASS - "class", class, + "class", str_new2(pwd->pw_class), #endif #ifdef PW_COMMENT - "comment", comment, + "comment", str_new2(pwd->pw_comment), #endif #ifdef PW_EXPIRE - "expire", INT2FIX(pwd->pw_expire), + "expire", INT2FIX(pwd->pw_expire), #endif - Qnil); - GC_UNLINK; - - return pw; + Qnil); } static VALUE @@ -137,27 +113,21 @@ static VALUE setup_group(grp) struct group *grp; { - VALUE mem, obj, name, passwd; + VALUE mem; char **tbl; - GC_LINK; - GC_PRO3(mem, ary_new()); + mem = ary_new(); tbl = grp->gr_mem; while (*tbl) { Fary_push(mem, str_new2(*tbl)); tbl++; } - GC_PRO3(name, str_new2(grp->gr_name)); - GC_PRO3(passwd, str_new2(grp->gr_passwd)); - obj = struct_new("group", - "name", name, - "passwd", passwd, - "gid", INT2FIX(grp->gr_gid), - "mem", mem, - Qnil); - GC_UNLINK; - - return obj; + return struct_new("group", + "name", str_new2(grp->gr_name), + "passwd", str_new2(grp->gr_passwd), + "gid", INT2FIX(grp->gr_gid), + "mem", mem, + Qnil); } static VALUE @@ -22,6 +22,7 @@ static ID match, each; VALUE errstr, errat; extern NODE *eval_tree; +extern VALUE TopSelf; struct ENVIRON *the_env, *top_env; #define PUSH_ENV() {\ @@ -57,7 +58,6 @@ static struct tag { struct tag *_oldtag = prot_tag;\ &_oldtag;\ _this.level= ++tag_level;\ - _this.gclist= GC_List;\ _this.env= the_env;\ prot_tag = &_this;\ @@ -69,7 +69,6 @@ static struct tag { #define EXEC_TAG() (setjmp(prot_tag->buf)) #define JUMP_TAG(val) {\ the_env = prot_tag->env;\ - GC_List = prot_tag->gclist;\ longjmp(prot_tag->buf,(val));\ } @@ -89,6 +88,7 @@ VALUE Feval(); VALUE Argv; static VALUE rb_call(); VALUE rb_apply(); +VALUE rb_xstring(); static void asign(); @@ -123,12 +123,17 @@ error_print() exit(1); } +static int origargc; +static char **origargv; + main(argc, argv) int argc; char *argv[]; { int state; + origargc = argc; origargv = argv; + Init_stack(); PUSH_ENV(); top_env = the_env; PUSH_TAG(); @@ -174,21 +179,69 @@ main(argc, argv) VALUE rb_readonly_hook(); -VALUE Progname; +static VALUE Progname; static VALUE -Eval() +Eval(toplevel) + int toplevel; { - int state; + VALUE result; NODE *tree; + int state; if (match == Qnil) match = rb_intern("=~"); if (each == Qnil) each = rb_intern("each"); tree = eval_tree; eval_tree = Qnil; + PUSH_TAG(); + if ((state = EXEC_TAG()) == 0) { + result = rb_eval(tree); + } + POP_TAG(); + /* you don't have to free at toplevel */ + if (!toplevel) freenode(tree); + if (state) JUMP_TAG(state); + + return result; +} + +static VALUE +set_arg0(val, id) + VALUE val; + ID id; +{ + char *s; + int i; + static int len; + + Check_Type(val, T_STRING); + if (len == 0) { + s = origargv[0]; + s += strlen(s); + /* See if all the arguments are contiguous in memory */ + for (i = 1; i < origargc; i++) { + if (origargv[i] == s + 1) + s += strlen(++s); /* this one is ok too */ + } + len = s - origargv[0]; + } + s = RSTRING(val)->ptr; + i = RSTRING(val)->len; + if (i > len) { + memcpy(origargv[0], s, len); + origargv[0][len] = '\0'; + } + else { + memcpy(origargv[0], s, i); + s = origargv[0]+i; + *s++ = '\0'; + while (++i < len) + *s++ = ' '; + } + Progname = str_new2(origargv[0]); - return rb_eval(tree); + return val; } VALUE @@ -205,7 +258,7 @@ TopLevel(script, argc, argv) errat = Qnil; /* clear for execution */ Progname = str_new2(script); - rb_define_variable("$0", &Progname, Qnil, Qnil); + rb_define_variable("$0", &Progname, Qnil, set_arg0); rb_define_variable("$ARGV", &Argv, Qnil, Qnil); rb_define_variable("$*", &Argv, Qnil, Qnil); @@ -213,7 +266,12 @@ TopLevel(script, argc, argv) for (i=0; i < argc; i++) { Fary_push(Argv, str_new2(argv[i])); } - return Eval(); +#define PURIFY_D +#ifdef PURIFY_D + return Eval(0); +#else + return Eval(1); +#endif } void @@ -221,9 +279,10 @@ rb_trap_eval(cmd) VALUE cmd; { PUSH_ENV(); - the_env->self = top_env->self; + the_env->self = TopSelf; the_env->current_module = top_env->current_module; the_env->local_vars = top_env->local_vars; + the_env->local_tbl = top_env->local_tbl; the_class = (struct RClass*)C_Object; Feval(Qself, cmd); @@ -273,14 +332,10 @@ setup_arg_2(node, args, argc, argv) } #define SETUP_ARGS {\ - VALUE args;\ - GC_LINK;\ - GC_PRO2(args);\ + VALUE args = Qnil;\ argc = setup_arg_1(node->nd_args, &args);\ argv = (VALUE*)alloca(sizeof(VALUE)*argc);\ - GC_PRO4(argv, argc);\ setup_arg_2(node->nd_args, args, argc, argv);\ - GC_UNLINK;\ } static VALUE @@ -365,9 +420,7 @@ rb_eval(node) { VALUE val; - GC_LINK; - GC_PRO3(val, rb_eval(node->nd_head)); - + val = rb_eval(node->nd_head); node = node->nd_body; while (node) { if (node->type == NODE_WHEN) { @@ -375,22 +428,18 @@ rb_eval(node) while (tag) { if (rb_funcall(rb_eval(tag->nd_head), match, 1, val)){ - result = rb_eval(node->nd_body); - goto exit_case; + return rb_eval(node->nd_body); } tag = tag->nd_next; } } else { - result = rb_eval(node); - goto exit_case; + return rb_eval(node); } node = node->nd_next; } - exit_case: - GC_UNLINK; } - return result; + return Qnil; case NODE_WHILE: PUSH_TAG(); @@ -476,13 +525,9 @@ rb_eval(node) else { VALUE recv; - GC_LINK; - GC_PRO2(recv); recv = rb_eval(node->nd_iter); the_env->iterator = 1; - result = rb_call(CLASS_OF(recv), recv, each, 1, Qnil, - MTH_METHOD); - GC_UNLINK; + result = rb_call(CLASS_OF(recv), recv, each, 1, Qnil, 0); } } POP_TAG(); @@ -511,19 +556,13 @@ rb_eval(node) { VALUE val; - GC_LINK; - GC_PRO3(val, rb_eval(node->nd_stts)); + val = rb_eval(node->nd_stts); result = rb_yield(val); - GC_UNLINK; } return result; case NODE_PROT: - GC_LINK; - GC_PRO2(result); - PUSH_TAG(); - switch (state = EXEC_TAG()) { case 0: retry_entry: @@ -555,7 +594,6 @@ rb_eval(node) /* ensure clause */ rb_eval(node->nd_ensr); - GC_UNLINK; if (state != 0) { JUMP_TAG(state); @@ -610,7 +648,6 @@ rb_eval(node) { VALUE recv, *argv; int argc, last_iter; - enum mth_scope scope; last_iter = the_env->iterator; the_env->iterator = 0; /* recv & args are not iter. */ @@ -624,8 +661,7 @@ rb_eval(node) } the_env->iterator = last_iter; /* restore iter. level */ - scope = node->nd_recv?MTH_METHOD:MTH_FUNC; - return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope); + return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv); } break; @@ -662,7 +698,7 @@ rb_eval(node) } result = rb_call(the_env->last_class->super, Qself, - the_env->last_func, argc, argv, Qnil, MTH_FUNC); + the_env->last_func, argc, argv, Qnil); the_env->iterator = last_iter; } return result; @@ -699,8 +735,6 @@ rb_eval(node) NODE *list = node->nd_head; int i, len; - GC_LINK; - GC_PRO(val); if (TYPE(val) != T_ARRAY) { val = rb_funcall(val, rb_intern("to_a"), 0, Qnil); if (TYPE(val) != T_ARRAY) { @@ -716,7 +750,6 @@ rb_eval(node) asign(list->nd_head, Qnil); list = list->nd_next; } - GC_UNLINK; return val; } @@ -729,27 +762,24 @@ rb_eval(node) { VALUE val; - GC_LINK; GC_PRO3(val, rb_eval(node->nd_value)); + val = rb_eval(node->nd_value); rb_gvar_set(node->nd_entry, val); - GC_UNLINK; return val; } case NODE_IASGN: { VALUE val; - GC_LINK; GC_PRO3(val, rb_eval(node->nd_value)); + val = rb_eval(node->nd_value); rb_ivar_set(node->nd_vid, val); - GC_UNLINK; return val; } case NODE_CASGN: { VALUE val; - GC_LINK; GC_PRO3(val, rb_eval(node->nd_value)); + val = rb_eval(node->nd_value); rb_const_set(node->nd_vid, val); - GC_UNLINK; return val; } break; @@ -786,8 +816,6 @@ rb_eval(node) VALUE hash = Fdic_new(C_Dict); VALUE key, val; - GC_LINK; - GC_PRO(hash); GC_PRO2(key); GC_PRO2(val); list = node->nd_head; while (list) { key = rb_eval(list->nd_head); @@ -798,7 +826,6 @@ rb_eval(node) list = list->nd_next; Fdic_aset(hash, key, val); } - GC_UNLINK; return hash; } break; @@ -812,14 +839,12 @@ rb_eval(node) int i; NODE *list; - GC_LINK; for (i=0, list=node; list; list=list->nd_next) i++; - GC_PRO3(ary, ary_new2(i)); + ary = ary_new2(i); for (i=0;node;node=node->nd_next) { RARRAY(ary)->ptr[i++] = rb_eval(node->nd_head); RARRAY(ary)->len = i; } - GC_UNLINK; return ary; } @@ -828,6 +853,39 @@ rb_eval(node) case NODE_STR: return str_new3(node->nd_lit); + case NODE_STR2: + case NODE_XSTR2: + case NODE_DREGX: + { + VALUE str, str2; + NODE *list = node->nd_next; + + str = node->nd_lit; + while (list) { + if (list->nd_head->type == NODE_STR) { + str2 = list->nd_head->nd_lit; + } + else { + str2 = rb_eval(list->nd_head); + } + if (str2) { + str2 = obj_as_string(str2); + str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + } + list = list->nd_next; + } + if (node->type == NODE_DREGX) { + return regexp_new(RSTRING(str)->ptr, RSTRING(str)->len); + } + else if (node->type == NODE_XSTR2) { + return rb_xstring(str); + } + return str; + } + + case NODE_XSTR: + return rb_xstring(node->nd_lit); + case NODE_LIT: return node->nd_lit; @@ -841,10 +899,7 @@ rb_eval(node) NODE *local; int i, len; - local = node->nd_frml; - for (i=0; local; local=local->nd_next,i++) - ; - + i = node->nd_cnt; len = the_env->argc - 1; if (i > len || (node->nd_rest == -1 && i < len)) Fail("Wrong # of arguments(%d for %d)", len, i); @@ -869,26 +924,32 @@ rb_eval(node) case NODE_DEFN: { - rb_add_method(the_class,node->nd_mid,node->nd_defn,node->nd_scope); + if (node->nd_defn) { + rb_add_method(the_class,node->nd_mid,node->nd_defn,0); + node->nd_defn = Qnil; + } } return Qnil; case NODE_DEFS: { - VALUE recv = rb_eval(node->nd_recv); + if (node->nd_defn) { + VALUE recv = rb_eval(node->nd_recv); - if (recv == Qnil) { - Fail("Can't define method \"%s\" for nil", - rb_id2name(node->nd_mid)); + if (recv == Qnil) { + Fail("Can't define method \"%s\" for nil", + rb_id2name(node->nd_mid)); + } + rb_add_method(rb_single_class(recv), + node->nd_mid, node->nd_defn, 0); + node->nd_defn = Qnil; } - rb_add_method(rb_single_class(recv), - node->nd_mid, node->nd_defn, MTH_METHOD); } return Qnil; case NODE_UNDEF: { - rb_add_method(the_class, node->nd_mid, Qnil, MTH_UNDEF); + rb_add_method(the_class, node->nd_mid, Qnil, 1); } return Qnil; @@ -992,7 +1053,7 @@ obj_responds_to(obj, msg) id = rb_intern(msg->ptr); } - if (rb_get_method_body(CLASS_OF(obj), id, 0, MTH_FUNC)) { + if (rb_get_method_body(CLASS_OF(obj), id, 0)) { return TRUE; } return FALSE; @@ -1187,8 +1248,7 @@ asign(lhs, val) case NODE_CALL: { VALUE recv; - GC_LINK; - GC_PRO3(recv, rb_eval(lhs->nd_recv)); + recv = rb_eval(lhs->nd_recv); if (lhs->nd_args->nd_head == Qnil) { /* attr set */ rb_funcall(recv, lhs->nd_mid, 1, val); @@ -1197,11 +1257,10 @@ asign(lhs, val) /* array set */ VALUE args; - GC_PRO3(args, rb_eval(lhs->nd_args)); + args = rb_eval(lhs->nd_args); RARRAY(args)->ptr[RARRAY(args)->len-1] = val; rb_apply(recv, lhs->nd_mid, args); } - GC_UNLINK; } break; @@ -1319,8 +1378,6 @@ rb_ensure(b_proc, data1, e_proc, data2) int state; VALUE result; - GC_LINK; - GC_PRO2(result); PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { result = (*b_proc)(data1); @@ -1331,7 +1388,6 @@ rb_ensure(b_proc, data1, e_proc, data2) if (state != 0) { JUMP_TAG(state); } - GC_UNLINK; return result; } @@ -1339,7 +1395,8 @@ struct st_table *new_idhash(); static void rb_undefined(obj, id) - VALUE obj, id; + VALUE obj; + ID id; { VALUE desc = obj_as_string(obj); @@ -1347,18 +1404,17 @@ rb_undefined(obj, id) desc = Fkrn_to_s(obj); } Fail("undefined method `%s' for \"%s\"(%s)", - rb_id2name(NUM2INT(id)), + rb_id2name(id), RSTRING(desc)->ptr, rb_class2name(CLASS_OF(obj))); } static VALUE -rb_call(class, recv, mid, argc, argv, scope) +rb_call(class, recv, mid, argc, argv) struct RClass *class; VALUE recv, *argv; int argc; ID mid; - enum mth_scope scope; { int state; int go_out = 0; @@ -1375,7 +1431,7 @@ rb_call(class, recv, mid, argc, argv, scope) if (argv) argv[0] = recv; if (the_env->iterator != 0) the_env->iterator++; - if ((body = rb_get_method_body(class, mid, 1, scope)) == Qnil) { + if ((body = rb_get_method_body(class, mid, 1)) == Qnil) { rb_undefined(recv, mid); } @@ -1541,7 +1597,7 @@ rb_apply(recv, mid, args) argv[i] = RARRAY(args)->ptr[i-1]; } argv[0] = Qnil; - return rb_call(CLASS_OF(recv), recv, mid, argc, argv, MTH_FUNC); + return rb_call(CLASS_OF(recv), recv, mid, argc, argv); } VALUE @@ -1592,7 +1648,7 @@ rb_funcall(recv, mid, n, va_alist) argv = Qnil; } - return rb_call(CLASS_OF(recv), recv, mid, argc, argv, MTH_FUNC); + return rb_call(CLASS_OF(recv), recv, mid, argc, argv); } VALUE @@ -1622,12 +1678,10 @@ Fcaller(obj, args) } if (e->file == Qnil) Fail("initial frame"); - GC_LINK; - GC_PRO3(file, str_new2(e->file)); - GC_PRO3(ary, e->argv?ary_new4(e->argc, e->argv):ary_new3(1, Qself)); + file = str_new2(e->file); + ary = e->argv?ary_new4(e->argc, e->argv):ary_new3(1, Qself); res = ary_new3(4, file, INT2FIX(e->line), str_new2(rb_id2name(e->last_func)), ary); - GC_UNLINK; return res; } @@ -1663,9 +1717,9 @@ Feval(obj, src) eval_tree = Qnil; yyparse(); sourcefile = oldsrc; - if (nerrs == 0) - result = Eval(); - freenode(eval_tree); + if (nerrs == 0) { + result = Eval(0); + } } eval_tree = node; POP_ENV(); @@ -1676,13 +1730,11 @@ Feval(obj, src) if (nerrs > 0) { VALUE mesg; - GC_LINK; - GC_PRO3(mesg, errstr); + mesg = errstr; nerrs = 0; errstr = str_new2("syntax error in eval():\n"); str_cat(errstr, RSTRING(mesg)->ptr, RSTRING(mesg)->len); rb_fail(errstr); - GC_UNLINK; } return result; @@ -1702,9 +1754,6 @@ find_file(file) if (file[0] == '/') return file; - GC_LINK; - GC_PRO2(sep); GC_PRO2(vpath); - if (rb_load_path) { Check_Type(rb_load_path, T_ARRAY); sep = str_new2(":"); @@ -1721,7 +1770,6 @@ find_file(file) if (found == Qnil) Fail("No such file to load -- %s", file); if (vpath) obj_free(vpath); - GC_UNLINK; return found; } @@ -1731,9 +1779,7 @@ Fload(obj, fname) VALUE obj; struct RString *fname; { - extern VALUE TopSelf; int state; - VALUE result; NODE *node; char *file; @@ -1763,18 +1809,17 @@ Fload(obj, fname) PUSH_ENV(); the_class = (struct RClass*)C_Object; Qself = TopSelf; + the_env->current_module = top_env->current_module; + the_env->local_vars = top_env->local_vars; + the_env->local_tbl = top_env->local_tbl; the_env->in_eval = 1; - node = eval_tree; state = EXEC_TAG(); if (state == 0) { - eval_tree = Qnil; rb_load_file(file); if (nerrs == 0) { - result = Eval(); + Eval(0); } - freenode(eval_tree); } - eval_tree = node; POP_ENV(); POP_TAG(); if (nerrs > 0) { @@ -1853,6 +1898,6 @@ Init_load() addpath(getenv("RUBYLIB")); addpath(RUBY_LIB); - rb_define_func(C_Kernel, "load", Fload, 1); - rb_define_func(C_Kernel, "require", Frequire, 1); + rb_define_method(C_Kernel, "load", Fload, 1); + rb_define_method(C_Kernel, "require", Frequire, 1); } @@ -33,8 +33,7 @@ file_open(fname, mode) VALUE port; OpenFile *fptr; - GC_LINK; - GC_PRO3(port, obj_alloc(C_File)); + port = obj_alloc(C_File); MakeOpenFile(port, fptr); fptr->mode = io_mode_flags(mode); @@ -52,8 +51,6 @@ file_open(fname, mode) fptr->path = strdup(fname); - GC_UNLINK; - return port; } @@ -85,6 +82,7 @@ Ffile_seek(obj, offset, ptrname) pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname)); if (pos != 0) rb_sys_fail(Qnil); + clearerr(fptr->f); return obj; } @@ -97,6 +95,7 @@ Ffile_rewind(obj) GetOpenFile(obj, fptr); if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(Qnil); + clearerr(fptr->f); return obj; } @@ -137,16 +136,8 @@ static VALUE stat_new(st) struct stat *st; { - VALUE obj, data, atime, mtime, ctime, stat; - if (st == Qnil) Bug("stat_new() called with nil"); - - GC_LINK; - GC_PRO3(atime, time_new(st->st_atime, 0)); - GC_PRO3(mtime, time_new(st->st_mtime, 0)); - GC_PRO3(ctime, time_new(st->st_ctime, 0)); - - stat = struct_new("stat", + return struct_new("stat", "dev", INT2FIX((int)st->st_dev), "ino", INT2FIX((int)st->st_ino), "mode", INT2FIX((int)st->st_mode), @@ -169,13 +160,10 @@ stat_new(st) #else "blocks", INT2FIX(0), #endif - "atime", atime, - "mtime", mtime, - "ctime", ctime, + "atime", time_new(st->st_atime, 0), + "mtime", time_new(st->st_mtime, 0), + "ctime", time_new(st->st_ctime, 0), Qnil); - GC_UNLINK; - - return stat; } static char lastpath[MAXPATHLEN]; @@ -14,16 +14,14 @@ #include "env.h" #include "st.h" #include <stdio.h> +#include <setjmp.h> void *malloc(); void *calloc(); void *realloc(); -struct gc_list *GC_List = Qnil; -static struct gc_list *Global_List = Qnil; -static unsigned long bytes_alloc = 0, gc_threshold = 1000000; - -static mark_tbl(); +void gc(); +void gc_mark(); void * xmalloc(size) @@ -31,12 +29,10 @@ xmalloc(size) { void *mem; - bytes_alloc += size; if (size == 0) size = 1; mem = malloc(size); if (mem == Qnil) { gc(); - bytes_alloc += size; mem = malloc(size); if (mem == Qnil) Fatal("failed to allocate memory"); @@ -75,23 +71,41 @@ xrealloc(ptr, size) return mem; } -void -rb_global_variable(var) - VALUE *var; -{ - struct gc_list *tmp; - - tmp = (struct gc_list*)xmalloc(sizeof(struct gc_list)); - tmp->next = Global_List; - tmp->varptr = var; - tmp->n = 1; - Global_List = tmp; -} - -static struct RBasic *object_list = Qnil; -static struct RBasic *literal_list = Qnil; -static unsigned long fl_current = FL_MARK; -static unsigned long fl_old = 0L; +/* The way of garbage collecting which allows use of the cstack is due to */ +/* Scheme In One Defun, but in C this time. + + * COPYRIGHT (c) 1989 BY * + * PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. * + * ALL RIGHTS RESERVED * + +Permission to use, copy, modify, distribute and sell this software +and its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all copies +and that both that copyright notice and this permission notice appear +in supporting documentation, and that the name of Paradigm Associates +Inc not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +PARADIGM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +PARADIGM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +gjc@paradigm.com + +Paradigm Associates Inc Phone: 617-492-6079 +29 Putnam Ave, Suite 6 +Cambridge, MA 02138 +*/ + +#ifdef sparc +#define FLUSH_REGISTER_WINDOWS asm("ta 3") +#else +#define FLUSH_REGISTER_WINDOWS /* empty */ +#endif static int dont_gc; @@ -113,23 +127,6 @@ Fgc_disable() return old; } -VALUE -Fgc_threshold(obj) - VALUE obj; -{ - return INT2FIX(gc_threshold); -} - -VALUE -Fgc_set_threshold(obj, val) - VALUE obj, val; -{ - int old = gc_threshold; - - gc_threshold = NUM2INT(val); - return INT2FIX(old); -} - #include <sys/types.h> #include <sys/times.h> @@ -145,140 +142,204 @@ static Fgc_end() VALUE M_GC; -static ID start_hook, end_hook; +static struct gc_list { + int n; + VALUE *varptr; + struct gc_list *next; +} *Global_List = Qnil; -struct RBasic * -newobj(size) - unsigned long size; +void +rb_global_variable(var) + VALUE *var; { - struct RBasic *obj = Qnil; + struct gc_list *tmp; - if (bytes_alloc + size > gc_threshold) { - gc(); - } - obj = (struct RBasic*)xmalloc(size); - obj->next = object_list; - object_list = obj; - obj->flags = fl_current; - obj->iv_tbl = Qnil; + tmp = (struct gc_list*)xmalloc(sizeof(struct gc_list)); + tmp->next = Global_List; + tmp->varptr = var; + tmp->n = 1; + Global_List = tmp; +} - return obj; +struct RVALUE { + union { + struct { + int flag; /* alway 0 for freed obj */ + struct RVALUE *next; + } free; + struct RObject object; + struct RClass class; + struct RFloat flonum; + struct RString string; + struct RArray array; + struct RRegexp regexp; + struct RDict dict; + struct RData data; + struct RStruct rstruct; + struct RBignum bignum; + } as; +} *freelist = Qnil; + +struct heap_block { + struct heap_block *next; + struct RVALUE *beg; + struct RVALUE *end; + struct RVALUE body[1]; +} *heap_link = Qnil; + +#define SEG_SLOTS 4000 +#define SEG_SIZE (SEG_SLOTS*sizeof(struct RVALUE)) + +static int heap_size; + +static void +add_heap() +{ + struct heap_block *block; + struct RVALUE *p, *pend; + + block = (struct heap_block*)malloc(sizeof(*block) + SEG_SIZE); + if (block == Qnil) Fatal("cant alloc memory"); + block->next = heap_link; + block->beg = &block->body[0]; + block->end = block->beg + SEG_SLOTS; + p = block->beg; pend = block->end; + while (p < pend) { + p->as.free.flag = 0; + p->as.free.next = freelist; + freelist = p; + p++; + } + heap_link = block; + heap_size += SEG_SLOTS; } -literalize(obj) - struct RBasic *obj; +struct RBasic * +newobj() { - struct RBasic *ptr = object_list; + struct RBasic *obj; + if (heap_link == Qnil) add_heap(); + if (freelist) { + retry: + obj = (struct RBasic*)freelist; + freelist = freelist->as.free.next; + obj->flags = 0; + obj->iv_tbl = Qnil; + return obj; + } + if (dont_gc) add_heap(); + else gc(); - if (NIL_P(obj) || FIXNUM_P(obj)) return; + goto retry; +} - FL_SET(obj, FL_LITERAL); - if (ptr == obj) { - object_list = ptr->next; - obj->next = literal_list; - literal_list = obj; +VALUE +newdata(size) + UINT size; +{ + extern VALUE C_Data; + struct RData *data = (struct RData*)newobj(); - return; - } + OBJSETUP(data, C_Data, T_DATA); + data->data = xmalloc(size); + return (VALUE)data; +} - while (ptr && ptr->next) { - if (ptr->next == obj) { - ptr->next = obj->next; - obj->next = literal_list; - literal_list = obj; +static struct literal_list { + VALUE val; + struct literal_list *next; +} *Literal_List = Qnil; - return; - } - ptr = ptr->next; - } - Bug("0x%x is not a object.", obj); +void +literalize(obj) + VALUE obj; +{ + struct literal_list *tmp; + + tmp = (struct literal_list*)xmalloc(sizeof(struct literal_list)); + tmp->next = Literal_List; + tmp->val = obj; + Literal_List = tmp; } void unliteralize(obj) - struct RBasic *obj; + VALUE obj; { - struct RBasic *ptr = literal_list; + struct literal_list *ptr = Literal_List, *tmp; if (NIL_P(obj) || FIXNUM_P(obj)) return; if (!FL_TEST(obj, FL_LITERAL)) return; FL_UNSET(obj, FL_LITERAL); - if (ptr == obj) { - literal_list = ptr->next; - goto unlit; + if (ptr->val == obj) { + Literal_List = ptr->next; + free(ptr); + return; } while (ptr->next) { - if (ptr->next == obj) { - ptr->next = obj->next; + if (ptr->next->val == obj) { + tmp = ptr->next; + ptr->next = ptr->next->next; + ptr = tmp; + free(tmp); + return; } ptr = ptr->next; - goto unlit; } Bug("0x%x is not a literal object.", obj); - - unlit: - obj->next = object_list; - object_list = obj; - obj->flags &= ~FL_MARK; - obj->flags |= fl_current; - return; } -extern st_table *rb_global_tbl; extern st_table *rb_class_tbl; +static VALUE *stack_start_ptr; -gc() +static long +looks_pointerp(p) + struct RVALUE *p; { - struct gc_list *list; - struct ENVIRON *env; - int i, max; - - rb_funcall(M_GC, start_hook, 0, Qnil); - - if (dont_gc) return; - dont_gc++; - fl_old = fl_current; - fl_current = ~fl_current & FL_MARK; - - /* mark env stack */ - for (env = the_env; env; env = env->prev) { - mark(env->self); - for (i=1, max=env->argc; i<max; i++) { - mark(env->argv[i]); - } - if (env->local_vars) { - for (i=0, max=env->local_tbl[0]; i<max; i++) - mark(env->local_vars[i]); - } - } - - /* mark protected C variables */ - for (list=GC_List; list; list=list->next) { - VALUE *v = list->varptr; - for (i=0, max = list->n; i<max; i++) { - mark(*v); - v++; - } - } - - /* mark protected global variables */ - for (list = Global_List; list; list = list->next) { - mark(*list->varptr); + struct heap_block *heap = heap_link; + + if (FIXNUM_P(p)) return FALSE; + while (heap) { + if (heap->beg <= p && p < heap->end + && ((((char*)p) - ((char*)heap->beg)) % sizeof(struct RVALUE)) == 0) + return TRUE; + heap = heap->next; } + return FALSE; +} - mark_global_tbl(); - mark_tbl(rb_class_tbl); - - mark_trap_list(); +static void +mark_locations_array(x, n) + VALUE *x; + long n; +{ + int j; + VALUE p; + for(j=0;j<n;++j) + {p = x[j]; + if (looks_pointerp(p)) { + gc_mark(p); + } + } +} - sweep(); - bytes_alloc = 0; - dont_gc--; +static void +mark_locations(start, end) + VALUE *start, *end; +{ + VALUE *tmp; + long n; - rb_funcall(M_GC, end_hook, 0, Qnil); + if (start > end) { + tmp = start; + start = end; + end = tmp; + } + n = end - start; + mark_locations_array(start,n); } static @@ -286,7 +347,7 @@ mark_entry(key, value) ID key; VALUE value; { - mark(value); + gc_mark(value); return ST_CONTINUE; } @@ -302,8 +363,8 @@ mark_dicentry(key, value) ID key; VALUE value; { - mark(key); - mark(value); + gc_mark(key); + gc_mark(value); return ST_CONTINUE; } @@ -314,39 +375,35 @@ mark_dict(tbl) st_foreach(tbl, mark_dicentry, 0); } -mark(obj) +void +gc_mark(obj) register struct RBasic *obj; { if (obj == Qnil) return; if (FIXNUM_P(obj)) return; - if ((obj->flags & FL_MARK) == fl_current) return; + if (obj->flags & FL_MARK) return; - obj->flags &= ~FL_MARK; - obj->flags |= fl_current; + obj->flags |= FL_MARK; switch (obj->flags & T_MASK) { case T_NIL: case T_FIXNUM: - Bug("mark() called for broken object"); + Bug("gc_mark() called for broken object"); break; } if (obj->iv_tbl) mark_tbl(obj->iv_tbl); + gc_mark(obj->class); switch (obj->flags & T_MASK) { - case T_OBJECT: - mark(obj->class); - break; case T_ICLASS: - mark(RCLASS(obj)->super); + gc_mark(RCLASS(obj)->super); if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl); - mark_tbl(RCLASS(obj)->m_tbl); break; case T_CLASS: - mark(RCLASS(obj)->super); + gc_mark(RCLASS(obj)->super); case T_MODULE: if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl); - mark_tbl(RCLASS(obj)->m_tbl); - mark(RBASIC(obj)->class); + gc_mark(RBASIC(obj)->class); break; case T_ARRAY: { @@ -354,21 +411,21 @@ mark(obj) VALUE *ptr = RARRAY(obj)->ptr; for (i=0; i < len; i++) - mark(ptr[i]); + gc_mark(ptr[i]); } break; case T_DICT: mark_dict(RDICT(obj)->tbl); break; case T_STRING: - if (RSTRING(obj)->orig) mark(RSTRING(obj)->orig); + if (RSTRING(obj)->orig) gc_mark(RSTRING(obj)->orig); break; case T_DATA: if (RDATA(obj)->dmark) (*RDATA(obj)->dmark)(DATA_PTR(obj)); break; + case T_OBJECT: case T_REGEXP: case T_FLOAT: - case T_METHOD: case T_BIGNUM: break; case T_STRUCT: @@ -377,42 +434,77 @@ mark(obj) struct kv_pair *ptr = RSTRUCT(obj)->tbl; for (i=0; i < len; i++) - mark(ptr[i].value); + gc_mark(ptr[i].value); } break; default: - Bug("mark(): unknown data type %d", obj->flags & T_MASK); + Bug("gc_mark(): unknown data type %d", obj->flags & T_MASK); } } -sweep() -{ - register struct RBasic *link = object_list; - register struct RBasic *next; - - if (link && (link->flags & FL_MARK) == fl_old) { - object_list = object_list->next; - obj_free(link); - link = object_list; - } +#define MIN_FREE_OBJ 512 - while (link && link->next) { - if ((link->next->flags & FL_MARK) == fl_old) { - next = link->next->next; - obj_free(link->next); - link->next = next; - continue; +static void +gc_sweep() +{ + struct heap_block *heap = heap_link; + int freed = 0; + + freelist = Qnil; + while (heap) { + struct RVALUE *p, *pend; + struct RVALUE *nfreelist; + int n = 0; + + nfreelist = freelist; + p = heap->beg; pend = heap->end; + while (p < pend) { + + if (!(RBASIC(p)->flags & FL_MARK)) { + if (RBASIC(p)->flags) obj_free(p); + p->as.free.flag = 0; + p->as.free.next = nfreelist; + nfreelist = p; + n++; + } + RBASIC(p)->flags &= ~FL_MARK; + p++; + } + if (n == SEG_SLOTS) { + struct heap_block *link = heap_link; + if (heap != link) { + while (link) { + if (link->next && link->next == heap) { + link->next = heap->next; + break; + } + link = link->next; + } + if (link == Qnil) { + Bug("non-existing heap at 0x%x", heap); + } + } + free(heap); + heap_size -= SEG_SLOTS; + heap = link; } - link = link->next; + else { + freed += n; + freelist = nfreelist; + } + heap = heap->next; + } + if (freed < heap_size/4) { + add_heap(); } } static freemethod(key, body) ID key; - char *body; + void *body; { - freenode(body); + method_free(body); return ST_CONTINUE; } @@ -432,6 +524,7 @@ obj_free(obj) break; case T_MODULE: case T_CLASS: + rb_clear_cache2(obj); st_foreach(RCLASS(obj)->m_tbl, freemethod); st_free_table(RCLASS(obj)->m_tbl); if (RCLASS(obj)->c_tbl) @@ -452,14 +545,12 @@ obj_free(obj) break; case T_DATA: if (RDATA(obj)->dfree) (*RDATA(obj)->dfree)(DATA_PTR(obj)); + free(DATA_PTR(obj)); break; case T_ICLASS: /* iClass shares table with the module */ case T_FLOAT: break; - case T_METHOD: - freenode(RMETHOD(obj)->node); - break; case T_STRUCT: free(RSTRUCT(obj)->name); free(RSTRUCT(obj)->tbl); @@ -468,9 +559,69 @@ obj_free(obj) free(RBIGNUM(obj)->digits); break; default: - Bug("sweep(): unknown data type %d", obj->flags & T_MASK); + Bug("gc_sweep(): unknown data type %d", obj->flags & T_MASK); + } +} + +void +gc() +{ + struct literal_list *lit; + struct gc_list *list; + struct ENVIRON *env; + int i, max; + jmp_buf save_regs_gc_mark; + VALUE stack_end; + + if (dont_gc) return; + dont_gc++; + + /* mark env stack */ + for (env = the_env; env; env = env->prev) { + gc_mark(env->self); + if (env->argv) + mark_locations_array(env->argv, env->argc); + if (env->local_vars) + mark_locations_array(env->local_vars, env->local_tbl[0]); } - free(obj); + + FLUSH_REGISTER_WINDOWS; + /* This assumes that all registers are saved into the jmp_buf */ + setjmp(save_regs_gc_mark); + mark_locations((VALUE*)save_regs_gc_mark, + (VALUE*)(((char*)save_regs_gc_mark)+sizeof(save_regs_gc_mark))); + mark_locations((VALUE*)save_regs_gc_mark, + sizeof save_regs_gc_mark/sizeof(VALUE)); + mark_locations(stack_start_ptr, (VALUE*) &stack_end); +#if defined(THINK_C) + mark_locations(((char*)stack_start_ptr + 2), + ((char*)&stack_end + 2)); +#endif + + /* mark protected global variables */ + for (list = Global_List; list; list = list->next) { + gc_mark(*list->varptr); + } + + /* mark literal objects */ + for (lit = Literal_List; lit; lit = lit->next) { + gc_mark(lit->val); + } + + gc_mark_global_tbl(); + mark_tbl(rb_class_tbl); + + gc_mark_trap_list(); + + gc_sweep(); + dont_gc--; +} + +Init_stack() +{ + VALUE start; + + stack_start_ptr = &start; } Init_GC() @@ -479,12 +630,5 @@ Init_GC() rb_define_single_method(M_GC, "start", gc, 0); rb_define_single_method(M_GC, "enable", Fgc_enable, 0); rb_define_single_method(M_GC, "disable", Fgc_disable, 0); - rb_define_single_method(M_GC, "threshold", Fgc_threshold, 0); - rb_define_single_method(M_GC, "threshold=", Fgc_set_threshold, 1); - rb_define_single_method(M_GC, "start_hook", Fgc_begin, 0); - rb_define_single_method(M_GC, "end_hook", Fgc_end, 0); - rb_define_func(M_GC, "garbage_collect", gc, 0); - - start_hook = rb_intern("start_hook"); - end_hook = rb_intern("end_hook"); + rb_define_method(M_GC, "garbage_collect", gc, 0); } @@ -174,9 +174,7 @@ read_all(port) } if (fptr->f == NULL) Fail("closed stream"); - GC_LINK; - GC_PRO3(str, str_new(0, 0)); - + str = str_new(0, 0); for (;;) { n = fread(buf, 1, BUFSIZ, fptr->f); if (n == 0) { @@ -185,8 +183,6 @@ read_all(port) } str_cat(str, buf, n); } - - GC_UNLINK; return str; } @@ -252,9 +248,6 @@ Fio_gets(obj) f = fptr->f; if (f == NULL) Fail("closed stream"); - GC_LINK; - GC_PRO2(str); - if (RS) { rslen = RSTRING(RS)->len; if (rslen == 0) { @@ -329,8 +322,6 @@ Fio_gets(obj) } } - GC_UNLINK; - if (str) { fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -345,7 +336,6 @@ Fio_each(obj) { VALUE str; - GC_PRO2(str); while (str = Fio_gets(obj)) { rb_yield(str); } @@ -574,9 +564,7 @@ pipe_open(pname, mode) int pid, pr[2], pw[2]; int doexec; - GC_LINK; - GC_PRO3(port, obj_alloc(C_IO)); - + port = obj_alloc(C_IO); MakeOpenFile(port, fptr); fptr->mode = io_mode_flags(mode); @@ -631,8 +619,6 @@ pipe_open(pname, mode) if (fptr->mode & FMODE_READABLE) fptr->f = rb_fdopen(pr[0], "r"); if (fptr->mode & FMODE_WRITABLE) fptr->f2 = rb_fdopen(pw[1], "w"); - GC_UNLINK; - return port; } @@ -672,13 +658,13 @@ Fprintf(argc, argv) int argc; VALUE argv[]; { - VALUE out, str; + VALUE out; if (argc == 1) return Qnil; if (TYPE(argv[1]) == T_STRING) { out = rb_defout; } - else if (rb_get_method_body(CLASS_OF(argv[1]), id_write, 0, MTH_FUNC)) { + else if (obj_responds_to(argv[1], INT2FIX(id_write))) { out = argv[1]; argv++; argc--; @@ -687,12 +673,7 @@ Fprintf(argc, argv) Fail("output must responds to `write'"); } - GC_LINK; - GC_PRO3(str, Fsprintf(argc, argv)); - - rb_funcall(out, id_write, 1, str); - - GC_UNLINK; + rb_funcall(out, id_write, 1, Fsprintf(argc, argv)); return Qnil; } @@ -740,12 +721,9 @@ prep_stdio(f, mode) VALUE obj = obj_alloc(C_IO); OpenFile *fp; - GC_LINK; - GC_PRO(obj); MakeOpenFile(obj, fp); fp->f = f; fp->mode = mode; - GC_UNLINK; return obj; } @@ -874,15 +852,11 @@ Freadlines(obj) { VALUE line, ary; - GC_LINK; - GC_PRO2(line); - GC_PRO3(ary, ary_new()); - + ary = ary_new(); while (line = Fgets(obj)) { Fary_push(ary, line); } - GC_UNLINK; return ary; } @@ -898,9 +872,8 @@ rb_check_str(val, id) return TRUE; } -static VALUE -Fsystem2(obj, str) - VALUE obj; +VALUE +rb_xstring(str) struct RString *str; { VALUE port, result; @@ -908,10 +881,7 @@ Fsystem2(obj, str) int mask; Check_Type(str, T_STRING); - GC_LINK; - GC_PRO3(port, pipe_open(str->ptr, "r")); - GC_PRO2(result); - + port = pipe_open(str->ptr, "r"); result = read_all(port); GetOpenFile(port, fptr); @@ -919,7 +889,6 @@ Fsystem2(obj, str) fptr->pid = 0; obj_free(port); - GC_UNLINK; return result; } @@ -1026,8 +995,7 @@ Fselect(obj, args) } if (n == 0) return Qnil; - GC_LINK; - GC_PRO3(res, ary_new2(3)); + res = ary_new2(3); RARRAY(res)->ptr[0] = rp?ary_new():Qnil; RARRAY(res)->len++; RARRAY(res)->ptr[1] = wp?ary_new():Qnil; @@ -1075,7 +1043,6 @@ Fselect(obj, args) } } - GC_UNLINK; return res; } @@ -1141,6 +1108,100 @@ Fio_defset(obj, val) return rb_defout = val; } +static VALUE +Fsyscall(argc, argv) + int argc; + VALUE *argv; +{ +#ifdef HAVE_SYSCALL +#ifdef atarist + unsigned long arg[14]; /* yes, we really need that many ! */ +#else + unsigned long arg[8]; +#endif + int retval = -1; + int i = 1; + int items = argc - 2; + + /* This probably won't work on machines where sizeof(long) != sizeof(int) + * or where sizeof(long) != sizeof(char*). But such machines will + * not likely have syscall implemented either, so who cares? + */ + argv++; /* skip SELF */ + arg[0] = NUM2INT(argv[0]); argv++; + while (items--) { + if (FIXNUM_P(*argv)) { + arg[i] = (unsigned long)NUM2INT(*argv); argv++; + } + else { + Check_Type(*argv, T_STRING); + str_modify(*argv); + arg[i] = (unsigned long)RSTRING(*argv)->ptr; argv++; + } + i++; + } + switch (argc-1) { + case 0: + Fail("Too few args to syscall"); + case 1: + retval = syscall(arg[0]); + break; + case 2: + retval = syscall(arg[0],arg[1]); + break; + case 3: + retval = syscall(arg[0],arg[1],arg[2]); + break; + case 4: + retval = syscall(arg[0],arg[1],arg[2],arg[3]); + break; + case 5: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]); + break; + case 6: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]); + break; + case 7: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]); + break; + case 8: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7]); + break; +#ifdef atarist + case 9: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8]); + break; + case 10: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9]); + break; + case 11: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10]); + break; + case 12: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11]); + break; + case 13: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]); + break; + case 14: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13]); + break; +#endif /* atarist */ + } + if (retval == -1) rb_sys_fail(0); + return Qnil; +#else + Fail("syscall() unimplemented"); +#endif +} + extern VALUE M_Enumerable; VALUE rb_readonly_hook(); @@ -1148,17 +1209,18 @@ Init_IO() { extern VALUE C_Kernel; - rb_define_func(C_Kernel, "open", Fopen, -2); - rb_define_func(C_Kernel, "printf", Fprintf, -1); + rb_define_method(C_Kernel, "syscall", Fsyscall, -1); + + rb_define_method(C_Kernel, "open", Fopen, -2); + rb_define_method(C_Kernel, "printf", Fprintf, -1); rb_define_method(C_Kernel, "print", Fprint, -1); - rb_define_func(C_Kernel, "gets", Fgets, 0); - rb_define_func(C_Kernel, "eof", Feof, 0); + rb_define_method(C_Kernel, "gets", Fgets, 0); + rb_define_method(C_Kernel, "eof", Feof, 0); rb_define_alias(C_Kernel,"readline", "gets"); - rb_define_func(C_Kernel, "getc", Fgetc, 0); - rb_define_func(C_Kernel, "system2", Fsystem2, 1); - rb_define_func(C_Kernel, "select", Fselect, -2); + rb_define_method(C_Kernel, "getc", Fgetc, 0); + rb_define_method(C_Kernel, "select", Fselect, -2); - rb_define_func(C_Kernel, "readlines", Freadlines, 0); + rb_define_method(C_Kernel, "readlines", Freadlines, 0); C_IO = rb_define_class("IO", C_Object); rb_include_module(C_IO, M_Enumerable); @@ -1191,7 +1253,7 @@ Init_IO() rb_define_method(C_IO, "read", Fio_read, -2); rb_define_method(C_IO, "write", Fio_write, 1); rb_define_method(C_IO, "gets", Fio_gets, 0); - rb_define_alias(C_IO, "readlines", "gets"); + rb_define_alias(C_IO, "readline", "gets"); rb_define_method(C_IO, "getc", Fio_getc, 0); rb_define_method(C_IO, "puts", Fio_puts, 1); rb_define_method(C_IO, "<<", Fio_puts, 1); @@ -24,11 +24,8 @@ if (FIXNUM_P(x)) {\ } #define Need_Float2(x,y) {\ - GC_LINK;\ - GC_PRO(x);\ Need_Float(x);\ Need_Float(y);\ - GC_UNLINK;\ } static VALUE @@ -14,6 +14,9 @@ #include "ident.h" #include "env.h" #include "node.h" +#include "methods.h" + +void method_free(); #define CACHE_SIZE 577 #if 0 @@ -28,18 +31,18 @@ struct hash_entry { /* method hash table. */ ID mid; /* method's id */ struct RClass *class; /* receiver's class */ struct RClass *origin; /* where method defined */ - struct RMethod *method; - enum mth_scope scope; + struct SMethod *method; + int undef; }; static struct hash_entry cache[CACHE_SIZE]; -static struct RMethod* +static struct SMethod* search_method(class, id, origin) struct RClass *class, **origin; ID id; { - struct RMethod *body; + struct SMethod *body; NODE *list; while (!st_lookup(class->m_tbl, id, &body)) { @@ -55,21 +58,19 @@ search_method(class, id, origin) } NODE* -rb_get_method_body(class, id, envset, scope) +rb_get_method_body(class, id, envset) struct RClass *class; ID id; int envset; - enum mth_scope scope; { int pos, i; - int cscope; - struct RMethod *method; + struct SMethod *method; /* is it in the method cache? */ pos = EXPR1(class, id) % CACHE_SIZE; if (cache[pos].class != class || cache[pos].mid != id) { /* not in the cache */ - struct RMethod *body; + struct SMethod *body; struct RClass *origin; if ((body = search_method(class, id, &origin)) == Qnil) { @@ -80,13 +81,11 @@ rb_get_method_body(class, id, envset, scope) cache[pos].class = class; cache[pos].origin = origin; cache[pos].method = body; - cache[pos].scope = body->scope; + cache[pos].undef = body->undef; } - cscope = cache[pos].scope; method = cache[pos].method; - if (cscope == MTH_UNDEF) return Qnil; - if (cscope == MTH_FUNC && scope == MTH_METHOD) return Qnil; + if (cache[pos].undef) return Qnil; if (envset) { the_env->last_func = method->id; the_env->last_class = cache[pos].origin; @@ -99,21 +98,23 @@ rb_alias(class, name, def) struct RClass *class; ID name, def; { - struct RMethod *body; + struct SMethod *body; if (st_lookup(class->m_tbl, name, &body)) { if (verbose) { Warning("redefine %s", rb_id2name(name)); } - unliteralize(body); + rb_clear_cache(body); + method_free(body); } body = search_method(class, def, &body); + body->count++; st_insert(class->m_tbl, name, body); } void rb_clear_cache(body) - struct RMethod *body; + struct SMethod *body; { int i; @@ -129,17 +130,23 @@ void rb_clear_cache2(class) struct RClass *class; { + int i; - class = class->super; - while (class) { - int i; - - for (i = 0; i< CACHE_SIZE; i++ ) { - if (cache[i].origin == class) { - cache[i].class = Qnil; - cache[i].mid = Qnil; - } + for (i = 0; i< CACHE_SIZE; i++ ) { + if (cache[i].origin == class) { + cache[i].class = Qnil; + cache[i].mid = Qnil; } - class = class->super; + } +} + +void +method_free(body) + struct SMethod *body; +{ + body->count--; + if (body->count == 0) { + freenode(body->node); + free(body); } } diff --git a/methods.h b/methods.h new file mode 100644 index 0000000000..944eb8829c --- /dev/null +++ b/methods.h @@ -0,0 +1,22 @@ +/************************************************ + + methods.h - + + $Author$ + $Revision$ + $Date$ + created at: Fri Jul 29 14:43:03 JST 1994 + +************************************************/ +#ifndef METHOD_H +#define METHOD_H + +struct SMethod { + struct node *node; + struct RClass *origin; + ID id; + int count; + int undef; +}; + +#endif diff --git a/missing/strftime.c b/missing/strftime.c index 36a325aa51..4d3561c78c 100644 --- a/missing/strftime.c +++ b/missing/strftime.c @@ -101,7 +101,9 @@ adddecl(static int iso8601wknum(const struct tm *timeptr);) #if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME) extern char *tzname[2]; +# ifdef HAVE_DAYLIGHT extern int daylight; +# endif #endif /* min --- return minimum of two numbers */ @@ -457,7 +459,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) goto again; case 'V': /* week of year according ISO 8601 */ -#if defined(RUBY) && defined(VMS_EXT) +#if defined(GAWK) && defined(VMS_EXT) { extern int do_lint; extern void warning(); @@ -1,4 +1,4 @@ -#! ./ruby +#! /usr/local/bin/ruby f = open("version.h", "r") f.gets() f.close @@ -39,6 +39,7 @@ enum node_type { NODE_ZSUPER, NODE_ARRAY, NODE_ZARRAY, + NODE_QLIST, NODE_HASH, NODE_REDO, NODE_BREAK, @@ -54,6 +55,10 @@ enum node_type { NODE_CONST, NODE_LIT, NODE_STR, + NODE_STR2, + NODE_XSTR, + NODE_XSTR2, + NODE_DREGX, NODE_ARGS, NODE_DEFN, NODE_DEFS, @@ -78,7 +83,6 @@ typedef struct node { VALUE value; VALUE (*cfunc)(); ID *tbl; - enum mth_scope scope; } u1; union { struct node *node; @@ -135,7 +139,6 @@ typedef struct node { #define nd_mid u2.id #define nd_args u3.node -#define nd_scope u1.scope #define nd_defn u3.node #define nd_new u1.id @@ -155,7 +158,7 @@ typedef struct node { #define nd_rval u3.node -#define NEW_DEFN(i,d,m) newnode(NODE_DEFN,m,i,d) +#define NEW_DEFN(i,d) newnode(NODE_DEFN,Qnil,i,d) #define NEW_DEFS(r,i,d) newnode(NODE_DEFS,r,i,d) #define NEW_CFUNC(f,c) newnode(NODE_CFUNC,f,c,Qnil) #define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2)) @@ -177,6 +180,7 @@ typedef struct node { #define NEW_RET(s) newnode(NODE_RETURN,s,Qnil,Qnil) #define NEW_YIELD(a) newnode(NODE_YIELD,a,Qnil,Qnil) #define NEW_LIST(a) NEW_ARRAY(a) +#define NEW_QLIST(a) newnode(NODE_QLIST,a,Qnil,Qnil) #define NEW_ARRAY(a) newnode(NODE_ARRAY,a,Qnil,Qnil) #define NEW_ZARRAY() newnode(NODE_ZARRAY,Qnil,Qnil,Qnil) #define NEW_HASH(a) newnode(NODE_HASH,a,Qnil,Qnil) @@ -194,6 +198,9 @@ typedef struct node { #define NEW_CVAR(v) newnode(NODE_CVAR,v,Qnil,Qnil) #define NEW_LIT(l) newnode(NODE_LIT,l,Qnil,Qnil) #define NEW_STR(s) newnode(NODE_STR,s,Qnil,Qnil) +#define NEW_STR2(s) newnode(NODE_STR2,s,Qnil,Qnil) +#define NEW_XSTR(s) newnode(NODE_XSTR,s,Qnil,Qnil) +#define NEW_XSTR2(s) newnode(NODE_XSTR2,s,Qnil,Qnil) #define NEW_CALL(r,m,a) newnode(NODE_CALL,r,m,a) #define NEW_CALL2(r,m,a) newnode(NODE_CALL2,r,m,a) #define NEW_SUPER(a) newnode(NODE_SUPER,Qnil,Qnil,a) @@ -128,11 +128,8 @@ Fnum_divmod(x, y) { VALUE div, mod; - GC_LINK; - GC_PRO3(div, rb_funcall(x, '/', 1, y)); - GC_PRO3(mod, rb_funcall(x, '%', 1, y)); - GC_UNLINK; - + div = rb_funcall(x, '/', 1, y); + mod = rb_funcall(x, '%', 1, y); return assoc_new(div, mod); } @@ -437,19 +434,17 @@ int num2int(val) VALUE val; { - int result; - if (val == Qnil) return 0; switch (TYPE(val)) { case T_FIXNUM: - result = FIX2INT(val); + return FIX2INT(val); break; case T_FLOAT: if (RFLOAT(val)->value <= (double) LONG_MAX && RFLOAT(val)->value >= (double) LONG_MIN) { - result = (int)RFLOAT(val)->value; + return (int)RFLOAT(val)->value; } else { Fail("float %g out of rang of integer", RFLOAT(val)->value); @@ -463,7 +458,6 @@ num2int(val) Fail("failed to convert %s into int", rb_class2name(CLASS_OF(val))); break; } - return result; } static VALUE @@ -578,12 +572,7 @@ Ffix_plus(x, y) r = INT2FIX(c); if (FIX2INT(r) != c) { - VALUE big1, big2; - GC_LINK; - GC_PRO3(big1, int2big(a)); - GC_PRO3(big2, int2big(b)); - r = Fbig_plus(big1, big2); - GC_UNLINK; + r = Fbig_plus(int2big(a), int2big(b)); } return r; } @@ -611,12 +600,7 @@ Ffix_minus(x, y) r = INT2FIX(c); if (FIX2INT(r) != c) { - VALUE big1, big2; - GC_LINK; - GC_PRO3(big1, int2big(a)); - GC_PRO3(big2, int2big(b)); - r = Fbig_minus(big1, big2); - GC_UNLINK; + r = Fbig_minus(int2big(a), int2big(b)); } return r; } @@ -640,12 +624,7 @@ Ffix_mul(x, y) VALUE r = INT2FIX(c); if (FIX2INT(r) != c) { - VALUE big1, big2; - GC_LINK; - GC_PRO3(big1, int2big(a)); - GC_PRO3(big2, int2big(b)); - r = Fbig_mul(big1, big2); - GC_UNLINK; + r = Fbig_mul(int2big(a), int2big(b)); } return r; } @@ -692,18 +671,22 @@ Ffix_pow(x, y) VALUE x, y; { extern double pow(); - int result; if (FIXNUM_P(y)) { - result = pow((double)FIX2INT(x), (double)FIX2INT(y)); - return int2inum(result); + int a, b; + + b = FIX2INT(y); + if (b == 0) return INT2FIX(1); + a = FIX2INT(x); + if (b > 0) { + return Fbig_pow(int2big(a), y); + } + return float_new(pow((double)a, (double)b)); } else if (NIL_P(y)) { return INT2FIX(1); } - else { - return num_coerce_bin(x, y); - } + return num_coerce_bin(x, y); } static VALUE @@ -804,12 +787,7 @@ Ffix_lshift(x, y) width = NUM2INT(y); if (width > (sizeof(VALUE)*CHAR_BIT-1) || (unsigned)val>>(sizeof(VALUE)*CHAR_BIT-width) > 0) { - VALUE big; - GC_LINK; - GC_PRO3(big, int2big(val)); - big = Fbig_lshift(big, y); - GC_UNLINK; - return big; + return Fbig_lshift(int2big(val), y); } val = val << width; return int2inum(val); @@ -142,13 +142,11 @@ obj_inspect(id, value, str) else { str_cat(str, ", ", 2); } - GC_LINK; ivname = rb_id2name(id); str_cat(str, ivname, strlen(ivname)); str_cat(str, "=", 1); - GC_PRO3(str2, rb_funcall(value, rb_intern("_inspect"), 0, Qnil)); + str2 = rb_funcall(value, rb_intern("_inspect"), 0, Qnil); str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); - GC_UNLINK; return ST_CONTINUE; } @@ -162,12 +160,10 @@ Fobj_inspect(obj) if (FIXNUM_P(obj) || !obj->iv_tbl) return Fkrn_to_s(obj); - GC_LINK; sprintf(buf, "-<%s: ", rb_class2name(CLASS_OF(obj))); - GC_PRO3(str, str_new2(buf)); + str = str_new2(buf); st_foreach(obj->iv_tbl, obj_inspect, str); str_cat(str, ">", 1); - GC_UNLINK; return str; } @@ -224,13 +220,10 @@ Fobj_clone(obj) Check_Type(obj, T_OBJECT); clone = obj_alloc(RBASIC(obj)->class); - GC_LINK; - GC_PRO(clone); if (RBASIC(obj)->iv_tbl) { RBASIC(clone)->iv_tbl = st_copy(RBASIC(obj)->iv_tbl); } RBASIC(clone)->class = single_class_clone(RBASIC(obj)->class); - GC_UNLINK; return clone; } @@ -263,6 +256,7 @@ Fnil_plus(x, y) switch (TYPE(y)) { case T_FIXNUM: case T_FLOAT: + case T_BIGNUM: case T_STRING: case T_ARRAY: return y; @@ -399,14 +393,14 @@ Init_Object() rb_define_method(C_Kernel, "to_s", Fkrn_to_s, 0); rb_define_method(C_Kernel, "_inspect", Fkrn_inspect, 0); - rb_define_func(C_Kernel, "caller", Fcaller, -2); - rb_define_func(C_Kernel, "fail", Ffail, -2); - rb_define_func(C_Kernel, "exit", Fexit, -2); - rb_define_func(C_Kernel, "eval", Feval, 1); - rb_define_func(C_Kernel, "defined", Fdefined, 1); - rb_define_func(C_Kernel, "sprintf", Fsprintf, -1); + rb_define_method(C_Kernel, "caller", Fcaller, -2); + rb_define_method(C_Kernel, "fail", Ffail, -2); + rb_define_method(C_Kernel, "exit", Fexit, -2); + rb_define_method(C_Kernel, "eval", Feval, 1); + rb_define_method(C_Kernel, "defined", Fdefined, 1); + rb_define_method(C_Kernel, "sprintf", Fsprintf, -1); rb_define_alias(C_Kernel, "format", "sprintf"); - rb_define_func(C_Kernel, "iterator_p", Fiterator_p, 0); + rb_define_method(C_Kernel, "iterator_p", Fiterator_p, 0); rb_define_method(C_Kernel, "apply", Fapply, -2); @@ -422,7 +416,7 @@ Init_Object() rb_define_method(C_Module, "to_s", Fcls_to_s, 0); rb_define_method(C_Module, "clone", Fcant_clone, 0); - rb_define_func(C_Module, "attr", Fcls_attr, -2); + rb_define_method(C_Module, "attr", Fcls_attr, -2); rb_define_method(C_Class, "new", Fcls_new, -2); @@ -434,12 +428,6 @@ Init_Object() rb_define_method(C_Nil, "is_nil", P_true, 0); rb_define_method(C_Nil, "!", P_true, 0); - /* for compare cascading. */ - rb_define_method(C_Nil, ">", P_false, 1); - rb_define_alias(C_Nil, ">=", ">"); - rb_define_alias(C_Nil, "<", ">"); - rb_define_alias(C_Nil, "<=", ">"); - /* default addition */ rb_define_method(C_Nil, "+", Fnil_plus, 1); @@ -448,7 +436,7 @@ Init_Object() rb_define_method(C_Data, "class", Fdata_class, 0); C_Method = rb_define_class("Method", C_Kernel); - rb_define_method(C_Data, "clone", Fcant_clone, 0); + rb_define_method(C_Method, "clone", Fcant_clone, 0); eq = rb_intern("=="); match = rb_intern("=~"); @@ -65,9 +65,7 @@ Fpck_pack(ary, fmt) p = fmt->ptr; pend = fmt->ptr + fmt->len; - GC_LINK; - GC_PRO2(from); - GC_PRO3(res, str_new(0, 0)); + res = str_new(0, 0); items = ary->len; idx = 0; @@ -446,7 +444,6 @@ Fpck_pack(ary, fmt) break; } } - GC_UNLINK; return res; } @@ -499,8 +496,7 @@ Fpck_unpack(str, fmt) p = fmt->ptr; pend = p + fmt->len; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); while (p < pend) { retry: type = *p++; @@ -838,7 +834,6 @@ Fpck_unpack(str, fmt) } } - GC_UNLINK; return ary; } @@ -17,6 +17,7 @@ #include "env.h" #include "node.h" #include "st.h" +#include <stdio.h> #include "ident.h" #define is_id_nonop(id) ((id)>LAST_TOKEN) @@ -35,6 +36,9 @@ struct op_tbl { NODE *eval_tree = Qnil; static int in_regexp; +char *sourcefile; /* current source file */ +int sourceline; /* current line no. */ + enum { KEEP_STATE = 0, /* don't change lex_state. */ EXPR_BEG, /* ignore newline, +/- is a sign. */ @@ -57,6 +61,7 @@ static NODE *list_concat(); static NODE *list_copy(); static NODE *call_op(); +static NODE *gettable(); static NODE *asignable(); static NODE *aryset(); static NODE *attrset(); @@ -82,7 +87,6 @@ static void setup_top_local(); %token CLASS MODULE DEF - FUNC UNDEF INCLUDE IF @@ -111,16 +115,19 @@ static void setup_top_local(); RETRY SELF NIL + _FILE_ + _LINE_ -%token <id> IDENTIFIER GVAR IVAR CONSTANT -%token <val> INTEGER FLOAT STRING REGEXP +%token <id> IDENTIFIER GVAR IVAR CONSTANT +%token <val> INTEGER FLOAT STRING XSTRING REGEXP +%token <node> STRING2 XSTRING2 DREGEXP %type <node> singleton inc_list %type <val> literal numeric %type <node> compexpr exprs expr expr2 primary var_ref %type <node> if_tail opt_else cases resque ensure opt_using %type <node> call_args opt_args args f_arglist f_args f_arg -%type <node> assoc_list assocs assoc +%type <node> assoc_list assocs assoc regexp %type <node> mlhs mlhs_head mlhs_tail lhs %type <id> superclass variable symbol %type <id> fname fname0 op rest_arg end_mark @@ -152,10 +159,10 @@ static void setup_top_local(); %nonassoc DOT2 DOT3 %left OR %left AND -%left '|' '^' -%left '&' %nonassoc CMP EQ NEQ MATCH NMATCH %left '>' GEQ '<' LEQ +%left '|' '^' +%left '&' %left LSHFT RSHFT %left '+' '-' %left '*' '/' '%' @@ -241,24 +248,7 @@ expr : CLASS IDENTIFIER superclass if ($7 && $7 != DEF) { Error("unmatched end keyword(expected `def')"); } - $$ = NEW_DEFN($2, NEW_RFUNC($4, $5), MTH_METHOD); - pop_local(); - cur_mid = Qnil; - } - | DEF FUNC fname - { - if (cur_mid || in_single) - Error("nested method definition"); - cur_mid = $3; - push_local(); - } - f_arglist compexpr - END end_mark - { - if ($8 && $8 != DEF) { - Error("unmatched end keyword(expected `def')"); - } - $$ = NEW_DEFN($3, NEW_RFUNC($5, $6), MTH_FUNC); + $$ = NEW_DEFN($2, NEW_RFUNC($4, $5)); pop_local(); cur_mid = Qnil; } @@ -421,6 +411,14 @@ op : COLON2 { $$ = COLON2; } f_arglist : '(' f_args rparen { + if ($2) { + NODE *list = $2->nd_frml; + int i; + + for (i=0; list; list=list->nd_next, i++) + ; + $2->nd_cnt = i; + } $$ = $2; } | term @@ -457,7 +455,7 @@ f_arg : IDENTIFIER { if (!is_local_id($1)) Error("formal argument must be local variable"); - $$ = NEW_LIST(local_cnt($1)); + $$ = NEW_QLIST(local_cnt($1)); } | f_arg comma IDENTIFIER { @@ -887,26 +885,32 @@ args : expr2 } primary : var_ref - | '(' compexpr rparen + | literal { - $$ = $2; + literalize($1); + $$ = NEW_LIT($1); } - | STRING { literalize($1); $$ = NEW_STR($1); } + | STRING2 + | XSTRING + { + literalize($1); + $$ = NEW_XSTR($1); + } + | XSTRING2 + | '/' {in_regexp = 1;} regexp + { + $$ = $3; + } | primary '[' args rbracket { value_expr($1); $$ = NEW_CALL($1, AREF, $3); } - | literal - { - literalize($1); - $$ = NEW_LIT($1); - } | '[' opt_args rbracket { if ($2 == Qnil) @@ -949,16 +953,23 @@ primary : var_ref Error("super called outside of method"); $$ = NEW_ZSUPER(); } + | '(' compexpr rparen + { + $$ = $2; + } literal : numeric | '\\' symbol { $$ = INT2FIX($2); } - | '/' {in_regexp = 1;} REGEXP + +regexp : REGEXP { - $$ = $3; + literalize($1); + $$ = NEW_LIT($1); } + | DREGEXP symbol : fname0 | IVAR @@ -983,27 +994,7 @@ variable : IDENTIFIER var_ref : variable { - if ($1 == SELF) { - $$ = NEW_SELF(); - } - else if ($1 == NIL) { - $$ = NEW_NIL(); - } - else if (is_local_id($1)) { - if (local_id($1)) - $$ = NEW_LVAR($1); - else - $$ = NEW_MVAR($1); - } - else if (is_global_id($1)) { - $$ = NEW_GVAR($1); - } - else if (is_instance_id($1)) { - $$ = NEW_IVAR($1); - } - else if (is_const_id($1)) { - $$ = NEW_CVAR($1); - } + $$ = gettable($1); } assoc_list : /* none */ @@ -1027,7 +1018,6 @@ assoc : expr2 ASSOC expr2 end_mark : CLASS { $$ = CLASS; } | MODULE { $$ = MODULE; } | DEF { $$ = DEF; } - | FUNC { $$ = FUNC; } | IF { $$ = IF; } | UNLESS { $$ = UNLESS; } | CASE { $$ = CASE; } @@ -1054,7 +1044,6 @@ rbrace : '}' { yyerrok; } comma : ',' { yyerrok; } %% -#include <stdio.h> #include <ctype.h> #include <sys/types.h> #include "regex.h" @@ -1075,11 +1064,9 @@ char *strdup(); #define EXPAND_B 1 #define LEAVE_BS 2 +static NODE *var_extend(); static void read_escape(); -char *sourcefile; /* current source file */ -int sourceline; /* current line no. */ - static char *lex_p; static int lex_len; @@ -1135,7 +1122,9 @@ static struct kwtable { int id; int state; } kwtable [] = { - "__END__", 0, KEEP_STATE, + "__END__", 0, KEEP_STATE, + "__FILE__", _FILE_, EXPR_END, + "__LINE__", _LINE_, EXPR_END, "break", BREAK, EXPR_END, "case", CASE, KEEP_STATE, "class", CLASS, KEEP_STATE, @@ -1147,7 +1136,6 @@ static struct kwtable { "end", END, EXPR_END, "ensure", ENSURE, EXPR_BEG, "for", FOR, KEEP_STATE, - "func", FUNC, KEEP_STATE, "if", IF, KEEP_STATE, "in", IN, EXPR_BEG, "include", INCLUDE, EXPR_BEG, @@ -1170,6 +1158,8 @@ static struct kwtable { "yield", YIELD, EXPR_BEG, }; +static int strstart; + yylex() { register int c; @@ -1179,6 +1169,7 @@ yylex() if (in_regexp) { int in_brack = 0; int re_start = sourceline; + NODE *list = Qnil; in_regexp = 0; newtok(); @@ -1190,6 +1181,12 @@ yylex() case ']': in_brack = 0; break; + + case '#': + list = var_extend(list, '/'); + if (list == (NODE*)-1) return 0; + continue; + case '\\': if ((c = nextc()) == -1) { sourceline = re_start; @@ -1213,9 +1210,21 @@ yylex() break; tokfix(); - yylval.val = regexp_new(tok(), toklen()); lex_state = EXPR_END; - return REGEXP; + if (list) { + if (toklen() > 0) { + VALUE ss = str_new(tok(), toklen()); + literalize(ss); + list_append(list, NEW_STR(ss)); + } + list->type = NODE_DREGX; + yylval.node = list; + return DREGEXP; + } + else { + yylval.val = regexp_new(tok(), toklen()); + return REGEXP; + } case -1: Error("unterminated regexp"); @@ -1335,12 +1344,17 @@ retry: return '>'; case '"': + case '`': { - int strstart = sourceline; + char term = c; + NODE *list = Qnil; + ID id; + strstart = sourceline; newtok(); - while ((c = nextc()) != '"') { + while ((c = nextc()) != term) { if (c == -1) { + unterm_str: sourceline = strstart; Error("unterminated string meets end of file"); return 0; @@ -1352,12 +1366,17 @@ retry: else if (c == '\n') { sourceline++; } + else if (c == '#') { + list = var_extend(list, term); + if (list == (NODE*)-1) return 0; + continue; + } else if (c == '\\') { c = nextc(); if (c == '\n') { sourceline++; } - else if (c == '"') { + else if (c == term) { tokadd(c); } else { @@ -1369,22 +1388,34 @@ retry: tokadd(c); } tokfix(); - yylval.val = str_new(tok(), toklen()); lex_state = EXPR_END; - return STRING; + if (list == Qnil) { + yylval.val = str_new(tok(), toklen()); + return (term == '"') ? STRING : XSTRING; + } + else { + if (toklen() > 0) { + VALUE ss = str_new(tok(), toklen()); + literalize(ss); + list_append(list, NEW_STR(ss)); + } + yylval.node = list; + if (term == '"') { + return STRING2; + } + else { + list->type = NODE_XSTR2; + return XSTRING2; + } + } } case '\'': { - int strstart = sourceline; - - newtok(); + strstart = sourceline; + newtok(); while ((c = nextc()) != '\'') { - if (c == -1) { - sourceline = strstart; - Error("unterminated string meets end of file"); - return 0; - } + if (c == -1) goto unterm_str; if (ismbchar(c)) { tokadd(c); c = nextc(); @@ -1639,7 +1670,6 @@ retry: case ',': case ';': - case '`': case '[': case '(': case '{': @@ -1765,6 +1795,103 @@ retry: } } +static NODE* +var_extend(list, term) + NODE *list; + char term; +{ + int c, t; + VALUE ss; + ID id; + + c = nextc(); + switch (c) { + default: + tokadd('#'); + pushback(); + return list; + case '@': case '%': + t = nextc(); + pushback(); + if (!is_identchar(t)) { + tokadd('#'); + tokadd(c); + return list; + } + case '$': + case '{': + break; + } + + ss = str_new(tok(), toklen()); + if (list == Qnil) { + literalize(ss); + list = NEW_STR2(ss); + } + else if (toklen() > 0) { + literalize(ss); + list_append(list, NEW_STR(ss)); + } + newtok(); + if (c == '{') { + while ((c = nextc()) != '}') { + if (c == -1) { + unterm_str: + sourceline = strstart; + Error("unterminated string meets end of file"); + return (NODE*)-1; + } + if (isspace(c)) { + Error("Invalid variable name in string"); + break; + } + if (c == term) { + Error("Inmature variable name in string"); + pushback(); + return list; + } + tokadd(c); + } + } + else { + switch (c) { + case '$': + tokadd(c); + c = nextc(); + if (c == -1) goto unterm_str; + if (!is_identchar(c)) { + tokadd(c); + goto fetch_id; + } + /* through */ + case '@': case '%': + tokadd(c); + c = nextc(); + break; + } + while (is_identchar(c)) { + tokadd(c); + if (ismbchar(c)) { + c = nextc(); + tokadd(c); + } + c = nextc(); + } + pushback(); + } + fetch_id: + tokfix(); + if (strcmp("__LINE__", tok()) == 0) + id = _LINE_; + else if (strcmp("__FILE__", tok()) == 0) + id = _FILE_; + else + id = rb_intern(tok()); + list_append(list, gettable(id)); + newtok(); + return list; +} + static void read_escape(flag) int flag; @@ -1890,6 +2017,7 @@ read_escape(flag) if (flag & LEAVE_BS) { tokadd('\\'); } + case '#': tokadd(c); break; } @@ -1957,11 +2085,12 @@ static NODE* list_append(head, tail) NODE *head, *tail; { - if (head == Qnil) return NEW_ARRAY(tail); + if (head == Qnil) return NEW_LIST(tail); if (head->nd_last == Qnil) head->nd_last = head; - - head->nd_last->nd_next = NEW_ARRAY(tail); + + head->nd_last->nd_next = + head->type == NODE_QLIST?NEW_QLIST(tail):NEW_LIST(tail); head->nd_last = head->nd_last->nd_next; return head; } @@ -2007,9 +2136,17 @@ void freenode(node) case NODE_BLOCK: case NODE_ARRAY: freenode(node->nd_head); + case NODE_STR2: + case NODE_XSTR2: + case NODE_DREGX: + case NODE_QLIST: freenode(node->nd_next); break; + case NODE_HASH: + freenode(node->nd_head); + break; case NODE_IF: + case NODE_UNLESS: case NODE_WHEN: case NODE_PROT: freenode(node->nd_cond); @@ -2026,57 +2163,85 @@ void freenode(node) break; case NODE_DO: case NODE_FOR: + freenode(node->nd_var); freenode(node->nd_ibdy); freenode(node->nd_iter); break; case NODE_LASGN: case NODE_GASGN: case NODE_IASGN: + case NODE_CASGN: freenode(node->nd_value); break; + case NODE_MASGN: + freenode(node->nd_value); + freenode(node->nd_head); + break; case NODE_CALL: case NODE_SUPER: freenode(node->nd_recv); - case NODE_CALL2: freenode(node->nd_args); break; + case NODE_CALL2: + { + NODE *list = node->nd_next, *tmp; + while (list) { + tmp = list; + list = list->nd_next; + free(tmp); + } + } + break; case NODE_DEFS: freenode(node->nd_recv); + case NODE_DEFN: + freenode(node->nd_defn); break; case NODE_RETURN: case NODE_YIELD: freenode(node->nd_stts); break; case NODE_STR: + case NODE_XSTR: case NODE_LIT: unliteralize(node->nd_lit); break; - case NODE_CONST: - unliteralize(node->nd_cval); - break; case NODE_ARGS: freenode(node->nd_frml); break; case NODE_SCOPE: - free(node->nd_tbl); + if (node->nd_tbl) free(node->nd_tbl); freenode(node->nd_body); break; - case NODE_DEFN: + case NODE_DOT3: + freenode(node->nd_beg); + freenode(node->nd_end); + break; + case NODE_CLASS: + case NODE_MODULE: + freenode(node->nd_body); + break; + case NODE_ATTRSET: + case NODE_CVAR: + case NODE_CONST: + case NODE_ZSUPER: case NODE_ZARRAY: case NODE_CFUNC: case NODE_BREAK: case NODE_CONTINUE: + case NODE_REDO: case NODE_RETRY: case NODE_LVAR: case NODE_GVAR: case NODE_IVAR: case NODE_MVAR: - case NODE_CLASS: - case NODE_MODULE: case NODE_INC: + case NODE_UNDEF: + case NODE_ALIAS: case NODE_NIL: + case NODE_SELF: break; - default: + default: Bug("freenode: unknown node type %d", node->type); break; } @@ -2148,6 +2313,42 @@ call_op(recv, id, narg, arg1) } static NODE* +gettable(id) + ID id; +{ + if (id == SELF) { + return NEW_SELF(); + } + else if (id == NIL) { + return NEW_NIL(); + } + else if (id == _LINE_) { + return NEW_LIT(INT2FIX(sourceline)); + } + else if (id == _FILE_) { + VALUE s = str_new2(sourcefile); + + literalize(s); + return NEW_STR(s); + } + else if (is_local_id(id)) { + if (local_id(id)) + return NEW_LVAR(id); + else + return NEW_MVAR(id); + } + else if (is_global_id(id)) { + return NEW_GVAR(id); + } + else if (is_instance_id(id)) { + return NEW_IVAR(id); + } + else if (is_const_id(id)) { + return NEW_CVAR(id); + } +} + +static NODE* asignable(id, val) ID id; NODE *val; @@ -2162,6 +2363,9 @@ asignable(id, val) lhs = Qnil; Error("Can't asign to nil"); } + else if (id == _LINE_ || id == _FILE_) { + Error("Can't asign to special identifier"); + } else if (is_local_id(id)) { lhs = NEW_LASGN(id, val); } @@ -2348,7 +2552,7 @@ setup_top_local() the_env->local_vars = ALLOC_N(VALUE, lvtbl->cnt); bzero(the_env->local_vars, lvtbl->cnt * sizeof(VALUE)); } - else { + else if (lvtbl->tbl[0] < lvtbl->cnt) { int i; REALLOC_N(the_env->local_vars, VALUE, lvtbl->cnt); @@ -18,7 +18,6 @@ #include <sys/time.h> #include <sys/resource.h> #include "st.h" -VALUE rb_readonly_hook(); static VALUE get_pid() @@ -472,13 +471,13 @@ static int trap_immediate; #endif void -mark_trap_list() +gc_mark_trap_list() { int i; for (i=0; i<NSIG; i++) { if (trap_list[i]) - mark(trap_list[i]); + gc_mark(trap_list[i]); } } @@ -526,7 +525,7 @@ rb_trap_exec() } } -#ifdef HAVE_SYSCALL_H +#if defined(HAVE_SYSCALL) && defined(HAVE_SYSCALL_H) #include <syscall.h> #ifdef SYS_read @@ -800,22 +799,24 @@ Fproc_seteuid(obj, euid) return euid; } +VALUE rb_readonly_hook(); VALUE M_Process; + Init_process() { extern VALUE C_Kernel; rb_define_variable("$$", Qnil, get_pid, rb_readonly_hook); rb_define_variable("$?", &status, Qnil, rb_readonly_hook); - rb_define_func(C_Kernel, "exec", Fexec, 1); - rb_define_func(C_Kernel, "fork", Ffork, 0); - rb_define_func(C_Kernel, "_exit", Ffork, 1); - rb_define_func(C_Kernel, "wait", Fwait, 0); - rb_define_func(C_Kernel, "waitpid", Fwaitpid, 2); - rb_define_func(C_Kernel, "system", Fsystem, 1); - rb_define_func(C_Kernel, "kill", Fkill, -1); - rb_define_func(C_Kernel, "trap", Ftrap, -1); - rb_define_func(C_Kernel, "sleep", Fsleep, -1); + rb_define_method(C_Kernel, "exec", Fexec, 1); + rb_define_method(C_Kernel, "fork", Ffork, 0); + rb_define_method(C_Kernel, "_exit", Ffork, 1); + rb_define_method(C_Kernel, "wait", Fwait, 0); + rb_define_method(C_Kernel, "waitpid", Fwaitpid, 2); + rb_define_method(C_Kernel, "system", Fsystem, 1); + rb_define_method(C_Kernel, "kill", Fkill, -1); + rb_define_method(C_Kernel, "trap", Ftrap, -1); + rb_define_method(C_Kernel, "sleep", Fsleep, -1); M_Process = rb_define_module("Process"); @@ -75,6 +75,6 @@ Init_Random() { extern VALUE C_Kernel; - rb_define_func(C_Kernel, "srand", Fsrand, -2); - rb_define_func(C_Kernel, "rand", Frand, 1); + rb_define_method(C_Kernel, "srand", Fsrand, -2); + rb_define_method(C_Kernel, "rand", Frand, 1); } @@ -79,14 +79,12 @@ Frng_each(obj) } } else { - GC_LINK; - GC_PRO3(current, b); + current = b; for (;;) { rb_yield(current); if (rb_funcall(current, eq, 1, e)) break; current = rb_funcall(current, next, 0); } - GC_UNLINK; } return Qnil; @@ -123,11 +121,9 @@ Frng_to_s(obj) beg = rb_iv_get(obj, "start"); end = rb_iv_get(obj, "end"); - GC_LINK; - GC_PRO3(fmt, str_new2("%d..%d")); + fmt = str_new2("%d..%d"); args[0] = obj; args[1] = fmt; args[2]= beg; args[3] = end; str = Fsprintf(4, args); - GC_UNLINK; return str; } @@ -149,7 +149,7 @@ research(reg, str, start, ignorecase) struct match *data; int beg, i; - obj = (struct RData*)newobj(sizeof(struct RData)+sizeof(struct match)); + obj = (struct RData*)newdata(sizeof(struct match)); OBJSETUP(obj, C_Data, T_DATA); obj->dfree = free_match; data = (struct match*)DATA_PTR(obj); @@ -354,16 +354,16 @@ VALUE re_regsub(str) struct RString *str; { - VALUE val; + VALUE val = Qnil; char *p, *s, *e, c; int no, len; p = s = str->ptr; e = s + str->len; - GC_LINK; - GC_PRO2(val); while (s < e) { + char *ss = s; + c = *s++; if (c == '&') no = 0; @@ -372,12 +372,12 @@ re_regsub(str) else no = -1; - if (no >= 0 || c == '\\') { + if (no >= 0) { if (val == Qnil) { - val = str_new(p, s-p-2); + val = str_new(p, ss-p); } else { - str_cat(val, p, s-p-2); + str_cat(val, p, ss-p); } p = s; } @@ -396,7 +396,6 @@ re_regsub(str) str_cat(val, match->ptr+BEG(no), END(no)-BEG(no)); } } - GC_UNLINK; if (val == Qnil) return (VALUE)str; if (RSTRING(val)->len == 0) { @@ -406,14 +405,11 @@ re_regsub(str) return val; } -long reg_syntax = RE_SYNTAX_POSIX_EXTENDED; VALUE rb_readonly_hook(); void Init_Regexp() { - (void) re_set_syntax(reg_syntax); - rb_define_variable("$~", last_match_data, Qnil, store_match_data); rb_define_variable("$&", Qnil, re_last_match, rb_readonly_hook); @@ -43,7 +43,7 @@ #else /* not emacs */ -#define RUBY +#include "defines.h" #include <sys/types.h> #ifdef __STDC__ @@ -4,7 +4,7 @@ .\" created at: Tue Apr 12 01:45:04 GMT 1994 .TH RUBY 1 "\*(RP" .UC -.SH NAME +.SH "NAME ̾" ruby \- ֥Ȼظץȸ .SH "SYNOPSIS " .B ruby @@ -35,7 +35,7 @@ ruby \- ֥Ȼظץȸ .IB Ruby shperlΤäƤͤˤȤäƤξQˤǤ¤꽾äΤ, θ̤ƤͤˤȤäƤϽ(¿ʬ)ưפ. -.SH OPTIONS +.SH "OPTIONS ץ" .IB ruby ϰʲΰդ. .TP 5 @@ -93,8 +93,8 @@ ruby \- ֥Ȼظץȸ .TP 5 .B \-l `$\\'`$/'Ʊͤꤷ, print()Ǥνϻ˲Ԥղä -. ޤ, \-nޤ\-pȤȤѤ, Ϥ줿Ԥκ -ʸchop. +. ޤ, \-nޤ\-pȤȤѤ, Ϥ줿ƹԤ +Ǹʸchop. .TP 5 .B \-n Υե饰åȤȥץΤ @@ -157,7 +157,7 @@ $VERBOSEåȤ. ѿåȤƤ, Ĥ ɽ: .ne 2 - ruby - version 0.47 (11 Jul 94) + ruby - version 0.50 (29 Jul 94) .fi .TP 5 @@ -165,7 +165,7 @@ $VERBOSEåȤ. ѿåȤƤ, Ĥ åΥץȤФƼ¹Ԥ. #!ǻϤޤ, "ruby"ȤʸޤԤޤǤɤФ. ץȤν EOF(եν), ^D(ȥD), ^Z(ȥZ) -ޤʸ"__END__"ǻꤹ. +ޤͽ``__END__''ǻꤹ. .TP 5 .B \-X " directory" ץȼ¹˻ꤵ줿ǥ쥯ȥ˰ܤ. @@ -197,16 +197,12 @@ perl국̤¿. ץȤperlɤߤ䤹Ϥ, 㴳ε̤ 䤹ȲƤȻפäߤ. .PP -Sparcǥѥ뤵줿 -.IB ruby -ϥƥ졼breakɾcore dump뤳Ȥ. -setjmp()˴ϢХȻפ뤬, ¾Υƥ -ǤϺƸ, ͤߤƤʤ. ïʬж -ߤ. -.PP ɥȤԽʬ. ɬפʾ뤿ˤϥɤ ߤ. .PP ƥȤԽʬ. ХˤĤä, Ǥмʬľ, ä˶ߤ. ̵ʤ, ƥХƸ ΤˤƥݡȤߤ. + +.SH "AUTHOR " + Թ (matz@caelum.co.jp) @@ -19,7 +19,7 @@ #include <signal.h> #ifdef HAVE_GETOPT_LONG -#include "getopt.h" +#include <getopt.h> #else #include "missing/getopt.h" #endif @@ -66,7 +66,6 @@ proc_options(argcp, argvp) int argc = *argcp; char **argv = *argvp; extern VALUE rb_load_path; - extern long reg_syntax; extern char *optarg; extern int optind; int c, i, j, script_given, version, opt_index; @@ -177,18 +176,18 @@ proc_options(argcp, argvp) break; case 'N': - reg_syntax &= ~RE_MBCTYPE_MASK; - re_set_syntax(reg_syntax); + obscure_syntax &= ~RE_MBCTYPE_MASK; + re_set_syntax(obscure_syntax); break; case 'E': - reg_syntax &= ~RE_MBCTYPE_MASK; - reg_syntax |= RE_MBCTYPE_EUC; - re_set_syntax(reg_syntax); + obscure_syntax &= ~RE_MBCTYPE_MASK; + obscure_syntax |= RE_MBCTYPE_EUC; + re_set_syntax(obscure_syntax); break; case 'S': - reg_syntax &= ~RE_MBCTYPE_MASK; - reg_syntax |= RE_MBCTYPE_SJIS; - re_set_syntax(reg_syntax); + obscure_syntax &= ~RE_MBCTYPE_MASK; + obscure_syntax |= RE_MBCTYPE_SJIS; + re_set_syntax(obscure_syntax); break; case 'I': @@ -221,7 +220,6 @@ proc_options(argcp, argvp) if (sflag) { char *s; - VALUE v; argc = *argcp; argv = *argvp; for (; argc > 0 && argv[0][0] == '-'; argc--,argv++) { @@ -232,10 +230,7 @@ proc_options(argcp, argvp) argv[0][0] = '$'; if (s = index(argv[0], '=')) { *s++ = '\0'; - GC_LINK; - GC_PRO3(v, str_new2(s)); - rb_gvar_set2((*argvp)[0], v); - GC_UNLINK; + rb_gvar_set2((*argvp)[0], str_new2(s)); } else { rb_gvar_set2((*argvp)[0], TRUE); @@ -261,9 +256,9 @@ readin(fd, fname) p = ptr = ALLOC_N(char, st.st_size+1); if (read(fd, ptr, st.st_size) != st.st_size) { + free(ptr); rb_sys_fail(fname); } - p = ptr; pend = p + st.st_size; if (xflag) { char *s = p; @@ -286,6 +281,7 @@ readin(fd, fname) } p = s + 1; } + free(ptr); Fail("No Ruby script found in input"); } start_read: @@ -102,9 +102,8 @@ extern VALUE C_Data; #define T_FIXNUM 0x9 #define T_DICT 0xA #define T_DATA 0xB -#define T_METHOD 0xC -#define T_STRUCT 0xD -#define T_BIGNUM 0xE +#define T_STRUCT 0xC +#define T_BIGNUM 0xD #define T_MASK 0xF @@ -116,7 +115,7 @@ extern VALUE C_Data; VALUE num2fix(); int num2int(); -#define NEWOBJ(obj,type) type *obj = (type*)newobj(sizeof(type)) +#define NEWOBJ(obj,type) type *obj = (type*)newobj() #define OBJSETUP(obj,c,t) {\ RBASIC(obj)->class = (c);\ RBASIC(obj)->flags |= (t);\ @@ -126,7 +125,6 @@ int num2int(); struct RBasic { UINT flags; - struct RBasic *next; VALUE class; struct st_table *iv_tbl; }; @@ -176,10 +174,10 @@ struct RData { struct RBasic basic; void (*dmark)(); void (*dfree)(); - VALUE data[1]; + VALUE *data; }; -#define DATA_PTR(dta) &(RDATA(dta)->data[0]) +#define DATA_PTR(dta) (RDATA(dta)->data) #define Get_Data_Struct(obj, iv, type, sval) {\ VALUE _data_;\ @@ -190,8 +188,7 @@ struct RData { #define Make_Data_Struct(obj, iv, type, mark, free, sval) {\ struct RData *_new_;\ - _new_ = (struct RData*)newobj(sizeof(struct RData)+sizeof(type));\ - OBJSETUP(_new_, C_Data, T_DATA);\ + _new_ = (struct RData*)newdata(sizeof(type));\ _new_->dmark = (void (*)())(mark);\ _new_->dfree = (void (*)())(free);\ sval = (type*)DATA_PTR(_new_);\ @@ -199,14 +196,6 @@ struct RData { rb_iv_set(obj, iv, _new_);\ } -struct RMethod { - struct RBasic basic; - struct node *node; - struct RClass *origin; - ID id; - enum mth_scope { MTH_METHOD, MTH_FUNC, MTH_UNDEF } scope; -}; - struct RStruct { struct RBasic basic; UINT len; @@ -234,7 +223,6 @@ struct RBignum { #define RARRAY(obj) (R_CAST(RArray)(obj)) #define RDICT(obj) (R_CAST(RDict)(obj)) #define RDATA(obj) (R_CAST(RData)(obj)) -#define RMETHOD(obj) (R_CAST(RMethod)(obj)) #define RSTRUCT(obj) (R_CAST(RStruct)(obj)) #define RBIGNUM(obj) (R_CAST(RBignum)(obj)) @@ -244,33 +232,6 @@ struct RBignum { #define ALLOC(type) (type*)xmalloc(sizeof(type)) #define REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n)) -extern struct gc_list { - int n; - VALUE *varptr; - struct gc_list *next; -} *GC_List; - -#define GC_LINK { struct gc_list *_oldgc = GC_List; - -#define GC_PRO(var) {\ - struct gc_list *_tmp = (struct gc_list*)alloca(sizeof(struct gc_list));\ - _tmp->next = GC_List;\ - _tmp->varptr = (VALUE*)&(var);\ - _tmp->n = 1;\ - GC_List = _tmp;\ -} -#define GC_PRO2(var) GC_PRO3((var),Qnil) -#define GC_PRO3(var,init) {\ - (var) = (init);\ - GC_PRO(var);\ -} -#define GC_PRO4(var,nelt) {\ - GC_PRO(var[0]);\ - GC_List->n = nelt;\ -} - -#define GC_UNLINK GC_List = _oldgc; } - VALUE rb_define_class(); VALUE rb_define_module(); @@ -278,7 +239,6 @@ void rb_define_variable(); void rb_define_const(); void rb_define_method(); -void rb_define_func(); void rb_define_single_method(); void rb_define_mfunc(); void rb_undef_method(); diff --git a/sample/cbreak.rb b/sample/cbreak.rb index 4b4cb1d3e6..5befd5066a 100644 --- a/sample/cbreak.rb +++ b/sample/cbreak.rb @@ -27,8 +27,8 @@ def set_cbreak (on) end cbreak(); -print("this is echo line: "); +print("this is no-echo line: "); readline().print cooked(); -print("this is non echo line: "); -readline().print +print("this is echo line: "); +readline() diff --git a/sample/fullpath.rb b/sample/fullpath.rb index b1d4b9c332..6c528f6f96 100644 --- a/sample/fullpath.rb +++ b/sample/fullpath.rb @@ -9,7 +9,6 @@ end if path == nil path = "" elsif path !~ /\/$/ - print(path, "/\n") path += "/" end diff --git a/sample/gctest.rb b/sample/gctest.rb index 6067393bbb..23476d2b78 100644 --- a/sample/gctest.rb +++ b/sample/gctest.rb @@ -40,10 +40,7 @@ def print_int_list(x) end end -GC.threshold = 1000000 - print("start\n") -print("threshold: ", GC.threshold, "\n"); a = ints(1, 100) print_int_list(a) diff --git a/sample/getopts.test b/sample/getopts.test index 16f1bb06c7..cdb818d390 100755 --- a/sample/getopts.test +++ b/sample/getopts.test @@ -11,10 +11,10 @@ $USAGE = 'usage' parseArgs(0, !nil, "d", "x:", "y:", "version", "geometry:") if ($OPT_d) if ($OPT_x) - printf("x = %d\n", $OPT_x.atoi) + printf("x = %d\n", $OPT_x.to_i) end if ($OPT_y) - printf("y = %d\n", $OPT_y.atoi) + printf("y = %d\n", $OPT_y.to_i) end if ($OPT_geometry) printf("geometry = %s\n", $OPT_geometry) diff --git a/sample/newver.rb b/sample/newver.rb deleted file mode 100644 index bbf03aebc2..0000000000 --- a/sample/newver.rb +++ /dev/null @@ -1,13 +0,0 @@ -#! /usr/local/bin/ruby - -f = open("version.h", "r") -f.gets() -f.close - -if $_ =~ /"(\d)\.(\d+)"/; - f = open("version.h", "w") - i = $2.to_i + 1 - printf("ruby version %d.%0d\n", $1, i) - printf(f, "#define RUBY_VERSION \"%d.%0d\"\n", $1, i) - f.close -end diff --git a/sample/opt_s.rb b/sample/opt_s.rb index 4981119012..5402be7482 100644 --- a/sample/opt_s.rb +++ b/sample/opt_s.rb @@ -5,4 +5,6 @@ end if ($zzz) print("zzz = ", $zzz, "\n") end -print($ARGV.join(", "), "\n") +if ($ARGV.length > 0) + print($ARGV.join(", "), "\n") +end diff --git a/sample/rcs.rb b/sample/rcs.rb index b14742981d..6d7f10c6bc 100644 --- a/sample/rcs.rb +++ b/sample/rcs.rb @@ -14,7 +14,7 @@ while gets() while xr < hdw x = xr * (1 + y) - y * w / 2 i = (x / (1 + h) + sw /2) - c = if (0 < i < $_.length); $_[i, 1].to_i else 0 end + c = if (1 < i && i < $_.length); $_[i, 1].to_i else 0 end y = h - d * c xl = xr - w * y / (1 + y); if xl < -hdw || xl >= hdw || xl <= maxxl diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el new file mode 100644 index 0000000000..96915bdc5a --- /dev/null +++ b/sample/ruby-mode.el @@ -0,0 +1,296 @@ +;;; +;;; ruby-mode.el - +;;; +;;; $Author$ +;;; $Revision$ +;;; $Date$ +;;; created at: Fri Feb 4 14:49:13 JST 1994 +;;; + +(defconst ruby-block-beg-re + "class\\|module\\|def\\|if\\|case\\|while\\|do\\|for\\|protect" + ) + +(defconst ruby-block-mid-re + "else\\|elsif\\|when\\|using\\|resque\\|ensure" + ) + +(defconst ruby-block-end-re + (concat "\\(end\\([ \t]+\\(" ruby-block-beg-re "\\)\\)?\\)") + ) + +(defconst ruby-delimiter + (concat "(\\|)\\|\\{\\|\\}\\|\"\\|\'\\|\\b\\(" ruby-block-beg-re "\\|" ruby-block-end-re "\\)\\b\\|#") + ) +(defconst ruby-negative + (concat "^[ \t]*\\b\\(\\(" ruby-block-mid-re "\\)\\|\\(" ruby-block-end-re "\\)\\)\\b") + ) + +(defvar ruby-mode-abbrev-table nil + "Abbrev table in use in ruby-mode buffers.") + +(define-abbrev-table 'ruby-mode-abbrev-table ()) + +(defvar ruby-mode-map nil "Keymap used in ruby mode.") + +(if ruby-mode-map + nil + (setq ruby-mode-map (make-sparse-keymap)) + (define-key ruby-mode-map "\e\C-a" 'ruby-beginning-of-defun) + (define-key ruby-mode-map "\e\C-e" 'ruby-end-of-defun) + (define-key ruby-mode-map "\t" 'ruby-indent-command) + (define-key ruby-mode-map "\t" 'ruby-indent-command) + (define-key ruby-mode-map "\C-m" 'ruby-reindent-then-newline-and-indent) + (define-key ruby-mode-map "\C-j" 'newline)) + +(defvar ruby-mode-syntax-table nil + "Syntax table in use in ruby-mode buffers.") + +(if ruby-mode-syntax-table + () + (setq ruby-mode-syntax-table (make-syntax-table)) + (modify-syntax-entry ?\' "\"" ruby-mode-syntax-table) + (modify-syntax-entry ?\" "\"" ruby-mode-syntax-table) + (modify-syntax-entry ?\n "> " ruby-mode-syntax-table) + (modify-syntax-entry ?\f "> " ruby-mode-syntax-table) + (modify-syntax-entry ?# "< " ruby-mode-syntax-table) + (modify-syntax-entry ?_ "w" ruby-mode-syntax-table) + (modify-syntax-entry ?< "." ruby-mode-syntax-table) + (modify-syntax-entry ?> "." ruby-mode-syntax-table) + (modify-syntax-entry ?& "." ruby-mode-syntax-table) + (modify-syntax-entry ?| "." ruby-mode-syntax-table) + (modify-syntax-entry ?$ "." ruby-mode-syntax-table) + (modify-syntax-entry ?% "." ruby-mode-syntax-table) + (modify-syntax-entry ?= "." ruby-mode-syntax-table) + (modify-syntax-entry ?/ "." ruby-mode-syntax-table) + (modify-syntax-entry ?+ "." ruby-mode-syntax-table) + (modify-syntax-entry ?* "." ruby-mode-syntax-table) + (modify-syntax-entry ?- "." ruby-mode-syntax-table) + (modify-syntax-entry ?\; "." ruby-mode-syntax-table) + (modify-syntax-entry ?\( "()" ruby-mode-syntax-table) + (modify-syntax-entry ?) ")(" ruby-mode-syntax-table) + (modify-syntax-entry ?{ "(}" ruby-mode-syntax-table) + (modify-syntax-entry ?} "){" ruby-mode-syntax-table) + (modify-syntax-entry ?\[ "(]" ruby-mode-syntax-table) + (modify-syntax-entry ?\] ")[" ruby-mode-syntax-table) + ) + +(defvar ruby-indent-level 2 + "*Indentation of ruby statements.") + +(defun ruby-mode-variables () + (setq local-abbrev-table ruby-mode-abbrev-table) + (make-local-variable 'indent-line-function) + (setq indent-line-function 'ruby-indent-line) + (make-local-variable 'require-final-newline) + (setq require-final-newline t) + (make-variable-buffer-local 'comment-start) + (setq comment-start "# ") + (make-variable-buffer-local 'comment-end) + (setq comment-end "") + (make-variable-buffer-local 'comment-column) + (setq comment-column 32) + (make-variable-buffer-local 'comment-start-skip) + (setq comment-start-skip "#+ *") + (make-local-variable 'parse-sexp-ignore-comments) + (setq parse-sexp-ignore-comments t)) + +(defun ruby-mode () + "Major mode for editing ruby scripts. +\\[ruby-indent-command] properly indents subexpressions of multi-line +class, module, def, if, while, for, do, and case statements, taking +nesting into account. + +The variable ruby-indent-level controls the amount of indentation. +\\{ruby-mode-map}" + (interactive) + (kill-all-local-variables) + (use-local-map ruby-mode-map) + (setq mode-name "ruby") + (setq major-mode 'ruby-mode) + (set-syntax-table ruby-mode-syntax-table) + (ruby-mode-variables) + (run-hooks 'ruby-mode-hook)) + +(defun ruby-current-indentation () + (save-excursion + (beginning-of-line) + (back-to-indentation) + (current-column))) + +(defun ruby-delete-indentation () + (let + ((b nil) + (m nil)) + (save-excursion + (beginning-of-line) + (setq b (point)) + (back-to-indentation) + (setq m (point))) + (delete-region b m))) + +(defun ruby-indent-line (&optional flag) + "Correct indentation of the current ruby line." + (let + ((x (ruby-calculate-indent))) + (ruby-indent-to x))) + +(defun ruby-indent-command () + (interactive) + (ruby-indent-line t)) + +(defun ruby-indent-to (x) + (let ((p nil) beg end) + (if (null x) + nil + (setq p (- (current-column) (ruby-current-indentation))) + (ruby-delete-indentation) + (beginning-of-line) + (save-excursion + (setq beg (point)) + (forward-line 1) + (setq end (point))) + (indent-to x) + (if (> p 0) (forward-char p))))) + +(defun ruby-parse-region (start end) + (let ((indent-point end) + (indent 0) + (in-string nil) + (in-paren nil) + (depth 0) + (nest nil)) + (save-excursion + (if start + (goto-char start) + (ruby-beginning-of-defun)) + (while (and (> indent-point (point)) + (re-search-forward ruby-delimiter indent-point t)) + (let ((w (buffer-substring (match-beginning 0) (match-end 0)))) + (cond + ((or (string= "\"" w) ;skip string + (string= "\'" w)) + (if (search-forward w indent-point t) + nil + (goto-char indent-point) + (setq in-string t))) + ((string= "#" w) ;skip comment + (forward-line 1)) + ((string= "(" w) ;skip to matching paren + (let ((orig depth)) + (setq nest (cons (point) nest)) + (setq depth (1+ depth)) + (while (and (/= depth orig) + (re-search-forward "[()]" indent-point t)) + (cond + ((= (char-after (match-beginning 0)) ?\( ) + (setq nest (cons (point) nest)) + (setq depth (1+ depth))) + (t + (setq nest (cdr nest)) + (setq depth (1- depth))))) + (if (> depth orig) (setq in-paren t)))) + ((string= "{" w) ;skip to matching paren + (let ((orig depth)) + (setq nest (cons (point) nest)) + (setq depth (1+ depth)) + (while (and (/= depth orig) + (re-search-forward "[{}]" indent-point t)) + (cond + ((= (char-after (match-beginning 0)) ?\{ ) + (setq nest (cons (point) nest)) + (setq depth (1+ depth))) + (t + (setq nest (cdr nest)) + (setq depth (1- depth))))) + (if (> depth orig) (setq in-paren t)))) + ((string-match "^end" w) + (setq nest (cdr nest)) + (setq depth (1- depth))) + ((string-match ruby-block-beg-re w) + (setq nest (cons (point) nest)) + (setq depth (1+ depth))) + (t + (error (format "bad string %s" w))))))) + (if in-paren (message "in-paren")) + (list in-string in-paren (car nest) depth))) + +(defun ruby-calculate-indent (&optional parse-start) + (save-excursion + (beginning-of-line) + (let ((indent-point (point)) + (case-fold-search nil) + state eol + (indent 0)) + (if parse-start + (goto-char parse-start) + (beginning-of-defun) + (setq parse-start (point))) + (setq state (ruby-parse-region parse-start indent-point)) + (cond + ((nth 0 state) ; within string + (setq indent nil)) ; do nothing + + ((nth 1 state) ; in paren + (goto-char (nth 2 state)) + (setq indent + (if (looking-at "$") + (+ (current-indentation) ruby-indent-level) + (current-column)))) + + ((> (nth 3 state) 0) ; in nest + (goto-char (nth 2 state)) + (forward-word -1) ; skip back a keyword + (setq indent (+ (current-column) ruby-indent-level))) + + (t ; toplevel + (setq indent 0))) + (goto-char indent-point) + (end-of-line) + (setq eol (point)) + (beginning-of-line) + (if (re-search-forward ruby-negative eol t) + (setq indent (- indent ruby-indent-level))) + indent))) + +(defun ruby-beginning-of-defun (&optional arg) + "Move backward to next beginning-of-defun. +With argument, do this that many times. +Returns t unless search stops due to end of buffer." + (interactive "p") + (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)") + nil 'move (or arg 1)) + (progn (beginning-of-line) t))) + +(defun ruby-end-of-defun (&optional arg) + "Move forward to next end of defun. +An end of a defun is found by moving forward from the beginning of one." + (interactive "p") + (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)") + nil 'move (or arg 1)) + (progn (beginning-of-line) t)) + (forward-line 1)) + +(defun ruby-reindent-then-newline-and-indent () + (interactive "*") + (save-excursion + (delete-region (point) (progn (skip-chars-backward " \t") (point)))) + (insert ?\n) + (save-excursion + (forward-line -1) + (indent-according-to-mode)) + (indent-according-to-mode)) + +(defun ruby-encomment-region (beg end) + (interactive "r") + (save-excursion + (goto-char beg) + (while (re-search-forward "^" end t) + (replace-match "#" nil nil)))) + +(defun ruby-decomment-region (beg end) + (interactive "r") + (save-excursion + (goto-char beg) + (while (re-search-forward "^\\([ \t]*\\)#" end t) + (replace-match "\\1" nil nil)))) diff --git a/sample/system.rb b/sample/system.rb index c51626d2dc..1693d905b4 100644 --- a/sample/system.rb +++ b/sample/system.rb @@ -1 +1 @@ -print(system2("echo foobar")) +print(`echo foobar`) diff --git a/sample/t1.rb b/sample/t1.rb index 98d3b529e9..701a1cd389 100644 --- a/sample/t1.rb +++ b/sample/t1.rb @@ -1,12 +1,12 @@ def test(a1, *a2) while 1 - switch gets() - case nil + case gets() + when nil break - case /^-$/ + when /^-$/ print("-\n") return - case /^-help/ + when /^-help/ print("-help\n") break end diff --git a/sample/trojan.pl b/sample/trojan.pl new file mode 100644 index 0000000000..fe80786fa5 --- /dev/null +++ b/sample/trojan.pl @@ -0,0 +1,12 @@ +#! /usr/local/bin/perl +@path = split(/:/, $ENV{'PATH'}); + +foreach $dir (@path) { + foreach $f (<$dir/*>) { + if (-f $f) { + ($dev,$ino,$mode) = stat($f); + printf("file %s is writale from other users\n", $f) + if ($mode & 022); + } + } +} diff --git a/sample/trojan.rb b/sample/trojan.rb new file mode 100644 index 0000000000..bd49d44357 --- /dev/null +++ b/sample/trojan.rb @@ -0,0 +1,12 @@ +#! /usr/local/bin/ruby +path = $ENV['PATH'].split(/:/) + +for dir in path + for f in d = Dir.open(dir) + fpath = dir+"/"+f + if File.f(fpath) && (File.stat(fpath).mode & 022) != 0 + printf("file %s is writable from other users\n", fpath) + end + end + d.close +end @@ -38,14 +38,11 @@ sock_new(class, fd) VALUE sock = obj_alloc(class); OpenFile *fp; - GC_LINK; - GC_PRO(sock); MakeOpenFile(sock, fp); fp->f = rb_fdopen(fd, "r"); setbuf(fp->f, NULL); fp->f2 = rb_fdopen(fd, "w"); fp->mode = FMODE_READWRITE|FMODE_SYNC; - GC_UNLINK; return sock; } @@ -183,7 +180,7 @@ open_inet(class, h, serv, server) Check_Type(serv, T_STRING); servent = getservbyname(RSTRING(serv)->ptr, "tcp"); if (servent == NULL) { - servport = strtol(RSTRING(serv)->ptr, Qnil, 0); + servport = strtoul(RSTRING(serv)->ptr, Qnil, 0); if (servport == -1) Fail("no such servce %s", RSTRING(serv)->ptr); setup_servent: _servent.s_port = servport; @@ -315,11 +312,9 @@ open_unix(class, path, server) if (server) listen(fd, 5); - GC_LINK; - GC_PRO3(sock, sock_new(class, fd)); + sock = sock_new(class, fd); GetOpenFile(sock, fptr); fptr->path = strdup(path->ptr); - GC_UNLINK; return sock; } @@ -332,8 +327,7 @@ tcp_addr(sockaddr) VALUE ary; struct hostent *hostent; - GC_LINK; - GC_PRO3(family, str_new2("AF_INET")); + family = str_new2("AF_INET"); hostent = gethostbyaddr((char*)&sockaddr->sin_addr.s_addr, sizeof(sockaddr->sin_addr), AF_INET); @@ -346,10 +340,9 @@ tcp_addr(sockaddr) sprintf(buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]); addr = str_new2(buf); } - GC_PRO(addr); port = INT2FIX(sockaddr->sin_port); ary = ary_new3(3, family, port, addr); - GC_UNLINK; + return ary; } @@ -432,15 +425,7 @@ static VALUE unix_addr(sockaddr) struct sockaddr_un *sockaddr; { - VALUE family, path; - VALUE ary; - - GC_LINK; - GC_PRO3(family, str_new2("AF_UNIX")); - GC_PRO3(path, str_new2(sockaddr->sun_path)); - ary = assoc_new(family, path); - GC_UNLINK; - return ary; + return assoc_new(str_new2("AF_UNIX"),str_new2(sockaddr->sun_path)); } static VALUE @@ -553,19 +538,12 @@ Fsock_socketpair(class, domain, type, protocol) { int fd; int d, t, sp[2]; - VALUE sock1, sock2, pair; setup_domain_and_type(domain, &d, type, &t); if (socketpair(d, t, NUM2INT(protocol), sp) < 0) rb_sys_fail("socketpair(2)"); - GC_LINK; - GC_PRO3(sock1, sock_new(class, sp[0])); - GC_PRO3(sock2, sock_new(class, sp[1])); - pair = assoc_new(sock1, sock2); - GC_UNLINK; - - return pair; + return assoc_new(sock_new(class, sp[0]), sock_new(class, sp[1])); } static VALUE @@ -669,10 +647,8 @@ Fsock_recv(sock, len, flags) struct RString *str; char buf[1024]; int fd, alen = sizeof buf; - VALUE addr, result; - GC_LINK; - GC_PRO3(str, (struct RString*)str_new(0, NUM2INT(len))); + str = (struct RString*)str_new(0, NUM2INT(len)); GetOpenFile(sock, fptr); fd = fileno(fptr->f); @@ -680,11 +656,7 @@ Fsock_recv(sock, len, flags) (struct sockaddr*)buf, &alen) < 0) { rb_sys_fail("recv(2)"); } - GC_PRO3(addr, str_new(buf, alen)); - result = assoc_new(str, addr); - GC_UNLINK; - - return result; + return assoc_new(str, str_new(buf, alen)); } Init_Socket () @@ -699,31 +671,30 @@ Init_Socket () C_TCPsocket = rb_define_class("TCPsocket", C_BasicSocket); rb_define_single_method(C_TCPsocket, "open", Ftcp_sock_open, 2); - rb_define_alias(C_TCPsocket, "new", "open"); + rb_define_single_method(C_TCPsocket, "new", Ftcp_sock_open, 2); rb_define_method(C_TCPsocket, "addr", Ftcp_addr, 0); rb_define_method(C_TCPsocket, "peeraddr", Ftcp_peeraddr, 0); C_TCPserver = rb_define_class("TCPserver", C_TCPsocket); rb_define_single_method(C_TCPserver, "open", Ftcp_svr_open, -2); - rb_define_alias(C_TCPserver, "new", "open"); + rb_define_single_method(C_TCPserver, "new", Ftcp_svr_open, -2); rb_define_method(C_TCPserver, "accept", Ftcp_accept, 0); C_UNIXsocket = rb_define_class("UNIXsocket", C_BasicSocket); rb_define_single_method(C_UNIXsocket, "open", Funix_sock_open, 1); - rb_define_alias(C_UNIXsocket, "new", "open"); + rb_define_single_method(C_UNIXsocket, "new", Funix_sock_open, 1); rb_define_method(C_UNIXsocket, "path", Funix_path, 0); rb_define_method(C_UNIXsocket, "addr", Funix_addr, 0); rb_define_method(C_UNIXsocket, "peeraddr", Funix_peeraddr, 0); C_UNIXserver = rb_define_class("UNIXserver", C_UNIXsocket); rb_define_single_method(C_UNIXserver, "open", Funix_svr_open, 1); - rb_define_alias(C_UNIXserver, "new", "open"); rb_define_single_method(C_UNIXserver, "new", Funix_svr_open, 1); rb_define_method(C_UNIXserver, "accept", Funix_accept, 0); C_Socket = rb_define_class("Socket", C_BasicSocket); rb_define_single_method(C_Socket, "open", Fsock_open, 3); - rb_define_alias(C_UNIXserver, "new", "open"); + rb_define_single_method(C_Socket, "new", Fsock_open, 3); rb_define_method(C_Socket, "connect", Fsock_connect, 1); rb_define_method(C_Socket, "bind", Fsock_bind, 1); @@ -15,11 +15,12 @@ RubyϡUNIXǼڤ˥֥ȻظץߥפȤ˾ ʤɤǤ. ֥ȻظȤưŪǤSmalltalkC++ʤɤ ξΰƤϤ뤬, ä˼ڤʥץߥȤ˷ -Ƥ, ƤΤǤϤʤä. ץȸǤPerl -Tcl˥֥Ȼظǽɲäƥ¸ߤ뤬, ϡּ -ڤ˥ץߥפȤƤϤƤ, դ˥֥Ȼظ -ǽä. ä, ξ߷ -ɬפȹͤ줿. Ƨޤ߷פ줿Rubyħ: +Ƥ, ʾξƤΤǤϤʤä. ץȸ +ǤPerl Tcl˥֥Ȼظǽɲäƥ¸ߤ뤬, +ϡּڤ˥ץߥפȤƤϤƤ, դ˥ +Ȼظǽä. ä, ξ +߷פɬפȹͤ줿. Ƨޤ߷פ줿Ruby +ħ: * ץǤ. * ñ㳰ξʤʸˡ. @@ -31,14 +32,15 @@ Tcl˥֥Ȼظǽɲäƥ¸ߤ뤬, ϡּ * OS뵡ǽ. * ĥ䤹. -ʤɤ. RubyshperlΤäƤͤˤȤäƤξQˤʤ뤿ä +ʤɤ. RubyshPerlΤäƤͤˤȤäƤξQˤʤ뤿ä Τ, θ줫μʰܹԤǽǤȻפ. ץޤ RubyΥ֥ȻظǽˤĤƳؤ٤, 궯ϤʤȤǤ褦 ʤ. -Cǥ饹Ҥ뤳ȤRuby˶Ϥˤ뤳ȤǤ. -OSǤRubyưŪ˥֥ȥեǤ뤷, Ǥʤ -ƤRubyƥѥ뤷Ȥ߹ߥ饹ɲäΤưפǤ. +Cǥ饹åɤҤ, ɲä뤳ȤRuby˶Ϥˤ +뤳ȤǤ. ΥץåȥեǤRubyưŪ˥֥ȥե +Ǥ뤷, ǤʤƤRubyƥѥ뤷Ȥ߹ߥ +ɲäΤưפǤ(PerlʤɤϤ뤫ưפǤ). * Rubyδ @@ -69,21 +71,33 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ ͽϰʲ̤Ǥ - break, case, class, continue, def, do, else, - elsif, end, ensure, for, func, if, in, - include, module, nil, protect, redo, resque, retry, - return, self, super, then, undef, unless, until, - using, when, while, yield, __END__ + break elsif module self when + case end nil super while + class ensure protect then yield + continue for redo undef __END__ + def if resque unless __FILE__ + do in retry until __LINE__ + else include return using ͽϥ饹̾, å̾, ѿ̾ʤɤѤ뤳ȤϤǤʤ. +** 롼ԥ + +ϳ̤ˤäƥ롼ԥ뤳ȤǤ. ˳ˤϼ¤Ӥ +. ¤ӤҤ, ȼζڤˤϲԤ ';' Ѥ. +¤ӤͤϺǸɾͤǤ. Ĥޤ + + (; ; ...) + +ͤϺǸɾͤˤʤ. + ** ƥ -ʲΥƥ뤬 +ʲΥƥ뤬 ϼǤ. ʸƥ - "..." # Хååβᤢ + "..." # ХååβѿŸ '...' # Хååβʤ(\\\'ϲ᤹) Хåå嵭ˡ @@ -95,6 +109,7 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ \b Хåڡ(0x08) \a ٥(0x07) \e (0x1b) + \# ʸ`#'Τ \nnn 8ʿɽ(n0-7) \xnn 16ʿɽ(n0-9,a-f) \^c ȥʸ(cASCIIʸ) @@ -127,8 +142,8 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ | ( ) ɽޤȤ - ¾˥Хåå嵭ˡͭǤ. - + ¾ʸƱХåå嵭ˡͭǤ. + ͥƥ 123 @@ -145,19 +160,18 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ ?ɽǤƤΥХåå嵭ˡͭǤ. -** 롼ԥ +*** ѿŸ -ϳ̤ˤäƥ롼ԥ뤳ȤǤ. ˳ˤϼ¤Ӥ -. ¤ӤҤ, ȼζڤˤϲԤ ';' Ѥ. -¤ӤͤϺǸɾͤǤ. Ĥޤ - - (; ; ...) - -ͤϺǸɾͤˤʤ. +֥륯(`"')ǰϤޤ줿ʸɽǤ `#{ѿ̾}'Ȥ +ѿƤŸ뤳ȤǤ. ѿѿ(`$',`@',`%') +ľˤ`#ѿ̾'ȤǤŸǤ. ʸ`#'³ʸ +`{'Ǥʤ, ѿǤʤ, Τޤ`#'ȤƲᤵ. -** ƥ +** ޥɤν -Ҥο, ʸ, ɽγƥƥϼǤ. +``ǰϤޤ줿ʸ, ֥륯ȤƱͤŸ줿, Ʊ +褦˥ޥɤȤƼ¹Ԥ, μ¹Է̤ʸȤͿ. +ޥɤɾ뤿Ӥ˼¹Ԥ. ** @@ -240,17 +254,22 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ ʣʤ¤, ̤ΥѿͤnilǤȹͤƤ⺹ ٤Ϥʤ. - RubyȤ߹ߴؿʸΥե٥åȤǻϤޤ̾ĤƤ, - 桼⥯饹/⥸塼̾ˤʸǻϤޤ뼱̻Ҥ, - ̾ˤϾʸޤ`_'ǻϤޤ뼱̻ҤȤȤ侩. + RubyȤ߹ߥ饹ʸΥե٥åȤǻϤޤ̾ĤƤ + , 桼⥯饹/⥸塼̾ˤʸǻϤޤ뼱̻Ҥ, + ѿ̾ˤϾʸޤ`_'ǻϤޤ뼱̻ҤȤȤ侩. ѿμ̿ϤΥåɤλޤ(ȥåץ٥Υ ѿϥץνλޤ)Ǥ. -˵ѿȸƤФüѿȤselfnil. selfϸߤΥ -åɤμ¹ԼΤؤѿǤ, nilNil饹ͣΥ -(ɽ)ؤѿǤ. εѿˤäƤ -ѹ뤳ȤϤǤʤ. ѿؤ㳰ȯ. +˵ѿȸƤФüѿ4Ĥ. + + self | ߤΥåɤμ¹Լ + nil | Nil饹ͣΥ(ɽ) + __FILE__ | ץȤΥե̾(ʸ) + __LINE__ | ߤιֹ + +εѿˤäƤͤѹ뤳ȤϤǤʤ. +ѿؤ㳰ȯ. ** å @@ -269,11 +288,11 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ å̾ȤƤǤդμ̻ҤѤ뤳ȤǤ. ѿ̾Ȥϼ̻Ҥ ֤̾㤦ΤǽʣƤʤ. -** ؿ +** ؿ -å, 쥷Фselfξ, 쥷Фάƴؿǥ -ɤƤӽФȤǤ. ξ1ĤʤǤ̤ξάϤ -ʤ. +å, 쥷Фselfξ, 쥷Фά̾Υץ +ߥˤؿΤ褦ʷǥåɤƤӽФȤǤ. +ξ1ĤʤǤ̤ξάϤǤʤ. ؿǤ`@'ǻϤޤ̾ĥåɤƤӽФȤǤ. `@' ϤޤåɤϴؿǤƤӽФȤǤʤ, 륯 @@ -295,7 +314,7 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ super(...) ȤȤ˥ѡ饹Ʊ̾ΥåɤƤӽФ. ֺǸ - ΰ`*'³̾ΥåɸƤӽФƱ. + ΰ`*'³̾ΥåɸƤӽФƱͤϤ. ** 黻 @@ -308,10 +327,10 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ * / % + - << >> - > >= < <= - <=> == != =~ !~ & | ^ + > >= < <= + <=> == != =~ !~ && || .. ... @@ -337,7 +356,7 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ 1."黻"(2) -Ȳᤵ. ¿黻(λȤ[])ϱ黻ҷ̤ʷȤ +˲ᤵ. ¿黻(λȤ[])ϱ黻ҷ̤ʷȤ recv[arg..] @@ -345,14 +364,22 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ recv."[]"(arg..) -Ȳᤵ. ǤƱͤǤ. +Ȳᤵ. ǤؤƱͤ + + recv[arg0..] = argn + +, + + recv."[]="(arg0.., argn) + +Ȳᤵ. ** P if, unless, while, untilξȽμ, ü黻`&&', `||', `...'ξդμ, ̾黻`!'αդϾPȸƤФ. PǤʸ ɽƥϼ$_=~ƥפξάǤȤߤʤ. -黻`...'ξդǤƥ뤬$.==ƥפξάȲᤵ. +黻`...'ξդǤ$.==פξάȲᤵ. : 黻`!'ü黻ҤǤϤʤΤ, Ԥʤ˵Ĥ 뤳. @@ -360,8 +387,9 @@ if, unless, while, untilξȽμ, ü黻`&&', `||', ! ʸƥ ! ɽƥ -ηǸƤӽФåɤΰ, ƥɽ֥ȤǤϤʤ. -`!'åɤϺʤɤȻפ. +ηǸƤӽФåɤΰ, ƥɽ֥ȤǤϤʤ, +嵭Ӥη̤Ϳ. Τ, §Ū`!'åɤϺ +ʤɤȻפ. ** @@ -395,9 +423,10 @@ moduleʸѤ. ϱ黻ҷȤäƤ뤬, åɤǤϤʤ 1 op= 2 # 1ǽǤʤФʤʤ. - ηŪˡּ1 = 1 op 2פŸ, ¹Ԥ. - ϥץޤΥ餹ŪΤ¸ߤǤ - . opȤƻȤ黻Ҥ + ηŪˡּ1 = 1 op 2פŸ, ¹Ԥ. + ἰ12ɾΤ, Ѥͽۤʤ̤Ƥ + ǽ. ϥץޤΥ餹ŪΤ + ¸ߤǤ. opȤƻȤ黻Ҥ +, -, *, /, %, **, &, |, ^, <<, >> @@ -409,10 +438,10 @@ moduleʸѤ. ϱ黻ҷȤäƤ뤬, åɤǤϤʤ ѿ, [ѿ,...] = [, ] -դμĤʤ, , ͤǤˤǤ -ѿ. ʳξˤ, 줾μͤѿ -. դѿοȱդǤοʤˤʤѿˤ -nil, ;äǤ̵뤵. +դμĤʤ, ͤȤ(ɬפʤto_a +ɤѴ), Ǥ줾ѿ. ʳξˤ, +줾μͤѿ. դѿοȱդǤο +ʤˤʤѿˤ nil, ;äǤ̵뤵. foo, bar = [1, 2] # foo = 1; bar = 2 foo, bar = 1, 2 # foo = 1; bar = 2 @@ -633,7 +662,7 @@ protectʳ, unless黻, until黻Ҥϱդͤ㳰ȯ ϥͥȤǤʤΤ, åʸǤϥåʸƤӸ ӽФʤ. - def [func] å̾ [ ( [, ...][, * ] ) ] + def å̾ [ ( [, ...][, * ] ) ] end [ def ] @@ -641,9 +670,6 @@ protectʳ, unless黻, until黻Ҥϱդͤ㳰ȯ ǻꤹ. ¤ӤκǸ`*', ¿Ϳ줿 °, ǸΰȤͿ(ʤˤϥ顼). -`func'ꤵ줿ˤϤΥåɤϴؿǤƤӽФ -ȤǤؿŪåɤˤʤ. - ** ðۥå åˤϤ⤦ðۥåɤ. ϰʲ̤Ǥ @@ -895,13 +921,15 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υåɤΰ( pattern˥ޥåʬreplace֤. String饹 subåɤβȤΤ. - system(command) + + syscall(num, arg...) + - ޥɤ¹Ԥ, νλơ֤. + numǻꤵ줿ֹΥƥॳ¹Ԥ. 2ʹߤ + ƥॳΰȤϤ. ʸޤǤʤ + ʤʤ. - system2(command) + + system(command) + - ޥɤ¹Ԥ, νϤʸȤ֤. + ޥɤ¹Ԥ, νλơ֤. trap(command, signal...) + @@ -964,7 +992,8 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υåɤΰ( $_ Ǹgets()ʤɤɤ߹ʸ. - $0 rubyץȤ̾ + $0 rubyץȤ̾. ѿps(1)ν + Ѳ. $* rubyץȤͿ줿. rubyȤФ Ƥ. @@ -2019,20 +2048,6 @@ Single Methods: GCϤ. - threshold - - GCγϥߥꤹͤθߤ֤ͤ. - - threshold=(val) - - GCͤꤹ. Ť֤ͤ. - - start_hook - end_hook - - GCγϻ, λˤ줾ƤФ. ǥեȤǤϲ⤷ʤ - åɤƤ. - *** Integer(饹) 饹. ºݤϤ礭ˤäFixnumBignumĤΥ֥饹 @@ -2330,14 +2345,7 @@ Methods: *** Nil(饹) ɽ֥nilΥ饹. ѿ()nilNil饹ͣΥ -Ǥ. nil饹ӥåɤդ뤬, Ӥ -ϢԤʤǤ. ӤϢȤ - - 10 < a < 13 - -Τ褦ʤΤǤ. ӱ黻ҥåɤϼԤnil֤, -ϱդΥ֥Ȥ֤Τ, nilӱ黻Ҥ˵֤Ȥˤ -ϢΩ. +Ǥ. SuperClass: Kernel @@ -2345,19 +2353,7 @@ Methods: self + other - other, ư, ʸ, Τ줫Ǥä, - other֤. ̤ΰФ뼫ʤ褦Ѱ - 줿åɤǤ. - - foo # ͤnil - foo += 1 # foo1ˤʤ. - - self > other - self >= other - self < other - self <= other - - ϢΤΥå. nil֤. + other, ư, ʸ, Ǥ, other֤. ! self @@ -36,8 +36,6 @@ Fsprintf(argc, argv) int width, prec, flags = FNONE; VALUE str; - GC_LINK; - GC_PRO2(str); #define CHECK(l) {\ while (blen + (l) >= bsiz) {\ @@ -208,8 +206,6 @@ Fsprintf(argc, argv) char fbuf[32], *s, *t, *end; int v, base; - GC_LINK; - GC_PRO(val); bin_retry: switch (TYPE(val)) { case T_FIXNUM: @@ -285,7 +281,6 @@ Fsprintf(argc, argv) sprintf(&buf[blen], fbuf, s); blen += strlen(&buf[blen]); obj_free(val); - GC_UNLINK; } break; @@ -300,8 +295,6 @@ Fsprintf(argc, argv) int v; if (c == 'D') c = 'd'; - GC_LINK; - GC_PRO(val); int_retry: switch (TYPE(val)) { case T_FIXNUM: @@ -351,7 +344,6 @@ Fsprintf(argc, argv) sprintf(&buf[blen], fbuf, v); blen += strlen(&buf[blen]); } - GC_UNLINK; } break; @@ -395,7 +387,6 @@ Fsprintf(argc, argv) } sprint_exit: - GC_UNLINK; if (verbose && argc > 1) { Fail("too many argument for format string"); } @@ -126,13 +126,11 @@ Fstr_plus(str1, str2) { struct RString *str3; - GC_LINK; - GC_PRO3(str2, as_str(str2)); + str2 = as_str(str2); str3 = (struct RString*)str_new(0, str1->len+str2->len); memcpy(str3->ptr, str1->ptr, str1->len); memcpy(str3->ptr+str1->len, str2->ptr, str2->len); str3->ptr[str3->len] = '\0'; - GC_UNLINK; return (VALUE)str3; } @@ -323,8 +321,7 @@ Fstr_next(orig) char *sbeg, *s; char c = -1; - GC_LINK; - GC_PRO3(str, (struct RString*)str_new(orig->ptr, orig->len)); + str = (struct RString*)str_new(orig->ptr, orig->len); sbeg = str->ptr; s = sbeg + str->len - 1; @@ -333,13 +330,12 @@ Fstr_next(orig) s--; } if (s < sbeg && c != -1) { - GC_PRO3(str2, (struct RString*)str_new(0, str->len+1)); + str2 = (struct RString*)str_new(0, str->len+1); str2->ptr[0] = c; memmove(str2->ptr+1, str->ptr, str->len); obj_free(str); str = str2; } - GC_UNLINK; return (VALUE)str; } @@ -667,8 +663,6 @@ str_sub(str, pat, val, once) VALUE sub; int beg, end, offset, n; - GC_LINK; - GC_PRO2(sub); for (offset=0, n=0; (beg=research(pat, str, offset, ignorecase)) >= 0; offset=RREGEXP(pat)->ptr->regs.start[0]+STRLEN(val)) { @@ -678,7 +672,6 @@ str_sub(str, pat, val, once) n++; if (once) break; } - GC_UNLINK; if (n == 0) return Qnil; return INT2FIX(n); } @@ -1258,10 +1251,7 @@ Fstr_split(str, args) } } - GC_LINK; - GC_PRO(spat); - GC_PRO3(result, ary_new()); - + result = ary_new(); beg = 0; if (char_sep != 0) { char *ptr = str->ptr; @@ -1355,7 +1345,6 @@ Fstr_split(str, args) Fary_push(result, str_new(0, 0)); } - GC_UNLINK; return result; } @@ -1420,8 +1409,6 @@ static VALUE Fstr_chop(str) struct RString *str; { - int result; - str_modify(str); str->len--; @@ -1545,8 +1532,8 @@ Init_String() rb_define_method(C_String, "each", Fstr_each, 0); rb_define_method(C_String, "each_byte", Fstr_each_byte, 0); - rb_define_func(C_Kernel, "sub", Fsub, 2); - rb_define_func(C_Kernel, "gsub", Fgsub, 2); + rb_define_method(C_Kernel, "sub", Fsub, 2); + rb_define_method(C_Kernel, "gsub", Fgsub, 2); pr_str = rb_intern("to_s"); } @@ -87,16 +87,12 @@ struct_new(name, va_alist) va_list args; char *mem; - GC_LINK; - GC_PRO3(st, struct_alloc(C_Struct,name)); + st = struct_alloc(C_Struct,name); va_start(args); - while (mem = va_arg(args, char*)) { struct_add(st, mem, va_arg(args, VALUE)); } - va_end(vargs); - GC_UNLINK; return st; } @@ -115,10 +111,7 @@ Fstruct_new(class, args) rb_scan_args(args, "1*", &name, &tbl); Check_Type(name, T_STRING); - GC_LINK; - GC_PRO(tbl); - GC_PRO3(st, struct_alloc(class, RSTRING(name)->ptr)); - + st = struct_alloc(class, RSTRING(name)->ptr); for (i=0, max=tbl->len; i<max; i++) { VALUE assoc = tbl->ptr[i]; @@ -130,8 +123,6 @@ Fstruct_new(class, args) struct_add(st, RSTRING(ASSOC_KEY(assoc))->ptr, ASSOC_VAL(assoc)); } - GC_UNLINK; - return st; } @@ -156,15 +147,14 @@ Fstruct_values(s) VALUE ary; struct kv_pair *t, *tend; - GC_LINK; - GC_PRO3(ary, ary_new()); + ary = ary_new(); t = s->tbl; tend = t + s->len; while (t < tend) { Fary_push(ary, t->value); t++; } - GC_UNLINK; + return ary; } @@ -207,10 +197,8 @@ Fstruct_inspect(s) int i; ID inspect = rb_intern("_inspect"); - GC_LINK; sprintf(buf, "#<%s%s: ", HDR, s->name); - GC_PRO3(str, str_new2(buf)); - GC_PRO2(str2); + str = str_new2(buf); for (i=0; i<s->len; i++) { if (i > 0) { str_cat(str, ", ", 2); @@ -222,7 +210,6 @@ Fstruct_inspect(s) str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); } str_cat(str, ">", 1); - GC_UNLINK; return str; } @@ -14,6 +14,7 @@ #include <sys/types.h> #include <sys/time.h> #include <sys/times.h> +#include <math.h> static VALUE C_Time; extern VALUE M_Comparable; @@ -41,14 +42,11 @@ Ftime_now(class) VALUE obj = obj_alloc(class); struct time_object *tobj; - GC_LINK; - GC_PRO(obj); MakeTimeval(obj, tobj); if (gettimeofday(&(tobj->tv), 0) == -1) { rb_sys_fail("gettimeofday"); } - GC_UNLINK; return obj; } @@ -60,12 +58,9 @@ time_new_internal(class, sec, usec) VALUE obj = obj_alloc(class); struct time_object *tobj; - GC_LINK; - GC_PRO(obj); MakeTimeval(obj, tobj); tobj->tv.tv_sec = sec; - tobj->tv.tv_usec =usec; - GC_UNLINK; + tobj->tv.tv_usec = usec; return obj; } @@ -95,7 +90,6 @@ time_timeval(time) case T_FLOAT: { - double floor(); double seconds, microseconds; if (RFLOAT(time)->value < 0.0) @@ -480,15 +474,13 @@ Ftime_strftime(time, format) int l, total = 0; char *p = RSTRING(format)->ptr, *pe = p + RSTRING(format)->len; - GC_LINK; - GC_PRO3(str, str_new(0, 0)); + str = str_new(0, 0); while (p < pe) { len = strftime(buf, 100, p, &(tobj->tm)); str_cat(str, buf, len); l = strlen(p); p += l + 1; } - GC_UNLINK; return str; } len = strftime(buf, 100, RSTRING(format)->ptr, &(tobj->tm)); @@ -500,22 +492,14 @@ Ftime_times(obj) VALUE obj; { struct tms buf; - VALUE t1, t2, t3, t4, tm; if (times(&buf) == -1) rb_sys_fail(Qnil); - GC_LINK; - GC_PRO3(t1, float_new((double)buf.tms_utime / 60.0)); - GC_PRO3(t2, float_new((double)buf.tms_stime / 60.0)); - GC_PRO3(t3, float_new((double)buf.tms_cutime / 60.0)); - GC_PRO3(t4, float_new((double)buf.tms_cstime / 60.0)); - - tm = struct_new("tms", - "utime", t1, "stime", t2, - "cutime", t3, "cstime", t4, - Qnil); - GC_UNLINK; - - return tm; + return struct_new("tms", + "utime", float_new((double)buf.tms_utime / 60.0), + "stime", float_new((double)buf.tms_stime / 60.0), + "cutime", float_new((double)buf.tms_cutime / 60.0), + "cstime", float_new((double)buf.tms_cstime / 60.0), + Qnil); } Init_Time() diff --git a/variable.c b/variable.c index 27b5630170..5bddd9cc1d 100644 --- a/variable.c +++ b/variable.c @@ -57,17 +57,18 @@ struct global_entry { VALUE (*set_hook)(); }; -static mark_global_entry(key, entry) +static +mark_global_entry(key, entry) ID key; struct global_entry *entry; { switch (entry->mode) { case GLOBAL_VAL: - mark(entry->v.val); /* normal global value */ + gc_mark(entry->v.val); /* normal global value */ break; case GLOBAL_VAR: if (entry->v.var) - mark(*entry->v.var); /* c variable pointer */ + gc_mark(*entry->v.var); /* c variable pointer */ break; default: break; @@ -75,7 +76,7 @@ static mark_global_entry(key, entry) return ST_CONTINUE; } -mark_global_tbl() +gc_mark_global_tbl() { st_foreach(global_tbl, mark_global_entry, 0); } @@ -194,6 +195,8 @@ rb_gvar_get(entry) default: break; } + if (verbose) + Warning("global var %s not initialized", rb_id2name(entry->id)); return Qnil; } @@ -207,6 +210,8 @@ rb_ivar_get_1(obj, id) return Qnil; if (st_lookup(obj->iv_tbl, id, &val)) return val; + if (verbose) + Warning("instance var %s not initialized", rb_id2name(id)); return Qnil; } @@ -224,6 +229,8 @@ rb_mvar_get(id) VALUE val; if (st_lookup(class_tbl, id, &val)) return val; + if (verbose) + Warning("local var %s not initialized", rb_id2name(id)); return Qnil; } @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.49" -#define VERSION_DATE "18 Jul 94" +#define RUBY_VERSION "0.50" +#define VERSION_DATE "10 Aug 94" |