From 5d828b25d4ae30a000c054a724ac248dadbb97b3 Mon Sep 17 00:00:00 2001 From: Yukihiro Matsumoto Date: Tue, 10 Jan 1995 00:58:20 +0900 Subject: version 0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.64.tar.gz Tue Jan 10 00:58:20 1995 Yukihiro Matsumoto (matz@dyna) * eval.c: レシーバと引数は常にiterではない. * cons.c(aref,aset): negative offset対応. Mon Jan 9 14:40:39 1995 Yukihiro Matsumoto (matz@ix-02) * parse.y: foo{..}の形式において,fooをローカル変数やクラス名では なく,引数なしの関数型メソッド呼び出しとみなすようにした. * list.c -> cons.c: 名称変更(クラス名も). * list.c: a::b::c::nilをリスト(a b c)とみなすlisp形式から,a::b::c をリスト(a b c)とみなすruby形式に変更.[], []=, eachもそれに会わ せた仕様とする. * list.c: consペアとしての機能を強調.仕様変更. Sat Jan 7 01:26:26 1995 Yukihiro Matsumoto (matz@dyna) * eval.c: 自己代入の不具合修正. * eval.c(masign): 多重代入が配列もリストもとれるようにした. * list.c: assocを2要素の配列からList(CONSペア)に変更した. Fri Jan 6 13:42:12 1995 Yukihiro Matsumoto (matz@ix-02) * parse.y: a[b]+=cやa.b+=cなどの自己代入形式で,aやbを2度評価しな くなった. * eval.c: iterator設定のバグフィックス. * list.c: Listクラスを新設. Thu Jan 5 13:55:00 1995 Yukihiro Matsumoto (matz@ix-02) * parse.y: SCOPEのメモリリークをなくした. * eval.c: built-inメソッドへの引数の引き渡し方を変更して,配列の生 成数を減らした. * re.c: match-dataを毎回生成することをやめた.`$~'をアクセスした時 にon-demandで生成する. * string.c etc: 不必要なmemmoveをmemcpyに置換. * parse.y: =~, !~は副作用があるのでコンパイル時に展開できない. Tue Jan 3 02:04:36 1995 Yukihiro Matsumoto (matz@dyna) * eval.c: rest引数のbug fix. * eval.c,gc.c: scopeをオブジェクトにした. * eval.c: envとscopeの扱いを変更した. Wed Dec 28 09:46:57 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y: evalでローカル変数が追加された場合に対応した. * parse.y: 演算子を含むaliasのbug fix. Tue Dec 27 16:45:20 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y: def A Bをalias A Bに変更. * eval.c: alias関係のbug修正.nodeをオブジェクト化した時にenbugし たようだ. * signal.c: システムコールの再定義を止めた. * io.c(select): write/exceptのフラグ設定にバグ. * Makefile.in: static link用オプションをMake変数として独立させた. --- ChangeLog | 77 ++++++ Makefile.in | 8 +- array.c | 96 ++++---- bignum.c | 4 +- class.c | 45 ++-- configure.in | 1 + cons.c | 270 ++++++++++++++++++++ dbm.c | 14 +- defines.h | 5 +- dict.c | 15 +- dir.c | 22 +- enum.c | 28 ++- env.h | 13 +- error.c | 8 +- etc.c | 12 +- eval.c | 785 +++++++++++++++++++++++++++++++++-------------------------- file.c | 32 ++- gc.c | 152 +++++++----- inits.c | 3 +- io.c | 78 ++++-- node.h | 18 +- numeric.c | 4 +- object.c | 48 ++-- parse.y | 183 +++++++------- process.c | 19 +- random.c | 12 +- re.c | 151 +++++++----- ruby.c | 4 +- ruby.h | 28 ++- signal.c | 78 +----- socket.c | 62 +++-- spec | 135 +++++++--- sprintf.c | 4 +- string.c | 75 +++--- struct.c | 25 +- variable.c | 75 +----- version.h | 4 +- 37 files changed, 1575 insertions(+), 1018 deletions(-) create mode 100644 cons.c diff --git a/ChangeLog b/ChangeLog index 01c06993e6..f6246f3a0d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,80 @@ +Tue Jan 10 00:58:20 1995 Yukihiro Matsumoto (matz@dyna) + + * eval.c: 쥷ФȰϾiterǤϤʤ + + * cons.c(aref,aset): negative offsetб + +Mon Jan 9 14:40:39 1995 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: foo{..}ηˤơfooѿ䥯饹̾Ǥ + ʤʤδؿ᥽åɸƤӽФȤߤʤ褦ˤ + + * list.c -> cons.c: ̾ѹ(饹̾) + + * list.c: a::b::c::nilꥹ(a b c)Ȥߤʤlisp顤a::b::c + ꥹ(a b c)Ȥߤʤrubyѹ[], []=, each⤽˲ + ͤȤ롥 + + * list.c: consڥȤƤεǽĴѹ + +Sat Jan 7 01:26:26 1995 Yukihiro Matsumoto (matz@dyna) + + * eval.c: Զ罤 + + * eval.c(masign): ¿ꥹȤȤ褦ˤ + + * list.c: assoc2Ǥ󤫤List(CONSڥ)ѹ + +Fri Jan 6 13:42:12 1995 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: a[b]+=ca.b+=cʤɤμǡab2ɾ + ʤä + + * eval.c: iteratorΥХեå + + * list.c: List饹ߡ + +Thu Jan 5 13:55:00 1995 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: SCOPEΥ꡼ʤ + + * eval.c: built-in᥽åɤؤΰΰϤѹơ + 򸺤餷 + + * re.c: match-data뤳Ȥ᤿`$~'򥢥 + on-demand롥 + + * string.c etc: ɬפmemmovememcpyִ + + * parse.y: =~, !~ѤΤǥѥŸǤʤ + +Tue Jan 3 02:04:36 1995 Yukihiro Matsumoto (matz@dyna) + + * eval.c: restbug fix. + + * eval.c,gc.c: scope򥪥֥Ȥˤ + + * eval.c: envscopeΰѹ + +Wed Dec 28 09:46:57 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: evalǥѿɲä줿б + + * parse.y: 黻Ҥޤaliasbug fix. + +Tue Dec 27 16:45:20 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: def A Balias A Bѹ + + * eval.c: aliasطbugnode򥪥֥Ȳenbug + 褦 + + * signal.c: ƥॳκߤ᤿ + + * io.c(select): write/exceptΥե饰˥Х + + * Makefile.in: static linkѥץMakeѿȤΩ + Tue Dec 20 00:46:19 1994 Yukihiro Matsumoto (matz@dyna) * 0.63 released diff --git a/Makefile.in b/Makefile.in index 6b4543d4bf..477b4fdbd2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,11 +11,12 @@ YACC = @YACC@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ +PURIFY= CFLAGS = -g -LDFLAGS = @STATIC@ $(CFLAGS) +STATIC = @STATIC@ +LDFLAGS = $(CFLAGS) LIBS = @LIBS@ -DEFS = @DEFS@ MISSING = @LIBOBJS@ @ALLOCA@ prefix = /usr/local @@ -41,6 +42,7 @@ OBJS = array.o \ bignum.o \ class.o \ compar.o \ + cons.o \ dbm.o \ dict.o \ dir.o \ @@ -87,7 +89,7 @@ all: $(PROGRAM) $(PROGRAM): $(OBJS) @rm -f $(PROGRAM) - $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) + $(PURIFY) $(CC) $(STATIC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM) $(bindir)/$(PROGRAM): $(PROGRAM) $(INSTALL_PROGRAM) $(PROGRAM) $(bindir)/$(PROGRAM) diff --git a/array.c b/array.c index 6ecadb50cc..5a8f040723 100644 --- a/array.c +++ b/array.c @@ -3,7 +3,7 @@ array.c - $Author: matz $ - $Date: 1994/12/06 09:29:47 $ + $Date: 1995/01/10 10:42:18 $ created at: Fri Aug 6 09:46:12 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -14,8 +14,6 @@ VALUE C_Array; -static ID eq; - VALUE rb_to_a(); #define ARY_DEFAULT_SIZE 16 @@ -73,12 +71,13 @@ ary_new4(n, elts) struct RArray* ary; ary = (struct RArray*)ary_new2(n); - memcpy(ary->ptr, elts, sizeof(VALUE)*n); + MEMCPY(ary->ptr, elts, VALUE, n); ary->len = n; return (VALUE)ary; } +#if 0 VALUE assoc_new(elm1, elm2) VALUE elm1, elm2; @@ -92,6 +91,7 @@ assoc_new(elm1, elm2) return (VALUE)ary; } +#endif static VALUE Sary_new(class) @@ -121,8 +121,8 @@ astore(ary, idx, val) ary->capa = idx + ary->capa/5; REALLOC_N(ary->ptr, VALUE, ary->capa); } - if (idx >= ary->len) { - memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(idx-ary->len+1)); + if (idx > ary->len) { + MEMZERO(ary->ptr+ary->len, VALUE, idx-ary->len+1); } if (idx >= ary->len) { @@ -137,7 +137,7 @@ ary_push(ary, item) VALUE item; { astore(ary, ary->len, item); - return item; + return (VALUE)ary; } static VALUE @@ -232,7 +232,7 @@ ary_subseq(ary, beg, len) } ary2 = (struct RArray*)ary_new2(len); - memmove(ary2->ptr, ary->ptr+beg, sizeof(VALUE)*len); + MEMCPY(ary2->ptr, ary->ptr+beg, VALUE, len); ary2->len = len; return (VALUE)ary2; @@ -270,13 +270,14 @@ range_beg_end(range, begp, lenp, len) } static VALUE -Fary_aref(ary, args) +Fary_aref(argc, argv, ary) + int argc; + VALUE *argv; struct RArray *ary; - VALUE args; { VALUE arg1, arg2; - if (rb_scan_args(args, "11", &arg1, &arg2) == 2) { + if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) { int beg, len; beg = NUM2INT(arg1); @@ -311,7 +312,7 @@ Fary_index(ary, val) int i; for (i=0; ilen; i++) { - if (rb_funcall(ary->ptr[i], eq, 1, val)) + if (rb_equal(ary->ptr[i], val)) return INT2FIX(i); } return Qnil; @@ -340,15 +341,16 @@ Fary_indexes(ary, args) } static VALUE -Fary_aset(ary, args) +Fary_aset(argc, argv, ary) + int argc; + VALUE *argv; struct RArray *ary; - VALUE args; { VALUE arg1, arg2; struct RArray *arg3; int offset; - if (rb_scan_args(args, "21", &arg1, &arg2, &arg3) == 3) { + if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { int beg, len; beg = NUM2INT(arg1); @@ -367,8 +369,8 @@ Fary_aset(ary, args) ary->capa=len; REALLOC_N(ary->ptr, VALUE, ary->capa); } - memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(beg-ary->len)); - memcpy(ary->ptr+beg, arg3->ptr, sizeof(VALUE)*arg3->len); + MEMZERO(ary->ptr+ary->len, VALUE, beg-ary->len); + MEMCPY(ary->ptr+beg, arg3->ptr, VALUE, arg3->len); ary->len = len; } else { @@ -390,7 +392,7 @@ Fary_aset(ary, args) memmove(ary->ptr+beg+arg3->len, ary->ptr+beg+len, sizeof(VALUE)*(ary->len-(beg+len))); - memmove(ary->ptr+beg, arg3->ptr, sizeof(VALUE)*arg3->len); + memcpy(ary->ptr+beg, arg3->ptr, sizeof(VALUE)*arg3->len); ary->len = alen; } return (VALUE)arg3; @@ -408,9 +410,8 @@ Fary_aset(ary, args) ary->capa=len; REALLOC_N(ary->ptr, VALUE, ary->capa); } - memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(beg-ary->len)); - memcpy(ary->ptr+beg, RARRAY(arg2)->ptr, - sizeof(VALUE)*RARRAY(arg2)->len); + MEMZERO(ary->ptr+ary->len, VALUE, beg-ary->len); + MEMCPY(ary->ptr+beg, RARRAY(arg2)->ptr, VALUE, RARRAY(arg2)->len); ary->len = len; } else { @@ -424,7 +425,7 @@ Fary_aset(ary, args) memmove(ary->ptr+beg+RARRAY(arg2)->len, ary->ptr+beg+len, sizeof(VALUE)*(ary->len-(beg+len))); - memmove(ary->ptr+beg, RARRAY(arg2)->ptr, + memcpy(ary->ptr+beg, RARRAY(arg2)->ptr, sizeof(VALUE)*RARRAY(arg2)->len); ary->len = alen; } @@ -480,7 +481,7 @@ ary_clone(ary) VALUE ary2 = ary_new2(ary->len); CLONESETUP(ary2, ary); - memcpy(RARRAY(ary2)->ptr, ary->ptr, sizeof(VALUE)*ary->len); + MEMCPY(RARRAY(ary2)->ptr, ary->ptr, VALUE, ary->len); RARRAY(ary2)->len = ary->len; return ary2; } @@ -520,13 +521,14 @@ ary_join(ary, sep) } static VALUE -Fary_join(ary, args) +Fary_join(argc, argv, ary) + int argc; + VALUE *argv; struct RArray *ary; - VALUE args; { VALUE sep; - rb_scan_args(args, "01", &sep); + rb_scan_args(argc, argv, "01", &sep); if (sep == Qnil) sep = OFS; if (sep != Qnil) @@ -666,7 +668,7 @@ Fary_delete(ary, item) int i1, i2; for (i1 = i2 = 0; i1 < ary->len; i1++) { - if (rb_funcall(ary->ptr[i1], eq, 1, item)) continue; + if (rb_equal(ary->ptr[i1], item)) continue; if (i1 != i2) { ary->ptr[i2] = ary->ptr[i1]; } @@ -704,15 +706,16 @@ Fary_clear(ary) } static VALUE -Fary_fill(ary, args) +Fary_fill(argc, argv, ary) + int argc; + VALUE *argv; struct RArray *ary; - VALUE args; { VALUE item, arg1, arg2; int beg, len, end; VALUE *p, *pend; - rb_scan_args(args, "12", &item, &arg1, &arg2); + rb_scan_args(argc, argv, "12", &item, &arg1, &arg2); if (arg2 == Qnil && obj_is_kind_of(arg1, C_Range)) { range_beg_end(arg1, &beg, &len, ary->len); } @@ -736,7 +739,7 @@ Fary_fill(ary, args) REALLOC_N(ary->ptr, VALUE, ary->capa); } if (beg > ary->len) { - memset(ary->ptr+ary->len, 0, sizeof(VALUE)*(end-ary->len)); + MEMZERO(ary->ptr+ary->len, VALUE, end-ary->len); } ary->len = end; } @@ -757,8 +760,8 @@ Fary_plus(x, y) switch (TYPE(y)) { case T_ARRAY: z = (struct RArray*)ary_new2(x->len + y->len); - memcpy(z->ptr, x->ptr, x->len*sizeof(VALUE)); - memcpy(z->ptr+x->len, y->ptr, y->len*sizeof(VALUE)); + MEMCPY(z->ptr, x->ptr, VALUE, x->len); + MEMCPY(z->ptr+x->len, y->ptr, VALUE, y->len); z->len = x->len + RARRAY(y)->len; break; @@ -783,7 +786,7 @@ Fary_times(ary, times) ary2->len = len; for (i=0; ilen) { - memcpy(ary2->ptr+i, ary->ptr, ary->len*sizeof(VALUE)); + MEMCPY(ary2->ptr+i, ary->ptr, VALUE, ary->len); } return (VALUE)ary2; @@ -798,9 +801,8 @@ Fary_assoc(ary, key) p = ary->ptr; pend = p + ary->len; while (p < pend) { - if (TYPE(*p) == T_ARRAY - && RARRAY(*p)->len == 2 - && rb_funcall(RARRAY(*p)->ptr[0], eq, 1, key)) + if (TYPE(*p) == T_CONS + && rb_equal(RCONS(*p)->car, key)) return *p; } return Qnil; @@ -815,9 +817,8 @@ Fary_rassoc(ary, value) p = ary->ptr; pend = p + ary->len; while (p < pend) { - if (TYPE(*p) == T_ARRAY - && RARRAY(*p)->len == 2 - && rb_funcall(RARRAY(*p)->ptr[1], eq, 1, value)) + if (TYPE(*p) == T_CONS + && rb_equal(RCONS(*p)->cdr, value)) return *p; } return Qnil; @@ -832,7 +833,7 @@ Fary_equal(ary1, ary2) if (TYPE(ary2) != T_ARRAY) return FALSE; if (ary1->len != ary2->len) return FALSE; for (i=0; ilen; i++) { - if (!rb_funcall(ary1->ptr[i], eq, 1, ary2->ptr[i])) + if (!rb_equal(ary1->ptr[i], ary2->ptr[i])) return FALSE; } return TRUE; @@ -860,7 +861,7 @@ Fary_includes(ary, item) { int i; for (i=0; ilen; i++) { - if (rb_funcall(ary->ptr[i], eq, 1, item)) { + if (rb_equal(ary->ptr[i], item)) { return TRUE; } } @@ -943,8 +944,8 @@ Init_Array() 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_aref, -1); + rb_define_method(C_Array, "[]=", Fary_aset, -1); rb_define_method(C_Array, "<<", Fary_append, 1); rb_define_method(C_Array, "push", ary_push, 1); rb_define_method(C_Array, "pop", ary_pop, 0); @@ -957,13 +958,13 @@ Init_Array() rb_define_method(C_Array, "index", Fary_index, 1); rb_define_method(C_Array, "indexes", Fary_indexes, -2); rb_define_method(C_Array, "clone", ary_clone, 0); - rb_define_method(C_Array, "join", Fary_join, -2); + rb_define_method(C_Array, "join", Fary_join, -1); rb_define_method(C_Array, "reverse", Fary_reverse, 0); rb_define_method(C_Array, "sort", Fary_sort, 0); rb_define_method(C_Array, "delete", Fary_delete, 1); rb_define_method(C_Array, "delete_if", Fary_delete_if, 0); rb_define_method(C_Array, "clear", Fary_clear, 0); - rb_define_method(C_Array, "fill", Fary_fill, -2); + rb_define_method(C_Array, "fill", Fary_fill, -1); rb_define_method(C_Array, "includes", Fary_includes, 1); rb_define_method(C_Array, "assoc", Fary_assoc, 1); @@ -977,7 +978,4 @@ Init_Array() rb_define_method(C_Array, "|", Fary_or, 1); cmp = rb_intern("<=>"); - eq = rb_intern("=="); - - rb_define_method(C_Kernel, "::", assoc_new, 1); } diff --git a/bignum.c b/bignum.c index 9490b36672..59667faaca 100644 --- a/bignum.c +++ b/bignum.c @@ -3,7 +3,7 @@ bignum.c - $Author: matz $ - $Date: 1994/12/06 09:29:49 $ + $Date: 1995/01/10 10:42:19 $ created at: Fri Jun 10 00:48:55 JST 1994 ************************************************/ @@ -58,7 +58,7 @@ big_clone(x) { VALUE z = bignew_1(CLASS_OF(x), x->len, x->sign); - memcpy(BDIGITS(z), BDIGITS(x), x->len*sizeof(USHORT)); + MEMCPY(BDIGITS(z), BDIGITS(x), USHORT, x->len); return (VALUE)z; } diff --git a/class.c b/class.c index fa1860060a..ba056a6283 100644 --- a/class.c +++ b/class.c @@ -3,7 +3,7 @@ class.c - $Author: matz $ - $Date: 1994/12/16 00:59:42 $ + $Date: 1995/01/10 10:42:21 $ created at: Tue Aug 10 15:05:44 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -285,7 +285,7 @@ rb_define_attr(class, name, pub) ID attr, attreq, attriv; attr = rb_intern(name); - buf = (char*)alloca(strlen(name) + 2); + buf = ALLOCA_N(char,strlen(name)+2); sprintf(buf, "%s=", name); attreq = rb_intern(buf); sprintf(buf, "@%s", name); @@ -311,41 +311,32 @@ rb_define_single_attr(obj, name, pub) #include int -rb_scan_args(args, fmt, va_alist) - VALUE args; +rb_scan_args(argc, argv, fmt, va_alist) + int argc; + VALUE *argv; char *fmt; va_dcl { - int n, i, len; + int n, i; char *p = fmt; VALUE *var; va_list vargs; - if (NIL_P(args)) { - len = 0; - args = ary_new(); - } - else { - Check_Type(args, T_ARRAY); - len = RARRAY(args)->len; - } - va_start(vargs); if (*p == '*') { var = va_arg(vargs, VALUE*); - *var = args; - return len; + *var = ary_new4(argc, argv); + return argc; } if (isdigit(*p)) { n = *p - '0'; - if (n > len) - Fail("Wrong number of arguments for %s", - rb_id2name(the_env->last_func)); + if (n > argc) + Fail("Wrong number of arguments (%d for %d)", argc, n); for (i=0; i i) { - *var = ary_entry(args, i); + if (argc > i) { + *var = argv[i]; } else { *var = Qnil; @@ -369,16 +360,16 @@ rb_scan_args(args, fmt, va_alist) if(*p == '*') { var = va_arg(vargs, VALUE*); - if (len > i) { - *var = ary_new4(RARRAY(args)->len-i, RARRAY(args)->ptr+i); + if (argc > i) { + *var = ary_new4(argc-i, argv+i); } else { *var = ary_new(); } } else if (*p == '\0') { - if (len > i) { - Fail("Wrong # of arguments(%d for %d)", len, i); + if (argc > i) { + Fail("Wrong # of arguments(%d for %d)", argc, i); } } else { @@ -386,7 +377,7 @@ rb_scan_args(args, fmt, va_alist) } va_end(vargs); - return len; + return argc; error: Fail("bad scan arg format: %s", fmt); diff --git a/configure.in b/configure.in index 5ee5463ab9..efe87a287c 100644 --- a/configure.in +++ b/configure.in @@ -25,6 +25,7 @@ AC_HAVE_LIBRARY(m, [LIBS="$LIBS -lm"]) AC_HAVE_LIBRARY(dbm, [LIBS="$LIBS -ldbm"]) AC_HAVE_LIBRARY(socket, [LIBS="$LIBS -lsocket"]) AC_HAVE_LIBRARY(crypt, [LIBS="$LIBS -lcrypt"]) +AC_VFORK AC_REPLACE_FUNCS(memmove mkdir strerror strftime\ strstr strtol strtoul strdup) AC_HAVE_FUNCS(fmod killpg socket random wait4 waitpid syscall getcwd\ diff --git a/cons.c b/cons.c new file mode 100644 index 0000000000..ac562814ca --- /dev/null +++ b/cons.c @@ -0,0 +1,270 @@ +/************************************************ + + cons.c - + + $Author: matz $ + $Date: 1995/01/10 10:22:24 $ + created at: Fri Jan 6 10:10:36 JST 1995 + + Copyright (C) 1994 Yukihiro Matsumoto + +************************************************/ + +#include "ruby.h" + +VALUE C_Cons; + +static ID eq; + +VALUE rb_to_a(); + +VALUE +assoc_new(car, cdr) + VALUE car, cdr; +{ + NEWOBJ(cons, struct RCons); + OBJSETUP(cons, C_Cons, T_CONS); + + cons->car = car; + cons->cdr = cdr; + + return (VALUE)cons; +} + +#define cons_new assoc_new + +static VALUE +Fcons_car(cons) + struct RCons *cons; +{ + return cons->car; +} + +static VALUE +Fcons_cdr(cons) + struct RCons *cons; +{ + return cons->cdr; +} + +static VALUE +Fcons_set_car(cons, val) + struct RCons *cons; + VALUE val; +{ + return cons->car = val; +} + +static VALUE +Fcons_set_cdr(cons, val) + struct RCons *cons; + VALUE val; +{ + return cons->cdr = val; +} + +static int +cons_length(list) + struct RCons *list; +{ + int len = 1; + + while (TYPE(list) == T_CONS) { + len++; + list = RCONS(list->cdr); + } + return len; +} + +static VALUE +Fcons_length(list) + struct RCons *list; +{ + int len = cons_length(list); + return INT2FIX(len); +} + +static VALUE +cons_aref(list, nth) + struct RCons *list; + int nth; +{ + if (nth == 0) return list->car; + list = RCONS(list->cdr); + if (TYPE(list) != T_CONS) { + if (nth == 1) return (VALUE)list; + return Qnil; + } + + return cons_aref(list, nth-1); +} + +static VALUE +Fcons_aref(list, nth) + struct RCons *list; + VALUE nth; +{ + int n = NUM2INT(nth); + + if (n < 0) { + n = cons_length(list)+n; + if (n < 0) return Qnil; + } + return cons_aref(list, n); +} + +static VALUE +cons_aset(list, nth, val) + struct RCons *list; + int nth; + VALUE val; +{ + if (nth == 0) return list->car = val; + if (TYPE(list->cdr) != T_CONS) { + if (nth > 2) { + Fail("list too short"); + } + if (nth == 1) + list->cdr = val; + else + list->cdr = cons_new(list->cdr, val); + return val; + } + return cons_aset(list->cdr, nth-1, val); +} + +static VALUE +Fcons_aset(list, nth, val) + struct RCons *list; + VALUE nth, val; +{ + int n = NUM2INT(nth); + + if (n < 0) { + n = cons_length(list)+n; + if (n < 0) { + Fail("negative offset too big"); + } + } + return cons_aset(list, n, val); +} + +static VALUE +Fcons_each(list) + struct RCons *list; +{ + rb_yield(list->car); + if (TYPE(list->cdr) != T_CONS) { + rb_yield(list->cdr); + return Qnil; + } + return Fcons_each(list->cdr); +} + +static VALUE +Fcons_equal(cons1, cons2) + struct RCons *cons1, *cons2; +{ + if (TYPE(cons2) != T_CONS) return FALSE; + if (!rb_equal(cons1->car, cons2->car)) return FALSE; + return rb_equal(cons1->cdr, cons2->cdr); +} + +static ID hash; + +static VALUE +Fcons_hash(cons) + struct RCons *cons; +{ + int key; + + key = rb_funcall(cons->car, hash, 0, 0); + key ^= rb_funcall(cons->cdr, hash, 0, 0); + return INT2FIX(key); +} + +static VALUE +Fcons_to_s(cons) + struct RCons *cons; +{ + VALUE str1, str2; + ID to_s = rb_intern("to_s"); + + str1 = rb_funcall(cons->car, to_s, 0); + cons = RCONS(cons->cdr); + while (cons) { + if (TYPE(cons) != T_CONS) { + str2 = rb_funcall(cons, to_s, 0); + str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len); + break; + } + str2 = rb_funcall(cons->car, to_s, 0); + str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len); + cons = RCONS(cons->cdr); + } + + return str1; +} + +static VALUE +Fcons_inspect(cons) + struct RCons *cons; +{ + VALUE str1, str2; + ID inspect = rb_intern("_inspect"); + + str1 = rb_funcall(cons->car, inspect, 0, 0); + str2 = rb_funcall(cons->cdr, inspect, 0, 0); + str_cat(str1, "::", 2); + str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len); + + return str1; +} + +static VALUE +Fcons_copy(list) + struct RCons *list; +{ + VALUE cdr = list->cdr; + + if (TYPE(cdr) == T_CONS) + return cons_new(list->car, Fcons_copy(list->cdr)); + else + return cons_new(list->car, cdr); +} + +extern VALUE C_Kernel; +extern VALUE M_Enumerable; + +Init_Cons() +{ + C_Cons = rb_define_class("Cons", C_Object); + + rb_undef_method(CLASS_OF(C_Cons), "new"); + rb_undef_method(C_Cons, "clone"); + + rb_include_module(C_Cons, M_Enumerable); + + rb_define_method(C_Cons, "car", Fcons_car, 0); + rb_define_method(C_Cons, "cdr", Fcons_cdr, 0); + + rb_define_method(C_Cons, "car=", Fcons_set_car, 1); + rb_define_method(C_Cons, "cdr=", Fcons_set_cdr, 1); + + rb_define_method(C_Cons, "==", Fcons_equal, 1); + rb_define_method(C_Cons, "hash", Fcons_hash, 0); + hash = rb_intern("hash"); + rb_define_method(C_Cons, "length", Fcons_length, 0); + + rb_define_method(C_Cons, "to_s", Fcons_to_s, 0); + rb_define_method(C_Cons, "_inspect", Fcons_inspect, 0); + + /* methods to access as list */ + rb_define_method(C_Cons, "[]", Fcons_aref, 1); + rb_define_method(C_Cons, "[]=", Fcons_aset, 2); + rb_define_method(C_Cons, "each", Fcons_each, 0); + + rb_define_method(C_Cons, "copy", Fcons_copy, 0); + + rb_define_method(C_Kernel, "::", assoc_new, 1); +} diff --git a/dbm.c b/dbm.c index 16ca0880f7..c0fd514e59 100644 --- a/dbm.c +++ b/dbm.c @@ -3,7 +3,7 @@ dbm.c - $Author: matz $ - $Date: 1994/12/06 09:29:52 $ + $Date: 1995/01/10 10:42:24 $ created at: Mon Jan 24 15:59:52 JST 1994 Copyright (C) 1994 Yukihiro Matsumoto @@ -15,7 +15,7 @@ #ifdef USE_DBM #include -#include +#include #include VALUE C_DBM; @@ -50,15 +50,17 @@ free_dbm(dbmp) } static VALUE -Sdbm_open(class, args) - VALUE class, args; +Sdbm_open(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; { VALUE file, vmode; DBM *dbm, **dbm2; int mode; VALUE obj; - if (rb_scan_args(args, "11", &file, &vmode) == 1) { + if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) { mode = 0666; /* default value */ } else if (NIL_P(vmode)) { @@ -389,7 +391,7 @@ Init_DBM() C_DBM = rb_define_class("DBM", C_Object); rb_include_module(C_DBM, M_Enumerable); - rb_define_single_method(C_DBM, "open", Sdbm_open, -2); + rb_define_single_method(C_DBM, "open", Sdbm_open, -1); 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); diff --git a/defines.h b/defines.h index 4928db7d1e..ac4ca46075 100644 --- a/defines.h +++ b/defines.h @@ -3,7 +3,7 @@ defines.h - $Author: matz $ - $Date: 1994/12/09 01:28:22 $ + $Date: 1995/01/10 10:42:25 $ created at: Wed May 18 00:21:44 JST 1994 ************************************************/ @@ -30,9 +30,6 @@ /* define USE_DBM to use dbm class. */ #define USE_DBM -#ifdef HAVE_SYSCALL_H -/* define SAFE_SIGHANDLE to override syscall for trap. */ #define SAFE_SIGHANDLE -#endif #endif diff --git a/dict.c b/dict.c index 3db2501fd9..d6ccbca56e 100644 --- a/dict.c +++ b/dict.c @@ -3,7 +3,7 @@ dict.c - $Author: matz $ - $Date: 1994/12/19 08:30:00 $ + $Date: 1995/01/10 10:42:26 $ created at: Mon Nov 22 18:51:18 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -16,14 +16,14 @@ VALUE C_Dict; static VALUE envtbl; -static ID hash, eq; +static ID hash; VALUE Fgetenv(), Fsetenv(); static VALUE rb_cmp(a, b) VALUE a, b; { - return rb_funcall(a, eq, 1, b)?0:1; + return rb_equal(a, b)?0:1; } static VALUE @@ -34,8 +34,8 @@ rb_hash(a, mod) return rb_funcall(a, hash, 0) % mod; } -#define ASSOC_KEY(a) RARRAY(a)->ptr[0] -#define ASSOC_VAL(a) RARRAY(a)->ptr[1] +#define ASSOC_KEY(a) RCONS(a)->car +#define ASSOC_VAL(a) RCONS(a)->cdr static VALUE Sdic_new(class) @@ -342,7 +342,7 @@ static int dic_search_value(key, value, data) VALUE key, value, *data; { - if (rb_funcall(value, eq, 1, data[1])) { + if (rb_equal(value, data[1])) { data[0] = TRUE; return ST_STOP; } @@ -378,7 +378,7 @@ dic_equal(key, val1, data) data->result = FALSE; return ST_STOP; } - if (!rb_funcall(val1, eq, 1, val2)) { + if (!rb_equal(val1, val2)) { data->result = FALSE; return ST_STOP; } @@ -544,7 +544,6 @@ Init_Dict() extern VALUE M_Enumerable; hash = rb_intern("hash"); - eq = rb_intern("=="); C_Dict = rb_define_class("Dict", C_Object); rb_name_class(C_Dict, rb_intern("Hash")); /* alias */ diff --git a/dir.c b/dir.c index 84299127ca..0baa13fdd1 100644 --- a/dir.c +++ b/dir.c @@ -3,7 +3,7 @@ dir.c - $Author: matz $ - $Date: 1994/12/09 09:40:18 $ + $Date: 1995/01/10 10:42:28 $ created at: Wed Jan 5 09:51:01 JST 1994 Copyright (C) 1994 Yukihiro Matsumoto @@ -146,13 +146,15 @@ Fdir_close(dir) char *getenv(); static VALUE -Sdir_chdir(obj, args) - VALUE obj, args; +Sdir_chdir(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE path; char *dist = ""; - rb_scan_args(args, "01", args, &path); + rb_scan_args(argc, argv, "01", &path); if (path) { Check_Type(path, T_STRING); dist = RSTRING(path)->ptr; @@ -199,13 +201,15 @@ Sdir_chroot(dir, path) } static VALUE -Sdir_mkdir(obj, args) - VALUE obj, args; +Sdir_mkdir(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE path, vmode; int mode; - if (rb_scan_args(args, "11", &path, &vmode) == 2) { + if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) { mode = NUM2INT(vmode); } else { @@ -248,11 +252,11 @@ Init_Dir() rb_define_method(C_Dir,"seek", Fdir_seek, 1); rb_define_method(C_Dir,"close", Fdir_close, 0); - rb_define_single_method(C_Dir,"chdir", Sdir_chdir, -2); + rb_define_single_method(C_Dir,"chdir", Sdir_chdir, -1); rb_define_single_method(C_Dir,"getwd", Sdir_getwd, 0); rb_define_single_method(C_Dir,"pwd", Sdir_getwd, 0); rb_define_single_method(C_Dir,"chroot", Sdir_chroot, 1); - rb_define_single_method(C_Dir,"mkdir", Sdir_mkdir, -2); + rb_define_single_method(C_Dir,"mkdir", Sdir_mkdir, -1); rb_define_single_method(C_Dir,"rmdir", Sdir_rmdir, 1); rb_define_single_method(C_Dir,"delete", Sdir_rmdir, 1); rb_define_single_method(C_Dir,"unlink", Sdir_rmdir, 1); diff --git a/enum.c b/enum.c index c6866b425f..5eaef855f1 100644 --- a/enum.c +++ b/enum.c @@ -3,7 +3,7 @@ enum.c - $Author: matz $ - $Date: 1994/12/06 09:29:56 $ + $Date: 1995/01/10 10:42:29 $ created at: Fri Oct 1 15:15:19 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -13,7 +13,7 @@ #include "ruby.h" VALUE M_Enumerable; -static ID id_each, id_match, id_equal, id_cmp; +static ID id_each, id_match, id_cmp; void rb_each(obj) @@ -235,7 +235,7 @@ enum_index(item, iv) VALUE item; struct i_v_pair *iv; { - if (rb_funcall(item, id_equal, 1, iv->v)) { + if (rb_equal(item, 1, iv->v)) { iv->found = 1; rb_break(); } @@ -263,7 +263,7 @@ enum_includes(item, iv) VALUE item; struct i_v_pair *iv; { - if (rb_funcall(item, id_equal, 1, iv->v)) { + if (rb_equal(item, iv->v)) { iv->i = 1; rb_break(); } @@ -282,6 +282,24 @@ Fenum_includes(obj, val) return FALSE; } +static void +enum_length(i, length) + VALUE i; + int *length; +{ + (*length)++; +} + +static VALUE +Fenum_length(obj) + VALUE obj; +{ + int length = 0; + + rb_iterate(rb_each, obj, enum_length, &length); + return INT2FIX(length); +} + Init_Enumerable() { M_Enumerable = rb_define_module("Enumerable"); @@ -297,9 +315,9 @@ Init_Enumerable() rb_define_method(M_Enumerable,"max", Fenum_max, 0); rb_define_method(M_Enumerable,"index", Fenum_index, 1); rb_define_method(M_Enumerable,"includes", Fenum_includes, 1); + rb_define_method(M_Enumerable,"length", Fenum_length, 0); id_each = rb_intern("each"); id_match = rb_intern("=~"); - id_equal = rb_intern("=="); id_cmp = rb_intern("<=>"); } diff --git a/env.h b/env.h index ebed038d39..b13b5f0683 100644 --- a/env.h +++ b/env.h @@ -3,8 +3,8 @@ env.h - $Author: matz $ - $Revision: 1.7 $ - $Date: 1994/12/19 08:30:01 $ + $Revision: 1.8 $ + $Date: 1995/01/10 10:42:30 $ created at: Mon Jul 11 11:53:03 JST 1994 ************************************************/ @@ -14,19 +14,20 @@ extern struct ENVIRON { int argc; VALUE *argv; - VALUE arg_ary; ID last_func; struct RClass *last_class; struct ENVIRON *prev; } *the_env; -extern struct SCOPE { +struct SCOPE { + struct RBasic super; ID *local_tbl; VALUE *local_vars; - VALUE var_ary; - struct SCOPE *prev; + int flags; } *the_scope; +#define SCOPE_MALLOCED (1<<0) + extern int rb_in_eval; #endif /* ENV_H */ diff --git a/error.c b/error.c index 05463504f8..437d0baef3 100644 --- a/error.c +++ b/error.c @@ -3,7 +3,7 @@ error.c - $Author: matz $ - $Date: 1994/11/22 01:22:31 $ + $Date: 1995/01/10 10:42:31 $ created at: Mon Aug 9 16:11:34 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -159,11 +159,15 @@ static char *builtin_types[] = { "Regexp", "Array", "Fixnum", - "Dictionary", + "Dict", "Data", "Method", "Struct", "Bignum", + "Node", + "Scope", + "Cons", + "Data", }; WrongType(x, t) diff --git a/etc.c b/etc.c index 501c9106d3..141d979fad 100644 --- a/etc.c +++ b/etc.c @@ -3,7 +3,7 @@ etc.c - $Author: matz $ - $Date: 1994/12/06 09:29:57 $ + $Date: 1995/01/10 10:42:32 $ created at: Tue Mar 22 18:39:19 JST 1994 ************************************************/ @@ -60,14 +60,16 @@ setup_passwd(pwd) } static VALUE -Fetc_getpwuid(obj, args) - VALUE obj, args; +Fetc_getpwuid(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE id; int uid; struct passwd *pwd; - if (rb_scan_args(args, "01", &id) == 1) { + if (rb_scan_args(argc, argv, "01", &id) == 1) { uid = NUM2INT(id); } else { @@ -180,7 +182,7 @@ Init_Etc() rb_define_module_function(M_Etc, "getlogin", Fetc_getlogin, 0); - rb_define_module_function(M_Etc, "getpwuid", Fetc_getpwuid, -2); + rb_define_module_function(M_Etc, "getpwuid", Fetc_getpwuid, -1); rb_define_module_function(M_Etc, "getpwnam", Fetc_getpwnam, 1); rb_define_module_function(M_Etc, "passwd", Fetc_passwd, 0); diff --git a/eval.c b/eval.c index 952d8c2f7d..c54fa14e5e 100644 --- a/eval.c +++ b/eval.c @@ -3,7 +3,7 @@ eval.c - $Author: matz $ - $Date: 1994/12/20 05:07:05 $ + $Date: 1995/01/10 10:42:34 $ created at: Thu Jun 10 14:22:17 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -26,17 +26,10 @@ void rb_clear_cache(); #include #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 */ @@ -79,6 +72,7 @@ rb_get_method_body(classp, idp, noexp) if ((body = search_method(class, id, &origin)) == Qnil) { return Qnil; } + if (body->nd_body == Qnil) return Qnil; ent = cache + EXPR1(class, id); #ifdef TEST @@ -87,19 +81,20 @@ rb_get_method_body(classp, idp, noexp) } #endif /* store in cache */ - ent->mid = id; ent->class = class; - ent->origin = origin; - ent->method = body->nd_body; ent->noex = body->nd_noex; body = body->nd_body; - - if (body == Qnil) return Qnil; if (nd_type(body) == NODE_FBODY) { - *idp = body->nd_mid; - body = body->nd_head; + *classp = ent->origin = (struct RClass*)body->nd_orig; + *idp = ent->mid = body->nd_mid; + body = ent->method = body->nd_head; } - *classp = origin; + else { + *classp = ent->origin = origin; + ent->mid = id; + ent->method = body; + } + if (noexp) *noexp = ent->noex; return body; } @@ -114,7 +109,7 @@ rb_alias(class, name, def) if (name == def) return; body = search_method(class, def, &origin); - if (body == Qnil) { + if (body == Qnil || body->nd_body == Qnil) { Fail("undefined method `%s' for class `%s'", rb_id2name(def), rb_class2name(class)); } @@ -126,8 +121,9 @@ rb_alias(class, name, def) rb_clear_cache(old->nd_body); } - st_insert(class->m_tbl, name, NEW_METHOD(NEW_FBODY(body->nd_body, name), - body->nd_noex)); + st_insert(class->m_tbl, name, + NEW_METHOD(NEW_FBODY(body->nd_body, def, origin), + body->nd_noex)); } void @@ -196,7 +192,7 @@ rb_clear_cache2(class) } } -static ID match, each; +static ID match, each, aref, aset; VALUE errstr, errat; extern NODE *eval_tree; extern int nerrs; @@ -214,18 +210,18 @@ struct ENVIRON *the_env, *top_env; struct SCOPE *the_scope, *top_scope; #define PUSH_ENV() { \ - struct ENVIRON _this; \ - _this.prev = the_env; \ - the_env = &_this; \ + struct ENVIRON _env; \ + _env.prev = the_env; \ + the_env = &_env; \ -#define POP_ENV() the_env = the_env->prev; } +#define POP_ENV() the_env = _env.prev; } struct BLOCK { NODE *var; NODE *body; VALUE self; struct ENVIRON env; - struct SCOPE scope; + struct SCOPE *scope; int level; VALUE block; int iter; @@ -233,16 +229,16 @@ struct BLOCK { } *the_block; #define PUSH_BLOCK(v,b) { \ - struct BLOCK _this; \ - _this.level = tag_level; \ - _this.var=v; \ - _this.body = b; \ - _this.self = Qself; \ - _this.env = *the_env; \ - _this.scope = *the_scope; \ - _this.block = Qnil; \ - _this.prev = the_block; \ - the_block = &_this; \ + struct BLOCK _block; \ + _block.level = tag_level; \ + _block.var=v; \ + _block.body = b; \ + _block.self = Qself; \ + _block.env = *the_env; \ + _block.scope = the_scope; \ + _block.block = Qnil; \ + _block.prev = the_block; \ + the_block = &_block; \ #define PUSH_BLOCK2(b) { \ b->prev = the_block; \ @@ -255,14 +251,18 @@ static struct iter { struct iter *prev; } *iter; -#define PUSH_ITER(i) {\ - struct iter __iter__;\ - __iter__.prev = iter;\ - __iter__.iter = (i);\ - iter = &__iter__;\ +#define ITER_NOT 0 +#define ITER_PRE 1 +#define ITER_CUR 2 + +#define PUSH_ITER(i) { \ + struct iter _iter; \ + _iter.prev = iter; \ + _iter.iter = (i); \ + iter = &_iter; \ -#define POP_ITER() \ - iter = iter->prev;\ +#define POP_ITER() \ + iter = _iter.prev; \ } static int tag_level, target_level; @@ -277,13 +277,13 @@ static struct tag { } *prot_tag; #define PUSH_TAG() { \ - struct tag _this; \ - _this.level= ++tag_level; \ - _this.self = Qself; \ - _this.env = the_env; \ - _this.iter = iter; \ - _this.prev = prot_tag; \ - prot_tag = &_this; \ + struct tag _tag; \ + _tag.level= ++tag_level; \ + _tag.self = Qself; \ + _tag.env = the_env; \ + _tag.iter = iter; \ + _tag.prev = prot_tag; \ + prot_tag = &_tag; \ #define EXEC_TAG() (setjmp(prot_tag->buf)) #define JUMP_TAG(val) { \ @@ -294,7 +294,7 @@ static struct tag { #define POP_TAG() \ tag_level--; \ - prot_tag = prot_tag->prev; \ + prot_tag = _tag.prev; \ } #define TAG_RETURN 1 @@ -321,15 +321,16 @@ struct class_link { #define POP_CLASS() \ the_class = class_link->class; \ - class_link = class_link->prev; } + class_link = _link.prev; } #define PUSH_SCOPE() { \ - struct SCOPE _scope; \ - _scope = *the_scope; \ - _scope.prev = the_scope; \ - the_scope = &_scope; \ + struct SCOPE *_old; \ + NEWOBJ(_scope, struct SCOPE); \ + OBJSETUP(_scope, Qnil, T_SCOPE); \ + _old = the_scope; \ + the_scope = _scope; \ -#define POP_SCOPE() the_scope = the_scope->prev; } +#define POP_SCOPE() the_scope = _old; } static VALUE rb_eval(); static VALUE Feval(); @@ -386,15 +387,23 @@ ruby_init(argc, argv, envp) { int state; static struct ENVIRON env; - static struct SCOPE scope; the_env = top_env = &env; - the_scope = top_scope = &scope; - + + PUSH_SCOPE(); + the_scope->local_vars = Qnil; + the_scope->local_tbl = Qnil; + top_scope = the_scope; + PUSH_TAG(); + PUSH_ITER(ITER_NOT); if ((state = EXEC_TAG()) == 0) { ruby_init0(argc, argv, envp); } + POP_ITER(); POP_TAG(); + POP_SCOPE(); + the_scope = top_scope; + if (state) { PUSH_TAG(); error_print(); @@ -412,9 +421,6 @@ Eval(toplevel) NODE *tree; int state; - if (match == Qnil) match = rb_intern("=~"); - if (each == Qnil) each = rb_intern("each"); - tree = eval_tree; eval_tree = Qnil; sourcefile = tree->file; @@ -440,10 +446,12 @@ ruby_run() errat = Qnil; /* clear for execution */ PUSH_TAG(); + PUSH_ITER(ITER_NOT); if ((state = EXEC_TAG()) == 0) { the_class = (struct RClass*)C_Object; Eval(1); } + POP_ITER(); POP_TAG(); switch (state) { @@ -484,29 +492,51 @@ void rb_trap_eval(cmd) VALUE cmd; { - int state, go_out; + int state; + struct SCOPE *saved_scope; PUSH_SELF(TopSelf); PUSH_CLASS(); PUSH_TAG(); - PUSH_SCOPE(); - if ((state = EXEC_TAG()) == 0) { - the_class = (struct RClass*)C_Object; - the_scope->local_vars = top_scope->local_vars; - the_scope->local_tbl = top_scope->local_tbl; + saved_scope = the_scope; + the_scope = top_scope; + + the_class = (struct RClass*)C_Object; + if ((state = EXEC_TAG()) == 0) { Feval(Qself, cmd); - go_out = 0; } - else { - go_out = 1; - } - POP_SCOPE(); + + the_scope = saved_scope; POP_TAG(); POP_CLASS(); POP_SELF(); - if (go_out) JUMP_TAG(state); + 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; + default: +#ifdef SAFE_SIGHANDLE + trap_immediate = 0; +#endif + JUMP_TAG(state); + break; + } } #define SETUP_ARGS {\ @@ -515,12 +545,12 @@ rb_trap_eval(cmd) argc = 0;\ argv = Qnil;\ }\ - else if (nd_type(n) == NODE_ARRAY) {\ + else if (/*nd_type(n) == NODE_LIST ||*/ nd_type(n) == NODE_ARRAY) {\ argc=n->nd_alen;\ if (argc > 0) {\ int i;\ n = node->nd_args;\ - argv = (VALUE*)alloca(sizeof(VALUE)*argc);\ + argv = ALLOCA_N(VALUE,argc);\ for (i=0;ind_head);\ n=n->nd_next;\ @@ -528,10 +558,12 @@ rb_trap_eval(cmd) }\ }\ else {\ - argc = -2;\ - argv = (VALUE*)rb_eval(n);\ - if (TYPE(argv) != T_ARRAY)\ - argv = (VALUE*)rb_to_a(argv);\ + VALUE args = rb_eval(n);\ + if (TYPE(args) != T_ARRAY)\ + args = rb_to_a(args);\ + argc = RARRAY(args)->len;\ + argv = ALLOCA_N(VALUE, argc);\ + MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\ }\ } @@ -694,13 +726,17 @@ rb_eval(node) state = EXEC_TAG(); if (state == 0) { if (nd_type(node) == NODE_ITER) { + PUSH_ITER(ITER_PRE); result = rb_eval(node->nd_iter); + POP_ITER(); } else { VALUE recv; recv = rb_eval(node->nd_iter); - result = rb_call(CLASS_OF(recv),recv,each,0,Qnil,0,1); + PUSH_ITER(ITER_PRE); + result = rb_call(CLASS_OF(recv),recv,each,0,Qnil,0); + POP_ITER(); } } POP_TAG(); @@ -743,17 +779,6 @@ rb_eval(node) } return result; - case NODE_IYIELD: - { - VALUE val; - - val = rb_eval(node->nd_stts); - PUSH_ITER(1); - result = rb_yield(val); - POP_ITER(); - } - return result; - case NODE_PROT: PUSH_TAG(); switch (state = EXEC_TAG()) { @@ -841,16 +866,16 @@ rb_eval(node) break; case NODE_CALL: - case NODE_ICALL: { VALUE recv; int argc; VALUE *argv; /* used in SETUP_ARGS */ - VALUE buf[3]; + PUSH_ITER(ITER_NOT); recv = node->nd_recv?rb_eval(node->nd_recv):Qself; SETUP_ARGS; + POP_ITER(); return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv, - node->nd_recv?0:1, nd_type(node)==NODE_ICALL); + node->nd_recv?0:1); } break; @@ -865,11 +890,15 @@ rb_eval(node) argv = the_env->argv; } else { + PUSH_ITER(ITER_NOT); SETUP_ARGS; + POP_ITER(); } + PUSH_ITER(iter->iter?ITER_PRE:ITER_NOT); result = rb_call(the_env->last_class->super, Qself, - the_env->last_func, argc, argv, 1, iter->iter); + the_env->last_func, argc, argv, 1); + POP_ITER(); } return result; @@ -880,9 +909,8 @@ rb_eval(node) PUSH_SCOPE(); PUSH_TAG(); if (node->nd_cnt > 0) { - the_scope->local_vars = (VALUE*) - alloca(sizeof(VALUE)*node->nd_cnt); - memset(the_scope->local_vars, 0, sizeof(VALUE)*node->nd_cnt); + the_scope->local_vars = ALLOCA_N(VALUE, node->nd_cnt); + MEMZERO(the_scope->local_vars, VALUE, node->nd_cnt); the_scope->local_tbl = node->nd_tbl; } else { @@ -893,12 +921,45 @@ rb_eval(node) result = rb_eval(node->nd_body); } POP_TAG(); + if (!(the_scope->flags & SCOPE_MALLOCED)) { + the_scope->local_vars = Qnil; + the_scope->local_tbl = Qnil; + } POP_SCOPE(); if (state != 0) JUMP_TAG(state); return result; } + case NODE_OP_ASGN1: + { + VALUE recv, args, val; + NODE *rval; + + recv = rb_eval(node->nd_recv); + rval = node->nd_args->nd_head; + + args = rb_eval(node->nd_args->nd_next); + val = rb_apply(recv, aref, args); + val = rb_funcall(val, node->nd_mid, 1, rb_eval(rval)); + ary_push(args, val); + return rb_apply(recv, aset, args); + } + + case NODE_OP_ASGN2: + { + ID id = node->nd_aid; + VALUE recv, val; + + recv = rb_funcall(rb_eval(node->nd_recv), id, 0); + + id &= ~ID_SCOPE_MASK; + id |= ID_ATTRSET; + + val = rb_eval(node->nd_value); + return rb_funcall(recv, id, 1, val); + } + case NODE_MASGN: { VALUE val = rb_eval(node->nd_value); @@ -946,6 +1007,18 @@ rb_eval(node) case NODE_IVAR: return rb_ivar_get(node->nd_vid); case NODE_MVAR: + if (the_scope->flags & SCOPE_MALLOCED) { + ID id = node->nd_vid, *tbl = the_scope->local_tbl; + int i, len = tbl[0]; + + tbl++; + for (i=0; ilocal_vars[i]; + } + } return rb_mvar_get(node->nd_vid); case NODE_CVAR: @@ -1193,12 +1266,14 @@ rb_exit(status) } static VALUE -Fexit(obj, args) - VALUE obj, args; +Fexit(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE status; - if (rb_scan_args(args, "01", &status) == 1) { + if (rb_scan_args(argc, argv, "01", &status) == 1) { Need_Fixnum(status); } else { @@ -1270,25 +1345,26 @@ Fiterator_p() return FALSE; } - VALUE rb_yield(val) VALUE val; { struct BLOCK *block; NODE *node; - int state, go_out; + int state; VALUE result; + struct ENVIRON *old_env; + struct SCOPE *old_scope; if (!iterator_p()) { Fail("yield called out of iterator"); } block = the_block; - block->env.prev = the_env; + old_env = the_env; the_env = &(block->env); - block->scope.prev = the_scope; - the_scope = &(block->scope); + old_scope = the_scope; + the_scope = block->scope; the_block = block->prev; if (block->var) { if (nd_type(block->var) == NODE_MASGN) @@ -1298,6 +1374,7 @@ rb_yield(val) } PUSH_ITER(block->iter); + PUSH_SELF(block->self); PUSH_TAG(); node = block->body; switch (state = EXEC_TAG()) { @@ -1309,28 +1386,26 @@ rb_yield(val) else { result = rb_eval(node); } - go_out = 0; break; case TAG_REDO: goto redo; case TAG_CONTINUE: - go_out = 0; + state = 0; break; case TAG_RETRY: case TAG_BREAK: case TAG_RETURN: target_level = block->level; state = IN_BLOCK|state; - default: - go_out = 1; break; } POP_TAG(); + POP_SELF(); POP_ITER(); the_block = block; - the_env = the_env->prev; - the_scope = the_scope->prev; - if (go_out) JUMP_TAG(state); + the_env = old_env; + the_scope = old_scope; + if (state) JUMP_TAG(state); return result; } @@ -1359,12 +1434,12 @@ masign(node, val) asign(node->nd_args, ary_new4(len-i, RARRAY(val)->ptr+i)); } else { - asign(node->nd_args, ary_new()); + asign(node->nd_args, Qnil); } } } else if (node->nd_args) { - asign(node->nd_args, ary_new()); + asign(node->nd_args, Qnil); } while (list) { asign(list->nd_head, Qnil); @@ -1432,7 +1507,7 @@ rb_iterate(it_proc, data1, bl_proc, data2) NODE *node = NEW_CFUNC(bl_proc, data2); struct BLOCK block; - PUSH_ITER(1); + PUSH_ITER(ITER_PRE); PUSH_BLOCK(Qnil, node); PUSH_TAG(); @@ -1564,23 +1639,24 @@ rb_undefined(obj, id, noex) } static VALUE -rb_call(class, recv, mid, argc, argv, func, itr) +rb_call(class, recv, mid, argc, argv, func) struct RClass *class; VALUE recv; ID mid; int argc; VALUE *argv; - int func, itr; + int func; { NODE *body; int noex; VALUE result; struct cache_entry *ent; + int itr; /* is it in the method cache? */ ent = cache + EXPR1(class, mid); - if (ent->class == class && ent->mid == mid) { - if (ent->method == Qnil) rb_undefined(recv, mid, 0); + if (ent->mid == mid && ent->class == class) { + /* if (ent->method == Qnil) rb_undefined(recv, mid, 0); */ class = ent->origin; mid = ent->mid; body = ent->method; @@ -1597,206 +1673,224 @@ rb_call(class, recv, mid, argc, argv, func, itr) if (!func && noex) rb_undefined(recv, mid, 1); + switch (iter->iter) { + case ITER_PRE: + itr = ITER_CUR; + break; + case ITER_CUR: + default: + itr = ITER_NOT; + break; + } PUSH_ITER(itr); PUSH_SELF(recv); PUSH_ENV(); the_env->last_func = mid; the_env->last_class = class; - - if (argc < 0) { - the_env->arg_ary = (VALUE)argv; - argc = RARRAY(argv)->len; - argv = RARRAY(argv)->ptr; - } - else { - the_env->arg_ary = Qnil; - } the_env->argc = argc; the_env->argv = argv; - if (nd_type(body) == NODE_CFUNC) { - int len = body->nd_argc; + switch (nd_type(body)) { + case NODE_CFUNC: + { + int len = body->nd_argc; - if (len >= 0 && argc != len) { - Fail("Wrong # of arguments(%d for %d)", argc, body->nd_argc); - } + if (len >= 0 && argc != len) { + Fail("Wrong # of arguments(%d for %d)", argc, len); + } - switch (len) { - case -2: - result = (*body->nd_cfnc)(recv, ary_new4(argc, argv)); - break; - case -1: - result = (*body->nd_cfnc)(argc, argv); - break; - case 0: + switch (len) { + case -2: + result = (*body->nd_cfnc)(recv, ary_new4(argc, argv)); + break; + case -1: + result = (*body->nd_cfnc)(argc, argv, recv); + break; + case 0: result = (*body->nd_cfnc)(recv); - break; - case 1: - result = (*body->nd_cfnc)(recv, argv[0]); - break; - case 2: - result = (*body->nd_cfnc)(recv, argv[0], argv[1]); - break; - case 3: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2]); - break; - case 4: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3]); - break; - case 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[0], argv[1], argv[2], - argv[3], argv[4], argv[5]); - break; - case 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[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7]); - break; - case 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[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[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[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[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[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[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: - if (len < 0) { - Bug("bad argc(%d) specified for `%s(%s)'", - len, rb_class2name(class), rb_id2name(mid)); - } - else { - Fail("too many arguments(%d)", len); + break; + case 1: + result = (*body->nd_cfnc)(recv, argv[0]); + break; + case 2: + result = (*body->nd_cfnc)(recv, argv[0], argv[1]); + break; + case 3: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2]); + break; + case 4: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3]); + break; + case 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[0], argv[1], argv[2], + argv[3], argv[4], argv[5]); + break; + case 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[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7]); + break; + case 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[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[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[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[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[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[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: + if (len < 0) { + Bug("bad argc(%d) specified for `%s(%s)'", + len, rb_class2name(class), rb_id2name(mid)); + } + else { + Fail("too many arguments(%d)", len); + } + break; } - break; } - } - else { - int state; - VALUE *local_vars; + break; - sourcefile = body->file; - PUSH_SCOPE(); - PUSH_TAG(); - if (body->nd_cnt > 0) { - local_vars = (VALUE*)alloca(sizeof(VALUE)*body->nd_cnt); - memset(local_vars, 0, sizeof(VALUE)*body->nd_cnt); - the_scope->local_tbl = body->nd_tbl; - the_scope->local_vars = local_vars; - } - else { - local_vars = the_scope->local_vars = Qnil; - the_scope->local_tbl = Qnil; - } - body = body->nd_body; - if (nd_type(body) == NODE_BLOCK) { - NODE *node = body->nd_head; - NODE *local; - int i; + /* for attr get/set */ + case NODE_ATTRSET: + case NODE_IVAR: + return rb_eval(body); - if (nd_type(node) != NODE_ARGS) { - Bug("no argument-node"); + default: + { + int state; + VALUE *local_vars; + + sourcefile = body->file; + PUSH_SCOPE(); + PUSH_TAG(); + + if (body->nd_cnt > 0) { + local_vars = ALLOCA_N(VALUE, body->nd_cnt); + MEMZERO(local_vars, VALUE, body->nd_cnt); + the_scope->local_tbl = body->nd_tbl; + the_scope->local_vars = local_vars; } + else { + local_vars = the_scope->local_vars = Qnil; + the_scope->local_tbl = Qnil; + } + body = body->nd_body; + + if (nd_type(body) == NODE_BLOCK) { + NODE *node = body->nd_head; + NODE *local; + int i; + + if (nd_type(node) != NODE_ARGS) { + Bug("no argument-node"); + } - body = body->nd_next; - i = node->nd_cnt; - if (i > argc || (node->nd_rest == -1 && i < argc)) - Fail("Wrong # of arguments(%d for %d)", argc, i); - - if (local_vars) { - memcpy(local_vars, argv, argc*sizeof(VALUE)); - if (node->nd_rest >= 0) { - if (argc == 0) - local_vars[node->nd_rest] = ary_new(); - else - local_vars[node->nd_rest] = ary_new4(argc-i, argv+i); + body = body->nd_next; + i = node->nd_cnt; + if (i > argc || (node->nd_rest == -1 && i < argc)) + Fail("Wrong # of arguments(%d for %d)", argc, i); + + if (local_vars) { + if (i > 0) { + MEMCPY(local_vars, argv, VALUE, i); + } + if (node->nd_rest >= 0) { + if (argc == 0) + local_vars[node->nd_rest] = ary_new(); + else + local_vars[node->nd_rest] = ary_new4(argc-i, argv+i); + } } } - } - state = EXEC_TAG(); - if (state == 0) { - result = rb_eval(body); - } - POP_TAG(); - POP_SCOPE(); - switch (state) { - case 0: - 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_RETURN: - result = last_val; - break; - default: - JUMP_TAG(state); + state = EXEC_TAG(); + if (state == 0) { + result = rb_eval(body); + } + POP_TAG(); + if (!(the_scope->flags & SCOPE_MALLOCED)) { + the_scope->local_vars = Qnil; + the_scope->local_tbl = Qnil; + } + POP_SCOPE(); + switch (state) { + case 0: + 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_RETURN: + result = last_val; + break; + default: + JUMP_TAG(state); + } } } POP_ENV(); POP_SELF(); POP_ITER(); - return result; } @@ -1806,17 +1900,25 @@ rb_apply(recv, mid, args) struct RArray *args; ID mid; { - return rb_call(CLASS_OF(recv), recv, mid, -2, (VALUE*)args, 1, 0); + int argc; + VALUE *argv; + + argc = RARRAY(args)->len; + argv = ALLOCA_N(VALUE, argc); + MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc); + return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1); } static VALUE -Fapply(recv, args) - VALUE recv, args; +Fapply(argc, argv, recv) + int argc; + VALUE *argv; + VALUE recv; { VALUE vid, rest; ID mid; - rb_scan_args(args, "1*", &vid, &rest); + rb_scan_args(argc, argv, "1*", &vid, &rest); if (TYPE(vid) == T_STRING) { mid = rb_intern(RSTRING(vid)->ptr); } @@ -1841,7 +1943,7 @@ rb_funcall(recv, mid, n, va_alist) if (n > 0) { int i; - argv = (VALUE*)alloca(sizeof(VALUE)*n); + argv = ALLOCA_N(VALUE, n); va_start(ar); for (i=0;iptr); @@ -1953,15 +2055,15 @@ Fload(obj, fname) static int rb_dln_init = 0; extern char *rb_dln_argv0; int len = strlen(file); - + if (len > 2 && file[len-1] == 'o' && file[len-2] == '.') { if (rb_dln_init == 0 && dln_init(rb_dln_argv0) == -1) { Fail("%s: %s", rb_dln_argv0, dln_strerror()); } - + if (dln_load(file) == -1) Fail(dln_strerror()); - + return TRUE; } } @@ -2069,11 +2171,37 @@ Init_load() Init_eval() { + match = rb_intern("=~"); + each = rb_intern("each"); + + aref = rb_intern("[]"); + aset = rb_intern("[]="); + + rb_global_variable(&top_scope); rb_global_variable(&eval_tree); - rb_define_private_method(C_Kernel, "exit", Fexit, -2); + rb_define_private_method(C_Kernel, "exit", Fexit, -1); rb_define_private_method(C_Kernel, "eval", Feval, 1); rb_define_private_method(C_Kernel, "iterator_p", Fiterator_p, 0); - rb_define_method(C_Kernel, "apply", Fapply, -2); + rb_define_method(C_Kernel, "apply", Fapply, -1); +} + +void +scope_dup(scope) + struct SCOPE *scope; +{ + ID *tbl; + VALUE *vars; + + if (scope->flags & SCOPE_MALLOCED) return; + if (!scope->local_tbl) return; + + tbl = scope->local_tbl; + scope->local_tbl = ALLOC_N(ID, tbl[0]+1); + MEMCPY(scope->local_tbl, tbl, ID, tbl[0]+1); + vars = scope->local_vars; + scope->local_vars = ALLOC_N(VALUE, tbl[0]); + MEMCPY(scope->local_vars, vars, VALUE, tbl[0]); + scope->flags |= SCOPE_MALLOCED; } VALUE C_Block; @@ -2083,8 +2211,8 @@ static void blk_mark(data) struct BLOCK *data; { - gc_mark_scope(&data->scope); - gc_mark(data->env.arg_ary); + gc_mark_env(&data->env); + gc_mark(data->scope); gc_mark(data->var); gc_mark(data->body); gc_mark(data->self); @@ -2094,8 +2222,7 @@ static void blk_free(data) struct BLOCK *data; { - free(data->scope.local_tbl); - free(data->scope.local_vars); + free(data->env.argv); } static VALUE @@ -2104,8 +2231,6 @@ Sblk_new(class) VALUE blk; struct BLOCK *data; struct SCOPE *scope; - ID *tbl; - int len; if (!iterator_p() && !Fiterator_p()) { Fail("tryed to create Block out of iterator"); @@ -2115,30 +2240,12 @@ Sblk_new(class) blk = obj_alloc(class); Make_Data_Struct(blk, blkdata, struct BLOCK, Qnil, blk_free, data); - memcpy(data, the_block, sizeof(struct BLOCK)); - scope = the_scope; - tbl = data->scope.local_tbl; - len = tbl ? tbl[0] : 0; - - while (scope && scope->local_tbl != tbl) - scope = scope->prev; + MEMCPY(data, the_block, struct BLOCK, 1); - if (!scope) { - Bug("non-existing scope"); - } - if (scope->var_ary == Qnil) { - scope->var_ary = ary_new4(len, scope->local_vars); - scope->local_vars = RARRAY(scope->var_ary)->ptr; - } - data->scope.local_vars = scope->local_vars; - data->scope.var_ary = scope->var_ary; + data->env.argv = ALLOC_N(VALUE, data->env.argc); + MEMCPY(data->env.argv, the_block->env.argv, VALUE, data->env.argc); - if (len > 0) { - len++; - tbl = ALLOC_N(ID, len); - memcpy(tbl, data->scope.local_tbl, sizeof(ID)*len); - data->scope.local_tbl = tbl; - } + scope_dup(data->scope); the_block->block = blk; return blk; @@ -2171,7 +2278,7 @@ Fblk_do(blk, args) /* PUSH BLOCK from data */ PUSH_BLOCK2(data); - PUSH_ITER(1); + PUSH_ITER(ITER_CUR); PUSH_TAG(); state = EXEC_TAG(); diff --git a/file.c b/file.c index 8fd04bc8b1..bae2c3140b 100644 --- a/file.c +++ b/file.c @@ -4,7 +4,7 @@ file.c - $Author: matz $ - $Date: 1994/12/09 09:40:19 $ + $Date: 1995/01/10 10:42:36 $ created at: Mon Nov 15 12:24:34 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -837,15 +837,17 @@ chmod_internal(path, mode) } static VALUE -Sfile_chmod(obj, args) - VALUE obj, args; +Sfile_chmod(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE vmode; VALUE rest; int mode, n; VALUE path; - rb_scan_args(args, "1*", &vmode, &rest); + rb_scan_args(argc, argv, "1*", &vmode, &rest); mode = NUM2INT(vmode); n = apply2files(chmod_internal, rest, mode); @@ -882,14 +884,16 @@ chown_internal(path, args) } static VALUE -Sfile_chown(obj, args) - VALUE obj, args; +Sfile_chown(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE o, g, rest; struct chown_args arg; int n; - rb_scan_args(args, "2*", &o, &g, &rest); + rb_scan_args(argc, argv, "2*", &o, &g, &rest); if (o == Qnil) { arg.owner = -1; } @@ -932,14 +936,16 @@ utime_internal(path, tvp) } static VALUE -Sfile_utime(obj, args) - VALUE obj, args; +Sfile_utime(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE atime, mtime, rest; struct timeval tvp[2]; int n; - rb_scan_args(args, "2*", &atime, &mtime, &rest); + rb_scan_args(argc, argv, "2*", &atime, &mtime, &rest); tvp[0] = *time_timeval(atime); tvp[1] = *time_timeval(mtime); @@ -1134,9 +1140,9 @@ Init_File() rb_define_single_method(C_File, "mtime", Sfile_mtime, 1); rb_define_single_method(C_File, "ctime", Sfile_ctime, 1); - rb_define_single_method(C_File, "utime", Sfile_utime, -2); - rb_define_single_method(C_File, "chmod", Sfile_chmod, -2); - rb_define_single_method(C_File, "chown", Sfile_chown, -2); + rb_define_single_method(C_File, "utime", Sfile_utime, -1); + rb_define_single_method(C_File, "chmod", Sfile_chmod, -1); + rb_define_single_method(C_File, "chown", Sfile_chown, -1); rb_define_single_method(C_File, "link", Sfile_link, 2); rb_define_single_method(C_File, "symlink", Sfile_symlink, 2); diff --git a/gc.c b/gc.c index 780d1902f8..af6741f6ca 100644 --- a/gc.c +++ b/gc.c @@ -3,7 +3,7 @@ gc.c - $Author: matz $ - $Date: 1994/12/19 08:39:19 $ + $Date: 1995/01/10 10:42:37 $ created at: Tue Oct 5 09:44:46 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -170,6 +170,7 @@ struct RVALUE { UINT flag; /* always 0 for freed obj */ struct RVALUE *next; } free; + struct RBasic basic; struct RObject object; struct RClass class; struct RFloat flonum; @@ -181,6 +182,8 @@ struct RVALUE { struct RStruct rstruct; struct RBignum bignum; struct RNode node; + struct RCons cons; + struct SCOPE scope; } as; } *freelist = Qnil; @@ -193,8 +196,7 @@ struct heap_block { #define SEG_SLOTS 10000 #define SEG_SIZE (SEG_SLOTS*sizeof(struct RVALUE)) - -static int heap_size; +#define FREE_MIN 512 static void add_heap() @@ -203,7 +205,7 @@ add_heap() struct RVALUE *p, *pend; block = (struct heap_block*)malloc(sizeof(*block) + SEG_SIZE); - if (block == Qnil) Fatal("cant alloc memory"); + if (block == Qnil) Fatal("can't alloc memory"); block->next = heap_link; block->beg = &block->body[0]; block->end = block->beg + SEG_SLOTS; @@ -215,7 +217,6 @@ add_heap() p++; } heap_link = block; - heap_size += SEG_SLOTS; } struct RBasic * @@ -227,8 +228,7 @@ newobj() retry: obj = (struct RBasic*)freelist; freelist = freelist->as.free.next; - obj->flags = 0; - obj->iv_tbl = Qnil; + memset(obj, 0, sizeof(struct RVALUE)); return obj; } if (dont_gc) add_heap(); @@ -349,40 +349,40 @@ gc_mark_maybe(obj) void gc_mark(obj) - register struct RBasic *obj; + register struct RVALUE *obj; { if (obj == Qnil) return; if (FIXNUM_P(obj)) return; - if (obj->flags & FL_MARK) return; + if (obj->as.basic.flags & FL_MARK) return; - obj->flags |= FL_MARK; + obj->as.basic.flags |= FL_MARK; - switch (obj->flags & T_MASK) { + switch (obj->as.basic.flags & T_MASK) { case T_NIL: case T_FIXNUM: Bug("gc_mark() called for broken object"); break; } - switch (obj->flags & T_MASK) { + switch (obj->as.basic.flags & T_MASK) { case T_ICLASS: - gc_mark(RCLASS(obj)->super); - if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl); - mark_tbl(RCLASS(obj)->m_tbl); + gc_mark(obj->as.class.super); + if (obj->as.class.c_tbl) mark_tbl(obj->as.class.c_tbl); + mark_tbl(obj->as.class.m_tbl); break; case T_CLASS: - gc_mark(RCLASS(obj)->super); + gc_mark(obj->as.class.super); case T_MODULE: - if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl); - mark_tbl(RCLASS(obj)->m_tbl); - gc_mark(RBASIC(obj)->class); + if (obj->as.class.c_tbl) mark_tbl(obj->as.class.c_tbl); + mark_tbl(obj->as.class.m_tbl); + gc_mark(obj->as.basic.class); break; case T_ARRAY: { - int i, len = RARRAY(obj)->len; - VALUE *ptr = RARRAY(obj)->ptr; + int i, len = obj->as.array.len; + VALUE *ptr = obj->as.array.ptr; for (i=0; i < len; i++) gc_mark(ptr[i]); @@ -390,15 +390,15 @@ gc_mark(obj) break; case T_DICT: - mark_dict(RDICT(obj)->tbl); + mark_dict(obj->as.dict.tbl); break; case T_STRING: - if (RSTRING(obj)->orig) gc_mark(RSTRING(obj)->orig); + if (obj->as.string.orig) gc_mark(obj->as.string.orig); break; case T_DATA: - if (RDATA(obj)->dmark) (*RDATA(obj)->dmark)(DATA_PTR(obj)); + if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj)); break; case T_OBJECT: @@ -409,30 +409,38 @@ gc_mark(obj) case T_STRUCT: { - int i, len = RSTRUCT(obj)->len; - struct kv_pair *ptr = RSTRUCT(obj)->tbl; + int i, len = obj->as.rstruct.len; + struct kv_pair *ptr = obj->as.rstruct.tbl; for (i=0; i < len; i++) gc_mark(ptr[i].value); } break; + case T_SCOPE: + { + struct SCOPE *scope = (struct SCOPE*)obj; + if (scope->local_vars) + mark_locations_array(scope->local_vars, scope->local_tbl[0]); + } + break; + case T_CONS: - gc_mark(RCONS(obj)->car); - gc_mark(RCONS(obj)->cdr); + gc_mark(obj->as.cons.car); + gc_mark(obj->as.cons.cdr); break; case T_NODE: - gc_mark_maybe(RNODE(obj)->u1.node); - gc_mark_maybe(RNODE(obj)->u2.node); - gc_mark_maybe(RNODE(obj)->u3.node); + gc_mark_maybe(obj->as.node.u1.node); + gc_mark_maybe(obj->as.node.u2.node); + gc_mark_maybe(obj->as.node.u3.node); return; /* no need to mark class & tbl */ default: - Bug("gc_mark(): unknown data type %d", obj->flags & T_MASK); + Bug("gc_mark(): unknown data type %d", obj->as.basic.flags & T_MASK); } - if (obj->iv_tbl) mark_tbl(obj->iv_tbl); - gc_mark(obj->class); + if (obj->as.basic.iv_tbl) mark_tbl(obj->as.basic.iv_tbl); + gc_mark(obj->as.basic.class); } #define MIN_FREE_OBJ 512 @@ -455,8 +463,8 @@ gc_sweep() p = heap->beg; pend = heap->end; while (p < pend) { - if (!(RBASIC(p)->flags & FL_MARK)) { - if (RBASIC(p)->flags) obj_free(p); + if (!(p->as.basic.flags & FL_MARK)) { + if (p->as.basic.flags) obj_free(p); p->as.free.flag = 0; p->as.free.next = nfreelist; nfreelist = p; @@ -480,7 +488,6 @@ gc_sweep() } } free(heap); - heap_size -= SEG_SLOTS; heap = link; } else { @@ -489,78 +496,88 @@ gc_sweep() } heap = heap->next; } - if (freed < heap_size/4) { + if (freed < FREE_MIN) { add_heap(); } } static void obj_free(obj) - struct RBasic *obj; + struct RVALUE *obj; { - switch (obj->flags & T_MASK) { + switch (obj->as.basic.flags & T_MASK) { case T_NIL: case T_FIXNUM: Bug("obj_free() called for broken object"); break; } - switch (obj->flags & T_MASK) { + switch (obj->as.basic.flags & T_MASK) { case T_OBJECT: break; case T_MODULE: case T_CLASS: rb_clear_cache2(obj); - st_free_table(RCLASS(obj)->m_tbl); - if (RCLASS(obj)->c_tbl) - st_free_table(RCLASS(obj)->c_tbl); + st_free_table(obj->as.class.m_tbl); + if (obj->as.class.c_tbl) + st_free_table(obj->as.class.c_tbl); break; case T_STRING: - if (RSTRING(obj)->orig == Qnil) free(RSTRING(obj)->ptr); + if (obj->as.string.orig == Qnil) free(obj->as.string.ptr); break; case T_ARRAY: - free(RARRAY(obj)->ptr); + free(obj->as.array.ptr); break; case T_DICT: - st_free_table(RDICT(obj)->tbl); + st_free_table(obj->as.dict.tbl); break; case T_REGEXP: - reg_free(RREGEXP(obj)->ptr); - free(RREGEXP(obj)->str); + reg_free(obj->as.regexp.ptr); + free(obj->as.regexp.str); break; case T_DATA: - if (RDATA(obj)->dfree) (*RDATA(obj)->dfree)(DATA_PTR(obj)); + if (obj->as.data.dfree) (*obj->as.data.dfree)(DATA_PTR(obj)); free(DATA_PTR(obj)); break; case T_ICLASS: /* iClass shares table with the module */ case T_FLOAT: + case T_CONS: break; case T_STRUCT: - free(RSTRUCT(obj)->name); - free(RSTRUCT(obj)->tbl); + free(obj->as.rstruct.name); + free(obj->as.rstruct.tbl); break; case T_BIGNUM: - free(RBIGNUM(obj)->digits); + free(obj->as.bignum.digits); break; case T_NODE: - if (nd_type(obj) == NODE_SCOPE && RNODE(obj)->nd_tbl) { - free(RNODE(obj)->nd_tbl); + if (nd_type(obj) == NODE_SCOPE && obj->as.node.nd_tbl) { + free(obj->as.node.nd_tbl); } return; /* no need to free iv_tbl */ + + case T_SCOPE: + { + struct SCOPE *scope = (struct SCOPE*)obj; + if (scope->local_vars) + free(scope->local_vars); + if (scope->local_tbl) + free(scope->local_tbl); + } + break; + default: - Bug("gc_sweep(): unknown data type %d", obj->flags & T_MASK); + Bug("gc_sweep(): unknown data type %d", obj->as.basic.flags & T_MASK); } - if (obj->iv_tbl) st_free_table(obj->iv_tbl); + if (obj->as.basic.iv_tbl) st_free_table(obj->as.basic.iv_tbl); } void -gc_mark_scope(scope) - struct SCOPE *scope; +gc_mark_env(env) + struct ENVIRON *env; { - if (scope->local_vars && scope->var_ary == Qnil) - mark_locations_array(scope->local_vars, scope->local_tbl[0]); - gc_mark(scope->var_ary); + mark_locations_array(env->argv, env->argc); } void @@ -568,7 +585,6 @@ gc() { struct gc_list *list; struct ENVIRON *env; - struct SCOPE *scope; int i, max; jmp_buf save_regs_gc_mark; VALUE stack_end; @@ -576,9 +592,13 @@ gc() if (dont_gc) return; dont_gc++; - /* mark scope stack */ - for (scope = the_scope; scope; scope = scope->prev) { - gc_mark_scope(scope); +#ifdef C_ALLOCA + alloca(0); +#endif + + /* mark env stack */ + for (env = the_env; env; env = env->prev) { + gc_mark_env(env); } FLUSH_REGISTER_WINDOWS; diff --git a/inits.c b/inits.c index 9a5b208306..45475e173f 100644 --- a/inits.c +++ b/inits.c @@ -3,7 +3,7 @@ inits.c - $Author: matz $ - $Date: 1994/12/16 00:59:24 $ + $Date: 1995/01/10 10:42:38 $ created at: Tue Dec 28 16:01:58 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -30,6 +30,7 @@ rb_call_inits() Init_Regexp(); Init_Glob(); Init_pack(); + Init_Cons(); Init_Range(); Init_IO(); Init_Dir(); diff --git a/io.c b/io.c index 2b73d89253..c0f246b60c 100644 --- a/io.c +++ b/io.c @@ -3,7 +3,7 @@ io.c - $Author: matz $ - $Date: 1994/12/19 08:30:05 $ + $Date: 1995/01/10 10:42:39 $ created at: Fri Oct 15 18:08:59 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -110,7 +110,10 @@ Fio_eof(obj) return FALSE; /* this is the most usual case */ #endif + TRAP_BEG; ch = getc(fptr->f); + TRAP_END; + if (ch != EOF) { (void)ungetc(ch, fptr->f); return FALSE; @@ -178,7 +181,9 @@ read_all(port) str = str_new(0, 0); for (;;) { + TRAP_BEG; n = fread(buf, 1, BUFSIZ, fptr->f); + TRAP_END; if (n == 0) { if (feof(fptr->f)) break; rb_sys_fail(Qnil); @@ -189,14 +194,16 @@ read_all(port) } static VALUE -Fio_read(obj, args) - VALUE obj, args; +Fio_read(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { OpenFile *fptr; int n, lgt; VALUE len, str; - if (rb_scan_args(args, "01", &len) == 0) { + if (rb_scan_args(argc, argv, "01", &len) == 0) { return read_all(obj); } @@ -209,7 +216,9 @@ Fio_read(obj, args) str = str_new(0, lgt); + TRAP_BEG; n = fread(RSTRING(str)->ptr, 1, RSTRING(str)->len, fptr->f); + TRAP_END; if (n == 0) { if (feof(fptr->f)) return Qnil; rb_sys_fail(Qnil); @@ -257,7 +266,9 @@ Fio_gets(obj) if (rslen == 0 && c == '\n') { do { + TRAP_BEG; c = getc(f); + TRAP_END; if (c != '\n') { ungetc(c,f); break; @@ -273,8 +284,11 @@ Fio_gets(obj) again: bp = buf; + + TRAP_BEG; while ((c = getc(f)) != EOF && (*bp++ = c) != newline && bp < bpe) ; + TRAP_END; if (c == EOF && !append && bp == buf) { str = Qnil; @@ -307,7 +321,9 @@ Fio_gets(obj) return_gets: if (rslen == 0 && c == '\n') { while (c != EOF) { + TRAP_BEG; c = getc(f); + TRAP_END; if (c != '\n') { ungetc(c, f); break; @@ -350,7 +366,11 @@ Fio_each_byte(obj) f = fptr->f; if (f == NULL) Fail("closed stream"); - while ((c = getc(f)) != EOF) { + for (;;) { + TRAP_BEG; + c = getc(f); + TRAP_END; + if (c == EOF) break; rb_yield(INT2FIX(c & 0xff)); } if (ferror(f) != 0) rb_sys_fail(Qnil); @@ -372,7 +392,10 @@ Fio_getc(obj) f = fptr->f; if (f == NULL) Fail("closed stream"); + TRAP_BEG; c = getc(f); + TRAP_END; + if (c == EOF) { if (ferror(f) != 0) rb_sys_fail(Qnil); return Qnil; @@ -458,7 +481,9 @@ Fio_sysread(obj, len) str = str_new(0, ilen); + TRAP_BEG; n = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len); + TRAP_END; if (n == -1) rb_sys_fail(Qnil); if (n == 0) return Qnil; /* EOF */ @@ -630,15 +655,17 @@ io_open(fname, mode) } static VALUE -Fopen(self, args) - VALUE self, args; +Fopen(argc, argv, self) + int argc; + VALUE *argv; + VALUE self; { char *mode; VALUE port; int pipe = 0; VALUE pname, pmode; - rb_scan_args(args, "11", &pname, &pmode); + rb_scan_args(argc, argv, "11", &pname, &pmode); Check_Type(pname, T_STRING); if (pmode == Qnil) { mode = "r"; @@ -671,22 +698,22 @@ Fprintf(argc, argv) else { Fail("output must responds to `write'"); } - rb_funcall(out, id_write, 1, Fsprintf(argc, argv)); return Qnil; } static VALUE -Fprint(argc, argv) +Fprint(argc, argv, self) int argc; - VALUE argv[]; + VALUE *argv; + VALUE self; { int i; /* if no argument given, print recv */ if (argc == 0) { - rb_funcall(Qself, id_print_on, 1, rb_defout); + rb_funcall(self, id_print_on, 1, rb_defout); } else { for (i=0; iptr[1]; for (i=0; i< RARRAY(write)->len; i++) { GetOpenFile(RARRAY(write)->ptr[i], fptr); - if (FD_ISSET(fileno(fptr->f), rp)) { + if (FD_ISSET(fileno(fptr->f), wp)) { ary_push(list, RARRAY(write)->ptr[i]); } - else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), rp)) { + else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), wp)) { ary_push(list, RARRAY(write)->ptr[i]); } } @@ -1055,10 +1087,10 @@ Fselect(obj, args) list = RARRAY(res)->ptr[2]; for (i=0; i< RARRAY(except)->len; i++) { GetOpenFile(RARRAY(except)->ptr[i], fptr); - if (FD_ISSET(fileno(fptr->f), rp)) { + if (FD_ISSET(fileno(fptr->f), ep)) { ary_push(list, RARRAY(except)->ptr[i]); } - else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), rp)) { + else if (fptr->f2 && FD_ISSET(fileno(fptr->f2), ep)) { ary_push(list, RARRAY(except)->ptr[i]); } } @@ -1220,7 +1252,7 @@ Farg_read(obj) for (;;) { retry: if (!next_argv()) return Qnil; - str2 = Fio_read(file, Qnil); + str2 = Fio_read(0, Qnil, file); if (str2 == Qnil && next_p != -1) { Fio_close(file); next_p = 1; @@ -1297,13 +1329,13 @@ Init_IO() rb_define_private_method(C_Kernel, "syscall", Fsyscall, -1); - rb_define_private_method(C_Kernel, "open", Fopen, -2); + rb_define_private_method(C_Kernel, "open", Fopen, -1); rb_define_private_method(C_Kernel, "printf", Fprintf, -1); rb_define_private_method(C_Kernel, "gets", Fgets, 0); rb_define_alias(C_Kernel,"readline", "gets"); rb_define_private_method(C_Kernel, "eof", Feof, 0); rb_define_private_method(C_Kernel, "getc", Fgetc, 0); - rb_define_private_method(C_Kernel, "select", Fselect, -2); + rb_define_private_method(C_Kernel, "select", Fselect, -1); rb_define_private_method(C_Kernel, "readlines", Freadlines, 0); diff --git a/node.h b/node.h index a032ee2176..9322417fa2 100644 --- a/node.h +++ b/node.h @@ -3,7 +3,7 @@ node.h - $Author: matz $ - $Date: 1994/12/16 03:10:04 $ + $Date: 1995/01/10 10:42:41 $ created at: Fri May 28 15:14:02 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -35,13 +35,13 @@ enum node_type { NODE_GASGN, NODE_IASGN, NODE_CASGN, + NODE_OP_ASGN1, + NODE_OP_ASGN2, NODE_CALL, - NODE_ICALL, NODE_SUPER, NODE_ZSUPER, NODE_ARRAY, NODE_ZARRAY, - NODE_QLIST, NODE_HASH, NODE_REDO, NODE_BREAK, @@ -50,7 +50,6 @@ enum node_type { NODE_RETRY, NODE_FAIL, NODE_YIELD, - NODE_IYIELD, NODE_LVAR, NODE_GVAR, NODE_IVAR, @@ -106,9 +105,9 @@ typedef struct RNode { #define RNODE(obj) (R_CAST(RNode)(obj)) -#define nd_type(n) (((n)->flags>>11)&0x3f) +#define nd_type(n) (((RNODE(n))->flags>>10)&0xff) #define nd_set_type(n,t) \ - (n)->flags=(((n)->flags&~FL_UMASK)|(((t)<<11)&FL_UMASK)) + RNODE(n)->flags=((RNODE(n)->flags&~FL_UMASK)|(((t)<<10)&FL_UMASK)) #define nd_head u1.node #define nd_alen u2.argc @@ -119,6 +118,8 @@ typedef struct RNode { #define nd_else u3.node #define nd_break u3.state +#define nd_orig u3.value + #define nd_resq u2.node #define nd_ensr u3.node @@ -140,6 +141,7 @@ typedef struct RNode { #define nd_iter u3.node #define nd_value u2.node +#define nd_aid u3.id #define nd_lit u1.value @@ -170,7 +172,7 @@ typedef struct RNode { #define nd_rval u3.node #define NEW_METHOD(n,x) newnode(NODE_METHOD,x,n,Qnil) -#define NEW_FBODY(n,i) newnode(NODE_FBODY,n,i,Qnil) +#define NEW_FBODY(n,i,o) newnode(NODE_FBODY,n,i,o) #define NEW_DEFN(i,d,p) newnode(NODE_DEFN,p,i,d) #define NEW_DEFS(r,i,d) newnode(NODE_DEFS,r,i,d) #define NEW_CFUNC(f,c) newnode(NODE_CFUNC,f,c,Qnil) @@ -207,6 +209,8 @@ typedef struct RNode { #define NEW_LASGN(v,val) newnode(NODE_LASGN,v,val,local_cnt(v)) #define NEW_IASGN(v,val) newnode(NODE_IASGN,v,val,Qnil) #define NEW_CASGN(v,val) newnode(NODE_CASGN,v,val,Qnil) +#define NEW_OP_ASGN1(p,id,a) newnode(NODE_OP_ASGN1,p,id,a) +#define NEW_OP_ASGN2(r,i,val) newnode(NODE_OP_ASGN1,r,val,i) #define NEW_GVAR(v) newnode(NODE_GVAR,v,Qnil,rb_global_entry(v)) #define NEW_LVAR(v) newnode(NODE_LVAR,v,Qnil,local_cnt(v)) #define NEW_IVAR(v) newnode(NODE_IVAR,v,Qnil,Qnil) diff --git a/numeric.c b/numeric.c index 97037b8c99..5b88a35454 100644 --- a/numeric.c +++ b/numeric.c @@ -3,7 +3,7 @@ numeric.c - $Author: matz $ - $Date: 1994/12/06 09:30:05 $ + $Date: 1995/01/10 10:42:42 $ created at: Fri Aug 13 18:33:09 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -924,7 +924,7 @@ Init_Numeric() C_Numeric = rb_define_class("Numeric", C_Object); rb_undef_method(CLASS_OF(C_Numeric), "new"); - rb_undef_method(CLASS_OF(C_Numeric), "clone"); + rb_undef_method(C_Numeric, "clone"); rb_include_module(C_Numeric, M_Comparable); rb_define_method(C_Numeric, "+@", Fnum_uplus, 0); diff --git a/object.c b/object.c index 21c71abd1b..e71043fdde 100644 --- a/object.c +++ b/object.c @@ -3,7 +3,7 @@ object.c - $Author: matz $ - $Date: 1994/12/20 05:01:01 $ + $Date: 1995/01/10 10:42:44 $ created at: Thu Jul 15 12:01:24 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -26,7 +26,6 @@ VALUE C_Data; struct st_table *new_idhash(); VALUE Fsprintf(); -VALUE Fdefined(); VALUE obj_responds_to(); VALUE obj_alloc(); @@ -47,11 +46,18 @@ P_false(obj) return FALSE; } +VALUE +rb_equal(obj1, obj2) + VALUE obj1, obj2; +{ + return rb_funcall(obj1, eq, 1, obj2); +} + static VALUE -Fkrn_equal(obj, other) - VALUE obj, other; +Fkrn_equal(obj1, obj2) + VALUE obj1, obj2; { - if (obj == other) return TRUE; + if (obj1 == obj2) return TRUE; return FALSE; } @@ -73,7 +79,7 @@ static VALUE Fkrn_noteq(obj, other) VALUE obj, other; { - if (rb_funcall(obj, eq, 1, other)) { + if (rb_equal(obj, other)) { return FALSE; } return TRUE; @@ -271,8 +277,10 @@ obj_alloc(class) } static VALUE -Fcls_new(class, args) - VALUE class, args; +Fcls_new(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; { return obj_alloc(class); } @@ -285,12 +293,14 @@ Fcls_to_s(class) } static VALUE -Fcls_attr(class, args) - VALUE class, args; +Fcls_attr(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; { VALUE name, pub; - rb_scan_args(args, "11", &name, &pub); + rb_scan_args(argc, argv, "11", &name, &pub); Check_Type(name, T_STRING); rb_define_attr(class, RSTRING(name)->ptr, pub); return Qnil; @@ -351,7 +361,8 @@ Fdata_class(data) return C_Data; } -static VALUE boot_defclass(name, super) +static +VALUE boot_defclass(name, super) char *name; VALUE super; { @@ -361,6 +372,11 @@ static VALUE boot_defclass(name, super) return (VALUE)obj; } +Fdo() +{ + return rb_yield(Qnil); +} + VALUE TopSelf; VALUE TRUE = 1; @@ -423,11 +439,11 @@ Init_Object() rb_define_method(C_Kernel, "to_s", Fkrn_to_s, 0); rb_define_method(C_Kernel, "_inspect", Fkrn_inspect, 0); - rb_define_private_method(C_Kernel, "defined", Fdefined, 1); - rb_define_private_method(C_Kernel, "sprintf", Fsprintf, -1); rb_define_alias(C_Kernel, "format", "sprintf"); + rb_define_private_method(C_Kernel, "do", Fdo, 0); + rb_define_method(C_Object, "_inspect", Fobj_inspect, 0); rb_define_method(C_Object, "responds_to", obj_responds_to, 1); @@ -437,11 +453,11 @@ Init_Object() rb_define_method(C_Module, "to_s", Fcls_to_s, 0); rb_define_method(C_Module, "clone", Fcant_clone, 0); - rb_define_private_method(C_Module, "attr", Fcls_attr, -2); + rb_define_private_method(C_Module, "attr", Fcls_attr, -1); rb_define_method(C_Module, "export", Fcls_export, -1); rb_define_method(C_Module, "unexport", Fcls_unexport, -1); - rb_define_method(C_Class, "new", Fcls_new, -2); + rb_define_method(C_Class, "new", Fcls_new, -1); C_Nil = rb_define_class("Nil", C_Kernel); rb_define_method(C_Nil, "to_s", Fnil_to_s, 0); diff --git a/parse.y b/parse.y index 4c8ef397de..c4148d88d3 100644 --- a/parse.y +++ b/parse.y @@ -3,7 +3,7 @@ parse.y - $Author: matz $ - $Date: 1994/12/20 05:07:09 $ + $Date: 1995/01/10 10:42:45 $ created at: Fri May 28 18:02:42 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -123,6 +123,7 @@ static void setup_top_local(); UNLESS_MOD WHILE_MOD UNTIL_MOD + ALIAS %token IDENTIFIER GVAR IVAR CONSTANT %token INTEGER FLOAT STRING XSTRING REGEXP GLOB @@ -131,8 +132,8 @@ static void setup_top_local(); %type singleton inc_list %type literal numeric %type compstmts stmts stmt stmt0 expr expr0 var_ref -%type if_tail opt_else cases resque ensure -%type call_args call_args0 opt_args args args2 +%type if_tail opt_else case_body cases resque ensure +%type call_args call_args0 args args2 array %type f_arglist f_args assoc_list assocs assoc %type mlhs mlhs_head mlhs_tail lhs iter_var opt_iter_var %type superclass variable symbol @@ -275,9 +276,9 @@ stmt : CLASS IDENTIFIER superclass { $$ = NEW_UNDEF($2); } - | DEF fname fname + | ALIAS fname {lex_state = EXPR_FNAME;} fname { - $$ = NEW_ALIAS($2, $3); + $$ = NEW_ALIAS($2, $4); } | INCLUDE inc_list { @@ -563,6 +564,11 @@ singleton : var_ref { switch (nd_type($2)) { case NODE_STR: + case NODE_STR2: + case NODE_XSTR: + case NODE_XSTR2: + case NODE_DREGX: + case NODE_DGLOB: case NODE_LIT: case NODE_ARRAY: case NODE_ZARRAY: @@ -609,29 +615,11 @@ expr : variable '=' expr } | expr0 '[' args rbracket OP_ASGN expr { - NODE *rval, *args; - value_expr($1); - value_expr($6); - - args = list_copy($3); - rval = NEW_CALL($1, AREF, args); - - args = list_append($3, call_op(rval, $5, 1, $6)); - $$ = NEW_CALL($1, ASET, args); + $$ = NEW_OP_ASGN1($1,$5,list_concat(NEW_LIST($6),$3)); } | expr0 '.' IDENTIFIER OP_ASGN expr { - ID id = $3; - NODE *rval; - - value_expr($1); - value_expr($5); - - id &= ~ID_SCOPE_MASK; - id |= ID_ATTRSET; - - rval = call_op(NEW_CALL($1, $3, Qnil), $4, 1, $5); - $$ = NEW_CALL($1, id, NEW_LIST(rval)); + $$ = NEW_OP_ASGN2($1, $4, $5); } | expr DOT2 expr { @@ -730,11 +718,11 @@ expr : variable '=' expr } | expr MATCH expr { - $$ = call_op($1, MATCH, 1, $3); + $$ = NEW_CALL($1, MATCH, NEW_LIST($3)); } | expr NMATCH expr { - $$ = call_op($1, NMATCH, 1, $3); + $$ = NEW_CALL($1, NMATCH, NEW_LIST($3)); } | '!' expr { @@ -794,12 +782,6 @@ call_args0 : args $$ = call_op($1, '+', 1, $4); } -opt_args : /* none */ - { - $$ = Qnil; - } - | args - args : expr { value_expr($1); @@ -813,8 +795,6 @@ args : expr args2 : args { - NODE *rhs; - if ($1 && $1->nd_next == Qnil) { $$ = $1->nd_head; } @@ -862,7 +842,7 @@ expr0 : literal value_expr($1); $$ = NEW_CALL($1, AREF, $3); } - | LBRACK opt_args rbracket + | LBRACK array rbracket { if ($2 == Qnil) $$ = NEW_ZARRAY(); /* zero length array*/ @@ -900,29 +880,11 @@ expr0 : literal { $$ = NEW_YIELD(Qnil); } - | expr0 lbrace opt_iter_var '|' compstmts rbrace + | expr0 '{' opt_iter_var '|' compstmts rbrace { - switch (nd_type($1)) { - case NODE_CALL: - nd_set_type($1, NODE_ICALL); - break; - case NODE_YIELD: - nd_set_type($1, NODE_IYIELD); - break; - case NODE_BLOCK: - { - NODE *tmp = $1; - while (tmp) { - if (nd_type(tmp->nd_head) == NODE_YIELD) { - nd_set_type(tmp->nd_head, NODE_IYIELD); - } - else if (nd_type(tmp->nd_head) == NODE_CALL) { - nd_set_type(tmp->nd_head, NODE_ICALL); - } - tmp = tmp->nd_next; - } - } - break; + if (nd_type($1) == NODE_LVAR + || nd_type($1) == NODE_MVAR) { + $1 = NEW_CALL(Qnil, $1->nd_vid, Qnil); } $$ = NEW_ITER($3, $1, $5); } @@ -956,12 +918,12 @@ expr0 : literal { $$ = NEW_UNTIL(cond($2), $4); } - | CASE stmt0 opt_term - cases + | CASE compstmts + case_body END { value_expr($2); - $$ = NEW_CASE($2, $4); + $$ = NEW_CASE($2, $3); } | FOR iter_var IN stmt0 term compstmts @@ -1019,6 +981,13 @@ opt_iter_var : /* none */ } | iter_var +case_body : WHEN args then + compstmts + cases + { + $$ = NEW_WHEN($2, $4, $5); + } + cases : opt_else | WHEN args then compstmts @@ -1048,6 +1017,12 @@ ensure : /* none */ $$ = $2; } +array : /* none */ + { + $$ = Qnil; + } + | args + literal : numeric | '\\' symbol { @@ -1097,8 +1072,7 @@ assocs : assoc assoc : expr ASSOC expr { - $$ = NEW_LIST($1); - $$ = list_append($$, $3); + $$ = list_append(NEW_LIST($1), $3); } @@ -1113,7 +1087,6 @@ nl : '\n' { yyerrok; } rparen : ')' { yyerrok; } rbracket : ']' { yyerrok; } -lbrace : '{' rbrace : '}' { yyerrok; } comma : ',' { yyerrok; } %% @@ -1347,6 +1320,7 @@ static struct kwtable { "__END__", 0, EXPR_BEG, "__FILE__", _FILE_, EXPR_END, "__LINE__", _LINE_, EXPR_END, + "alias", ALIAS, EXPR_FNAME, "and", AND, EXPR_BEG, "break", BREAK, EXPR_END, "case", CASE, EXPR_BEG, @@ -1373,7 +1347,7 @@ static struct kwtable { "self", SELF, EXPR_END, "super", SUPER, EXPR_END, "then", THEN, EXPR_BEG, - "undef", UNDEF, EXPR_BEG, + "undef", UNDEF, EXPR_FNAME, "unless", UNLESS, EXPR_BEG, "until", UNTIL, EXPR_BEG, "when", WHEN, EXPR_BEG, @@ -2292,8 +2266,10 @@ list_concat(head, tail) { NODE *last; +#if 0 if (nd_type(head) != NODE_ARRAY || nd_type(tail) != NODE_ARRAY) Bug("list_concat() called with non-list"); +#endif last = head; while (last->nd_next) { @@ -2370,6 +2346,8 @@ expand_op(recv, id, arg) return result; } +#define NODE_IS_CONST(n) (nd_type(n) == NODE_LIT || nd_type(n) == NODE_STR) + static NODE * call_op(recv, id, narg, arg1) NODE *recv; @@ -2382,8 +2360,7 @@ call_op(recv, id, narg, arg1) value_expr(arg1); } - if ((nd_type(recv) == NODE_LIT || nd_type(recv) == NODE_STR) - && (narg == 0 || (nd_type(arg1) == NODE_LIT || nd_type(arg1) == NODE_STR))) { + if (NODE_IS_CONST(recv) && (narg == 0 || NODE_IS_CONST(arg1))) { return expand_op(recv, id, (narg == 1)?arg1:Qnil); } return NEW_CALL(recv, id, narg==1?NEW_LIST(arg1):Qnil); @@ -2620,10 +2597,13 @@ local_cnt(id) if (lvtbl->tbl[cnt+1] == id) return cnt; } - if (lvtbl->tbl == Qnil) + if (lvtbl->tbl == Qnil) { lvtbl->tbl = ALLOC_N(ID, 2); - else + lvtbl->tbl[0] = 0; + } + else { REALLOC_N(lvtbl->tbl, ID, lvtbl->cnt+2); + } lvtbl->tbl[lvtbl->cnt+1] = id; return lvtbl->cnt++; @@ -2654,42 +2634,50 @@ init_top_local() else { lvtbl->cnt = 0; } - lvtbl->tbl = the_scope->local_tbl; + if (lvtbl->cnt > 0) { + lvtbl->tbl = ALLOC_N(ID, lvtbl->cnt); + MEMCPY(lvtbl->tbl, the_scope->local_tbl, VALUE, lvtbl->cnt); + } + else { + lvtbl->tbl = Qnil; + } } static void setup_top_local() { - if (lvtbl->cnt > 0) { - if (the_scope->local_vars == Qnil) { - the_scope->var_ary = ary_new2(lvtbl->cnt); - the_scope->local_vars = RARRAY(the_scope->var_ary)->ptr; - memset(the_scope->local_vars, 0, lvtbl->cnt * sizeof(VALUE)); - RARRAY(the_scope->var_ary)->len = lvtbl->cnt; - } - else if (lvtbl->tbl[0] < lvtbl->cnt) { - int i, len; - - if (the_scope->var_ary) { - for (i=0, len=lvtbl->cnt-lvtbl->tbl[0];ivar_ary, Qnil); - } + int len = lvtbl->cnt; + int i; + + if (len > 0) { + i = lvtbl->tbl[0]; + + if (i < len) { + if (the_scope->flags & SCOPE_MALLOCED) { + VALUE *vars = the_scope->local_vars; + + REALLOC_N(the_scope->local_vars, VALUE, len); + MEMZERO(the_scope->local_vars+i, VALUE, len-i); + free(the_scope->local_tbl); } else { VALUE *vars = the_scope->local_vars; - - the_scope->var_ary = ary_new2(lvtbl->cnt); - the_scope->local_vars = RARRAY(the_scope->var_ary)->ptr; - memcpy(the_scope->local_vars, vars, sizeof(VALUE)*lvtbl->cnt); - memset(the_scope->local_vars+i, 0, lvtbl->cnt-i); - RARRAY(the_scope->var_ary)->len = lvtbl->cnt; + the_scope->local_vars = ALLOC_N(VALUE, len); + if (vars) { + MEMCPY(the_scope->local_vars, vars, VALUE, i); + MEMZERO(the_scope->local_vars+i, VALUE, len-i); + } + else { + MEMZERO(the_scope->local_vars, VALUE, len); + } } + lvtbl->tbl[0] = len; + the_scope->local_tbl = lvtbl->tbl; + the_scope->flags |= SCOPE_MALLOCED; + } + else if (lvtbl->tbl) { + free(lvtbl->tbl); } - lvtbl->tbl[0] = lvtbl->cnt; - the_scope->local_tbl = lvtbl->tbl; - } - else { - the_scope->local_vars = Qnil; } } @@ -2819,7 +2807,7 @@ rb_intern(name) last = strlen(name)-1; if (name[last] == '=') { /* attribute asignment */ - char *buf = (char*)alloca(last+1); + char *buf = ALLOCA_N(char,last+1); strncpy(buf, name, last); buf[last] = '\0'; @@ -2874,7 +2862,7 @@ rb_id2name(id) res = rb_id2name(id2); if (res) { - char *buf = (char*)alloca(strlen(res)+2); + char *buf = ALLOCA_N(char,strlen(res)+2); strcpy(buf, res); strcat(buf, "="); @@ -2918,4 +2906,3 @@ rb_class2name(class) } Bug("class 0x%x not named", class); } - diff --git a/process.c b/process.c index 375ca640ec..f6de89d855 100644 --- a/process.c +++ b/process.c @@ -3,7 +3,7 @@ process.c - $Author: matz $ - $Date: 1994/12/20 05:07:11 $ + $Date: 1995/01/10 10:42:47 $ created at: Tue Aug 10 14:30:50 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -17,6 +17,9 @@ #include #include #include +#ifdef HAVE_VFORK_H +#include +#endif #include "st.h" static VALUE @@ -142,8 +145,8 @@ rb_proc_exec(str) return -1; } } - a = argv = (char**)alloca(((s - str)/2+2)*sizeof(char*)); - s = (char*)alloca(s - str + 1); + a = argv = ALLOCA_N(char*, (s-str)/2+2); + s = ALLOCA_N(char, s-str+1); strcpy(s, str); if (*a++ = strtok(s, " \t")) { while (t = strtok(NULL, " \t")) { @@ -278,13 +281,15 @@ Fsleep(argc, argv) } static VALUE -Fproc_getpgrp(obj, args) - VALUE obj, args; +Fproc_getpgrp(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { VALUE vpid; int pid, pgrp; - rb_scan_args(args, "01", &vpid); + rb_scan_args(argc, argv, "01", &vpid); if (vpid == Qnil) { pid = 0; } @@ -497,7 +502,7 @@ Init_process() rb_define_module_function(M_Process, "pid", get_pid, 0); rb_define_module_function(M_Process, "ppid", get_ppid, 0); - rb_define_module_function(M_Process, "getpgrp", Fproc_getpgrp, -2); + rb_define_module_function(M_Process, "getpgrp", Fproc_getpgrp, -1); rb_define_module_function(M_Process, "setpgrp", Fproc_setpgrp, 2); rb_define_module_function(M_Process, "getpriority", Fproc_getpriority, 2); diff --git a/random.c b/random.c index 8a2f18c947..b687434642 100644 --- a/random.c +++ b/random.c @@ -3,7 +3,7 @@ random.c - $Author: matz $ - $Date: 1994/11/01 08:28:18 $ + $Date: 1995/01/10 10:42:48 $ created at: Fri Dec 24 16:39:21 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -16,15 +16,17 @@ static int first = 1; static char state[256]; static VALUE -Fsrand(obj, args) - VALUE obj, args; +Fsrand(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; { int seed, old; #ifdef HAVE_RANDOM static int saved_seed; #endif - if (rb_scan_args(args, "01", &seed) == 0) { + if (rb_scan_args(argc, argv, "01", &seed) == 0) { seed = time(0); } else { @@ -75,6 +77,6 @@ Init_Random() { extern VALUE C_Kernel; - rb_define_private_method(C_Kernel, "srand", Fsrand, -2); + rb_define_private_method(C_Kernel, "srand", Fsrand, -1); rb_define_private_method(C_Kernel, "rand", Frand, 1); } diff --git a/re.c b/re.c index 06770ab71c..cdff895aa2 100644 --- a/re.c +++ b/re.c @@ -3,7 +3,7 @@ re.c - $Author: matz $ - $Date: 1994/12/19 08:30:12 $ + $Date: 1995/01/10 10:42:49 $ created at: Mon Aug 9 18:24:49 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -101,7 +101,7 @@ int len; */ rp = ALLOC(Regexp); - memset((char *)rp, 0, sizeof(Regexp)); + MEMZERO((char *)rp, Regexp, 1); rp->pat.buffer = ALLOC_N(char, 16); rp->pat.allocated = 16; rp->pat.fastmap = ALLOC_N(char, 256); @@ -117,14 +117,7 @@ struct match { struct re_registers regs; }; -static void -free_match(data) - struct match *data; -{ - free(data->ptr); -} - -VALUE last_match_data; +struct match last_match; int research(reg, str, start, ignorecase) @@ -148,20 +141,16 @@ research(reg, str, start, ignorecase) start, str->len - start, &(reg->ptr->regs)); if (result >= 0) { - struct RData *obj; - struct match *data; - int beg, i; - - data = ALLOC(struct match); - obj = (struct RData*)data_new(data, free_match, Qnil); - - data->len = str->len; - data->ptr = ALLOC_N(char, str->len+1); - memcpy(data->ptr, str->ptr, data->len); - data->ptr[data->len] = '\0'; - data->regs = reg->ptr->regs; - - last_match_data = (VALUE)obj; + last_match.len = str->len; + if (last_match.ptr == Qnil) { + last_match.ptr = ALLOC_N(char, str->len+1); + } + else { + REALLOC_N(last_match.ptr, char, str->len+1); + } + memcpy(last_match.ptr, str->ptr, last_match.len); + last_match.ptr[last_match.len] = '\0'; + last_match.regs = reg->ptr->regs; } return result; @@ -171,21 +160,16 @@ static VALUE nth_match(nth) int nth; { + int start, end, len; + if (nth >= RE_NREGS) { - Fail("argument out of range %d, %d", nth, RE_NREGS); - } - if (last_match_data) { - int start, end, len; - struct match *match; - - match = (struct match*)DATA_PTR(last_match_data); - start = match->regs.start[nth]; - if (start == -1) return Qnil; - end = match->regs.end[nth]; - len = end - start; - return str_new(match->ptr + start, len); + Fail("match out of range %d, %d", nth, RE_NREGS); } - return Qnil; + start = last_match.regs.start[nth]; + if (start == -1) return Qnil; + end = last_match.regs.end[nth]; + len = end - start; + return str_new(last_match.ptr + start, len); } VALUE @@ -200,10 +184,8 @@ re_match_pre() { struct match *match; - if (!last_match_data) return Qnil; - - match = (struct match*)DATA_PTR(last_match_data); - return str_new(match->ptr, match->regs.start[0]); + if (last_match.regs.start[0] == -1) return Qnil; + return str_new(last_match.ptr, last_match.regs.start[0]); } static VALUE @@ -211,10 +193,9 @@ re_match_post() { struct match *match; - if (!last_match_data) return Qnil; - - match = (struct match*)DATA_PTR(last_match_data); - return str_new(match->ptr+match->regs.end[0], match->ptr+match->len); + if (last_match.regs.start[0] == -1) return Qnil; + return str_new(last_match.ptr+last_match.regs.end[0], + last_match.len-last_match.regs.end[0]); } static VALUE @@ -223,14 +204,13 @@ re_match_last() struct match *match; int i; - if (!last_match_data) return Qnil; + if (last_match.regs.start[0] == -1) return Qnil; - match = (struct match*)DATA_PTR(last_match_data); for (i=0; iregs.start[i] == -1) break; + if (last_match.regs.start[i] == -1) break; } - i--; - return nth_match(i); + if (i == RE_NREGS) return Qnil; + return nth_match(i-1); } static VALUE @@ -241,11 +221,55 @@ get_match_data(id, nth) return nth_match(nth); } +static void +free_match(data) + struct match *data; +{ + free(data->ptr); +} + +static VALUE +get_match() +{ + struct match *data; + int beg, i; + + data = ALLOC(struct match); + + data->len = last_match.len; + data->ptr = ALLOC_N(char, last_match.len+1); + memcpy(data->ptr, last_match.ptr, data->len+1); + data->regs = last_match.regs; + + return data_new(data, free_match, Qnil); +} + static VALUE -store_match_data(val) +set_match(val) struct RArray *val; { + struct match *match; + Check_Type(val, T_DATA); + match = (struct match*)DATA_PTR(val); + last_match.len = match->len; + if (last_match.len == 0) { + if (last_match.ptr) { + free(last_match.ptr); + last_match.ptr = Qnil; + } + } + else { + if (last_match.ptr == Qnil) { + last_match.ptr = ALLOC_N(char, match->len+1); + } + else { + REALLOC_N(last_match.ptr, char, match->len+1); + } + } + memcpy(last_match.ptr, match->ptr, last_match.len+1); + last_match.regs = match->regs; + return (VALUE)val; } @@ -340,9 +364,10 @@ Freg_match2(re) } static VALUE -Sreg_new(argc, argv) +Sreg_new(argc, argv, self) int argc; VALUE *argv; + VALUE self; { VALUE src, reg; @@ -353,10 +378,10 @@ Sreg_new(argc, argv) src = argv[0]; switch (TYPE(src)) { case T_STRING: - reg = regexp_new_1(Qself, RREGEXP(src)->ptr, RREGEXP(src)->len); + reg = regexp_new_1(self, RREGEXP(src)->ptr, RREGEXP(src)->len); case T_REGEXP: - reg = regexp_new_1(Qself, RREGEXP(src)->str, RREGEXP(src)->len); + reg = regexp_new_1(self, RREGEXP(src)->str, RREGEXP(src)->len); default: Check_Type(src, T_STRING); @@ -417,15 +442,13 @@ re_regsub(str) if (no < 0) { /* Ordinary character. */ if (c == '\\' && (*s == '\\' || *s == '&')) p = ++s; - } else if (last_match_data) { - struct match *match; + } else { -#define BEG(no) match->regs.start[no] -#define END(no) match->regs.end[no] +#define BEG(no) last_match.regs.start[no] +#define END(no) last_match.regs.end[no] - match = (struct match*)DATA_PTR(last_match_data); if (BEG(no) == -1) continue; - str_cat(val, match->ptr+BEG(no), END(no)-BEG(no)); + str_cat(val, last_match.ptr+BEG(no), END(no)-BEG(no)); } } @@ -491,12 +514,18 @@ kanji_var_set(val) void Init_Regexp() { + int i; + 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, 0); + for (i=0; i -#include +#include #include #include #include diff --git a/ruby.h b/ruby.h index d20ed77a94..086c112084 100644 --- a/ruby.h +++ b/ruby.h @@ -3,12 +3,12 @@ ruby.h - $Author: matz $ - $Date: 1994/12/19 08:30:14 $ + $Date: 1995/01/10 10:42:52 $ created at: Thu Jun 10 14:26:32 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto - ************************************************/ +*************************************************/ #ifndef RUBY_H #define RUBY_H @@ -102,9 +102,10 @@ extern VALUE C_Data; #define T_BIGNUM 0x0c #define T_NODE 0x0d -#define T_CONS 0x0e +#define T_SCOPE 0x0e +#define T_CONS 0x0f -#define T_DATA 0xff +#define T_DATA 0x10 #define T_MASK 0xff @@ -237,16 +238,17 @@ struct RCons { #define FL_SINGLE (1<<8) #define FL_MARK (1<<9) -#define FL_LITERAL (1<<10) +#define FL_USER0 (1<<10) #define FL_USER1 (1<<11) #define FL_USER2 (1<<12) #define FL_USER3 (1<<13) #define FL_USER4 (1<<14) #define FL_USER5 (1<<15) #define FL_USER6 (1<<16) +#define FL_USER7 (1<<17) -#define FL_UMASK (0x3f<<11) +#define FL_UMASK (0xff<<10) #define FL_ABLE(x) (!(FIXNUM_P(x)||NIL_P(x))) #define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0) @@ -260,6 +262,20 @@ extern VALUE Qself; #define ALLOC(type) (type*)xmalloc(sizeof(type)) #define REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n)) +#define ALLOCA_N(type,n) (type*)alloca(sizeof(type)*(n)) + +#define MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n)) +#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n)) + +#ifdef SAFE_SIGHANDLE +extern int trap_immediate; +# define TRAP_BEG (trap_immediate=1) +# define TRAP_END (trap_immediate=0) +#else +# define TRAP_BEG +# define TRAP_END +#endif + VALUE rb_define_class(); VALUE rb_define_module(); diff --git a/signal.c b/signal.c index 0131941a5d..f711436f1c 100644 --- a/signal.c +++ b/signal.c @@ -3,7 +3,7 @@ signal.c - $Author: matz $ - $Date: 1994/12/20 05:15:42 $ + $Date: 1995/01/10 10:42:53 $ created at: Tue Dec 20 10:13:44 JST 1994 ************************************************/ @@ -226,7 +226,7 @@ static VALUE trap_list[NSIG]; #ifdef SAFE_SIGHANDLE static int trap_pending_list[NSIG]; int trap_pending; -static int trap_immediate; +int trap_immediate; #endif void @@ -252,8 +252,9 @@ sighandle(sig) #endif #ifdef SAFE_SIGHANDLE - if (trap_immediate) + if (trap_immediate) { rb_trap_eval(trap_list[sig]); + } else { trap_pending++; trap_pending_list[sig]++; @@ -270,7 +271,7 @@ rb_trap_exit() rb_trap_eval(trap_list[0]); } -#if defined(SAFE_SIGHANDLE) +#ifdef SAFE_SIGHANDLE rb_trap_exec() { int i; @@ -283,74 +284,7 @@ rb_trap_exec() } } } - -#if defined(HAVE_SYSCALL) && defined(HAVE_SYSCALL_H) -#include - -#ifdef SYS_read -int -read(fd, buf, nbytes) - int fd, nbytes; - char *buf; -{ - int res; - - trap_immediate++; - res = syscall(SYS_read, fd, buf, nbytes); - trap_immediate = 0; - return res; -} -#endif /* SYS_read */ - -#ifdef SYS_wait -int -wait(status) - union wait *status; -{ - int res; - - trap_immediate++; - res = syscall(SYS_wait, status); - trap_immediate =0; - return res; -} -#endif /* SYS_wait */ - -#ifdef SYS_sigpause -int -sigpause(mask) - int mask; -{ - int res; - - trap_immediate++; - res = syscall(SYS_sigpause, mask); - trap_immediate =0; - return res; -} -#endif /* SYS_sigpause */ - -/* linux syscall(select) doesn't work file. */ -#if defined(SYS_select) && !defined(linux) -#include - -int -select(nfds, readfds, writefds, exceptfds, timeout) - int nfds; - fd_set *readfds, *writefds, *exceptfds; - struct timeval *timeout; -{ - int res; - - trap_immediate++; - res = syscall(SYS_select, nfds, readfds, writefds, exceptfds, timeout); - trap_immediate =0; - return res; -} -#endif /* SYS_select */ - -#endif /* HAVE_SYSCALL_H */ -#endif /* SAFE_SIGHANDLE */ +#endif static VALUE Ftrap(argc, argv) diff --git a/socket.c b/socket.c index 098545cae9..b691e7e1c8 100644 --- a/socket.c +++ b/socket.c @@ -3,7 +3,7 @@ socket.c - $Author: matz $ - $Date: 1994/12/06 09:30:18 $ + $Date: 1995/01/10 10:42:55 $ created at: Thu Mar 31 12:21:29 JST 1994 ************************************************/ @@ -48,14 +48,16 @@ sock_new(class, fd) } static VALUE -Fbsock_shutdown(sock, args) - VALUE sock, args; +Fbsock_shutdown(argc, argv, sock) + int argc; + VALUE *argv; + VALUE sock; { VALUE howto; int how; OpenFile *fptr; - rb_scan_args(args, "01", &howto); + rb_scan_args(argc, argv, "01", &howto); if (howto == Qnil) how = 2; else { @@ -235,12 +237,14 @@ Stcp_sock_open(class, host, serv) } static VALUE -Stcp_svr_open(class, args) - VALUE class, args; +Stcp_svr_open(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; { VALUE arg1, arg2; - if (rb_scan_args(args, "11", &arg1, &arg2) == 2) + if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) return open_inet(class, arg1, arg2, 1); else return open_inet(class, Qnil, arg1, 1); @@ -618,8 +622,10 @@ Fsock_accept(sock) } static VALUE -Fsock_send(sock, args) - VALUE sock, args; +Fsock_send(argc, argv, sock) + int argc; + VALUE *argv; + VALUE sock; { struct RString *msg, *to; VALUE flags; @@ -627,7 +633,7 @@ Fsock_send(sock, args) FILE *f; int fd, n; - rb_scan_args(args, "21", &msg, &flags, &to); + rb_scan_args(argc, argv, "21", &msg, &flags, &to); Check_Type(msg, T_STRING); @@ -649,8 +655,10 @@ Fsock_send(sock, args) } static VALUE -sock_recv(sock, args, from) - VALUE sock, args; +sock_recv(sock, argc, argv, from) + VALUE sock; + int argc; + VALUE *argv; int from; { OpenFile *fptr; @@ -661,7 +669,7 @@ sock_recv(sock, args, from) VALUE len, flg; int flags; - rb_scan_args(args, "11", &len, &flg); + rb_scan_args(argc, argv, "11", &len, &flg); if (flg == Qnil) flags = 0; else flags = NUM2INT(flg); @@ -682,24 +690,28 @@ sock_recv(sock, args, from) } static VALUE -Fsock_recv(sock, args) - VALUE sock, args; +Fsock_recv(argc, argv, sock) + int argc; + VALUE *argv; + VALUE sock; { - return sock_recv(sock, args, 0); + return sock_recv(sock, argc, argv, 0); } static VALUE -Fsock_recvfrom(sock, args) - VALUE sock, args; +Fsock_recvfrom(argc, argv, sock) + int argc; + VALUE *argv; + VALUE sock; { - return sock_recv(sock, args, 1); + return sock_recv(sock, argc, argv, 1); } Init_Socket () { C_BasicSocket = rb_define_class("BasicSocket", C_IO); rb_undef_method(C_BasicSocket, "new"); - rb_define_method(C_BasicSocket, "shutdown", Fbsock_shutdown, -2); + rb_define_method(C_BasicSocket, "shutdown", Fbsock_shutdown, -1); rb_define_method(C_BasicSocket, "setopt", Fbsock_setopt, 3); rb_define_method(C_BasicSocket, "getopt", Fbsock_getopt, 2); rb_define_method(C_BasicSocket, "getsockname", Fbsock_getsockname, 0); @@ -712,8 +724,8 @@ Init_Socket () rb_define_method(C_TCPsocket, "peeraddr", Ftcp_peeraddr, 0); C_TCPserver = rb_define_class("TCPserver", C_TCPsocket); - rb_define_single_method(C_TCPserver, "open", Stcp_svr_open, -2); - rb_define_single_method(C_TCPserver, "new", Stcp_svr_open, -2); + rb_define_single_method(C_TCPserver, "open", Stcp_svr_open, -1); + rb_define_single_method(C_TCPserver, "new", Stcp_svr_open, -1); rb_define_method(C_TCPserver, "accept", Ftcp_accept, 0); C_UNIXsocket = rb_define_class("UNIXsocket", C_BasicSocket); @@ -738,9 +750,9 @@ Init_Socket () rb_define_method(C_Socket, "listen", Fsock_listen, 1); rb_define_method(C_Socket, "accept", Fsock_accept, 0); - rb_define_method(C_Socket, "send", Fsock_send, -2); - rb_define_method(C_Socket, "recv", Fsock_recv, -2); - rb_define_method(C_Socket, "recvfrom", Fsock_recv, -2); + rb_define_method(C_Socket, "send", Fsock_send, -1); + rb_define_method(C_Socket, "recv", Fsock_recv, -1); + rb_define_method(C_Socket, "recvfrom", Fsock_recv, -1); rb_define_single_method(C_Socket, "socketpair", Ssock_socketpair, 3); } diff --git a/spec b/spec index 98504255e9..75bd5e8065 100644 --- a/spec +++ b/spec @@ -66,13 +66,14 @@ Ruby ͽϰʲ̤Ǥ - 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 + alias elsif module self yield + and end nil super __END__ + break ensure or then __FILE__ + case fail protect undef __LINE__ + class for redo unless + continue if resque until + def in retry when + else include return while ͽϥ饹̾᥽å̾ѿ̾ʤɤѤ뤳ȤϤǤʤ @@ -414,10 +415,9 @@ moduleʸ 1 op= 2 # 1ǽǤʤФʤʤ -ηŪˡּ1 = 1 op 2פŸ졤¹Ԥ롥Τ -12ɾΤǡѤͽۤʤ̤Ƥֲǽ -롥ϥץޤΥ׿򸺤餹ŪΤ¸ߤ -Ǥ롥opȤƻȤ黻Ҥ +ηŪˡּ1 = 1 op 2פƱͤɾ롥1 +1󤷤ɾʤΤǡ1Ѥϡּ1 = 1 op 2 +Ȥưۤʤ̤Ȥʤ롥opȤƻȤ黻Ҥ +, -, *, /, %, **, &, |, ^, <<, >> @@ -561,7 +561,7 @@ if ƥ졼Ȥ湽¤(ä˥롼)ݲΤѤ᥽åɤ Ǥ롥ƥ졼θƤӽФϰʲιʸǹԤʤ롥 - '{' ѿ... '|' ʸ '}' + '{' ѿ... '|' ʸ... '}' ʸפ֥åȤꤷּפΥ᥽åɤ򥤥ƥ졼Ȥɾ 롥ּפΥȥåץ٥Υ᥽åɤƥ졼ȤƸƤӽФ졤 @@ -584,7 +584,7 @@ Enumerable γǤФʸ¹Ԥ롥ϰʲμǤ롥 - '{' ѿ '|' ʸ '}' + ().each '{' ѿ.. '|' ʸ '}' äƼͤΥ֥Ȥ᥽åeachʤ硤for¹Ԥ 㳰ȯ롥 @@ -825,7 +825,7 @@ yieldʸ ʲηǥ᥽åɤ̾Ĥ뤳ȤǤ롥 - def ᥽å̾1 ᥽å̾2 + alias ᥽å̾1 ᥽å̾2 ̾դ줿᥽åɤϡλǤΥ᥽åѤΥ åɤƤ⡤Ť᥽åɤƤӽФ줿ΤƱƯ @@ -865,6 +865,13 @@ Ruby exit()Ȥϰäơ㳰ʤɤϰڹԤʤʤfork()θ塤 ץλʤɤѤ롥 + do() + + ֥å1٤¹Ԥ륤ƥ졼֥åޤȤ뤿 + ¸ߤ롥Ȥ: + + do { foobar() } while (baz()) + eof() ޥɥ饤󤫤ϤEOFãƤ硤֤ @@ -1263,8 +1270,8 @@ Methods: assoc(key) - Ϣۥꥹ(2ǤǤȤ)򸡺1Ǥkey - ("=="Ӥ)֤ + Ϣۥꥹ(CONSڥǤȤ)򸡺1Ǥkey + ("=="Ӥ)֤ clear @@ -1497,6 +1504,63 @@ Methods: selfminmaxϰˤ֤ +*** Cons(饹) + +ǡ(ڥ)ɽ륯饹̾`::'黻ҤѤƹԤʤ +롥LispCONSڥƱͤListѤ뤳Ȥ⤢롥 +Cons饹Υ᥽å`[]',`[]=',`each'CONSڥʤꥹȤФ +ư褦߷פƤ롥 + +: + a=1::2::3 + a[0] # a[0] => 1 + a[2] = 5 # a => 1::5::3 + for i in a + print i + end # prints `153' + +SuperClass: Object + +Included Modules: Enumerable + +Methods: + + self [nth] + + CONSڥʤꥹȤnthܤǤ֤бǤ¸ + ߤʤnil֤ + + self [nth]= val + + CONSڥʤꥹȤnthܤǤѹ롥ꥹȤĹ + nthǻꤷĹûơбǤ¸ߤʤ + 㳰ȯ롥nthꥹȤĹˤϥꥹȤ + Ǥɲä롥 + + car + + CONSڥΥǡCAR֤ + + car=(val) + + CONSڥCARΥǡѹ롥 + + cdr + + CONSڥΥǡCDR֤ + + cdr=(val) + + CONSڥCDRΥǡѹ롥 + + copy + + CONSڥʤꥹȤʣ֤(shallow copy) + + each + + CONSڥʤꥹȤγǤͿ륤ƥ졼 + *** DBM(饹) NDBMե򥢥륯饹ǡȤʸǤʤФ @@ -1533,22 +1597,22 @@ Methods: delete_if - Ǥ륤ƥ졼[key, value]ȤͿơ֥ + Ǥ륤ƥ졼key::valueȤڥͿơ֥ ɾͤλܤ롥 each each_pair - [key, value]ʤͿ륤ƥ졼 - - each_value - - ƤvalueФƷ֤ƥ졼 + key::valueʤڥͿ륤ƥ졼 each_key ƤkeyФƷ֤ƥ졼 + each_value + + ƤvalueФƷ֤ƥ졼 + has_key(key) includes(key) @@ -1625,21 +1689,21 @@ Methods: delete_if - Ǥ륤ƥ졼[key, value]ȤͿơ֥ + Ǥ륤ƥ졼key::valueȤڥͿơ֥ ɾͤλܤ롥 each - each_value + each_pair - ƤvalueФƷ֤ƥ졼 + key::valueʤڥͿ륤ƥ졼 each_key ƤkeyФƷ֤ƥ졼 - each_pair + each_value - [key, value]ʤͿ륤ƥ졼 + ƤvalueФƷ֤ƥ졼 has_key(key) includes(key) @@ -1780,6 +1844,10 @@ Methods: ֺǽǤ0ˤʤ롥Ǥ¸ߤʤˤnil֤ ʤ饹ФƤϤޤ̣ʤ + length + + Ǥο֤ + min ǾǤ֤ƤǤߤ`<=>'᥽åɤӤǤ @@ -2286,7 +2354,7 @@ Methods: each - 磻ɥɤ˥ޥåե֤̾ƥ졼 + 磻ɥɤ˥ޥåե̾Ϳ륤ƥ졼 Single Methods: @@ -2469,10 +2537,8 @@ Methods: self :: other - selfotherǤȤĹ2֤Ȥ - ̣ [self, other]ƱƯ򤹤뤬鷺˸ - Ψɤα黻ҤϱǤΤǡa::b::c (a::(b::c)) - Ȳᤵ롥 + selfotherǤȤCONSڥ֤α黻ҤϱǤ + Τǡa::b::c (a::(b::c)) Ȳᤵ롥 is_nil @@ -2645,7 +2711,7 @@ Methods: divmod(other) - Ⱦ;2Ǥ֤ + Ⱦ;Υڥ֤ next @@ -2870,8 +2936,7 @@ Single Methods: socketpair(domain, type, protocol) - åȤΥڥ2ǤȤ֤λ - openƱǤ롥 + åȤΥڥ֤λ openƱǤ롥 *** Regexp(饹) diff --git a/sprintf.c b/sprintf.c index 507724f6b9..278b16607c 100644 --- a/sprintf.c +++ b/sprintf.c @@ -3,7 +3,7 @@ sprintf.c - $Author: matz $ - $Date: 1994/12/06 09:30:23 $ + $Date: 1995/01/10 10:42:59 $ created at: Fri Oct 15 10:39:26 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -46,7 +46,7 @@ Fsprintf(argc, argv) #define PUSH(s, l) { \ CHECK(l);\ - memmove(&buf[blen], s, l);\ + memcpy(&buf[blen], s, l);\ blen += (l);\ } diff --git a/string.c b/string.c index d1dc737f4a..3861f71d32 100644 --- a/string.c +++ b/string.c @@ -3,7 +3,7 @@ string.c - $Author: matz $ - $Date: 1994/12/09 09:40:28 $ + $Date: 1995/01/10 10:43:01 $ created at: Mon Aug 9 17:12:58 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -105,7 +105,7 @@ Sstr_new(class, str) str2->len = str->len; str2->ptr = ALLOC_N(char, str->len+1); if (str2->ptr) { - memmove(str2->ptr, str->ptr, str->len); + memcpy(str2->ptr, str->ptr, str->len); } str2->ptr[str->len] = '\0'; str2->orig = Qnil; @@ -147,7 +147,7 @@ Fstr_times(str, times) str2 = (struct RString*)str_new(0, str->len*times); for (i=0; iptr+(i*str->len), str->ptr, str->len); + memcpy(str2->ptr+(i*str->len), str->ptr, str->len); } str2->ptr[str2->len] = '\0'; @@ -269,7 +269,7 @@ str_cat(str, ptr, len) if (len > 0) { REALLOC_N(str->ptr, char, str->len + len + 1); if (ptr) - memmove(str->ptr + str->len, ptr, len); + memcpy(str->ptr + str->len, ptr, len); str->len += len; str->ptr[str->len] = '\0'; /* sentinel */ } @@ -435,15 +435,16 @@ str_index(str, sub, offset) } static VALUE -Fstr_index(str, args) +Fstr_index(argc, argv, str) + int argc; + VALUE *argv; struct RString *str; - VALUE args; { struct RString *sub; VALUE initpos; int pos; - if (rb_scan_args(args, "11", &sub, &initpos) == 2) { + if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) { pos = NUM2INT(initpos); } else { @@ -468,16 +469,17 @@ Fstr_index(str, args) } static VALUE -Fstr_rindex(str, args) +Fstr_rindex(argc, argv, str) + int argc; + VALUE *argv; struct RString *str; - VALUE args; { struct RString *sub; VALUE initpos; int pos, len; char *s, *sbeg, *t; - if (rb_scan_args(args, "11", &sub, &initpos) == 2) { + if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) { pos = NUM2INT(initpos); if (pos >= str->len) pos = str->len; } @@ -543,7 +545,7 @@ Fstr_next(orig) 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); + memcpy(str2->ptr+1, str->ptr, str->len); str = str2; } @@ -617,13 +619,14 @@ Fstr_aref_internal(str, indx) } static VALUE -Fstr_aref(str, args) +Fstr_aref(argc, argv, str) + int argc; + VALUE *argv; struct RString *str; - VALUE args; { VALUE arg1, arg2; - if (rb_scan_args(args, "11", &arg1, &arg2) == 2) { + if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) { return str_substr(str, NUM2INT(arg1), NUM2INT(arg2)); } return Fstr_aref_internal(str, arg1); @@ -640,7 +643,7 @@ str_replace(str, beg, len, val) } memmove(str->ptr+beg+val->len, str->ptr+beg+len, str->len-(beg+len)); - memmove(str->ptr+beg, val->ptr, val->len); + memcpy(str->ptr+beg, val->ptr, val->len); str->len += val->len - len; str->ptr[str->len] = '\0'; } @@ -752,15 +755,16 @@ Fstr_aset_internal(str, indx, val) } static VALUE -Fstr_aset(str, args) +Fstr_aset(argc, argv, str) + int argc; + VALUE *argv; struct RString *str; - VALUE args; { VALUE arg1, arg2, arg3; str_modify(str); - if (rb_scan_args(args, "21", &arg1, &arg2, &arg3) == 3) { + if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { int beg, len; Check_Type(arg3, T_STRING); @@ -1222,13 +1226,14 @@ tr_squeeze(str1, str2) } static VALUE -Fstr_squeeze(str1, args) +Fstr_squeeze(argc, argv, str1) + int argc; + VALUE *argv; VALUE str1; - VALUE *args; { VALUE str2; - rb_scan_args(args, "01", &str2); + rb_scan_args(argc, argv, "01", &str2); if (str2) { Check_Type(str2, T_STRING); } @@ -1247,9 +1252,10 @@ Fstr_tr_s(str, src, repl) } static VALUE -Fstr_split(str, args) +Fstr_split(argc, argv, str) + int argc; + VALUE *argv; struct RString *str; - VALUE args; { extern VALUE FS; struct RRegexp *spat; @@ -1258,7 +1264,7 @@ Fstr_split(str, args) int beg, end, lim, i; VALUE result, tmp; - rb_scan_args(args, "02", &spat, &limit); + rb_scan_args(argc, argv, "02", &spat, &limit); if (limit) { lim = NUM2INT(limit); i = 1; @@ -1523,15 +1529,16 @@ Fstr_intern(str) } static VALUE -Fstr_sum(str, args) +Fstr_sum(argc, argv, str) + int argc; + VALUE *argv; struct RString *str; - VALUE args; { VALUE vbits; int bits; char *p, *pend; - rb_scan_args(args, "01", &vbits); + rb_scan_args(argc, argv, "01", &vbits); if (vbits == Qnil) bits = 16; else bits = NUM2INT(vbits); @@ -1640,16 +1647,16 @@ Init_String() rb_define_method(C_String, "+", Fstr_plus, 1); rb_define_method(C_String, "*", Fstr_times, 1); rb_define_method(C_String, "..", Fstr_dot2, 1); - rb_define_method(C_String, "[]", Fstr_aref, -2); - rb_define_method(C_String, "[]=", Fstr_aset, -2); + rb_define_method(C_String, "[]", Fstr_aref, -1); + rb_define_method(C_String, "[]=", Fstr_aset, -1); 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); + rb_define_method(C_String, "index", Fstr_index, -1); + rb_define_method(C_String, "rindex", Fstr_rindex, -1); rb_define_method(C_String, "to_i", Fstr_to_i, 0); rb_define_method(C_String, "to_f", Fstr_to_f, 0); @@ -1666,7 +1673,7 @@ Init_String() rb_define_method(C_String, "hex", Fstr_hex, 0); rb_define_method(C_String, "oct", Fstr_oct, 0); - rb_define_method(C_String, "split", Fstr_split, -2); + rb_define_method(C_String, "split", Fstr_split, -1); rb_define_method(C_String, "reverse", Fstr_reverse, 0); rb_define_method(C_String, "concat", Fstr_concat, 1); rb_define_method(C_String, "crypt", Fstr_crypt, 1); @@ -1684,12 +1691,12 @@ Init_String() rb_define_method(C_String, "tr", Fstr_tr, 2); rb_define_method(C_String, "tr_s", Fstr_tr_s, 2); rb_define_method(C_String, "delete", Fstr_delete, 1); - rb_define_method(C_String, "squeeze", Fstr_squeeze, -2); + rb_define_method(C_String, "squeeze", Fstr_squeeze, -1); 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_String, "sum", Fstr_sum, -1); rb_define_private_method(C_Kernel, "sub", Fsub, 2); rb_define_private_method(C_Kernel, "gsub", Fgsub, 2); diff --git a/struct.c b/struct.c index 6f69d0cf02..819b3526da 100644 --- a/struct.c +++ b/struct.c @@ -3,7 +3,7 @@ struct.c - $Author: matz $ - $Date: 1994/12/06 09:30:26 $ + $Date: 1995/01/10 10:43:02 $ created at: Tue Mar 22 18:44:30 JST 1994 ************************************************/ @@ -97,28 +97,27 @@ struct_new(name, va_alist) return st; } -#define ASSOC_KEY(a) RARRAY(a)->ptr[0] -#define ASSOC_VAL(a) RARRAY(a)->ptr[1] +#define ASSOC_KEY(a) RCONS(a)->car +#define ASSOC_VAL(a) RCONS(a)->cdr static VALUE -Sstruct_new(class, args) - VALUE class, args; +Sstruct_new(argc, argv, class) + int argc; + VALUE *argv; + VALUE class; { VALUE name, st; struct RArray *tbl; int i, max; - rb_scan_args(args, "1*", &name, &tbl); + rb_scan_args(argc, argv, "1*", &name, &tbl); Check_Type(name, T_STRING); st = struct_alloc(class, RSTRING(name)->ptr); for (i=0, max=tbl->len; iptr[i]; - Check_Type(assoc, T_ARRAY); - if (RARRAY(assoc)->len != 2) { - Fail("args must be pairs"); - } + Check_Type(assoc, T_CONS); Check_Type(ASSOC_KEY(assoc), T_STRING); struct_add(st, RSTRING(ASSOC_KEY(assoc))->ptr, ASSOC_VAL(assoc)); } @@ -183,7 +182,7 @@ Fstruct_to_s(s) { char *buf; - buf = (char*)alloca(strlen(s->name) + sizeof(HDR) + 1); + buf = ALLOCA_N(char, strlen(s->name)+sizeof(HDR)+1); sprintf(buf, "%s%s", HDR, s->name); return str_new2(buf); } @@ -238,7 +237,7 @@ Fstruct_clone(s) CLONESETUP(st, s); st->len = s->len; st->tbl = ALLOC_N(struct kv_pair, s->len); - memcpy(st->tbl, s->tbl, sizeof(struct kv_pair) * st->len); + MEMCPY(st->tbl, s->tbl, struct kv_pair, st->len); RBASIC(st)->class = single_class_clone(RBASIC(s)->class); return (VALUE)st; } @@ -248,7 +247,7 @@ Init_Struct() C_Struct = rb_define_class("Struct", C_Object); rb_include_module(C_Struct, M_Enumerable); - rb_define_single_method(C_Struct, "new", Sstruct_new, -2); + rb_define_single_method(C_Struct, "new", Sstruct_new, -1); rb_define_method(C_Struct, "clone", Fstruct_clone, 0); rb_define_method(C_Struct, "to_s", Fstruct_to_s, 0); diff --git a/variable.c b/variable.c index af8ae603f8..88a306841f 100644 --- a/variable.c +++ b/variable.c @@ -3,7 +3,7 @@ variable.c - $Author: matz $ - $Date: 1994/12/20 05:07:14 $ + $Date: 1995/01/10 10:43:03 $ created at: Tue Apr 19 23:55:15 JST 1994 ************************************************/ @@ -47,7 +47,7 @@ rb_name_class(class, id) } struct global_entry { - enum { GLOBAL_VAL, GLOBAL_VAR, GLOBAL_SYSVAR, GLOBAL_UNDEF } mode; + enum { GLOBAL_VAL, GLOBAL_VAR, GLOBAL_UNDEF } mode; ID id; union { VALUE val; @@ -68,7 +68,6 @@ mark_global_entry(key, entry) gc_mark(entry->v.val); /* normal global value */ break; case GLOBAL_VAR: - case GLOBAL_SYSVAR: if (entry->v.var) gc_mark(*entry->v.var); /* c variable pointer */ break; @@ -117,14 +116,14 @@ rb_define_variable(name, var, get_hook, set_hook, data) if (name[0] == '$') id = rb_intern(name); else { - char *buf = (char*)alloca(strlen(name)+2); + char *buf = ALLOCA_N(char, strlen(name)+2); buf[0] = '$'; strcpy(buf+1, name); id = rb_intern(buf); } entry = rb_global_entry(id); - entry->mode = GLOBAL_SYSVAR; + entry->mode = GLOBAL_VAR; entry->v.var = var; entry->get_hook = get_hook; entry->set_hook = set_hook; @@ -143,7 +142,7 @@ rb_define_varhook(name, get_hook, set_hook, data) if (name[0] == '$') id = rb_intern(name); else { - char *buf = (char*)alloca(strlen(name)+2); + char *buf = ALLOCA_N(char, strlen(name)+2); buf[0] = '$'; strcpy(buf+1, name); id = rb_intern(buf); @@ -199,7 +198,6 @@ rb_gvar_get(entry) return entry->v.val; case GLOBAL_VAR: - case GLOBAL_SYSVAR: if (entry->v.var == Qnil) return val; return *entry->v.var; @@ -271,17 +269,18 @@ rb_gvar_set(entry, val) if (entry->set_hook) (*entry->set_hook)(val, entry->id, entry->data); - if (entry->mode == GLOBAL_VAR || entry->mode == GLOBAL_SYSVAR) { - if (entry->v.var == Qnil) { - rb_readonly_hook(val, entry->id); + if (entry->mode == GLOBAL_VAR) { + if (entry->v.var) { + *entry->v.var = val; } - return *entry->v.var = val; } else { - if (entry->mode == GLOBAL_UNDEF) + if (entry->mode == GLOBAL_UNDEF) { entry->mode = GLOBAL_VAL; - return entry->v.val = val; + } + entry->v.val = val; } + return val; } VALUE @@ -378,53 +377,3 @@ rb_iv_set(obj, name, val) return rb_ivar_set_1(obj, id, val); } - -VALUE -Fdefined(obj, name) - VALUE obj; - struct RString *name; -{ - ID id; - struct global_entry *entry; - - if (FIXNUM_P(name)) { - id = FIX2INT(name); - } - else { - Check_Type(name, T_STRING); - id = rb_intern(name->ptr); - } - - if (id == rb_intern("nil") || id == rb_intern("self")) return TRUE; - - switch (id & ID_SCOPE_MASK) { - case ID_GLOBAL: - if (st_lookup(global_tbl, id, &entry) && entry->mode != GLOBAL_UNDEF) - return TRUE; - break; - - case ID_INSTANCE: - if (TYPE(Qself) != T_OBJECT || instance_tbl == Qnil) break; - if (st_lookup(instance_tbl, id, Qnil)) return TRUE; - break; - - case ID_CONST: - return const_bound(CLASS_OF(Qself), id); - break; - - default: - { - int i, max; - - if (the_scope->local_tbl) { - for (i=1, max=the_scope->local_tbl[0]+1; ilocal_tbl[i] == id) return TRUE; - } - } - } - if (st_lookup(class_tbl, id, Qnil)) return TRUE; - break; - } - return FALSE; - -} diff --git a/version.h b/version.h index 92781b4078..ef005b1692 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.63" -#define VERSION_DATE "94/12/20" +#define RUBY_VERSION "0.64" +#define VERSION_DATE "95/01/10" -- cgit v1.2.3