summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYukihiro Matsumoto <matz@ruby-lang.org>1994-08-10 06:54:46 (GMT)
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-17 13:09:30 (GMT)
commit6e3090413652b6592346556149fed1e9aec5495d (patch)
treebac97139bbeedc8cb67cb2e451a22ed4ddb2b2d4
parent200e0ee2fd3c1c006c528874a88f684447215524 (diff)
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-IF181
-rw-r--r--CVS/Entries51
-rw-r--r--CVS/Repository1
-rw-r--r--ChangeLog131
-rw-r--r--Makefile206
-rw-r--r--Makefile.in10
-rw-r--r--README51
-rw-r--r--ToDo2
-rw-r--r--array.c51
-rw-r--r--bignum.c107
-rw-r--r--bring57
-rw-r--r--class.c61
-rwxr-xr-xconfig.status72
-rw-r--r--configure.in4
-rw-r--r--dbm.c25
-rw-r--r--defines.h4
-rw-r--r--dict.c87
-rw-r--r--dir.c13
-rw-r--r--enum.c43
-rw-r--r--error.c3
-rw-r--r--etc.c76
-rw-r--r--eval.c257
-rw-r--r--file.c26
-rw-r--r--gc.c522
-rw-r--r--io.c166
-rw-r--r--math.c3
-rw-r--r--methods.c59
-rw-r--r--methods.h22
-rw-r--r--missing/strftime.c4
-rwxr-xr-xnewver.rb2
-rw-r--r--node.h13
-rw-r--r--numeric.c58
-rw-r--r--object.c36
-rw-r--r--pack.c9
-rw-r--r--parse.y388
-rw-r--r--process.c27
-rw-r--r--random.c4
-rw-r--r--range.c8
-rw-r--r--re.c18
-rw-r--r--regex.c2
-rw-r--r--ruby.122
-rw-r--r--ruby.c28
-rw-r--r--ruby.h52
-rw-r--r--sample/cbreak.rb6
-rw-r--r--sample/fullpath.rb1
-rw-r--r--sample/gctest.rb3
-rwxr-xr-xsample/getopts.test4
-rw-r--r--sample/newver.rb13
-rw-r--r--sample/opt_s.rb4
-rw-r--r--sample/rcs.rb2
-rw-r--r--sample/ruby-mode.el296
-rw-r--r--sample/system.rb2
-rw-r--r--sample/t1.rb8
-rw-r--r--sample/trojan.pl12
-rw-r--r--sample/trojan.rb12
-rw-r--r--socket.c53
-rw-r--r--spec192
-rw-r--r--sprintf.c9
-rw-r--r--string.c25
-rw-r--r--struct.c23
-rw-r--r--time.c34
-rw-r--r--variable.c15
-rw-r--r--version.h4
63 files changed, 1998 insertions, 1682 deletions
diff --git a/C-IF b/C-IF
index df4dffc..de50de0 100644
--- a/C-IF
+++ b/C-IF
@@ -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 067e16d..0000000
--- 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 b98482f..0000000
--- a/CVS/Repository
+++ /dev/null
@@ -1 +0,0 @@
-/work/cvsroot/ruby
diff --git a/ChangeLog b/ChangeLog
index c54fa30..73803d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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ΥץϤʤʤä.
diff --git a/Makefile b/Makefile
index a5d9bab..0908d49 100644
--- a/Makefile
+++ b/Makefile
@@ -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 33338c9..66b3689 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 0000000..3ca523b
--- /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Ǥ, 쥸
+ ɥեå夹륳ɤɲäɬפ뤫Τʤ.
diff --git a/ToDo b/ToDo
index b909816..ed9c6d0 100644
--- a/ToDo
+++ b/ToDo
@@ -1,6 +1,4 @@
-* $0ؤpsνϤѲ褦
* rubyѿhookμ¸
-* FUNCΥ᥽åɤɬפ
* write debugger for ruby
* re-write regex code for speeding
* byte code interpretor
diff --git a/array.c b/array.c
index 91c06a3..d71edd2 100644
--- a/array.c
+++ b/array.c
@@ -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);
diff --git a/bignum.c b/bignum.c
index ce124a6..c149242 100644
--- a/bignum.c
+++ b/bignum.c
@@ -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 771cd04..0000000
--- 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
diff --git a/class.c b/class.c
index 406c0f1..867a2ac 100644
--- a/class.c
+++ b/class.c
@@ -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 7bdc7b2..0000000
--- 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 0acb17e..041018e 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
diff --git a/dbm.c b/dbm.c
index f3946f7..cee887e 100644
--- a/dbm.c
+++ b/dbm.c
@@ -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;
}
diff --git a/defines.h b/defines.h
index b654334..2e91751 100644
--- a/defines.h
+++ b/defines.h
@@ -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
diff --git a/dict.c b/dict.c
index 909a85a..016917e 100644
--- a/dict.c
+++ b/dict.c
@@ -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);
}
diff --git a/dir.c b/dir.c
index bf62e30..87c9bce 100644
--- a/dir.c
+++ b/dir.c
@@ -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);
}
diff --git a/enum.c b/enum.c
index bf04757..38feb29 100644
--- a/enum.c
+++ b/enum.c
@@ -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;
}
diff --git a/error.c b/error.c
index 001f93d..d76922b 100644
--- a/error.c
+++ b/error.c
@@ -154,6 +154,9 @@ static char *builtin_types[] = {
"Fixnum",
"Dictionary",
"Data",
+ "Method",
+ "Struct",
+ "Bignum",
};
WrongType(x, t)
diff --git a/etc.c b/etc.c
index 311f6eb..eb7e225 100644
--- a/etc.c
+++ b/etc.c
@@ -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
diff --git a/eval.c b/eval.c
index f4d6d54..7a69a22 100644
--- a/eval.c
+++ b/eval.c
@@ -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);
}
diff --git a/file.c b/file.c
index 7001a2f..8ff7c75 100644
--- a/file.c
+++ b/file.c
@@ -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];
diff --git a/gc.c b/gc.c
index 5f30206..96b886f 100644
--- a/gc.c
+++ b/gc.c
@@ -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);
}
diff --git a/io.c b/io.c
index b3ed236..4b3c03a 100644
--- a/io.c
+++ b/io.c
@@ -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);
diff --git a/math.c b/math.c
index b6fbb06..ebe14ee 100644
--- a/math.c
+++ b/math.c
@@ -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
diff --git a/methods.c b/methods.c
index d861323..b085799 100644
--- a/methods.c
+++ b/methods.c
@@ -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 0000000..944eb88
--- /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 36a325a..4d3561c 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();
diff --git a/newver.rb b/newver.rb
index 48ff389..bee3853 100755
--- a/newver.rb
+++ b/newver.rb
@@ -1,4 +1,4 @@
-#! ./ruby
+#! /usr/local/bin/ruby
f = open("version.h", "r")
f.gets()
f.close
diff --git a/node.h b/node.h
index 2e4c134..4f6ef4a 100644
--- a/node.h
+++ b/node.h
@@ -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)
diff --git a/numeric.c b/numeric.c
index 34d8213..c8fcc45 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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);
diff --git a/object.c b/object.c
index fd00c2f..25e3342 100644
--- a/object.c
+++ b/object.c
@@ -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("=~");
diff --git a/pack.c b/pack.c
index 18de67e..6adc0a6 100644
--- a/pack.c
+++ b/pack.c
@@ -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;
}
diff --git a/parse.y b/parse.y
index 0f4f640..ff1a7f6 100644
--- a/parse.y
+++ b/parse.y
@@ -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);
diff --git a/process.c b/process.c
index 7a1dd39..8032524 100644
--- a/process.c
+++ b/process.c
@@ -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");
diff --git a/random.c b/random.c
index ed21c7e..eaccbab 100644
--- a/random.c
+++ b/random.c
@@ -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);
}
diff --git a/range.c b/range.c
index 816ce27..70e0d49 100644
--- a/range.c
+++ b/range.c
@@ -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;
}
diff --git a/re.c b/re.c
index ac70478..ac92b4b 100644
--- a/re.c
+++ b/re.c
@@ -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);
diff --git a/regex.c b/regex.c
index ae6db7c..58ef7f5 100644
--- a/regex.c
+++ b/regex.c
@@ -43,7 +43,7 @@
#else /* not emacs */
-#define RUBY
+#include "defines.h"
#include <sys/types.h>
#ifdef __STDC__
diff --git a/ruby.1 b/ruby.1
index df2e0aa..a674a3d 100644
--- a/ruby.1
+++ b/ruby.1
@@ -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)
diff --git a/ruby.c b/ruby.c
index 5b98281..3a580e6 100644
--- a/ruby.c
+++ b/ruby.c
@@ -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:
diff --git a/ruby.h b/ruby.h
index a454394..092d26f 100644
--- a/ruby.h
+++ b/ruby.h
@@ -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 4b4cb1d..5befd50 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 b1d4b9c..6c528f6 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 6067393..23476d2 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 16f1bb0..cdb818d 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 bbf03ae..0000000
--- 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 4981119..5402be7 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 b147429..6d7f10c 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 0000000..96915bd
--- /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 c51626d..1693d90 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 98d3b52..701a1cd 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 0000000..fe80786
--- /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 0000000..bd49d44
--- /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
diff --git a/socket.c b/socket.c
index ce0f71d..8fc8e25 100644
--- a/socket.c
+++ b/socket.c
@@ -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);
diff --git a/spec b/spec
index 2171e95..aa3d96e 100644
--- a/spec
+++ b/spec
@@ -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
diff --git a/sprintf.c b/sprintf.c
index e63798b..7ae3ecc 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -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");
}
diff --git a/string.c b/string.c
index 57198e4..d3b07a9 100644
--- a/string.c
+++ b/string.c
@@ -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");
}
diff --git a/struct.c b/struct.c
index 6589251..162fb69 100644
--- a/struct.c
+++ b/struct.c
@@ -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;
}
diff --git a/time.c b/time.c
index 05f477c..4f9d38f 100644
--- a/time.c
+++ b/time.c
@@ -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 27b5630..5bddd9c 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;
}
diff --git a/version.h b/version.h
index f158e8a..ed525e1 100644
--- a/version.h
+++ b/version.h
@@ -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"