summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYukihiro Matsumoto <matz@ruby-lang.org>1994-10-13 12:13:48 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-17 22:09:30 +0900
commiteed5c920dd5429bac6075e9bc98d82360392b424 (patch)
tree825427093bc27339080dbbcaebc1563703bae357
parent6e3090413652b6592346556149fed1e9aec5495d (diff)
version 0.51v0_51
https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.51.tar.gz Thu Oct 13 12:13:48 1994 Yukihiro Matsumoto (matz@ix-02) * eval.c(SETUP_ARGS): 付加演算子が配列でない時には配列に変換する. * parse.y: 括弧なしのメソッド呼び出しでも`*'による付加引数が使える ようにした. ただし, 通常引数が一つもない場合は乗算演算子と区別が つかないので, 必ず括弧が必要. Wed Oct 12 10:09:07 1994 Yukihiro Matsumoto (matz@ix-02) * eval.c(rb_call): キャッシュの計算をinline化. キャッシュミスがあ れば関数呼び出しでメソッドを検索する. methods.cはなくなった. * eval.c(rb_eval): ローカル変数用の領域をalloca()するように変更. サイズの変更が必要になれば改めてmalloc()するように. * parse.y: error recoveryの際にlex_stateを更新しておくように. Tue Oct 11 17:10:46 1994 Yukihiro Matsumoto (matz@ix-02) * socket.c(for_fd): ファイル記述子(Fixnum)からソケットインスタンス を得るメソッド. たとえばinetdから起動されたサーバで標準入出力に ソケット操作を行なうために使う. つまりSocket.for_fd($stdin)で標 準入力に対応するソケットオブジェクトが得られる. * io.c(to_i): IOクラスのインスタンスを整数に変換するとそのファイル 記述子を返すように. * numeric.c(num2int): to_iメソッドを使って, できる限り整数に変換す る. 以前はnum2fixだけが全てのオブジェクトに対してto_iメソッドを 適用していた. * sprintf.c(Fsprintf): 整数表示の際, オブジェクトをできる限り整数 に変換するように(to_iメソッドを使う). Fri Oct 7 14:06:32 1994 Yukihiro Matsumoto (matz@ix-02) * eval.c(Fcaller): 必要性がよく分からないのでドキュメントから削除. 将来デバッガを作る時に復活させよう. * eval.c(rb_call): Cで記述されたメソッド呼び出しでは環境をスタック にセーブしないことによって高速化. Wed Oct 5 15:00:58 1994 Yukihiro Matsumoto (matz@ix-02) * ruby.h: 一時env.hに移動してたQselfの定義を復活. ただし今回は関数 として実現(env.hでは変数として再定義してある). * ruby.h: TRUEでsyntax errorにならないよう#undefを追加. * eval.c(rb_eval): thread化に挑戦したが, 失敗(速くならなかった). が, Scopingなどの無駄なコードの削除とメソッド呼び出しの引数セッ トのinline化で若干の高速化を実現した. 副作用として, argc, argv形 式の関数呼び出しの仕様が変化した(argvにselfを含まなくなった). * eval.c(rb_call): メソッド呼び出しの高速化. Tue Oct 4 11:40:53 1994 Yukihiro Matsumoto (matz@ix-02) * ruby-mode.el: 修飾子に対応した. * parse.y: 多重代入にrestをつけた. この機能を使えばoptional引数の 解析が簡単にできる(はず). * pack.c(unpack): uuencode形式のdecodeの際に文字列の長さが間違って いた. Mon Oct 3 15:58:41 1994 Yukihiro Matsumoto (matz@ix-02) * file.c(type): ファイルタイプを文字列で返すメソッド. Fri Sep 30 11:36:07 1994 Yukihiro Matsumoto (matz@ix-02) * object.c: デフォルトの真の値である%TRUEの値を1(Fixnum)からtに変 更した. to_sで文字列に変換した時にも`t'と表示される. 更に踏み込 んで`t'を予約語にしてlispのようにしようかとも思ったが, そこまで は決心できなかった. 一文字のローカル変数はかなり使いそうな気がす るので…. * array.c,dict.c: equalを再定義しているクラスで, hashを正しく定義 した. Wed Sep 28 23:30:28 1994 Yukihiro Matsumoto (matz@dyna) * eval.c(Ffail): 今までfailはカーネルクラスのメソッドであったが, 構文に組み込んだ. この変更によって, 1)`fail'は予約語となり, ロー カル変数に用いることができなくなった. 2)`fail'単体で例外を発生す るようになった. 3)failはメソッドではなくなったので再定義される可 能性がなくなった. * dic.c, dbm.c(indexes): Arrayのindexesと同様の機能を持つメソッド を追加. * array.c(indexes): 引数をインデックスとする要素の配列を返す. 整数 の配列を引数とする時には引数の要素をインデックスとする要素の配列 を返す. Mon Sep 19 13:42:31 1994 Yukihiro Matsumoto (matz@ix-02) * array.c(aset): 部分配列に対する代入で配列以外のオブジェクトが指 定された場合に多重代入と同じルールで配列化するようにした. * io.c(print): 引数として与えられた各オブジェクトにprint_onメッセー ジを与えるように. 実行速度は落ちるが柔軟性は増す. Fri Sep 16 14:59:18 1994 Yukihiro Matsumoto (matz@ix-02) * glob.c: ワイルドカードの導入. bashに使われているGNUのglobルーチ ンを流用した. Mon Sep 12 18:36:58 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y(value_expr): 式がnilの時に対応. * class.c: ICLASSのclassが必ずClass/Moduleを指すように. Tue Sep 6 16:23:28 1994 Yukihiro Matsumoto (matz@ix-02) * re.c: 正規表現内で「\数字」形式が指定できるように. * parse.y:「do expr using var ... end」形式はなくなった. 寂しい気 もする. *BACKWARD INCOMPATIBILITY* Mon Sep 5 10:59:01 1994 Yukihiro Matsumoto (matz@ix-02) * numeric.c(next): Numericクラスにもnextを提供. * string.c(upto): uptoを提供. * range.c(each): nextを使ったインタフェースからuptoを使うように変 更した. この方が一つのメソッドで処理をまとめで行なうことができる. Fri Sep 2 15:25:39 1994 Yukihiro Matsumoto (matz@ix-02) * dict.c(each): 戻り値を[key, value]のペアに変更. 今までのeachは each_valueとして残る. *BACKWARD INCOMPATIBILITY* Thu Sep 1 10:49:04 1994 Yukihiro Matsumoto (matz@ix-02) * 成功した(特別な戻り値を持たない)システムコールは`0'を返すように. Wed Aug 31 00:26:51 1994 Yukihiro Matsumoto (matz@dyna) * string.c: チェックサムを得るメソッド`sum'を作った. * class.c(include_class_new): ICLASSのclassをもとのクラスにした. gcの際に元クラスをマークする必要があるのが, フィールドを増やす余 地が無いので, classフィールドを流用した. 私の見積りが間違ってい て, ICLASSのインスタンスにメッセージを送る事があれば, おかしな動 作をするだろう. * eval.c(masign): 式(a,b = nil)の値を[nil]からnilに変更した. Mon Aug 29 11:56:09 1994 Yukihiro Matsumoto (matz@ix-02) * class.c: rb_define_mfuncを無くして, メタクラスにモジュールをイン クルードするようにした. * error.c(yyerror): 同じ行で複数のsyntax errorをリポートしないよう にした. * file.c: FileTestモジュールにファイルテストメソッドを分離した. * parse.y: 演算子を指定する時のlex_stateを正しく設定した. Sat Aug 27 01:23:34 1994 Yukihiro Matsumoto (matz@dyna) * parse.y: if/whileなどの複合式をprimaryに移動した. これによって例 えば「if cond then a else b end.message()」のような式が書けるよ うになった. Fri Aug 26 10:46:30 1994 Yukihiro Matsumoto (matz@ix-02) * spec: 整理された文法にしたがって書き直した. * parse.y: ここ数日で混乱していた文法を整理した. 括弧を省略したメ ソッド呼び出しができるようになったこと, modifierが付けられるよう になったこと, returnにリストが渡せるようになったことが主な変更点 である. * process周りが怪しいがとにかくSolaris 2.3で動くように. * parse.y: 曖昧性がない場合にはメソッド呼び出しの引数の括弧を省略 できるように. 省略できるメソッド呼び出しの条件は, 1)かならず1個 以上の引数を必要とすること, 2)第1引数が`+', `-', `(', `[', `{', `/'など, 式の始まりに置かれた時と途中に現れた時とで解釈が違う記 号で始まらないこと, である. Thu Aug 25 13:54:58 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y(cond): 条件式の展開部にbugがあった. Wed Aug 24 00:01:15 1994 Yukihiro Matsumoto (matz@dyna) * parse.y: returnはコンマで区切ったリストも受け取るように. つまり, return a, b, cはreturn [a, b, c]と同じ意味になる. * parse.y: yield以外の大域脱出制御式をexprからexpr0に移した. よっ てメソッドの引数に制御式を使えなくなる(これで困る人はいないはず). * parse.y: `+'の定数展開の際に演算子の優先順位を忘れていた. * eval.c: untilの戻り値はnilになった. * parse.y: modifierとしてのif/unless/while/untilを追加. * parse.y: 文法からendの後ろにつけるキーワードを削除. ほとんど使わ なかった上に, emacsではruby-modeがあれば対応のチェックが機械的に 出来るため. Tue Aug 23 18:08:33 1994 Yukihiro Matsumoto (matz@ix-02) * eval.c: スクリプト実行開始前に例外が発生した時にcore dumpした. 組み込み用にコードを変更した時にenbugしてしまった. Tue Aug 23 00:07:17 1994 Yukihiro Matsumoto (matz@dyna) * eval.c: doの戻り値がいつもnilになっていた. * parse.y: loop制御変数の多重代入化にbugがあった. * parse.y(expand_op): 文字列も畳み込みの対象に. Mon Aug 22 10:50:01 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y(expand_op): `+'に関しては結合則を使って, より多く定数畳 み込みを行なうように. * ruby.c(proc_options): argcが0の時にも対応. * parse.y: forなどの制御変数に多重代入も使えるように. Sat Aug 20 00:59:40 1994 Yukihiro Matsumoto (matz@dyna) * parse.y(call_op): 演算子`~'の取り扱いをルール部へ移動. Fri Aug 19 11:44:13 1994 Yukihiro Matsumoto (matz@ix-02) * main.c: rubyをほかのプログラムに組み込めるようにmain()を分割した. それにともない, プログラムの呼び出し構造を修正した. * parse.y: 条件式の定義を変更. ifなどの条件式の中でだけ`&&'や`||' および`!'の引数が条件式になるように. この変更により条件式以外の 場所での `&&', `||', `!'演算子の動作が直観に一致する. * parse.y: 実引数の`*'の後に続く引数はexprに制限した. 今までは全て の文が有効であったが, ここで定義文があってもしょうがない. Thu Aug 18 10:21:45 1994 Yukihiro Matsumoto (matz@ix-02) * re.c: 正規表現ルーチンの初期化部分を削除してしまっていた. これで はemacsの正規表現になってしまう. * version.c: copyright表示を追加. * version.c: バージョン表示をstderrに. * configure.in: gccがない場合testに失敗していた. Fri Aug 12 14:12:23 1994 Yukihiro Matsumoto (matz@ix-02) * array.c(astore): 配列の拡大する時にある程度の大きさをまとめて拡 大するように. * io.c(Fprint): 配列に対しては一度文字列に変換することなく, 直接内 容を出力するように. * string.c(str_new): memmoveからmemcpyへ置き換えた. これでもかなり 速度が違う. * ruby.h: データメンバの取り出しで名前を文字列からIDで指定するよう にした. かなりの高速化になる. * io.c: $ARGFという変数で引数列からなる仮想ファイルをオブジェクト として扱えるようにした. 今まではトップレベルのgets()などを使って アクセスしていたが, どうもオブジェクト指向的ではなかった. Thu Aug 11 11:43:15 1994 Yukihiro Matsumoto (matz@ix-02) * gc.c: mark_location()の間違った呼び出し方の行が残っていた. * method.c: プロトタイプ宣言が足りなかった.
-rw-r--r--C-IF63
-rw-r--r--ChangeLog314
-rw-r--r--Makefile6
-rw-r--r--Makefile.in27
-rw-r--r--ToDo2
-rw-r--r--array.c122
-rw-r--r--bignum.c4
-rw-r--r--class.c28
-rw-r--r--compar.c48
-rw-r--r--configure.in12
-rw-r--r--dbm.c46
-rw-r--r--defines.h2
-rw-r--r--dict.c81
-rw-r--r--dir.c21
-rw-r--r--dln.c14
-rw-r--r--dln.h4
-rw-r--r--enum.c2
-rw-r--r--env.h13
-rw-r--r--error.c9
-rw-r--r--etc.c20
-rw-r--r--eval.c881
-rw-r--r--file.c219
-rw-r--r--fnmatch.c189
-rw-r--r--fnmatch.h36
-rw-r--r--gc.c23
-rw-r--r--glob.c177
-rw-r--r--gnuglob.c572
-rw-r--r--ident.h4
-rw-r--r--inits.c3
-rw-r--r--io.c180
-rw-r--r--io.h10
-rw-r--r--main.c17
-rw-r--r--math.c20
-rw-r--r--methods.c152
-rw-r--r--methods.h6
-rw-r--r--missing.c2
-rw-r--r--missing/strstr.c2
-rw-r--r--node.h20
-rw-r--r--numeric.c163
-rw-r--r--object.c53
-rw-r--r--pack.c11
-rw-r--r--parse.y1341
-rw-r--r--process.c100
-rw-r--r--random.c2
-rw-r--r--range.c60
-rw-r--r--re.c11
-rw-r--r--re.h4
-rw-r--r--ruby.1121
-rw-r--r--ruby.c161
-rw-r--r--ruby.h17
-rw-r--r--sample/biorhythm.rb4
-rw-r--r--sample/cat2.rb4
-rw-r--r--sample/getopts.rb2
-rw-r--r--sample/io.rb2
-rw-r--r--[-rwxr-xr-x]sample/newver.rb (renamed from newver.rb)7
-rw-r--r--sample/rcs.rb10
-rw-r--r--sample/ruby-mode.el139
-rw-r--r--sample/sieve.rb16
-rw-r--r--sample/t2.rb7
-rw-r--r--sample/trojan.rb12
-rw-r--r--sample/tt.rb19
-rw-r--r--socket.c25
-rw-r--r--spec1459
-rw-r--r--sprintf.c8
-rw-r--r--st.c2
-rw-r--r--string.c189
-rw-r--r--struct.c2
-rw-r--r--time.c10
-rw-r--r--variable.c13
-rw-r--r--version.c12
-rw-r--r--version.h4
71 files changed, 4887 insertions, 2454 deletions
diff --git a/C-IF b/C-IF
index de50de0eed..98d45925af 100644
--- a/C-IF
+++ b/C-IF
@@ -21,8 +21,19 @@ Ruby-C 󥿡ե
ѿ: ߤself֥Ȥ. ̤˥᥽åɤˤselfؤ
ͿΤ, ѿ˥ɬפϤʤ. ѿͤ
- ѹϰʸselfͤΤΤѤäƤޤΤ, Ť˹Ԥ
- .
+ ѹϰʸselfͤΤΤѤäƤޤΤ, ̤ʻ
+ ʤ¤ƤϤʤʤ.
+
+ : إåե"env.h"򥤥󥯥롼ɤƤʤեǤ,
+ QselfǤ, ʸˡ顼Ȥʤ.
+
+ TRUE
+
+ : t֥(Υǥե)
+
+ FALSE
+
+ : nil֥
饹⥸塼
@@ -54,8 +65,8 @@ Ruby-C 󥿡ե
void rb_global_variable(VALUE *var)
- GCRubyϥʤ, Ruby֥Ȥޤѿ
- ޡ.
+ GCΤRubyϥʤ, Ruby֥Ȥޤ
+ ޡ.
void rb_read_only_hook()
@@ -72,9 +83,10 @@ Ruby-C 󥿡ե
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
- ᥽åɤ. argcselfο. argc-1λ,
- argc, argvͿ. argc-2λ, self, args(args
- ޤruby)ȤͿ.
+ ᥽åɤ. argcselfο. argc-1λ, ؿ
+ ϰο(selfޤޤʤ)1, 2Ȥ
+ Ϳ. argc-2λ, self, args(argsϰޤruby
+ )ȤͿ.
rb_define_single_method(VALUE class, char *name, VALUE (*func)(), int argc)
@@ -83,10 +95,10 @@ Ruby-C 󥿡ե
rb_scan_args(VALUE args, char *fmt, ...)
argsͿ줿ʬ򤹤. fmtɬܰο, ղðο,
- Ĥΰ뤫ꤹʸ, "*"ȤǤ.
- 2 ܤο"*"ϾάǽǤ. 3ʹߤѿؤΥݥ󥿤,
- Ǥѿ˳Ǽ. ղðͿʤ
- Qnil.
+ Ĥΰ뤫ꤹʸ, "*"ȤǤ.
+ 2 ܤο"*"Ϥ줾άǽǤ. 3ʹߤѿؤΥ
+ 󥿤, Ǥѿ˳Ǽ. ղðб
+ ͿƤʤѿQnil.
Ruby᥽åɸƤӽФ
@@ -109,6 +121,11 @@ Ruby᥽åɸƤӽФ
IDбʸ֤(ǥХå).
+ char *rb_class2name(VALUE class)
+
+ class֤̾(ǥХå). class̾ʤˤ, ֶ
+ ̾ĥ饹֤̾.
+
󥹥ѿ
VALUE rb_iv_get(VALUE obj, char *name)
@@ -125,8 +142,8 @@ Ruby᥽åɸƤӽФ
VALUE rb_iterate(VALUE (*func1)(), char *arg1, VALUE (*func2)(), char *arg2)
func2֥åȤꤷ, func1򥤥ƥ졼ȤƸƤ. func1
- arg1ȤϤ, func2ˤ1˥ƥ졼ȤͿ
- 줿, 2arg2Ϥ.
+ arg1ȤϤ, func2ˤ1˥ƥ졼Ϳ
+ , 2arg2Ϥ.
VALUE rb_yield(VALUE val)
@@ -142,10 +159,14 @@ Ruby᥽åɸƤӽФ
ؿfunc1arg1ȤƼ¹Ԥ, ¹Խλ(Ȥ㳰ȯ
) func2arg2ȤƼ¹Ԥ. ͤfunc1ͤǤ(
- ȯnil).
+ ȯʤ).
㳰顼
+ void Warning(char *fmt, ...)
+
+ ɸ२顼Ϥ˷ٹɽ. printf()Ʊ.
+
void Fail(char *fmt, ...)
㳰ȯ. printf()Ʊ.
@@ -161,6 +182,20 @@ Ruby᥽åɸƤӽФ
Ƥ. 󥿡ץ꥿ϥפľ˽λ. 㳰ϰڹ
ʤʤ.
+rubyν¹
+
+ void ruby_init(int argc, char **argv, char **envp)
+
+ ruby󥿥ץ꥿νԤʤ.
+
+ void ruby_run()
+
+ ruby󥿥ץ꥿¹Ԥ.
+
+ void ruby_script(char *name)
+
+ rubyΥץ̾($0)ꤹ.
+
/*
* Local variables:
* fill-column: 70
diff --git a/ChangeLog b/ChangeLog
index 73803d128e..c6886439c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,286 @@
+Thu Oct 13 12:13:48 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * eval.c(SETUP_ARGS): ղñ黻ҤǤʤˤѴ.
+
+ * parse.y: ̤ʤΥ᥽åɸƤӽФǤ`*'ˤղðȤ
+ 褦ˤ. , ̾ĤʤϾ軻黻Ҥȶ̤
+ ĤʤΤ, ɬ̤ɬ.
+
+Wed Oct 12 10:09:07 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * eval.c(rb_call): åη׻inline. åߥ
+ дؿƤӽФǥ᥽åɤ򸡺. methods.cϤʤʤä.
+
+ * eval.c(rb_eval): ѿѤΰalloca()褦ѹ.
+ ѹɬפˤʤвmalloc()褦.
+
+ * parse.y: error recoveryκݤlex_state򹹿Ƥ褦.
+
+Tue Oct 11 17:10:46 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * socket.c(for_fd): ե뵭һ(Fixnum)饽åȥ󥹥
+ ᥽å. Ȥinetd鵯ư줿ФɸϤ
+ åԤʤ˻Ȥ. ĤޤSocket.for_fd($stdin)ɸ
+ Ϥб륽åȥ֥Ȥ.
+
+ * io.c(to_i): IO饹Υ󥹥󥹤ѴȤΥե
+ һҤ֤褦.
+
+ * numeric.c(num2int): to_i᥽åɤȤä, Ǥ¤Ѵ
+ . num2fixƤΥ֥ȤФto_i᥽åɤ
+ ŬѤƤ.
+
+ * sprintf.c(Fsprintf): ɽκ, ֥ȤǤ¤
+ Ѵ褦(to_i᥽åɤȤ).
+
+Fri Oct 7 14:06:32 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * eval.c(Fcaller): ɬ褯ʬʤΤǥɥȤ.
+ ǥХå褵褦.
+
+ * eval.c(rb_call): CǵҤ줿᥽åɸƤӽФǤϴĶ򥹥å
+ ˥֤ʤȤˤäƹ®.
+
+Wed Oct 5 15:00:58 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * ruby.h: env.h˰ưƤQself. ϴؿ
+ ȤƼ¸(env.hǤѿȤƺƤ).
+
+ * ruby.h: TRUEsyntax errorˤʤʤ褦#undefɲ.
+
+ * eval.c(rb_eval): threadĩ路, (®ʤʤä).
+ , Scopingʤɤ̵̤ʥɤκȥ᥽åɸƤӽФΰ
+ ȤinlineǼ㴳ι®¸. ѤȤ, argc, argv
+ δؿƤӽФλͤѲ(argvselfޤޤʤʤä).
+
+ * eval.c(rb_call): ᥽åɸƤӽФι®.
+
+Tue Oct 4 11:40:53 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * ruby-mode.el: Ҥб.
+
+ * parse.y: ¿restĤ. εǽȤoptional
+ ϤñˤǤ(Ϥ).
+
+ * pack.c(unpack): uuencodedecodeκݤʸĹְä
+ .
+
+Mon Oct 3 15:58:41 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * file.c(type): ե륿פʸ֤᥽å.
+
+Fri Sep 30 11:36:07 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * object.c: ǥեȤοͤǤ%TRUEͤ1(Fixnum)t
+ . to_sʸѴˤ`t'ɽ. Ƨ߹
+ `t'ͽˤlispΤ褦ˤ褦Ȥפä, ޤ
+ Ϸ迴Ǥʤä. ʸΥѿϤʤȤʵ
+ Τǡ.
+
+ * array.c,dict.c: equalƤ륯饹, hash
+ .
+
+Wed Sep 28 23:30:28 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * eval.c(Ffail): ޤfailϥͥ륯饹Υ᥽åɤǤä,
+ ʸȤ߹. ѹˤä, 1)`fail'ͽȤʤ,
+ ѿѤ뤳ȤǤʤʤä. 2)`fail'ñΤ㳰ȯ
+ 褦ˤʤä. 3)failϥ᥽åɤǤϤʤʤäΤǺ
+ ǽʤʤä.
+
+ * dic.c, dbm.c(indexes): ArrayindexesƱͤεǽĥ᥽å
+ ɲ.
+
+ * array.c(indexes): 򥤥ǥåȤǤ֤.
+ ȤˤϰǤ򥤥ǥåȤǤ
+ ֤.
+
+Mon Sep 19 13:42:31 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * array.c(aset): ʬФʳΥ֥Ȥ
+ ꤵ줿¿Ʊ롼󲽤褦ˤ.
+
+ * io.c(print): ȤͿ줿ƥ֥Ȥprint_onå
+ Ϳ褦. ¹®٤뤬.
+
+Fri Sep 16 14:59:18 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * glob.c: 磻ɥɤƳ. bash˻ȤƤGNUglob롼
+ ήѤ.
+
+Mon Sep 12 18:36:58 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * parse.y(value_expr): nilλб.
+
+ * class.c: ICLASSclassɬClass/Moduleؤ褦.
+
+Tue Sep 6 16:23:28 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * re.c: ɽǡ\׷Ǥ褦.
+
+ * parse.y:do expr using var ... end׷Ϥʤʤä. 䤷
+ ⤹. *BACKWARD INCOMPATIBILITY*
+
+Mon Sep 5 10:59:01 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * numeric.c(next): Numeric饹ˤnext.
+
+ * string.c(upto): upto.
+
+ * range.c(each): nextȤä󥿥եuptoȤ褦
+ . ĤΥ᥽åɤǽޤȤǹԤʤȤǤ.
+
+Fri Sep 2 15:25:39 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * dict.c(each): ͤ[key, value]Υڥѹ. ޤǤeach
+ each_valueȤƻĤ. *BACKWARD INCOMPATIBILITY*
+
+Thu Sep 1 10:49:04 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * (̤ͤʤ)ƥॳ`0'֤褦.
+
+Wed Aug 31 00:26:51 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * string.c: å᥽å`sum'ä.
+
+ * class.c(include_class_new): ICLASSclassȤΥ饹ˤ.
+ gcκݤ˸饹ޡɬפΤ, եɤ䤹;
+ Ϥ̵Τ, classեɤήѤ. θѤְ꤬äƤ
+ , ICLASSΥ󥹥󥹤˥å, ư
+ 򤹤.
+
+ * eval.c(masign): (a,b = nil)ͤ[nil]nilѹ.
+
+Mon Aug 29 11:56:09 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * class.c: rb_define_mfunc̵, ᥿饹˥⥸塼򥤥
+ 롼ɤ褦ˤ.
+
+ * error.c(yyerror): ƱԤʣsyntax errorݡȤʤ褦
+ ˤ.
+
+ * file.c: FileTest⥸塼˥եƥȥ᥽åɤʬΥ.
+
+ * parse.y: 黻Ҥꤹlex_stateꤷ.
+
+Sat Aug 27 01:23:34 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * parse.y: if/whileʤɤʣ缰primary˰ư. ˤä
+ Сif cond then a else b end.message()פΤ褦ʼ񤱤
+ ˤʤä.
+
+Fri Aug 26 10:46:30 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * spec: 줿ʸˡˤäƽľ.
+
+ * parse.y: Ǻ𤷤Ƥʸˡ. ̤ά
+ åɸƤӽФǤ褦ˤʤä, modifierդ褦
+ ˤʤä, return˥ꥹȤϤ褦ˤʤäȤѹ
+ Ǥ.
+
+ * process꤬ȤˤSolaris 2.3ư褦.
+
+ * parse.y: ۣʤˤϥ᥽åɸƤӽФΰγ̤ά
+ Ǥ褦. άǤ᥽åɸƤӽФξ, 1)ʤ餺1
+ ʾΰɬפȤ뤳, 2)1`+', `-', `(', `[', `{',
+ `/'ʤ, λϤޤ֤줿˸줿ȤDz᤬㤦
+ ǻϤޤʤ, Ǥ.
+
+Thu Aug 25 13:54:58 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * parse.y(cond): PŸbugä.
+
+Wed Aug 24 00:01:15 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * parse.y: returnϥޤǶڤäꥹȤ褦. Ĥޤ,
+ return a, b, creturn [a, b, c]Ʊ̣ˤʤ.
+
+ * parse.y: yieldʳæ漰exprexpr0˰ܤ.
+ ƥ᥽åɤΰ漰Ȥʤʤ(ǺͤϤʤϤ).
+
+ * parse.y: `+'Ÿκݤ˱黻Ҥ̤ͥ˺Ƥ.
+
+ * eval.c: untilͤnilˤʤä.
+
+ * parse.y: modifierȤƤif/unless/while/untilɲ.
+
+ * parse.y: ʸˡendθˤĤ륭ɤ. ۤȤɻȤ
+ ʤä, emacsǤruby-modeбΥåŪ
+ 뤿.
+
+Tue Aug 23 18:08:33 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * eval.c: ץȼ¹Գ㳰ȯcore dump.
+ Ȥ߹Ѥ˥ɤѹenbugƤޤä.
+
+Tue Aug 23 00:07:17 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * eval.c: doͤĤnilˤʤäƤ.
+
+ * parse.y: loopѿ¿bugä.
+
+ * parse.y(expand_op): ʸ߹ߤоݤ.
+
+Mon Aug 22 10:50:01 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * parse.y(expand_op): `+'˴ؤƤϷ§Ȥä, ¿
+ ߹ߤԤʤ褦.
+
+ * ruby.c(proc_options): argc0λˤб.
+
+ * parse.y: forʤɤѿ¿Ȥ褦.
+
+Sat Aug 20 00:59:40 1994 Yukihiro Matsumoto (matz@dyna)
+
+ * parse.y(call_op): 黻`~'μ갷롼ذư.
+
+Fri Aug 19 11:44:13 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * main.c: rubyۤΥץȤ߹褦main()ʬ䤷.
+ ˤȤʤ, ץθƤӽФ¤.
+
+ * parse.y: Pѹ. ifʤɤξPǤ`&&'`||'
+ `!'ΰPˤʤ褦. ѹˤPʳ
+ Ǥ `&&', `||', `!'黻ҤưľѤ˰פ.
+
+ * parse.y: °`*'θ³expr¤. ޤǤ
+ ʸͭǤä, ʸäƤ⤷礦ʤ.
+
+Thu Aug 18 10:21:45 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * re.c: ɽ롼νʬƤޤäƤ.
+ emacsɽˤʤäƤޤ.
+
+ * version.c: copyrightɽɲ.
+
+ * version.c: Сɽstderr.
+
+ * configure.in: gccʤtest˼ԤƤ.
+
+Fri Aug 12 14:12:23 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * array.c(astore): γ礹ˤ٤礭ޤȤƳ
+ 礹褦.
+
+ * io.c(Fprint): ФƤϰʸѴ뤳Ȥʤ, ľ
+ ƤϤ褦.
+
+ * string.c(str_new): memmovememcpy֤. Ǥ⤫ʤ
+ ®٤㤦.
+
+ * ruby.h: ǡФμФ̾ʸ󤫤IDǻꤹ褦
+ ˤ. ʤι®ˤʤ.
+
+ * io.c: $ARGFȤѿǰ󤫤ʤ벾ۥե򥪥֥
+ Ȥư褦ˤ. ޤǤϥȥåץ٥gets()ʤɤȤä
+ Ƥ, ɤ⥪֥ȻظŪǤϤʤä.
+
+Thu Aug 11 11:43:15 1994 Yukihiro Matsumoto (matz@ix-02)
+
+ * gc.c: mark_location()δְäƤӽФιԤĤäƤ.
+
+ * method.c: ץȥ­ʤä.
+
Wed Aug 10 15:54:46 1994 Yukihiro Matsumoto (matz@ix-02)
* variable.c: -vץ󤬻ꤵƤϽƤʤ,
@@ -15,7 +298,7 @@ Tue Aug 9 11:50:48 1994 Yukihiro Matsumoto (matz@ix-02)
* array.c(Fary_aref): 1ĤFixnumλ, Range checkԤʤ
褦˽.
- * eval.c: ο򥳥ѥ˷׻Ƽ㴳ι®.
+ * eval.c: ᥽åɤΰο򥳥ѥ˷׻Ƽ㴳ι®.
Mon Aug 8 13:06:24 1994 Yukihiro Matsumoto (matz@ix-02)
@@ -105,23 +388,6 @@ Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02)
* dbm.c, dict.c(clear): ᥽åɲ.
-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): ᥽åɲ.
-
Fri Jul 15 10:54:45 1994 Yukihiro Matsumoto (matz@ix-02)
* array.c(Fary_fill,Fary_clear): ᥽åɤɲ.
@@ -141,10 +407,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)
- * eval.c: ᥽åɤ¸ߤʤˤKernel:_undefined(id)ƤФ
- 褦. , rubyǤϸġΥ᥽åν, 饹
- ñ̤νɬפʵ⤹ʤ.
-
* autoexec.c: . autoloadطεǽϺ帡Ƥ褦.
* dict.c: 񥯥饹̾ΤDictѹ. ̾ȤHash
@@ -408,8 +670,8 @@ Wed Jun 15 10:18:27 1994 Yukihiro Matsumoto (matz@ix-02)
Tue Jun 14 16:08:42 1994 Yukihiro Matsumoto (matz@ix-02)
- * gc.c: BignumɲäΤ˺Ƥ. Ȥ߹߷ɲäˤ
- ɬmark()sweep()ˤη˴ؤɲäɬפ.
+ * gc.c: BignumɲäΤ˺Ƥ. Ȥ߹߷ɲä
+ ɬmark()sweep()ˤη˴ؤɲäɬפ.
* bignum: 任ư褦ʵ. 르ꥺ򤷤Ƥʤ
Τ, ʤ.
@@ -422,7 +684,7 @@ Mon Jun 13 14:36:55 1994 Yukihiro Matsumoto (matz@ix-02)
Fri Jun 10 17:26:42 1994 Yukihiro Matsumoto (matz@ix-02)
* Comparable: äȤʤ᥽åɤ`=='`>'`<=>'ѹ.
- ComparableΥ֥饹`<=>'ɬפ.
+ ComparableΥ֥饹`<=>'ɬפ.
Wed Jun 8 13:12:18 1994 Yukihiro Matsumoto (matz@ix-02)
@@ -569,7 +831,7 @@ Mon May 30 10:07:42 1994 Yukihiro Matsumoto (matz@ix-02)
Ϻ򤱤뤳ȤǤȻפ.
* autoconfȤä, ưŪMakefile, config.h褦ˤ.
- , ΥޥǤ`configure'¹Ԥ, `make'ȯǥ
+ , ¿ΥޥǤ`configure'¹Ԥ, `make'ȯǥ
ѥǤȻפ.
* clone: ֥饹ФѤ줿, Υ֥ȤƱ
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 0908d49776..0000000000
--- a/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile -
-#
-# created at: Wed Aug 10 15:21:29 JST 1994
-
-all:; @echo "You must run configure first."
diff --git a/Makefile.in b/Makefile.in
index 66b3689260..7cb2829dce 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -53,11 +53,14 @@ SRCS = array.c \
etc.c \
eval.c \
file.c \
+ fnmatch.c \
gc.c \
+ glob.c \
+ gnuglob.c \
inits.c \
io.c \
+ main.c \
math.c \
- methods.c \
missing.c \
numeric.c \
object.c \
@@ -91,11 +94,14 @@ OBJS = array.o \
etc.o \
eval.o \
file.o \
+ fnmatch.o \
gc.o \
+ glob.o \
+ gnuglob.o \
inits.o \
io.o \
+ main.o \
math.o \
- methods.o \
missing.o \
numeric.o \
object.o \
@@ -128,9 +134,11 @@ $(PROGRAM): $(OBJS)
@rm -f $(PROGRAM)
$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
-install: $(PROGMAM)
+$(bindir)/$(PROGRAM): $(PROGRAM)
$(INSTALL_PROGRAM) $(PROGRAM) $(bindir)/$(PROGRAM)
+install: $(bindir)/$(PROGRAM)
+
clean:; @rm -f $(OBJS)
realclean:; @rm -f $(OBJS)
@@ -142,7 +150,7 @@ dbm.o:dbm.c
# Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT:
###
-parse.o : parse.y ruby.h defines.h env.h ident.h node.h st.h regex.h
+parse.o : parse.y ruby.h defines.h env.h node.h st.h ident.h regex.h
###
array.o : array.c ruby.h defines.h
bignum.o : bignum.c ruby.h defines.h
@@ -155,24 +163,27 @@ dln.o : dln.c defines.h dln.h
enum.o : enum.c ruby.h defines.h
error.o : error.c ruby.h defines.h env.h
etc.o : etc.c ruby.h defines.h
-eval.o : eval.c ruby.h defines.h env.h node.h ident.h st.h
+eval.o : eval.c ruby.h defines.h ident.h env.h node.h methods.h st.h
file.o : file.c ruby.h defines.h io.h
+fnmatch.o : fnmatch.c fnmatch.h
gc.o : gc.c ruby.h defines.h env.h st.h
+glob.o : glob.c ruby.h defines.h fnmatch.h
+gnuglob.o : gnuglob.c fnmatch.h
inits.o : inits.c ruby.h defines.h
io.o : io.c ruby.h defines.h io.h
+main.o : main.c
math.o : math.c ruby.h defines.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
-numeric.o : numeric.c ruby.h defines.h env.h
+numeric.o : numeric.c ruby.h defines.h
object.o : object.c ruby.h defines.h env.h node.h st.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
+regex.o : regex.c defines.h 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
sprintf.o : sprintf.c ruby.h defines.h
diff --git a/ToDo b/ToDo
index ed9c6d06b7..001675c762 100644
--- a/ToDo
+++ b/ToDo
@@ -1,3 +1,5 @@
+* Ŭڤsignal handling
+* dlnCOFFб
* rubyѿhookμ¸
* write debugger for ruby
* re-write regex code for speeding
diff --git a/array.c b/array.c
index d71edd2edf..6193db0644 100644
--- a/array.c
+++ b/array.c
@@ -3,7 +3,7 @@
array.c -
$Author: matz $
- $Date: 1994/06/27 15:48:20 $
+ $Date: 1994/08/12 11:06:34 $
created at: Fri Aug 6 09:46:12 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -16,6 +16,8 @@ VALUE C_Array;
static ID eq;
+VALUE rb_to_a();
+
#define ARY_DEFAULT_SIZE 16
VALUE
@@ -111,19 +113,16 @@ astore(ary, idx, val)
int idx;
VALUE val;
{
- int max;
-
if (idx < 0) {
Fail("negative index for array");
}
- max = idx + 1;
if (idx >= ary->capa) {
- ary->capa = max;
- REALLOC_N(ary->ptr, VALUE, max);
+ ary->capa = idx + ary->capa/5;
+ REALLOC_N(ary->ptr, VALUE, ary->capa);
}
if (idx >= ary->len) {
- bzero(ary->ptr+ary->len, sizeof(VALUE)*(max-ary->len));
+ memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(idx-ary->len+1));
}
if (idx >= ary->len) {
@@ -305,6 +304,42 @@ Fary_aref(ary, args)
}
static VALUE
+Fary_index(ary, val)
+ struct RArray *ary;
+ VALUE val;
+{
+ int i;
+
+ for (i=0; i<ary->len; i++) {
+ if (rb_funcall(ary->ptr[i], eq, 1, val))
+ return INT2FIX(i);
+ }
+ return Qnil;
+}
+
+static VALUE
+Fary_indexes(ary, args)
+ struct RArray *ary, *args;
+{
+ VALUE *p, *pend;
+ VALUE new;
+ int i = 0;
+
+ if (!args || args->len == 1) {
+ args = (struct RArray*)rb_to_a(args->ptr[0]);
+ }
+
+ new = ary_new2(args->len);
+
+ p = args->ptr; pend = p + args->len;
+ while (p < pend) {
+ astore(new, i++, ary_entry(ary, NUM2INT(*p)));
+ p++;
+ }
+ return new;
+}
+
+static VALUE
Fary_aset(ary, args)
struct RArray *ary;
VALUE args;
@@ -317,7 +352,9 @@ Fary_aset(ary, args)
int beg, len;
beg = NUM2INT(arg1);
- Check_Type(arg3, T_ARRAY);
+ if (TYPE(arg3) != T_ARRAY) {
+ arg3 = (struct RArray*)rb_to_a(arg3);
+ }
if (beg < 0) {
beg = ary->len + beg;
if (beg < 0) {
@@ -330,7 +367,7 @@ Fary_aset(ary, args)
ary->capa=len;
REALLOC_N(ary->ptr, VALUE, ary->capa);
}
- bzero(ary->ptr+ary->len, sizeof(VALUE)*(beg-ary->len));
+ memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(beg-ary->len));
memcpy(ary->ptr+beg, arg3->ptr, sizeof(VALUE)*arg3->len);
ary->len = len;
}
@@ -371,7 +408,7 @@ Fary_aset(ary, args)
ary->capa=len;
REALLOC_N(ary->ptr, VALUE, ary->capa);
}
- bzero(ary->ptr+ary->len, sizeof(VALUE)*(beg-ary->len));
+ memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(beg-ary->len));
memcpy(ary->ptr+beg, RARRAY(arg2)->ptr,
sizeof(VALUE)*RARRAY(arg2)->len);
ary->len = len;
@@ -500,6 +537,24 @@ Fary_to_s(ary)
}
static VALUE
+Fary_print_on(ary, port)
+ struct RArray *ary;
+ VALUE port;
+{
+ int i;
+
+ for (i=0; i<ary->len; i++) {
+ if (OFS && i>1) {
+ Fio_write(port, OFS);
+ }
+ Fio_write(port, ary->ptr[i]);
+ }
+ return port;
+}
+
+#define INSPECT_MAX 10
+
+static VALUE
Fary_inspect(ary)
struct RArray *ary;
{
@@ -511,6 +566,7 @@ Fary_inspect(ary)
len = ary->len;
for (i=0; i<len; i++) {
+ if (i > INSPECT_MAX) break;
ary->ptr[i] = rb_funcall(ary->ptr[i], rb_intern("_inspect"), 0, Qnil);
}
@@ -518,11 +574,18 @@ Fary_inspect(ary)
str = ary_join(ary, str);
if (str == Qnil) return str_new2("[]");
len = RSTRING(str)->len;
- str_grow(str, len+2);
+ if (ary->len > INSPECT_MAX)
+ str_grow(str, len+5);
+ else
+ str_grow(str, len+2);
+
p = RSTRING(str)->ptr;
memmove(p+1, p, len);
p[0] = '[';
- p[len+1] = ']';
+ if (ary->len > INSPECT_MAX)
+ strcpy(p+len, "...]");
+ else
+ p[len+1] = ']';
return str;
}
@@ -534,6 +597,18 @@ Fary_to_a(ary)
return ary;
}
+VALUE
+rb_to_a(obj)
+ VALUE obj;
+{
+ if (TYPE(obj) == T_ARRAY) return obj;
+ obj = rb_funcall(obj, rb_intern("to_a"), 0);
+ if (TYPE(obj) != T_ARRAY) {
+ Bug("`to_a' did not return Array");
+ }
+ return obj;
+}
+
static VALUE
Fary_reverse(ary)
struct RArray *ary;
@@ -653,7 +728,7 @@ Fary_fill(ary, args)
REALLOC_N(ary->ptr, VALUE, ary->capa);
}
if (beg > ary->len) {
- bzero(ary->ptr+ary->len, sizeof(VALUE)*(end-ary->len));
+ memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(end-ary->len));
}
ary->len = end;
}
@@ -755,6 +830,21 @@ Fary_equal(ary1, ary2)
return TRUE;
}
+static VALUE
+Fary_hash(ary)
+ struct RArray *ary;
+{
+ int i, h;
+ ID hash = rb_intern("hash");
+
+ h = 0;
+ for (i=0; i<ary->len; i++) {
+ h += rb_funcall(ary->ptr[i], hash, 0);
+ }
+ h += ary->len;
+ return INT2FIX(h);
+}
+
extern VALUE C_Kernel;
extern VALUE M_Enumerable;
@@ -768,7 +858,10 @@ 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, "print_on", Fary_print_on, 1);
+
rb_define_method(C_Array, "==", Fary_equal, 1);
+ rb_define_method(C_Array, "hash", Fary_hash, 0);
rb_define_method(C_Array, "[]", Fary_aref, -2);
rb_define_method(C_Array, "[]=", Fary_aset, -2);
rb_define_method(C_Array, "<<", Fary_append, 1);
@@ -778,6 +871,9 @@ Init_Array()
rb_define_method(C_Array, "unshift", Fary_unshift, 1);
rb_define_method(C_Array, "each", Fary_each, 0);
rb_define_method(C_Array, "length", Fary_length, 0);
+ rb_define_alias(C_Array, "size", "length");
+ rb_define_method(C_Array, "index", Fary_index, 1);
+ rb_define_method(C_Array, "indexes", Fary_indexes, -2);
rb_define_method(C_Array, "clone", Fary_clone, 0);
rb_define_method(C_Array, "join", Fary_join, -2);
rb_define_method(C_Array, "reverse", Fary_reverse, 0);
diff --git a/bignum.c b/bignum.c
index c14924205b..623a6a8928 100644
--- a/bignum.c
+++ b/bignum.c
@@ -3,7 +3,7 @@
bignum.c -
$Author: matz $
- $Date: 1994/06/27 15:48:21 $
+ $Date: 1994/08/12 04:47:06 $
created at: Fri Jun 10 00:48:55 JST 1994
************************************************/
@@ -58,7 +58,7 @@ Fbig_clone(x)
{
VALUE z = bignew_1(CLASS_OF(x), x->len, x->sign);
- bcopy(BDIGITS(x), BDIGITS(z), x->len*sizeof(USHORT));
+ memcpy(BDIGITS(z), BDIGITS(x), x->len*sizeof(USHORT));
return (VALUE)z;
}
diff --git a/class.c b/class.c
index 867a2ac039..ddadfbf793 100644
--- a/class.c
+++ b/class.c
@@ -3,7 +3,7 @@
class.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 11:06:35 $
created at: Tue Aug 10 15:05:44 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -131,6 +131,12 @@ include_class_new(module, super)
cls->m_tbl = module->m_tbl;
cls->c_tbl = module->c_tbl;
cls->super = super;
+ if (TYPE(module) == T_ICLASS) {
+ RBASIC(cls)->class = RBASIC(module)->class;
+ }
+ else {
+ RBASIC(cls)->class = (VALUE)module;
+ }
return cls;
}
@@ -243,17 +249,6 @@ rb_define_single_method(obj, name, func, argc)
}
void
-rb_define_mfunc(class, name, func, argc)
- struct RClass *class;
- char *name;
- VALUE (*func)();
- int argc;
-{
- rb_define_method(class, name, func, argc);
- rb_define_single_method(class, name, func, argc);
-}
-
-void
rb_define_alias(class, name1, name2)
struct RClass *class;
char *name1, *name2;
@@ -276,11 +271,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) == Qnil) {
- rb_add_method(class, attr, NEW_IVAR(attriv), TRUE);
+ if (rb_method_boundp(class, attr) == Qnil) {
+ rb_add_method(class, attr, NEW_IVAR(attriv), FALSE);
}
- if (pub && rb_get_method_body(class, attreq, 0) == Qnil) {
- rb_add_method(class, attreq, NEW_ATTRSET(attriv), TRUE);
+ if (pub && rb_method_boundp(class, attreq) == Qnil) {
+ rb_add_method(class, attreq, NEW_ATTRSET(attriv), FALSE);
}
}
@@ -309,6 +304,7 @@ rb_scan_args(args, fmt, va_alist)
if (NIL_P(args)) {
len = 0;
+ args = ary_new();
}
else {
Check_Type(args, T_ARRAY);
diff --git a/compar.c b/compar.c
index 84b2583ce5..f2d773eb3d 100644
--- a/compar.c
+++ b/compar.c
@@ -3,7 +3,7 @@
compar.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 04:47:09 $
created at: Thu Aug 26 14:39:48 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -17,10 +17,10 @@ VALUE M_Comparable;
static ID cmp;
static VALUE
-Fcmp_eq(this, other)
- VALUE this, other;
+Fcmp_eq(x, y)
+ VALUE x, y;
{
- VALUE c = rb_funcall(this, cmp, 1, other);
+ VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
if (t == 0) return TRUE;
@@ -28,58 +28,58 @@ Fcmp_eq(this, other)
}
static VALUE
-Fcmp_gt(this, other)
- VALUE this, other;
+Fcmp_gt(x, y)
+ VALUE x, y;
{
- VALUE c = rb_funcall(this, cmp, 1, other);
+ VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t > 0) return other;
+ if (t > 0) return y;
return FALSE;
}
static VALUE
-Fcmp_ge(this, other)
- VALUE this, other;
+Fcmp_ge(x, y)
+ VALUE x, y;
{
- VALUE c = rb_funcall(this, cmp, 1, other);
+ VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t >= 0) return other;
+ if (t >= 0) return y;
return FALSE;
}
static VALUE
-Fcmp_lt(this, other)
- VALUE this, other;
+Fcmp_lt(x, y)
+ VALUE x, y;
{
- VALUE c = rb_funcall(this, cmp, 1, other);
+ VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t < 0) return other;
+ if (t < 0) return y;
return FALSE;
}
static VALUE
-Fcmp_le(this, other)
- VALUE this, other;
+Fcmp_le(x, y)
+ VALUE x, y;
{
- VALUE c = rb_funcall(this, cmp, 1, other);
+ VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t <= 0) return other;
+ if (t <= 0) return y;
return FALSE;
}
static VALUE
-Fcmp_between(this, min, max)
- VALUE this, min, max;
+Fcmp_between(x, min, max)
+ VALUE x, min, max;
{
- VALUE c = rb_funcall(this, cmp, 1, min);
+ VALUE c = rb_funcall(x, cmp, 1, min);
int t = NUM2INT(c);
if (t < 0) return FALSE;
- c = rb_funcall(this, cmp, 1, min);
+ c = rb_funcall(x, cmp, 1, min);
t = NUM2INT(c);
if (t > 0) return FALSE;
return TRUE;
diff --git a/configure.in b/configure.in
index 041018e0d2..bd841c434c 100644
--- a/configure.in
+++ b/configure.in
@@ -1,16 +1,15 @@
-
dnl Process this file with autoconf to produce a configure script.
AC_INIT(ruby.h)
PROGS="ruby"
AC_SUBST(PROGS)dnl
AC_PROG_CC
AC_GCC_TRADITIONAL
-if test $GCC -eq 1 ; then
+if test "$GCC" = 1 ; then
DBM=-fpcc-struct-return
fi
AC_SUBST(DBM)dnl
if test "$HOSTTYPE" = sparc; then
- if test $GCC -eq 1 ; then
+ if test "$GCC" = 1 ; then
STATIC=-static
else
STATIC=-Bstatic
@@ -27,7 +26,8 @@ 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 syscall)
+AC_HAVE_FUNCS(wait4 waitpid syscall getcwd)
+AC_HAVE_FUNCS(getpriority sigprocmask)
if echo $DEFS | grep "HAVE_SETENV" 2>&1 > /dev/null; then
:
else
@@ -38,13 +38,15 @@ if echo $DEFS | grep "HAVE_STRFTIME" 2>&1 > /dev/null; then
else
AC_TIMEZONE
AC_COMPILE_CHECK([daylight], [],
- [extern int daylight; int i; i = daylight;], AC_DEFINE(HAVE_DAYLIGHT))
+ [extern int daylight; int i = daylight;], AC_DEFINE(HAVE_DAYLIGHT))
fi
AC_ALLOCA
AC_WORDS_BIGENDIAN
AC_ST_BLKSIZE
AC_ST_BLOCKS
AC_ST_RDEV
+AC_COMPILE_CHECK([std stdio], [#include <stdio.h>],
+[stdin->_cnt > 0;], AC_DEFINE(STDSTDIO))
AC_COMPILE_CHECK([pw_change in struct passwd], [#include <pwd.h>],
[struct passwd pw; pw.pw_change;], AC_DEFINE(PW_CHANGE))
AC_COMPILE_CHECK([pw_quota in struct passwd], [#include <pwd.h>],
diff --git a/dbm.c b/dbm.c
index cee887e688..4640d487cf 100644
--- a/dbm.c
+++ b/dbm.c
@@ -3,7 +3,7 @@
dbm.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 11:06:37 $
created at: Mon Jan 24 15:59:52 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
@@ -15,10 +15,11 @@
#ifdef USE_DBM
#include <ndbm.h>
-#include <sys/file.h>
+#include <sys/fcntl.h>
#include <errno.h>
VALUE C_DBM;
+static ID id_dbm;
extern VALUE M_Enumerable;
@@ -30,7 +31,7 @@ closeddbm()
#define GetDBM(obj, dbmp) {\
DBM **_dbm;\
- Get_Data_Struct(obj, "dbm", DBM*, _dbm);\
+ Get_Data_Struct(obj, id_dbm, DBM*, _dbm);\
dbmp = *_dbm;\
if (dbmp == Qnil) closeddbm();\
}
@@ -44,7 +45,7 @@ free_dbm(dbmp)
#define MakeDBM(obj, dp) {\
DBM **_dbm;\
- Make_Data_Struct(obj,"dbm",DBM*,Qnil,free_dbm,_dbm);\
+ Make_Data_Struct(obj,id_dbm,DBM*,Qnil,free_dbm,_dbm);\
*_dbm=dp;\
}
@@ -93,7 +94,7 @@ Fdbm_close(obj)
{
DBM **dbmp;
- Get_Data_Struct(obj, "dbm", DBM*, dbmp);
+ Get_Data_Struct(obj, id_dbm, DBM*, dbmp);
if (*dbmp == Qnil) Fail("already closed DBM file");
dbm_close(*dbmp);
*dbmp = Qnil;
@@ -121,6 +122,29 @@ Fdbm_fetch(obj, keystr)
}
static VALUE
+Fdbm_indexes(obj, args)
+ VALUE obj;
+ struct RArray *args;
+{
+ VALUE *p, *pend;
+ struct RArray *new;
+ int i = 0;
+
+ if (!args || args->len == 1 && TYPE(args->ptr) != T_ARRAY) {
+ args = (struct RArray*)rb_to_a(args->ptr[0]);
+ }
+
+ new = (struct RArray*)ary_new2(args->len);
+
+ p = args->ptr; pend = p + args->len;
+ while (p < pend) {
+ new->ptr[i++] = Fdbm_fetch(obj, *p++);
+ new->len = i;
+ }
+ return (VALUE)new;
+}
+
+static VALUE
Fdbm_delete(obj, keystr)
VALUE obj, keystr;
{
@@ -133,7 +157,7 @@ Fdbm_delete(obj, keystr)
GetDBM(obj, dbm);
if (dbm_delete(dbm, key)) {
- Fail("DBM delete failed");
+ Fail("dbm_delete failed");
}
return obj;
}
@@ -153,7 +177,7 @@ Fdbm_delete_if(obj)
valstr = str_new(val.dptr, val.dsize);
if (rb_yield(assoc_new(keystr, valstr))
&& dbm_delete(dbm, key)) {
- Fail("DBM delete failed");
+ Fail("dbm_delete failed");
}
}
return obj;
@@ -169,7 +193,7 @@ Fdbm_clear(obj)
GetDBM(obj, dbm);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
if (dbm_delete(dbm, key)) {
- Fail("DBM delete failed");
+ Fail("dbm_delete failed");
}
}
return obj;
@@ -198,7 +222,7 @@ Fdbm_store(obj, keystr, valstr)
if (dbm_store(dbm, key, val, DBM_REPLACE)) {
dbm_clearerr(dbm);
if (errno == EPERM) rb_sys_fail(Qnil);
- Fail("DBM store failed");
+ Fail("dbm_store failed");
}
return valstr;
}
@@ -369,7 +393,9 @@ Init_DBM()
rb_define_method(C_DBM, "close", Fdbm_close, 0);
rb_define_method(C_DBM, "[]", Fdbm_fetch, 1);
rb_define_method(C_DBM, "[]=", Fdbm_store, 2);
+ rb_define_method(C_DBM, "indexes", Fdbm_indexes, -2);
rb_define_method(C_DBM, "length", Fdbm_length, 0);
+ rb_define_alias(C_DBM, "size", "length");
rb_define_method(C_DBM, "each", Fdbm_each, 0);
rb_define_method(C_DBM, "each_value", Fdbm_each, 0);
rb_define_method(C_DBM, "each_key", Fdbm_each_key, 0);
@@ -384,5 +410,7 @@ Init_DBM()
rb_define_method(C_DBM, "has_value", Fdbm_has_value, 1);
rb_define_method(C_DBM, "to_a", Fdbm_to_a, 0);
+
+ id_dbm = rb_intern("dbm");
}
#endif /* USE_DBM */
diff --git a/defines.h b/defines.h
index 2e917510c7..ed098386b4 100644
--- a/defines.h
+++ b/defines.h
@@ -3,7 +3,7 @@
defines.h -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 04:47:11 $
created at: Wed May 18 00:21:44 JST 1994
************************************************/
diff --git a/dict.c b/dict.c
index 016917e311..19df65bf0a 100644
--- a/dict.c
+++ b/dict.c
@@ -3,7 +3,7 @@
dict.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 04:47:13 $
created at: Mon Nov 22 18:51:18 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -74,6 +74,29 @@ Fdic_aref(dic, key)
}
static VALUE
+Fdic_indexes(dic, args)
+ struct RDict *dic;
+ struct RArray *args;
+{
+ VALUE *p, *pend;
+ struct RArray *new;
+ int i = 0;
+
+ if (!args || args->len == 1 && TYPE(args->ptr) != T_ARRAY) {
+ args = (struct RArray*)rb_to_a(args->ptr[0]);
+ }
+
+ new = (struct RArray*)ary_new2(args->len);
+
+ p = args->ptr; pend = p + args->len;
+ while (p < pend) {
+ new->ptr[i++] = Fdic_aref(dic, *p++);
+ }
+ new->len = i;
+ return (VALUE)new;
+}
+
+static VALUE
Fdic_delete(dic, key)
struct RDict *dic;
VALUE key;
@@ -140,7 +163,7 @@ Fdic_length(dic)
}
static
-dic_each(key, value)
+dic_each_value(key, value)
VALUE key, value;
{
rb_yield(value);
@@ -148,10 +171,10 @@ dic_each(key, value)
}
static VALUE
-Fdic_each(dic)
+Fdic_each_value(dic)
struct RDict *dic;
{
- st_foreach(dic->tbl, dic_each);
+ st_foreach(dic->tbl, dic_each_value);
return (VALUE)dic;
}
@@ -304,14 +327,12 @@ Fdic_has_key(dic, key)
return FALSE;
}
-static VALUE value_found;
-
static int
-dic_search_value(key, value, arg)
- VALUE key, value, arg;
+dic_search_value(key, value, data)
+ VALUE key, value, *data;
{
- if (rb_funcall(value, eq, 1, arg)) {
- value_found = TRUE;
+ if (rb_funcall(value, eq, 1, data[1])) {
+ data[0] = TRUE;
return ST_STOP;
}
return ST_CONTINUE;
@@ -322,9 +343,12 @@ Fdic_has_value(dic, val)
struct RDict *dic;
VALUE val;
{
- value_found = FALSE;
- st_foreach(dic->tbl, dic_search_value, val);
- return value_found;
+ VALUE data[2];
+
+ data[0] = FALSE;
+ data[1] = val;
+ st_foreach(dic->tbl, dic_search_value, data);
+ return data[0];
}
struct equal_data {
@@ -367,7 +391,27 @@ Fdic_equal(dic1, dic2)
return data.result;
}
-char *index();
+static int
+dic_hash(key, val, data)
+ VALUE key, val;
+ int *data;
+{
+ *data ^= rb_funcall(key, hash, 0);
+ *data ^= rb_funcall(val, hash, 0);
+ return ST_CONTINUE;
+}
+
+static VALUE
+Fdic_hash(dic)
+ struct RDict *dic;
+{
+ int h;
+
+ st_foreach(dic->tbl, dic_hash, &h);
+ return INT2FIX(h);
+}
+
+char *strchr();
extern VALUE rb_readonly_hook();
extern char **environ;
@@ -381,7 +425,7 @@ Fenv_each(dic)
env = environ;
while (*env) {
VALUE var, val;
- char *s = index(*env, '=');
+ char *s = strchr(*env, '=');
var = str_new(*env, s-*env);
val = str_new2(s+1);
@@ -500,11 +544,14 @@ Init_Dict()
rb_define_method(C_Dict,"_inspect", Fdic_inspect, 0);
rb_define_method(C_Dict,"==", Fdic_equal, 1);
+ rb_define_method(C_Dict,"hash", Fdic_hash, 0);
rb_define_method(C_Dict,"[]", Fdic_aref, 1);
rb_define_method(C_Dict,"[]=", Fdic_aset, 2);
+ rb_define_method(C_Dict,"indexes", Fdic_indexes, -2);
rb_define_method(C_Dict,"length", Fdic_length, 0);
- rb_define_method(C_Dict,"each", Fdic_each, 0);
- rb_define_method(C_Dict,"each_value", Fdic_each, 0);
+ rb_define_alias(C_Dict, "size", "length");
+ rb_define_method(C_Dict,"each", Fdic_each_pair, 0);
+ rb_define_method(C_Dict,"each_value", Fdic_each_value, 0);
rb_define_method(C_Dict,"each_key", Fdic_each_key, 0);
rb_define_method(C_Dict,"each_pair", Fdic_each_pair, 0);
diff --git a/dir.c b/dir.c
index 87c9bce69a..c621f85aed 100644
--- a/dir.c
+++ b/dir.c
@@ -3,7 +3,7 @@
dir.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 11:06:38 $
created at: Wed Jan 5 09:51:01 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
@@ -37,6 +37,7 @@
#endif /* not (DIRENT or _POSIX_VERSION) */
static VALUE C_Dir;
+static ID id_dir;
static void
free_dir(dir)
@@ -59,7 +60,7 @@ Fdir_open(dir_class, dirname)
if (dirp == NULL) Fail("Can't open directory %s", dirname->ptr);
obj = obj_alloc(dir_class);
- Make_Data_Struct(obj, "dir", DIR*, Qnil, free_dir, d);
+ Make_Data_Struct(obj, id_dir, DIR*, Qnil, free_dir, d);
*d = dirp;
return obj;
@@ -73,7 +74,7 @@ closeddir()
#define GetDIR(obj, dirp) {\
DIR **_dp;\
- Get_Data_Struct(obj, "dir", DIR*, _dp);\
+ Get_Data_Struct(obj, id_dir, DIR*, _dp);\
dirp = *_dp;\
if (dirp == NULL) closeddir();\
}
@@ -134,7 +135,7 @@ Fdir_close(dir)
{
DIR **dirpp;
- Get_Data_Struct(dir, "dir", DIR*, dirpp);
+ Get_Data_Struct(dir, id_dir, DIR*, dirpp);
if (*dirpp == NULL) Fail("already closed directory");
closedir(*dirpp);
*dirpp = NULL;
@@ -166,7 +167,7 @@ Fdir_chdir(obj, args)
if (chdir(dist) < 0)
rb_sys_fail(Qnil);
- return Qnil;
+ return INT2FIX(0);
}
static VALUE
@@ -176,7 +177,11 @@ Fdir_getwd(dir)
extern char *getwd();
char path[MAXPATHLEN];
+#ifdef HAVE_GETCWD
+ if (getcwd(path, sizeof(path)) == 0) Fail(path);
+#else
if (getwd(path) == 0) Fail(path);
+#endif
return str_new2(path);
}
@@ -190,7 +195,7 @@ Fdir_chroot(dir, path)
if (chroot(RSTRING(path)->ptr) == -1)
rb_sys_fail(Qnil);
- return Qnil;
+ return INT2FIX(0);
}
static VALUE
@@ -211,7 +216,7 @@ Fdir_mkdir(obj, args)
if (mkdir(RSTRING(path)->ptr, mode) == -1)
rb_sys_fail(RSTRING(path)->ptr);
- return Qnil;
+ return INT2FIX(0);
}
static VALUE
@@ -251,4 +256,6 @@ Init_Dir()
rb_define_single_method(C_Dir,"rmdir", Fdir_rmdir, 1);
rb_define_single_method(C_Dir,"delete", Fdir_rmdir, 1);
rb_define_single_method(C_Dir,"unlink", Fdir_rmdir, 1);
+
+ id_dir = rb_intern("dir");
}
diff --git a/dln.c b/dln.c
index 766297e2ae..6df511c2e0 100644
--- a/dln.c
+++ b/dln.c
@@ -3,7 +3,7 @@
dln.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 04:47:16 $
created at: Tue Jan 18 17:05:06 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
@@ -32,7 +32,7 @@ static int dln_init_p = 0;
static char fbuf[MAXPATHLEN];
static char *dln_find_1();
char *getenv();
-char *index();
+char *strchr();
int strcmp();
char *
@@ -74,7 +74,7 @@ dln_find_1(fname, path, exe_flag)
int fspace;
/* extract a component */
- ep = index(dp, ':');
+ ep = strchr(dp, ':');
if (ep == NULL)
ep = dp+strlen(dp);
@@ -420,18 +420,18 @@ dln_load_text_data(fd, hdrp, bss, disp)
}
if (bss == -1) {
- bzero(addr + hdrp->a_text + hdrp->a_data, hdrp->a_bss);
+ memset(addr + hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss);
}
else if (bss > 0) {
- bzero(addr + hdrp->a_text + hdrp->a_data, bss );
+ memset(addr + hdrp->a_text + hdrp->a_data, 0, bss);
}
return (long)addr;
}
static int
-undef_print(key, value, arg)
- char *key;
+undef_print(key, value)
+ char *key, *value;
{
fprintf(stderr, " %s\n", key);
return ST_CONTINUE;
diff --git a/dln.h b/dln.h
index 0589954e73..e2370e1aa1 100644
--- a/dln.h
+++ b/dln.h
@@ -3,8 +3,8 @@
dln.h -
$Author: matz $
- $Revision: 1.1.1.1 $
- $Date: 1994/06/17 14:23:49 $
+ $Revision: 1.2 $
+ $Date: 1994/08/12 04:47:17 $
created at: Wed Jan 19 16:53:09 JST 1994
************************************************/
diff --git a/enum.c b/enum.c
index 38feb29aa4..1a52a20c67 100644
--- a/enum.c
+++ b/enum.c
@@ -3,7 +3,7 @@
enum.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 04:47:18 $
created at: Fri Oct 1 15:15:19 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
diff --git a/env.h b/env.h
index 09ff31d13f..66a873db6f 100644
--- a/env.h
+++ b/env.h
@@ -2,9 +2,9 @@
env.h -
- $Author$
- $Revision$
- $Date$
+ $Author: matz $
+ $Revision: 1.3 $
+ $Date: 1994/08/12 11:06:39 $
created at: Mon Jul 11 11:53:03 JST 1994
************************************************/
@@ -17,8 +17,10 @@ extern struct ENVIRON {
VALUE *argv;
struct RClass *current_module;
struct RClass *last_class;
+#ifdef USE_CALLER
char *file;
int line;
+#endif
ID last_func;
ID *local_tbl;
VALUE *local_vars;
@@ -29,12 +31,15 @@ extern struct ENVIRON {
struct ENVIRON *prev;
} *the_env;
-#define ITERATOR_P() (the_env->iterator > 0 && the_env->iterator < 3)
+#define ITERATOR_P() (the_env->iterator == 1 || the_env->iterator == 2)
+
+#undef Qself
#define Qself the_env->self
#define the_class the_env->current_module
#define DURING_ITERATE 1
#define DURING_RESQUE 2
#define DURING_CALL 4
+#define VARS_MALLOCED 8
#endif /* ENV_H */
diff --git a/error.c b/error.c
index d76922b919..1596f57f41 100644
--- a/error.c
+++ b/error.c
@@ -3,7 +3,7 @@
error.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/12 04:47:21 $
created at: Mon Aug 9 16:11:34 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -53,9 +53,16 @@ err_print(fmt, args)
}
}
+void
yyerror(msg)
char *msg;
{
+ static char *f;
+ static int line;
+
+ if (line == sourceline && strcmp(f, sourcefile) == 0)
+ return;
+ f = sourcefile; line = sourceline;
Error("%s", msg);
}
diff --git a/etc.c b/etc.c
index eb7e225ebb..7c88a640c8 100644
--- a/etc.c
+++ b/etc.c
@@ -3,7 +3,7 @@
etc.c -
$Author: matz $
- $Date: 1994/06/17 14:23:49 $
+ $Date: 1994/08/24 09:25:27 $
created at: Tue Mar 22 18:39:19 JST 1994
************************************************/
@@ -21,7 +21,7 @@ Fetc_getlogin(obj)
char *login = getlogin();
if (login)
- return str_new2(getlogin());
+ return str_new2(login);
return Qnil;
}
@@ -178,13 +178,15 @@ Init_Etc()
{
M_Etc = rb_define_module("Etc");
- rb_define_mfunc(M_Etc, "getlogin", Fetc_getlogin, 0);
+ rb_define_method(M_Etc, "getlogin", Fetc_getlogin, 0);
- rb_define_mfunc(M_Etc, "getpwuid", Fetc_getpwuid, -2);
- rb_define_mfunc(M_Etc, "getpwnam", Fetc_getpwnam, 1);
- rb_define_mfunc(M_Etc, "passwd", Fetc_passwd, 0);
+ rb_define_method(M_Etc, "getpwuid", Fetc_getpwuid, -2);
+ rb_define_method(M_Etc, "getpwnam", Fetc_getpwnam, 1);
+ rb_define_method(M_Etc, "passwd", Fetc_passwd, 0);
- rb_define_mfunc(M_Etc, "getgrgid", Fetc_getgrgid, 1);
- rb_define_mfunc(M_Etc, "getgrnam", Fetc_getgrnam, 1);
- rb_define_mfunc(M_Etc, "group", Fetc_group, 0);
+ rb_define_method(M_Etc, "getgrgid", Fetc_getgrgid, 1);
+ rb_define_method(M_Etc, "getgrnam", Fetc_getgrnam, 1);
+ rb_define_method(M_Etc, "group", Fetc_group, 0);
+
+ rb_include_module(CLASS_OF(M_Etc), M_Etc);
}
diff --git a/eval.c b/eval.c
index 7a69a22a75..4a7241e7f7 100644
--- a/eval.c
+++ b/eval.c
@@ -3,7 +3,7 @@
eval.c -
$Author: matz $
- $Date: 1994/06/27 15:48:23 $
+ $Date: 1994/08/24 09:25:28 $
created at: Thu Jun 10 14:22:17 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -11,23 +11,183 @@
************************************************/
#include "ruby.h"
+#include "ident.h"
#include "env.h"
#include "node.h"
-#include "ident.h"
+#include "methods.h"
+
#include <stdio.h>
#include <setjmp.h>
#include "st.h"
+void method_free();
+void rb_clear_cache();
+
+/* #define TEST /* prints cache miss */
+#ifdef TEST
+#include <stdio.h>
+#endif
+
+#if 1
+#define CACHE_SIZE 0x200
+#define CACHE_MASK 0x1ff
+#define EXPR1(c,m) ((((int)(c)>>3)^(m))&CACHE_MASK)
+
+#else
+
+#define CACHE_SIZE 577
+#define EXPR1(c,m) (((int)(c)^(m))%CACHE_SIZE)
+#endif
+
+struct cache_entry { /* method hash table. */
+ ID mid; /* method's id */
+ struct RClass *class; /* receiver's class */
+ struct RClass *origin; /* where method defined */
+ struct SMethod *method;
+ int undef;
+};
+
+static struct cache_entry cache[CACHE_SIZE];
+
+static struct SMethod*
+search_method(class, id, origin)
+ struct RClass *class, **origin;
+ ID id;
+{
+ struct SMethod *body;
+ NODE *list;
+
+ while (!st_lookup(class->m_tbl, id, &body)) {
+ class = class->super;
+ if (class == Qnil) return Qnil;
+ }
+
+ if (body->origin)
+ *origin = body->origin;
+ else
+ *origin = class;
+ return body;
+}
+
+static NODE*
+rb_get_method_body(classp, idp)
+ struct RClass **classp;
+ ID *idp;
+{
+ int pos, i;
+ ID id = *idp;
+ struct RClass *class = *classp;
+ struct SMethod *method;
+ struct SMethod *body;
+ struct RClass *origin;
+ struct cache_entry *ent;
+
+ if ((body = search_method(class, id, &origin)) == Qnil) {
+ return Qnil;
+ }
+
+ ent = cache + EXPR1(class, id);
+#ifdef TEST
+ if (ent->mid != 0) {
+ fprintf(stderr, "0x%x 0x%x %x\n", class, id, EXPR1(class, id));
+ }
+#endif
+ /* store in cache */
+ ent->mid = id;
+ ent->class = class;
+ ent->origin = origin;
+ ent->method = body;
+ ent->undef = body->undef;
+
+ if (ent->undef) return Qnil;
+ *idp = ent->method->id;
+ *classp = ent->origin;
+ return ent->method->node;
+}
+
+VALUE
+rb_method_boundp(class, id)
+ struct RClass *class;
+ ID id;
+{
+ if (rb_get_method_body(&class, &id))
+ return TRUE;
+ return FALSE;
+}
+
+void
+rb_alias(class, name, def)
+ struct RClass *class;
+ ID name, def;
+{
+ struct SMethod *body;
+
+ if (st_lookup(class->m_tbl, name, &body)) {
+ if (verbose) {
+ Warning("redefine %s", rb_id2name(name));
+ }
+ 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 SMethod *body;
+{
+ struct cache_entry *ent, *end;
+
+ ent = cache; end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->method == body) {
+ ent->class = Qnil;
+ ent->mid = Qnil;
+ }
+ ent++;
+ }
+}
+
+void
+rb_clear_cache2(class)
+ struct RClass *class;
+{
+ struct cache_entry *ent, *end;
+
+ ent = cache; end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->origin == class) {
+ ent->class = Qnil;
+ ent->mid = Qnil;
+ }
+ ent++;
+ }
+}
+
+void
+method_free(body)
+ struct SMethod *body;
+{
+ body->count--;
+ if (body->count == 0) {
+ freenode(body->node);
+ free(body);
+ }
+}
+
static ID match, each;
VALUE errstr, errat;
extern NODE *eval_tree;
+extern int nerrs;
extern VALUE TopSelf;
struct ENVIRON *the_env, *top_env;
#define PUSH_ENV() {\
struct ENVIRON _this;\
- if (the_env) _this = *the_env; else bzero(&_this, sizeof(_this));\
+ _this = *the_env;\
_this.prev = the_env;\
_this.flags = 0;\
the_env = &_this;\
@@ -51,6 +211,8 @@ static struct tag {
jmp_buf buf;
struct gc_list *gclist;
struct ENVIRON *env;
+ VALUE self;
+ int ilevel;
} *prot_tag;
#define PUSH_TAG() {\
@@ -59,6 +221,8 @@ static struct tag {
&_oldtag;\
_this.level= ++tag_level;\
_this.env= the_env;\
+ _this.self= Qself;\
+ _this.ilevel= the_env->iterator;\
prot_tag = &_this;\
#define POP_TAG() \
@@ -69,6 +233,8 @@ static struct tag {
#define EXEC_TAG() (setjmp(prot_tag->buf))
#define JUMP_TAG(val) {\
the_env = prot_tag->env;\
+ the_env->iterator = prot_tag->ilevel;\
+ Qself = prot_tag->self;\
longjmp(prot_tag->buf,(val));\
}
@@ -85,11 +251,12 @@ static struct tag {
static VALUE rb_eval();
VALUE Feval();
-VALUE Argv;
static VALUE rb_call();
VALUE rb_apply();
VALUE rb_xstring();
+void rb_fail();
+static VALUE masign();
static void asign();
static VALUE last_val;
@@ -99,6 +266,12 @@ extern VALUE rb_stderr;
extern int sourceline;
extern char *sourcefile;
+VALUE
+rb_self()
+{
+ return Qself;
+}
+
static ID last_func;
static void
error_print()
@@ -123,71 +296,36 @@ error_print()
exit(1);
}
-static int origargc;
-static char **origargv;
-
-main(argc, argv)
+void
+ruby_init(argc, argv, envp)
int argc;
- char *argv[];
+ char **argv, **envp;
{
int state;
+ static struct ENVIRON top_env;
+ the_env = &top_env;
- origargc = argc; origargv = argv;
- Init_stack();
- PUSH_ENV();
- top_env = the_env;
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
- rb_main(argc, argv);
+ ruby_init0(argc, argv, envp);
}
POP_TAG();
-
- switch (state) {
- case 0:
- break;
- case TAG_RETURN:
- Fatal("unexpected return");
- break;
- case TAG_CONTINUE:
- Fatal("unexpected continue");
- break;
- case TAG_BREAK:
- Fatal("unexpected break");
- break;
- case TAG_REDO:
- Fatal("unexpected redo");
- break;
- case TAG_RETRY:
- Fatal("retry outside of protect clause");
- break;
- case TAG_FAIL:
- PUSH_TAG()
+ if (state) {
+ PUSH_TAG();
error_print();
POP_TAG();
- break;
- case TAG_EXIT:
- rb_trap_exit();
- exit(FIX2UINT(last_val));
- break;
- default:
- Bug("Unknown longjmp status %d", state);
- break;
}
- POP_ENV();
- exit(0);
}
VALUE rb_readonly_hook();
-static VALUE Progname;
-
static VALUE
Eval(toplevel)
int toplevel;
{
VALUE result;
NODE *tree;
- int state;
+ int state;
if (match == Qnil) match = rb_intern("=~");
if (each == Qnil) each = rb_intern("each");
@@ -199,79 +337,72 @@ Eval(toplevel)
result = rb_eval(tree);
}
POP_TAG();
+/* #define PURIFY_D /* define when purify'ing */
+#ifdef PURIFY_D
+ freenode(tree);
+#else
/* you don't have to free at toplevel */
if (!toplevel) freenode(tree);
+#endif
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 val;
-}
-
-VALUE
-TopLevel(script, argc, argv)
- char *script;
- int argc;
- char **argv;
+ruby_run()
{
- int i;
+ int state;
- the_class = (struct RClass*)C_Object;
+ if (nerrs > 0) exit(nerrs);
+ Init_stack();
rb_define_variable("$!", &errstr, Qnil, Qnil);
errat = Qnil; /* clear for execution */
- Progname = str_new2(script);
- rb_define_variable("$0", &Progname, Qnil, set_arg0);
+ PUSH_ENV();
+ top_env = the_env;
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ int i;
- rb_define_variable("$ARGV", &Argv, Qnil, Qnil);
- rb_define_variable("$*", &Argv, Qnil, Qnil);
- Argv = ary_new2(argc);
- for (i=0; i < argc; i++) {
- Fary_push(Argv, str_new2(argv[i]));
+ the_class = (struct RClass*)C_Object;
+ Eval(1);
}
-#define PURIFY_D
-#ifdef PURIFY_D
- return Eval(0);
-#else
- return Eval(1);
-#endif
+ POP_TAG();
+
+ switch (state) {
+ case 0:
+ break;
+ case TAG_RETURN:
+ Fatal("unexpected return");
+ break;
+ case TAG_CONTINUE:
+ Fatal("unexpected continue");
+ break;
+ case TAG_BREAK:
+ Fatal("unexpected break");
+ break;
+ case TAG_REDO:
+ Fatal("unexpected redo");
+ break;
+ case TAG_RETRY:
+ Fatal("retry outside of protect clause");
+ break;
+ case TAG_FAIL:
+ PUSH_TAG();
+ error_print();
+ POP_TAG();
+ break;
+ case TAG_EXIT:
+ rb_trap_exit();
+ exit(FIX2UINT(last_val));
+ break;
+ default:
+ Bug("Unknown longjmp status %d", state);
+ break;
+ }
+ POP_ENV();
+ exit(0);
}
void
@@ -289,61 +420,38 @@ rb_trap_eval(cmd)
POP_ENV();
}
-static int
-setup_arg_1(node, args)
- NODE *node;
- VALUE *args;
-{
- int argc;
-
- if (node->type == NODE_ARRAY) {
- for (argc=0; node; node=node->nd_next) argc++;
- argc++;
- }
- else {
- *args = rb_eval(node);
- if (TYPE(*args) != T_ARRAY)
- Fail("*`argument' must be array");
- argc = RARRAY(*args)->len + 1;
- }
- return argc;
-}
-
-static void
-setup_arg_2(node, args, argc, argv)
- NODE *node;
- VALUE args;
- int argc;
- VALUE *argv;
-{
- int i;
-
- bzero(argv, sizeof(VALUE)*argc);
- if (node->type == NODE_ARRAY) {
- for (i=1;node;node=node->nd_next) {
- argv[i++] = rb_eval(node->nd_head);
- }
- }
- else {
- for (i=1;i<argc;i++) {
- argv[i] = RARRAY(args)->ptr[i-1];
- }
- }
-}
-
#define SETUP_ARGS {\
- VALUE args = Qnil;\
- argc = setup_arg_1(node->nd_args, &args);\
- argv = (VALUE*)alloca(sizeof(VALUE)*argc);\
- setup_arg_2(node->nd_args, args, argc, argv);\
+ NODE *n = node->nd_args;\
+ if (!n) {\
+ argc = 0;\
+ argv = Qnil;\
+ }\
+ else if (n->type == NODE_ARRAY) {\
+ int i;\
+ for (argc=0; n; n=n->nd_next) argc++;\
+ if (argc > 0) {\
+ n = node->nd_args;\
+ argv = (VALUE*)alloca(sizeof(VALUE)*argc);\
+ for (i=0;n;n=n->nd_next) {\
+ argv[i++] = rb_eval(n->nd_head);\
+ }\
+ }\
+ }\
+ else {\
+ args = rb_eval(n);\
+ if (TYPE(args) != T_ARRAY)\
+ args = rb_to_a(args);\
+ argc = RARRAY(args)->len;\
+ argv = RARRAY(args)->ptr;\
+ }\
}
static VALUE
rb_eval(node)
register NODE *node;
{
- int state;
- int go_out = 0;
+ int state;
+ int go_out = 0;
VALUE result;
&go_out;
@@ -388,34 +496,6 @@ rb_eval(node)
if (node) goto again;
return Qnil;
- case NODE_UNLESS:
- {
- VALUE res;
-
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- res = rb_eval(node->nd_cond);
- }
- POP_TAG();
- if (state == 0)
- ;
- else if (state == TAG_FAIL) {
- res = Qnil;
- }
- else {
- JUMP_TAG(state);
- }
-
- if (res == Qnil) {
- node = node->nd_body;
- }
- else {
- node = node->nd_else;
- }
- if (node) goto again;
- return res;
- }
-
case NODE_CASE:
{
VALUE val;
@@ -441,6 +521,29 @@ rb_eval(node)
}
return Qnil;
+ case NODE_EXNOT:
+ {
+ VALUE res;
+
+ PUSH_TAG();
+ switch (state = EXEC_TAG()) {
+ case 0:
+ res = rb_eval(node->nd_cond);
+ break;
+
+ case TAG_FAIL:
+ res = Qnil;
+ break;
+
+ default:
+ go_out++;
+ }
+ POP_TAG();
+ if (go_out) JUMP_TAG(state);
+ if (res) return FALSE;
+ return TRUE;
+ }
+
case NODE_WHILE:
PUSH_TAG();
switch (state = EXEC_TAG()) {
@@ -465,47 +568,29 @@ rb_eval(node)
if (go_out) JUMP_TAG(state);
return Qnil;
- case NODE_UNTIL:
- for (;;) {
- VALUE res;
-
- PUSH_TAG();
- switch (state = EXEC_TAG()) {
- case 0:
- res = rb_eval(node->nd_cond);
- break;
-
- case TAG_FAIL:
- res = Qnil;
- break;
-
- default:
- go_out++;
- }
- POP_TAG();
- if (go_out) JUMP_TAG(state);
- if (res) return res;
-
- PUSH_TAG();
- switch (state = EXEC_TAG()) {
- case 0:
- until_redo:
+ case NODE_WHILE2:
+ PUSH_TAG();
+ switch (state = EXEC_TAG()) {
+ case 0:
+ while2_cont:
+ do {
+ while2_redo:
rb_eval(node->nd_body);
- break;
- case TAG_REDO:
- goto until_redo;
- case TAG_CONTINUE:
- break;
- case TAG_BREAK:
- goto until_break;
- default:
- go_out++;
- }
- POP_TAG();
- if (go_out) JUMP_TAG(state);
+ } while (rb_eval(node->nd_cond));
+ break;
+ case TAG_REDO:
+ goto while2_redo;
+ case TAG_CONTINUE:
+ goto while2_cont;
+ default:
+ go_out++;
+ case TAG_BREAK:
+ break;
}
- until_break:
- break;
+ while2_out:
+ POP_TAG();
+ if (go_out) JUMP_TAG(state);
+ return Qnil;
case NODE_DO:
case NODE_FOR:
@@ -520,14 +605,14 @@ rb_eval(node)
if (state == 0) {
if (node->type == NODE_DO) {
the_env->iterator = 1;
- rb_eval(node->nd_iter);
+ result = rb_eval(node->nd_iter);
}
else {
VALUE recv;
recv = rb_eval(node->nd_iter);
the_env->iterator = 1;
- result = rb_call(CLASS_OF(recv), recv, each, 1, Qnil, 0);
+ result = rb_call(CLASS_OF(recv), recv, each, 0, Qnil);
}
}
POP_TAG();
@@ -552,6 +637,14 @@ rb_eval(node)
}
return result;
+ case NODE_FAIL:
+ {
+ VALUE mesg = rb_eval(node->nd_stts);
+ if (mesg) Check_Type(mesg, T_STRING);
+ rb_fail(mesg);
+ return Qnil; /* not reached */
+ }
+
case NODE_YIELD:
{
VALUE val;
@@ -634,6 +727,10 @@ rb_eval(node)
JUMP_TAG(TAG_CONTINUE);
break;
+ case NODE_REDO:
+ JUMP_TAG(TAG_REDO);
+ break;
+
case NODE_RETRY:
JUMP_TAG(TAG_RETRY);
break;
@@ -648,17 +745,12 @@ rb_eval(node)
{
VALUE recv, *argv;
int argc, last_iter;
+ VALUE args = Qnil; /* used in SETUP_ARGS */
last_iter = the_env->iterator;
the_env->iterator = 0; /* recv & args are not iter. */
recv = node->nd_recv?rb_eval(node->nd_recv):Qself;
- if (node->nd_args) {
- SETUP_ARGS;
- }
- else {
- argc = 1;
- argv = &recv;
- }
+ SETUP_ARGS;
the_env->iterator = last_iter; /* restore iter. level */
return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv);
@@ -671,20 +763,17 @@ rb_eval(node)
int last_iter;
int i, argc;
VALUE *argv;
+ VALUE args = Qnil; /* used in SETUP_ARGS */
last_iter = the_env->iterator; /* recv & args are not iter. */
the_env->iterator = 0;
- if (node->nd_args) {
- SETUP_ARGS;
- }
- else if (node->type == NODE_ZSUPER) {
+ if (node->type == NODE_ZSUPER) {
argc = the_env->argc;
argv = the_env->argv;
}
else {
- argc = 1;
- argv = Qnil;
+ SETUP_ARGS;
}
/* restore iter. level */
@@ -707,23 +796,23 @@ rb_eval(node)
{
VALUE result;
- PUSH_ENV();
PUSH_TAG();
if (node->nd_cnt > 0) {
- the_env->local_vars = ALLOC_N(VALUE, node->nd_cnt);
- bzero(the_env->local_vars, sizeof(VALUE)*node->nd_cnt);
+ the_env->local_vars = alloca(sizeof(VALUE)*node->nd_cnt);
+ memset(the_env->local_vars, 0, sizeof(VALUE)*node->nd_cnt);
the_env->local_tbl = node->nd_tbl;
}
else {
the_env->local_vars = Qnil;
- the_env->local_tbl = Qnil;
+ the_env->local_tbl = Qnil;
}
if ((state = EXEC_TAG()) == 0) {
result = rb_eval(node->nd_body);
}
POP_TAG();
- if (the_env->local_vars) free(the_env->local_vars);
- POP_ENV();
+ if (the_env->local_vars && (the_env->flags&VARS_MALLOCED))
+ free(the_env->local_vars);
+ the_env->local_vars = Qnil;
if (state != 0) JUMP_TAG(state);
return result;
@@ -732,25 +821,7 @@ rb_eval(node)
case NODE_MASGN:
{
VALUE val = rb_eval(node->nd_value);
- NODE *list = node->nd_head;
- int i, len;
-
- if (TYPE(val) != T_ARRAY) {
- val = rb_funcall(val, rb_intern("to_a"), 0, Qnil);
- if (TYPE(val) != T_ARRAY) {
- Bug("to_a did not return Array");
- }
- }
- len = RARRAY(val)->len;
- for (i=0; list && i<len; i++) {
- asign(list->nd_head, RARRAY(val)->ptr[i]);
- list = list->nd_next;
- }
- while (list) {
- asign(list->nd_head, Qnil);
- list = list->nd_next;
- }
- return val;
+ return masign(node, val);
}
case NODE_LASGN:
@@ -856,6 +927,7 @@ rb_eval(node)
case NODE_STR2:
case NODE_XSTR2:
case NODE_DREGX:
+ case NODE_DGLOB:
{
VALUE str, str2;
NODE *list = node->nd_next;
@@ -877,9 +949,12 @@ rb_eval(node)
if (node->type == NODE_DREGX) {
return regexp_new(RSTRING(str)->ptr, RSTRING(str)->len);
}
- else if (node->type == NODE_XSTR2) {
+ if (node->type == NODE_XSTR2) {
return rb_xstring(str);
}
+ if (node->type == NODE_DGLOB) {
+ return glob_new(str);
+ }
return str;
}
@@ -890,9 +965,9 @@ rb_eval(node)
return node->nd_lit;
case NODE_ATTRSET:
- if (the_env->argc != 2)
- Fail("Wrong # of arguments(%d for 1)", the_env->argc - 1);
- return rb_ivar_set(node->nd_vid, the_env->argv[1]);
+ if (the_env->argc != 1)
+ Fail("Wrong # of arguments(%d for 1)", the_env->argc);
+ return rb_ivar_set(node->nd_vid, the_env->argv[0]);
case NODE_ARGS:
{
@@ -900,7 +975,7 @@ rb_eval(node)
int i, len;
i = node->nd_cnt;
- len = the_env->argc - 1;
+ len = the_env->argc;
if (i > len || (node->nd_rest == -1 && i < len))
Fail("Wrong # of arguments(%d for %d)", len, i);
@@ -909,15 +984,15 @@ rb_eval(node)
Bug("unexpected local variable asignment");
for (i=1;local;i++) {
- the_env->local_vars[(int)local->nd_head] = the_env->argv[i];
+ the_env->local_vars[(int)local->nd_head] = the_env->argv[i-1];
local = local->nd_next;
}
if (node->nd_rest >= 0) {
- if (the_env->argc == 1)
+ if (the_env->argc == 0)
the_env->local_vars[node->nd_rest] = ary_new();
else
the_env->local_vars[node->nd_rest] =
- ary_new4(the_env->argc-i, the_env->argv+i);
+ ary_new4(the_env->argc-i+1, the_env->argv+i-1);
}
}
return Qnil;
@@ -1053,7 +1128,7 @@ obj_responds_to(obj, msg)
id = rb_intern(msg->ptr);
}
- if (rb_get_method_body(CLASS_OF(obj), id, 0)) {
+ if (rb_method_boundp(CLASS_OF(obj), id)) {
return TRUE;
}
return FALSE;
@@ -1147,19 +1222,6 @@ rb_fail(mesg)
}
VALUE
-Ffail(self, args)
- VALUE self, args;
-{
- VALUE mesg;
-
- rb_scan_args(args, "01", &mesg);
-
- if (mesg) Check_Type(mesg, T_STRING);
- rb_fail(mesg);
-
- return Qnil; /* not reached */
-}
-
iterator_p()
{
return ITERATOR_P();
@@ -1170,10 +1232,10 @@ rb_yield(val)
VALUE val;
{
struct BLOCK *block;
- int state;
- int go_out;
+ int state;
+ int go_out;
VALUE result;
- int cnt;
+ int cnt;
&go_out;
block = the_env->block;
@@ -1186,7 +1248,10 @@ rb_yield(val)
the_env = &(block->env);
the_env->flags = the_env->prev->flags;
if (block->var) {
- asign(block->var, val);
+ if (block->var->type == NODE_MASGN)
+ masign(block->var, val);
+ else
+ asign(block->var, val);
}
go_out = 0;
@@ -1221,6 +1286,44 @@ rb_yield(val)
return result;
}
+static VALUE
+masign(node, val)
+ NODE *node;
+ VALUE val;
+{
+ NODE *list;
+ int i, len;
+
+ list = node->nd_head;
+
+ if (val) {
+ if (TYPE(val) != T_ARRAY) {
+ val = rb_to_a(val);
+ }
+ len = RARRAY(val)->len;
+ for (i=0; list && i<len; i++) {
+ asign(list->nd_head, RARRAY(val)->ptr[i]);
+ list = list->nd_next;
+ }
+ if (node->nd_args) {
+ if (!list && i<len) {
+ asign(node->nd_args, ary_new4(len-i, RARRAY(val)->ptr+i));
+ }
+ else {
+ asign(node->nd_args, ary_new());
+ }
+ }
+ }
+ else if (node->nd_args) {
+ asign(node->nd_args, ary_new());
+ }
+ while (list) {
+ asign(list->nd_head, Qnil);
+ list = list->nd_next;
+ }
+ return val;
+}
+
static void
asign(lhs, val)
NODE *lhs;
@@ -1275,7 +1378,7 @@ rb_iterate(it_proc, data1, bl_proc, data2)
VALUE (*it_proc)(), (*bl_proc)();
char *data1, *data2;
{
- int state;
+ int state;
VALUE retval;
NODE *node = NEW_CFUNC(bl_proc, data2);
struct BLOCK block;
@@ -1324,8 +1427,8 @@ rb_resque(b_proc, data1, r_proc, data2)
VALUE (*b_proc)(), (*r_proc)();
char *data1, *data2;
{
- int state;
- int go_out;
+ int state;
+ int go_out;
VALUE result;
&go_out;
@@ -1375,7 +1478,7 @@ rb_ensure(b_proc, data1, e_proc, data2)
VALUE (*b_proc)(), (*e_proc)();
char *data1, *data2;
{
- int state;
+ int state;
VALUE result;
PUSH_TAG();
@@ -1396,7 +1499,7 @@ struct st_table *new_idhash();
static void
rb_undefined(obj, id)
VALUE obj;
- ID id;
+ ID id;
{
VALUE desc = obj_as_string(obj);
@@ -1413,126 +1516,133 @@ static VALUE
rb_call(class, recv, mid, argc, argv)
struct RClass *class;
VALUE recv, *argv;
- int argc;
- ID mid;
+ int argc;
+ ID mid;
{
- int state;
- int go_out = 0;
- int c = argc - 1;
- NODE *body;
- VALUE result;
+ int state, go_out;
+ NODE *body;
+ VALUE result;
+ VALUE saved_self = Qself;
+ int saved_ilevel = the_env->iterator;
+ struct cache_entry *ent;
+ ID id;
- &go_out;
- PUSH_ENV();
- the_env->flags |= DURING_CALL;
- the_env->argc = argc;
- the_env->argv = argv;
Qself = recv;
- if (argv) argv[0] = recv;
if (the_env->iterator != 0) the_env->iterator++;
- if ((body = rb_get_method_body(class, mid, 1)) == Qnil) {
- rb_undefined(recv, mid);
+ /* is it in the method cache? */
+ ent = cache + EXPR1(class, mid);
+ if (ent->class == class && ent->mid == mid) {
+ if (ent->undef) rb_undefined(recv, mid);
+ class = ent->origin;
+ id = ent->method->id;
+ body = ent->method->node;
+ }
+ else {
+ id = mid;
+ if ((body = rb_get_method_body(&class, &id)) == Qnil) {
+ rb_undefined(recv, mid);
+ }
}
if (body->type == NODE_CFUNC) {
int len = body->nd_argc;
- if (len >= 0 && c != len) {
- Fail("Wrong # of arguments for(%d for %d)", c, body->nd_argc);
+ if (len >= 0 && argc != len) {
+ Fail("Wrong # of arguments for(%d for %d)", argc, body->nd_argc);
}
if (len == -2) {
- result = (*body->nd_cfnc)(recv, ary_new4(argc-1, argv+1));
+ result = (*body->nd_cfnc)(recv, ary_new4(argc, argv));
}
else if (len == -1) {
result = (*body->nd_cfnc)(argc, argv);
}
else if (len >= 0) {
- switch (c) {
+ switch (argc) {
case 0:
result = (*body->nd_cfnc)(recv);
break;
case 1:
- result = (*body->nd_cfnc)(recv, argv[1]);
+ result = (*body->nd_cfnc)(recv, argv[0]);
break;
case 2:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1]);
break;
case 3:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2]);
break;
case 4:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3]);
break;
case 5:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4]);
break;
case 6:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5]);
break;
case 7:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6]);
break;
case 8:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7]);
break;
case 9:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8]);
break;
case 10:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9],
- argv[7], argv[8], argv[9],
- argv[10]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8],
+ argv[6], argv[7], argv[8],
+ argv[9]);
break;
case 11:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9],
- argv[7], argv[8], argv[9],
- argv[10], argv[11]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8],
+ argv[6], argv[7], argv[8],
+ argv[9], argv[10]);
break;
case 12:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9],
- argv[7], argv[8], argv[9],
- argv[10], argv[11], argv[12]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8],
+ argv[6], argv[7], argv[8],
+ argv[9], argv[10], argv[11]);
break;
case 13:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9],
- argv[7], argv[8], argv[9],
- argv[10], argv[11], argv[12],
- argv[13]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8],
+ argv[6], argv[7], argv[8],
+ argv[9], argv[10], argv[11],
+ argv[12]);
break;
case 14:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9],
- argv[7], argv[8], argv[9],
- argv[10], argv[11], argv[12],
- argv[13], argv[14]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8],
+ argv[6], argv[7], argv[8],
+ argv[9], argv[10], argv[11],
+ argv[12], argv[13]);
break;
case 15:
- result = (*body->nd_cfnc)(recv, argv[1], argv[2], argv[3],
- argv[4], argv[5], argv[6],
- argv[7], argv[8], argv[9],
- argv[7], argv[8], argv[9],
- argv[10], argv[11], argv[12],
- argv[13], argv[14], argv[15]);
+ result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2],
+ argv[3], argv[4], argv[5],
+ argv[6], argv[7], argv[8],
+ argv[6], argv[7], argv[8],
+ argv[9], argv[10], argv[11],
+ argv[12], argv[13], argv[14]);
break;
default:
Fail("too many arguments(%d)", len);
@@ -1545,15 +1655,25 @@ rb_call(class, recv, mid, argc, argv)
}
}
else {
- the_env->file = sourcefile;
- the_env->line = sourceline;
+ PUSH_ENV();
+
the_env->local_vars = Qnil;
the_env->local_tbl = Qnil;
+ the_env->flags |= DURING_CALL;
+ the_env->argc = argc;
+ the_env->argv = argv;
+ the_env->last_class = class;
+ the_env->last_func = id;
+#ifdef USE_CALLER
+ the_env->file = sourcefile;
+ the_env->line = sourceline;
+#endif
PUSH_TAG();
switch (state = EXEC_TAG()) {
case 0:
result = rb_eval(body);
+ go_out=0;
break;
case TAG_CONTINUE:
Fatal("unexpected continue");
@@ -1571,14 +1691,14 @@ rb_call(class, recv, mid, argc, argv)
result = last_val;
break;
default:
- go_out++;
+ go_out=1;
}
POP_TAG();
+ POP_ENV();
+ if (go_out) JUMP_TAG(state);
}
-
- POP_ENV();
-
- if (go_out) JUMP_TAG(state);
+ Qself = saved_self;
+ the_env->iterator = saved_ilevel;
return result;
}
@@ -1627,30 +1747,27 @@ rb_funcall(recv, mid, n, va_alist)
va_dcl
{
va_list ar;
- int argc;
VALUE *argv;
if (n > 0) {
int i;
- argc = n + 1;
- argv = (VALUE*)alloca(sizeof(VALUE)*argc);
+ argv = (VALUE*)alloca(sizeof(VALUE)*n);
va_start(ar);
- for (i=1;i<argc;i++) {
+ for (i=0;i<n;i++) {
argv[i] = va_arg(ar, VALUE);
}
- argv[0] = Qnil;
va_end(ar);
}
else {
- argc = 1;
argv = Qnil;
}
- return rb_call(CLASS_OF(recv), recv, mid, argc, argv);
+ return rb_call(CLASS_OF(recv), recv, mid, n, argv);
}
+#ifdef USE_CALLER
VALUE
Fcaller(obj, args)
VALUE obj, args;
@@ -1679,15 +1796,15 @@ Fcaller(obj, args)
if (e->file == Qnil) Fail("initial frame");
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);
+ ary = e->argv?ary_new4(e->argc, e->argv):ary_new2(0);
+ res = ary_new3(5, file, INT2FIX(e->line),
+ str_new2(rb_id2name(e->last_func)), Qself, ary);
return res;
}
+#endif
int in_eval = 0;
-extern int nerrs;
VALUE
Feval(obj, src)
@@ -1855,7 +1972,7 @@ Frequire(obj, fname)
}
char *getenv();
-char *index();
+char *strchr();
#ifndef RUBY_LIB
#define RUBY_LIB "/usr/local/lib/ruby:."
@@ -1874,7 +1991,7 @@ addpath(path)
p = s = path;
while (*p) {
while (*p == RUBY_LIB_SEP) p++;
- if (s = index(p, RUBY_LIB_SEP)) {
+ if (s = strchr(p, RUBY_LIB_SEP)) {
Fary_push(rb_load_path, str_new(p, (int)(s-p)));
p = s + 1;
}
diff --git a/file.c b/file.c
index 8ff7c758e6..d9a303eea6 100644
--- a/file.c
+++ b/file.c
@@ -4,7 +4,7 @@
file.c -
$Author: matz $
- $Date: 1994/06/27 15:48:26 $
+ $Date: 1994/08/18 07:06:21 $
created at: Mon Nov 15 12:24:34 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -23,6 +23,7 @@ char *strdup();
extern VALUE C_IO;
VALUE C_File;
+VALUE M_FileTest;
VALUE time_new();
@@ -76,8 +77,6 @@ Ffile_seek(obj, offset, ptrname)
OpenFile *fptr;
long pos;
- Check_Type(ptrname, T_FIXNUM);
-
GetOpenFile(obj, fptr);
pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname));
@@ -88,6 +87,21 @@ Ffile_seek(obj, offset, ptrname)
}
static VALUE
+Ffile_set_pos(obj, offset)
+ VALUE obj, offset;
+{
+ OpenFile *fptr;
+ long pos;
+
+ GetOpenFile(obj, fptr);
+ pos = fseek(fptr->f, NUM2INT(offset), 0);
+ if (pos != 0) rb_sys_fail(Qnil);
+ clearerr(fptr->f);
+
+ return obj;
+}
+
+static VALUE
Ffile_rewind(obj)
VALUE obj;
{
@@ -310,7 +324,7 @@ eaccess(path, mode)
}
static VALUE
-Ffile_d(obj, fname)
+Ftest_d(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -327,7 +341,7 @@ Ffile_d(obj, fname)
}
static VALUE
-Ffile_p(obj, fname)
+Ftest_p(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -347,7 +361,7 @@ Ffile_p(obj, fname)
}
static VALUE
-Ffile_l(obj, fname)
+Ftest_l(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -376,7 +390,7 @@ Ffile_l(obj, fname)
return FALSE;
}
-Ffile_S(obj, fname)
+Ftest_S(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -406,7 +420,7 @@ Ffile_S(obj, fname)
}
static VALUE
-Ffile_b(obj, fname)
+Ftest_b(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -428,7 +442,7 @@ Ffile_b(obj, fname)
}
static VALUE
-Ffile_c(obj, fname)
+Ftest_c(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -446,7 +460,7 @@ Ffile_c(obj, fname)
}
static VALUE
-Ffile_e(obj, fname)
+Ftest_e(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -458,7 +472,7 @@ Ffile_e(obj, fname)
}
static VALUE
-Ffile_r(obj, fname)
+Ftest_r(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -468,7 +482,7 @@ Ffile_r(obj, fname)
}
static VALUE
-Ffile_R(obj, fname)
+Ftest_R(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -478,7 +492,7 @@ Ffile_R(obj, fname)
}
static VALUE
-Ffile_w(obj, fname)
+Ftest_w(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -488,7 +502,7 @@ Ffile_w(obj, fname)
}
static VALUE
-Ffile_W(obj, fname)
+Ftest_W(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -498,7 +512,7 @@ Ffile_W(obj, fname)
}
static VALUE
-Ffile_x(obj, fname)
+Ftest_x(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -508,7 +522,7 @@ Ffile_x(obj, fname)
}
static VALUE
-Ffile_X(obj, fname)
+Ftest_X(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -518,7 +532,7 @@ Ffile_X(obj, fname)
}
static VALUE
-Ffile_f(obj, fname)
+Ftest_f(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -531,7 +545,7 @@ Ffile_f(obj, fname)
}
static VALUE
-Ffile_z(obj, fname)
+Ftest_z(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -544,7 +558,7 @@ Ffile_z(obj, fname)
}
static VALUE
-Ffile_s(obj, fname)
+Ftest_s(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -557,7 +571,7 @@ Ffile_s(obj, fname)
}
static VALUE
-Ffile_owned(obj, fname)
+Ftest_owned(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -570,7 +584,7 @@ Ffile_owned(obj, fname)
}
static VALUE
-Ffile_grpowned(obj, fname)
+Ftest_grpowned(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -597,7 +611,7 @@ check3rdbyte(file, mode)
#endif
static VALUE
-Ffile_suid(obj, fname)
+Ftest_suid(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -610,7 +624,7 @@ Ffile_suid(obj, fname)
}
static VALUE
-Ffile_sgid(obj, fname)
+Ftest_sgid(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -623,7 +637,7 @@ Ffile_sgid(obj, fname)
}
static VALUE
-Ffile_sticky(obj, fname)
+Ftest_sticky(obj, fname)
VALUE obj;
struct RString *fname;
{
@@ -636,6 +650,51 @@ Ffile_sticky(obj, fname)
}
static VALUE
+Ffile_type(obj, fname)
+ VALUE obj;
+ struct RString *fname;
+{
+ struct stat st;
+ char *t;
+
+ Check_Type(fname, T_STRING);
+ if (cache_stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+
+ if (S_ISREG(st.st_mode)) {
+ t = "file";
+ } else if (S_ISDIR(st.st_mode)) {
+ t = "directory";
+ } else if (S_ISCHR(st.st_mode)) {
+ t = "characterSpecial";
+ }
+#ifdef S_ISBLK
+ else if (S_ISBLK(st.st_mode)) {
+ t = "blockSpecial";
+ }
+#endif
+#ifndef S_ISFIFO
+ else if (S_ISFIFO(st.st_mode)) {
+ t = "fifo";
+ }
+#endif
+#ifdef S_ISLNK
+ else if (S_ISLNK(st.st_mode)) {
+ t = "link";
+ }
+#endif
+#ifdef S_ISSOCK
+ else if (S_ISSOCK(st.st_mode)) {
+ t = "socket";
+ }
+#endif
+ else {
+ t = "unknown";
+ }
+
+ return str_new2(t);
+}
+
+static VALUE
Ffile_atime(obj, fname)
VALUE obj;
struct RString *fname;
@@ -733,7 +792,7 @@ Ffile_chmod(obj, args)
rb_sys_fail(RSTRING(path)->ptr);
}
- return Qnil;
+ return INT2FIX(i);
}
static VALUE
@@ -749,7 +808,7 @@ Ffile_chmod2(obj, vmode)
if (fchmod(fileno(fptr->f), mode) == -1)
rb_sys_fail(fptr->path);
- return obj;
+ return INT2FIX(0);
}
static VALUE
@@ -797,7 +856,7 @@ Ffile_chown2(obj, owner, group)
if (fchown(fileno(fptr->f), NUM2INT(owner), NUM2INT(group)) == -1)
rb_sys_fail(fptr->path);
- return obj;
+ return INT2FIX(0);
}
struct timeval *time_timeval();
@@ -838,7 +897,7 @@ Ffile_link(obj, from, to)
if (link(from->ptr, to->ptr) < 0)
rb_sys_fail(from->ptr);
- return TRUE;
+ return INT2FIX(0);
}
static VALUE
@@ -899,7 +958,7 @@ Ffile_rename(obj, from, to)
if (rename(from->ptr, to->ptr) == -1)
rb_sys_fail(from->ptr);
- return TRUE;
+ return INT2FIX(0);
}
static VALUE
@@ -910,11 +969,11 @@ Ffile_umask(argc, argv)
VALUE mask;
int omask;
- if (argc == 1) {
+ if (argc == 0) {
int omask = umask(0);
umask(omask);
}
- else if (argc == 2) {
+ else if (argc == 1) {
omask = umask(NUM2INT(argv[1]));
}
else {
@@ -962,64 +1021,69 @@ Ffile_fcntl(obj, req, arg)
Init_File()
{
+ M_FileTest = rb_define_module("FileTest");
+
+ rb_define_method(M_FileTest, "d", Ftest_d, 1);
+ rb_define_method(M_FileTest, "isdirectory", Ftest_d, 1);
+ rb_define_method(M_FileTest, "a", Ftest_e, 1);
+ rb_define_method(M_FileTest, "e", Ftest_e, 1);
+ rb_define_method(M_FileTest, "exists", Ftest_e, 1);
+ rb_define_method(M_FileTest, "r", Ftest_r, 1);
+ rb_define_method(M_FileTest, "readable", Ftest_r, 1);
+ rb_define_method(M_FileTest, "R", Ftest_R, 1);
+ rb_define_method(M_FileTest, "w", Ftest_w, 1);
+ rb_define_method(M_FileTest, "writable", Ftest_w, 1);
+ rb_define_method(M_FileTest, "W", Ftest_W, 1);
+ rb_define_method(M_FileTest, "x", Ftest_x, 1);
+ rb_define_method(M_FileTest, "executable", Ftest_x, 1);
+ rb_define_method(M_FileTest, "X", Ftest_X, 1);
+ rb_define_method(M_FileTest, "f", Ftest_f, 1);
+ rb_define_method(M_FileTest, "isfile", Ftest_f, 1);
+ rb_define_method(M_FileTest, "z", Ftest_z, 1);
+ rb_define_method(M_FileTest, "s", Ftest_s, 1);
+ rb_define_method(M_FileTest, "size", Ftest_s, 1);
+ rb_define_method(M_FileTest, "O", Ftest_owned, 1);
+ rb_define_method(M_FileTest, "owned", Ftest_owned, 1);
+ rb_define_method(M_FileTest, "G", Ftest_grpowned, 1);
+
+ rb_define_method(M_FileTest, "p", Ftest_p, 1);
+ rb_define_method(M_FileTest, "ispipe", Ftest_p, 1);
+ rb_define_method(M_FileTest, "l", Ftest_l, 1);
+ rb_define_method(M_FileTest, "issymlink", Ftest_l, 1);
+ rb_define_method(M_FileTest, "S", Ftest_S, 1);
+ rb_define_method(M_FileTest, "issocket", Ftest_S, 1);
+
+ rb_define_method(M_FileTest, "b", Ftest_b, 1);
+ rb_define_method(M_FileTest, "c", Ftest_c, 1);
+
+ rb_define_method(M_FileTest, "u", Ftest_suid, 1);
+ rb_define_method(M_FileTest, "setuid", Ftest_suid, 1);
+ rb_define_method(M_FileTest, "g", Ftest_sgid, 1);
+ rb_define_method(M_FileTest, "setgid", Ftest_sgid, 1);
+ rb_define_method(M_FileTest, "k", Ftest_sticky, 1);
+
C_File = rb_define_class("File", C_IO);
+ rb_include_module(CLASS_OF(C_File), M_FileTest);
+
rb_define_single_method(C_File, "stat", Ffile_stat, 1);
- rb_define_single_method(C_File, "lstat", Ffile_lstat, 1);
-
- rb_define_single_method(C_File, "d", Ffile_d, 1);
- rb_define_single_method(C_File, "isdirectory", Ffile_d, 1);
- rb_define_single_method(C_File, "a", Ffile_e, 1);
- rb_define_single_method(C_File, "e", Ffile_e, 1);
- rb_define_single_method(C_File, "exists", Ffile_e, 1);
- rb_define_single_method(C_File, "r", Ffile_r, 1);
- rb_define_single_method(C_File, "readable", Ffile_r, 1);
- rb_define_single_method(C_File, "R", Ffile_R, 1);
- rb_define_single_method(C_File, "w", Ffile_w, 1);
- rb_define_single_method(C_File, "writable", Ffile_w, 1);
- rb_define_single_method(C_File, "W", Ffile_W, 1);
- rb_define_single_method(C_File, "x", Ffile_x, 1);
- rb_define_single_method(C_File, "executable", Ffile_x, 1);
- rb_define_single_method(C_File, "X", Ffile_X, 1);
- rb_define_single_method(C_File, "f", Ffile_f, 1);
- rb_define_single_method(C_File, "isfile", Ffile_f, 1);
- rb_define_single_method(C_File, "z", Ffile_z, 1);
- rb_define_single_method(C_File, "s", Ffile_s, 1);
- rb_define_single_method(C_File, "size", Ffile_s, 1);
- rb_define_single_method(C_File, "O", Ffile_owned, 1);
- rb_define_single_method(C_File, "owned", Ffile_owned, 1);
- rb_define_single_method(C_File, "G", Ffile_grpowned, 1);
-
- rb_define_single_method(C_File, "p", Ffile_p, 1);
- rb_define_single_method(C_File, "ispipe", Ffile_p, 1);
- rb_define_single_method(C_File, "l", Ffile_l, 1);
- rb_define_single_method(C_File, "issymlink", Ffile_l, 1);
- rb_define_single_method(C_File, "S", Ffile_S, 1);
- rb_define_single_method(C_File, "issocket", Ffile_S, 1);
-
- rb_define_single_method(C_File, "b", Ffile_b, 1);
- rb_define_single_method(C_File, "c", Ffile_c, 1);
-
- rb_define_single_method(C_File, "u", Ffile_suid, 1);
- rb_define_single_method(C_File, "setuid", Ffile_suid, 1);
- rb_define_single_method(C_File, "g", Ffile_sgid, 1);
- rb_define_single_method(C_File, "setgid", Ffile_sgid, 1);
- rb_define_single_method(C_File, "k", Ffile_sticky, 1);
+ rb_define_single_method(C_File, "lstat", Ffile_lstat, 1);
+ rb_define_single_method(C_File, "type", Ffile_type, 1);
rb_define_single_method(C_File, "atime", Ffile_atime, 1);
rb_define_single_method(C_File, "mtime", Ffile_mtime, 1);
rb_define_single_method(C_File, "ctime", Ffile_ctime, 1);
- rb_define_single_method(C_File, "utime", Ffile_utime, -1);
+ rb_define_single_method(C_File, "utime", Ffile_utime, -2);
rb_define_single_method(C_File, "chmod", Ffile_chmod, -2);
- rb_define_single_method(C_File, "chown", Ffile_chown, -1);
+ rb_define_single_method(C_File, "chown", Ffile_chown, -2);
rb_define_single_method(C_File, "link", Ffile_link, 2);
rb_define_single_method(C_File, "symlink", Ffile_symlink, 2);
rb_define_single_method(C_File, "readlink", Ffile_readlink, 1);
- rb_define_single_method(C_File, "unlink", Ffile_unlink, -1);
- rb_define_single_method(C_File, "delete", Ffile_unlink, -1);
+ rb_define_single_method(C_File, "unlink", Ffile_unlink, -2);
+ rb_define_single_method(C_File, "delete", Ffile_unlink, -2);
rb_define_single_method(C_File, "rename", Ffile_rename, 2);
rb_define_single_method(C_File, "umask", Ffile_umask, -1);
rb_define_single_method(C_File, "truncate", Ffile_truncate, 2);
@@ -1037,6 +1101,11 @@ Init_File()
rb_define_method(C_File, "tell", Ffile_tell, 0);
rb_define_method(C_File, "seek", Ffile_seek, 2);
+
+
+ rb_define_method(C_File, "pos", Ffile_tell, 0);
+ rb_define_method(C_File, "pos=", Ffile_set_pos, 1);
+
rb_define_method(C_File, "rewind", Ffile_rewind, 0);
rb_define_method(C_File, "isatty", Ffile_isatty, 0);
rb_define_method(C_File, "eof", Ffile_eof, 0);
diff --git a/fnmatch.c b/fnmatch.c
new file mode 100644
index 0000000000..6a8b574902
--- /dev/null
+++ b/fnmatch.c
@@ -0,0 +1,189 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#include <errno.h>
+#include "fnmatch.h"
+
+#if !defined (__GNU_LIBRARY__) && !defined (STDC_HEADERS)
+# if !defined (errno)
+extern int errno;
+# endif /* !errno */
+#endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ it matches, FNM_NOMATCH if not. */
+int
+fnmatch (pattern, string, flags)
+ char *pattern;
+ char *string;
+ int flags;
+{
+ register char *p = pattern, *n = string;
+ register char c;
+
+ if ((flags & ~__FNM_FLAGS) != 0)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ while ((c = *p++) != '\0')
+ {
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return (FNM_NOMATCH);
+ else if ((flags & FNM_PATHNAME) && *n == '/')
+ return (FNM_NOMATCH);
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+ return (FNM_NOMATCH);
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ c = *p++;
+ if (*n != c)
+ return (FNM_NOMATCH);
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+ return (FNM_NOMATCH);
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
+ if (((flags & FNM_PATHNAME) && *n == '/') ||
+ (c == '?' && *n == '\0'))
+ return (FNM_NOMATCH);
+
+ if (c == '\0')
+ return (0);
+
+ {
+ char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || *n == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return (0);
+ return (FNM_NOMATCH);
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return (FNM_NOMATCH);
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+ return (FNM_NOMATCH);
+
+ /* Make sure there is a closing `]'. If there isn't, the `['
+ is just a character to be matched. */
+ {
+ register char *np;
+
+ for (np = p; np && *np && *np != ']'; np++);
+
+ if (np && !*np)
+ {
+ if (*n != '[')
+ return (FNM_NOMATCH);
+ goto next_char;
+ }
+ }
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ register char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ cstart = cend = *p++;
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return (FNM_NOMATCH);
+
+ c = *p++;
+
+ if ((flags & FNM_PATHNAME) && c == '/')
+ /* [/] can never match. */
+ return (FNM_NOMATCH);
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return (FNM_NOMATCH);
+ c = *p++;
+ }
+
+ if (*n >= cstart && *n <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return (FNM_NOMATCH);
+
+ next_char:
+ break;
+
+ matched:
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return (FNM_NOMATCH);
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ /* 1003.2d11 is unclear if this is right. %%% */
+ ++p;
+ }
+ if (not)
+ return (FNM_NOMATCH);
+ }
+ break;
+
+ default:
+ if (c != *n)
+ return (FNM_NOMATCH);
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return (0);
+
+ return (FNM_NOMATCH);
+}
diff --git a/fnmatch.h b/fnmatch.h
new file mode 100644
index 0000000000..62c8c8fa02
--- /dev/null
+++ b/fnmatch.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA. */
+
+#ifndef _FNMATCH_H
+
+#define _FNMATCH_H 1
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+#define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */
+#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD)
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* Match STRING against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+extern int fnmatch();
+
+#endif /* fnmatch.h */
diff --git a/gc.c b/gc.c
index 96b886fa2f..1eebe39419 100644
--- a/gc.c
+++ b/gc.c
@@ -3,7 +3,7 @@
gc.c -
$Author: matz $
- $Date: 1994/06/27 15:48:27 $
+ $Date: 1994/08/12 04:47:27 $
created at: Tue Oct 5 09:44:46 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -48,7 +48,7 @@ xcalloc(n, size)
void *mem;
mem = xmalloc(n * size);
- bzero(mem, n * size);
+ memset(mem, 0, n * size);
return mem;
}
@@ -318,12 +318,13 @@ mark_locations_array(x, n)
{
int j;
VALUE p;
- for(j=0;j<n;++j)
- {p = x[j];
- if (looks_pointerp(p)) {
- gc_mark(p);
- }
- }
+
+ for(j=0;j<n;++j) {
+ p = x[j];
+ if (looks_pointerp(p)) {
+ gc_mark(p);
+ }
+ }
}
static void
@@ -590,12 +591,10 @@ gc()
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));
+ mark_locations((VALUE*)((char*)stack_start_ptr + 2),
+ (VALUE*)((char*)&stack_end + 2));
#endif
/* mark protected global variables */
diff --git a/glob.c b/glob.c
new file mode 100644
index 0000000000..1c21d25f14
--- /dev/null
+++ b/glob.c
@@ -0,0 +1,177 @@
+/************************************************
+
+ glob.c -
+
+ $Author$
+ $Date$
+ created at: Mon Sep 12 18:56:43 JST 1994
+
+************************************************/
+
+#include "ruby.h"
+#include "fnmatch.h"
+#include <sys/param.h>
+
+char *strdup();
+
+VALUE C_Glob;
+
+struct glob_data {
+ char **globs;
+};
+
+static ID id_data;
+
+static void
+glob_free(data)
+ struct glob_data *data;
+{
+ char **globs = data->globs;
+ while (*globs) {
+ free(*globs);
+ globs++;
+ }
+ free(data->globs);
+}
+
+#define isdelim(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)=='\0')
+
+char *strchr();
+char *strdup();
+
+static int
+expand_brace(s, data, len)
+ char *s;
+ struct glob_data *data;
+ int len;
+{
+ char org[MAXPATHLEN], path[MAXPATHLEN];
+ char *pre, *post, *head, *p, *t;
+
+ strcpy(org, s);
+ pre = strchr(org, '{');
+ if (pre) post = strchr(pre, '}');
+ if (!pre || !post) {
+ data->globs[len++] = strdup(s);
+ REALLOC_N(data->globs, char*, len+1);
+ return len;
+ }
+
+ memcpy(path, org, pre - org);
+ p = org + (pre - org) + 1;
+ head = path + (pre - org);
+
+ while (p < post) {
+ t = p;
+ while (t < post) {
+ if (*t == ',') break;
+ t++;
+ }
+ memcpy(head, p, t-p);
+ strcpy(head+(t-p), post+1);
+ len = expand_brace(path, data, len);
+ p = t + 1;
+ }
+ return len;
+}
+
+static VALUE
+glob_new0(class, str)
+ VALUE class;
+ struct RString *str;
+{
+ VALUE new;
+ struct glob_data *data;
+ char *p1, *p2, *pend, *s;
+ int len = 0;
+
+ new = obj_alloc(class);
+ Make_Data_Struct(new, id_data, struct glob_data, Qnil, glob_free, data);
+ data->globs = ALLOC_N(char*, 1);
+
+ p1 = p2 = str->ptr;
+ pend = p1 + str->len;
+ while (p1 < pend) {
+ char s[MAXPATHLEN];
+ int d;
+
+ while (isdelim(*p1)) p1++;
+ p2 = p1;
+ while (!isdelim(*p2)) p2++;
+ d = p2 - p1;
+ memcpy(s, p1, d);
+ s[d] = '\0';
+ len = expand_brace(s, data, len);
+ p1 = p2;
+ }
+ data->globs[len] = Qnil;
+
+ return new;
+}
+
+VALUE
+glob_new(str)
+ char *str;
+{
+ return glob_new0(C_Glob, str);
+}
+
+char **glob_filename();
+
+static VALUE
+Fglob_each(glob)
+ VALUE glob;
+{
+ struct glob_data *data;
+ char **patv, **fnames, **ff;
+
+ Get_Data_Struct(glob, id_data, struct glob_data, data);
+ for (patv = data->globs; *patv; patv++) {
+ if (!glob_pattern_p(*patv)) {
+ rb_yield(str_new2(*patv));
+ continue;
+ }
+ fnames = ff = glob_filename(*patv);
+ while (*ff) {
+ rb_yield(str_new2(*ff));
+ free(*ff);
+ ff++;
+ }
+ free(fnames);
+ }
+ return Qnil;
+}
+
+VALUE
+Fglob_match(glob, str)
+ VALUE glob;
+ struct RString *str;
+{
+ struct glob_data *data;
+ char **patv;
+
+ Check_Type(str, T_STRING);
+ Get_Data_Struct(glob, id_data, struct glob_data, data);
+ patv = data->globs;
+ while (*patv) {
+ if (fnmatch(*patv, str->ptr, 0) != FNM_NOMATCH)
+ return TRUE;
+ patv++;
+ }
+ return FALSE;
+}
+
+extern VALUE M_Enumerable;
+
+Init_Glob()
+{
+ C_Glob = rb_define_class("Glob", C_Object);
+ rb_include_module(C_Glob, M_Enumerable);
+
+ rb_define_single_method(C_Glob, "new", glob_new0, 1);
+
+ rb_define_method(C_Glob, "each", Fglob_each, 0);
+ rb_define_method(C_Glob, "=~", Fglob_match, 1);
+
+ id_data = rb_intern("data");
+}
diff --git a/gnuglob.c b/gnuglob.c
new file mode 100644
index 0000000000..e5eecc1a79
--- /dev/null
+++ b/gnuglob.c
@@ -0,0 +1,572 @@
+/* File-name wildcard pattern matching for GNU.
+ Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc.
+
+ 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 1, 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. */
+
+/* To whomever it may concern: I have never seen the code which most
+ Unix programs use to perform this function. I wrote this from scratch
+ based on specifications for the pattern matching. --RMS. */
+
+#if defined (SHELL)
+# if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+# else
+# include "ansi_stdlib.h"
+# endif /* HAVE_STDLIB_H */
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
+# if !defined (HAVE_DIRENT_H)
+# define HAVE_DIRENT_H
+# endif /* !HAVE_DIRENT_H */
+#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
+
+#if defined (HAVE_DIRENT_H)
+# include <dirent.h>
+# if !defined (direct)
+# define direct dirent
+# endif /* !direct */
+# define D_NAMLEN(d) strlen ((d)->d_name)
+#else /* !HAVE_DIRENT_H */
+# define D_NAMLEN(d) ((d)->d_namlen)
+# if defined (USG)
+# if defined (Xenix)
+# include <sys/ndir.h>
+# else /* !Xenix (but USG...) */
+# include "ndir.h"
+# endif /* !Xenix */
+# else /* !USG */
+# include <sys/dir.h>
+# endif /* !USG */
+#endif /* !HAVE_DIRENT_H */
+
+#if defined (_POSIX_SOURCE)
+/* Posix does not require that the d_ino field be present, and some
+ systems do not provide it. */
+# define REAL_DIR_ENTRY(dp) 1
+#else
+# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+#endif /* _POSIX_SOURCE */
+
+#if defined (USG) || defined (NeXT)
+# if !defined (HAVE_STRING_H)
+# define HAVE_STRING_H
+# endif /* !HAVE_STRING_H */
+#endif /* USG || NeXT */
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if defined (USG)
+# if !defined (isc386)
+# include <memory.h>
+# endif /* !isc386 */
+# if defined (RISC6000)
+extern void bcopy ();
+# else /* !RISC6000 */
+# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
+# endif /* !RISC6000 */
+#endif /* USG */
+
+#include "fnmatch.h"
+
+/* If the opendir () on your system lets you open non-directory files,
+ then we consider that not robust. Define OPENDIR_NOT_ROBUST in the
+ SYSDEP_CFLAGS for your machines entry in machines.h. */
+#if defined (OPENDIR_NOT_ROBUST)
+# if defined (SHELL)
+# include "posixstat.h"
+# else /* !SHELL */
+# include <sys/stat.h>
+# endif /* !SHELL */
+#endif /* OPENDIR_NOT_ROBUST */
+
+#if !defined (HAVE_STDLIB_H)
+extern char *malloc (), *realloc ();
+extern void free ();
+#endif /* !HAVE_STDLIB_H */
+
+#if !defined (NULL)
+# if defined (__STDC__)
+# define NULL ((void *) 0)
+# else
+# define NULL 0x0
+# endif /* __STDC__ */
+#endif /* !NULL */
+
+#if defined (SHELL)
+extern int interrupt_state;
+#endif /* SHELL */
+
+/* Global variable which controls whether or not * matches .*.
+ Non-zero means don't match .*. */
+int noglob_dot_filenames = 1;
+
+/* Global variable to return to signify an error in globbing. */
+char *glob_error_return;
+
+
+/* Return nonzero if PATTERN has any special globbing chars in it. */
+int
+glob_pattern_p (pattern)
+ char *pattern;
+{
+ register char *p = pattern;
+ register char c;
+ int open = 0;
+
+ while ((c = *p++) != '\0')
+ switch (c)
+ {
+ case '?':
+ case '*':
+ return (1);
+
+ case '[': /* Only accept an open brace if there is a close */
+ open++; /* brace to match it. Bracket expressions must be */
+ continue; /* complete, according to Posix.2 */
+ case ']':
+ if (open)
+ return (1);
+ continue;
+
+ case '\\':
+ if (*p++ == '\0')
+ return (0);
+ }
+
+ return (0);
+}
+
+/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
+static void
+dequote_pathname (pathname)
+ char *pathname;
+{
+ register int i, j;
+
+ for (i = j = 0; pathname && pathname[i]; )
+ {
+ if (pathname[i] == '\\')
+ i++;
+
+ pathname[j++] = pathname[i++];
+
+ if (!pathname[i - 1])
+ break;
+ }
+ pathname[j] = '\0';
+}
+
+
+/* Return a vector of names of files in directory DIR
+ whose names match glob pattern PAT.
+ The names are not in any particular order.
+ Wildcards at the beginning of PAT do not match an initial period.
+
+ The vector is terminated by an element that is a null pointer.
+
+ To free the space allocated, first free the vector's elements,
+ then free the vector.
+
+ Return 0 if cannot get enough memory to hold the pointer
+ and the names.
+
+ Return -1 if cannot access directory DIR.
+ Look in errno for more information. */
+
+char **
+glob_vector (pat, dir)
+ char *pat;
+ char *dir;
+{
+ struct globval
+ {
+ struct globval *next;
+ char *name;
+ };
+
+ DIR *d;
+ register struct direct *dp;
+ struct globval *lastlink;
+ register struct globval *nextlink;
+ register char *nextname;
+ unsigned int count;
+ int lose, skip;
+ register char **name_vector;
+ register unsigned int i;
+#if defined (OPENDIR_NOT_ROBUST)
+ struct stat finfo;
+
+ if (stat (dir, &finfo) < 0)
+ return ((char **) &glob_error_return);
+
+ if (!S_ISDIR (finfo.st_mode))
+ return ((char **) &glob_error_return);
+#endif /* OPENDIR_NOT_ROBUST */
+
+ d = opendir (dir);
+ if (d == NULL)
+ return ((char **) &glob_error_return);
+
+ lastlink = 0;
+ count = 0;
+ lose = 0;
+ skip = 0;
+
+ /* If PAT is empty, skip the loop, but return one (empty) filename. */
+ if (!pat || !*pat)
+ {
+ nextlink = (struct globval *)alloca (sizeof (struct globval));
+ nextlink->next = lastlink;
+ nextname = (char *) malloc (1);
+ if (!nextname)
+ lose = 1;
+ else
+ {
+ lastlink = nextlink;
+ nextlink->name = nextname;
+ nextname[0] = '\0';
+ count++;
+ }
+ skip = 1;
+ }
+
+ /* Scan the directory, finding all names that match.
+ For each name that matches, allocate a struct globval
+ on the stack and store the name in it.
+ Chain those structs together; lastlink is the front of the chain. */
+ while (!skip)
+ {
+ int flags; /* Flags passed to fnmatch (). */
+#if defined (SHELL)
+ /* Make globbing interruptible in the bash shell. */
+ if (interrupt_state)
+ {
+ closedir (d);
+ lose = 1;
+ goto lost;
+ }
+#endif /* SHELL */
+
+ dp = readdir (d);
+ if (dp == NULL)
+ break;
+
+ /* If this directory entry is not to be used, try again. */
+ if (!REAL_DIR_ENTRY (dp))
+ continue;
+
+ /* If a dot must be explicity matched, check to see if they do. */
+ if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.')
+ continue;
+
+ flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
+
+ if (fnmatch (pat, dp->d_name, flags) != FNM_NOMATCH)
+ {
+ nextlink = (struct globval *) alloca (sizeof (struct globval));
+ nextlink->next = lastlink;
+ nextname = (char *) malloc (D_NAMLEN (dp) + 1);
+ if (nextname == NULL)
+ {
+ lose = 1;
+ break;
+ }
+ lastlink = nextlink;
+ nextlink->name = nextname;
+ bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
+ ++count;
+ }
+ }
+ (void) closedir (d);
+
+ if (!lose)
+ {
+ name_vector = (char **) malloc ((count + 1) * sizeof (char *));
+ lose |= name_vector == NULL;
+ }
+
+ /* Have we run out of memory? */
+ lost:
+ if (lose)
+ {
+ /* Here free the strings we have got. */
+ while (lastlink)
+ {
+ free (lastlink->name);
+ lastlink = lastlink->next;
+ }
+#if defined (SHELL)
+ if (interrupt_state)
+ throw_to_top_level ();
+#endif /* SHELL */
+ return (NULL);
+ }
+
+ /* Copy the name pointers from the linked list into the vector. */
+ for (i = 0; i < count; ++i)
+ {
+ name_vector[i] = lastlink->name;
+ lastlink = lastlink->next;
+ }
+
+ name_vector[count] = NULL;
+ return (name_vector);
+}
+
+/* Return a new array which is the concatenation of each string in ARRAY
+ to DIR. This function expects you to pass in an allocated ARRAY, and
+ it takes care of free()ing that array. Thus, you might think of this
+ function as side-effecting ARRAY. */
+static char **
+glob_dir_to_array (dir, array)
+ char *dir, **array;
+{
+ register unsigned int i, l;
+ int add_slash;
+ char **result;
+
+ l = strlen (dir);
+ if (l == 0)
+ return (array);
+
+ add_slash = dir[l - 1] != '/';
+
+ i = 0;
+ while (array[i] != NULL)
+ ++i;
+
+ result = (char **) malloc ((i + 1) * sizeof (char *));
+ if (result == NULL)
+ return (NULL);
+
+ for (i = 0; array[i] != NULL; i++)
+ {
+ result[i] = (char *) malloc (l + (add_slash ? 1 : 0)
+ + strlen (array[i]) + 1);
+ if (result[i] == NULL)
+ return (NULL);
+ sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
+ }
+ result[i] = NULL;
+
+ /* Free the input array. */
+ for (i = 0; array[i] != NULL; i++)
+ free (array[i]);
+ free ((char *) array);
+
+ return (result);
+}
+
+/* Do globbing on PATHNAME. Return an array of pathnames that match,
+ marking the end of the array with a null-pointer as an element.
+ If no pathnames match, then the array is empty (first element is null).
+ If there isn't enough memory, then return NULL.
+ If a file system error occurs, return -1; `errno' has the error code. */
+char **
+glob_filename (pathname)
+ char *pathname;
+{
+ char *strrchr();
+
+ char **result;
+ unsigned int result_size;
+ char *directory_name, *filename;
+ unsigned int directory_len;
+
+ result = (char **) malloc (sizeof (char *));
+ result_size = 1;
+ if (result == NULL)
+ return (NULL);
+
+ result[0] = NULL;
+
+ /* Find the filename. */
+ filename = strrchr (pathname, '/');
+ if (filename == NULL)
+ {
+ filename = pathname;
+ directory_name = "";
+ directory_len = 0;
+ }
+ else
+ {
+ directory_len = (filename - pathname) + 1;
+ directory_name = (char *) alloca (directory_len + 1);
+
+ bcopy (pathname, directory_name, directory_len);
+ directory_name[directory_len] = '\0';
+ ++filename;
+ }
+
+ /* If directory_name contains globbing characters, then we
+ have to expand the previous levels. Just recurse. */
+ if (glob_pattern_p (directory_name))
+ {
+ char **directories;
+ register unsigned int i;
+
+ if (directory_name[directory_len - 1] == '/')
+ directory_name[directory_len - 1] = '\0';
+
+ directories = glob_filename (directory_name);
+
+ if (directories == NULL)
+ goto memory_error;
+ else if (directories == (char **)&glob_error_return)
+ return ((char **) &glob_error_return);
+ else if (*directories == NULL)
+ {
+ free ((char *) directories);
+ return ((char **) &glob_error_return);
+ }
+
+ /* We have successfully globbed the preceding directory name.
+ For each name in DIRECTORIES, call glob_vector on it and
+ FILENAME. Concatenate the results together. */
+ for (i = 0; directories[i] != NULL; ++i)
+ {
+ char **temp_results;
+
+ /* Scan directory even on a NULL pathname. That way, `*h/'
+ returns only directories ending in `h', instead of all
+ files ending in `h' with a `/' appended. */
+ temp_results = glob_vector (filename, directories[i]);
+
+ /* Handle error cases. */
+ if (temp_results == NULL)
+ goto memory_error;
+ else if (temp_results == (char **)&glob_error_return)
+ /* This filename is probably not a directory. Ignore it. */
+ ;
+ else
+ {
+ char **array;
+ register unsigned int l;
+
+ array = glob_dir_to_array (directories[i], temp_results);
+ l = 0;
+ while (array[l] != NULL)
+ ++l;
+
+ result =
+ (char **)realloc (result, (result_size + l) * sizeof (char *));
+
+ if (result == NULL)
+ goto memory_error;
+
+ for (l = 0; array[l] != NULL; ++l)
+ result[result_size++ - 1] = array[l];
+
+ result[result_size - 1] = NULL;
+
+ /* Note that the elements of ARRAY are not freed. */
+ free ((char *) array);
+ }
+ }
+ /* Free the directories. */
+ for (i = 0; directories[i]; i++)
+ free (directories[i]);
+
+ free ((char *) directories);
+
+ return (result);
+ }
+
+ /* If there is only a directory name, return it. */
+ if (*filename == '\0')
+ {
+ result = (char **) realloc ((char *) result, 2 * sizeof (char *));
+ if (result == NULL)
+ return (NULL);
+ result[0] = (char *) malloc (directory_len + 1);
+ if (result[0] == NULL)
+ goto memory_error;
+ bcopy (directory_name, result[0], directory_len + 1);
+ result[1] = NULL;
+ return (result);
+ }
+ else
+ {
+ char **temp_results;
+
+ /* There are no unquoted globbing characters in DIRECTORY_NAME.
+ Dequote it before we try to open the directory since there may
+ be quoted globbing characters which should be treated verbatim. */
+ if (directory_len > 0)
+ dequote_pathname (directory_name);
+
+ /* We allocated a small array called RESULT, which we won't be using.
+ Free that memory now. */
+ free (result);
+
+ /* Just return what glob_vector () returns appended to the
+ directory name. */
+ temp_results =
+ glob_vector (filename, (directory_len == 0 ? "." : directory_name));
+
+ if (temp_results == NULL || temp_results == (char **)&glob_error_return)
+ return (temp_results);
+
+ return (glob_dir_to_array (directory_name, temp_results));
+ }
+
+ /* We get to memory_error if the program has run out of memory, or
+ if this is the shell, and we have been interrupted. */
+ memory_error:
+ if (result != NULL)
+ {
+ register unsigned int i;
+ for (i = 0; result[i] != NULL; ++i)
+ free (result[i]);
+ free ((char *) result);
+ }
+#if defined (SHELL)
+ if (interrupt_state)
+ throw_to_top_level ();
+#endif /* SHELL */
+ return (NULL);
+}
+
+#if defined (TEST)
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ unsigned int i;
+
+ for (i = 1; i < argc; ++i)
+ {
+ char **value = glob_filename (argv[i]);
+ if (value == NULL)
+ puts ("Out of memory.");
+ else if (value == &glob_error_return)
+ perror (argv[i]);
+ else
+ for (i = 0; value[i] != NULL; i++)
+ puts (value[i]);
+ }
+
+ exit (0);
+}
+#endif /* TEST. */
diff --git a/ident.h b/ident.h
index 8047c272ca..d1b46c8381 100644
--- a/ident.h
+++ b/ident.h
@@ -3,8 +3,8 @@
ident.h -
$Author: matz $
- $Revision: 1.1.1.1 $
- $Date: 1994/06/17 14:23:49 $
+ $Revision: 1.2 $
+ $Date: 1994/08/12 04:47:29 $
created at: Mon Jan 31 16:23:19 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
diff --git a/inits.c b/inits.c
index 58d686d912..873f11bc78 100644
--- a/inits.c
+++ b/inits.c
@@ -3,7 +3,7 @@
inits.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/19 09:32:02 $
created at: Tue Dec 28 16:01:58 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -27,6 +27,7 @@ rb_call_inits()
Init_Struct();
Init_String();
Init_Regexp();
+ Init_Glob();
Init_pack();
Init_Range();
Init_IO();
diff --git a/io.c b/io.c
index 4b3c03afb8..429a1b9f3a 100644
--- a/io.c
+++ b/io.c
@@ -3,7 +3,7 @@
io.c -
$Author: matz $
- $Date: 1994/06/27 15:48:29 $
+ $Date: 1994/08/12 11:06:40 $
created at: Fri Oct 15 18:08:59 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -21,7 +21,7 @@
VALUE rb_ad_string();
-VALUE C_IO;
+VALUE C_IO, C_ARGFILE;
extern VALUE C_File;
VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout;
@@ -29,12 +29,12 @@ VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout;
VALUE FS, OFS;
VALUE RS, ORS;
-ID id_write;
+ID id_write, id_fd, id_print_on;
extern char *inplace;
/* writing functions */
-static VALUE
+VALUE
Fio_write(obj, str)
VALUE obj;
struct RString *str;
@@ -151,11 +151,11 @@ Fio_fileno(obj)
VALUE obj;
{
OpenFile *fptr;
- int f;
+ int fd;
GetOpenFile(obj, fptr);
- f = fileno(fptr->f);
- return INT2FIX(f);
+ fd = fileno(fptr->f);
+ return INT2FIX(fd);
}
/* reading functions */
@@ -178,7 +178,7 @@ read_all(port)
for (;;) {
n = fread(buf, 1, BUFSIZ, fptr->f);
if (n == 0) {
- if (feof(fptr->f)) break;
+ if (feof(fptr->f)) return Qnil;
rb_sys_fail(Qnil);
}
str_cat(str, buf, n);
@@ -219,15 +219,6 @@ Fio_read(obj, args)
return str;
}
-static void
-io_gets(str)
- VALUE str;
-{
- rb_break();
-}
-
-void rb_each();
-
VALUE rb_lastline;
static VALUE lineno;
@@ -660,12 +651,12 @@ Fprintf(argc, argv)
{
VALUE out;
- if (argc == 1) return Qnil;
- if (TYPE(argv[1]) == T_STRING) {
+ if (argc == 0) return Qnil;
+ if (TYPE(argv[0]) == T_STRING) {
out = rb_defout;
}
- else if (obj_responds_to(argv[1], INT2FIX(id_write))) {
- out = argv[1];
+ else if (obj_responds_to(argv[0], INT2FIX(id_write))) {
+ out = argv[0];
argv++;
argc--;
}
@@ -678,15 +669,6 @@ Fprintf(argc, argv)
return Qnil;
}
-static void
-obj_print(obj)
- VALUE obj;
-{
- int i;
-
- Fio_write(rb_defout, obj);
-}
-
static VALUE
Fprint(argc, argv)
int argc;
@@ -695,25 +677,32 @@ Fprint(argc, argv)
int i;
/* if no argument given, print recv */
- if (argc == 1) {
- obj_print(argv[0]);
+ if (argc == 0) {
+ rb_funcall(Qself, id_print_on, 1, rb_defout);
}
else {
- for (i=1; i<argc; i++) {
- obj_print(argv[i]);
- if (OFS && i>1) {
- obj_print(OFS);
+ for (i=0; i<argc; i++) {
+ if (OFS && i>0) {
+ Fio_write(rb_defout, OFS);
}
+ rb_funcall(argv[i], id_print_on, 1, rb_defout);
}
}
if (ORS) {
- obj_print(ORS);
+ Fio_write(rb_defout, ORS);
}
return Qnil;
}
static VALUE
+Fprint_on(obj, port)
+ VALUE obj, port;
+{
+ return Fio_write(port, obj);
+}
+
+static VALUE
prep_stdio(f, mode)
FILE *f;
int mode;
@@ -806,8 +795,7 @@ next_argv()
}
static VALUE
-Fgets(obj)
- VALUE obj;
+Fgets()
{
VALUE line;
@@ -827,8 +815,7 @@ Fgets(obj)
}
static VALUE
-Feof(obj)
- VALUE obj;
+Feof()
{
if (init_p == 0 && !next_argv())
return TRUE;
@@ -840,8 +827,7 @@ Feof(obj)
}
static VALUE
-Fgetc(obj)
- VALUE obj;
+Fgetc()
{
return Fio_getc(rb_stdin);
}
@@ -1120,14 +1106,14 @@ Fsyscall(argc, argv)
unsigned long arg[8];
#endif
int retval = -1;
- int i = 1;
- int items = argc - 2;
+ int i = 0;
+ int items = argc - 1;
/* 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)) {
@@ -1140,7 +1126,7 @@ Fsyscall(argc, argv)
}
i++;
}
- switch (argc-1) {
+ switch (argc) {
case 0:
Fail("Too few args to syscall");
case 1:
@@ -1196,12 +1182,80 @@ Fsyscall(argc, argv)
#endif /* atarist */
}
if (retval == -1) rb_sys_fail(0);
- return Qnil;
+ return INT2FIX(0);
#else
Fail("syscall() unimplemented");
#endif
}
+static VALUE
+Farg_read(obj)
+ VALUE obj;
+{
+ VALUE str, str2;
+
+ str = str_new(0, 0);
+ for (;;) {
+ retry:
+ if (!next_argv()) return Qnil;
+ str2 = Fio_read(file, Qnil);
+ if (str2 == Qnil && next_p != -1) {
+ Fio_close(file);
+ next_p = 1;
+ goto retry;
+ }
+ if (str2 == Qnil) break;
+ str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
+ }
+
+ return str;
+}
+
+static VALUE
+Farg_getc()
+{
+ VALUE byte;
+
+ retry:
+ if (!next_argv()) return Qnil;
+ byte = Fio_getc(file);
+ if (byte == Qnil && next_p != -1) {
+ Fio_close(file);
+ next_p = 1;
+ goto retry;
+ }
+
+ return byte;
+}
+
+static VALUE
+Farg_each()
+{
+ VALUE str;
+
+ while (str = Fgets()) {
+ rb_yield(str);
+ }
+ return Qnil;
+}
+
+static VALUE
+Farg_each_byte()
+{
+ VALUE byte;
+
+ while (byte = Farg_getc()) {
+ rb_yield(byte);
+ }
+ return Qnil;
+}
+
+static VALUE
+Farg_to_s()
+{
+ return str_new2("$ARGF");
+}
+
extern VALUE M_Enumerable;
VALUE rb_readonly_hook();
@@ -1209,19 +1263,25 @@ Init_IO()
{
extern VALUE C_Kernel;
+ id_write = rb_intern("write");
+ id_fd = rb_intern("fd");
+ id_print_on = rb_intern("print_on");
+
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_method(C_Kernel, "gets", Fgets, 0);
- rb_define_method(C_Kernel, "eof", Feof, 0);
rb_define_alias(C_Kernel,"readline", "gets");
+ rb_define_method(C_Kernel, "eof", Feof, 0);
rb_define_method(C_Kernel, "getc", Fgetc, 0);
rb_define_method(C_Kernel, "select", Fselect, -2);
rb_define_method(C_Kernel, "readlines", Freadlines, 0);
+ rb_define_method(C_Kernel, "print_on", Fprint_on, 1);
+
C_IO = rb_define_class("IO", C_Object);
rb_include_module(C_IO, M_Enumerable);
@@ -1245,7 +1305,9 @@ Init_IO()
rb_define_method(C_IO, "sysread", Fio_sysread, 1);
rb_define_method(C_IO, "fileno", Fio_fileno, 0);
- rb_define_method(C_IO, "sync", Fio_sync, 0);
+ rb_define_alias(C_IO, "to_i", "fileno");
+
+ rb_define_method(C_IO, "sync", Fio_sync, 0);
rb_define_method(C_IO, "sync=", Fio_set_sync, 1);
rb_define_alias(C_IO, "readlines", "to_a");
@@ -1278,6 +1340,22 @@ Init_IO()
rb_define_single_method(C_IO, "default", Fio_defget, 0);
rb_define_single_method(C_IO, "default=", Fio_defset, 1);
- id_write = rb_intern("write");
+ C_ARGFILE = rb_define_class("ARGFILE", C_Object);
+ rb_include_module(C_ARGFILE, M_Enumerable);
+
+ rb_define_variable("$ARGF", &C_ARGFILE, Qnil, rb_readonly_hook);
+
+ rb_define_single_method(C_ARGFILE, "each", Farg_each, 0);
+ rb_define_single_method(C_ARGFILE, "each_byte", Farg_each_byte, 0);
+
+ rb_define_single_method(C_ARGFILE, "read", Farg_read, 0);
+ rb_define_single_method(C_ARGFILE, "readlines", Freadlines, 0);
+ rb_define_single_method(C_ARGFILE, "gets", Fgets, 0);
+ rb_define_single_method(C_ARGFILE, "realine", Fgets, 0);
+ rb_define_single_method(C_ARGFILE, "getc", Farg_getc, 0);
+ rb_define_single_method(C_ARGFILE, "eof", Feof, 0);
+
+ rb_define_single_method(C_ARGFILE, "to_s", Farg_to_s, 0);
+
Init_File();
}
diff --git a/io.h b/io.h
index f325de3c3c..c1216598f9 100644
--- a/io.h
+++ b/io.h
@@ -3,8 +3,8 @@
io.h -
$Author: matz $
- $Revision: 1.1.1.1 $
- $Date: 1994/06/17 14:23:50 $
+ $Revision: 1.3 $
+ $Date: 1994/08/12 11:06:42 $
created at: Fri Nov 12 16:47:09 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -31,12 +31,14 @@ typedef struct {
#define FMODE_READWRITE 3
#define FMODE_SYNC 4
-#define GetOpenFile(obj,fp) Get_Data_Struct(obj, "fd", OpenFile, fp)
+extern ID id_fd;
+
+#define GetOpenFile(obj,fp) Get_Data_Struct(obj, id_fd, OpenFile, fp)
void io_free_OpenFile();
#define MakeOpenFile(obj, fp) {\
- Make_Data_Struct(obj, "fd", OpenFile, Qnil, io_free_OpenFile, fp);\
+ Make_Data_Struct(obj, id_fd, OpenFile, Qnil, io_free_OpenFile, fp);\
fp->f = fp->f2 = NULL;\
fp->mode = 0;\
fp->pid = 0;\
diff --git a/main.c b/main.c
new file mode 100644
index 0000000000..0dee01c269
--- /dev/null
+++ b/main.c
@@ -0,0 +1,17 @@
+/************************************************
+
+ main.c -
+
+ $Author: matz $
+ $Date: 1994/08/19 09:32:03 $
+ created at: Fri Aug 19 13:19:58 JST 1994
+
+************************************************/
+
+main(argc, argv, envp)
+ int argc;
+ char **argv, **envp;
+{
+ ruby_init(argc, argv, envp);
+ ruby_run();
+}
diff --git a/math.c b/math.c
index ebe14ee5c4..6beb8a61b5 100644
--- a/math.c
+++ b/math.c
@@ -3,7 +3,7 @@
math.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/12 04:47:35 $
created at: Tue Jan 25 14:12:56 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
@@ -110,13 +110,15 @@ Init_Math()
{
M_Math = rb_define_module("Math");
- rb_define_mfunc(M_Math, "atan2", Fmath_atan2, 2);
- rb_define_mfunc(M_Math, "cos", Fmath_cos, 1);
- rb_define_mfunc(M_Math, "sin", Fmath_sin, 1);
- rb_define_mfunc(M_Math, "tan", Fmath_tan, 1);
+ rb_define_method(M_Math, "atan2", Fmath_atan2, 2);
+ rb_define_method(M_Math, "cos", Fmath_cos, 1);
+ rb_define_method(M_Math, "sin", Fmath_sin, 1);
+ rb_define_method(M_Math, "tan", Fmath_tan, 1);
- rb_define_mfunc(M_Math, "exp", Fmath_exp, 1);
- rb_define_mfunc(M_Math, "log", Fmath_log, 1);
- rb_define_mfunc(M_Math, "log10", Fmath_log10, 1);
- rb_define_mfunc(M_Math, "sqrt", Fmath_sqrt, 1);
+ rb_define_method(M_Math, "exp", Fmath_exp, 1);
+ rb_define_method(M_Math, "log", Fmath_log, 1);
+ rb_define_method(M_Math, "log10", Fmath_log10, 1);
+ rb_define_method(M_Math, "sqrt", Fmath_sqrt, 1);
+
+ rb_include_module(CLASS_OF(M_Math), M_Math);
}
diff --git a/methods.c b/methods.c
deleted file mode 100644
index b085799a45..0000000000
--- a/methods.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/************************************************
-
- methods.c -
-
- $Author: matz $
- $Date: 1994/06/17 14:23:50 $
- created at: Fri Oct 1 17:25:07 JST 1993
-
- Copyright (C) 1994 Yukihiro Matsumoto
-
-************************************************/
-
-#include "ruby.h"
-#include "ident.h"
-#include "env.h"
-#include "node.h"
-#include "methods.h"
-
-void method_free();
-
-#define CACHE_SIZE 577
-#if 0
-#define EXPR1(c,m) (((int)(c)*(m))>>0)
-#else
-#define EXPR1(c,m) ((int)(c)^(m))
-#endif
-
-#define TRIAL 3
-
-struct hash_entry { /* method hash table. */
- ID mid; /* method's id */
- struct RClass *class; /* receiver's class */
- struct RClass *origin; /* where method defined */
- struct SMethod *method;
- int undef;
-};
-
-static struct hash_entry cache[CACHE_SIZE];
-
-static struct SMethod*
-search_method(class, id, origin)
- struct RClass *class, **origin;
- ID id;
-{
- struct SMethod *body;
- NODE *list;
-
- while (!st_lookup(class->m_tbl, id, &body)) {
- class = class->super;
- if (class == Qnil) return Qnil;
- }
-
- if (body->origin)
- *origin = body->origin;
- else
- *origin = class;
- return body;
-}
-
-NODE*
-rb_get_method_body(class, id, envset)
- struct RClass *class;
- ID id;
- int envset;
-{
- int pos, i;
- 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 SMethod *body;
- struct RClass *origin;
-
- if ((body = search_method(class, id, &origin)) == Qnil) {
- return Qnil;
- }
- /* store in cache */
- cache[pos].mid = id;
- cache[pos].class = class;
- cache[pos].origin = origin;
- cache[pos].method = body;
- cache[pos].undef = body->undef;
- }
-
- method = cache[pos].method;
- if (cache[pos].undef) return Qnil;
- if (envset) {
- the_env->last_func = method->id;
- the_env->last_class = cache[pos].origin;
- }
- return method->node;
-}
-
-void
-rb_alias(class, name, def)
- struct RClass *class;
- ID name, def;
-{
- struct SMethod *body;
-
- if (st_lookup(class->m_tbl, name, &body)) {
- if (verbose) {
- Warning("redefine %s", rb_id2name(name));
- }
- 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 SMethod *body;
-{
- int i;
-
- for (i = 0; i< CACHE_SIZE; i++ ) {
- if (cache[i].method == body) {
- cache[i].class = Qnil;
- cache[i].mid = Qnil;
- }
- }
-}
-
-void
-rb_clear_cache2(class)
- struct RClass *class;
-{
- int i;
-
- for (i = 0; i< CACHE_SIZE; i++ ) {
- if (cache[i].origin == class) {
- cache[i].class = Qnil;
- cache[i].mid = Qnil;
- }
- }
-}
-
-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
index 944eb8829c..dffd70197c 100644
--- a/methods.h
+++ b/methods.h
@@ -2,9 +2,9 @@
methods.h -
- $Author$
- $Revision$
- $Date$
+ $Author: matz $
+ $Revision: 1.2 $
+ $Date: 1994/08/12 04:47:38 $
created at: Fri Jul 29 14:43:03 JST 1994
************************************************/
diff --git a/missing.c b/missing.c
index ef2651ee94..cccadb494f 100644
--- a/missing.c
+++ b/missing.c
@@ -60,7 +60,7 @@ strdup(str)
tmp = xmalloc(len);
if (tmp == NULL) return NULL;
- bcopy(str, tmp, len);
+ memcpy(tmp, str, len);
return tmp;
}
diff --git a/missing/strstr.c b/missing/strstr.c
index ff28ebffd6..68f40f8260 100644
--- a/missing/strstr.c
+++ b/missing/strstr.c
@@ -14,7 +14,7 @@
*/
#ifndef lint
-static char rcsid[] = "$Header: /work/cvsroot/ruby/missing/strstr.c,v 1.1 1994/06/27 15:49:21 matz Exp $ SPRITE (Berkeley)";
+static char rcsid[] = "$Header: /usr/ext/cvsroot/ruby/missing/strstr.c,v 1.2 1994/08/12 04:48:34 matz Exp $ SPRITE (Berkeley)";
#endif /* not lint */
/*
diff --git a/node.h b/node.h
index 4f6ef4a9eb..9b9e53fb20 100644
--- a/node.h
+++ b/node.h
@@ -3,7 +3,7 @@
node.h -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/24 09:25:29 $
created at: Fri May 28 15:14:02 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -20,9 +20,9 @@ enum node_type {
NODE_IF,
NODE_CASE,
NODE_WHEN,
- NODE_UNLESS,
NODE_WHILE,
- NODE_UNTIL,
+ NODE_WHILE2,
+ NODE_EXNOT,
NODE_DO,
NODE_FOR,
NODE_PROT,
@@ -46,6 +46,7 @@ enum node_type {
NODE_CONTINUE,
NODE_RETURN,
NODE_RETRY,
+ NODE_FAIL,
NODE_YIELD,
NODE_LVAR,
NODE_GVAR,
@@ -59,6 +60,7 @@ enum node_type {
NODE_XSTR,
NODE_XSTR2,
NODE_DREGX,
+ NODE_DGLOB,
NODE_ARGS,
NODE_DEFN,
NODE_DEFS,
@@ -165,11 +167,14 @@ typedef struct node {
#define NEW_SCOPE(b) newnode(NODE_SCOPE, local_tbl(),(b),local_cnt(0))
#define NEW_BLOCK(a) newnode(NODE_BLOCK,a,Qnil,Qnil)
#define NEW_IF(c,t,e) newnode(NODE_IF,c,t,e)
-#define NEW_UNLESS(c,t,e) newnode(NODE_UNLESS,c,t,e)
+#define NEW_EXNOT(c) newnode(NODE_EXNOT,c,Qnil,Qnil)
+#define NEW_UNLESS(c,t,e) newnode(NODE_IF,NEW_EXNOT(c),t,e)
#define NEW_CASE(h,b) newnode(NODE_CASE,h,b,Qnil)
#define NEW_WHEN(c,t,e) newnode(NODE_WHEN,c,t,e)
#define NEW_WHILE(c,b) newnode(NODE_WHILE,c,b,Qnil)
-#define NEW_UNTIL(c,b) newnode(NODE_UNTIL,c,b,Qnil)
+#define NEW_UNTIL(c,b) newnode(NODE_WHILE,NEW_EXNOT(c),b,Qnil)
+#define NEW_WHILE2(c,b) newnode(NODE_WHILE2,c,b,Qnil)
+#define NEW_UNTIL2(c,b) newnode(NODE_WHILE2,NEW_EXNOT(c),b,Qnil)
#define NEW_FOR(v,i,b) newnode(NODE_FOR,v,b,i)
#define NEW_DO(v,i,b) newnode(NODE_DO,v,b,i)
#define NEW_PROT(b,ex,en) newnode(NODE_PROT,b,ex,en)
@@ -178,6 +183,7 @@ typedef struct node {
#define NEW_CONT() newnode(NODE_CONTINUE,Qnil,Qnil,Qnil)
#define NEW_RETRY() newnode(NODE_RETRY,Qnil,Qnil,Qnil)
#define NEW_RET(s) newnode(NODE_RETURN,s,Qnil,Qnil)
+#define NEW_FAIL(s) newnode(NODE_FAIL,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)
@@ -186,7 +192,7 @@ typedef struct node {
#define NEW_HASH(a) newnode(NODE_HASH,a,Qnil,Qnil)
#define NEW_AND(a,b) newnode(NODE_AND,a,b,Qnil)
#define NEW_OR(a,b) newnode(NODE_OR,a,b,Qnil)
-#define NEW_MASGN(l,val) newnode(NODE_MASGN,l,val,Qnil)
+#define NEW_MASGN(l,r) newnode(NODE_MASGN,l,r,Qnil)
#define NEW_GASGN(v,val) newnode(NODE_GASGN,v,val,rb_global_entry(v))
#define NEW_LASGN(v,val) newnode(NODE_LASGN,v,val,local_cnt(v))
#define NEW_IASGN(v,val) newnode(NODE_IASGN,v,val,Qnil)
@@ -217,7 +223,7 @@ typedef struct node {
#define NEW_NIL() newnode(NODE_NIL,Qnil,Qnil,Qnil)
NODE *newnode();
-NODE *rb_get_method_body();
+VALUE rb_method_booundp();
void freenode();
#endif
diff --git a/numeric.c b/numeric.c
index c8fcc4545b..07d3ec7d59 100644
--- a/numeric.c
+++ b/numeric.c
@@ -3,7 +3,7 @@
numeric.c -
$Author: matz $
- $Date: 1994/06/27 15:48:32 $
+ $Date: 1994/08/12 04:47:41 $
created at: Fri Aug 13 18:33:09 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -11,7 +11,6 @@
************************************************/
#include "ruby.h"
-#include "env.h"
#include <math.h>
static ID coerce;
@@ -25,12 +24,23 @@ VALUE C_Fixnum;
extern VALUE C_Range;
double big2dbl();
+VALUE
+float_new(d)
+ double d;
+{
+ NEWOBJ(flt, struct RFloat);
+ OBJSETUP(flt, C_Float, T_FLOAT);
+
+ flt->value = d;
+ return (VALUE)flt;
+}
+
static
-num_coerce_bin(this, other)
- VALUE this, other;
+num_coerce_bin(x, mid, y)
+ VALUE x, y;
+ ID mid;
{
- return rb_funcall(rb_funcall(other, coerce, 1, this),
- the_env->last_func, 1, other);
+ return rb_funcall(rb_funcall(y, coerce, 1, x), mid, 1, y);
}
static VALUE
@@ -57,6 +67,14 @@ Fnum_dot2(left, right)
}
static VALUE
+Fnum_next(num)
+ VALUE num;
+{
+ num = rb_funcall(num, rb_intern("to_i"), 0);
+ return rb_funcall(num, '+', 1, INT2FIX(1));
+}
+
+VALUE
Fnum_upto(from, to)
VALUE from, to;
{
@@ -128,8 +146,15 @@ Fnum_divmod(x, y)
{
VALUE div, mod;
- div = rb_funcall(x, '/', 1, y);
- mod = rb_funcall(x, '%', 1, y);
+ div = rb_funcall(x, '/', 1, y);
+ if (TYPE(div) == T_FLOAT) {
+ double d = floor(RFLOAT(div)->value);
+
+ if (RFLOAT(div)->value > d) {
+ div = float_new(d);
+ }
+ }
+ mod = rb_funcall(x, '%', 1, y);
return assoc_new(div, mod);
}
@@ -140,28 +165,17 @@ Fnum_is_int(num)
return FALSE;
}
-VALUE
-float_new(flt)
- double flt;
-{
- NEWOBJ(flo, struct RFloat);
- OBJSETUP(flo, C_Float, T_FLOAT);
-
- flo->value = flt;
- return (VALUE)flo;
-}
-
static VALUE
-Fflo_new(flo)
- struct RFloat *flo;
+Fflo_new(flt)
+ struct RFloat *flt;
{
- Check_Type(flo, T_FLOAT);
+ Check_Type(flt, T_FLOAT);
{
- NEWOBJ(flo2, struct RFloat);
- CLONESETUP(flo2, flo);
+ NEWOBJ(flt2, struct RFloat);
+ CLONESETUP(flt2, flt);
- flo2->value = flo->value;
- return (VALUE)flo2;
+ flt2->value = flt->value;
+ return (VALUE)flt2;
}
}
@@ -177,18 +191,18 @@ Fflo_to_s(flt)
}
static VALUE
-Fflo_coerce(this, other)
- VALUE this, other;
+Fflo_coerce(x, y)
+ VALUE x, y;
{
- switch (TYPE(other)) {
+ switch (TYPE(y)) {
case T_FIXNUM:
- return float_new((double)FIX2INT(other));
+ return float_new((double)FIX2INT(y));
case T_FLOAT:
- return other;
+ return y;
case T_BIGNUM:
- return Fbig_to_f(other);
+ return Fbig_to_f(y);
default:
- Fail("can't coerce %s to Float", rb_class2name(CLASS_OF(other)));
+ Fail("can't coerce %s to Float", rb_class2name(CLASS_OF(y)));
}
/* not reached */
return Qnil;
@@ -215,7 +229,7 @@ Fflo_plus(x, y)
case T_STRING:
return Fstr_plus(obj_as_string(x), y);
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '+', y);
}
}
@@ -231,7 +245,7 @@ Fflo_minus(x, y)
case T_FLOAT:
return float_new(x->value - y->value);
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '-', y);
}
}
@@ -249,7 +263,7 @@ Fflo_mul(x, y)
case T_STRING:
return Fstr_times(y, INT2FIX((int)x->value));
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '*', y);
}
}
@@ -273,7 +287,7 @@ Fflo_div(x, y)
if (y->value == 0.0) Fail("devided by 0");
return float_new(x->value / y->value);
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '/', y);
}
}
@@ -294,7 +308,7 @@ Fflo_mod(x, y)
value = y->value;
break;
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '%', y);
}
#ifdef HAVE_FMOD
{
@@ -324,7 +338,7 @@ Fflo_pow(x, y)
case T_FLOAT:
return float_new(pow(x->value, y->value));
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, rb_intern("**"), y);
}
}
@@ -343,7 +357,7 @@ Fflo_eq(x, y)
case T_FLOAT:
return (x->value == y->value)?TRUE:FALSE;
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, rb_intern("=="), y);
}
}
@@ -385,7 +399,7 @@ Fflo_cmp(x, y)
break;
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, rb_intern("<=>"), y);
}
if (a == b) return INT2FIX(0);
if (a > b) return INT2FIX(1);
@@ -430,6 +444,20 @@ Fflo_abs(flt)
return float_new(val);
}
+static VALUE
+to_integer(val)
+ VALUE val;
+{
+ return rb_funcall(val, to_i, 0);
+}
+
+static VALUE
+fail_to_integer(val)
+ VALUE val;
+{
+ Fail("failed to convert %s into integer", rb_class2name(CLASS_OF(val)));
+}
+
int
num2int(val)
VALUE val;
@@ -444,7 +472,7 @@ num2int(val)
case T_FLOAT:
if (RFLOAT(val)->value <= (double) LONG_MAX
&& RFLOAT(val)->value >= (double) LONG_MIN) {
- return (int)RFLOAT(val)->value;
+ return (int)(RFLOAT(val)->value);
}
else {
Fail("float %g out of rang of integer", RFLOAT(val)->value);
@@ -455,25 +483,11 @@ num2int(val)
return big2int(val);
default:
- Fail("failed to convert %s into int", rb_class2name(CLASS_OF(val)));
- break;
+ val = rb_resque(to_integer, val, fail_to_integer, val);
+ return NUM2INT(val);
}
}
-static VALUE
-to_fixnum(val)
- VALUE val;
-{
- return rb_funcall(val, to_i, 0);
-}
-
-static VALUE
-fail_to_fixnum(val)
- VALUE val;
-{
- Fail("failed to convert %s into fixnum", rb_class2name(CLASS_OF(val)));
-}
-
VALUE
num2fix(val)
VALUE val;
@@ -487,13 +501,11 @@ num2fix(val)
case T_FLOAT:
case T_BIGNUM:
+ default:
v = num2int(val);
if (!FIXABLE(v))
Fail("integer %d out of rang of Fixnum", v);
return INT2FIX(v);
-
- default:
- return rb_resque(to_fixnum, val, fail_to_fixnum, val);
}
}
@@ -579,7 +591,7 @@ Ffix_plus(x, y)
case T_FLOAT:
return float_new((double)FIX2INT(x) + y->value);
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '+', y);
}
}
@@ -607,7 +619,7 @@ Ffix_minus(x, y)
case T_FLOAT:
return float_new((double)FIX2INT(x) - y->value);
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '-', y);
}
}
@@ -631,7 +643,7 @@ Ffix_mul(x, y)
case T_FLOAT:
return float_new((double)FIX2INT(x) * y->value);
default:
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '*', y);
}
}
@@ -648,7 +660,7 @@ Ffix_div(x, y)
i = FIX2INT(x)/i;
return INT2FIX(i);
}
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '/', y);
}
static VALUE
@@ -663,7 +675,7 @@ Ffix_mod(x, y)
i = FIX2INT(x)%i;
return INT2FIX(i);
}
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, '%', y);
}
static VALUE
@@ -686,7 +698,7 @@ Ffix_pow(x, y)
else if (NIL_P(y)) {
return INT2FIX(1);
}
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, rb_intern("**"), y);
}
static VALUE
@@ -700,7 +712,7 @@ Ffix_equal(x, y)
return Qnil;
}
else {
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, rb_intern("=="), y);
}
}
@@ -716,7 +728,7 @@ Ffix_cmp(x, y)
return INT2FIX(-1);
}
else {
- return num_coerce_bin(x, y);
+ return num_coerce_bin(x, rb_intern("<=>"), y);
}
}
@@ -861,6 +873,15 @@ Ffix_id2name(fix)
return Qnil;
}
+static VALUE
+Ffix_next(fix)
+ VALUE fix;
+{
+ int i = FIX2INT(fix) + 1;
+
+ return int2inum(i);
+}
+
extern VALUE M_Comparable;
extern Fkrn_inspect();
@@ -874,7 +895,9 @@ Init_Numeric()
rb_define_method(C_Numeric, "+@", Fnum_uplus, 0);
rb_define_method(C_Numeric, "-@", Fnum_uminus, 0);
rb_define_method(C_Numeric, "..", Fnum_dot2, 1);
+ rb_define_method(C_Numeric, "divmod", Fnum_divmod, 1);
+ rb_define_method(C_Numeric, "next", Fnum_next, 0);
rb_define_method(C_Numeric, "upto", Fnum_upto, 1);
rb_define_method(C_Numeric, "downto", Fnum_downto, 1);
rb_define_method(C_Numeric, "step", Fnum_step, 2);
@@ -919,6 +942,8 @@ Init_Numeric()
rb_define_method(C_Fixnum, "to_i", Ffix_to_i, 0);
rb_define_method(C_Fixnum, "to_f", Ffix_to_f, 0);
+ rb_define_method(C_Fixnum, "next", Ffix_next, 0);
+
C_Float = rb_define_class("Float", C_Numeric);
rb_define_single_method(C_Float, "new", Fflo_new, 1);
rb_define_method(C_Float, "clone", Fflo_clone, 0);
diff --git a/object.c b/object.c
index 25e33422cb..53a9e30a02 100644
--- a/object.c
+++ b/object.c
@@ -3,7 +3,7 @@
object.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/12 04:47:42 $
created at: Thu Jul 15 12:01:24 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -27,7 +27,6 @@ VALUE C_Method;
struct st_table *new_idhash();
VALUE Fsprintf();
-VALUE Ffail();
VALUE Fexit();
VALUE Feval();
VALUE Fapply();
@@ -274,6 +273,13 @@ Fmain_to_s(obj)
return str_new2("main");
}
+static VALUE
+Ftrue_to_s(obj)
+ VALUE obj;
+{
+ return str_new2("t");
+}
+
VALUE
obj_alloc(class)
VALUE class;
@@ -335,6 +341,7 @@ static VALUE boot_defclass(name, super)
}
VALUE TopSelf;
+VALUE TRUE = 1;
Init_Object()
{
@@ -351,31 +358,33 @@ Init_Object()
metaclass = RBASIC(C_Class)->class = single_class_new(metaclass);
/*
+ * Ruby's Class Hierarchy Chart
+ *
* +-------nil +---------------------+
* | ^ | |
* | | | |
* | Kernel----->(Kernel) |
* | ^ ^ ^ ^ |
* | | | | | |
- * | +---+ +-----+ | +---+ |
- * | | +------|---+ | |
- * | | | | | |
+ * | +---+ +----+ | +---+ |
+ * | | +-----|----+ | |
+ * | | | | | |
* +->Nil->(Nil) Object---->(Object) |
- * ^ ^ ^ ^ |
- * | | | | |
- * | | +-------+ | |
- * | | | | |
- * | +---------+ +------+ |
- * | | | | |
- * +--------+ | Module--->(Module) |
+ * ^ ^ ^ ^ |
+ * | | | | |
+ * | | +-------+ | |
+ * | | | | |
+ * | +---------+ +------+ |
+ * | | | | |
+ * +---------+ | Module--->(Module) |
* | | ^ ^ |
* OtherClass-->(OtherClass) | | |
* Class---->(Class) |
- * ^ |
- * | |
- * +-----+
+ * ^ |
+ * | |
+ * +----------------+
*
- * + all metaclasses are instance of class Class
+ * + All metaclasses are instances of the class `Class'.
*/
rb_define_method(C_Kernel, "is_nil", P_false, 0);
@@ -393,8 +402,9 @@ Init_Object()
rb_define_method(C_Kernel, "to_s", Fkrn_to_s, 0);
rb_define_method(C_Kernel, "_inspect", Fkrn_inspect, 0);
+#ifdef USE_CALLER
rb_define_method(C_Kernel, "caller", Fcaller, -2);
- rb_define_method(C_Kernel, "fail", Ffail, -2);
+#endif
rb_define_method(C_Kernel, "exit", Fexit, -2);
rb_define_method(C_Kernel, "eval", Feval, 1);
rb_define_method(C_Kernel, "defined", Fdefined, 1);
@@ -404,9 +414,6 @@ Init_Object()
rb_define_method(C_Kernel, "apply", Fapply, -2);
- rb_define_const(C_Kernel, "%TRUE", TRUE);
- rb_define_const(C_Kernel, "%FALSE", FALSE);
-
rb_define_method(C_Object, "_inspect", Fobj_inspect, 0);
rb_define_method(C_Object, "responds_to", obj_responds_to, 1);
@@ -443,4 +450,10 @@ Init_Object()
Qself = TopSelf = obj_alloc(C_Object);
rb_define_single_method(TopSelf, "to_s", Fmain_to_s, 0);
+
+ TRUE = obj_alloc(C_Object);
+ rb_define_single_method(TRUE, "to_s", Ftrue_to_s, 0);
+ rb_define_const(C_Kernel, "%TRUE", TRUE);
+ rb_define_const(C_Kernel, "%FALSE", FALSE);
}
+
diff --git a/pack.c b/pack.c
index 6adc0a6b43..ded70be1ee 100644
--- a/pack.c
+++ b/pack.c
@@ -3,7 +3,7 @@
pack.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/12 04:47:44 $
created at: Thu Feb 10 15:17:05 JST 1994
Copyright (C) 1994 Yukihiro Matsumoto
@@ -76,7 +76,7 @@ Fpck_pack(ary, fmt)
type = *p++; /* get data type */
if (*p == '*') { /* set data length */
- len = index("@Xxu", type) ? 0 : items;
+ len = strchr("@Xxu", type) ? 0 : items;
p++;
}
else if (isdigit(*p)) {
@@ -773,13 +773,15 @@ Fpck_unpack(str, fmt)
{
VALUE str = str_new(0, (send - s)*3/4);
char *ptr = RSTRING(str)->ptr;
+ int total = 0;
while (s < send && *s > ' ' && *s < 'a') {
- int a,b,c,d;
+ long a,b,c,d;
char hunk[4];
hunk[3] = '\0';
len = (*s++ - ' ') & 077;
+ total += len;
while (len > 0) {
if (s < send && *s >= ' ')
a = (*s++ - ' ') & 077;
@@ -804,11 +806,12 @@ Fpck_unpack(str, fmt)
ptr += 3;
len -= 3;
}
- if (s[0] == '\n')
+ if (*s == '\n')
s++;
else if (s[1] == '\n') /* possible checksum byte */
s += 2;
}
+ RSTRING(str)->len = total;
Fary_push(ary, str);
}
break;
diff --git a/parse.y b/parse.y
index ff1a7f669d..74774d86c7 100644
--- a/parse.y
+++ b/parse.y
@@ -3,7 +3,7 @@
parse.y -
$Author: matz $
- $Date: 1994/06/27 15:48:34 $
+ $Date: 1994/08/25 09:21:07 $
created at: Fri May 28 18:02:42 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -34,19 +34,18 @@ 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. */
+static int yylex();
+
+static enum lex_state {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_MID, /* newline significant, +/- is a sign. */
- EXPR_END, /* +/- is a operator. newline significant */
-};
-
-static int lex_state;
+ EXPR_END, /* newline significant, +/- is a operator. */
+ EXPR_FNAME, /* ignore newline, +/- is a operator. */
+} lex_state;
static ID cur_class = Qnil, cur_mid = Qnil;
static int in_module, in_single;
@@ -59,6 +58,7 @@ static NODE *block_append();
static NODE *list_append();
static NODE *list_concat();
static NODE *list_copy();
+static NODE *expand_op();
static NODE *call_op();
static NODE *gettable();
@@ -100,8 +100,6 @@ static void setup_top_local();
WHILE
FOR
IN
- DO
- USING
PROTECT
RESQUE
ENSURE
@@ -110,6 +108,7 @@ static void setup_top_local();
BREAK
CONTINUE
RETURN
+ FAIL
YIELD
SUPER
RETRY
@@ -117,20 +116,24 @@ static void setup_top_local();
NIL
_FILE_
_LINE_
+ IF_MOD
+ UNLESS_MOD
+ WHILE_MOD
+ UNTIL_MOD
%token <id> IDENTIFIER GVAR IVAR CONSTANT
-%token <val> INTEGER FLOAT STRING XSTRING REGEXP
-%token <node> STRING2 XSTRING2 DREGEXP
+%token <val> INTEGER FLOAT STRING XSTRING REGEXP GLOB
+%token <node> STRING2 XSTRING2 DREGEXP DGLOB
%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 regexp
-%type <node> mlhs mlhs_head mlhs_tail lhs
+%type <node> compstmts stmts stmt stmt0 expr expr0 var_ref
+%type <node> if_tail opt_else cases resque ensure
+%type <node> call_args call_args0 opt_args args args2
+%type <node> f_arglist f_args f_arg assoc_list assocs assoc
+%type <node> mlhs mlhs_head mlhs_tail lhs iter_var opt_iter_var
%type <id> superclass variable symbol
-%type <id> fname fname0 op rest_arg end_mark
+%type <id> fname fname0 op rest_arg
%token UPLUS /* unary+ */
%token UMINUS /* unary- */
@@ -148,12 +151,13 @@ static void setup_top_local();
%token COLON2 /* :: */
%token <id> SELF_ASGN /* +=, -= etc. */
%token ASSOC /* => */
+%token LPAREN LBRACK LBRACE
/*
* precedence table
*/
-%left YIELD RETURN
+%left YIELD RETURN FAIL
%right '=' SELF_ASGN
%right COLON2
%nonassoc DOT2 DOT3
@@ -176,42 +180,43 @@ program : {
lex_state = EXPR_BEG;
init_top_local();
}
- compexpr
+ compstmts
{
eval_tree = block_append(eval_tree, $2);
setup_top_local();
}
-compexpr : exprs opt_term
+compstmts : stmts opt_term
-exprs : /* none */
+stmts : /* none */
{
$$ = Qnil;
}
- | expr
- | exprs term expr
+ | stmt
+ | stmts term stmt
{
$$ = block_append($1, $3);
}
- | exprs error expr
+ | stmts error
+ {
+ lex_state = EXPR_BEG;
+ }
+ stmt
{
yyerrok;
- $$ = $1;
+ $$ = block_append($1, $4);
}
-expr : CLASS IDENTIFIER superclass
+stmt : CLASS IDENTIFIER superclass
{
if (cur_class || cur_mid || in_single)
Error("nested class definition");
cur_class = $2;
push_local();
}
- compexpr
- END end_mark
+ compstmts
+ END
{
- if ($7 && $7 != CLASS) {
- Error("unmatched end keyword(expected `class')");
- }
$$ = NEW_CLASS($2, $5, $3);
pop_local();
cur_class = Qnil;
@@ -224,12 +229,9 @@ expr : CLASS IDENTIFIER superclass
in_module = 1;
push_local();
}
- compexpr
- END end_mark
+ compstmts
+ END
{
- if ($6 && $6 != MODULE) {
- Error("unmatched end keyword(expected `module')");
- }
$$ = NEW_MODULE($2, $4);
pop_local();
cur_class = Qnil;
@@ -242,12 +244,9 @@ expr : CLASS IDENTIFIER superclass
cur_mid = $2;
push_local();
}
- f_arglist compexpr
- END end_mark
+ f_arglist compstmts
+ END
{
- if ($7 && $7 != DEF) {
- Error("unmatched end keyword(expected `def')");
- }
$$ = NEW_DEFN($2, NEW_RFUNC($4, $5));
pop_local();
cur_mid = Qnil;
@@ -259,12 +258,9 @@ expr : CLASS IDENTIFIER superclass
push_local();
}
f_arglist
- compexpr
- END end_mark
+ compstmts
+ END
{
- if ($9 && $9 != DEF) {
- Error("unmatched end keyword(expected `def')");
- }
$$ = NEW_DEFS($2, $4, NEW_RFUNC($6, $7));
pop_local();
in_single--;
@@ -283,40 +279,113 @@ expr : CLASS IDENTIFIER superclass
Error("include appeared in method definition");
$$ = $2;
}
- | mlhs '=' args
+ | stmt0 IF_MOD stmt0
{
- NODE *rhs;
-
- if ($3->nd_next == Qnil) {
- rhs = $3->nd_head;
- free($3);
- }
- else {
- rhs = $3;
- }
-
- $$ = NEW_MASGN($1, rhs);
+ $$ = NEW_IF(cond($3), $1, Qnil);
+ }
+ | stmt0 UNLESS_MOD stmt0
+ {
+ $$ = NEW_UNLESS(cond($3), $1, Qnil);
}
- | expr2
+ | stmt0 WHILE_MOD stmt0
+ {
+ $$ = NEW_WHILE2(cond($3), $1);
+ }
+ | stmt0 UNTIL_MOD stmt0
+ {
+ $$ = NEW_UNTIL2(cond($3), $1);
+ }
+ | stmt0
+stmt0 : mlhs '=' args2
+ {
+ $1->nd_value = $3;
+ $$ = $1;
+ }
+ | REDO
+ {
+ $$ = NEW_REDO();
+ }
+ | BREAK
+ {
+ $$ = NEW_BREAK();
+ }
+ | CONTINUE
+ {
+ $$ = NEW_CONT();
+ }
+ | RETRY
+ {
+ $$ = NEW_RETRY();
+ }
+ | RETURN args2
+ {
+ value_expr($2);
+ if (!cur_mid && !in_single)
+ Error("return appeared outside of method");
+ $$ = NEW_RET($2);
+ }
+ | RETURN
+ {
+ if (!cur_mid && !in_single)
+ Error("return appeared outside of method");
+ $$ = NEW_RET(Qnil);
+ }
+ | FAIL args2
+ {
+ value_expr($2);
+ $$ = NEW_FAIL($2);
+ }
+ | YIELD args2
+ {
+ value_expr($2);
+ $$ = NEW_YIELD($2);
+ }
+ | IDENTIFIER call_args0
+ {
+ $$ = NEW_CALL(Qnil, $1, $2);
+ }
+ | expr0 '.' IDENTIFIER call_args0
+ {
+ value_expr($1);
+ $$ = NEW_CALL($1, $3, $4);
+ }
+ | SUPER call_args0
+ {
+ if (!cur_mid && !in_single)
+ Error("super called outside of method");
+ $$ = NEW_SUPER($2);
+ }
+ | expr
mlhs : mlhs_head
+ {
+ $$ = NEW_MASGN(NEW_LIST($1),Qnil);
+ }
+ | mlhs_head '*' lhs
+ {
+ $$ = NEW_MASGN(NEW_LIST($1),$3);
+ }
| mlhs_head mlhs_tail
{
- $$ = list_concat($1, $2);
+ $$ = NEW_MASGN(list_concat(NEW_LIST($1),$2),Qnil);
+ }
+ | mlhs_head mlhs_tail comma '*' lhs
+ {
+ $$ = NEW_MASGN(list_concat(NEW_LIST($1),$2),$5);
}
mlhs_head : variable comma
{
- $$ = NEW_LIST(asignable($1, Qnil));
+ $$ = asignable($1, Qnil);
}
- | primary '[' args rbracket comma
+ | expr0 '[' args rbracket comma
{
- $$ = NEW_LIST(aryset($1, $3, Qnil));
+ $$ = aryset($1, $3, Qnil);
}
- | primary '.' IDENTIFIER comma
+ | expr0 '.' IDENTIFIER comma
{
- $$ = NEW_LIST(attrset($1, $3, Qnil));
+ $$ = attrset($1, $3, Qnil);
}
mlhs_tail : lhs
@@ -332,11 +401,11 @@ lhs : variable
{
$$ = asignable($1, Qnil);
}
- | primary '[' args rbracket
+ | expr0 '[' args rbracket
{
$$ = aryset($1, $3, Qnil);
}
- | primary '.' IDENTIFIER
+ | expr0 '.' IDENTIFIER
{
$$ = attrset($1, $3, Qnil);
}
@@ -360,23 +429,24 @@ inc_list : IDENTIFIER
}
| error
{
+ lex_state = EXPR_BEG;
$$ = Qnil;
}
| inc_list comma error
+ {
+ lex_state = EXPR_BEG;
+ $$ = $1;
+ }
fname : fname0
| IVAR
fname0 : IDENTIFIER
- | IDENTIFIER '='
+ | op
{
- ID id = $1;
-
- id &= ~ID_SCOPE_MASK;
- id |= ID_ATTRSET;
- $$ = id;
+ lex_state = EXPR_END;
+ $$ = $1;
}
- | op
op : COLON2 { $$ = COLON2; }
| DOT2 { $$ = DOT2; }
@@ -402,12 +472,10 @@ op : COLON2 { $$ = COLON2; }
| POW { $$ = POW; }
| '!' { $$ = '!'; }
| '~' { $$ = '~'; }
- | '!' '@' { $$ = '!'; }
- | '~' '@' { $$ = '~'; }
- | '-' '@' { $$ = UMINUS; }
- | '+' '@' { $$ = UPLUS; }
- | '[' ']' { $$ = AREF; }
- | '[' ']' '=' { $$ = ASET; }
+ | UPLUS { $$ = UMINUS; }
+ | UMINUS { $$ = UPLUS; }
+ | AREF { $$ = AREF; }
+ | ASET { $$ = ASET; }
f_arglist : '(' f_args rparen
{
@@ -444,10 +512,12 @@ f_args : /* no arg */
}
| f_arg error
{
+ lex_state = EXPR_BEG;
$$ = NEW_ARGS($1, -1);
}
| error
{
+ lex_state = EXPR_BEG;
$$ = Qnil;
}
@@ -485,7 +555,7 @@ singleton : var_ref
$$ = $1;
}
}
- | '(' compexpr rparen
+ | LPAREN compstmts rparen
{
switch ($2->type) {
case NODE_STR:
@@ -499,130 +569,22 @@ singleton : var_ref
$$ = $2;
}
-expr2 : IF expr2 then
- compexpr
- if_tail
- END end_mark
- {
- if ($7 && $7 != IF) {
- Error("unmatched end keyword(expected `if')");
- }
- $$ = NEW_IF(cond($2), $4, $5);
- }
- | UNLESS expr2 then
- compexpr opt_else END end_mark
- {
- if ($7 && $7 != UNLESS) {
- Error("unmatched end keyword(expected `if')");
- }
- $$ = NEW_UNLESS(cond($2), $4, $5);
- }
- | CASE expr2 opt_term
- cases
- END end_mark
- {
- if ($6 && $6 != CASE) {
- Error("unmatched end keyword(expected `case')");
- }
- value_expr($2);
- $$ = NEW_CASE($2, $4);
- }
- | WHILE expr2 term compexpr END end_mark
- {
- if ($6 && $6 != WHILE) {
- Error("unmatched end keyword(expected `while')");
- }
- $$ = NEW_WHILE(cond($2), $4);
- }
- | UNTIL expr2 term compexpr END end_mark
- {
- if ($6 && $6 != UNTIL) {
- Error("unmatched end keyword(expected `until')");
- }
- $$ = NEW_UNTIL(cond($2), $4);
- }
- | FOR lhs IN expr2 term
- compexpr
- END end_mark
- {
- if ($8 && $8 != FOR) {
- Error("unmatched end keyword(expected `for')");
- }
- value_expr($4);
- $$ = NEW_FOR($2, $4, $6);
- }
- | DO expr2 opt_using
- compexpr
- END end_mark
- {
- if ($6 && $6 != DO) {
- Error("unmatched end keyword(expected `do')");
- }
- value_expr($2);
- $$ = NEW_DO($3, $2, $4);
- }
- | PROTECT
- compexpr
- resque
- ensure
- END end_mark
- {
- if ($6 && $6 != PROTECT) {
- Error("unmatched end keyword(expected `protect')");
- }
- if ($3 == Qnil && $4 == Qnil) {
- Warning("useless protect clause");
- $$ = $2;
- }
- else {
- $$ = NEW_PROT($2, $3, $4);
- }
- }
- | REDO
- {
- $$ = NEW_REDO();
- }
- | BREAK
- {
- $$ = NEW_BREAK();
- }
- | CONTINUE
- {
- $$ = NEW_CONT();
- }
- | RETRY
- {
- $$ = NEW_RETRY();
- }
- | RETURN expr2
- {
- value_expr($2);
- if (!cur_mid && !in_single)
- Error("return appeared outside of method");
- $$ = NEW_RET($2);
- }
- | RETURN
- {
- if (!cur_mid && !in_single)
- Error("return appeared outside of method");
- $$ = NEW_RET(Qnil);
- }
- | variable '=' expr2
+expr : variable '=' expr
{
value_expr($3);
$$ = asignable($1, $3);
}
- | primary '[' args rbracket '=' expr2
+ | expr0 '[' args rbracket '=' expr
{
value_expr($6);
$$ = aryset($1, $3, $6);
}
- | primary '.' IDENTIFIER '=' expr2
+ | expr0 '.' IDENTIFIER '=' expr
{
value_expr($5);
$$ = attrset($1, $3, $5);
}
- | variable SELF_ASGN expr2
+ | variable SELF_ASGN expr
{
NODE *val;
@@ -641,7 +603,7 @@ expr2 : IF expr2 then
}
$$ = asignable($1, call_op(val, $2, 1, $3));
}
- | primary '[' args rbracket SELF_ASGN expr2
+ | expr0 '[' args rbracket SELF_ASGN expr
{
NODE *rval, *args;
value_expr($1);
@@ -653,7 +615,7 @@ expr2 : IF expr2 then
args = list_append($3, call_op(rval, $5, 1, $6));
$$ = NEW_CALL($1, ASET, args);
}
- | primary '.' IDENTIFIER SELF_ASGN expr2
+ | expr0 '.' IDENTIFIER SELF_ASGN expr
{
ID id = $3;
NODE *rval;
@@ -667,202 +629,163 @@ expr2 : IF expr2 then
rval = call_op(NEW_CALL2($1, $3, Qnil), $4, 1, $5);
$$ = NEW_CALL($1, id, NEW_LIST(rval));
}
- | YIELD expr2
- {
- value_expr($2);
- $$ = NEW_YIELD($2);
- }
- | expr2 DOT2 expr2
+ | expr DOT2 expr
{
$$ = call_op($1, DOT2, 1, $3);
}
- | expr2 DOT3 expr2
+ | expr DOT3 expr
{
$$ = NEW_DOT3(cond2($1), cond2($3));
}
- | expr2 '+' expr2
+ | expr '+' expr
{
- $$ = call_op($1, '+', 1, $3);
+ $$ = Qnil;
+ if ($1 && $3
+ && ($3->type == NODE_LIT || $3->type == NODE_STR)
+ && $1->type == NODE_CALL && $1->nd_mid == '+') {
+ if ($1->nd_args->nd_head == Qnil)
+ Bug("bad operand for `+'");
+ if ($1->nd_args->nd_head->type == NODE_LIT
+ || $1->nd_args->nd_head->type == NODE_STR) {
+ $1->nd_args->nd_head =
+ expand_op($1->nd_args->nd_head, '+', $3);
+ $$ = $1;
+ }
+ }
+ if ($$ == Qnil) {
+ $$ = call_op($1, '+', 1, $3);
+ }
}
- | expr2 '-' expr2
+ | expr '-' expr
{
$$ = call_op($1, '-', 1, $3);
}
- | expr2 '*' expr2
+ | expr '*' expr
{
$$ = call_op($1, '*', 1, $3);
}
- | expr2 '/' expr2
+ | expr '/' expr
{
$$ = call_op($1, '/', 1, $3);
}
- | expr2 '%' expr2
+ | expr '%' expr
{
$$ = call_op($1, '%', 1, $3);
}
- | expr2 POW expr2
+ | expr POW expr
{
$$ = call_op($1, POW, 1, $3);
}
- | '+' expr2 %prec UPLUS
+ | UPLUS expr
{
$$ = call_op($2, UPLUS, 0);
-
}
- | '-' expr2 %prec UMINUS
+ | UMINUS expr
{
$$ = call_op($2, UMINUS, 0);
}
- | expr2 '|' expr2
+ | expr '|' expr
{
$$ = call_op($1, '|', 1, $3);
}
- | expr2 '^' expr2
+ | expr '^' expr
{
$$ = call_op($1, '^', 1, $3);
}
- | expr2 '&' expr2
+ | expr '&' expr
{
$$ = call_op($1, '&', 1, $3);
}
- | expr2 CMP expr2
+ | expr CMP expr
{
$$ = call_op($1, CMP, 1, $3);
}
- | expr2 '>' expr2
+ | expr '>' expr
{
$$ = call_op($1, '>', 1, $3);
}
- | expr2 GEQ expr2
+ | expr GEQ expr
{
$$ = call_op($1, GEQ, 1, $3);
}
- | expr2 '<' expr2
+ | expr '<' expr
{
$$ = call_op($1, '<', 1, $3);
}
- | expr2 LEQ expr2
+ | expr LEQ expr
{
$$ = call_op($1, LEQ, 1, $3);
}
- | expr2 EQ expr2
+ | expr EQ expr
{
$$ = call_op($1, EQ, 1, $3);
}
- | expr2 NEQ expr2
+ | expr NEQ expr
{
$$ = call_op($1, NEQ, 1, $3);
}
- | expr2 MATCH expr2
+ | expr MATCH expr
{
$$ = call_op($1, MATCH, 1, $3);
}
- | expr2 NMATCH expr2
+ | expr NMATCH expr
{
$$ = call_op($1, NMATCH, 1, $3);
}
- | '!' expr2
+ | '!' expr
{
- $$ = call_op(cond($2), '!', 0);
+ $$ = call_op($2, '!', 0);
}
- | '~' expr2
+ | '~' expr
{
- $$ = call_op($2, '~', 0);
+ if ($2
+ && ($2->type == NODE_STR
+ || ($2->type == NODE_LIT
+ && (TYPE($2->nd_lit) == T_REGEXP
+ || TYPE($2->nd_lit) == T_STRING)))) {
+ $$ = NEW_CALL($2, '~', Qnil);
+ }
+ else {
+ $$ = call_op($2, '~', 0);
+ }
}
- | expr2 LSHFT expr2
+ | expr LSHFT expr
{
$$ = call_op($1, LSHFT, 1, $3);
}
- | expr2 RSHFT expr2
+ | expr RSHFT expr
{
$$ = call_op($1, RSHFT, 1, $3);
}
- | expr2 COLON2 expr2
+ | expr COLON2 expr
{
$$ = call_op($1, COLON2, 1, $3);
}
- | expr2 AND expr2
+ | expr AND expr
{
- $$ = NEW_AND(cond($1), cond($3));
+ $$ = NEW_AND($1, $3);
}
- | expr2 OR expr2
+ | expr OR expr
{
- $$ = NEW_OR(cond($1), cond($3));
+ $$ = NEW_OR($1, $3);
}
- |primary
+ |expr0
{
$$ = $1;
}
-then : term
- | THEN
- | term THEN
-
-if_tail : opt_else
- | ELSIF expr2 then
- compexpr
- if_tail
- {
- $$ = NEW_IF(cond($2), $4, $5);
- }
-
-opt_else : /* none */
- {
- $$ = Qnil;
- }
- | ELSE compexpr
- {
- $$ = $2;
- }
-
-opt_using : term
- {
- $$ = Qnil;
- }
- | opt_term USING lhs term
- {
- $$ = $3;
- }
-
-cases : opt_else
- | WHEN args term
- compexpr
- cases
- {
- $$ = NEW_WHEN($2, $4, $5);
- }
-
-resque : /* none */
- {
- $$ = Qnil;
- }
- | RESQUE compexpr
- {
- if ($2 == Qnil)
- $$ = (NODE*)1;
- else
- $$ = $2;
- }
-
-ensure : /* none */
- {
- $$ = Qnil;
- }
- | ENSURE compexpr
- {
- $$ = $2;
- }
-
call_args : /* none */
{
$$ = Qnil;
}
- | args
- | '*' exprs
+ | call_args0
+ | '*' expr
{
$$ = $2;
}
- | args comma '*' exprs
+
+call_args0 : args
+ | args comma '*' expr
{
$$ = call_op($1, '+', 1, $4);
}
@@ -873,19 +796,31 @@ opt_args : /* none */
}
| args
-args : expr2
+args : expr
{
value_expr($1);
$$ = NEW_LIST($1);
}
- | args comma expr2
+ | args comma expr
{
value_expr($3);
$$ = list_append($1, $3);
}
-primary : var_ref
- | literal
+args2 : args
+ {
+ NODE *rhs;
+
+ if ($1 && $1->nd_next == Qnil) {
+ $$ = $1->nd_head;
+ free($1);
+ }
+ else {
+ $$ = $1;
+ }
+ }
+
+expr0 : literal
{
literalize($1);
$$ = NEW_LIT($1);
@@ -902,16 +837,36 @@ primary : var_ref
$$ = NEW_XSTR($1);
}
| XSTRING2
- | '/' {in_regexp = 1;} regexp
+ | DREGEXP
+ | DGLOB
+ | var_ref
+ | IDENTIFIER '(' call_args rparen
+ {
+ $$ = NEW_CALL(Qnil, $1, $3);
+ }
+ | IVAR '(' call_args rparen
+ {
+ $$ = NEW_CALL(Qnil, $1, $3);
+ }
+ | SUPER '(' call_args rparen
+ {
+ if (!cur_mid && !in_single)
+ Error("super called outside of method");
+ $$ = NEW_SUPER($3);
+ }
+ | SUPER
{
- $$ = $3;
+ if (!cur_mid && !in_single)
+ Error("super called outside of method");
+ $$ = NEW_ZSUPER();
}
- | primary '[' args rbracket
+
+ | expr0 '[' args rbracket
{
value_expr($1);
$$ = NEW_CALL($1, AREF, $3);
}
- | '[' opt_args rbracket
+ | LBRACK opt_args rbracket
{
if ($2 == Qnil)
$$ = NEW_ZARRAY(); /* zero length array*/
@@ -919,41 +874,158 @@ primary : var_ref
$$ = $2;
}
}
- | lbrace assoc_list rbrace
+ | LBRACE assoc_list rbrace
{
$$ = NEW_HASH($2);
}
- | primary '.' IDENTIFIER '(' call_args rparen
+ | FAIL '(' args2 ')'
+ {
+ value_expr($3);
+ $$ = NEW_FAIL($3);
+ }
+ | FAIL '(' ')'
+ {
+ $$ = NEW_FAIL(Qnil);
+ }
+ | FAIL
+ {
+ $$ = NEW_FAIL(Qnil);
+ }
+ | YIELD '(' args2 ')'
+ {
+ value_expr($3);
+ $$ = NEW_YIELD($3);
+ }
+ | YIELD '(' ')'
+ {
+ $$ = NEW_YIELD(Qnil);
+ }
+ | YIELD
+ {
+ $$ = NEW_YIELD(Qnil);
+ }
+ | expr0 lbrace opt_iter_var '|' compstmts rbrace
+ {
+ $$ = NEW_DO($3, $1, $5);
+ }
+ | expr0 '.' IDENTIFIER '(' call_args rparen
{
value_expr($1);
$$ = NEW_CALL($1, $3, $5);
}
- | primary '.' IDENTIFIER
+ | expr0 '.' IDENTIFIER
{
value_expr($1);
$$ = NEW_CALL($1, $3, Qnil);
}
- | IDENTIFIER '(' call_args rparen
+ | IF stmt0 then
+ compstmts
+ if_tail
+ END
{
- $$ = NEW_CALL(Qnil, $1, $3);
+ $$ = NEW_IF(cond($2), $4, $5);
}
- | IVAR '(' call_args rparen
+ | UNLESS stmt0 then
+ compstmts opt_else END
{
- $$ = NEW_CALL(Qnil, $1, $3);
+ $$ = NEW_UNLESS(cond($2), $4, $5);
}
- | SUPER '(' call_args rparen
+ | WHILE stmt0 term compstmts END
{
- if (!cur_mid && !in_single)
- Error("super called outside of method");
- $$ = NEW_SUPER($3);
+ $$ = NEW_WHILE(cond($2), $4);
}
- | SUPER
+ | UNTIL stmt0 term compstmts END
{
- if (!cur_mid && !in_single)
- Error("super called outside of method");
- $$ = NEW_ZSUPER();
+ $$ = NEW_UNTIL(cond($2), $4);
+ }
+ | CASE stmt0 opt_term
+ cases
+ END
+ {
+ value_expr($2);
+ $$ = NEW_CASE($2, $4);
+ }
+ | FOR iter_var IN stmt0 term
+ compstmts
+ END
+ {
+ value_expr($4);
+ $$ = NEW_FOR($2, $4, $6);
+ }
+ | PROTECT
+ compstmts
+ resque
+ ensure
+ END
+ {
+ if ($3 == Qnil && $4 == Qnil) {
+ Warning("useless protect clause");
+ $$ = $2;
+ }
+ else {
+ $$ = NEW_PROT($2, $3, $4);
+ }
}
- | '(' compexpr rparen
+ | LPAREN compstmts rparen
+ {
+ $$ = $2;
+ }
+
+then : term
+ | THEN
+ | term THEN
+
+if_tail : opt_else
+ | ELSIF stmt0 then
+ compstmts
+ if_tail
+ {
+ $$ = NEW_IF(cond($2), $4, $5);
+ }
+
+opt_else : /* none */
+ {
+ $$ = Qnil;
+ }
+ | ELSE compstmts
+ {
+ $$ = $2;
+ }
+
+iter_var : lhs
+ | mlhs
+
+opt_iter_var : /* none */
+ {
+ $$ = Qnil;
+ }
+ | iter_var
+
+cases : opt_else
+ | WHEN args term
+ compstmts
+ cases
+ {
+ $$ = NEW_WHEN($2, $4, $5);
+ }
+
+resque : /* none */
+ {
+ $$ = Qnil;
+ }
+ | RESQUE compstmts
+ {
+ if ($2 == Qnil)
+ $$ = (NODE*)1;
+ else
+ $$ = $2;
+ }
+
+ensure : /* none */
+ {
+ $$ = Qnil;
+ }
+ | ENSURE compstmts
{
$$ = $2;
}
@@ -963,13 +1035,9 @@ literal : numeric
{
$$ = INT2FIX($2);
}
+ | REGEXP
+ | GLOB
-regexp : REGEXP
- {
- literalize($1);
- $$ = NEW_LIT($1);
- }
- | DREGEXP
symbol : fname0
| IVAR
@@ -1009,24 +1077,12 @@ assocs : assoc
$$ = list_concat($1, $3);
}
-assoc : expr2 ASSOC expr2
+assoc : expr ASSOC expr
{
$$ = NEW_LIST($1);
$$ = list_append($$, $3);
}
-end_mark : CLASS { $$ = CLASS; }
- | MODULE { $$ = MODULE; }
- | DEF { $$ = DEF; }
- | IF { $$ = IF; }
- | UNLESS { $$ = UNLESS; }
- | CASE { $$ = CASE; }
- | WHILE { $$ = WHILE; }
- | UNTIL { $$ = UNTIL; }
- | FOR { $$ = FOR; }
- | DO { $$ = DO; }
- | PROTECT { $$ = PROTECT; }
- | { $$ = Qnil;}
opt_term : /* none */
| term
@@ -1039,7 +1095,7 @@ nl : '\n' { yyerrok; }
rparen : ')' { yyerrok; }
rbracket : ']' { yyerrok; }
-lbrace : '{' { yyerrok; }
+lbrace : '{'
rbrace : '}' { yyerrok; }
comma : ',' { yyerrok; }
%%
@@ -1053,8 +1109,6 @@ comma : ',' { yyerrok; }
static char *tokenbuf = NULL;
static int tokidx, toksiz = 0;
-char *xmalloc();
-char *xrealloc();
VALUE newregexp();
VALUE newstring();
VALUE newfloat();
@@ -1070,6 +1124,7 @@ static void read_escape();
static char *lex_p;
static int lex_len;
+void
lex_setsrc(src, ptr, len)
char *src;
char *ptr;
@@ -1115,33 +1170,182 @@ tokadd(c)
tokenbuf[tokidx++] = c;
}
+static int
+parse_regx()
+{
+ register int c;
+ int in_brack = 0;
+ int re_start = sourceline;
+ NODE *list = Qnil;
+
+ newtok();
+ while (c = nextc()) {
+ switch (c) {
+ case '[':
+ in_brack = 1;
+ break;
+ 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;
+ Error("unterminated regexp meets end of file");
+ return 0;
+ }
+ else if (c == '\n') {
+ sourceline++;
+ }
+ else if (in_brack && c == 'b') {
+ tokadd('\b');
+ }
+ else if (isdigit(c)) {
+ tokadd('\\');
+ tokadd(c);
+ }
+ else {
+ pushback();
+ read_escape(LEAVE_BS);
+ }
+ continue;
+
+ case '/': /* end of the regexp */
+ if (in_brack)
+ break;
+
+ tokfix();
+ lex_state = EXPR_END;
+ 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");
+ return 0;
+
+ default:
+ if (ismbchar(c)) {
+ tokadd(c);
+ c = nextc();
+ }
+ break;
+ }
+ tokadd(c);
+ }
+}
+
+static int
+parse_string(term)
+ int term;
+{
+ int c;
+ NODE *list = Qnil;
+ ID id;
+ int strstart;
+
+ strstart = sourceline;
+ newtok();
+ while ((c = nextc()) != term) {
+ if (c == -1) {
+ unterm_str:
+ sourceline = strstart;
+ Error("unterminated string meets end of file");
+ return 0;
+ }
+ if (ismbchar(c)) {
+ tokadd(c);
+ c = nextc();
+ }
+ else if (c == '\n') {
+ sourceline++;
+ }
+ else if (c == '#') {
+ list = var_extend(list, term);
+ if (list == (NODE*)-1) goto unterm_str;
+ continue;
+ }
+ else if (c == '\\') {
+ c = nextc();
+ if (c == '\n') {
+ sourceline++;
+ }
+ else if (c == term) {
+ tokadd(c);
+ }
+ else {
+ pushback();
+ read_escape(LEAVE_BS | EXPAND_B);
+ }
+ continue;
+ }
+ tokadd(c);
+ }
+ tokfix();
+ lex_state = EXPR_END;
+ if (list == Qnil) {
+ yylval.val = str_new(tok(), toklen());
+ return (term == '`') ? XSTRING : STRING;
+ }
+ else {
+ if (toklen() > 0) {
+ VALUE ss = str_new(tok(), toklen());
+ literalize(ss);
+ list_append(list, NEW_STR(ss));
+ }
+ yylval.node = list;
+ if (term == '`') {
+ list->type = NODE_XSTR2;
+ return XSTRING2;
+ }
+ else {
+ return STRING2;
+ }
+ }
+}
+
#define LAST(v) ((v)-1 + sizeof(v)/sizeof(v[0]))
static struct kwtable {
char *name;
int id;
- int state;
+ enum lex_state state;
} kwtable [] = {
- "__END__", 0, KEEP_STATE,
+ "__END__", 0, EXPR_BEG,
"__FILE__", _FILE_, EXPR_END,
"__LINE__", _LINE_, EXPR_END,
"break", BREAK, EXPR_END,
- "case", CASE, KEEP_STATE,
- "class", CLASS, KEEP_STATE,
+ "case", CASE, EXPR_BEG,
+ "class", CLASS, EXPR_BEG,
"continue", CONTINUE, EXPR_END,
- "def", DEF, KEEP_STATE,
- "do", DO, KEEP_STATE,
+ "def", DEF, EXPR_FNAME,
"else", ELSE, EXPR_BEG,
"elsif", ELSIF, EXPR_BEG,
"end", END, EXPR_END,
"ensure", ENSURE, EXPR_BEG,
- "for", FOR, KEEP_STATE,
- "if", IF, KEEP_STATE,
+ "fail", FAIL, EXPR_END,
+ "for", FOR, EXPR_BEG,
+ "if", IF, EXPR_BEG,
"in", IN, EXPR_BEG,
"include", INCLUDE, EXPR_BEG,
- "module", MODULE, KEEP_STATE,
+ "module", MODULE, EXPR_BEG,
"nil", NIL, EXPR_END,
- "protect", PROTECT, KEEP_STATE,
+ "protect", PROTECT, EXPR_BEG,
"redo", REDO, EXPR_END,
"resque", RESQUE, EXPR_BEG,
"retry", RETRY, EXPR_END,
@@ -1152,95 +1356,18 @@ static struct kwtable {
"undef", UNDEF, EXPR_BEG,
"unless", UNLESS, EXPR_BEG,
"until", UNTIL, EXPR_BEG,
- "using", USING, KEEP_STATE,
"when", WHEN, EXPR_BEG,
- "while", WHILE, KEEP_STATE,
- "yield", YIELD, EXPR_BEG,
+ "while", WHILE, EXPR_BEG,
+ "yield", YIELD, EXPR_END,
};
-static int strstart;
-
+static int
yylex()
{
register int c;
struct kwtable *low = kwtable, *mid, *high = LAST(kwtable);
int last;
- if (in_regexp) {
- int in_brack = 0;
- int re_start = sourceline;
- NODE *list = Qnil;
-
- in_regexp = 0;
- newtok();
- while (c = nextc()) {
- switch (c) {
- case '[':
- in_brack = 1;
- break;
- 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;
- Error("unterminated regexp meets end of file");
- return 0;
- }
- else if (c == '\n') {
- sourceline++;
- }
- else if (in_brack && c == 'b') {
- tokadd('\b');
- }
- else {
- pushback();
- read_escape(LEAVE_BS);
- }
- continue;
-
- case '/': /* end of the regexp */
- if (in_brack)
- break;
-
- tokfix();
- lex_state = EXPR_END;
- 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");
- return 0;
-
- default:
- if (ismbchar(c)) {
- tokadd(c);
- c = nextc();
- }
- break;
- }
- tokadd(c);
- }
- }
-
retry:
switch (c = nextc()) {
case '\0':
@@ -1251,6 +1378,7 @@ retry:
/* white spaces */
case ' ': case '\t': case '\f': case '\r':
+ case '\13': /* '\v' */
goto retry;
case '#': /* it's a comment */
@@ -1261,7 +1389,8 @@ retry:
/* fall through */
case '\n':
sourceline++;
- if (lex_state == EXPR_BEG) goto retry;
+ if (lex_state == EXPR_BEG || lex_state == EXPR_FNAME)
+ goto retry;
lex_state = EXPR_BEG;
return '\n';
@@ -1283,6 +1412,13 @@ retry:
return '*';
case '!':
+ if (lex_state == EXPR_FNAME) {
+ if ((c = nextc()) == '@') {
+ lex_state = EXPR_BEG;
+ return '!';
+ }
+ pushback();
+ }
lex_state = EXPR_BEG;
if ((c = nextc()) == '=') {
return NEQ;
@@ -1308,6 +1444,14 @@ retry:
return '=';
case '<':
+ if (lex_state == EXPR_BEG) {
+ if (parse_string('>') == STRING) {
+ yylval.val = glob_new(yylval.val);
+ return GLOB;
+ }
+ yylval.node->type = NODE_DGLOB;
+ return DGLOB;
+ }
lex_state = EXPR_BEG;
if ((c = nextc()) == '=') {
if ((c = nextc()) == '>') {
@@ -1345,16 +1489,16 @@ retry:
case '"':
case '`':
+ return parse_string(c);
+
+ case '\'':
{
- char term = c;
- NODE *list = Qnil;
- ID id;
+ int strstart;
strstart = sourceline;
newtok();
- while ((c = nextc()) != term) {
- if (c == -1) {
- unterm_str:
+ while ((c = nextc()) != '\'') {
+ if (c == -1) {
sourceline = strstart;
Error("unterminated string meets end of file");
return 0;
@@ -1366,63 +1510,6 @@ 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 == term) {
- tokadd(c);
- }
- else {
- pushback();
- read_escape(LEAVE_BS | EXPAND_B);
- }
- continue;
- }
- tokadd(c);
- }
- tokfix();
- lex_state = EXPR_END;
- 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 '\'':
- {
- strstart = sourceline;
- newtok();
- while ((c = nextc()) != '\'') {
- if (c == -1) goto unterm_str;
- if (ismbchar(c)) {
- tokadd(c);
- c = nextc();
- }
- else if (c == '\n') {
- sourceline++;
- }
else if (c == '\\') {
c = nextc();
switch (c) {
@@ -1491,6 +1578,15 @@ retry:
if (isdigit(c)) {
goto start_num;
}
+ lex_state = EXPR_BEG;
+ return UPLUS;
+ }
+ else if (lex_state == EXPR_FNAME) {
+ if ((c = nextc()) == '@') {
+ return UPLUS;
+ }
+ pushback();
+ return '+';
}
lex_state = EXPR_BEG;
if ((c = nextc()) == '=') {
@@ -1508,6 +1604,15 @@ retry:
c = '-';
goto start_num;
}
+ lex_state = EXPR_BEG;
+ return UMINUS;
+ }
+ else if (lex_state == EXPR_FNAME) {
+ if ((c = nextc()) == '@') {
+ return UMINUS;
+ }
+ pushback();
+ return '-';
}
lex_state = EXPR_BEG;
if ((c = nextc()) == '=') {
@@ -1518,17 +1623,16 @@ retry:
return '-';
case '.':
+ lex_state = EXPR_BEG;
if ((c = nextc()) == '.') {
if ((c = nextc()) == '.') {
return DOT3;
}
pushback();
- lex_state = EXPR_BEG;
return DOT2;
}
pushback();
if (!isdigit(c)) {
- lex_state = EXPR_BEG;
return '.';
}
c = '.';
@@ -1563,11 +1667,7 @@ retry:
} while (c >= '0' && c <= '9');
pushback();
tokfix();
-#if 0
- yylval.val = INT2FIX(strtoul(tok(), Qnil, 8));
-#else
yylval.val = str2inum(tok(), 8);
-#endif
return INTEGER;
}
}
@@ -1651,6 +1751,9 @@ retry:
return ':';
case '/':
+ if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
+ return parse_regx();
+ }
lex_state = EXPR_BEG;
if (nextc() == '=') {
yylval.id = '/';
@@ -1670,17 +1773,52 @@ retry:
case ',':
case ';':
- case '[':
+ lex_state = EXPR_BEG;
+ return c;
+
+ case '~':
+ if (lex_state == EXPR_FNAME) {
+ if ((c = nextc()) != '@') {
+ pushback();
+ }
+ }
+ lex_state = EXPR_BEG;
+ return c;
+
case '(':
+ if (lex_state != EXPR_END)
+ c = LPAREN;
+ lex_state = EXPR_BEG;
+ return c;
+
+ case '[':
+
+ if (lex_state == EXPR_BEG || lex_state == EXPR_MID)
+ c = LBRACK;
+ else if (lex_state == EXPR_FNAME) {
+ if ((c = nextc()) == ']') {
+ if ((c = nextc()) == '=') {
+ return ASET;
+ }
+ pushback();
+ return AREF;
+ }
+ pushback();
+ return '[';
+ }
+ lex_state = EXPR_BEG;
+ return c;
+
case '{':
- case '~':
+ if (lex_state != EXPR_END)
+ c = LBRACE;
lex_state = EXPR_BEG;
return c;
case '\\':
c = nextc();
if (c == '\n') goto retry; /* skip \\n */
- lex_state = EXPR_BEG;
+ lex_state = EXPR_FNAME;
pushback();
return '\\';
@@ -1767,8 +1905,13 @@ retry:
while (low <= high) {
mid = low + (high - low)/2;
if (( c = strcmp(mid->name, tok())) == 0) {
- if (mid->state != KEEP_STATE) {
- lex_state = mid->state;
+ enum lex_state state = lex_state;
+ lex_state = mid->state;
+ if (state != EXPR_BEG) {
+ if (mid->id == IF) return IF_MOD;
+ if (mid->id == UNLESS) return UNLESS_MOD;
+ if (mid->id == WHILE) return WHILE_MOD;
+ if (mid->id == UNTIL) return UNTIL_MOD;
}
return mid->id;
}
@@ -1781,17 +1924,30 @@ retry:
}
id_fetch:
- lex_state = EXPR_END;
- yylval.id = rb_intern(tok());
- switch (tok()[0]) {
- case '%':
- return CONSTANT;
- case '$':
- return GVAR;
- case '@':
- return IVAR;
- default:
- return IDENTIFIER;
+ {
+ enum lex_state state = lex_state;
+
+ lex_state = EXPR_END;
+ yylval.id = rb_intern(tok());
+ switch (tok()[0]) {
+ case '%':
+ return CONSTANT;
+ case '$':
+ return GVAR;
+ case '@':
+ return IVAR;
+ default:
+ if (state == EXPR_FNAME) {
+ if ((c = nextc()) == '=') {
+ yylval.id &= ~ID_SCOPE_MASK;
+ yylval.id |= ID_ATTRSET;
+ }
+ else {
+ pushback();
+ }
+ }
+ return IDENTIFIER;
+ }
}
}
@@ -1836,9 +1992,6 @@ var_extend(list, term)
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)) {
@@ -1858,7 +2011,7 @@ var_extend(list, term)
case '$':
tokadd(c);
c = nextc();
- if (c == -1) goto unterm_str;
+ if (c == -1) return (NODE*)-1;
if (!is_identchar(c)) {
tokadd(c);
goto fetch_id;
@@ -1994,7 +2147,7 @@ read_escape(flag)
i *= 16;
i += c - '0';
}
- else if ((int)index("abcdefABCDEF", (c = nextc()))) {
+ else if ((int)strchr("abcdefABCDEF", (c = nextc()))) {
i *= 16;
i += toupper(c) - 'A' + 10;
}
@@ -2139,14 +2292,17 @@ void freenode(node)
case NODE_STR2:
case NODE_XSTR2:
case NODE_DREGX:
+ case NODE_DGLOB:
case NODE_QLIST:
freenode(node->nd_next);
break;
case NODE_HASH:
freenode(node->nd_head);
break;
+ case NODE_EXNOT:
+ freenode(node->nd_cond);
+ break;
case NODE_IF:
- case NODE_UNLESS:
case NODE_WHEN:
case NODE_PROT:
freenode(node->nd_cond);
@@ -2155,7 +2311,7 @@ void freenode(node)
break;
case NODE_CASE:
case NODE_WHILE:
- case NODE_UNTIL:
+ case NODE_WHILE2:
case NODE_AND:
case NODE_OR:
freenode(node->nd_head);
@@ -2176,6 +2332,7 @@ void freenode(node)
case NODE_MASGN:
freenode(node->nd_value);
freenode(node->nd_head);
+ freenode(node->nd_args);
break;
case NODE_CALL:
case NODE_SUPER:
@@ -2199,6 +2356,7 @@ void freenode(node)
break;
case NODE_RETURN:
case NODE_YIELD:
+ case NODE_FAIL:
freenode(node->nd_stts);
break;
case NODE_STR:
@@ -2221,9 +2379,11 @@ void freenode(node)
case NODE_MODULE:
freenode(node->nd_body);
break;
+ case NODE_CONST:
+ unliteralize(node->nd_cval);
+ break;
case NODE_ATTRSET:
case NODE_CVAR:
- case NODE_CONST:
case NODE_ZSUPER:
case NODE_ZARRAY:
case NODE_CFUNC:
@@ -2272,44 +2432,49 @@ except_lit()
}
static NODE *
+expand_op(recv, id, arg)
+ NODE *recv, *arg;
+ ID id;
+{
+ struct call_arg arg_data;
+ VALUE val;
+ NODE *result;
+
+ arg_data.recv = recv->nd_lit;
+ arg_data.id = id;
+ arg_data.narg = arg?1:0;
+ arg_data.arg = arg->nd_lit;
+
+ val = rb_resque(call_lit, &arg_data, except_lit, Qnil);
+ if (TYPE(val) == T_STRING) {
+ result = NEW_STR(val);
+ }
+ else {
+ result = NEW_LIT(val);
+ }
+
+ freenode(recv);
+ if (arg) freenode(arg);
+ return result;
+}
+
+static NODE *
call_op(recv, id, narg, arg1)
NODE *recv;
ID id;
int narg;
NODE *arg1;
{
- NODE *args;
-
value_expr(recv);
- if (narg == 1)
+ if (narg == 1) {
value_expr(arg1);
-
- if (recv->type != NODE_LIT || recv->type != NODE_STR
- || (narg == 0 && id == '~'
- && (TYPE(recv->nd_lit)==T_REGEXP || TYPE(recv->nd_lit)==T_STRING))
- || arg1->type == NODE_LIT || arg1->type == NODE_STR) {
- if (narg > 0) {
- args = NEW_ARRAY(arg1);
- args->nd_argc = 1;
- }
- else {
- args = Qnil;
- }
- return NEW_CALL(recv, id, args);
}
- else {
- struct call_arg arg_data;
- NODE *result;
-
- arg_data.recv = recv->nd_lit;
- arg_data.id = id;
- arg_data.narg = narg;
- if (narg == 1) arg_data.arg = arg1->nd_lit;
- result = NEW_LIT(rb_resque(call_lit, &arg_data, except_lit, Qnil));
- freenode(recv);
- if (narg == 1) freenode(arg1);
- return result;
+
+ if ((recv->type == NODE_LIT || recv->type == NODE_STR)
+ && (narg == 0 || (arg1->type == NODE_LIT || arg1->type == NODE_STR))) {
+ return expand_op(recv, id, (narg == 1)?arg1:Qnil);
}
+ return NEW_CALL(recv, id, narg==1?NEW_LIST(arg1):Qnil);
}
static NODE*
@@ -2390,8 +2555,6 @@ static NODE *
aryset(recv, idx, val)
NODE *recv, *idx, *val;
{
- NODE *args;
-
value_expr(recv);
return NEW_CALL(recv, ASET, list_append(idx, val));
}
@@ -2413,18 +2576,25 @@ static void
value_expr(node)
NODE *node;
{
+ if (node == Qnil) return;
+
switch (node->type) {
case NODE_RETURN:
case NODE_CONTINUE:
case NODE_BREAK:
case NODE_REDO:
case NODE_RETRY:
+ case NODE_WHILE:
+ case NODE_WHILE2:
+ case NODE_INC:
+ case NODE_CLASS:
+ case NODE_MODULE:
Error("void value expression");
break;
case NODE_BLOCK:
if (node->nd_last)
- return value_expr(node->nd_last->nd_head);
+ value_expr(node->nd_last->nd_head);
break;
default:
@@ -2433,28 +2603,49 @@ value_expr(node)
}
static NODE*
-cond(node)
+cond0(node)
NODE *node;
{
- value_expr(node);
- if (node->type == NODE_STR) {
+ enum node_type type = node->type;
+
+ if (type == NODE_STR || type == NODE_STR2 || type == NODE_DREGX) {
return call_op(NEW_GVAR(rb_intern("$_")),MATCH,1,node);
}
- else if (node->type == NODE_LIT && TYPE(node->nd_lit) == T_REGEXP) {
+ else if (type == NODE_LIT && TYPE(node->nd_lit) == T_REGEXP) {
return call_op(node,MATCH,1,NEW_GVAR(rb_intern("$_")));
}
return node;
}
static NODE*
+cond(node)
+ NODE *node;
+{
+ enum node_type type = node->type;
+
+ value_expr(node);
+
+ node = cond0(node);
+ if (type == NODE_AND || type == NODE_OR) {
+ node->nd_1st = cond(node->nd_1st);
+ node->nd_2nd = cond(node->nd_2nd);
+ }
+ else if (type == NODE_CALL && node->nd_mid == '!') {
+ if (node->nd_args || node->nd_recv == Qnil) {
+ Bug("method `!' called with wrong # of operand");
+ }
+ node->nd_recv = cond0(node->nd_recv);
+ }
+ return node;
+}
+
+static NODE*
cond2(node)
NODE *node;
{
node = cond(node);
- if (node->type == NODE_LIT) {
- if (FIXNUM_P(node->nd_lit)) {
- return call_op(node,EQ,1,NEW_GVAR(rb_intern("$.")));
- }
+ if (node->type == NODE_LIT && FIXNUM_P(node->nd_lit)) {
+ return call_op(node,EQ,1,NEW_GVAR(rb_intern("$.")));
}
return node;
}
@@ -2550,15 +2741,21 @@ setup_top_local()
if (lvtbl->cnt > 0) {
if (the_env->local_vars == Qnil) {
the_env->local_vars = ALLOC_N(VALUE, lvtbl->cnt);
- bzero(the_env->local_vars, lvtbl->cnt * sizeof(VALUE));
+ memset(the_env->local_vars, 0, lvtbl->cnt * sizeof(VALUE));
}
else if (lvtbl->tbl[0] < lvtbl->cnt) {
int i;
- REALLOC_N(the_env->local_vars, VALUE, lvtbl->cnt);
- for (i=lvtbl->tbl[0]; i<lvtbl->cnt; i++) {
- the_env->local_vars[i] = Qnil;
+ if (the_env->flags&VARS_MALLOCED) {
+ REALLOC_N(the_env->local_vars, VALUE, lvtbl->cnt);
+ }
+ else {
+ VALUE *vars = the_env->local_vars;
+ the_env->local_vars = ALLOC_N(VALUE, lvtbl->cnt);
+ memcpy(the_env->local_vars, vars, sizeof(VALUE)*lvtbl->cnt);
+ the_env->flags |= VARS_MALLOCED;
}
+ memset(the_env->local_vars+i, 0, lvtbl->cnt-i);
}
lvtbl->tbl[0] = lvtbl->cnt;
the_env->local_tbl = lvtbl->tbl;
diff --git a/process.c b/process.c
index 8032524710..96fb4ce132 100644
--- a/process.c
+++ b/process.c
@@ -3,7 +3,7 @@
process.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/12 04:47:47 $
created at: Tue Aug 10 14:30:50 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -84,6 +84,8 @@ static int wait_status;
static wait_each(key, value)
int key, value;
{
+ if (wait_status != -1) return ST_STOP;
+
wait_pid = key;
wait_status = value;
return ST_DELETE;
@@ -135,7 +137,7 @@ rb_proc_exec(str)
char **argv, **a;
for (s=str; *s; s++) {
- if (*s != ' ' && !isalpha(*s) && index("*?{}[]<>()~&|\\$;'`\"\n",*s)) {
+ if (*s != ' ' && !isalpha(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) {
execl("/bin/sh", "sh", "-c", str, (char *)NULL);
return -1;
}
@@ -173,10 +175,10 @@ Ffork(obj)
switch (pid = fork()) {
case 0:
- return Qnil;
+ return INT2FIX(0);
case -1:
- rb_sys_fail(Qnil);
+ rb_sys_fail("fork(2)");
break;
default:
@@ -410,18 +412,18 @@ Fkill(argc, argv)
int sig;
int i;
- if (argc < 3)
+ if (argc < 2)
Fail("wrong # of arguments -- kill(sig, pid...)");
- switch (TYPE(argv[1])) {
+ switch (TYPE(argv[0])) {
case T_FIXNUM:
- sig = FIX2UINT(argv[1]);
+ sig = FIX2UINT(argv[0]);
break;
case T_STRING:
{
int negative = 0;
- char *s = RSTRING(argv[1])->ptr;
+ char *s = RSTRING(argv[0])->ptr;
if (*s == '-') {
negative++;
s++;
@@ -437,13 +439,13 @@ Fkill(argc, argv)
break;
default:
- Fail("bad signal type %s", rb_class2name(CLASS_OF(argv[1])));
+ Fail("bad signal type %s", rb_class2name(CLASS_OF(argv[0])));
break;
}
if (sig < 0) {
sig = -sig;
- for (i=2; i<argc; i++) {
+ for (i=1; i<argc; i++) {
int pid = NUM2INT(argv[i]);
#ifdef HAS_KILLPG
if (killpg(pid, sig) < 0)
@@ -454,13 +456,13 @@ Fkill(argc, argv)
}
}
else {
- for (i=2; i<argc; i++) {
+ for (i=1; i<argc; i++) {
Check_Type(argv[i], T_FIXNUM);
if (kill(FIX2UINT(argv[i]), sig) < 0)
rb_sys_fail(Qnil);
}
}
- return INT2FIX(i-2);
+ return INT2FIX(i-1);
}
static VALUE trap_list[NSIG];
@@ -601,39 +603,48 @@ Ftrap(argc, argv)
RETSIGTYPE (*func)();
VALUE command;
int i, sig;
+#ifdef HAVE_SIGPROCMASK
+ sigset_t mask;
+#else
int mask;
+#endif
- if (argc < 3)
+ if (argc < 2)
Fail("wrong # of arguments -- kill(cmd, sig...)");
/* disable interrupt */
+#ifdef HAVE_SIGPROCMASK
+ sigfillset(&mask);
+ sigprocmask(SIG_BLOCK, &mask, &mask);
+#else
mask = sigblock(~0);
+#endif
func = sighandle;
- if (argv[1] == Qnil) {
+ if (argv[0] == Qnil) {
func = SIG_IGN;
command = Qnil;
}
else {
- Check_Type(argv[1], T_STRING);
- command = argv[1];
- if (RSTRING(argv[1])->len == 0) {
+ Check_Type(argv[0], T_STRING);
+ command = argv[0];
+ if (RSTRING(argv[0])->len == 0) {
func = SIG_IGN;
}
- else if (RSTRING(argv[1])->len == 7) {
- if (strncmp(RSTRING(argv[1])->ptr, "SIG_IGN", 7) == 0) {
+ else if (RSTRING(argv[0])->len == 7) {
+ if (strncmp(RSTRING(argv[0])->ptr, "SIG_IGN", 7) == 0) {
func = SIG_IGN;
}
- else if (strncmp(RSTRING(argv[1])->ptr, "SIG_DFL", 7) == 0) {
+ else if (strncmp(RSTRING(argv[0])->ptr, "SIG_DFL", 7) == 0) {
func = SIG_DFL;
}
- else if (strncmp(RSTRING(argv[1])->ptr, "DEFAULT", 7) == 0) {
+ else if (strncmp(RSTRING(argv[0])->ptr, "DEFAULT", 7) == 0) {
func = SIG_DFL;
}
}
- else if (RSTRING(argv[1])->len == 6) {
- if (strncmp(RSTRING(argv[1])->ptr, "IGNORE", 6) == 0) {
+ else if (RSTRING(argv[0])->len == 6) {
+ if (strncmp(RSTRING(argv[0])->ptr, "IGNORE", 6) == 0) {
func = SIG_IGN;
}
}
@@ -641,7 +652,7 @@ Ftrap(argc, argv)
if (func == SIG_IGN || func == SIG_DFL)
command = Qnil;
- for (i=2; i<argc; i++) {
+ for (i=1; i<argc; i++) {
if (TYPE(argv[i]) == T_STRING) {
char *s = RSTRING(argv[i])->ptr;
@@ -654,15 +665,24 @@ Ftrap(argc, argv)
else {
sig = NUM2INT(argv[i]);
}
- if (i < 0 || i > NSIG)
+ if (sig < 0 || sig > NSIG)
Fail("Invalid signal no %d", sig);
signal(sig, sighandle);
trap_list[sig] = command;
/* enable at least specified signal. */
+#ifdef HAVE_SIGPROCMASK
+ sigdelset(&mask, sig);
+#else
mask &= ~sigmask(sig);
+#endif
}
+ /* disable interrupt */
+#ifdef HAVE_SIGPROCMASK
+ sigprocmask(SIG_SETMASK, &mask, NULL);
+#else
sigsetmask(mask);
+#endif
return Qnil;
}
@@ -676,8 +696,8 @@ Fsleep(argc, argv)
if (argc == 1) {
sleep((32767<<16)+32767);
}
- else if (argc == 2) {
- sleep(NUM2INT(argv[1]));
+ else if (argc == 1) {
+ sleep(NUM2INT(argv[0]));
}
else {
Fail("wrong # of arguments");
@@ -718,13 +738,14 @@ Fproc_setpgrp(obj, pid, pgrp)
if (getpgrp(ipid, ipgrp) == -1) rb_sys_fail(Qnil);
- return Qnil;
+ return INT2FIX(0);
}
static VALUE
Fproc_getpriority(obj, which, who)
VALUE obj, which, who;
{
+#ifdef HAVE_GETPRIORITY
int prio, iwhich, iwho;
iwhich = NUM2INT(which);
@@ -733,12 +754,16 @@ Fproc_getpriority(obj, which, who)
prio = getpriority(iwhich, iwho);
if (prio == -1) rb_sys_fail(Qnil);
return INT2FIX(prio);
+#else
+ Fail("The getpriority() function is unimplemented on this machine");
+#endif
}
static VALUE
Fproc_setpriority(obj, which, who, prio)
VALUE obj, which, who, prio;
{
+#ifdef HAVE_GETPRIORITY
int iwhich, iwho, iprio;
iwhich = NUM2INT(which);
@@ -747,7 +772,10 @@ Fproc_setpriority(obj, which, who, prio)
if (setpriority(iwhich, iwho, iprio) == -1)
rb_sys_fail(Qnil);
- return Qnil;
+ return INT2FIX(0);
+#else
+ Fail("The setpriority() function is unimplemented on this machine");
+#endif
}
static VALUE
@@ -826,14 +854,14 @@ Init_process()
rb_define_single_method(M_Process, "waitpid", Fwaitpid, 2);
rb_define_single_method(M_Process, "kill", Fkill, -1);
- rb_define_mfunc(M_Process, "pid", get_pid, 0);
- rb_define_mfunc(M_Process, "ppid", get_ppid, 0);
+ rb_define_method(M_Process, "pid", get_pid, 0);
+ rb_define_method(M_Process, "ppid", get_ppid, 0);
- rb_define_mfunc(M_Process, "getpgrp", Fproc_getpgrp, -2);
- rb_define_mfunc(M_Process, "setpgrp", Fproc_setpgrp, 2);
+ rb_define_method(M_Process, "getpgrp", Fproc_getpgrp, -2);
+ rb_define_method(M_Process, "setpgrp", Fproc_setpgrp, 2);
- rb_define_mfunc(M_Process, "getpriority", Fproc_getpriority, 2);
- rb_define_mfunc(M_Process, "setpriority", Fproc_setpriority, 3);
+ rb_define_method(M_Process, "getpriority", Fproc_getpriority, 2);
+ rb_define_method(M_Process, "setpriority", Fproc_setpriority, 3);
rb_define_const(M_Process, "%PRIO_PROCESS", INT2FIX(PRIO_PROCESS));
rb_define_const(M_Process, "%PRIO_PGRP", INT2FIX(PRIO_PGRP));
@@ -847,4 +875,6 @@ Init_process()
rb_define_method(M_Process, "euid", Fproc_geteuid, 0);
rb_define_single_method(M_Process, "euid=", Fproc_seteuid, 1);
rb_define_method(M_Process, "euid=", Fproc_seteuid, 1);
+
+ rb_include_module(CLASS_OF(M_Process), M_Process);
}
diff --git a/random.c b/random.c
index eaccbab6d7..85fa7b4643 100644
--- a/random.c
+++ b/random.c
@@ -3,7 +3,7 @@
random.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/12 04:47:48 $
created at: Fri Dec 24 16:39:21 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
diff --git a/range.c b/range.c
index 70e0d4943c..0e464c0bc2 100644
--- a/range.c
+++ b/range.c
@@ -3,7 +3,7 @@
range.c -
$Author: matz $
- $Date: 1994/06/17 14:23:50 $
+ $Date: 1994/08/12 04:47:49 $
created at: Thu Aug 19 17:46:47 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -59,6 +59,24 @@ Frng_match(rng, obj)
}
}
+struct upto_data {
+ VALUE beg;
+ VALUE end;
+};
+
+static rng_upto(data)
+ struct upto_data *data;
+{
+ return rb_funcall(data->beg, rb_intern("upto"), 1, data->end);
+}
+
+static rng_upto_yield(v)
+ VALUE v;
+{
+ rb_yield(v);
+ return Qnil;
+}
+
static VALUE
Frng_each(obj)
VALUE obj;
@@ -69,22 +87,18 @@ Frng_each(obj)
e = rb_iv_get(obj, "end");
if (FIXNUM_P(b)) { /* fixnum is a special case(for performance) */
- int beg, end, i;
-
- beg = FIX2INT(b);
- end = FIX2INT(e);
-
- for (i=beg; i<=end; i++) {
- rb_yield(INT2FIX(i));
- }
+ Fnum_upto(b, e);
+ }
+ else if (TYPE(b) == T_STRING) {
+ Fstr_upto(b, e);
}
else {
- current = b;
- for (;;) {
- rb_yield(current);
- if (rb_funcall(current, eq, 1, e)) break;
- current = rb_funcall(current, next, 0);
- }
+ struct upto_data data;
+
+ data.beg = b;
+ data.end = e;
+
+ rb_iterate(rng_upto, &data, rng_upto_yield, Qnil);
}
return Qnil;
@@ -114,18 +128,12 @@ static VALUE
Frng_to_s(obj)
VALUE obj;
{
- int beg, end;
- VALUE fmt, str, args[4];
-
-
- beg = rb_iv_get(obj, "start");
- end = rb_iv_get(obj, "end");
-
- fmt = str_new2("%d..%d");
- args[0] = obj; args[1] = fmt; args[2]= beg; args[3] = end;
- str = Fsprintf(4, args);
+ VALUE args[4];
- return str;
+ args[0] = str_new2("%d..%d");
+ args[1] = rb_iv_get(obj, "start");
+ args[2] = rb_iv_get(obj, "end");
+ return Fsprintf(3, args);
}
extern VALUE M_Enumerable;
diff --git a/re.c b/re.c
index ac92b4b007..42e881eeb3 100644
--- a/re.c
+++ b/re.c
@@ -3,7 +3,7 @@
re.c -
$Author: matz $
- $Date: 1994/06/27 15:48:36 $
+ $Date: 1994/08/18 07:06:23 $
created at: Mon Aug 9 18:24:49 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -101,7 +101,7 @@ int len;
*/
rp = ALLOC(Regexp);
- bzero((char *)rp, sizeof(Regexp));
+ memset((char *)rp, 0, sizeof(Regexp));
rp->pat.buffer = ALLOC_N(char, 16);
rp->pat.allocated = 16;
rp->pat.fastmap = ALLOC_N(char, 256);
@@ -153,7 +153,7 @@ research(reg, str, start, ignorecase)
OBJSETUP(obj, C_Data, T_DATA);
obj->dfree = free_match;
data = (struct match*)DATA_PTR(obj);
- bzero(data, sizeof(struct match));
+ memset(data, 0, sizeof(struct match));
beg = reg->ptr->regs.start[0];
data->len = reg->ptr->regs.end[0] - beg;
data->ptr = ALLOC_N(char, data->len+1);
@@ -410,6 +410,11 @@ VALUE rb_readonly_hook();
void
Init_Regexp()
{
+ obscure_syntax = RE_NO_BK_PARENS | RE_NO_BK_VBAR
+ | RE_CONTEXT_INDEP_OPS | RE_INTERVALS
+ | RE_NO_BK_CURLY_BRACES
+ | RE_MBCTYPE_EUC;
+
rb_define_variable("$~", last_match_data, Qnil, store_match_data);
rb_define_variable("$&", Qnil, re_last_match, rb_readonly_hook);
diff --git a/re.h b/re.h
index e483080fc5..4c6ecfbdb1 100644
--- a/re.h
+++ b/re.h
@@ -3,8 +3,8 @@
re.h -
$Author: matz $
- $Revision: 1.1.1.1 $
- $Date: 1994/06/17 14:23:50 $
+ $Revision: 1.2 $
+ $Date: 1994/08/12 04:47:52 $
created at: Thu Sep 30 14:18:32 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
diff --git a/ruby.1 b/ruby.1
index a674a3dfd9..ec6ba557e8 100644
--- a/ruby.1
+++ b/ruby.1
@@ -1,26 +1,26 @@
.\"ruby.1 - -*- Nroff -*-
-.\" $Author$
-.\" $Date$
-.\" created at: Tue Apr 12 01:45:04 GMT 1994
+.\" $Author: matz $
+.\" $Date: 1994/08/18 07:06:25 $
+.\" created at: Tue Apr 12 01:45:04 JST 1994
.TH RUBY 1 "\*(RP"
.UC
-.SH "NAME ̾"
+.SH NAME
ruby \- ֥Ȼظץȸ
-.SH "SYNOPSIS "
+.SH SYNOPSIS
.B ruby
[
.B options
] filename args
.SH DESCRIPTION
-.IB Ruby
+.B Ruby
, ڤʥ֥Ȼظץߥ󥰤¸뤿μ
-εǽĥ֥ȻظץȸǤ. ߷פ
+εǽĥ֥ȻظץȸǤ롥߷פ
ܸ§, ʲ̤Ǥ.
.IP ǽ
֥Ȼظץߥ󥰤ȥץȥץߥ󥰤Τ
ɬפʵǽʬ. ä˥ƥȽطεǽ˭
-٤˻. ޤ, ʥ֥ȻظǤʤ, ɬ
+٤˻ġޤ, ʥ֥ȻظǤʤ, ɬ
Ǥм³ץߥ󥰤ǽǤ.
.IP ĥ
ɬפ˱ưפ˵ǽĥǤ. 饹ͳɲäǤ
@@ -28,33 +28,57 @@ ruby \- ֥Ȼظץȸ
뵡ǽɲäǤ. ˥ץåȥեˤäƤ, ưŪ
֥ȥɤ󥯤뵡ǽ󶡤.
.IP
-θ§ΤŬѤ褦ʰΤͤ.
-ˤäơ֥ѥγڤפϸΤʤ. ,
+θ§ΤŬѤ褦ʰΤͤ.
+ˤäơ֥ѥγڤפϸΤʤ. ,
ΤȤ䤹ˤ뤳ȤϤʤ.
.PP
-.IB Ruby
-shperlΤäƤͤˤȤäƤξQˤǤ¤꽾äΤ,
+.B Ruby
+shperlΤäƤͤˤȤäƤξQˤǤ¤꽾äΤ,
θ̤ƤͤˤȤäƤϽ(¿ʬ)ưפ.
-.SH "OPTIONS ץ"
-.IB ruby
-ϰʲΰդ.
+.SH OPTIONS
+.B ruby
+󥿥ץ꥿ϰʲΰդ.
.TP 5
.B \-a
`\-n'`\-p'ȤȤѤ, ȥץåȥ⡼ɤONˤ.
-ȥץåȥ⡼ɤǤϳƥ롼פƬ,
+ȥץåȥ⡼ɤǤϳƥ롼פƬ,
.nf
.ne 2
$F = $_.split
.fi
-¹Ԥ. `\-n'`\-p'ץ󤬻ꤵʤ¤,
-ץϰ̣ʤ.
+¹Ԥ. `\-n'`\-p'ץƱ˻ꤵʤ¤,
+Υץϰ̣ʤ.
.TP 5
.B \-c
ץȤؤΥѥΤߤԤ, ¹Ԥʤ.
ѥ뽪λ, ʸˡ顼̵, "Syntax OK"ȽϤ.
.TP 5
+.B \-C " code"
+.B ruby
+νɤꤹ.
+.B ruby
+ϻꤷʸ `E'ޤ`e'Ϥޤʸ䥢
+ե뤬EUCǵҤƤȲꤹ. Ʊͤ`S'
+`s'ξSJISȤƽ. `N'ϴʤ.
+եȤEUC.
+.nf
+.ne 2
+
+ ruby -C EUC -e 'print "ƥ"'
+ ruby -Ceuc -e 'print "ƥ"'
+ ruby -C 'Shift JIS' -e 'print "ƥ"'
+ ruby -CN 'print "ƥ"'
+
+.fi
+ΥץϾʸɤμưȽ̵ǽɲä줿
+ˤѹ.
+.TP 5
+.B \-d, \-\-debug
+ǥХå⡼ɤonˤ. Υե饰åȤȥƥ
+ѿ$DEBUGåȤ.
+.TP 5
.B \-e " script"
ޥɥ饤󤫤饹ץȤꤹ. \-eץդ
ˤϰ饹ץȥե̾ʤ.
@@ -84,13 +108,9 @@ ruby \- ֥Ȼظץȸ
.B \-I " directory"
եɤѥ(ɲ). ꤵ줿ǥ쥯
ȥ
-.IB ruby
+.B ruby
ѿ$LOAD_PATHɲä.
.TP 5
-.B \-d, \--debug
-ǥХå⡼ɤonˤ. Υե饰åȤȥƥ
-ѿ$DEBUGåȤ.
-.TP 5
.B \-l
`$\\'`$/'Ʊͤꤷ, print()Ǥνϻ˲Ԥղä
. ޤ, \-nޤ\-pȤȤѤ, Ϥ줿ƹԤ
@@ -109,12 +129,12 @@ ruby \- ֥Ȼظץȸ
ǰϤޤƤ褦ư.
.TP 5
.B \-p
-\-nե饰Ʊ, ƥ롼פκǸѿ`$_'ͤϤ.
+`\-n'ե饰Ʊ, ƥ롼פκǸѿ`$_'ͤϤ.
.nf
:
.ne 2
- % echo matz | ruby \-p \-e '$_.tr("a-z", "A-Z")'
+ % echo matz | ruby \-p \-e '$_\.tr("a-z", "A-Z")'
MATZ
.fi
@@ -136,28 +156,32 @@ ruby \- ֥Ȼظץȸ
:
.ne 2
- #! /usr/local/ruby -s
- # -xyzץͿ"true"ɽ.
- if $xyz then print("true\n") end
+ #! /usr/local/bin/ruby \-s
+ # \-xyzץͿ"true"ɽ.
+ if $xyz then print("true\\n") end
.fi
.TP 5
-.B \-v, \--verbose
+.B \-S
+ץ̾`/'ǻϤޤäƤʤ, Ķѿ`PATH'ͤ
+ȤäƥץȤõ.
+.TP 5
+.B \-v, \-\-verbose
Ĺ⡼. ư˥СֹɽԤ, ƥѿ
$VERBOSE򥻥åȤ. ѿåȤƤ, Ĥ
Υ᥽åɤϼ¹Ի˾ĹʥåϤ. \-v ץ
-ꤵƤ, ץʳΰʤˤϥС
-ɽ, ¹Ԥλ(ɸϤΥץ
-Ԥʤ).
+󤬻ꤵq, ץʳΰʤˤϥС
+ɽ, ¹Ԥλ(ɸϤΥץȤԤ
+ʤ).
.TP 5
-.B \--version
-.IB ruby
+.B \-\-version
+.B ruby
ΥСɽ.
.nf
ɽ:
.ne 2
- ruby - version 0.50 (29 Jul 94)
+ ruby - version 0.51 (05 Sep 94)
.fi
.TP 5
@@ -170,39 +194,34 @@ $VERBOSE򥻥åȤ. ѿåȤƤ, Ĥ
.B \-X " directory"
ץȼ¹˻ꤵ줿ǥ쥯ȥ˰ܤ.
.TP 5
-.B \-y, \--yydebug
+.B \-y, \-\-yydebug
ѥǥХå⡼. ѥιʸϤβɽ
. ɽ˾ĹʤΤ, ѥ餽ΤΤǥХ
ͰʳɽʤɤȻפ.
-.TP 5
-.B \-N, \-E, \-S
-.IB ruby
-νɤꤹ. Nϴʤ. EEUC,
-SSJISɽ. ǥեȤϴб.
-.SH "BUG Х(뤤Ϸ)"
+.SH BUGS
.PP
-٤. ñʽξperlawkʤɤ2,3ܤμ¹Ի֤.
-¾θȰۤʤ, 󶡤뵡ǽΤۤȤɤ᥽åɸƤӽ
-𤹤뤳Ȥ, ¾θǤؿƤӽФ¿ʤ
-褦ʽǤϥ᥽åɥåʬ
-.IB ruby
+٤. ñʽξperlawkʤɤ2,3ܤμ¹Ի֤.
+θȰۤʤ, 󶡤뵡ǽΤۤȤɤ᥽åɸ
+ӽФ𤹤뤳Ȥ, ¾θǤؿƤӽФ¿
+ʤ褦ʽǤϥ᥽åɥåʬ
+.B ruby
ͭˤʤ뤷, ǡ¤ʣˤʤ, ֥Ȼظ
åȤ褫Τ, ޤ뤫Τʤ.
.PP
perl국̤¿.
-.IB ruby
+.B ruby
ɵᤷ̤Ǥ. , η,
-.IB ruby
+.B ruby
ץȤperlɤߤ䤹Ϥ, 㴳ε̤
򤷤䤹ȲƤȻפäߤ.
.PP
ɥȤԽʬ. ɬפʾ뤿ˤϥɤ
ߤ.
.PP
-ƥȤԽʬ. ХˤĤä, Ǥмʬľ,
+ƥȤԽʬ. ХˤĤä, Ǥмʬľ,
ä˶ߤ. ̵ʤ, ƥХƸ
ΤˤƥݡȤߤ.
-.SH "AUTHOR "
+.SH AUTHOR
Թ (matz@caelum.co.jp)
diff --git a/ruby.c b/ruby.c
index 3a580e6c34..4cef8d714e 100644
--- a/ruby.c
+++ b/ruby.c
@@ -3,7 +3,7 @@
ruby.c -
$Author: matz $
- $Date: 1994/06/27 15:48:37 $
+ $Date: 1994/08/24 09:25:34 $
created at: Tue Aug 10 12:47:31 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -13,7 +13,7 @@
#include "ruby.h"
#include "re.h"
#include <stdio.h>
-#include <sys/file.h>
+#include <sys/fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
@@ -24,12 +24,15 @@
#include "missing/getopt.h"
#endif
+static int version, copyright;
+
static struct option long_options[] =
{
{"debug", 0, 0, 'd'},
{"yydebug", 0, 0, 'y'},
{"verbose", 0, 0, 'v'},
- {"version", 0, 0, 0},
+ {"version", 0, &version, 1},
+ {"copyright", 0, &copyright, 1},
{0, 0, 0, 0}
};
@@ -40,7 +43,8 @@ static int sflag = FALSE;
char *inplace = Qnil;
char *strdup();
char *strstr();
-char *index();
+char *strchr();
+char *dln_find_file();
extern int yydebug;
extern int nerrs;
@@ -58,7 +62,9 @@ static int do_loop = FALSE, do_print = FALSE;
static int do_check = FALSE, do_line = FALSE;
static int do_split = FALSE;
-static char*
+static char *script;
+
+static void
proc_options(argcp, argvp)
int *argcp;
char ***argvp;
@@ -68,26 +74,20 @@ proc_options(argcp, argvp)
extern VALUE rb_load_path;
extern char *optarg;
extern int optind;
- int c, i, j, script_given, version, opt_index;
+ int c, i, j, script_given, do_search, opt_index;
extern VALUE RS, ORS, FS;
- char *script;
char *src;
+ if (argc == 0) return;
+
version = FALSE;
script_given = FALSE;
- script = Qnil;
+ do_search = FALSE;
optind = 0;
- while ((c = getopt_long(argc, argv, "+acde:F:i:I:lnpR:svxX:yNES",
+ while ((c = getopt_long(argc, argv, "+acC:de:F:i:I:lnpR:svxX:yS",
long_options, &opt_index)) != EOF) {
switch (c) {
- case 0: /* long options */
- if (strcmp(long_options[opt_index].name, "version") == 0) {
- version = TRUE;
- show_version();
- }
- break;
-
case 'p':
do_print = TRUE;
/* through */
@@ -104,7 +104,7 @@ proc_options(argcp, argvp)
break;
case 'v':
- version = verbose = TRUE;
+ verbose = TRUE;
show_version();
break;
@@ -175,19 +175,29 @@ proc_options(argcp, argvp)
do_split = TRUE;
break;
- case 'N':
- obscure_syntax &= ~RE_MBCTYPE_MASK;
- re_set_syntax(obscure_syntax);
- break;
- case 'E':
- obscure_syntax &= ~RE_MBCTYPE_MASK;
- obscure_syntax |= RE_MBCTYPE_EUC;
+ case 'C':
+ switch (optarg[0]) {
+ case 'E':
+ case 'e':
+ obscure_syntax &= ~RE_MBCTYPE_MASK;
+ obscure_syntax |= RE_MBCTYPE_EUC;
+ break;
+ case 'S':
+ case 's':
+ obscure_syntax &= ~RE_MBCTYPE_MASK;
+ obscure_syntax |= RE_MBCTYPE_SJIS;
+ break;
+ default:
+ case 'N':
+ case 'n':
+ obscure_syntax &= ~RE_MBCTYPE_MASK;
+ break;
+ }
re_set_syntax(obscure_syntax);
break;
+
case 'S':
- obscure_syntax &= ~RE_MBCTYPE_MASK;
- obscure_syntax |= RE_MBCTYPE_SJIS;
- re_set_syntax(obscure_syntax);
+ do_search = TRUE;
break;
case 'I':
@@ -199,17 +209,29 @@ proc_options(argcp, argvp)
}
}
- if (argv[0] == Qnil) return Qnil;
+ if (version) {
+ show_version();
+ exit(0);
+ }
+ if (copyright) {
+ show_copyright();
+ }
+
+ if (argv[0] == Qnil) return;
if (script_given == 0) {
if (argc == optind) { /* no more args */
- if (version == TRUE) exit(0);
+ if (verbose) exit(0);
script = "-";
load_stdin();
}
else {
script = argv[optind];
- rb_load_file(argv[optind]);
+ if (do_search) {
+ script = dln_find_file(script, getenv("PATH"));
+ if (!script) script = argv[optind];
+ }
+ rb_load_file(script);
optind++;
}
}
@@ -228,7 +250,7 @@ proc_options(argcp, argvp)
break;
}
argv[0][0] = '$';
- if (s = index(argv[0], '=')) {
+ if (s = strchr(argv[0], '=')) {
*s++ = '\0';
rb_gvar_set2((*argvp)[0], str_new2(s));
}
@@ -238,8 +260,6 @@ proc_options(argcp, argvp)
}
*argcp = argc; *argvp = argv;
}
-
- return script;
}
static void
@@ -331,13 +351,68 @@ load_stdin()
readin(fd, "-");
}
+static VALUE Progname;
+VALUE Argv;
+
+static int origargc;
+static char **origargv, **origenvp;
+
+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 val;
+}
+
void
-rb_main(argc, argv) /* real main() is in eval.c */
+ruby_script(name)
+ char *name;
+{
+ if (name) {
+ Progname = str_new2(name);
+ }
+}
+
+void
+ruby_init0(argc, argv, envp)
int argc;
- char **argv;
+ char **argv, **envp;
{
- char *script;
extern VALUE errat;
+ int i;
+
+ origargc = argc; origargv = argv; origenvp = envp;
rb_call_inits();
@@ -350,7 +425,7 @@ rb_main(argc, argv) /* real main() is in eval.c */
rb_dln_argv0 = argv[0];
#endif
- script = proc_options(&argc, &argv);
+ proc_options(&argc, &argv);
if (do_check && nerrs == 0) {
printf("Syntax OK\n");
exit(0);
@@ -362,9 +437,13 @@ rb_main(argc, argv) /* real main() is in eval.c */
yywhole_loop(do_line, do_split);
}
- if (nerrs == 0) {
- TopLevel(script, argc, argv);
- }
+ rb_define_variable("$0", &Progname, Qnil, set_arg0);
+ ruby_script(script);
- exit(nerrs);
+ rb_define_variable("$ARGV", &Argv, Qnil, Qnil);
+ rb_define_variable("$*", &Argv, Qnil, Qnil);
+ Argv = ary_new2(argc);
+ for (i=0; i < argc; i++) {
+ Fary_push(Argv, str_new2(argv[i]));
+ }
}
diff --git a/ruby.h b/ruby.h
index 092d26f600..94fd224df0 100644
--- a/ruby.h
+++ b/ruby.h
@@ -3,7 +3,7 @@
ruby.h -
$Author: matz $
- $Date: 1994/06/27 15:48:38 $
+ $Date: 1994/08/12 11:06:43 $
created at: Thu Jun 10 14:26:32 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -70,7 +70,8 @@ typedef unsigned short USHORT;
#define POINTER(p) (p)
#define NIL_P(p) ((p) == Qnil)
-#define TRUE INT2FIX(1)
+#undef TRUE
+extern VALUE TRUE;
#define FALSE Qnil
extern VALUE C_Object;
@@ -179,9 +180,12 @@ struct RData {
#define DATA_PTR(dta) (RDATA(dta)->data)
+VALUE rb_ivar_get_1();
+VALUE rb_ivar_set_1();
+
#define Get_Data_Struct(obj, iv, type, sval) {\
VALUE _data_;\
- _data_ = rb_iv_get(obj, iv);\
+ _data_ = rb_ivar_get_1(obj, iv);\
Check_Type(_data_, T_DATA);\
sval = (type*)DATA_PTR(_data_);\
}
@@ -192,8 +196,8 @@ struct RData {
_new_->dmark = (void (*)())(mark);\
_new_->dfree = (void (*)())(free);\
sval = (type*)DATA_PTR(_new_);\
- bzero(sval, sizeof(type));\
- rb_iv_set(obj, iv, _new_);\
+ memset(sval, 0, sizeof(type));\
+ rb_ivar_set_1(obj, iv, _new_);\
}
struct RStruct {
@@ -226,6 +230,8 @@ struct RBignum {
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
+extern VALUE rb_self();
+#define Qself rb_self()
#define Qnil (VALUE)0
#define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n))
@@ -240,7 +246,6 @@ void rb_define_const();
void rb_define_method();
void rb_define_single_method();
-void rb_define_mfunc();
void rb_undef_method();
void rb_define_alias();
void rb_define_attr();
diff --git a/sample/biorhythm.rb b/sample/biorhythm.rb
index 3261c4377f..eb14ca7365 100644
--- a/sample/biorhythm.rb
+++ b/sample/biorhythm.rb
@@ -41,7 +41,7 @@ def leapyear(y)
return ta
end
-def bcalc(t, m, j)
+def bcalc(tt, m, j)
ta = 0
if (m <= 2)
ta = (m - 1) * 31
@@ -51,7 +51,7 @@ def bcalc(t, m, j)
end
ta = ta + (j - 1) * 365 + ((j - 1) / 4.0).to_i
ta = ta - ((j - 1) / 100) + ((j - 1) / 400.0).to_i
- ta = ta + t
+ ta = ta + tt
return ta
end
diff --git a/sample/cat2.rb b/sample/cat2.rb
new file mode 100644
index 0000000000..f979dc53cb
--- /dev/null
+++ b/sample/cat2.rb
@@ -0,0 +1,4 @@
+while gets()
+ if 1 ... /^\*/; print("--") end
+ printf("%5d: %s", $., $_)
+end
diff --git a/sample/getopts.rb b/sample/getopts.rb
index 57a7db424f..01eddcea98 100644
--- a/sample/getopts.rb
+++ b/sample/getopts.rb
@@ -55,7 +55,7 @@ def getopts(single_opts, *opts)
while ($ARGV.length != 0)
compare = nil
case $ARGV[0]
- when /^-*$/
+ when /^--?$/
$ARGV.shift
break
when /^--.*/
diff --git a/sample/io.rb b/sample/io.rb
index 45d50d653a..b5591af7e4 100644
--- a/sample/io.rb
+++ b/sample/io.rb
@@ -13,7 +13,7 @@ end
printf("%s:(%d)%s\n", $0, $ARGV.length, $ARGV[0])
passwd = open($ARGV[0], "r")
-#printf("%s", do passwd.find using i; i =~ /\*/ end)
+#printf("%s", passwd.find{i|i =~ /\*/})
n = 1
for i in passwd #.grep(/^\*/)
diff --git a/newver.rb b/sample/newver.rb
index bee3853c25..bbf03aebc2 100755..100644
--- a/newver.rb
+++ b/sample/newver.rb
@@ -1,14 +1,13 @@
#! /usr/local/bin/ruby
+
f = open("version.h", "r")
f.gets()
f.close
-if $_ =~ /"(\d+)\.(\d+)"/;
+if $_ =~ /"(\d)\.(\d+)"/;
f = open("version.h", "w")
i = $2.to_i + 1
- date = Time.now.strftime("%d %b %y")
- printf("ruby version %d.%0d (%s)\n", $1, i, date)
+ printf("ruby version %d.%0d\n", $1, i)
printf(f, "#define RUBY_VERSION \"%d.%0d\"\n", $1, i)
- printf(f, "#define VERSION_DATE \"%s\"\n", date)
f.close
end
diff --git a/sample/rcs.rb b/sample/rcs.rb
index 6d7f10c6bc..0ed4a36c1e 100644
--- a/sample/rcs.rb
+++ b/sample/rcs.rb
@@ -14,12 +14,16 @@ while gets()
while xr < hdw
x = xr * (1 + y) - y * w / 2
i = (x / (1 + h) + sw /2)
- c = if (1 < i && i < $_.length); $_[i, 1].to_i else 0 end
+ if (1 < i && i < $_.length);
+ c = $_[i, 1].to_i
+ else
+ c = 0
+ end
y = h - d * c
xl = xr - w * y / (1 + y);
if xl < -hdw || xl >= hdw || xl <= maxxl
- t = rand(ss.length)
- c = ss[t, 1]
+ tt = rand(ss.length)
+ c = ss[tt, 1]
else
c = s[xl + hdw, 1]
maxxl = xl
diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el
index 96915bdc5a..8f864d3846 100644
--- a/sample/ruby-mode.el
+++ b/sample/ruby-mode.el
@@ -8,22 +8,23 @@
;;;
(defconst ruby-block-beg-re
- "class\\|module\\|def\\|if\\|case\\|while\\|do\\|for\\|protect"
+ "class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|protect"
)
(defconst ruby-block-mid-re
- "else\\|elsif\\|when\\|using\\|resque\\|ensure"
+ "else\\|elsif\\|when\\|resque\\|ensure"
)
-(defconst ruby-block-end-re
- (concat "\\(end\\([ \t]+\\(" ruby-block-beg-re "\\)\\)?\\)")
- )
+(defconst ruby-block-end-re "end")
(defconst ruby-delimiter
- (concat "(\\|)\\|\\{\\|\\}\\|\"\\|\'\\|\\b\\(" ruby-block-beg-re "\\|" ruby-block-end-re "\\)\\b\\|#")
+ (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")
+ (concat "^[ \t]*\\(\\b\\(" ruby-block-mid-re "\\)\\|\\("
+ ruby-block-end-re "\\)\\b\\|\\}\\|\\]\\)")
)
(defvar ruby-mode-abbrev-table nil
@@ -51,9 +52,10 @@
(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 ?\n ">" ruby-mode-syntax-table)
+;;(modify-syntax-entry ?\f ">" ruby-mode-syntax-table)
+ (modify-syntax-entry ?# "<" 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)
@@ -68,9 +70,9 @@
(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)
)
@@ -78,23 +80,6 @@
(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
@@ -109,7 +94,21 @@ The variable ruby-indent-level controls the amount of indentation.
(setq mode-name "ruby")
(setq major-mode 'ruby-mode)
(set-syntax-table ruby-mode-syntax-table)
- (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)
(run-hooks 'ruby-mode-hook))
(defun ruby-current-indentation ()
@@ -131,10 +130,8 @@ The variable ruby-indent-level controls the amount of indentation.
(defun ruby-indent-line (&optional flag)
"Correct indentation of the current ruby line."
- (let
- ((x (ruby-calculate-indent)))
- (ruby-indent-to x)))
-
+ (ruby-indent-to (ruby-calculate-indent)))
+
(defun ruby-indent-command ()
(interactive)
(ruby-indent-line t))
@@ -166,14 +163,36 @@ The variable ruby-indent-level controls the amount of indentation.
(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))))
+ (let ((w (buffer-substring (match-beginning 0) (match-end 0)))
+ (pnt (match-beginning 0)))
(cond
((or (string= "\"" w) ;skip string
- (string= "\'" w))
+ (string= "'" w)
+ (string= "`" w))
(if (search-forward w indent-point t)
nil
(goto-char indent-point)
(setq in-string t)))
+ ((or (string= "/" w)
+ (string= "<" w))
+ (if (string= "<" w) (setq w ">"))
+ (let (c)
+ (save-excursion
+ (goto-char pnt)
+ (skip-chars-backward " \t")
+ (setq c (char-after (1- (point))))
+ (if c
+ (setq c (char-syntax c))))
+ (cond
+ ((or (eq c ?.)
+ (and (eq c ?w)
+ (save-excursion
+ (forward-word -1)
+ (looking-at ruby-block-beg-re))))
+ (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
@@ -189,7 +208,21 @@ The variable ruby-indent-level controls the amount of indentation.
(t
(setq nest (cdr nest))
(setq depth (1- depth)))))
- (if (> depth orig) (setq in-paren t))))
+ (if (> depth orig) (setq in-paren ?\())))
+ ((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 ?\[))))
((string= "{" w) ;skip to matching paren
(let ((orig depth))
(setq nest (cons (point) nest))
@@ -197,22 +230,28 @@ The variable ruby-indent-level controls the amount of indentation.
(while (and (/= depth orig)
(re-search-forward "[{}]" indent-point t))
(cond
- ((= (char-after (match-beginning 0)) ?\{ )
+ ((= (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)
+ (if (> depth orig) (setq in-paren ?{))))
+ ((string-match ruby-block-end-re 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)))
+ (let (c)
+ (save-excursion
+ (goto-char pnt)
+ (skip-chars-backward " \t")
+ (setq c (char-after (1- (point)))))
+ (if (or (null c) (= c ?\n) (= c ?\;))
+ (progn
+ (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)
@@ -224,7 +263,7 @@ The variable ruby-indent-level controls the amount of indentation.
(indent 0))
(if parse-start
(goto-char parse-start)
- (beginning-of-defun)
+ (ruby-beginning-of-defun)
(setq parse-start (point)))
(setq state (ruby-parse-region parse-start indent-point))
(cond
@@ -234,9 +273,9 @@ The variable ruby-indent-level controls the amount of indentation.
((nth 1 state) ; in paren
(goto-char (nth 2 state))
(setq indent
- (if (looking-at "$")
- (+ (current-indentation) ruby-indent-level)
- (current-column))))
+ (if (and (eq (nth 1 state) ?\( ) (not (looking-at "$")))
+ (current-column)
+ (+ (current-indentation) ruby-indent-level))))
((> (nth 3 state) 0) ; in nest
(goto-char (nth 2 state))
@@ -258,7 +297,7 @@ The variable ruby-indent-level controls the amount of indentation.
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 "\\)")
+ (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)\\b")
nil 'move (or arg 1))
(progn (beginning-of-line) t)))
@@ -266,7 +305,7 @@ Returns t unless search stops due to end of buffer."
"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 "\\)")
+ (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\b")
nil 'move (or arg 1))
(progn (beginning-of-line) t))
(forward-line 1))
diff --git a/sample/sieve.rb b/sample/sieve.rb
new file mode 100644
index 0000000000..0228243fda
--- /dev/null
+++ b/sample/sieve.rb
@@ -0,0 +1,16 @@
+sieve = []
+unless max = $ARGV.shift; max = 100; end
+max = max.to_i
+
+print "1"
+for i in 2 .. max
+ protect
+ for d in sieve
+ fail if i % d == 0
+ end
+ print ", "
+ print i
+ sieve.push(i)
+ resque
+ end
+end
diff --git a/sample/t2.rb b/sample/t2.rb
index 7f5b9df480..a34c171837 100644
--- a/sample/t2.rb
+++ b/sample/t2.rb
@@ -7,7 +7,7 @@ def println(*args)
print(a)
end
print("\n")
-end def
+end
def tt
for i in 1..10
@@ -16,9 +16,8 @@ def tt
end
end
-test =
-do tt() using i
+test = tt{i|
if i == 3; break end
println("ttt: ", i);
-end
+}
#exit()
diff --git a/sample/trojan.rb b/sample/trojan.rb
index bd49d44357..b42fd166a8 100644
--- a/sample/trojan.rb
+++ b/sample/trojan.rb
@@ -2,11 +2,13 @@
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)
+ if File.d(dir)
+ 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
- d.close
end
diff --git a/sample/tt.rb b/sample/tt.rb
index cb863e3527..c53ec39d68 100644
--- a/sample/tt.rb
+++ b/sample/tt.rb
@@ -5,13 +5,13 @@ module Print
print(a)
end
print("\n")
- end def
+ end
def println2(*args)
print(*args)
print("\n")
- end def
-end module
+ end
+end
module Print2
def println(*args)
@@ -52,20 +52,20 @@ class Fib:Object
if args; println(*args) end
args = args.grep(/^c/)
super(*args)
- end def
+ end
def init
println("in Fib.init");
- end def
+ end
def fib(n)
a =0; b = 1
while b <= n
c = a; a = b; b = c+b
- end while
+ end
return b
- end def
+ end
end
def Object.test(*args)
@@ -96,8 +96,5 @@ def tt
end
end
-test = do tt() using i
- if i == 2; break end
-end
-
+test = tt() {i|break if i == 2}
println([1,2,3,4].join(":"))
diff --git a/socket.c b/socket.c
index 8fc8e25f44..d8e9cb0329 100644
--- a/socket.c
+++ b/socket.c
@@ -3,7 +3,7 @@
socket.c -
$Author: matz $
- $Date: 1994/06/17 14:23:51 $
+ $Date: 1994/08/12 04:47:56 $
created at: Thu Mar 31 12:21:29 JST 1994
************************************************/
@@ -65,7 +65,8 @@ Fbsock_shutdown(sock, args)
GetOpenFile(sock, fptr);
if (shutdown(fileno(fptr->f), how) == -1)
rb_sys_fail(Qnil);
- return sock;
+
+ return INT2FIX(0);
}
static VALUE
@@ -84,7 +85,8 @@ Fbsock_setopt(sock, lev, optname, val)
GetOpenFile(sock, fptr);
if (setsockopt(fileno(fptr->f), level, option, val->ptr, val->len) < 0)
rb_sys_fail(fptr->path);
- return sock;
+
+ return INT2FIX(0);
}
static VALUE
@@ -533,6 +535,13 @@ Fsock_open(class, domain, type, protocol)
}
static VALUE
+Fsock_for_fd(class, fd)
+ VALUE class, fd;
+{
+ return sock_new(class, NUM2INT(fd));
+}
+
+static VALUE
Fsock_socketpair(class, domain, type, protocol)
VALUE class, domain, type, protocol;
{
@@ -559,7 +568,8 @@ Fsock_connect(sock, addr)
GetOpenFile(sock, fptr);
if (connect(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
rb_sys_fail("connect(2)");
- return sock;
+
+ return INT2FIX(0);
}
static VALUE
@@ -575,7 +585,8 @@ Fsock_bind(sock, addr)
GetOpenFile(sock, fptr);
if (bind(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
rb_sys_fail("bind(2)");
- return sock;
+
+ return INT2FIX(0);
}
static VALUE
@@ -587,7 +598,8 @@ Fsock_listen(sock, log)
GetOpenFile(sock, fptr);
if (listen(fileno(fptr->f), NUM2INT(log)) < 0)
rb_sys_fail("listen(2)");
- return sock;
+
+ return INT2FIX(0);
}
static VALUE
@@ -695,6 +707,7 @@ Init_Socket ()
C_Socket = rb_define_class("Socket", C_BasicSocket);
rb_define_single_method(C_Socket, "open", Fsock_open, 3);
rb_define_single_method(C_Socket, "new", Fsock_open, 3);
+ rb_define_single_method(C_Socket, "for_fd", Fsock_for_fd, 1);
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 aa3d96e868..37e6260611 100644
--- a/spec
+++ b/spec
@@ -42,10 +42,10 @@ RubyΥ֥ȻظǽˤĤƳؤ٤, 궯ϤʤȤǤ褦
󥯤Ǥ뤷, ǤʤƤRubyƥѥ뤷Ȥ߹ߥ
ɲäΤưפǤ(PerlʤɤϤ뤫ưפǤ).
-* Rubyδ
+* Rubyʸˡ
-RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ
-ۤ񤷤ʤ.
+ǤRubyʸˡ⤹. RubyδŪʬ˾, ʸ
+ˡ㳰ʤΤǿȤˤĤΤϤۤ񤷤ʤ.
**
@@ -54,214 +54,193 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ
** ڤ국
-ʸ(֤ȥڡ)Ӳ(\n)ڤ국Ȥʤ. ,
+ʸ(֤ȥڡ)Ӳ(\n)ڤ국Ȥʤ.
a +
b
-Τ褦˹Ԥ(ʸ)ǽ, ιԤ³Ȥʾʳϲ
-ʸζڤȤǧ.
-
-** ̻
-
-ե٥åȤ`_'ǻϤޤ, ե٥å, , `_'Ǥդ¤Ӥϼ
-̻ҤǤ. ̻ҤŤϤʤ.
+Τ褦˹Ԥ(ʸ)ǽ, ιԤ³Ȥʾʳʸ
+ڤȤƤǧ.
** ͽ
ͽϰʲ̤Ǥ
- 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
+ break end module self while
+ case ensure nil super yield
+ class fail protect then __END__
+ continue for redo undef __FILE__
+ def if resque unless __LINE__
+ else in retry until
+ elsif include return when
ͽϥ饹̾, ᥽å̾, ѿ̾ʤɤѤ뤳ȤϤǤʤ.
-** 롼ԥ
-
-ϳ̤ˤäƥ롼ԥ󥰤뤳ȤǤ. ˳ˤϼ¤Ӥ
-񤱤. ¤Ӥ򵭽Ҥ, ȼζڤˤϲԤ ';' Ѥ.
-¤ӤͤϺǸɾͤǤ. Ĥޤ
-
- (; ; ...)
-
-ͤϺǸɾͤˤʤ.
-
-** ƥ
-
-ʲΥƥ뤬 ϼǤ.
+**
- ʸƥ
+RubyץǤϼʸǤ. ޤ, ⤹.
- "..." # ХååβѿŸ
- '...' # Хååβʤ(\\\'ϲ᤹)
+*** ƥ
- Хåå嵭ˡ
+ץľܵҤǤ륪֥ȤƥȸƤ. RubyΥƥ
+ˤʸ, ɽ, ͤȤƥ뤬.
- \t (0x09)
- \n ʸ(0x0a)
- \r ʸ(0x0d)
- \f ڡʸ(0x0c)
- \b Хåڡ(0x08)
- \a ٥(0x07)
- \e (0x1b)
- \# ʸ`#'Τ
- \nnn 8ʿɽ(n0-7)
- \xnn 16ʿɽ(n0-9,a-f)
- \^c ȥʸ(cASCIIʸ)
- \C-c ȥʸ(Ʊ)
- \M-c ᥿ʸ(c|0x80)
+**** ʸƥ
- ɽƥ
+ "..." # ХååβѿŸ
+ '...' # Хååβʤ(\\\'ϲ᤹)
- /.../
+**** Хåå嵭ˡ
- ɽ
+ \t (0x09)
+ \n ʸ(0x0a)
+ \r ʸ(0x0d)
+ \f ڡʸ(0x0c)
+ \b Хåڡ(0x08)
+ \a ٥(0x07)
+ \e (0x1b)
+ \# ʸ`#'Τ
+ \nnn 8ʿɽ(n0-7)
+ \xnn 16ʿɽ(n0-9,a-f)
+ \^c ȥʸ(cASCIIʸ)
+ \C-c ȥʸ(Ʊ)
+ \M-c ᥿ʸ(c|0x80)
- ^ Ƭ
- $
- . Ǥդ1ʸ
- \w ѿ. [0-9A-Za-z_]Ʊ
- \W ѿ
- \s ʸ. [ \t\n\r\f]Ʊ
- \S ʸ
- \d . [0-9] Ʊ
- \D
- \b 춭ʸ(ʸ饹)
- \B 춭ʸ
- \b (0x08)(ʸ饹)
- [ ] ʸ饹
- * ľɽ0ʾη֤
- + ľɽ1ʾη֤
- {m,n} m󤫤nη֤
- ? 0ޤ1
- |
- ( ) ɽޤȤ
-
- ¾ʸƱХåå嵭ˡͭǤ.
-
- ͥƥ
-
- 123
- -123 (Ĥ)
- 1_234 (10ʿ`_'ޤळȤǤ)
- 123.45 ư
- 1.2e-3 ư
- 0xffff 16
- 0377 8
- ?a ʸ`a'Υ(97)
- ?\C-a ȥaΥ(1)
- ?\M-a ᥿aΥ(225)
- ?\M-\C-a ᥿-ȥaΥ(129)
-
- ?ɽǤƤΥХåå嵭ˡͭǤ.
-
-*** ѿŸ
+**** ѿŸ
֥륯(`"')ǰϤޤ줿ʸɽǤ `#{ѿ̾}'Ȥ
ѿƤŸ뤳ȤǤ. ѿѿ(`$',`@',`%')
ľˤ`#ѿ̾'ȤǤŸǤ. ʸ`#'³ʸ
-`{'Ǥʤ, ѿǤʤ, Τޤ`#'ȤƲᤵ.
-
-** ޥɤν
-
-``ǰϤޤ줿ʸ, ֥륯ȤƱͤŸ줿, Ʊ
-褦˥ޥɤȤƼ¹Ԥ, μ¹Է̤ʸȤͿ.
-ޥɤɾ뤿Ӥ˼¹Ԥ.
+`{',`$',`@',`%'Ǥʤ, Τޤ`#'ȤƲᤵ.
-**
+**** ɽƥ
-󼰤ϰʲηǤ.
+ /.../
- [ , ... ]
+ ^ Ƭ
+ $
+ . Ǥդ1ʸ
+ \w ѿ. [0-9A-Za-z_]Ʊ
+ \W ѿ
+ \s ʸ. [ \t\n\r\f]Ʊ
+ \S ʸ
+ \d . [0-9] Ʊ
+ \D
+ \b 춭ʸ(ʸ饹)
+ \B 춭ʸ
+ \b (0x08)(ʸ饹)
+ [ ] ʸ饹
+ * ľɽ0ʾη֤
+ + ľɽ1ʾη֤
+ {m,n} m󤫤nη֤
+ ? 0ޤ1
+ |
+ ( ) ɽޤȤ
-줾μɾ̤ޤ֤. Ǥ0뤿
-ˤ϶
+¾ʸƱХåå嵭ˡͭǤ.
- []
+**** 磻ɥɥƥ
-Ѥ.
+ <...>
-** Ϣ
+ * Ǥդʸ(ʸޤ)Ȱ
+ ? Ǥդ1ʸȰ
+ [ ] []Τ줫1ʸȰ
+ {..} {}Τ줫ʸȰ
-ϢȤǤդΥ֥Ȥ򥭡(ź)ȤƻƤǤ. Ruby
-ǤϢSmalltalkѸڤDict()ȤƤФ. ܺ٤ϥ
-饹Dictι򻲾Ȥ줿. ϢϢ󼰤ϰʲη
-.
+**** ͥƥ
- { =>, ... }
+ 123
+ -123 (Ĥ)
+ 1_234 (10ʿ`_'ޤळȤǤ)
+ 123.45 ư
+ 1.2e-3 ư
+ 0xffff 16
+ 0377 8
+ ?a ʸ`a'Υ(97)
+ ?\C-a ȥaΥ(1)
+ ?\M-a ᥿aΥ(225)
+ ?\M-\C-a ᥿-ȥaΥ(129)
-줾μɾ̤򥭡ͤȤϢ󥪥֥Ȥ֤.
-Ǥ0Ϣ뤿ˤ϶Ϣ
+ \ܥ ̻/ѿ̾Ȱаб. applyʤɤǥ᥽
+ ɤꤹΤ˻Ȥ.
- {}
+?ɽǤƤΥХåå嵭ˡͭǤ.
-Ѥ.
+*** ޥɤν
-** ѿ
+RubyǤshΤ褦˥ޥɤμ¹Է̤ʸƥΤ褦˻ȤȤ
+Ǥ. ``ǰϤޤ줿ʸ, ֥륯ȤƱͤ˥Хåå嵭
+ˡβѿŸԤʤ줿, ޥɤȤƼ¹Ԥ, μ¹Է
+ʸȤͿ. ޥɤɾ뤿Ӥ˼¹Ԥ.
-ѿˤ4ढä, μѿ̾κǽΰʸǷꤵ.
-Ƥʤѿ򻲾ȤͤnilǤ.
+*** ѿ
- 饹ѿ()
+Rubyѿϥ(ͭϰ)ȼ̿(ͭ)ˤä4ʬव,
+μѿ̾κǽΰʸǷꤵ. ̾ѿ2ʸܰʹߤ
+ѿޤ`_'Ǥ뤬, ƥѿΰϡ`$'+1ʸεפȤ
+ѿ. ѿ̾Ĺ˴ؤ̤¤Ϥʤ.
- `%'ǻϤޤѿϥ饹ѿǤ, Υ饹ƤΥ֥饹
- 󥹥󥹤黲ȤǤ. ѿؤϥȥåץ٥, ʤ
- ᥽åɤǤ٥ǤΤ߲ǽǤ. ѿϥ饹֤
- ͤͭ, ȥ᥽åɤͤѹ뤳ȤǤ
- Τ,ȤѤ.
+ѿΥפ˴ؤ餺, Ƥʤѿ򻲾Ȥͤnil
+Ǥ.
- 󥹥ѿ
+**** Хѿ
- `@'ǻϤޤѿϥ󥹥ѿǤ, Υ饹ޤϥ֥
- Υ᥽åɤ黲ȤǤ. μ̿ϥ֥Ȥμ̿.
+`$'ǻϤޤѿΥפϥХǤ, ץΤɤǤ
+ȤǤ. μ̿ϥץμ̿.
- Хѿ
+**** 󥹥ѿ
- `$'ǻϤޤѿΥפϥХǤ, μ̿ϥץ
- μ̿.
+`@'ǻϤޤѿϥ󥹥ѿǤ, Υ饹ޤϥ֥饹
+᥽åɤ黲ȤǤ. פϥ᥽åǤ, μ̿ϥ֥
+Ȥμ̿.
- 饹̾/⥸塼̾/ѿ
+**** 饹̾/⥸塼̾/ѿ
- ե٥åȤޤ`_'ǻϤޤѿϼ̻ҤȤƤФ,
- ѿ, 饹̾ޤϥ⥸塼̾Ǥ.
+ե٥åȤޤ`_'ǻϤޤѿϼ̻ҤȤƤФ, ѿ,
+饹̾ޤϥ⥸塼̾Ǥ.
- ֤Ǥϼ̻Ҥϥ饹/⥸塼̾Ȥߤʤ뤬(륯
- ¸ߤʤͤnil), κդ˸줿̻Ҥ,Υ
- ǤϥѿȤƸʤ, Ʊ̾Υ饹⥸塼
- . ΰ̣Ǽ̻ҤؤȤƤƯ.
+֤Ǥϼ̻Ҥϥ饹/⥸塼̾Ȥߤʤ뤬(륯饹
+¸ߤʤͤnil), κդ˸줿̻Ҥ,Υ
+ǤϥѿȤƸʤ, Ʊ̾Υ饹⥸塼ϱ.
+ΰ̣Ǽ̻ҤؤȤƤƯ.
Array # 󥯥饹 Array
Array = 15 # . ʸArrayϥѿ
- print(Array, "\n") # `15'Ϥ
+ print Array, "\n" # `15'Ϥ
- ϥѥ˲ᤵ뤿, ̻Ҥؤºݤ˼
- ԤƤ, ʤƤ, ʹߤΥǤϤμ̻Ҥϥ
- ѿȤߤʤ.
+ȤƤβϥѥ˹Ԥʤ뤿, ̻Ҥؤ
+ºݤ˼¹ԤƤ⤵ʤƤ, ʹߤΥǤϤμ̻Ҥ
+ѿȤߤʤ.
Array # 󥯥饹 Array
if %FALSE
Array = 15 # Υɤϼ¹Ԥʤ,
# ʹArrayϥѿȤߤʤ.
end
- print(Array, "\n") # `nil'Ϥ
+ print Array, "\n" # `nil'Ϥ
+
+Υ롼ϰ츫ʣ, 饹/⥸塼̾ȥѿ̾ʣ
+ʤ¤, ̤ΥѿͤnilǤȹͤƤ⺹٤Ϥ
+. RubyȤ߹ߥ饹ʸΥե٥åȤǻϤޤ̾Ĥ
+, 桼⥯饹/⥸塼̾ˤʸǻϤޤ뼱̻Ҥ,
+ѿ̾ˤϾʸޤ`_'ǻϤޤ뼱̻ҤȤȤ򶯤侩.
- Υ롼ϰ츫ʣ, 饹/⥸塼̾ȥѿ̾
- ʣʤ¤, ̤ΥѿͤnilǤȹͤƤ⺹
- ٤Ϥʤ.
+ѿΥפ̿⤽Υ֥åνޤ(ȥåץ٥Υ
+ѿϥץνλޤ)Ǥ.
- RubyȤ߹ߥ饹ʸΥե٥åȤǻϤޤ̾ĤƤ
- , 桼⥯饹/⥸塼̾ˤʸǻϤޤ뼱̻Ҥ,
- ѿ̾ˤϾʸޤ`_'ǻϤޤ뼱̻ҤȤȤ򶯤侩.
+**** 饹ѿ()
- ѿμ̿ϤΥ᥽åɤλޤ(ȥåץ٥Υ
- ѿϥץνλޤ)Ǥ.
+`%'ǻϤޤѿϥ饹ѿǤ, Υ饹ƤΥ֥饹Υ
+󥹤黲ȤǤ. ѿؤϥȥåץ٥, ʤ᥽
+ɤǤ٥ǤΤ߲ǽǤ. ѿϥ饹֤ͤͭ,
+ȥ᥽åɤͤѹ뤳ȤǤʤΤ,Ȥ
+Ѥ.
-˵ѿȸƤФüѿ4Ĥ.
+**** ѿ
+
+̾ѿʳ˵ѿȸƤФüѿ4Ĥ.
self | ߤΥ᥽åɤμ¹Լ
nil | Nil饹ͣΥ󥹥(ɽ)
@@ -271,52 +250,99 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ
εѿˤäƤͤѹ뤳ȤϤǤʤ.
ѿؤ㳰ȯ.
-** å
+*** å
֥Ȥ˥åŪʹʸåǤ, δ
ܷϰʲ̤Ǥ.
- 1.᥽å̾(...)
+ 1 '.' ᥽å̾ '(' 1... [',' '*' n ]')'
- 1ɾ륪֥Ȥ, ̻Ҥǻꤵ᥽
- ɤƤӽФ. ֺǸΰ'*'³(ñ)Ǥ,
- μɾ(Ǥɬפ)Ÿ, Ȥ
- ɲä.
+1ɾ륪֥Ȥ, ̻Ҥǻꤵ᥽åɤƤ
+Ф. ֺǸΰ'*'³(ñ)Ǥ, μɾ
+(Ǥɬפ)Ÿ, Ȥɲä.
- Ĥʤˤϳ̤άǤ.
+Ĥʤˤϳ̤άǤ.
᥽å̾ȤƤǤդμ̻ҤѤ뤳ȤǤ. ѿ̾Ȥϼ̻Ҥ
֤̾㤦ΤǽʣƤ⹽ʤ.
-** ؿ
-
å, 쥷Фselfξ, 쥷Фά̾Υץ
ߥ󥰸ˤؿΤ褦ʷǥ᥽åɤƤӽФȤǤ.
ξ1ĤʤǤ̤ξάϤǤʤ.
ؿǤ`@'ǻϤޤ̾ĥ᥽åɤƤӽФȤǤ. `@'
Ϥޤ᥽åɤϴؿǤƤӽФȤǤʤ, 륯
-ޤ, Υ֥饹餷ƤФʤΤ, ץ饤١ȥ᥽åɤ
-ƤФ. ץ饤١ȥ᥽åɤC++ˤprotected member function
-.
+ޤϤΥ֥饹餷ƤФʤΤ, ץ饤١ȥ᥽åɤȸ
+Ф. ץ饤١ȥ᥽åɤC++ˤprotected member function˳
+.
-** ѡ饹Υ᥽åɸƤӽФ
+*** ѡ饹Υ᥽åɸƤӽФ
åüʥȤƥѡ饹Υ᥽åɤθƤӽФ
. ηϥ᥽åɤ˥ѡ饹Ѥ뤿
˻Ȥ.
- super
+ super
+
+ߤΥ᥽åɤͿ줿Τޤޥѥ饹Ʊ̾Υ᥽åɤƤ
+Ф.
+
+ super'(' ... ')'
+
+ȤȤ˥ѡ饹Ʊ̾Υ᥽åɤƤӽФ. ֺǸΰ
+`*'³̾Υ᥽åɸƤӽФƱͤϤ.
- ߤΥ᥽åɤͿ줿Τޤޥѥ饹Ʊ̾Υ᥽
- ɤƤӽФ.
+*** /Ϣ
- super(...)
+Υ֥Ȥ뼰ηϰʲηǤ.
- ȤȤ˥ѡ饹Ʊ̾Υ᥽åɤƤӽФ. ֺǸ
- ΰ`*'³̾Υ᥽åɸƤӽФƱͤϤ.
+ '[' , ... ']'
-** 黻
+줾μɾ̤ޤ֤. ǿ0ζ
+뤿ˤ϶
+
+ '[' ']'
+
+Ѥ.
+
+** Ϣ
+
+ϢȤǤդΥ֥Ȥ򥭡(ź)ȤƻƤǤ. Ruby
+ǤϢSmalltalkѸڤDict()ȤƤФ. ܺ٤ϥ
+饹Dictι򻲾Ȥ줿. ϢϢ󼰤ϰʲη
+.
+
+ '{' '=>' ... '}'
+
+줾μɾ̤򥭡ͤȤϢ󥪥֥Ȥ֤.
+ǿ0Ϣ뤿ˤ϶Ϣ
+
+ '{' '}'
+
+Ѥ.
+
+*** 󻲾,
+
+(Ϣޤ)ǤλȤϰʲηǹԤʤ.
+
+ 1 '[' 2... ']'
+
+ηŪ, 1"[]"ȤåȲᤵ.
+ư򵿻ŪʥɤǵҤаʲΤ褦ˤʤ.
+
+ 1"[]="(2)
+
+, Ǥ
+
+ 1 '[' 2... ']' '=' n
+
+ȤǹԤʤ,
+
+ 1."[]="(2..)
+
+ȤȤƲᤵ.
+
+*** 黻ҷ
ץߥ󥰤ؤΤ˰Υ᥽åɸƤӽФ湽¤ϱ黻ҷ
Ȥ. Rubyˤϰʲˤ黻Ҥ. ΤΤۤɷ̤,
@@ -335,68 +361,33 @@ RubyδŪʬ˾, ʸˡ㳰ʤΤǿȤˤĤΤ
||
.. ...
::
- =() (+=, -=, ..)
- yield
+ =() (+=, -=, ..)
ۤȤɤα黻ˤϥ᥽åɸƤӽФȤƲᤵ(饹˺
Ǥ), ǤʤüʤΤ. Ǥʤü黻
Ҥ
&&(), ||(), =(), ...(ϰϻ),
- yield(֥åƤӽФ)
-5ĤǤ.
+4ĤǤ.
Ǥü黻Ұʳα黻ҷϥ᥽åɸƤӽФȸʤ.
ñ黻(+, -, !, ~)
- 1."黻"()
-
-Ȥ, 2黻Ҥ
+ 1."黻"()
- 1."黻"(2)
+Ȥ, ʳ2黻Ҥ
-˲ᤵ. ¿黻(λȤ[])ϱ黻ҷ̤ʷȤ
+ 1."黻"(2)
- recv[arg..]
-
-,
-
- recv."[]"(arg..)
-
-Ȳᤵ. ǤؤƱͤ
-
- recv[arg0..] = argn
-
-,
-
- recv."[]="(arg0.., argn)
-
-Ȳᤵ.
-
-** P
-
-if, unless, while, untilξȽμ, ü黻`&&', `||',
-`...'ξդμ, ̾黻`!'αդϾPȸƤФ. PǤʸ
-ɽƥϼ$_=~ƥפξάǤȤߤʤ.
-黻`...'ξդǤ$.==פξάȲᤵ.
-
-: 黻`!'ü黻ҤǤϤʤΤ, Ԥʤ˵Ĥ
-뤳.
-
- ! ʸƥ
- ! ɽƥ
-
-ηǸƤӽФ᥽åɤΰ, ƥɽ֥ȤǤϤʤ,
-嵭Ӥη̤Ϳ. Τ, §Ū`!'᥽åɤϺ
-ʤɤȻפ.
+˲ᤵ.
**
ˤѿФ(), ץñˤ뤿Υ
å奬ȤƤ. ϰʲηǤ.
- ѿ =
+ ѿ '='
ϼɾ, ѿͤȤ. 饹⥸塼䵿ѿ
ˤǤʤ. 饹⥸塼ѹ뤿ˤclassʸ,
@@ -405,171 +396,207 @@ moduleʸѤ. ϱ黻ҷȤäƤ뤬, ᥽åɤǤϤʤ
󥿥å奬ȤƤϰʲΤΤ.
- Ǥؤ
+Ǥؤ
- 1[2,..] = n
+ 1'[' 2... ' ]' '=' n
- 1ɾ륪֥Ȥ, 2鼰nޤǤȤ
- , "[]="Ȥ᥽åɤƤӽФ.
+1ɾ륪֥Ȥ, 2鼰nޤǤȤ, "[]="
+Ȥ᥽åɤƤӽФ.
- °
- 1.̻ = 2
+ 1 '.' ̻ '=' 2
- 1ɾ륪֥ȤФ"̻="Ȥ᥽
- ɤ, 2ȤƸƤӽФ.
+1ɾ륪֥ȤФ"̻="Ȥ᥽åɤ,
+2ȤƸƤӽФ.
-
+
- 1 op= 2 # 1ǽǤʤФʤʤ.
+ 1 op= 2 # 1ǽǤʤФʤʤ.
- ηŪˡּ1 = 1 op 2פŸ, ¹Ԥ.
- ἰ12ɾΤ, Ѥͽۤʤ̤Ƥ
- ǽ. ϥץޤΥ׿򸺤餹ŪΤ
- ¸ߤǤ. opȤƻȤ黻Ҥ
+ηŪˡּ1 = 1 op 2פŸ, ¹Ԥ. Τ
+12ɾΤ, Ѥͽۤʤ̤Ƥֲǽ
+. ϥץޤΥ׿򸺤餹ŪΤ¸ߤ
+Ǥ. opȤƻȤ黻Ҥ
+, -, *, /, %, **, &, |, ^, <<, >>
- 11Ǥ. 黻Ҥ`='δ֤˥ڡƤϤʤ.
-
-*** ¿
-
-ƱʣѿԤʤȤǤ. ηϰʲ̤Ǥ.
+11Ǥ. 黻Ҥ`='δ֤˥ڡƤϤʤ.
- ѿ, [ѿ,...] = [, ]
+*** ʬ
-դμĤʤ, ͤȤ(ɬפʤto_a᥽
-ɤѴ), Ǥ򤽤줾ѿ. ʳξˤ,
-줾μͤѿ. դѿοȱդǤο
-ʤˤ­ʤѿˤ nil, ;äǤ̵뤵.
+ͤˤäʬ뼰ϰʲ˼if, unless, caseʣʸ
+3ȱ黻ҷ3ढ. RubyǤnil, ʳɾ.
+CPerlʤɤȤϰۤʤ, 0 ""(ʸ)ϵȤɾʤΤǵ
+뤳.
- foo, bar = [1, 2] # foo = 1; bar = 2
- foo, bar = 1, 2 # foo = 1; bar = 2
- foo, bar = 1 # foo = 1; bar = nil
-
- foo, bar, baz = 1, 2 # foo = 1; bar = 2; baz = nil
- foo, bar = 1, 2, 3 # foo = 1; bar = 2
-
-** ʬ
+if
if 1 [then]
ʸ1
- [ elsif 2 [then]
+ [elsif 2 [then]
ʸ2 ]...
- [ else
+ [else
ʸn ]
- end [ if ]
+ end
- Ƚʸ. else if ǤelifǤʤelsififϢ³ԤʤȤ
- դ뤳.
+ȽǼ. 1ξʸ1ɾ. ʳξʸ2ɾ
+. Rubyifelse ifǤelifǤʤelsififϢ³ԤʤȤ
+դ뤳.
+
+unless
unless 1 [then]
- ʸ1
- [ else
+ ʸ1
+ [else
ʸ2 ]
- end [ unless ]
-
- 1(nil)֤, 2ɾ㳰ȯʸ1ɾ
- .
-
- 1 && 2
-
- 1ɾ, ͤ(nilʳ)Ǥ, 2ɾ.
-
- 1 || 2
-
- 1ɾ, ͤǤ, 2ɾ.
+ end
- 1 ... 2
+1(nil)֤, 2ɾ㳰ȯʸ1ɾ.
+ʳξʸ2ɾ.
- 1ˤʤޤǤϵ֤, θϼ2֤ޤǤϿ֤.
- 2ˤʤо֤ϵ
+case
case 0
- [ when 1 [, 2]...
+ [when 1 [, 2]...
ʸ1 ]...
- [ else
+ [else
ʸn ]
- end [ case ]
+ end
- ʬ, CswitchPascalcase˻Ƥ. breakæФ뤳
- Ȥʸ˷³뤳ȤʤΤ.
+ʬ, CswitchPascalcase˻Ƥ. breakæФ뤳Ȥ
+ʸ˷³뤳ȤʤΤ.
- ΰפϡּn =~ 0]ǹԤʤ. Ĥޤ,
+ΰפϡּn =~ 0]ǹԤʤ. Ĥޤ,
- case expr0
- when expr1, expr2
- stmt1
- when expr3, expr4
+ case expr0
+ when expr1, expr2
+ stmt1
+ when expr3, expr4
+ stmt2
+ else
+ stmt3
+ end
+
+ϰʲifʸǤ.
+
+ _tmp = expr0
+ if expr1 =~ _tmp || expr2 =~ _tmp
+ stmt1
+ elsif expr3 =~ _tmp || expr4 =~ _tmp
stmt2
- else
+ else
stmt3
- end
+ end
+
+黻ҷ
+
+ 1 '&&' 2
+
+1ɾ, ͤ(nilʳ)Ǥ, 2ɾ.
+
+ 1 '||' 2
- ϰʲifʸǤ.
+1ɾ, ͤǤ, 2ɾ.
- _tmp = expr0
- if expr1 =~ _tmp || expr2 =~ _tmp
- stmt1
- elsif expr3 =~ _tmp || expr4 =~ _tmp
- stmt2
- else
- stmt3
- end
+ 1 '...' 2
-** ֤
+1ˤʤޤǤϵ֤, θϼ2֤ޤǤϿ֤. 2
+ˤʤо֤ϵ
+
+*** ֤(ñ㷿)
+
+롼פ뼰. μͤϾnilǤ. ֥Ȥ˹
+롼פԤʤˤϼ˽Ҥ٤륤ƥ졼Ѥ.
+
+while
while
ʸ
- end [ while ]
+ end
+
+郎δ, ʸ򷫤֤¹Ԥ.
- 郎δ, ʸ򷫤֤¹Ԥ.
+until
until
ʸ
- end [ until ]
+ end
1 until 2
- (nil)֤, ɾ㳰ȯ, ʸ򷫤֤
- Ԥ.
+(nil)֤, ɾ㳰ȯ, ʸ򷫤֤¹Ԥ
+.
+
+*** PˤĤ
+
+if, unless, while, untilξȽμ, ü黻`...'ξ
+μϾPȸƤФ. PǤʸɽƥϼ$_=~
+ƥפξάǤȤߤʤ. ˱黻`...'ξդǤ
+$.==פξάȲᤵ. P˸黻 `&&', `||', `!'
+դμPȤߤʤ.
+
+: 黻`!'ü黻ҤǤϤʤΤ, Ԥʤ˵Ĥ
+뤳. P
+
+ ! ʸƥ
+ ! ɽƥ
+
+ηǸƤӽФ᥽åɤΰ, ƥɽ֥ȤǤϤʤ,
+嵭Ӥη̤Ϳ. Τ, §Ū`!'᥽åɤϺ
+ʤɤ.
+
+*** ƥ졼(֤)
** ƥ졼
ƥ졼Ȥ湽¤(ä˥롼)ݲΤѤ᥽åɤ
+Ǥ. ɤ(֥åȸƤФ)ꤷƥƥ졼Ƥ
+Ф, ƥ졼Ŭͤ򥻥åȤƥ֥åɾ(餯
+ʣ). ƥ졼Υ֥åθƤӽФyieldѤ().
+
+ƥ졼θƤӽФϰʲιʸǹԤʤ.
+
+ƥ졼Ȥ湽¤(ä˥롼)ݲΤѤ᥽åɤ
Ǥ. ƥ졼θƤӽФϰʲιʸǹԤʤ.
- do
- ʸ1
- using ѿ
- ʸ2
- end [ do ]
-
- ʸ2פ֥åȤꤷ, ʸ1Υ᥽åɤ򥤥ƥ졼Ȥɾ
- . ʸ1Υȥåץ٥Υ᥽åɤƥ졼ȤƸƤӽФ,
- 쥷Фɽ, μϥƥ졼ȤƤϸƤӽФʤ. ʸ
- 1ʣμгơƥ졼Ȥƽ˸ƤФ.
-
-ƥ졼yield value¹Ԥ, ͤdoʸǻꤵ줿ѿ
-֥å¹Ԥ. ֥åμ¹ԤλȤͤ
-yieldͤȤ֤. ᥽åɤƥ졼ȤƸƤӽФ줿
-ɤϴؿiterator_p()Τ뤳ȤǤ. ˤEnumerable⥸塼
-grep᥽åɤΤ褦˥ƥ졼ȤƸƤФ줿̤Υ᥽åɤȤ
-ƸƤФ줿Ȥưۤʤ᥽åɤ⤢.
-
- for ѿ in
+ '{' ѿ... '|' ʸ '}'
+
+ʸפ֥åȤꤷ, ּפΥ᥽åɤ򥤥ƥ졼Ȥɾ
+. ּפΥȥåץ٥Υ᥽åɤƥ졼ȤƸƤӽФ,
+쥷Фɽ, μϥƥ졼ȤƤϸƤӽФʤ. ּ
+ʣμޤ, ơƥ졼Ȥƽ˸ƤФ.
+
+ƥ졼yieldʸ¹Ԥ, ǻꤵ줿ͤdoʸǻꤵ
+줿ѿ, ֥å¹Ԥ. ֥åμ¹ԤλȤ
+ͤ yieldʸͤȤ֤. ᥽åɤƥ졼ȤƸƤӽ
+줿ɤϥ᥽åiterator_p()ͤΤ뤳ȤǤ. ˤ
+Enumerable⥸塼grep᥽åɤΤ褦˥ƥ졼ȤƸƤФ줿
+̤Υ᥽åɤȤƸƤФ줿Ȥưۤʤ᥽åɤ⤢.
+
+֥ȤγǤФԤʤη󶡤Ƥ.
+ϰʲ̤.
+
+ for ѿ.. in
ʸ
- end [ for ]
+ end
- γǤФʸ¹Ԥ. ϰʲdoʸǤ.
+γǤФʸ¹Ԥ. ϰʲμǤ.
- do ().each using ѿ
- ʸ
- end
+ '{' ѿ '|' ʸ '}'
+
+äƼͤΥ֥Ȥ᥽åeachʤ, for¹Ԥ
+㳰ȯ.
+
+*** ƥ졼ǤΥ֥åƤӽФ
+
+ yield '(' [ [',' ...]])
+ yield
- äƼͤΥ֥Ȥ᥽åeachʤ, for¹
- 㳰ȯ.
+ƥ졼ǥ֥åθƤӽФԤʤ. yield¹Ԥ᥽åɤ
+ƥ졼ȤƸƤӽФƤʤˤ㳰ȯ. yield ͤϥ
+åͤǤ.
-** 㳰
+*** 㳰
ͽʤ֤ȯˤ㳰ȯ. RubyǤ㳰
ª, ƻԤ, Ԥʤäꤹ뤳ȤǤ.
@@ -580,116 +607,212 @@ yieldͤȤ֤. ᥽åɤƥ졼ȤƸƤӽФ줿
ʸ2 ]
[ ensure
ʸ3 ]
- end [ protect ]
+ end
+
+ʸ1¹Ԥ, μ¹㳰ȯresqueǻꤵ줿ʸ2¹
+. ensure᤬¸ߤprotectʸλɬ(ェλ
+Ǥʤ, 㳰, return, break, continue, redoʤɤˤæФǤ)ʸ3
+¹Ԥ.
+
+unlessʸ, untilʸϾɾ㳰ȯ, ɾ̤
+ǤȸʤΤ, ۤ㳰ԤʤäƤ뤳Ȥˤʤ.
+
+*** 롼ԥ
+
+ϳ̤ˤäƥ롼ԥ󥰤뤳ȤǤ.
+
+ '(' ')'
+
+˳̤Ѥ, ʸ(ޤʸ¤)򼰤ˤ뤳ȤǤ.
+
+ '(' ʸ ';' ʸ... ')'
+
+ʸ¤ӤͤϺǸɾͤǤ. ĤޤͤϺǸɾʸ
+ͤˤʤ.
+
+** ʸ
+
+Rubyץ⤦ĤǤʸǤ. ʸˤñʸ, ʸ,
+ʸ. ̤ʸͤѤ뤳ȤϤʤ, ȤѤ
+⤢Τ, ͤ. ̾ʸͤnilǤ.
+
+***
+
+ñʸǤ.
+
+*** ¿
+
+ƱʣѿԤʤȤǤ. ηϰʲ̤Ǥ.
+
+ ѿ ',' [ѿ ',' ...] ['*' ѿ]= [, ...]
+
+դμĤʤ, ͤȤ(ɬפʤto_a᥽
+ɤѴ), Ǥ򤽤줾ѿ. ʳξˤ,
+줾μͤѿ. դѿοȱդǤο
+ʤˤ­ʤѿˤ nil, ;äǤ̵뤵. ¿
+κǸǤ`*', ĤưȤ
+.
+
+ foo, bar = [1, 2] # foo = 1; bar = 2
+ foo, bar = 1, 2 # foo = 1; bar = 2
+ foo, bar = 1 # foo = 1; bar = nil
+
+ foo, bar, baz = 1, 2 # foo = 1; bar = 2; baz = nil
+ foo, bar = 1, 2, 3 # foo = 1; bar = 2
+ foo,*bar = 1, 2, 3 # foo = 1; bar = [2, 3]
+
+¿ñʸǤ. ͤ(Ѵ줿)դǤ.
- ʸ1¹Ԥ, μ¹㳰ȯresqueǻꤵ줿ʸ2
- ¹Ԥ. ensure᤬¸ߤprotectʸλɬ(
- ェλǤʤ, 㳰, return, break, continue, redoʤɤˤ
- æФǤ)ʸ3¹Ԥ.
+*** ʸ
-protectʳ, unless黻, until黻Ҥϱդͤ㳰ȯ
-, դͤȤƵͿ줿ȸʤΤ, ۤ㳰
-ԤʤäƤ뤳Ȥˤʤ.
+ήѹʲʸ. ñʸǤ.
-** æ
+returnʸ
- return []
+ return [[, ...]]
- ᥽åɤμ¹Ԥλ.
+ͤͤȤƥ᥽åɤμ¹Ԥλ. 2İʾͿ줿
+ˤ, ǤȤ᥽åɤͤȤ. Ĥʤ
+ˤ nil ͤȤʤ.
+
+롼ʸ
continue
redo
break
- 嵭3Ĥϥ롼ǻȤ.
+嵭3Ĥϥ롼ǻȤ.
+
+continueϤäȤ¦Υ롼פμη֤Ϥ. redoϥ롼׾
+ΥåԤʤ鷺, ߤη֤ľ. break ϥ롼פæФ
+. CȰ㤤, breakϤäȤ¦Υ롼פæФѤ, case
+ȴѤϻʤ.
- continueϤäȤ¦Υ롼פμη֤Ϥ. redoϥ롼
- Υ롼׾ΥåԤʤ鷺, ߤη֤ľ. break
- ϥ롼פæФ. CȰ㤤, breakϤäȤ¦Υ롼פæФ
- Ѥ, caseȴѤϻʤ.
+retryʸ
retry
- protectʸresqueǻȤ, protectʸϤᤫ¹Ԥ. 㳰
- ԤʤäƤƻԤΤ˻Ȥ.
+protectʸresqueǻȤ, protectʸϤᤫ¹Ԥ. 㳰Ԥʤ
+ƤƻԤΤ˻Ȥ. resqueʳretryѤ줿㳰ȯ
+.
+
+failʸ
+
+ fail '(' [å] ')'
+ fail [å]
+
+㳰ȯ. åͿ줿ˤȯե
+̾, ֹ򥷥ƥѿ`$@', å`$!'˥åȤ.
+
+yieldʸ
+
+ yield [',' ...]
+
+ʸȤyieldѤ뤳ȤǤ. ξϼ̤dzɬפϤʤ.
+
+*** ᥽åɸƤӽФʸ
+
+1İʾĥ᥽åɤʸȤƸƤӽФˤϰ̤dzɬ
+פϤʤ. ηϰʲ̤Ǥ.
+
+ '.' ᥽å̾ 1 ',' [ 2... ][ '*' n ]
+ ᥽å̾ 1 ',' [ 2... ][ '*' n ]
+ super 1 ',' [ 2... ][ '*' n ]
+
+ʸϻ, Τ褦˲ǤϼȤƤβ᤬ͥ褵.
+
+ foo bar+baz # ᥽åɸƤӽФfoo(bar+baz)
+ foo (bar)+baz # ᥽åɸƤӽФfoo(bar) + bar
+ foo 1 # ᥽åɸƤӽФfoo(1)
+ foo -1 # ѿfoo - 1
+
+᥽åɸƤӽФʸñʸǤ.
- fail([å]) * Kernel饹Υ᥽åɤǤ.
+*** 潤
- 㳰ȯ. åͿ줿ˤȯե
- ̾, ֹ$@˥å$!˥åȤ.
+ñʸ潤ҤղäΤʸǤ(ñʸǤϤʤ). Ҥϰ
+4Ǥ.
-** ƥ졼ǤΥ֥åƤӽФ
+ ñʸ if
+ ñʸ unless
+ ñʸ while
+ ñʸ until
- yield
+、(if/unless)μԤʸäɾ. ưб
+ʬƱͤǤ.
- ƥ졼ǥ֥åθƤӽФԤʤ. yield¹Ԥ᥽
- ɤƥ졼ȤƸƤӽФƤʤˤ㳰ȯ.
+֤(while/until)ϤޤԤʸɾƤPɾ
+Τ, ٤ʸ¹Ԥ뤳Ȥˤʤ.
-** 饹
+*** 饹ʸ
饹빽ʸϰʲ̤Ǥ.
- class 饹̾ [ : ѡ饹̾ ]
+ class 饹̾ [':' ѡ饹̾ ]
- end [ class ]
+ end
-ͤnil. 饹̾ʸǻϤޤ뼱̻ҤǤ. 饹ΥͥȤϤ
-ʤΤ¾ʸǤϥ饹Ǥʤ.
+饹̾Ǥդμ̻ҤǤ(ʸǻϤ뤳Ȥ侩). 饹
+ΥͥȤϤǤʤΤ¾ʸǤϥ饹Ǥʤ.
-** ⥸塼
+*** ⥸塼ʸ
⥸塼빽ʸϰʲ̤Ǥ.
module 饹̾
- end [ module ]
+ end
⥸塼̾ʸǻϤޤ뼱̻ҤǤ. 饹Ʊ, ⥸塼
ͥȤǤʤ.
-** 󥯥롼
+*** 󥯥롼ʸ
-饹˥⥸塼򥤥󥯥롼ɤ빽ʸϰʲ̤Ǥ.
+⥸塼򥤥󥯥롼ɤ뤳Ȥˤä, 饹ޤϥ⥸塼˵ǽ
+ɲäǤ. ⥸塼򥤥󥯥롼ɤ, Υ⥸塼(
+Υ⥸塼뤬˥󥯥롼ɤƤ⥸塼)ƤΥ᥽åɤ
+Ѥ. ̤Τ򤹤Х󥯥롼ɤϸꤵ줿¿ŷѾȤ.
- include ⥸塼̾ [, ⥸塼̾...]
+¾Υ⥸塼򥤥󥯥롼ɤ빽ʸϰʲ̤Ǥ.
-ߤΥ饹ޤϥ⥸塼(ȥåץ٥ǤObject)˻ꤷ
-⥸塼򥤥󥯥롼ɤ. ˤä¿ŷѾ򥨥ߥ졼ȤǤ.
+ include ⥸塼̾ [',' ⥸塼̾...]
-** ᥽å
+ߤΥ饹ޤϥ⥸塼(ȥåץ٥ǤObject饹)˻
+ꤷ⥸塼򥤥󥯥롼ɤ.
+
+*** ᥽åʸ
̾(ðۥ᥽åɤǤʤ)᥽åηϰʲ̤Ǥ. ̾᥽
ϥͥȤǤʤΤ, ᥽åʸǤϥ᥽åʸƤӸ
ӽФʤ.
- def ᥽å̾ [ ( [, ...][, * ] ) ]
+ def ᥽å̾ [ '(' [',' ...][',' '*' ] ')' ]
- end [ def ]
+ end
᥽å̾ϼ̻ҤޤʸǤ. 黻Ҥκ򤹤ˤʸ
ǻꤹ. ¤ӤκǸ`*', ¿Ϳ줿
°, ǸΰȤͿ(­ʤˤϥ顼).
-** ðۥ᥽å
+** ðۥ᥽åʸ
-᥽åˤϤ⤦ðۥ᥽åɤ. ϰʲ̤Ǥ
-.
+᥽åˤϤ⤦ðۥ᥽åɤ. ðۥ᥽åɤȤϤ
+Υ֥Ȥ˸ͭΥ᥽åɤǤ. ϰʲ̤Ǥ.
- def .᥽å̾ [ ( [, ...][, * ] ) ]
+ def '.' ᥽å̾ [ '(' [',' ...][',' '*' ] ')' ]
- end [ def ]
+ end
-ηϼͤǤ륪֥Ȥðۥ᥽åɤ. ͤ
+ηϼͤǤ륪֥Ȥðۥ᥽åɤ. ͤ
(ӥȥ󥯥饹Ǥʤ)̾索֥Ȥ, 饹ޤϥ⥸塼Ǥ
-ɬפ. ̾᥽åȤϰۤʤ, ϥ᥽åǤ
-ȤƸƤӽФȤǤ.
+ɬפ. ̾᥽åȤϰۤʤ, ðۥ᥽åɤϥ᥽å
+ǤͥȤ뤳ȤǤ.
-ðۥ᥽åɤΥ֥Ȥˤ°᥽åɤǤ. ä̾
-ϷѾʤ, 㳰Ȥƥ饹ðۥ᥽åɤϤΥ֥饹ˤ
-. ؤХ饹ðۥ᥽åɤ¾Υ֥Ȼظ
-ˤ륯饹᥽åɤƯ򤹤.
+ðۥ᥽åɤ̾ϷѾʤ, 㳰Ȥƥ饹ðۥ᥽åɤϤ
+Υ֥饹ˤѾ. ؤХ饹ðۥ᥽åɤ¾Υ
+Ȼظƥˤ륯饹᥽åɤƯ򤹤.
-** ᥽åɤ̾
+*** ᥽åɤ̾ʸ
ʲηǥ᥽åɤ̾Ĥ뤳ȤǤ.
@@ -699,7 +822,7 @@ protectʳ, unless黻, until黻Ҥϱդͤ㳰ȯ
åɤƤ, Ť᥽åɤƤӽФ줿ΤƱƯ
.
-** ᥽åä
+*** ᥽åäʸ
᥽åɤäˤundefѤ.
@@ -708,10 +831,11 @@ protectʳ, unless黻, until黻Ҥϱդͤ㳰ȯ
̻Ҥޤʸǻꤷ᥽åɤä.
defˤ̾undefˤäȤȥ饹Υ󥿥ե
-򥹡ѥ饹Ωѹ뤳ȤǤ. , ʬȤ˥å
-äƤդʤȴ¸Υ᥽åɤưʤʤǽ
-.
-
+򥹡ѡ饹Ωѹ뤳ȤǤ. , ᥽åɤself
+˥åäƤˤϤ褯դʤȴ¸Υ᥽åɤư
+ʤʤǽ.
+
+-------------------------------------------------------
* RubyȤ߹ߵǽ
Rubyץߥ󥰤δܤϥ饹, ⥸塼ȤΥ᥽åɤνǤ.
@@ -719,8 +843,6 @@ RubyˤϽϤΤΤ˰ʲεǽȤ߹ޤƤ. 饤֥
ɤ뤳ȤˤäƵǽ뤬, ˴ؤƤϤ줾Υ饤֥
ΥɥȤ򻲾ȤƤ餤.
-ü`+'ΤĤ᥽åɤϴؿ᥽åɤǤ.
-
** ؿ
Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
@@ -728,50 +850,38 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
᥽åɤʲˤ. Υ᥽åɤݤˤϸߴ
ͤƹԤʤ٤Ǥ.
- _exit(status) +
+ _exit(status)
ץμ¹Ԥλ. statusλơȤ.
exit()Ȥϰä, 㳰ʤɤϰڹԤʤʤ. fork()θ,
ץλʤɤѤ.
- caller +
- caller(level) +
-
- åե졼फ, ᥽åɤθƤӽФΥե
- ̾, ֹ, ǤȤ֤. levelͿ줿
- ϸߤΥåե졼levelʾξ֤.
-
- eof() +
+ eof()
ޥɥ饤󤫤ϤEOFãƤ, ֤.
- eval(expr) +
+ eval(expr)
exprȤͿ줿ʸrubyץȤƲ,¹Ԥ.
- exec(command) +
+ exec(command)
߼¹ԤƤץλ, commandʸǻꤵ
̥ץư.
- exit([status]) +
+ exit([status])
ץμ¹Ԥλ. statusȤͿ줿,
ͤRubyޥɤνλơȤ. ǥեȤ0.
- fail([message]) +
-
- 㳰ȯ. åͿ줿ˤϤ򥷥ƥ
- ѿ`$!'˥åȤ, ȯ֤򥷥ƥѿ`$@'˥åȤ.
-
- fork() +
+ fork()
forkƥॳ¹Ԥ, ҥץ. ܺ٤
fork(2)򻲾ȤΤ. ƥץ¦ǤϻҥץΥץid
֤, ҥץ¦Ǥnil֤. 餫θǻҥץ
˼Ԥˤ㳰ȯ.
- format(format, ...) +
+ format(format, ...)
եޥåȤȤͿ줿ʸCsprintfƱ褦
ᤷ, Ÿʸ֤. ᥽åsprintf()̾.
@@ -779,46 +889,47 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
RubyˤformatҤγĥˤĤƤsprintf()ι򻲾Ȥ
.
- getc() +
+ getc()
ɸϤʸФ. ͤɤ߹ʸʸ
(ASCII)ɽFixnumǤ.
- getenv(name) +
+ getenv(name)
- name˳ĶѿФ.
+ name˳ĶѿФ. $ENV[name]Ʊ.
- gets(pattern, replace) +
+ gets()
- ȤͿ줿ե(ʤɸ)ɤ߹
- , ɤ߹ߤˤϤʸ֤. եν
- ãˤnil֤. Ԥζڤϥƥѿ`$/'ˤä
- ѹǤ. ɤ߹ʸϥƥѿ`$_'ˤ⥻åȤ.
+ ȤͿ줿ե(ʤɸ)ǹ벾
+ Ūʥե($ARGFǥǤ)ɤ߹, ɤ߹
+ ߤˤϤʸ֤. եνã
+ ˤnil֤. Ԥζڤϥƥѿ`$/'ˤäѹǤ.
+ ɤ߹ʸϥƥѿ`$_'ˤ⥻åȤ.
- gsub() +
+ gsub(pattern, replace)
ƥѿ`$_'λؤʸФִԤʤ. ʸ
pattern˥ޥåʬreplace֤. String饹
gsub᥽åɤβ򻲾ȤΤ.
- iterator_p() +
+ iterator_p()
᥽åɤƥ졼ȤƸƤӽФ줿˿, Ǥʤ˵
֤Ҹ.
- kill(signal, pid...) +
+ kill(signal, pid...)
pidǻꤵ줿ץ˥ʥ. ʥϥʥ
椫̾ǻꤹ. ͤĥʥ(뤤ϥʥ̾
`-')ͿȥץǤϤʤץ롼פ˥ʥ
.
- load(file) +
+ load(file)
fileɤ. fileɤѥϥƥѿ$LOAD_PATH
Ƿꤵ.
- open(file[, mode]) +
+ open(file[, mode])
file򥪡ץ󤷤, File֥Ȥ֤. ե̾ϥ
󤹤ե򼨤. ե̾`|'ǻϤޤˤ³ʸ
@@ -860,7 +971,7 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
ѿ`$\'(ϥեɥѥ졼)nil ǤʤͤåȤ
ˤ, ǸˤϤ.
- printf([port, ]format, arg1, ..., argn) +
+ printf([port, ]format, arg1, ..., argn)
Cprintf()Ʊformat˽ʸѴ, Ϥ
. 1IOΥ֥饹Υ󥹥󥹤ǤäϤΥ
@@ -869,7 +980,7 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
RubyˤformatҤγĥˤĤƤsprintf()ι򻲾Ȥ
.
- rand(max) +
+ rand(max)
0maxۤʤϰϤȯ. ͤFixnum.
@@ -880,7 +991,7 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
ϺƥɤʤǤ. ºݤ˥ɤˤ%TRUE,
˥ɤƤˤ%FALSE֤.
- select(reads[, writes[, execpts[, timeout]]]) +
+ select(reads[, writes[, execpts[, timeout]]])
select(2)¹Ԥ. reads/writes/execptsˤIO(ޤϤΥ
饹)Υ󥹥󥹤Ϳ. timeoutFixnum / Float
@@ -888,17 +999,18 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
nil, ǤʤȤ3Ǥ֤, γǤ//
㳰ԤΥ֥ȤǤȤƻ.
- setenv(name, value) +
+ setenv(name, value)
- nameǻꤵĶѿvalue˥åȤ.
+ nameǻꤵĶѿvalue˥åȤ. $ENV[name]=value
+ ƱƯ򤹤.
- sleep([sec]) +
+ sleep([sec])
secäץμ¹Ԥߤ. secά줿, ץ
SIGALRMʤ¤, ʵפ˥꡼פ. ºݤ˥꡼
פÿ֤.
- sprintf(format, ...) +
+ sprintf(format, ...)
formatʸCsprintfƱ褦˲ᤷ, Ÿ
ʸ֤. ᥽åformat()̾.
@@ -910,40 +1022,40 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
8 , 16ʿɽԤʤ, ονκݤ2ɽ
Ϥʤ, ɽƬ`-'ĤΤɽ.
- srand([]) +
+ srand([])
νͤꤷ, Ť֤ͤ. ͤά줿
time(3)֤ͤǥեȤȤ.
- sub() +
+ sub(pattern, replace)
ƥѿ`$_'λؤʸФִԤʤ. ʸǺ
pattern˥ޥåʬreplace֤. String饹
sub᥽åɤβ򻲾ȤΤ.
- syscall(num, arg...) +
+ syscall(num, arg...)
numǻꤵ줿ֹΥƥॳ¹Ԥ. 2ʹߤ
ƥॳΰȤϤ. ʸޤǤʤ
ʤʤ.
- system(command) +
+ system(command)
ޥɤ¹Ԥ, νλơ֤.
- trap(command, signal...) +
+ trap(command, signal...)
signalγߤäcommand¹Ԥ. signalϥ
- ʥ̾ʥֹ. commandȤSIG_IGNޤIGNORE
- ˤϤΥʥ̵뤹(ǽʤ). SIG_DFLޤ
- DEFAULTꤷϥǥեȤưԤʤ.
+ ʥ̾ʥֹ. commandȤ"SIG_IGN"ޤ"IGNORE"
+ ꤷˤϤΥʥ̵뤹(ǽʤ). "SIG_DFL"
+ "DEFAULT"ꤷϥǥեȤưԤʤ.
- wait() +
+ wait()
ҥץλΤԤ, λҥץpid֤.
ҥץĤʤnil֤.
- waitpid(pid, flags) +
+ waitpid(pid, flags)
λҥץνλԤ, Υץλ˿
. ҥץ¸ߤʤ, Υ֥å󥰥⡼ɤǻҥץ
@@ -953,7 +1065,7 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
** ƥѿ
- $! 顼å. fail()ꤹ.
+ $! 顼å. failꤹ.
$@ 顼ȯΥե̾ȹֹ椬
@@ -1007,7 +1119,8 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
$ENV Ķѿ˥Ϣ(EnvDict). ѿ
`for'Ԥʤѿ̾ͤΥڥͿ.
- $FILENAME ؿgets()Ǹɤ߹Υե̾.
+ $FILENAME ۥե$ARGFǸɤ߹Υե̾. ᥽
+ gets()ɤǤե̾.
$DEBUG `-d'ե饰ξ()
@@ -1020,28 +1133,97 @@ Rubyˤϸ̩ʰ̣ǤϴؿϤʤKernel饹Υ᥽åɤΰ(
$stdout ɸ
$stderr ɸ२顼
+ $ARGF (ʤɸ)ǹ벾ۥե. Ĥޤ
+ gets()$ARGF.gets()Ʊ̣Ǥ.
+
$VERBOSE `-v'ե饰ξ()
$VERSION rubyΥС򼨤ʸ
** ƥ
- %TRUE 1(Fixnum)
+ %TRUE t
%FALSE nil
줾쿿ͤɽ. ȽǤnil, ʳƤͤ
- ȤȽǤ뤿, ֤ͤ᥽åɤ%TRUEʳͤ
- Τ¸ߤΤ, ӤѤΤŬڤǤʤȤդ
- Ǥ. 㤨мμϿˤʤʤ.
+ ȤȽǤ뤿, %TRUEͤɽŪʿͤȤʾΰ
+ ̣ʤ. ä, ᥽åɤͤǤȤȤ,
+ 줬%TRUE֤ȤȤϸ̩ˤƱǤϤʤ(ҸŪѤ
+ ᥽åɤ񿿤ͤȤ%TRUE֤褦ˤϤʤäƤ
+ ). Ĥޤ
+
+ if some.method() then .. else .. end
- (2 < 3) == %TRUE
+
- ᥽å"<"Ͽλ֤ͤΤ, ξͤ3Ǥ,
- %TRUE1Ȥϰۤʤ. %FALSE˴ؤƤ, Τ褦
+ if some.method() == %TRUE then .. else .. end
+
+ ϴˤƱǤϤʤ. %FALSE˴ؤƤ, Τ褦
ʤ.
** 饹/⥸塼
+*** ARGFILE(饹)
+
+ǻꤵ줿ե(ͿƤʤˤɸ)ǹ
+벾ۥե򥢥뤿Υ饹. Υ饹ðۥ᥽
+ɤ, ⥸塼ŪʻȤ򤵤. 饹̾Ǥʤƥ
+ѿ$ARGFǤ⻲ȤǤ.
+
+ while gets()
+ ...
+ end
+
+
+
+ for $_ in $ARGF
+ ...
+ end
+
+Ʊ̣, Ԥ, 򤷤䤹, ƥ֥å
+ΥȤΤ㴳٤.
+
+SuperClass: Object
+
+Included Modules: Enumerable
+
+Methods:
+
+ each
+
+ ƹ˷֤ƥ졼
+
+ each_byte
+
+ ʸ˷֤ƥ졼
+
+ eof
+
+ ɤ߹Ǥե(ۥեΤǤϤʤ)
+ ã˿֤.
+
+ getc
+
+ ۥե뤫1ʸɤ߹. ͤʸɤɽ
+ . եνãˤnil֤. Υ᥽åɤ
+ ɤ߹, ƥѿ`$.'Ѳʤ.
+
+ gets
+ readline
+
+ ۥե뤫ɤ߹, ɤ߹ߤˤϤʸ
+ ֤. եνãˤnil֤. Ԥζ
+ ϥƥѿ`$/'ˤäѹǤ. ɤ߹ʸϥ
+ ƥѿ`$_'ˤ⥻åȤ.
+
+ read
+
+ ۥեƤʸȤɤ߹.
+
+ readlines
+
+ ۥեɤ߹, ƹԤǤȤƻ֤.
+
*** Array(饹)
źȤΥ饹Ǥ. ϰŪˤ``[...]''
@@ -1101,9 +1283,9 @@ Methods:
礭0ˤ.
- delete(item)
+ delete(val)
- itemȰפǤ.
+ valȰפǤ.
delete_if
@@ -1122,6 +1304,18 @@ Methods:
lengthά줿νޤǤĹȤ. ꤵ줿
ʬ󤬸ϰϤۤϼưŪ˳ĥ.
+ index(val)
+
+ valǽǤΥǥå֤. Ǥ¸
+ ʤnil֤.
+
+ indexes(ary)
+ indexes(index-1, ..., index-n)
+
+ 1ܤηǤȤƼ, Ǥ򥤥ǥ
+ ȤǤޤ֤. 2ܤηǤϳưͤ
+ ǥåȤǤޤ֤.
+
join([sep])
ǤϢ뤷ʸ֤. ǤʸѴ,
@@ -1129,6 +1323,7 @@ Methods:
ͤѤ.
length
+ size
Ĺ(ǿ)֤.
@@ -1241,7 +1436,9 @@ Methods:
饹Υ饹. 긷̩ȥ饹ðۥ᥽åɤѾ뤿
, 줾᥿饹ȸƤФ̾Τʤ饹򥯥饹Ȥƻ,
ClassϤΥ᥿饹Υ饹Ǥ(ʬä?). , β⤬
-ǤʤƤ, RubyȤȤ˲λپʤ.
+ǤʤƤ, RubyȤȤ˲λپʤ. 饹ˤðۥ᥽åɤ
+Ǥ, ѡ饹줿ðۥ᥽åɤϤΥ֥饹
+ǤͭǤΤнʬǤ.
SuperClass: Module
@@ -1260,12 +1457,16 @@ Methods:
*** Comparable(⥸塼)
- ӱ黻饹ΤMixin. Υ⥸塼򥤥󥯥롼ɤ뤳
- Ȥˤä, `<=>'¾α黻ҤϤѤ
- .
+ӱ黻饹ΤMixin. Υ⥸塼򥤥󥯥롼ɤ뤳
+Ȥˤä, `<=>'黻Ҥ¾α黻ҤϤѤ
+Ǥ.
Methods:
+ self == other
+
+ selfother֤.
+
self > other
selfother礭֤.
@@ -1291,7 +1492,7 @@ Methods:
NDBMե򥢥륯饹. , ǡȤʸǤʤФ
ʤȤ¤, ǡե¸ȤƤ
Dict饹Ʊͤ˰ȤǤ. NDBMƤʤƥǤ
-Υ饹ؤΥ㳰ȯ.
+Υ饹ʤ.
SuperClass: Object
@@ -1326,6 +1527,10 @@ Methods:
ɾͤλ, ܤ.
each
+ each_pair
+
+ [key, value]ʤͿ륤ƥ졼.
+
each_value
ƤvalueФƷ֤ƥ졼.
@@ -1334,12 +1539,8 @@ Methods:
ƤkeyФƷ֤ƥ졼.
- each_pair
-
- [key, value]ʤͿ륤ƥ졼.
-
- includes(key)
has_key(key)
+ includes(key)
keyǡ١¸ߤ, ֤
@@ -1348,11 +1549,19 @@ Methods:
valueͤȤȤǡ١¸ߤ,
֤
+ indexes(ary)
+ indexes(key-1, ..., key-n)
+
+ 1ܤηǤʸȤƼ, Ǥ򥭡
+ ȤǤޤ֤. 2ܤηǤϳưͤ򥭡
+ Ǥޤ֤.
+
keys
ǡ١¸ߤ륭Ƥޤ֤.
length
+ size
ǡ١Ǥο֤. (:ߤμ¸Ǥǿ
뤿˥ǡ١Τ, 빽Ȥ⤤.
@@ -1422,8 +1631,8 @@ Methods:
[key, value]ʤͿ륤ƥ졼.
- includes(key)
has_key(key)
+ includes(key)
key¸ߤ, ֤
@@ -1431,11 +1640,19 @@ Methods:
valueͤȤȤ¸ߤ, ֤
+ indexes(ary)
+ indexes(key-1, ..., key-n)
+
+ 1ܤηǤȤƼ, Ǥ򥭡Ȥ
+ Ǥޤ֤. 2ܤηǤϳưͤ򥭡Ȥ
+ ޤ֤.
+
keys
¸ߤ륭Ƥޤ֤.
length
+ size
Ǥο֤.
@@ -1539,7 +1756,7 @@ Methods:
grep(pattern)
- pattern =~ ǡפΩƤǤޤ֤.
+ =~ patternפΩƤǤޤ֤.
졼ȤѤ줿Ͼ嵭ξΩǤФƥ֥
¹Ԥ.
@@ -1555,13 +1772,13 @@ Methods:
min
- ǾǤ֤. Ǥ`<=>'᥽åɤĤȤۤΤ
- ˲ꤷƤ.
+ ǾǤ֤. ƤǤߤ`<=>'᥽åɤӤǤ
+ 뤳ȤꤷƤ.
max
- Ǥ֤. Ǥ`<=>'᥽åɤĤȤۤΤ
- ˲ꤷƤ.
+ Ǥ֤. Ǥ`<=>'᥽åɤӤǤ뤳Ȥ
+ Ƥ.
reverse
@@ -1626,7 +1843,7 @@ Single Methods:
gecos # gecosե(ʸ)
dir # ۡǥ쥯ȥ(ʸ)
shell # 󥷥(ʸ)
- # ʹߤΥФϥƥˤäƤϤʤΤ⤢
+ # ʹߤΥФϥƥˤäƤ󶡤ʤ.
change # ѥѹ()
quota # ()
age # ()
@@ -1673,9 +1890,9 @@ Single Methods:
*** File(饹)
-ե륢ΤΥ饹. ؿ᥽åopen(). ޤ,
-Υ饹ðۥ᥽åɤȤtestΥեƥȱ黻Υ᥽å
-Ƥ.
+ե륢ΤΥ饹. ᥽åopen(). ޤ,
+饹ðۥ᥽åɤȤtestΥեƥȱ黻Υ᥽åɤ
+Ƥ(FileTest⥸塼Υ᥽åɷ).
SuperClass: IO
@@ -1693,7 +1910,7 @@ Methods:
եΥѡߥåѹ(cf chmod(2)).
- chmod(owner, group)
+ chown(owner, group)
եνͭԤȥ롼פѹ(cf chown(2)). nil-1
ꤹ뤳ȤˤäƽͭԤ䥰롼פ򸽺ߤΤޤѤʤǤ
@@ -1707,7 +1924,7 @@ Methods:
ե˴ؤStat¤Τ֤. lstatϥե뤬ܥ
󥯤ǤХ󥯤ΤΤ˴ؤStat¤Τ֤. ¤
- ƤˤĤƤstat 򻲾ȤΤ.
+ ƤˤĤƤstat򻲾ȤΤ.
mtime
@@ -1727,7 +1944,7 @@ Methods:
0, 1, 2Τ줫Ǥä, 줾եƬ, ߰,
եνüΤΤ줫Ф򼨤.
- stat()
+ stat
ե˴ؤStat¤Τ֤(Struct 򻲾).
@@ -1765,29 +1982,85 @@ Single Methods:
filenameκǽ֤.
- b(filename)
-
- filenameΥե뤬֥åڥեǤ,
- .
-
- c(filename)
-
- filenameΥե뤬饯ڥեǤ,
- ֤.
-
ctime(filename)
filenameκǽơѹ֤.
chmod(mode, path, file...)
- եΥѡߥåѹ(cf chmod(2)).
+ եΥѡߥåѹ(cf chmod(2)). ѹե
+ ֤.
chown(owner, group, file...)
եνͭԤȥ롼פѹ(cf chown(2)). nil-1
ꤹ뤳ȤˤäƽͭԤ䥰롼פ򸽺ߤΤޤѤʤǤ
- ȤǤ.
+ ȤǤ. ѹե֤.
+
+ link(old, new)
+
+ oldؤΥϡɥnew. link(2)Ʊ¤.
+
+ mtime(filename)
+
+ filenameκǽ֤.
+
+ readlink(path)
+
+ ܥåpathƤʸȤ֤.
+
+ rename(from, to)
+
+ ե̾fromtoѹ. rename(2). toȤ̾
+ Υե뤬¸ߤˤϤޤΥե뤬.
+
+ stat(filename)
+
+ filenameΥեStat¤Τ֤.
+
+ symlink(old, new)
+
+ oldؤΥܥånew.
+
+ truncate(path, length)
+
+ pathǻꤵ줿եڤΤƤƺlengthХȤˤ.
+
+ type(filename)
+
+ filenameΥեΥפɽʸ֤. ʸ"file",
+ "directory", "characterSpecial", "blockSpecial", "fifo",
+ "link", "socket"ΤΤ줫ĤǤ.
+
+ unlink(file...)
+
+ ե. ǥ쥯ȥκˤDir.rmdirȤ.
+
+ utime(atime, mtime, file...)
+
+ եΥatime, mtimeꤹ.
+ atime, mtimeϿޤTime饹Υ󥹥󥹤ǤʤФʤ
+ .
+
+ ʳFileTest⥸塼Υ᥽åɤðۥ᥽åɤȤƻ.
+
+*** FileTest(⥸塼)
+
+եƥѥ᥽åɤ򽸤᤿⥸塼. 󥯥롼ɤѤ뤳
+Ǥ.
+
+Methods:
+Single Methods:
+
+ b(filename)
+
+ filenameΥե뤬֥åڥեǤ,
+ .
+
+ c(filename)
+
+ filenameΥե뤬饯ڥեǤ,
+ ֤.
executable(filename)
x(filename)
@@ -1829,14 +2102,6 @@ Single Methods:
filenameΥե뤬åȤǤ, ֤.
- link(old, new)
-
- oldؤΥϡɥnew. link(2)Ʊ¤.
-
- mtime(filename)
-
- filenameκǽ֤.
-
owned(filename)
O(filename)
@@ -1847,15 +2112,6 @@ Single Methods:
filenameΥեɤߤȤǽλ, ֤.
- readlink(path)
-
- ܥåpathƤʸȤ֤.
-
- rename(from, to)
-
- ե̾fromtoѹ. rename(2). toȤ̾
- Υե뤬¸ߤˤϤޤΥե뤬.
-
R(filename)
filenameΥեuid/gidɤߤȤǽλ, ֤.
@@ -1881,24 +2137,6 @@ Single Methods:
filenameΥեstickyӥåȤåȤƤ, ֤.
- symlink(old, new)
-
- oldؤΥܥånew.
-
- truncate(path, length)
-
- pathǻꤵ줿եڤΤƤƺlengthХȤˤ.
-
- unlink(file...)
-
- ե. ǥ쥯ȥκˤDir.rmdirȤ.
-
- utime(atime, mtime, file...)
-
- եΥatime, mtimeꤹ.
- atime, mtimeϿޤTime饹Υ󥹥󥹤ǤʤФʤ
- .
-
writable(filename)
w(filename)
@@ -2002,7 +2240,7 @@ Methods:
coerce(num)
numfloatѴ. FloatǤ¾ο
- FixnumǤ.
+ FixnumBignumǤ.
to_f
@@ -2010,7 +2248,7 @@ Methods:
to_i
- floatѴ̤֤.
+ selfѴ̤֤.
Single Methods:
@@ -2024,13 +2262,9 @@ RubyȤ߹ߤgarbage collectorԤʤΥ⥸塼. Υ
塼Υ᥽åɤѤ뤳Ȥˤä, ŪGCߤ᤿, GCε
륿ߥ󥰤椷Ǥ.
-gcϻϤޤˤΥ⥸塼start_hook᥽åɤ, äˤ
-end_hook᥽åɤƤӽФ, ᥽åɤ뤳Ȥˤä
-hook򤫤뤳ȤǤ.
-
Methods:
- garbage_collect +
+ garbage_collect
GC򳫻Ϥ. GC.startפƱ.
@@ -2048,6 +2282,33 @@ Single Methods:
GC򳫻Ϥ.
+*** Glob(饹)
+
+磻ɥɤΥ饹. 磻ɥɤΥƥ<...>ȤǤ
+. ɽȤۤƱ褦˻Ȥ뤬, ϵǽʤ. ,
+ɥɤŸǽ.
+
+SuperClass: Object
+
+Included Modules: Enumerable
+
+Methods:
+
+ self =~ string
+
+ 磻ɥɤʸ˥ޥåˤϿ, ʤ
+ nil֤.
+
+ each
+
+ 磻ɥɤ˥ޥåե֤̾ƥ졼.
+
+Single Methods:
+
+ new(string)
+
+ ʸ磻ɥɤѴ֥Ȥ֤.
+
*** Integer(饹)
饹. ºݤϤ礭ˤäFixnumBignumĤΥ֥饹
@@ -2096,7 +2357,7 @@ Methods:
:
- $stdout << 1 << " is a " << Fixnum
+ $stdout << 1 << " is a " << Fixnum << "\n"
close
@@ -2115,6 +2376,7 @@ Methods:
FixnumǤ.
fileno
+ to_i
IO֥ȤȤäƤեǥץ(Fixnum)֤.
@@ -2125,7 +2387,7 @@ Methods:
getc
ɤ߹, ɤ߹ߤˤϤʸ֤. ե
- νãˤnil֤. ؿŪ᥽åɤgetc()
+ νãˤnil֤. ͥ᥽ågetc()
$stdin.getcƱ̣Ǥ.
gets
@@ -2146,6 +2408,10 @@ Methods:
lengthХɤ߹, ʸ֤. lengthά줿
ˤ, ƤΥǡɤ߹.
+ readlines
+
+ եɤ߹dzƹԤǤȤƤ֤.
+
sync
ߤνƱ⡼ɤ򿿵֤ͤ. Ʊ⡼ɤλϽϴ
@@ -2158,16 +2424,17 @@ Methods:
sysread(length)
stdioͳread(2)ѤϤԤʤ. Ϥ줿ǡ
- ޤʸ֤. եνãˤnil֤.
+ ޤʸ֤. եνãˤnil֤.
read(2)ˤɬlengthХȤʸɤ߹ޤ櫓
ǤϤʤ. gets()getc()ʤstdioͳ᥽åɤȺѤ
- ȤϥХåե󥰤ʤɤ, פư򤹤뤳Ȥ.
+ ȤϥХåե󥰤ʤɤǻפư򤹤뤳Ȥ.
syswrite(str)
- stdioͳ, wirte(2)ѤƽϤԤʤ. Υ᥽å
- ϥХåե󥰤ʤstdioƤ뤳ȤϰڹԤʤʤ.
- print()printf()syswrite()ѤΤϿ侩Ǥʤ.
+ stdioͳ, write(2)ѤƽϤԤʤ. Υ᥽å
+ ϥХåե󥰤ʤstdioƤ뤳ȤϰڹԤʤʤ.
+ syswriteϼºݤ˽񤭹Хȿ֤. print()printf()
+ syswrite()ѤΤϿ侩Ǥʤ.
write(str)
@@ -2179,14 +2446,14 @@ Single Methods:
printprintfΥǥեȤν֤. ͤ$stdout.
- default=
+ default=(io)
ǥեȤνꤹ.
*** Kernel(饹)
-ƤΥ饹δ쥯饹. RubyȤ߹ߤƤδؿŪ᥽åɤϤΥ
-饹Ƥ.
+ƤΥ饹δ쥯饹. RubyȤ߹ߤƤδؿŪ˸ƤФ᥽å
+ϤΥ饹Ƥ.
SuperClass: ʤ
@@ -2197,8 +2464,8 @@ Methods:
. Non-nilΥ֥Ȥξ˵(nil)֤. Υ᥽
ɤNil饹ǤϺ쿿֤.
- equal(other)
self == other
+ equal(other)
֥ȤΰȽ. 쥷ФȰΰפ,
֤. Kernel饹ǤΥ֥ȤƱλ
@@ -2217,13 +2484,13 @@ Methods:
self =~ other
- ޥå. ǥեȤ"=="ƱǤ. "=~"caseӤˤѤ
- .
+ ޥå. ǥեȤư"=="ƱǤ. "=~"caseӤ
+ Ѥ.
!~
- "=~". "=~"᥽åɤƤӽФƤΤ,
- ɬפϤʤ.
+ "=~". "=~"᥽åɤƤӽФƤΤ, Ϻ
+ ɬפϤʤ.
self :: other
@@ -2254,7 +2521,7 @@ Methods:
֥ȤΥϥå(Fixnum)֤. Dict饹ǥȤʤ
֥ȤǼΤѤƤ.A == BפΩ
ɬA.hash == B.hashפΩɬפΤ, "=="
- ˤϤ⤽˹碌ƺ뤳.
+ ˤɬ⤽˹碌ƺ뤳.
*** Math(⥸塼)
@@ -2309,7 +2576,7 @@ SuperClass: Object
Methods:
- attr(name[, public]) +
+ attr(name[, public])
Υ⥸塼򥤥󥯥롼ɤ饹Υ󥹥󥹤Ф
nameǻꤵ°ղä, °Ф륢᥽åɤ
@@ -2390,6 +2657,10 @@ Methods:
Ⱦ;2Ǥ֤.
+ next
+
+ ο֤. οȤϤοۤǾǤ.
+
*** Object(饹)
Ƥ̾說饹Υѥ饹. Υ饹Υ֥饹Ǥʤ饹
@@ -2410,9 +2681,9 @@ Methods:
clone
- ֥Ȥʣ. FixnumʳΥ饹ξ, 餯
- obj.eqaul(obj.clone)פϵǤ뤬, ¿ξobj ==
- obj.cloneפϿǤ.
+ ֥Ȥʣ. 󥹥󥹤¨ͤǤFixnum饹
+ ʳΥ饹ξ,obj.equal(obj.clone)פϵǤ뤬, ¿
+ ξobj == obj.cloneפϿǤ.
to_s
@@ -2587,7 +2858,7 @@ Single Methods:
ɽΥ饹. ɽΥƥ/.../Ȥɽ, ưŪ
뤿ˤ
- Regexp.compile(ʸ)
+ Regexp.new(ʸ)
Ȥ. , String饹`=~'ϤȤ¿Υ᥽åɤɽ
ؤʸͿ줿ˤŪɽΤ,
@@ -2598,7 +2869,6 @@ SuperClass: Object
Methods:
-
self =~ string
ɽʸ˥ޥå, ޥå֤֤. ޥå
@@ -2611,6 +2881,7 @@ Methods:
Single Methods:
complie(string)
+ new(string)
ʸɽѴ֥Ȥ֤.
@@ -2646,7 +2917,7 @@ Methods:
åȤΰʹߤ³λ. how0Ǥ, ʹߤμ,
how1Ǥ, ʹߤݤ. how2λˤ,
- ʹߤ, Ȥ˵ݤ.
+ ʹߤ, Ȥ˵ݤ. shutdown(2)򻲾.
*** String(饹)
@@ -2758,47 +3029,28 @@ Methods:
Ѵ.
length
+ size
ʸĹ(Хȿ)֤.
next
- ּΡʸ֤. ʸȤϿϿȤ,ʸ
- ʸȤä, 夬νԤʤ줿ԤǤ.
-
- "aa".next == "ab"
- "99".next == "100"
- "a9".next == "b0"
-
- Υ᥽åɤRange:eachѤƤΤ, ʲΤ褦ʽ
- ǽǤ.
-
- for i in "a" .. "ba"
- print(i, "\n");
- end
-
- a, b, c, .. aa, .. az, baޤǤƹԤ˽Ϥ.
-
-
- դʤФʤΤ, νλȽ羮طǤϤʤ
- `=='ȽꤵƤ뤿, `..'黻Ҥκդͤ³ʸ˱
- դʸ󤬴ޤޤƤʤ, ʲΤ褦ʾ̵¥롼פ
- ٤äƤޤ.
-
- for i in "0" .. "1a"
- print(i, "\n");
- end
+ selfendޤǡּΡʸ֤. ʸȤϿϿ
+ Ȥ,ʸϱʸȤä, 夬νԤʤ줿
+ ΤǤ.
- ԤϤ񤯤ȤˤäǤƨƤ褦ȤƤȹͤ
- ⤤뤫⤷ʤ. ο¬.
+ "aa".next => "ab"
+ "99".next => "100"
+ "a9".next => "b0"
oct
ʸ8ʿɽʸȲᤷ, Ѵ. 8ʿ
- /[0-7]+/Ǥ, ƤϤޤʤʸФƤ
- 0֤. perlȤϰäʸ0xϤޤäƤ뤫Ȥä
- 16ʿȸʤƤ줿Ϥʤ. 8ʿǤϤʤΤ0
- ֤.
+ /[0-7]+/Ǥ, ʸƬ餳Υѥ˥ޥå
+ ʬѴ. ƤϤޤʤʸФ
+ Ƥ0֤. perlȤϰäʸ0xϤޤäƤ뤫Ȥ
+ 16ʿȸʤƤ줿Ϥʤ. Ƭ08ʿ
+ ǧ, 0֤.
reverse
@@ -2844,6 +3096,16 @@ Methods:
Ƥ֤. sub()gsub()Ȱۤʤ, ǽΥޥå
ִ.
+ sum([bits])
+
+ ʸbitsӥåȤΥå. άͤ16Ǥ. ruby
+ ǤϰʲΥɤSystem V`sum'ץƱͤ.
+
+ while gets()
+ sum += $_.sum
+ end
+ sum %= 65536
+
to_f
ʸFloatѴ.
@@ -2918,6 +3180,36 @@ Methods:
X 1Хȸ
@ а֤ؤΰư
+ rubyunpackperlȰäƥåη׻ǽʤȤ
+ դ뤳.
+
+ upto(end)
+
+ selfϤޤä, endޤǡּΡʸͿ륤ƥ졼.
+ ʸȤstr.nextͿʸǤ.
+
+ Υ᥽åɤRange:eachѤƤΤ, ʲΤ褦ʽ
+ ǽǤ.
+
+ for i in "a" .. "ba"
+ print(i, "\n");
+ end
+
+ a, b, c, .. aa, .. az, baޤǤƹԤ˽Ϥ.
+
+
+ դʤФʤΤ, νλȽ羮طǤϤʤ
+ `=='ȽꤵƤ뤿, `..'黻Ҥκդͤ³ʸ˱
+ դʸ󤬴ޤޤƤʤ, ʲΤ褦ʾ̵¥롼פ
+ ٤äƤޤ.
+
+ for i in "0" .. "1a"
+ print(i, "\n");
+ end
+
+ ԤϤ񤯤ȤˤäǤƨƤ褦ȤƤȹͤ
+ ⤤뤫⤷ʤ. ο¬.
+
Single Methods:
new(string)
@@ -2930,20 +3222,24 @@ Single Methods:
ǡޤȤˤ󥯥饹Ѥ뤳Ȥ⤢뤬(: select),
¤ΤȤ٤ϰʲΤ褦ʾǤ.
- (1) Ǥο¿
+ (1) Ǥο
+
+ ǤοưΤϹ¤ΤȤΤˤϸʤ.
+
+ (2) Ǥο¿
ʹ֤٤ưפ˰복ǰο7ĤޤǤǤȤ⤬.
- β˽, ǡ4İʾξѤ,
- *2(ĤޤꥪեåȤȤΰ̣)7ۤ. ä, Τ褦
- ˤϹ¤ΤȤä򤷤䤹Ȼפ.
+ β˽, Ǥ4İʾ夢ǡξѤ
+ , ǿ*2(ĤޤꥪեåȤȤΰ̣)7ۤ. ä,
+ Τ褦ʾˤϹ¤ΤȤä򤷤䤹Ȼפ.
- (2) Ʊ̤ʤ
+ (3) Ʊ̤ʤ
- ¤Τ㴳Ȥ⤤Τ, ®٤ˤʤ
- ˤ, (Ʊ̤ʤ)Ϲ¤ΤλѤŬڤǤʤ
+ ¤Τ㴳Ȥ⤤Τ, ®٤ˤʤ
+ (㤨Ʊ̤ʤ)Ϲ¤ΤλѤŬڤǤʤ
ǽ.
-ƹ¤Τˤϥ̾Ʊ̾ΰΤʤ᥽åɤƤ.
+ƹ¤Τˤϥ̾Ʊ̾ΰΤʤ᥽åɤ.
ܥɥ, ¤Τɽ뤿ˤϰʲηȤ.
@@ -3079,8 +3375,7 @@ Included Modules: Comparable
Methods:
- self == other
- self > other
+ self <=> other
otherTimeΥ󥹥󥹤. Ϳ줿
ˤ1970ǯ 1 1 00:00:00 GMTÿǤ
@@ -3107,7 +3402,7 @@ Methods:
localtime
ॾνԤʤä(ǥե). localtime
- ⼫ʬȤ֤.
+ ϼʬȤ֤.
to_i
tv_sec
diff --git a/sprintf.c b/sprintf.c
index 7ae3eccbb8..b937928e9e 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -3,7 +3,7 @@
sprintf.c -
$Author: matz $
- $Date: 1994/06/27 15:48:40 $
+ $Date: 1994/08/12 04:47:57 $
created at: Fri Oct 15 10:39:26 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -51,7 +51,7 @@ Fsprintf(argc, argv)
}
#define GETARG() \
- ((argc == 1)?Fail("too few argument."):(argc--, argv++, argv[0]))
+ ((argc == 0)?Fail("too few argument."):(argc--, (argv++)[0]))
fmt = (struct RString*)GETARG();
Check_Type(fmt, T_STRING);
@@ -314,8 +314,8 @@ Fsprintf(argc, argv)
bignum = 1;
break;
default:
- WrongType(val, T_FIXNUM);
- break;
+ val = num2fix(val);
+ goto int_retry;
}
if (bignum) {
diff --git a/st.c b/st.c
index fcae526853..b44b51103f 100644
--- a/st.c
+++ b/st.c
@@ -2,7 +2,7 @@
static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible";
#ifndef lint
-static char *rcsid = "$Header: /work/cvsroot/ruby/st.c,v 1.2 1994/06/27 15:48:41 matz Exp $";
+static char *rcsid = "$Header: /usr/ext/cvsroot/ruby/st.c,v 1.2 1994/08/12 04:47:59 matz Exp $";
#endif
#include <stdio.h>
diff --git a/string.c b/string.c
index d3b07a91de..1d96557474 100644
--- a/string.c
+++ b/string.c
@@ -3,7 +3,7 @@
string.c -
$Author: matz $
- $Date: 1994/06/27 15:48:44 $
+ $Date: 1994/08/12 11:06:44 $
created at: Mon Aug 9 17:12:58 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -31,7 +31,7 @@ str_new(ptr, len)
str->len = len;
str->ptr = ALLOC_N(char,len+1);
if (ptr) {
- memmove(str->ptr, ptr, len);
+ memcpy(str->ptr, ptr, len);
}
str->ptr[len] = '\0';
str->orig = Qnil;
@@ -285,61 +285,6 @@ Fstr_concat(str1, str2)
return (VALUE)str1;
}
-static char
-str_next(s)
- char *s;
-{
- char c = *s;
-
- /* control code */
- if (c < ' ') return 0;
-
- /* numerics */
- if ('0' <= c && c < '9') (*s)++;
- else if (c == '9') {
- *s = '0';
- return '1';
- }
- /* small alphabets */
- else if ('a' <= c && c < 'z') (*s)++;
- else if (c == 'z') {
- return *s = 'a';
- }
- /* capital alphabets */
- else if ('A' <= c && c < 'Z') (*s)++;
- else if (c == 'Z') {
- return *s = 'A';
- }
- return 0;
-}
-
-static VALUE
-Fstr_next(orig)
- struct RString *orig;
-{
- struct RString *str, *str2;
- char *sbeg, *s;
- char c = -1;
-
- str = (struct RString*)str_new(orig->ptr, orig->len);
-
- sbeg = str->ptr; s = sbeg + str->len - 1;
-
- while (sbeg <= s) {
- if (isalnum(*s) && (c = str_next(s)) == Qnil) break;
- s--;
- }
- if (s < sbeg && c != -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;
- }
-
- return (VALUE)str;
-}
-
static
str_hash(str)
struct RString *str;
@@ -418,24 +363,29 @@ Fstr_cmp(str1, str2)
Regexp * make_regexp();
VALUE Freg_match();
+extern VALUE C_Glob;
+
static VALUE
-Fstr_match(this, other)
- struct RString *this, *other;
+Fstr_match(x, y)
+ struct RString *x, *y;
{
VALUE reg;
int start;
- switch (TYPE(other)) {
+ switch (TYPE(y)) {
case T_REGEXP:
- return Freg_match(other, this);
+ return Freg_match(y, x);
case T_STRING:
- reg = re_regcomp(other);
- start = research(reg, this, 0, ignorecase);
+ reg = re_regcomp(y);
+ start = research(reg, x, 0, ignorecase);
if (start == -1) {
return FALSE;
}
return INT2FIX(start);
default:
+ if (obj_is_kind_of(y, C_Glob)) {
+ return Fglob_match(y, x);
+ }
Fail("type mismatch");
break;
}
@@ -547,6 +497,74 @@ Fstr_rindex(str, args)
return Qnil;
}
+static char
+str_next(s)
+ char *s;
+{
+ char c = *s;
+
+ /* numerics */
+ if ('0' <= c && c < '9') (*s)++;
+ else if (c == '9') {
+ *s = '0';
+ return '1';
+ }
+ /* small alphabets */
+ else if ('a' <= c && c < 'z') (*s)++;
+ else if (c == 'z') {
+ return *s = 'a';
+ }
+ /* capital alphabets */
+ else if ('A' <= c && c < 'Z') (*s)++;
+ else if (c == 'Z') {
+ return *s = 'A';
+ }
+ return 0;
+}
+
+static VALUE
+Fstr_next(orig)
+ struct RString *orig;
+{
+ struct RString *str, *str2;
+ char *sbeg, *s;
+ char c = -1;
+
+ str = (struct RString*)str_new(orig->ptr, orig->len);
+
+ sbeg = str->ptr; s = sbeg + str->len - 1;
+
+ while (sbeg <= s) {
+ if (isalnum(*s) && (c = str_next(s)) == Qnil) break;
+ s--;
+ }
+ if (s < sbeg && c != -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;
+ }
+
+ return (VALUE)str;
+}
+
+VALUE
+Fstr_upto(beg, end)
+ VALUE beg, end;
+{
+ VALUE current;
+
+ current = beg;
+ for (;;) {
+ rb_yield(current);
+ if (Fstr_equal(current, end)) break;
+ current = Fstr_next(current);
+ }
+
+ return Qnil;
+}
+
static VALUE
Fstr_aref_internal(str, indx)
struct RString *str;
@@ -1474,6 +1492,47 @@ Fstr_intern(str)
return rb_intern(str->ptr)|FIXNUM_FLAG;
}
+static VALUE
+Fstr_sum(str, args)
+ struct RString *str;
+ VALUE args;
+{
+ VALUE vbits;
+ int bits;
+ char *p, *pend;
+
+ rb_scan_args(args, "01", &vbits);
+ if (vbits == Qnil) bits = 16;
+ else bits = NUM2INT(vbits);
+
+ p = str->ptr; pend = p + str->len;
+ if (bits > 32) {
+ VALUE res = INT2FIX(0);
+ VALUE mod;
+
+ mod = rb_funcall(INT2FIX(1), rb_intern("<<"), 1, INT2FIX(bits));
+ mod = rb_funcall(mod, '-', 1, INT2FIX(1));
+
+ while (p < pend) {
+ res = rb_funcall(res, '+', 1, INT2FIX((UINT)*p));
+ res = rb_funcall(res, '%', 1, mod);
+ p++;
+ }
+ return res;
+ }
+ else {
+ UINT res = 0;
+ UINT mod = (1<<bits)-1;
+
+ while (p < pend) {
+ res += (UINT)*p;
+ res %= mod;
+ p++;
+ }
+ return int2inum(res);
+ }
+}
+
extern VALUE C_Kernel;
extern VALUE M_Comparable;
extern VALUE M_Enumerable;
@@ -1494,9 +1553,11 @@ Init_String()
rb_define_method(C_String, "[]", Fstr_aref, -2);
rb_define_method(C_String, "[]=", Fstr_aset, -2);
rb_define_method(C_String, "length", Fstr_length, 0);
+ rb_define_alias(C_String, "size", "length");
rb_define_method(C_String, "=~", Fstr_match, 1);
rb_define_method(C_String, "~", Fstr_match2, 0);
rb_define_method(C_String, "next", Fstr_next, 0);
+ rb_define_method(C_String, "upto", Fstr_next, 1);
rb_define_method(C_String, "index", Fstr_index, -2);
rb_define_method(C_String, "rindex", Fstr_rindex, -2);
@@ -1532,6 +1593,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_method(C_String, "sum", Fstr_sum, -2);
+
rb_define_method(C_Kernel, "sub", Fsub, 2);
rb_define_method(C_Kernel, "gsub", Fgsub, 2);
diff --git a/struct.c b/struct.c
index 162fb691a7..3ecc265d32 100644
--- a/struct.c
+++ b/struct.c
@@ -3,7 +3,7 @@
struct.c -
$Author: matz $
- $Date: 1994/06/17 14:23:51 $
+ $Date: 1994/08/12 04:48:01 $
created at: Tue Mar 22 18:44:30 JST 1994
************************************************/
diff --git a/time.c b/time.c
index 4f9d38f0ed..4289f350b8 100644
--- a/time.c
+++ b/time.c
@@ -3,7 +3,7 @@
time.c -
$Author: matz $
- $Date: 1994/06/17 14:23:51 $
+ $Date: 1994/08/12 11:06:46 $
created at: Tue Dec 28 14:31:59 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -28,10 +28,12 @@ struct time_object {
int tm_got;
};
+static ID id_tv;
+
#define GetTimeval(obj, tobj) \
- Get_Data_Struct(obj, "tv", struct time_object, tobj)
+ Get_Data_Struct(obj, id_tv, struct time_object, tobj)
#define MakeTimeval(obj,tobj) {\
- Make_Data_Struct(obj, "tv", struct time_object, Qnil, Qnil, tobj);\
+ Make_Data_Struct(obj, id_tv, struct time_object, Qnil, Qnil, tobj);\
tobj->tm_got=0;\
}
@@ -543,4 +545,6 @@ Init_Time()
rb_define_method(C_Time, "usec", Ftime_usec, 0);
rb_define_method(C_Time, "strftime", Ftime_strftime, 1);
+
+ id_tv = rb_intern("tv");
}
diff --git a/variable.c b/variable.c
index 5bddd9cc1d..70aa959acd 100644
--- a/variable.c
+++ b/variable.c
@@ -3,7 +3,7 @@
variable.c -
$Author: matz $
- $Date: 1994/06/17 14:23:51 $
+ $Date: 1994/08/19 09:32:10 $
created at: Tue Apr 19 23:55:15 JST 1994
************************************************/
@@ -200,6 +200,7 @@ rb_gvar_get(entry)
return Qnil;
}
+VALUE
rb_ivar_get_1(obj, id)
struct RBasic *obj;
ID id;
@@ -285,6 +286,7 @@ rb_gvar_set2(name, val)
return val;
}
+VALUE
rb_ivar_set_1(obj, id, val)
struct RBasic *obj;
ID id;
@@ -304,11 +306,10 @@ rb_ivar_set(id, val)
}
static VALUE
-const_bound(id)
+const_bound(class, id)
+ struct RClass *class;
ID id;
{
- struct RClass *class = (struct RClass*)CLASS_OF(Qself);
-
while (class) {
if (class->c_tbl && st_lookup(class->c_tbl, id, Qnil)) {
return TRUE;
@@ -324,7 +325,7 @@ rb_const_set_1(class, id, val)
ID id;
VALUE val;
{
- if (const_bound(id))
+ if (const_bound(class, id))
Fail("already initialized constnant");
if (class->c_tbl == Qnil)
@@ -402,7 +403,7 @@ Fdefined(obj, name)
break;
case ID_CONST:
- return const_bound(id);
+ return const_bound(CLASS_OF(Qself), id);
break;
default:
diff --git a/version.c b/version.c
index b671b46139..17b5af4a20 100644
--- a/version.c
+++ b/version.c
@@ -3,8 +3,8 @@
version.c -
$Author: matz $
- $Revision: 1.1.1.1 $
- $Date: 1994/06/17 14:23:51 $
+ $Revision: 1.3 $
+ $Date: 1994/08/18 07:06:32 $
created at: Thu Sep 30 20:08:01 JST 1993
Copyright (C) 1994 Yukihiro Matsumoto
@@ -27,5 +27,11 @@ Init_version()
show_version()
{
- printf("ruby - version %s (%s)\n", RUBY_VERSION, VERSION_DATE);
+ fprintf(stderr, "ruby - version %s (%s)\n", RUBY_VERSION, VERSION_DATE);
+}
+
+show_copyright()
+{
+ fprintf(stderr, "ruby - Copyright (C) 1994 Yukihiro Matsumoto\n");
+ exit(0);
}
diff --git a/version.h b/version.h
index ed525e12f1..47b231013d 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
-#define RUBY_VERSION "0.50"
-#define VERSION_DATE "10 Aug 94"
+#define RUBY_VERSION "0.51"
+#define VERSION_DATE "13 Oct 94"