From b3f9ba5a3720de81a9a14d9d906509f81abeef7a Mon Sep 17 00:00:00 2001 From: Yukihiro Matsumoto Date: Mon, 19 Dec 1994 12:01:10 +0900 Subject: [PATCH] version 0.62 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.62.tar.gz Mon Dec 19 12:01:10 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y(cond): 条件式に代入式が置かれた場合,`-v'オプションで警 告が出るように. * parse.y(**): 冪乗演算子`**'の優先順位を単項演算子より高くした. * parse.y(and,or): 優先順位の低い演算子`and', `or'. * 0.62 released. * eval.c: 不必要になったPUSH_ENV, POP_ENVを減らした. * env.h: ENVIONからselfをはずした.PUSH_ENVはsuperの準備のためだけ に用いることにした. * eval.c: 下記のオブジェクト化で遅くなった実行速度をもとに戻した. Mon Dec 17 23:01:10 1994 Yukihiro Matsumoto (matz@ix-02) * eval.c: env.{argv,argc}とscope.local_varsのオブジェクト化. * eval.c: 1スコープ内で複数Blockを生成したときのバグを修正. Fri Dec 16 15:52:06 1994 Yukihiro Matsumoto (matz@ix-02) * parse.y: `&&'と`||'の両辺はいつでも条件式とした. Thu Dec 15 00:16:04 1994 Yukihiro Matsumoto (matz@dyna) * eval.c(Block): Blockオブジェクトを実現. * node.h: NODE_QLISTはなくなった. * eval.c(rb_call): 引数への代入を名前で一つずつ代入するのをやめて, 一度にコピーするようにした. * eval.c(rb_call): rubyで記述されたメソッドへの引数渡しをinline化. * eval.c: イテレータ判定処理の全面書き換え.不適切なイテレータ呼び 出しをなくした.例えば「[foo(),bar()]{i|baz(i)}」でfooもbarもイ テレータとして呼び出され*ない*. * eval.c(rb_call): SCOPE処理をinline化.メソッド呼び出しの若干の高 速化. Wed Dec 14 18:09:33 1994 Yukihiro Matsumoto (matz@ix-02) * node.h: nodeもオブジェクトにする.よってGCで回収される. --- ChangeLog | 42 +++- Makefile.in | 7 +- class.c | 7 +- configure.in | 22 +- defines.h | 2 +- dict.c | 16 +- dir.c | 4 +- dln.c | 2 +- env.h | 14 +- eval.c | 558 ++++++++++++++++++++++++++------------------- file.c | 6 +- gc.c | 133 +++++------ glob.c | 6 +- inits.c | 3 +- io.c | 32 +-- methods.h | 22 -- missing/strdup.c | 4 +- missing/strftime.c | 6 +- node.h | 40 ++-- object.c | 6 +- pack.c | 6 +- parse.y | 380 +++++++++++------------------- process.c | 6 +- re.c | 69 +++--- ruby.c | 14 +- ruby.h | 85 ++++--- sample/blk.rb | 9 + sample/export.rb | 2 +- spec | 31 ++- st.c | 2 +- string.c | 4 +- variable.c | 23 +- version.c | 6 +- version.h | 4 +- 34 files changed, 804 insertions(+), 769 deletions(-) delete mode 100644 methods.h create mode 100644 sample/blk.rb diff --git a/ChangeLog b/ChangeLog index 52af56fba7e8c7..dfa5c85f519955 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,44 @@ +Mon Dec 19 12:01:10 1994 Yukihiro Matsumoto (matz@ix-02) + + * eval.c: ɬפˤʤäPUSH_ENV, POP_ENV򸺤餷 + + * env.h: ENVIONselfϤPUSH_ENVsuperνΤ + Ѥ뤳Ȥˤ + + * eval.c: Υ֥Ȳ٤ʤä¹®٤Ȥᤷ + +Mon Dec 17 23:01:10 1994 Yukihiro Matsumoto (matz@ix-02) + + * eval.c: env.{argv,argc}scope.local_varsΥ֥Ȳ + + * eval.c: 1ʣBlockȤΥХ + +Fri Dec 16 15:52:06 1994 Yukihiro Matsumoto (matz@ix-02) + + * parse.y: `&&'`||'ξդϤĤǤPȤ + +Thu Dec 15 00:16:04 1994 Yukihiro Matsumoto (matz@dyna) + + * eval.c(Block): Block֥Ȥ¸ + + * node.h: NODE_QLISTϤʤʤä + + * eval.c(rb_call): ؤ̾ǰĤΤơ + ٤˥ԡ褦ˤ + + * eval.c(rb_call): rubyǵҤ줿᥽åɤؤΰϤinline + + * eval.c: ƥ졼Ƚ̽񤭴Ŭڤʥƥ졼Ƥ + Фʤ㤨С[foo(),bar()]{i|baz(i)}פfoobar⥤ + ƥ졼ȤƸƤӽФ*ʤ* + + * eval.c(rb_call): SCOPEinline᥽åɸƤӽФμ㴳ι + ® + +Wed Dec 14 18:09:33 1994 Yukihiro Matsumoto (matz@ix-02) + + * node.h: node⥪֥Ȥˤ롥äGCDz롥 + Thu Dec 8 14:17:29 1994 Yukihiro Matsumoto (matz@ix-02) * 0.60 released - alpha test baseline. - diff --git a/Makefile.in b/Makefile.in index 3a88a991be3f23..a63ee53af87b53 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,7 +16,7 @@ CFLAGS = -g LDFLAGS = @STATIC@ $(CFLAGS) LIBS = @LIBS@ DEFS = @DEFS@ -MISSING = @LIBOBJS@ +MISSING = @LIBOBJS@ @ALLOCA@ prefix = /usr/local binprefix = @@ -78,8 +78,7 @@ OBJS = array.o \ time.o \ variable.o \ version.o \ - $(MISSING) \ - @ALLOCA@ + $(MISSING) PROGRAM = ruby @@ -95,6 +94,8 @@ $(bindir)/$(PROGRAM): $(PROGRAM) install: $(bindir)/$(PROGRAM) clean:; @rm -f $(OBJS) + +realclean:; @rm -f $(OBJS) @rm -f core ruby *~ config.status Makefile .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< diff --git a/class.c b/class.c index 4a36f0e928e92e..fa1860060a7e89 100644 --- a/class.c +++ b/class.c @@ -3,7 +3,7 @@ class.c - $Author: matz $ - $Date: 1994/11/01 08:27:48 $ + $Date: 1994/12/16 00:59:42 $ created at: Tue Aug 10 15:05:44 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -86,7 +86,6 @@ rb_define_class_id(id, super) /* make metaclass */ RBASIC(cls)->class = single_class_new(super?super->class:C_Class); - literalize(RBASIC(cls)->class); return (VALUE)cls; } @@ -193,10 +192,6 @@ rb_add_method(class, mid, node, noex) Warning("redefine %s", rb_id2name(mid)); } rb_clear_cache(body); - freenode(body); - } - if (node && node->type != NODE_FBODY) { - node = NEW_FBODY(node, mid); } body = NEW_METHOD(node, noex); st_insert(class->m_tbl, mid, body); diff --git a/configure.in b/configure.in index 9eec8ad9995a05..5ee5463ab9abb8 100644 --- a/configure.in +++ b/configure.in @@ -16,17 +16,20 @@ fi AC_SUBST(STATIC)dnl AC_PROG_YACC AC_PROG_INSTALL -AC_HAVE_HEADERS(unistd.h syscall.h a.out.h) +AC_HAVE_HEADERS(unistd.h stdlib.h syscall.h a.out.h dirent.h\ + string.h strings.h) AC_DIR_HEADER AC_GETGROUPS_T AC_RETSIGTYPE -AC_REPLACE_FUNCS(memmove mkdir strerror strftime) -AC_REPLACE_FUNCS(strstr strtol strtoul strdup) -AC_HAVE_FUNCS(fmod killpg socket random) -AC_HAVE_FUNCS(wait4 waitpid syscall getcwd) -AC_HAVE_FUNCS(setruid seteuid setreuid) -AC_HAVE_FUNCS(setrgid setegid setregid) -AC_HAVE_FUNCS(getpriority sigprocmask) +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_REPLACE_FUNCS(memmove mkdir strerror strftime\ + strstr strtol strtoul strdup) +AC_HAVE_FUNCS(fmod killpg socket random wait4 waitpid syscall getcwd\ + setruid seteuid setreuid setrgid setegid setregid\ + getpriority sigprocmask) AC_FUNC_CHECK(setenv, [], AC_HAVE_FUNCS(putenv)) case "$LIBOBJS" in @@ -56,8 +59,5 @@ AC_COMPILE_CHECK([pw_comment in struct passwd], [#include ], [struct passwd pw; pw.pw_comment;], AC_DEFINE(PW_COMMENT)) AC_COMPILE_CHECK([pw_expire in struct passwd], [#include ], [struct passwd pw; pw.pw_expire;], AC_DEFINE(PW_EXPIRE)) -AC_HAVE_LIBRARY(m, [LIBS="$LIBS -lm"]) -AC_HAVE_LIBRARY(dbm, [LIBS="$LIBS -ldbm"]) -AC_HAVE_LIBRARY(socket, [LIBS="$LIBS -lsocket"]) AC_OUTPUT(Makefile) mv confdefs.h config.h diff --git a/defines.h b/defines.h index d5e86072af34f7..4928db7d1e540f 100644 --- a/defines.h +++ b/defines.h @@ -3,7 +3,7 @@ defines.h - $Author: matz $ - $Date: 1994/11/18 01:37:26 $ + $Date: 1994/12/09 01:28:22 $ created at: Wed May 18 00:21:44 JST 1994 ************************************************/ diff --git a/dict.c b/dict.c index 74bfc22e03ac31..3db2501fd954d9 100644 --- a/dict.c +++ b/dict.c @@ -3,7 +3,7 @@ dict.c - $Author: matz $ - $Date: 1994/12/06 09:29:53 $ + $Date: 1994/12/19 08:30:00 $ created at: Mon Nov 22 18:51:18 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -90,8 +90,16 @@ Fdic_indexes(dic, args) struct RArray *new; int i = 0; - if (!args || args->len == 1 && TYPE(args->ptr) != T_ARRAY) { - args = (struct RArray*)rb_to_a(args->ptr[0]); + if (!args || args->len == 0) { + Fail("wrong # of argment"); + } + else if (args->len == 1) { + if (TYPE(args->ptr[0])) { + args = (struct RArray*)rb_to_a(args->ptr[0]); + } + else { + args = (struct RArray*)args->ptr[0]; + } } new = (struct RArray*)ary_new2(args->len); @@ -583,7 +591,7 @@ Init_Dict() rb_define_single_method(envtbl,"to_s", Fenv_to_s, 0); rb_include_module(CLASS_OF(envtbl), M_Enumerable); - rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook); + rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook, 0); rb_define_private_method(C_Kernel, "getenv", Fgetenv, 1); rb_define_private_method(C_Kernel, "setenv", Fsetenv, 2); diff --git a/dir.c b/dir.c index f139c405541363..84299127ca420d 100644 --- a/dir.c +++ b/dir.c @@ -3,20 +3,20 @@ dir.c - $Author: matz $ - $Date: 1994/12/06 09:29:55 $ + $Date: 1994/12/09 09:40:18 $ created at: Wed Jan 5 09:51:01 JST 1994 Copyright (C) 1994 Yukihiro Matsumoto ************************************************/ +#include #include "ruby.h" #include #ifdef HAVE_UNISTD_H #include #endif -#include /* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */ #if defined(DIRENT) || defined(_POSIX_VERSION) diff --git a/dln.c b/dln.c index b15c01bce1c22c..44179ec3e976b9 100644 --- a/dln.c +++ b/dln.c @@ -3,7 +3,7 @@ dln.c - $Author: matz $ - $Date: 1994/11/18 01:37:28 $ + $Date: 1994/12/09 01:28:23 $ created at: Tue Jan 18 17:05:06 JST 1994 Copyright (C) 1994 Yukihiro Matsumoto diff --git a/env.h b/env.h index ebf378073ff637..ebed038d3963a0 100644 --- a/env.h +++ b/env.h @@ -3,8 +3,8 @@ env.h - $Author: matz $ - $Revision: 1.5 $ - $Date: 1994/11/01 08:27:51 $ + $Revision: 1.7 $ + $Date: 1994/12/19 08:30:01 $ created at: Mon Jul 11 11:53:03 JST 1994 ************************************************/ @@ -12,27 +12,21 @@ #define ENV_H extern struct ENVIRON { - VALUE self; int argc; VALUE *argv; + VALUE arg_ary; ID last_func; struct RClass *last_class; struct ENVIRON *prev; } *the_env; -#undef Qself -#define Qself the_env->self - extern struct SCOPE { ID *local_tbl; VALUE *local_vars; - VALUE block; - int flags; + VALUE var_ary; struct SCOPE *prev; } *the_scope; -#define VARS_MALLOCED (1<<2) - extern int rb_in_eval; #endif /* ENV_H */ diff --git a/eval.c b/eval.c index fac68662c9a9eb..e40d78121f6dfc 100644 --- a/eval.c +++ b/eval.c @@ -3,7 +3,7 @@ eval.c - $Author: matz $ - $Date: 1994/12/06 09:29:59 $ + $Date: 1994/12/19 08:39:17 $ created at: Thu Jun 10 14:22:17 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -92,12 +92,16 @@ rb_get_method_body(classp, idp, noexp) ent->origin = origin; ent->method = body->nd_body; ent->noex = body->nd_noex; + body = body->nd_body; - if (ent->method == Qnil) return Qnil; - *idp = ent->method->nd_mid; + if (body == Qnil) return Qnil; + if (nd_type(body) == NODE_FBODY) { + *idp = body->nd_mid; + body = body->nd_head; + } *classp = origin; if (noexp) *noexp = ent->noex; - return ent->method->nd_head; + return body; } void @@ -114,17 +118,16 @@ rb_alias(class, name, def) Fail("undefined method `%s' for class `%s'", rb_id2name(def), rb_class2name(class)); } - body->nd_body->nd_cnt++; if (st_lookup(class->m_tbl, name, &old)) { if (verbose) { Warning("redefine %s", rb_id2name(name)); } rb_clear_cache(old->nd_body); - freenode(old); } - st_insert(class->m_tbl, name, NEW_METHOD(body->nd_body, body->nd_noex)); + st_insert(class->m_tbl, name, NEW_METHOD(NEW_FBODY(body->nd_body, name), + body->nd_noex)); } void @@ -199,28 +202,33 @@ extern NODE *eval_tree; extern int nerrs; extern VALUE TopSelf; +VALUE Qself; + +#define PUSH_SELF(s) { \ + VALUE __saved_self__ = Qself; \ + Qself = s; \ + +#define POP_SELF() Qself = __saved_self__; } + 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;\ - -#define DUP_ENV() {\ - struct ENVIRON _this;\ - _this = *the_env;\ - _this.prev = the_env;\ - the_env = &_this;\ +#define PUSH_ENV() { \ + struct ENVIRON _this; \ + _this.prev = the_env; \ + the_env = &_this; \ #define POP_ENV() the_env = the_env->prev; } struct BLOCK { NODE *var; NODE *body; + VALUE self; struct ENVIRON env; struct SCOPE scope; int level; + VALUE block; + int iter; struct BLOCK *prev; } *the_block; @@ -229,38 +237,64 @@ struct BLOCK { _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; \ +#define PUSH_BLOCK2(b) { \ + b->prev = the_block; \ + the_block = b; \ + #define POP_BLOCK() the_block = the_block->prev; } +static struct iter { + int iter; + struct iter *prev; +} *iter; + +#define PUSH_ITER(i) {\ + struct iter __iter__;\ + __iter__.prev = iter;\ + __iter__.iter = (i);\ + iter = &__iter__;\ + +#define POP_ITER() \ + iter = iter->prev;\ +} + static int tag_level, target_level; static struct tag { int level; jmp_buf buf; struct gc_list *gclist; + VALUE self; struct ENVIRON *env; + struct iter *iter; struct tag *prev; } *prot_tag; -#define PUSH_TAG() {\ - struct tag _this;\ - _this.level= ++tag_level;\ - _this.env = the_env;\ - _this.prev = prot_tag;\ - prot_tag = &_this;\ +#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; \ -#define POP_TAG() \ - tag_level--;\ - prot_tag = prot_tag->prev;\ +#define EXEC_TAG() (setjmp(prot_tag->buf)) +#define JUMP_TAG(val) { \ + the_env = prot_tag->env; \ + iter = prot_tag->iter; \ + longjmp(prot_tag->buf,(val)); \ } -#define EXEC_TAG() (setjmp(prot_tag->buf)) -#define JUMP_TAG(val) {\ - the_env = prot_tag->env;\ - longjmp(prot_tag->buf,(val));\ +#define POP_TAG() \ + tag_level--; \ + prot_tag = prot_tag->prev; \ } #define TAG_RETURN 1 @@ -293,8 +327,6 @@ struct class_link { struct SCOPE _scope; \ _scope = *the_scope; \ _scope.prev = the_scope; \ - _scope.block = Qnil; \ - _scope.flags = 0; \ the_scope = &_scope; \ #define POP_SCOPE() the_scope = the_scope->prev; } @@ -317,8 +349,6 @@ extern VALUE rb_stderr; extern int sourceline; extern char *sourcefile; -static int iter_level = 0; - VALUE rb_self() { @@ -387,20 +417,13 @@ Eval(toplevel) tree = eval_tree; eval_tree = Qnil; - sourcefile = tree->src; + sourcefile = tree->file; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { result = rb_eval(tree); } POP_TAG(); -/* #define PURIFY_D /* define when purify'ing */ -#ifdef PURIFY_D - freenode(tree); -#else - /* you don't have to free at toplevel */ - if (!toplevel) freenode(tree); -#endif if (state) JUMP_TAG(state); return result; @@ -413,7 +436,7 @@ ruby_run() if (nerrs > 0) exit(nerrs); Init_stack(); - rb_define_variable("$!", &errstr, Qnil, Qnil); + rb_define_variable("$!", &errstr, Qnil, Qnil, 0); errat = Qnil; /* clear for execution */ PUSH_TAG(); @@ -463,12 +486,11 @@ rb_trap_eval(cmd) { int state, go_out; - DUP_ENV(); + PUSH_SELF(TopSelf); PUSH_CLASS(); PUSH_TAG(); PUSH_SCOPE(); if ((state = EXEC_TAG()) == 0) { - the_env->self = TopSelf; the_class = (struct RClass*)C_Object; the_scope->local_vars = top_scope->local_vars; the_scope->local_tbl = top_scope->local_tbl; @@ -482,7 +504,7 @@ rb_trap_eval(cmd) POP_SCOPE(); POP_TAG(); POP_CLASS(); - POP_ENV(); + POP_SELF(); if (go_out) JUMP_TAG(state); } @@ -493,23 +515,23 @@ rb_trap_eval(cmd) argc = 0;\ argv = Qnil;\ }\ - else if (n->type == NODE_ARRAY) {\ - int i;\ - for (argc=0; n; n=n->nd_next) argc++;\ + else if (nd_type(n) == NODE_ARRAY) {\ + argc=n->nd_alen;\ if (argc > 0) {\ + int i;\ n = node->nd_args;\ argv = (VALUE*)alloca(sizeof(VALUE)*argc);\ - for (i=0;n;n=n->nd_next) {\ - argv[i++] = rb_eval(n->nd_head);\ + for (i=0;ind_head);\ + n=n->nd_next;\ }\ }\ }\ else {\ - args = rb_eval(n);\ - if (TYPE(args) != T_ARRAY)\ - args = rb_to_a(args);\ - argc = RARRAY(args)->len;\ - argv = RARRAY(args)->ptr;\ + argc = -2;\ + argv = (VALUE*)rb_eval(n);\ + if (TYPE(argv) != T_ARRAY)\ + argv = (VALUE*)rb_to_a(argv);\ }\ } @@ -537,7 +559,7 @@ rb_eval(node) } #endif - switch (node->type) { + switch (nd_type(node)) { case NODE_BLOCK: while (node->nd_next) { rb_eval(node->nd_head); @@ -569,7 +591,7 @@ rb_eval(node) val = rb_eval(node->nd_head); node = node->nd_body; while (node) { - if (node->type == NODE_WHEN) { + if (nd_type(node) == NODE_WHEN) { NODE *tag = node->nd_head; while (tag) { @@ -667,31 +689,23 @@ rb_eval(node) case NODE_ITER: case NODE_FOR: { - int iter_saved = iter_level; - - DUP_ENV(); PUSH_BLOCK(node->nd_var, node->nd_body); PUSH_TAG(); state = EXEC_TAG(); if (state == 0) { - if (node->type == NODE_ITER) { - iter_level = 1; + if (nd_type(node) == NODE_ITER) { result = rb_eval(node->nd_iter); } else { VALUE recv; - iter_level = 0; recv = rb_eval(node->nd_iter); - iter_level = 1; - result = rb_call(CLASS_OF(recv), recv, each, 0, Qnil); + result = rb_call(CLASS_OF(recv),recv,each,0,Qnil,0,1); } } POP_TAG(); POP_BLOCK(); - POP_ENV(); - iter_level = iter_saved; switch (state) { case 0: break; @@ -730,6 +744,17 @@ 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()) { @@ -817,83 +842,26 @@ rb_eval(node) break; case NODE_CALL: - case NODE_CALL2: + case NODE_ICALL: { - VALUE recv, *argv; - int argc, iter_saved = iter_level; - VALUE args = Qnil; /* used in SETUP_ARGS */ + VALUE recv; + int argc; VALUE *argv; /* used in SETUP_ARGS */ VALUE buf[3]; - iter_level = 0; /* recv & args are not iter. */ recv = node->nd_recv?rb_eval(node->nd_recv):Qself; -#if 0 SETUP_ARGS; -#else - { - NODE *n = node->nd_args; - if (n == Qnil) { - argc = 0; - argv = Qnil; - } - else if (n->type == NODE_ARRAY) { - if (n->nd_next == Qnil) { - /* 1 arg */ - argc = 1; - buf[0] = rb_eval(n->nd_head); - argv = buf; - } - else if (n->nd_next->nd_next == Qnil) { - /* 2 args */ - argc = 2; - buf[0] = rb_eval(n->nd_head); - buf[1] = rb_eval(n->nd_next->nd_head); - argv = buf; - } - else if (n->nd_next->nd_next->nd_next == Qnil) { - /* 3 args */ - argc = 3; - buf[0] = rb_eval(n->nd_head); - buf[1] = rb_eval(n->nd_next->nd_head); - buf[2] = rb_eval(n->nd_next->nd_next->nd_head); - argv = buf; - } - else { - int i; - for (argc=0; n; n=n->nd_next) argc++; - n = node->nd_args; - argv = (VALUE*)alloca(sizeof(VALUE)*argc); - for (i=0;n;n=n->nd_next) { - argv[i++] = rb_eval(n->nd_head); - } - } - } - else { - args = rb_eval(n); - if (TYPE(args) != T_ARRAY) - args = rb_to_a(args); - argc = RARRAY(args)->len; - argv = RARRAY(args)->ptr; - } - } -#endif - iter_level = iter_saved; /* restore iter. level */ - return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv, - node->nd_recv?0:1); + node->nd_recv?0:1, nd_type(node)==NODE_ICALL); } break; case NODE_SUPER: case NODE_ZSUPER: { - int iter_saved = iter_level; - int i, argc; - VALUE *argv; - VALUE args = Qnil; /* used in SETUP_ARGS */ - - iter_level = 0; /* recv & args are not iter. */ + int i; + int argc; VALUE *argv; /* used in SETUP_ARGS */ - if (node->type == NODE_ZSUPER) { + if (nd_type(node) == NODE_ZSUPER) { argc = the_env->argc; argv = the_env->argv; } @@ -901,11 +869,8 @@ rb_eval(node) SETUP_ARGS; } - if (iter_saved == 0) iter_level = 1; result = rb_call(the_env->last_class->super, Qself, - the_env->last_func, argc, argv, 1); - /* restore iter. level */ - iter_level = iter_saved; + the_env->last_func, argc, argv, 1, iter->iter); } return result; @@ -929,8 +894,6 @@ rb_eval(node) result = rb_eval(node->nd_body); } POP_TAG(); - if (the_scope->local_vars && (the_scope->flags&VARS_MALLOCED)) - free(the_scope->local_vars); POP_SCOPE(); if (state != 0) JUMP_TAG(state); @@ -989,7 +952,8 @@ rb_eval(node) case NODE_CVAR: { VALUE val = rb_const_get(node->nd_vid); - node->type = NODE_CONST; + + nd_set_type(node, NODE_CONST); node->nd_cval = val; return val; } @@ -1026,7 +990,7 @@ rb_eval(node) int i; NODE *list; - for (i=0, list=node; list; list=list->nd_next) i++; + i = node->nd_alen; ary = ary_new2(i); for (i=0;node;node=node->nd_next) { RARRAY(ary)->ptr[i++] = rb_eval(node->nd_head); @@ -1050,7 +1014,7 @@ rb_eval(node) str = str_new3(node->nd_lit); while (list) { - if (list->nd_head->type == NODE_STR) { + if (nd_type(list->nd_head) == NODE_STR) { str2 = list->nd_head->nd_lit; } else { @@ -1062,13 +1026,13 @@ rb_eval(node) } list = list->nd_next; } - if (node->type == NODE_DREGX) { + if (nd_type(node) == NODE_DREGX) { return regexp_new(RSTRING(str)->ptr, RSTRING(str)->len); } - if (node->type == NODE_XSTR2) { + if (nd_type(node) == NODE_XSTR2) { return rb_xstring(str); } - if (node->type == NODE_DGLOB) { + if (nd_type(node) == NODE_DGLOB) { return glob_new(str); } return str; @@ -1085,38 +1049,9 @@ rb_eval(node) Fail("Wrong # of arguments(%d for 1)", the_env->argc); return rb_ivar_set(node->nd_vid, the_env->argv[0]); - case NODE_ARGS: - { - NODE *local; - int i, len; - - i = node->nd_cnt; - len = the_env->argc; - if (i > len || (node->nd_rest == -1 && i < len)) - Fail("Wrong # of arguments(%d for %d)", len, i); - - local = node->nd_frml; - if (the_scope->local_vars == Qnil) - Bug("unexpected local variable asignment"); - - for (i=0;local;i++) { - the_scope->local_vars[(int)local->nd_head] = the_env->argv[i]; - local = local->nd_next; - } - if (node->nd_rest >= 0) { - if (the_env->argc == 0) - the_scope->local_vars[node->nd_rest] = ary_new(); - else - the_scope->local_vars[node->nd_rest] = - ary_new4(the_env->argc-i, the_env->argv+i); - } - } - return Qnil; - case NODE_DEFN: { if (node->nd_defn) { - node->nd_defn->nd_cnt++; rb_add_method(the_class,node->nd_mid,node->nd_defn, node->nd_noex); } @@ -1132,7 +1067,6 @@ rb_eval(node) Fail("Can't define method \"%s\" for nil", rb_id2name(node->nd_mid)); } - node->nd_defn->nd_cnt++; rb_add_method(rb_single_class(recv), node->nd_mid, node->nd_defn, 0); } @@ -1169,21 +1103,19 @@ rb_eval(node) if (verbose) { Warning("redefine class %s", rb_id2name(node->nd_cname)); } - unliteralize(class); } - DUP_ENV(); + PUSH_SELF((VALUE)the_class); PUSH_CLASS(); the_class = (struct RClass*) rb_define_class_id(node->nd_cname, super); - Qself = (VALUE)the_class; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { rb_eval(node->nd_body); } POP_TAG(); POP_CLASS(); - POP_ENV(); + POP_SELF(); if (state) JUMP_TAG(state); } return Qnil; @@ -1196,20 +1128,18 @@ rb_eval(node) if (verbose) { Warning("redefine module %s", rb_id2name(node->nd_cname)); } - unliteralize(module); } - DUP_ENV(); + PUSH_SELF((VALUE)the_class); PUSH_CLASS(); the_class = (struct RClass*)rb_define_module_id(node->nd_cname); - Qself = (VALUE)the_class; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { rb_eval(node->nd_body); } POP_TAG(); POP_CLASS(); - POP_ENV(); + POP_SELF(); if (state) JUMP_TAG(state); } return Qnil; @@ -1227,7 +1157,7 @@ rb_eval(node) return Qnil; default: - Bug("unknown node type %d", node->type); + Bug("unknown node type %d", nd_type(node)); } return Qnil; /* not reached */ } @@ -1330,17 +1260,18 @@ rb_fail(mesg) VALUE iterator_p() { - if (iter_level == 0) return TRUE; + if (iter->iter) return TRUE; return FALSE; } static VALUE Fiterator_p() { - if (iter_level == -1) return TRUE; + if (iter->prev && iter->prev->iter) return TRUE; return FALSE; } + VALUE rb_yield(val) VALUE val; @@ -1350,7 +1281,7 @@ rb_yield(val) int state, go_out; VALUE result; - if (!iter_level == 0) { + if (!iterator_p()) { Fail("yield called out of iterator"); } @@ -1361,18 +1292,19 @@ rb_yield(val) the_scope = &(block->scope); the_block = block->prev; if (block->var) { - if (block->var->type == NODE_MASGN) + if (nd_type(block->var) == NODE_MASGN) masign(block->var, val); else asign(block->var, val); } + PUSH_ITER(block->iter); PUSH_TAG(); node = block->body; switch (state = EXEC_TAG()) { redo: case 0: - if (node->type == NODE_CFUNC) { + if (nd_type(node) == NODE_CFUNC) { result = (*node->nd_cfnc)(val,node->nd_argc); } else { @@ -1395,6 +1327,7 @@ rb_yield(val) break; } POP_TAG(); + POP_ITER(); the_block = block; the_env = the_env->prev; the_scope = the_scope->prev; @@ -1446,7 +1379,7 @@ asign(lhs, val) NODE *lhs; VALUE val; { - switch (lhs->type) { + switch (nd_type(lhs)) { case NODE_GASGN: rb_gvar_set(lhs->nd_entry, val); break; @@ -1495,28 +1428,23 @@ rb_iterate(it_proc, data1, bl_proc, data2) VALUE (*it_proc)(), (*bl_proc)(); char *data1, *data2; { - int state, iter_saved; + int state; VALUE retval; NODE *node = NEW_CFUNC(bl_proc, data2); struct BLOCK block; - DUP_ENV(); + PUSH_ITER(1); PUSH_BLOCK(Qnil, node); PUSH_TAG(); - iter_saved = iter_level; - iter_level = 1; state = EXEC_TAG(); if (state == 0) { retval = (*it_proc)(data1); } - iter_level = iter_saved; POP_TAG(); POP_BLOCK(); - POP_ENV(); - - freenode(node); + POP_ITER(); switch (state) { case 0: @@ -1637,12 +1565,13 @@ rb_undefined(obj, id, noex) } static VALUE -rb_call(class, recv, mid, argc, argv, func) +rb_call(class, recv, mid, argc, argv, func, itr) struct RClass *class; - VALUE recv, *argv; - int argc; + VALUE recv; ID mid; - int func; + int argc; + VALUE *argv; + int func, itr; { NODE *body; int noex; @@ -1655,7 +1584,7 @@ rb_call(class, recv, mid, argc, argv, func) if (ent->method == Qnil) rb_undefined(recv, mid, 0); class = ent->origin; mid = ent->mid; - body = ent->method->nd_head; + body = ent->method; noex = ent->noex; } else { @@ -1669,20 +1598,26 @@ rb_call(class, recv, mid, argc, argv, func) if (!func && noex) rb_undefined(recv, mid, 1); + PUSH_ITER(itr); + PUSH_SELF(recv); PUSH_ENV(); - Qself = recv; the_env->last_func = mid; - the_env->argc = argc; - the_env->argv = argv; - iter_level--; - the_env->last_class = class; - if (body->type == NODE_CFUNC) { + if (argc < 0) { + the_env->arg_ary = (VALUE)argv; + argc = RARRAY(argv)->len; + argv = RARRAY(argv)->ptr; + } + else { + the_env->arg_ary = Qnil; + } + + if (nd_type(body) == NODE_CFUNC) { int len = body->nd_argc; if (len >= 0 && argc != len) { - Fail("Wrong # of arguments for(%d for %d)", argc, body->nd_argc); + Fail("Wrong # of arguments(%d for %d)", argc, body->nd_argc); } switch (len) { @@ -1789,14 +1724,52 @@ rb_call(class, recv, mid, argc, argv, func) } else { int state; + VALUE *local_vars; - sourcefile = body->src; + 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; + + 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); + } + } + } state = EXEC_TAG(); if (state == 0) { result = rb_eval(body); } POP_TAG(); + POP_SCOPE(); switch (state) { case 0: break; @@ -1819,8 +1792,9 @@ rb_call(class, recv, mid, argc, argv, func) JUMP_TAG(state); } } - iter_level++; POP_ENV(); + POP_SELF(); + POP_ITER(); return result; } @@ -1831,18 +1805,7 @@ rb_apply(recv, mid, args) struct RArray *args; ID mid; { - VALUE *argv; - int argc, i; - - if (args) { - argc = args->len; - argv = args->ptr; - } - else { - argc = 0; - argv = Qnil; - } - return rb_call(CLASS_OF(recv), recv, mid, argc, argv, recv==Qself); + return rb_call(CLASS_OF(recv), recv, mid, -2, (VALUE*)args, 1, 0); } static VALUE @@ -1889,7 +1852,7 @@ rb_funcall(recv, mid, n, va_alist) argv = Qnil; } - return rb_call(CLASS_OF(recv), recv, mid, n, argv, recv==Qself); + return rb_call(CLASS_OF(recv), recv, mid, n, argv, 1, 0); } int rb_in_eval = 0; @@ -1906,7 +1869,6 @@ Feval(obj, src) Check_Type(src, T_STRING); PUSH_TAG(); - DUP_ENV(); rb_in_eval = 1; node = eval_tree; @@ -1926,7 +1888,6 @@ Feval(obj, src) } eval_tree = node; POP_CLASS(); - POP_ENV(); POP_TAG(); if (state) JUMP_TAG(state); @@ -2004,11 +1965,10 @@ Fload(obj, fname) } } #endif + PUSH_SELF(TopSelf); PUSH_TAG(); - DUP_ENV(); PUSH_CLASS(); the_class = (struct RClass*)C_Object; - Qself = TopSelf; the_scope->local_vars = top_scope->local_vars; the_scope->local_tbl = top_scope->local_tbl; rb_in_eval = 1; @@ -2020,8 +1980,8 @@ Fload(obj, fname) } } POP_CLASS(); - POP_ENV(); POP_TAG(); + POP_SELF(); rb_in_eval = in_eval; if (nerrs > 0) { rb_fail(errstr); @@ -2093,12 +2053,12 @@ Init_load() char *path; rb_load_path = ary_new(); - rb_define_variable("$:", &rb_load_path, Qnil, rb_readonly_hook); - rb_define_variable("$LOAD_PATH", &rb_load_path, Qnil, rb_readonly_hook); + rb_define_variable("$:", &rb_load_path, Qnil, rb_readonly_hook, 0); + rb_define_variable("$LOAD_PATH", &rb_load_path, Qnil, rb_readonly_hook, 0); rb_loadfiles = ary_new(); - rb_define_variable("$\"", &rb_load_path, Qnil, rb_readonly_hook); - rb_define_variable("$LOAD_FILES", &rb_load_path, Qnil, rb_readonly_hook); + rb_define_variable("$\"", &rb_load_path, Qnil, rb_readonly_hook, 0); + rb_define_variable("$LOAD_FILES", &rb_load_path, Qnil, rb_readonly_hook,0); addpath(getenv("RUBYLIB")); addpath(RUBY_LIB); @@ -2108,8 +2068,140 @@ Init_load() Init_eval() { + rb_global_variable(&eval_tree); rb_define_private_method(C_Kernel, "exit", Fexit, -2); 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); } + +VALUE C_Block; +static ID blkdata; + +static void +blk_mark(data) + struct BLOCK *data; +{ + gc_mark_scope(&data->scope); + gc_mark(data->env.arg_ary); + gc_mark(data->var); + gc_mark(data->body); + gc_mark(data->self); +} + +static void +blk_free(data) + struct BLOCK *data; +{ + free(data->scope.local_tbl); + free(data->scope.local_vars); +} + +static VALUE +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"); + } + if (the_block->block) return the_block->block; + blk = obj_alloc(C_Block); + 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; + + 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; + + if (len > 0) { + len++; + tbl = ALLOC_N(ID, len); + memcpy(tbl, data->scope.local_tbl, sizeof(ID)*len); + data->scope.local_tbl = tbl; + } + + the_block->block = blk; + return blk; +} + +static VALUE +Fblk_do(blk, args) + VALUE blk, args; +{ + struct BLOCK *data; + VALUE result; + int state; + + switch (RARRAY(args)->len) { + case 0: + args = Qnil; + break; + case 1: + args = RARRAY(args)->ptr[0]; + break; + } + + Get_Data_Struct(blk, blkdata, struct BLOCK, data); + + /* PUSH BLOCK from data */ + PUSH_BLOCK2(data); + PUSH_ITER(1); + PUSH_TAG(); + + state = EXEC_TAG(); + if (state == 0) { + result = rb_yield(args); + } + + POP_TAG(); + POP_ITER(); + POP_BLOCK(); + + switch (state) { + case 0: + break; + case TAG_RETRY: + case IN_BLOCK|TAG_RETRY: + Fail("retry from block-closure"); + break; + case TAG_BREAK: + case IN_BLOCK|TAG_BREAK: + Fail("break from block-closure"); + break; + case TAG_RETURN: + case IN_BLOCK|TAG_RETURN: + Fail("return from block-closure"); + break; + default: + JUMP_TAG(state); + } + + return result; +} + +Init_Block() +{ + C_Block = rb_define_class("Block", C_Object); + + rb_define_single_method(C_Block, "new", Sblk_new, 0); + + rb_define_method(C_Block, "do", Fblk_do, -2); + blkdata = rb_intern("blk"); +} diff --git a/file.c b/file.c index 1fc344778e9fd0..8fd04bc8b10aa6 100644 --- a/file.c +++ b/file.c @@ -4,17 +4,17 @@ file.c - $Author: matz $ - $Date: 1994/12/06 09:30:00 $ + $Date: 1994/12/09 09:40:19 $ created at: Mon Nov 15 12:24:34 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto ************************************************/ +#include +#include #include "ruby.h" #include "io.h" -#include -#include #ifdef HAVE_UNISTD_H #include #endif diff --git a/gc.c b/gc.c index 5c1d27e553481d..780d1902f85fb5 100644 --- a/gc.c +++ b/gc.c @@ -3,7 +3,7 @@ gc.c - $Author: matz $ - $Date: 1994/12/06 09:30:02 $ + $Date: 1994/12/19 08:39:19 $ created at: Tue Oct 5 09:44:46 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -13,6 +13,7 @@ #include "ruby.h" #include "env.h" #include "st.h" +#include "node.h" #include #include @@ -166,7 +167,7 @@ rb_global_variable(var) struct RVALUE { union { struct { - UINT flag; /* alway 0 for freed obj */ + UINT flag; /* always 0 for freed obj */ struct RVALUE *next; } free; struct RObject object; @@ -179,6 +180,7 @@ struct RVALUE { struct RData data; struct RStruct rstruct; struct RBignum bignum; + struct RNode node; } as; } *freelist = Qnil; @@ -189,7 +191,7 @@ struct heap_block { struct RVALUE body[1]; } *heap_link = Qnil; -#define SEG_SLOTS 4000 +#define SEG_SLOTS 10000 #define SEG_SIZE (SEG_SLOTS*sizeof(struct RVALUE)) static int heap_size; @@ -252,53 +254,6 @@ data_new(datap, dfree, dmark) return (VALUE)data; } -static struct literal_list { - VALUE val; - struct literal_list *next; -} *Literal_List = Qnil; - -void -literalize(obj) - VALUE obj; -{ - struct literal_list *tmp; - - tmp = (struct literal_list*)xmalloc(sizeof(struct literal_list)); - tmp->next = Literal_List; - tmp->val = obj; - Literal_List = tmp; -} - -void -unliteralize(obj) - VALUE obj; -{ - struct literal_list *ptr = Literal_List, *tmp; - - if (NIL_P(obj) || FIXNUM_P(obj)) return; - - if (!FL_TEST(obj, FL_LITERAL)) return; - FL_UNSET(obj, FL_LITERAL); - - if (ptr->val == obj) { - Literal_List = ptr->next; - free(ptr); - return; - } - - while (ptr->next) { - if (ptr->next->val == obj) { - tmp = ptr->next; - ptr->next = ptr->next->next; - ptr = tmp; - free(tmp); - return; - } - ptr = ptr->next; - } - Bug("0x%x is not a literal object.", obj); -} - extern st_table *rb_class_tbl; static VALUE *stack_start_ptr; @@ -311,7 +266,7 @@ looks_pointerp(p) if (FIXNUM_P(p)) return FALSE; while (heap) { if (heap->beg <= p && p < heap->end - && ((((char*)p) - ((char*)heap->beg)) % sizeof(struct RVALUE)) == 0) + && ((((char*)p)-((char*)heap->beg))%sizeof(struct RVALUE)) == 0) return TRUE; heap = heap->next; } @@ -383,6 +338,15 @@ mark_dict(tbl) st_foreach(tbl, mark_dicentry, 0); } +void +gc_mark_maybe(obj) + void *obj; +{ + if (looks_pointerp(obj)) { + gc_mark(obj); + } +} + void gc_mark(obj) register struct RBasic *obj; @@ -400,19 +364,21 @@ gc_mark(obj) break; } - if (obj->iv_tbl) mark_tbl(obj->iv_tbl); - gc_mark(obj->class); switch (obj->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); break; + case T_CLASS: gc_mark(RCLASS(obj)->super); case T_MODULE: if (RCLASS(obj)->c_tbl) mark_tbl(RCLASS(obj)->c_tbl); + mark_tbl(RCLASS(obj)->m_tbl); gc_mark(RBASIC(obj)->class); break; + case T_ARRAY: { int i, len = RARRAY(obj)->len; @@ -422,20 +388,25 @@ gc_mark(obj) gc_mark(ptr[i]); } break; + case T_DICT: mark_dict(RDICT(obj)->tbl); break; + case T_STRING: if (RSTRING(obj)->orig) gc_mark(RSTRING(obj)->orig); break; + case T_DATA: if (RDATA(obj)->dmark) (*RDATA(obj)->dmark)(DATA_PTR(obj)); break; + case T_OBJECT: case T_REGEXP: case T_FLOAT: case T_BIGNUM: break; + case T_STRUCT: { int i, len = RSTRUCT(obj)->len; @@ -445,9 +416,23 @@ gc_mark(obj) gc_mark(ptr[i].value); } break; + + case T_CONS: + gc_mark(RCONS(obj)->car); + gc_mark(RCONS(obj)->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); + return; /* no need to mark class & tbl */ + default: Bug("gc_mark(): unknown data type %d", obj->flags & T_MASK); } + if (obj->iv_tbl) mark_tbl(obj->iv_tbl); + gc_mark(obj->class); } #define MIN_FREE_OBJ 512 @@ -509,15 +494,6 @@ gc_sweep() } } -static -freemethod(key, body) - ID key; - void *body; -{ - freenode(body); - return ST_CONTINUE; -} - static void obj_free(obj) struct RBasic *obj; @@ -529,14 +505,12 @@ obj_free(obj) break; } - if (obj->iv_tbl) st_free_table(obj->iv_tbl); switch (obj->flags & T_MASK) { case T_OBJECT: break; case T_MODULE: case T_CLASS: rb_clear_cache2(obj); - st_foreach(RCLASS(obj)->m_tbl, freemethod); st_free_table(RCLASS(obj)->m_tbl); if (RCLASS(obj)->c_tbl) st_free_table(RCLASS(obj)->c_tbl); @@ -569,15 +543,29 @@ obj_free(obj) case T_BIGNUM: free(RBIGNUM(obj)->digits); break; + case T_NODE: + if (nd_type(obj) == NODE_SCOPE && RNODE(obj)->nd_tbl) { + free(RNODE(obj)->nd_tbl); + } + return; /* no need to free iv_tbl */ default: Bug("gc_sweep(): unknown data type %d", obj->flags & T_MASK); } + if (obj->iv_tbl) st_free_table(obj->iv_tbl); +} + +void +gc_mark_scope(scope) + struct SCOPE *scope; +{ + if (scope->local_vars && scope->var_ary == Qnil) + mark_locations_array(scope->local_vars, scope->local_tbl[0]); + gc_mark(scope->var_ary); } void gc() { - struct literal_list *lit; struct gc_list *list; struct ENVIRON *env; struct SCOPE *scope; @@ -588,17 +576,9 @@ gc() if (dont_gc) return; dont_gc++; - /* mark env stack */ - for (env = the_env; env; env = env->prev) { - gc_mark(env->self); - if (env->argv) - mark_locations_array(env->argv, env->argc); - } - /* mark scope stack */ for (scope = the_scope; scope; scope = scope->prev) { - if (scope->local_vars) - mark_locations_array(scope->local_vars, scope->local_tbl[0]); + gc_mark_scope(scope); } FLUSH_REGISTER_WINDOWS; @@ -617,11 +597,6 @@ gc() gc_mark(*list->varptr); } - /* mark literal objects */ - for (lit = Literal_List; lit; lit = lit->next) { - gc_mark(lit->val); - } - gc_mark_global_tbl(); mark_tbl(rb_class_tbl); diff --git a/glob.c b/glob.c index bc4ad8aad0676d..74dfe52fddf044 100644 --- a/glob.c +++ b/glob.c @@ -2,15 +2,15 @@ glob.c - - $Author$ - $Date$ + $Author: matz $ + $Date: 1994/12/09 09:47:52 $ created at: Mon Sep 12 18:56:43 JST 1994 ************************************************/ +#include #include "ruby.h" #include "fnmatch.h" -#include char *strdup(); diff --git a/inits.c b/inits.c index 6b227fb4980d46..9a5b2083064461 100644 --- a/inits.c +++ b/inits.c @@ -3,7 +3,7 @@ inits.c - $Author: matz $ - $Date: 1994/11/01 08:28:00 $ + $Date: 1994/12/16 00:59:24 $ created at: Tue Dec 28 16:01:58 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -38,6 +38,7 @@ rb_call_inits() Init_process(); Init_Etc(); Init_load(); + Init_Block(); Init_Math(); #ifdef USE_DBM Init_DBM(); diff --git a/io.c b/io.c index 27563c2c6dd495..2b73d89253103d 100644 --- a/io.c +++ b/io.c @@ -3,7 +3,7 @@ io.c - $Author: matz $ - $Date: 1994/12/06 09:30:03 $ + $Date: 1994/12/19 08:30:05 $ created at: Fri Oct 15 18:08:59 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -561,8 +561,8 @@ pipe_open(pname, mode) MakeOpenFile(port, fptr); fptr->mode = io_mode_flags(mode); - if ((fptr->mode & FMODE_READABLE) && pipe(pr) == -1 || - (fptr->mode & FMODE_WRITABLE) && pipe(pw) == -1) + if (((fptr->mode & FMODE_READABLE) && pipe(pr) == -1) || + ((fptr->mode & FMODE_WRITABLE) && pipe(pw) == -1)) rb_sys_fail(Qnil); doexec = (strcmp("-", pname) != 0); @@ -1313,15 +1313,15 @@ Init_IO() C_IO = rb_define_class("IO", C_Object); rb_include_module(C_IO, M_Enumerable); - rb_define_variable("$;", &FS, Qnil, rb_check_str); - rb_define_variable("$,", &OFS, Qnil, rb_check_str); + rb_define_variable("$;", &FS, Qnil, rb_check_str, 0); + rb_define_variable("$,", &OFS, Qnil, rb_check_str, 0); RS = str_new2("\n"); - rb_define_variable("$/", &RS, Qnil, rb_check_str); - rb_define_variable("$\\", &ORS, Qnil, rb_check_str); + rb_define_variable("$/", &RS, Qnil, rb_check_str, 0); + rb_define_variable("$\\", &ORS, Qnil, rb_check_str, 0); - rb_define_variable("$.", &lineno, Qnil, Qnil); - rb_define_variable("$_", &rb_lastline, Qnil, Qnil); + rb_define_variable("$.", &lineno, Qnil, Qnil, 0); + rb_define_variable("$_", &rb_lastline, Qnil, Qnil, 0); rb_define_method(C_IO, "each", Fio_each, 0); rb_define_method(C_IO, "each_byte", Fio_each_byte, 0); @@ -1355,17 +1355,17 @@ Init_IO() rb_define_method(C_IO, "ioctl", Fio_ioctl, 2); rb_stdin = prep_stdio(stdin, FMODE_READABLE); - rb_define_variable("$stdin", &rb_stdin, Qnil, rb_readonly_hook); + rb_define_variable("$stdin", &rb_stdin, Qnil, rb_readonly_hook, 0); rb_stdout = prep_stdio(stdout, FMODE_WRITABLE); - rb_define_variable("$stdout", &rb_stdout, Qnil, rb_readonly_hook); + rb_define_variable("$stdout", &rb_stdout, Qnil, rb_readonly_hook, 0); rb_stderr = prep_stdio(stderr, FMODE_WRITABLE); - rb_define_variable("$stderr", &rb_stderr, Qnil, rb_readonly_hook); + rb_define_variable("$stderr", &rb_stderr, Qnil, rb_readonly_hook, 0); rb_defout = rb_stdout; - rb_define_variable("$>", &rb_defout, Qnil, io_defset); + rb_define_variable("$>", &rb_defout, Qnil, io_defset, 0); argf = obj_alloc(C_Object); - rb_define_variable("$<", &argf, Qnil, rb_readonly_hook); - rb_define_variable("$ARGF", &argf, Qnil, rb_readonly_hook); + rb_define_variable("$<", &argf, Qnil, rb_readonly_hook, 0); + rb_define_variable("$ARGF", &argf, Qnil, rb_readonly_hook, 0); rb_define_single_method(argf, "each", Farg_each, 0); rb_define_single_method(argf, "each_byte", Farg_each_byte, 0); @@ -1383,7 +1383,7 @@ Init_IO() rb_include_module(CLASS_OF(argf), M_Enumerable); filename = str_new2("-"); - rb_define_variable("$FILENAME", &filename, Qnil, rb_readonly_hook); + rb_define_variable("$FILENAME", &filename, Qnil, rb_readonly_hook, 0); file = rb_stdin; rb_global_variable(&file); diff --git a/methods.h b/methods.h deleted file mode 100644 index dffd70197cc75a..00000000000000 --- a/methods.h +++ /dev/null @@ -1,22 +0,0 @@ -/************************************************ - - methods.h - - - $Author: matz $ - $Revision: 1.2 $ - $Date: 1994/08/12 04:47:38 $ - created at: Fri Jul 29 14:43:03 JST 1994 - -************************************************/ -#ifndef METHOD_H -#define METHOD_H - -struct SMethod { - struct node *node; - struct RClass *origin; - ID id; - int count; - int undef; -}; - -#endif diff --git a/missing/strdup.c b/missing/strdup.c index 2e1fe90bbd74bb..875290c03f963d 100644 --- a/missing/strdup.c +++ b/missing/strdup.c @@ -2,8 +2,8 @@ strdup.c - - $Author$ - $Date$ + $Author: matz $ + $Date: 1994/12/09 09:47:57 $ created at: Wed Dec 7 15:34:01 JST 1994 ************************************************/ diff --git a/missing/strftime.c b/missing/strftime.c index 313b9d00a1e9d2..1e668ef2ae8ec2 100644 --- a/missing/strftime.c +++ b/missing/strftime.c @@ -39,7 +39,11 @@ #include #include -#include +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ #include #include #include diff --git a/node.h b/node.h index 608c78c28dc868..a032ee21760dec 100644 --- a/node.h +++ b/node.h @@ -3,7 +3,7 @@ node.h - $Author: matz $ - $Date: 1994/11/01 08:28:04 $ + $Date: 1994/12/16 03:10:04 $ created at: Fri May 28 15:14:02 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -36,7 +36,7 @@ enum node_type { NODE_IASGN, NODE_CASGN, NODE_CALL, - NODE_CALL2, + NODE_ICALL, NODE_SUPER, NODE_ZSUPER, NODE_ARRAY, @@ -50,6 +50,7 @@ enum node_type { NODE_RETRY, NODE_FAIL, NODE_YIELD, + NODE_IYIELD, NODE_LVAR, NODE_GVAR, NODE_IVAR, @@ -77,24 +78,24 @@ enum node_type { NODE_NIL, }; -typedef struct node { - enum node_type type; - char *src; +typedef struct RNode { + UINT flags; + char *file; unsigned int line; union { - struct node *node; + struct RNode *node; ID id; VALUE value; VALUE (*cfunc)(); ID *tbl; } u1; union { - struct node *node; + struct RNode *node; ID id; int argc; } u2; union { - struct node *node; + struct RNode *node; ID id; int state; struct global_entry *entry; @@ -103,8 +104,14 @@ typedef struct node { } u3; } NODE; +#define RNODE(obj) (R_CAST(RNode)(obj)) + +#define nd_type(n) (((n)->flags>>11)&0x3f) +#define nd_set_type(n,t) \ + (n)->flags=(((n)->flags&~FL_UMASK)|(((t)<<11)&FL_UMASK)) + #define nd_head u1.node -#define nd_last u2.node +#define nd_alen u2.argc #define nd_next u3.node #define nd_cond u1.node @@ -163,13 +170,13 @@ typedef struct node { #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,1) -#define NEW_DEFN(i,d,p) newnode(NODE_DEFN,p,i,NEW_FBODY(d,i)) -#define NEW_DEFS(r,i,d) newnode(NODE_DEFS,r,i,NEW_FBODY(d,i)) +#define NEW_FBODY(n,i) newnode(NODE_FBODY,n,i,Qnil) +#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) #define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2)) #define NEW_SCOPE(b) newnode(NODE_SCOPE,local_tbl(),(b),local_cnt(0)) -#define NEW_BLOCK(a) newnode(NODE_BLOCK,a,Qnil,Qnil) +#define NEW_BLOCK(a) newnode(NODE_BLOCK,a,1,Qnil) #define NEW_IF(c,t,e) newnode(NODE_IF,c,t,e) #define NEW_EXNOT(c) newnode(NODE_EXNOT,c,Qnil,Qnil) #define NEW_UNLESS(c,t,e) newnode(NODE_IF,NEW_EXNOT(c),t,e) @@ -190,8 +197,7 @@ typedef struct node { #define NEW_FAIL(s) newnode(NODE_FAIL,s,Qnil,Qnil) #define NEW_YIELD(a) newnode(NODE_YIELD,a,Qnil,Qnil) #define NEW_LIST(a) NEW_ARRAY(a) -#define NEW_QLIST(a) newnode(NODE_QLIST,a,Qnil,Qnil) -#define NEW_ARRAY(a) newnode(NODE_ARRAY,a,Qnil,Qnil) +#define NEW_ARRAY(a) newnode(NODE_ARRAY,a,1,Qnil) #define NEW_ZARRAY() newnode(NODE_ZARRAY,Qnil,Qnil,Qnil) #define NEW_HASH(a) newnode(NODE_HASH,a,Qnil,Qnil) #define NEW_AND(a,b) newnode(NODE_AND,a,b,Qnil) @@ -212,10 +218,9 @@ typedef struct node { #define NEW_XSTR(s) newnode(NODE_XSTR,s,Qnil,Qnil) #define NEW_XSTR2(s) newnode(NODE_XSTR2,s,Qnil,Qnil) #define NEW_CALL(r,m,a) newnode(NODE_CALL,r,m,a) -#define NEW_CALL2(r,m,a) newnode(NODE_CALL2,r,m,a) #define NEW_SUPER(a) newnode(NODE_SUPER,Qnil,Qnil,a) #define NEW_ZSUPER() newnode(NODE_ZSUPER,Qnil,Qnil,Qnil) -#define NEW_ARGS(f,r) newnode(NODE_ARGS,f,r,Qnil) +#define NEW_ARGS(f,r) newnode(NODE_ARGS,Qnil,r,f) #define NEW_ALIAS(n,o) newnode(NODE_ALIAS,Qnil,n,o) #define NEW_UNDEF(i) newnode(NODE_UNDEF,Qnil,i,Qnil) #define NEW_CLASS(n,b,s) newnode(NODE_CLASS,n,NEW_SCOPE(b),s) @@ -228,6 +233,5 @@ typedef struct node { NODE *newnode(); VALUE rb_method_booundp(); -void freenode(); #endif diff --git a/object.c b/object.c index decb070dca86e9..4fa7f109b0b206 100644 --- a/object.c +++ b/object.c @@ -3,7 +3,7 @@ object.c - $Author: matz $ - $Date: 1994/12/06 09:30:06 $ + $Date: 1994/12/19 08:30:07 $ created at: Thu Jul 15 12:01:24 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -412,7 +412,7 @@ Init_Object() rb_define_method(C_Kernel, "!", P_false, 0); rb_define_method(C_Kernel, "==", Fkrn_equal, 1); rb_define_alias(C_Kernel, "equal", "=="); - rb_define_method(C_Kernel, "hash", rb_self, 0); + rb_define_method(C_Kernel, "hash", Fkrn_id, 0); rb_define_method(C_Kernel, "id", Fkrn_id, 0); rb_define_method(C_Kernel, "class", Fkrn_class, 0); rb_define_method(C_Kernel, "!=", Fkrn_noteq, 1); @@ -444,7 +444,7 @@ Init_Object() C_Nil = rb_define_class("Nil", C_Kernel); rb_define_method(C_Nil, "to_s", Fnil_to_s, 0); - rb_define_method(C_Nil, "clone", rb_self, 0); + rb_define_method(C_Nil, "clone", P_false, 0); rb_define_method(C_Nil, "class", Fnil_class, 0); rb_define_method(C_Nil, "is_nil", P_true, 0); diff --git a/pack.c b/pack.c index af7f8c274d0c36..e0c6e673d398cc 100644 --- a/pack.c +++ b/pack.c @@ -3,7 +3,7 @@ pack.c - $Author: matz $ - $Date: 1994/12/06 09:30:08 $ + $Date: 1994/12/09 09:40:22 $ created at: Thu Feb 10 15:17:05 JST 1994 Copyright (C) 1994 Yukihiro Matsumoto @@ -462,8 +462,8 @@ encodes(str, s, len) str_cat(str, hunk, 1); while (len > 0) { hunk[0] = ' ' + (077 & (*s >> 2)); - hunk[1] = ' ' + (077 & ((*s << 4) & 060 | (s[1] >> 4) & 017)); - hunk[2] = ' ' + (077 & ((s[1] << 2) & 074 | (s[2] >> 6) & 03)); + hunk[1] = ' ' + (077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))); + hunk[2] = ' ' + (077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))); hunk[3] = ' ' + (077 & (s[2] & 077)); str_cat(str, hunk, 4); s += 3; diff --git a/parse.y b/parse.y index 5fc35a504120fe..ec5030f1f10061 100644 --- a/parse.y +++ b/parse.y @@ -3,7 +3,7 @@ parse.y - $Author: matz $ - $Date: 1994/12/06 09:30:09 $ + $Date: 1994/12/19 08:30:08 $ created at: Fri May 28 18:02:42 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -79,9 +79,10 @@ static void setup_top_local(); %} %union { - struct node *node; + NODE *node; VALUE val; ID id; + int num; } %token CLASS @@ -130,11 +131,11 @@ static void setup_top_local(); %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 f_arglist f_args f_arg assoc_list assocs assoc +%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 %type fname op rest_arg - +%type f_arg %token UPLUS /* unary+ */ %token UMINUS /* unary- */ %token POW /* ** */ @@ -149,7 +150,7 @@ static void setup_top_local(); %token AREF ASET /* [] and []= */ %token LSHFT RSHFT /* << and >> */ %token COLON2 /* :: */ -%token SELF_ASGN /* +=, -= etc. */ +%token OP_ASGN /* +=, -= etc. */ %token ASSOC /* => */ %token LPAREN LBRACK LBRACE @@ -158,7 +159,7 @@ static void setup_top_local(); */ %left YIELD RETURN FAIL -%right '=' SELF_ASGN +%right '=' OP_ASGN %right COLON2 %nonassoc DOT2 DOT3 %left OR @@ -477,24 +478,16 @@ op : COLON2 { $$ = COLON2; } f_arglist : '(' f_args rparen { - if ($2) { - NODE *list = $2->nd_frml; - int i; - - for (i=0; list; list=list->nd_next, i++) - ; - $2->nd_cnt = i; - } $$ = $2; } | term { - $$ = Qnil; + $$ = NEW_ARGS(0, -1); } f_args : /* no arg */ { - $$ = Qnil; + $$ = NEW_ARGS(0, -1); } | f_arg { @@ -516,20 +509,22 @@ f_args : /* no arg */ | error { lex_state = EXPR_BEG; - $$ = Qnil; + $$ = NEW_ARGS(0, -1); } f_arg : IDENTIFIER { if (!is_local_id($1)) Error("formal argument must be local variable"); - $$ = NEW_QLIST(local_cnt($1)); + local_cnt($1); + $$ = 1; } | f_arg comma IDENTIFIER { if (!is_local_id($3)) Error("formal argument must be local variable"); - $$ = list_append($1, local_cnt($3)); + local_cnt($3); + $$ += 1; } rest_arg : '*' IDENTIFIER @@ -541,12 +536,11 @@ rest_arg : '*' IDENTIFIER singleton : var_ref { - if ($1->type == NODE_SELF) { + if (nd_type($1) == NODE_SELF) { $$ = NEW_SELF(); } - else if ($1->type == NODE_NIL) { + else if (nd_type($1) == NODE_NIL) { Error("Can't define single method for nil."); - freenode($1); $$ = Qnil; } else { @@ -555,7 +549,7 @@ singleton : var_ref } | LPAREN compstmts rparen { - switch ($2->type) { + switch (nd_type($2)) { case NODE_STR: case NODE_LIT: case NODE_ARRAY: @@ -582,7 +576,7 @@ expr : variable '=' expr value_expr($5); $$ = attrset($1, $3, $5); } - | variable SELF_ASGN expr + | variable OP_ASGN expr { NODE *val; @@ -601,19 +595,19 @@ expr : variable '=' expr } $$ = asignable($1, call_op(val, $2, 1, $3)); } - | expr0 '[' args rbracket SELF_ASGN expr + | expr0 '[' args rbracket OP_ASGN expr { NODE *rval, *args; value_expr($1); value_expr($6); args = list_copy($3); - rval = NEW_CALL2($1, AREF, args); + rval = NEW_CALL($1, AREF, args); args = list_append($3, call_op(rval, $5, 1, $6)); $$ = NEW_CALL($1, ASET, args); } - | expr0 '.' IDENTIFIER SELF_ASGN expr + | expr0 '.' IDENTIFIER OP_ASGN expr { ID id = $3; NODE *rval; @@ -624,7 +618,7 @@ expr : variable '=' expr id &= ~ID_SCOPE_MASK; id |= ID_ATTRSET; - rval = call_op(NEW_CALL2($1, $3, Qnil), $4, 1, $5); + rval = call_op(NEW_CALL($1, $3, Qnil), $4, 1, $5); $$ = NEW_CALL($1, id, NEW_LIST(rval)); } | expr DOT2 expr @@ -639,12 +633,12 @@ expr : variable '=' expr { $$ = Qnil; if ($1 && $3 - && ($3->type == NODE_LIT || $3->type == NODE_STR) - && $1->type == NODE_CALL && $1->nd_mid == '+') { + && (nd_type($3) == NODE_LIT || nd_type($3) == NODE_STR) + && nd_type($1) == NODE_CALL && $1->nd_mid == '+') { if ($1->nd_args->nd_head == Qnil) Bug("bad operand for `+'"); - if ($1->nd_args->nd_head->type == NODE_LIT - || $1->nd_args->nd_head->type == NODE_STR) { + if (nd_type($1->nd_args->nd_head) == NODE_LIT + || nd_type($1->nd_args->nd_head) == NODE_STR) { $1->nd_args->nd_head = expand_op($1->nd_args->nd_head, '+', $3); $$ = $1; @@ -737,8 +731,8 @@ expr : variable '=' expr | '~' expr { if ($2 - && ($2->type == NODE_STR - || ($2->type == NODE_LIT + && (nd_type($2) == NODE_STR + || (nd_type($2) == NODE_LIT && (TYPE($2->nd_lit) == T_REGEXP || TYPE($2->nd_lit) == T_STRING)))) { $$ = NEW_CALL($2, '~', Qnil); @@ -761,11 +755,11 @@ expr : variable '=' expr } | expr AND expr { - $$ = NEW_AND($1, $3); + $$ = NEW_AND(cond($1), cond($3)); } | expr OR expr { - $$ = NEW_OR($1, $3); + $$ = NEW_OR(cond($1), cond($3)); } |expr0 { @@ -811,7 +805,6 @@ args2 : args if ($1 && $1->nd_next == Qnil) { $$ = $1->nd_head; - free($1); } else { $$ = $1; @@ -820,18 +813,15 @@ args2 : args expr0 : literal { - literalize($1); $$ = NEW_LIT($1); } | STRING { - literalize($1); $$ = NEW_STR($1); } | STRING2 | XSTRING { - literalize($1); $$ = NEW_XSTR($1); } | XSTRING2 @@ -900,6 +890,28 @@ expr0 : literal } | expr0 lbrace 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; + } $$ = NEW_ITER($3, $1, $5); } | expr0 '.' IDENTIFIER '(' call_args rparen @@ -1218,10 +1230,9 @@ parse_regx() if (list) { if (toklen() > 0) { VALUE ss = str_new(tok(), toklen()); - literalize(ss); list_append(list, NEW_STR(ss)); } - list->type = NODE_DREGX; + nd_set_type(list, NODE_DREGX); yylval.node = list; return DREGEXP; } @@ -1301,12 +1312,11 @@ parse_string(term) else { if (toklen() > 0) { VALUE ss = str_new(tok(), toklen()); - literalize(ss); list_append(list, NEW_STR(ss)); } yylval.node = list; if (term == '`') { - list->type = NODE_XSTR2; + nd_set_type(list, NODE_XSTR2); return XSTRING2; } else { @@ -1395,14 +1405,14 @@ retry: if ((c = nextc()) == '*') { if (nextc() == '=') { yylval.id = POW; - return SELF_ASGN; + return OP_ASGN; } pushback(); return POW; } else if (c == '=') { yylval.id = '*'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return '*'; @@ -1445,7 +1455,7 @@ retry: yylval.val = glob_new(yylval.val); return GLOB; } - yylval.node->type = NODE_DGLOB; + nd_set_type(yylval.node, NODE_DGLOB); return DGLOB; } lex_state = EXPR_BEG; @@ -1459,7 +1469,7 @@ retry: if (c == '<') { if (nextc() == '=') { yylval.id = LSHFT; - return SELF_ASGN; + return OP_ASGN; } pushback(); return LSHFT; @@ -1475,7 +1485,7 @@ retry: if (c == '>') { if (nextc() == '=') { yylval.id = RSHFT; - return SELF_ASGN; + return OP_ASGN; } pushback(); return RSHFT; @@ -1550,7 +1560,7 @@ retry: } else if (c == '=') { yylval.id = '&'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return '&'; @@ -1562,7 +1572,7 @@ retry: } else if (c == '=') { yylval.id = '|'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return '|'; @@ -1587,7 +1597,7 @@ retry: lex_state = EXPR_BEG; if ((c = nextc()) == '=') { yylval.id = '+'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return '+'; @@ -1613,7 +1623,7 @@ retry: lex_state = EXPR_BEG; if ((c = nextc()) == '=') { yylval.id = '-'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return '-'; @@ -1753,7 +1763,7 @@ retry: lex_state = EXPR_BEG; if (nextc() == '=') { yylval.id = '/'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return c; @@ -1762,7 +1772,7 @@ retry: lex_state = EXPR_BEG; if (nextc() == '=') { yylval.id = '^'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return c; @@ -1830,7 +1840,7 @@ retry: lex_state = EXPR_BEG; if (nextc() == '=') { yylval.id = '%'; - return SELF_ASGN; + return OP_ASGN; } pushback(); return c; @@ -1984,11 +1994,9 @@ var_extend(list, term) ss = str_new(tok(), toklen()); if (list == Qnil) { - literalize(ss); list = NEW_STR2(ss); } else if (toklen() > 0) { - literalize(ss); list_append(list, NEW_STR(ss)); } newtok(); @@ -2079,8 +2087,8 @@ read_escape(flag) tokadd('\13'); break; - case 'a': - tokadd('\a'); + case 'a': /* alarm(bell) */ + tokadd('\1'); break; case 'e': /* escape */ @@ -2184,11 +2192,12 @@ newnode(type, a0, a1, a2) enum node_type type; NODE *a0, *a1, *a2; { - NODE *n = ALLOC(NODE); + NODE *n = (NODE*)newobj(); - n->type = type; + n->flags |= T_NODE; + nd_set_type(n, type); n->line = sourceline; - n->src = sourcefile; + n->file = sourcefile; n->u1.node = a0; n->u2.node = a1; @@ -2197,22 +2206,34 @@ newnode(type, a0, a1, a2) return n; } +enum node_type +nodetype(node) /* for debug */ + NODE *node; +{ + return (enum node_type)nd_type(node); +} + static NODE* block_append(head, tail) NODE *head, *tail; { extern int verbose; + NODE *last; if (tail == Qnil) return head; if (head == Qnil) return tail; - if (head->type != NODE_BLOCK) - head = NEW_BLOCK(head); - - if (head->nd_last == Qnil) head->nd_last = head; + if (nd_type(head) != NODE_BLOCK) + head = last = NEW_BLOCK(head); + else { + last = head; + while (last->nd_next) { + last = last->nd_next; + } + } if (verbose) { - switch (head->nd_last->nd_head->type) { + switch (nd_type(last->nd_head)) { case NODE_BREAK: case NODE_CONTINUE: case NODE_REDO: @@ -2226,14 +2247,11 @@ block_append(head, tail) } } - if (tail->type == NODE_BLOCK) { - head->nd_last->nd_next = tail; - head->nd_last = tail->nd_last; - } - else { - head->nd_last->nd_next = NEW_BLOCK(tail); - head->nd_last = head->nd_last->nd_next; + if (nd_type(tail) != NODE_BLOCK) { + tail = NEW_BLOCK(tail); } + last->nd_next = tail; + head->nd_alen += tail->nd_alen; return head; } @@ -2241,13 +2259,17 @@ static NODE* list_append(head, tail) NODE *head, *tail; { + NODE *last; + if (head == Qnil) return NEW_LIST(tail); - if (head->nd_last == Qnil) head->nd_last = head; + last = head; + while (last->nd_next) { + last = last->nd_next; + } - head->nd_last->nd_next = - head->type == NODE_QLIST?NEW_QLIST(tail):NEW_LIST(tail); - head->nd_last = head->nd_last->nd_next; + last->nd_next = NEW_LIST(tail); + head->nd_alen += 1; return head; } @@ -2257,12 +2279,16 @@ list_concat(head, tail) { NODE *last; - if (head->type != NODE_ARRAY || tail->type != NODE_ARRAY) + if (nd_type(head) != NODE_ARRAY || nd_type(tail) != NODE_ARRAY) Bug("list_concat() called with non-list"); - last = (head->nd_last)?head->nd_last:head; + last = head; + while (last->nd_next) { + last = last->nd_next; + } + last->nd_next = tail; - head->nd_last = tail->nd_last; + head->nd_alen += tail->nd_alen; return head; } @@ -2283,140 +2309,6 @@ list_copy(list) return tmp; } -void freenode(node) - NODE *node; -{ - if (node == Qnil) return; - - switch (node->type) { - case NODE_FBODY: - node->nd_cnt--; - if (node->nd_cnt > 0) return; - freenode(node->nd_head); - break; - case NODE_BLOCK: - case NODE_ARRAY: - freenode(node->nd_head); - case NODE_STR2: - case NODE_XSTR2: - case NODE_DREGX: - case NODE_DGLOB: - case NODE_QLIST: - freenode(node->nd_next); - break; - case NODE_HASH: - freenode(node->nd_head); - break; - case NODE_EXNOT: - freenode(node->nd_cond); - break; - case NODE_IF: - case NODE_WHEN: - case NODE_PROT: - freenode(node->nd_cond); - freenode(node->nd_body); - freenode(node->nd_else); - break; - case NODE_CASE: - case NODE_WHILE: - case NODE_WHILE2: - case NODE_AND: - case NODE_OR: - freenode(node->nd_head); - freenode(node->nd_body); - break; - case NODE_ITER: - case NODE_FOR: - freenode(node->nd_var); - freenode(node->nd_ibdy); - freenode(node->nd_iter); - break; - case NODE_LASGN: - case NODE_GASGN: - case NODE_IASGN: - case NODE_CASGN: - freenode(node->nd_value); - break; - case NODE_MASGN: - freenode(node->nd_value); - freenode(node->nd_head); - freenode(node->nd_args); - break; - case NODE_CALL: - case NODE_SUPER: - freenode(node->nd_recv); - freenode(node->nd_args); - break; - case NODE_CALL2: - { - NODE *list = node->nd_next, *tmp; - while (list) { - tmp = list; - list = list->nd_next; - free(tmp); - } - } - break; - case NODE_DEFS: - freenode(node->nd_recv); - case NODE_DEFN: - freenode(node->nd_defn); - break; - case NODE_RETURN: - case NODE_YIELD: - case NODE_FAIL: - freenode(node->nd_stts); - break; - case NODE_STR: - case NODE_XSTR: - case NODE_LIT: - unliteralize(node->nd_lit); - break; - case NODE_ARGS: - freenode(node->nd_frml); - break; - case NODE_SCOPE: - if (node->nd_tbl) free(node->nd_tbl); - freenode(node->nd_body); - break; - case NODE_DOT3: - freenode(node->nd_beg); - freenode(node->nd_end); - break; - case NODE_CLASS: - case NODE_MODULE: - case NODE_METHOD: - freenode(node->nd_body); - break; - case NODE_CONST: - unliteralize(node->nd_cval); - break; - case NODE_ATTRSET: - case NODE_CVAR: - case NODE_ZSUPER: - case NODE_ZARRAY: - case NODE_CFUNC: - case NODE_BREAK: - case NODE_CONTINUE: - case NODE_REDO: - case NODE_RETRY: - case NODE_LVAR: - case NODE_GVAR: - case NODE_IVAR: - case NODE_MVAR: - case NODE_INC: - case NODE_UNDEF: - case NODE_ALIAS: - case NODE_NIL: - case NODE_SELF: - break; - default: - Bug("freenode: unknown node type %d", node->type); - break; - } - free(node); -} - struct call_arg { ID id; VALUE recv; @@ -2462,8 +2354,6 @@ expand_op(recv, id, arg) result = NEW_LIT(val); } - freenode(recv); - if (arg) freenode(arg); return result; } @@ -2479,8 +2369,8 @@ call_op(recv, id, narg, arg1) value_expr(arg1); } - if ((recv->type == NODE_LIT || recv->type == NODE_STR) - && (narg == 0 || (arg1->type == NODE_LIT || arg1->type == NODE_STR))) { + if ((nd_type(recv) == NODE_LIT || nd_type(recv) == NODE_STR) + && (narg == 0 || (nd_type(arg1) == NODE_LIT || nd_type(arg1) == NODE_STR))) { return expand_op(recv, id, (narg == 1)?arg1:Qnil); } return NEW_CALL(recv, id, narg==1?NEW_LIST(arg1):Qnil); @@ -2502,7 +2392,6 @@ gettable(id) else if (id == _FILE_) { VALUE s = str_new2(sourcefile); - literalize(s); return NEW_STR(s); } else if (is_local_id(id)) { @@ -2587,7 +2476,7 @@ value_expr(node) { if (node == Qnil) return; - switch (node->type) { + switch (nd_type(node)) { case NODE_RETURN: case NODE_CONTINUE: case NODE_BREAK: @@ -2602,8 +2491,12 @@ value_expr(node) break; case NODE_BLOCK: - if (node->nd_last) - value_expr(node->nd_last->nd_head); + while (node->nd_next) { + node = node->nd_next; + } + if (node) { + value_expr(node->nd_head); + } break; default: @@ -2615,7 +2508,7 @@ static NODE* cond0(node) NODE *node; { - enum node_type type = node->type; + enum node_type type = nd_type(node); if (type == NODE_STR || type == NODE_STR2 || type == NODE_DREGX) { return call_op(NEW_GVAR(rb_intern("$_")),MATCH,1,node); @@ -2630,16 +2523,12 @@ static NODE* cond(node) NODE *node; { - enum node_type type = node->type; + enum node_type type = nd_type(node); value_expr(node); node = cond0(node); - if (type == NODE_AND || type == NODE_OR) { - node->nd_1st = cond(node->nd_1st); - node->nd_2nd = cond(node->nd_2nd); - } - else if (type == NODE_CALL && node->nd_mid == '!') { + if (type == NODE_CALL && node->nd_mid == '!') { if (node->nd_args || node->nd_recv == Qnil) { Bug("method `!' called with wrong # of operand"); } @@ -2653,7 +2542,7 @@ cond2(node) NODE *node; { node = cond(node); - if (node->type == NODE_LIT && FIXNUM_P(node->nd_lit)) { + if (nd_type(node) == NODE_LIT && FIXNUM_P(node->nd_lit)) { return call_op(node,EQ,1,NEW_GVAR(rb_intern("$."))); } return node; @@ -2664,7 +2553,7 @@ st_table *new_idhash(); static struct local_vars { ID *tbl; int cnt; - struct local_vars *next; + struct local_vars *prev; } *lvtbl; static void @@ -2673,7 +2562,7 @@ push_local() struct local_vars *local; local = ALLOC(struct local_vars); - local->next = lvtbl; + local->prev = lvtbl; local->cnt = 0; local->tbl = Qnil; lvtbl = local; @@ -2684,7 +2573,7 @@ pop_local() { struct local_vars *local = lvtbl; - lvtbl = local->next; + lvtbl = local->prev; if (local->tbl) local->tbl[0] = local->cnt; free(local); } @@ -2749,22 +2638,28 @@ setup_top_local() { if (lvtbl->cnt > 0) { if (the_scope->local_vars == Qnil) { - the_scope->local_vars = ALLOC_N(VALUE, lvtbl->cnt); + 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; + int i, len; - if (the_scope->flags&VARS_MALLOCED) { - REALLOC_N(the_scope->local_vars, VALUE, lvtbl->cnt); + if (the_scope->var_ary) { + for (i=0, len=lvtbl->cnt-lvtbl->tbl[0];ivar_ary, Qnil); + } } else { VALUE *vars = the_scope->local_vars; - the_scope->local_vars = ALLOC_N(VALUE, lvtbl->cnt); + + 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); - the_scope->flags |= VARS_MALLOCED; + memset(the_scope->local_vars+i, 0, lvtbl->cnt-i); + RARRAY(the_scope->var_ary)->len = lvtbl->cnt; } - memset(the_scope->local_vars+i, 0, lvtbl->cnt-i); } lvtbl->tbl[0] = lvtbl->cnt; the_scope->local_tbl = lvtbl->tbl; @@ -2999,3 +2894,4 @@ rb_class2name(class) } Bug("class 0x%x not named", class); } + diff --git a/process.c b/process.c index c4e46e052189e6..e0eb41965cac8b 100644 --- a/process.c +++ b/process.c @@ -3,7 +3,7 @@ process.c - $Author: matz $ - $Date: 1994/12/06 09:30:11 $ + $Date: 1994/12/19 08:30:10 $ created at: Tue Aug 10 14:30:50 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -905,8 +905,8 @@ Init_process() { extern VALUE C_Kernel; - rb_define_variable("$$", Qnil, get_pid, Qnil); - rb_define_variable("$?", &status, Qnil, rb_readonly_hook); + rb_define_variable("$$", Qnil, get_pid, Qnil, 0); + rb_define_variable("$?", &status, Qnil, rb_readonly_hook, 0); rb_define_private_method(C_Kernel, "exec", Fexec, 1); rb_define_private_method(C_Kernel, "fork", Ffork, 0); rb_define_private_method(C_Kernel, "_exit", Ffork, 1); diff --git a/re.c b/re.c index ce79c9093ca18b..06770ab71c9a77 100644 --- a/re.c +++ b/re.c @@ -3,7 +3,7 @@ re.c - $Author: matz $ - $Date: 1994/12/06 09:30:14 $ + $Date: 1994/12/19 08:30:12 $ created at: Mon Aug 9 18:24:49 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -135,8 +135,8 @@ research(reg, str, start, ignorecase) { int result; - if (FL_TEST(reg, FL_USER0)) { /* case-flag set for the object */ - ignorecase = FL_TEST(reg, FL_USER1); /* case-flag */ + if (FL_TEST(reg, FL_USER1)) { /* case-flag set for the object */ + ignorecase = FL_TEST(reg, FL_USER2); /* case-flag */ } if (ignorecase) reg->ptr->pat.translate = casetable; @@ -233,24 +233,13 @@ re_match_last() return nth_match(i); } -#ifdef __STDC__ -#define CONCAT(a,b) a##b -#else -#define CONCAT(a,b) a/**/b -#endif - -#define GET_MATCH(n) CONCAT(get_macth,n) -#define GET_MATCH_FUNC(n) GET_MATCH(n)(id) ID id; { return nth_match(n); } - -GET_MATCH_FUNC(1); -GET_MATCH_FUNC(2); -GET_MATCH_FUNC(3); -GET_MATCH_FUNC(4); -GET_MATCH_FUNC(5); -GET_MATCH_FUNC(6); -GET_MATCH_FUNC(7); -GET_MATCH_FUNC(8); -GET_MATCH_FUNC(9); +static VALUE +get_match_data(id, nth) + ID id; + int nth; +{ + return nth_match(nth); +} static VALUE store_match_data(val) @@ -374,12 +363,12 @@ Sreg_new(argc, argv) } if (argc == 2) { - FL_SET(reg, FL_USER0); + FL_SET(reg, FL_USER1); if (argv[1]) { - FL_SET(reg, FL_USER1); + FL_SET(reg, FL_USER2); } else { - FL_UNSET(reg, FL_USER1); + FL_UNSET(reg, FL_USER2); } } @@ -507,26 +496,26 @@ Init_Regexp() | RE_NO_BK_CURLY_BRACES | RE_MBCTYPE_EUC; - rb_define_variable("$~", last_match_data, Qnil, store_match_data); + rb_define_variable("$~", last_match_data, Qnil, store_match_data, 0); - rb_define_variable("$&", Qnil, re_last_match, Qnil); - rb_define_variable("$`", Qnil, re_match_pre, Qnil); - rb_define_variable("$'", Qnil, re_match_post, Qnil); - rb_define_variable("$+", Qnil, re_match_last, Qnil); + rb_define_variable("$&", Qnil, re_last_match, Qnil, 0); + rb_define_variable("$`", Qnil, re_match_pre, Qnil, 0); + rb_define_variable("$'", Qnil, re_match_post, Qnil, 0); + rb_define_variable("$+", Qnil, re_match_last, Qnil, 0); - rb_define_variable("$1", Qnil, GET_MATCH(1), Qnil); - rb_define_variable("$2", Qnil, GET_MATCH(2), Qnil); - rb_define_variable("$3", Qnil, GET_MATCH(3), Qnil); - rb_define_variable("$4", Qnil, GET_MATCH(4), Qnil); - rb_define_variable("$5", Qnil, GET_MATCH(5), Qnil); - rb_define_variable("$6", Qnil, GET_MATCH(6), Qnil); - rb_define_variable("$7", Qnil, GET_MATCH(7), Qnil); - rb_define_variable("$8", Qnil, GET_MATCH(8), Qnil); - rb_define_variable("$9", Qnil, GET_MATCH(9), Qnil); + rb_define_variable("$1", Qnil, get_match_data, Qnil, 1); + rb_define_variable("$2", Qnil, get_match_data, Qnil, 2); + rb_define_variable("$3", Qnil, get_match_data, Qnil, 3); + rb_define_variable("$4", Qnil, get_match_data, Qnil, 4); + rb_define_variable("$5", Qnil, get_match_data, Qnil, 5); + rb_define_variable("$6", Qnil, get_match_data, Qnil, 6); + rb_define_variable("$7", Qnil, get_match_data, Qnil, 7); + rb_define_variable("$8", Qnil, get_match_data, Qnil, 8); + rb_define_variable("$9", Qnil, get_match_data, Qnil, 9); - rb_define_variable("$KANJI", Qnil, kanji_var_get, kanji_var_set); + rb_define_variable("$KANJI", Qnil, kanji_var_get, kanji_var_set, 0); - rb_define_variable("$=", &ignorecase, Qnil, Qnil); + rb_define_variable("$=", &ignorecase, Qnil, Qnil, 0); C_Regexp = rb_define_class("Regexp", C_Object); rb_define_single_method(C_Regexp, "new", Sreg_new, -1); diff --git a/ruby.c b/ruby.c index cb5f8c68b64cc3..b4212a3a16acee 100644 --- a/ruby.c +++ b/ruby.c @@ -3,7 +3,7 @@ ruby.c - $Author: matz $ - $Date: 1994/12/06 09:30:15 $ + $Date: 1994/12/19 08:30:13 $ created at: Tue Aug 10 12:47:31 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -395,10 +395,10 @@ ruby_init0(argc, argv, envp) rb_call_inits(); - rb_define_variable("$@", &errat, Qnil, Qnil); + rb_define_variable("$@", &errat, Qnil, Qnil, 0); errat = str_new2(argv[0]); - rb_define_variable("$VERBOSE", &verbose, Qnil, Qnil); - rb_define_variable("$DEBUG", &debug, Qnil, Qnil); + rb_define_variable("$VERBOSE", &verbose, Qnil, Qnil, 0); + rb_define_variable("$DEBUG", &debug, Qnil, Qnil, 0); #ifdef USE_DLN rb_dln_argv0 = argv[0]; @@ -416,11 +416,11 @@ ruby_init0(argc, argv, envp) yywhole_loop(do_line, do_split); } - rb_define_variable("$0", &Progname, Qnil, set_arg0); + rb_define_variable("$0", &Progname, Qnil, set_arg0, 0); ruby_script(script); - rb_define_variable("$ARGV", &Argv, Qnil, Qnil); - rb_define_variable("$*", &Argv, Qnil, Qnil); + rb_define_variable("$ARGV", &Argv, Qnil, Qnil, 0); + rb_define_variable("$*", &Argv, Qnil, Qnil, 0); Argv = ary_new2(argc); for (i=0; i < argc; i++) { ary_push(Argv, str_new2(argv[i])); diff --git a/ruby.h b/ruby.h index f513557b976e83..d20ed77a94894b 100644 --- a/ruby.h +++ b/ruby.h @@ -1,14 +1,14 @@ /************************************************ - + ruby.h - - + $Author: matz $ - $Date: 1994/12/06 09:30:16 $ + $Date: 1994/12/19 08:30:14 $ created at: Thu Jun 10 14:26:32 JST 1993 - + Copyright (C) 1994 Yukihiro Matsumoto - -************************************************/ + + ************************************************/ #ifndef RUBY_H #define RUBY_H @@ -29,12 +29,16 @@ typedef unsigned int UINT; typedef UINT VALUE; typedef UINT ID; + typedef unsigned short USHORT; + #ifdef __STDC__ # include #else # ifndef LONG_MAX -# define LONG_MAX ((long)((unsigned long)~0L>>1)) +# if !defined(LONG_MAX) || !defined(CHAR_BIT) +# include +# endif # endif # ifndef LONG_MIN # if (0 != ~0) @@ -83,22 +87,26 @@ extern VALUE C_Data; #define CLASS_OF(obj) (FIXNUM_P(obj)?C_Fixnum: NIL_P(obj)?C_Nil:\ RBASIC(obj)->class) -#define T_NIL 0x0 -#define T_OBJECT 0x1 -#define T_CLASS 0x2 -#define T_ICLASS 0x3 -#define T_MODULE 0x4 -#define T_FLOAT 0x5 -#define T_STRING 0x6 -#define T_REGEXP 0x7 -#define T_ARRAY 0x8 -#define T_FIXNUM 0x9 -#define T_DICT 0xA -#define T_DATA 0xB -#define T_STRUCT 0xC -#define T_BIGNUM 0xD - -#define T_MASK 0xF +#define T_NIL 0x00 +#define T_OBJECT 0x01 +#define T_CLASS 0x02 +#define T_ICLASS 0x03 +#define T_MODULE 0x04 +#define T_FLOAT 0x05 +#define T_STRING 0x06 +#define T_REGEXP 0x07 +#define T_ARRAY 0x08 +#define T_FIXNUM 0x09 +#define T_DICT 0x0a +#define T_STRUCT 0x0b +#define T_BIGNUM 0x0c + +#define T_NODE 0x0d +#define T_CONS 0x0e + +#define T_DATA 0xff + +#define T_MASK 0xff #define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK) #define TYPE(x) (FIXNUM_P(x)?T_FIXNUM:NIL_P(x)?T_NIL:BUILTIN_TYPE(x)) @@ -115,7 +123,7 @@ int num2int(); } #define CLONESETUP(obj1,obj2) \ OBJSETUP(obj1,RBASIC(obj2)->class,RBASIC(obj2)->flags&T_MASK); - + struct RBasic { UINT flags; VALUE class; @@ -208,6 +216,11 @@ struct RBignum { USHORT *digits; }; +struct RCons { + struct RBasic basic; + VALUE car, cdr; +}; + #define R_CAST(st) (struct st*) #define RBASIC(obj) (R_CAST(RBasic)(obj)) #define ROBJECT(obj) (R_CAST(RObject)(obj)) @@ -220,24 +233,28 @@ struct RBignum { #define RDATA(obj) (R_CAST(RData)(obj)) #define RSTRUCT(obj) (R_CAST(RStruct)(obj)) #define RBIGNUM(obj) (R_CAST(RBignum)(obj)) +#define RCONS(obj) (R_CAST(RCons)(obj)) + +#define FL_SINGLE (1<<8) +#define FL_MARK (1<<9) +#define FL_LITERAL (1<<10) -#define FL_SINGLE (1<<4) -#define FL_MARK (1<<5) -#define FL_LITERAL (1<<6) +#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_USER0 (1<<7) -#define FL_USER1 (1<<8) -#define FL_USER2 (1<<9) -#define FL_USER3 (1<<10) +#define FL_UMASK (0x3f<<11) #define FL_ABLE(x) (!(FIXNUM_P(x)||NIL_P(x))) #define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0) #define FL_SET(x,f) if (FL_ABLE(x)) {RBASIC(x)->flags |= (f);} #define FL_UNSET(x,f) if(FL_ABLE(x)){RBASIC(x)->flags &= ~(f);} -extern VALUE rb_self(); -#define Qself rb_self() -#define Qnil (VALUE)0 +extern VALUE Qself; +#define Qnil 0 #define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n)) #define ALLOC(type) (type*)xmalloc(sizeof(type)) diff --git a/sample/blk.rb b/sample/blk.rb new file mode 100644 index 00000000000000..4e618bce2d2943 --- /dev/null +++ b/sample/blk.rb @@ -0,0 +1,9 @@ +def foo() + $block = Block.new +end + +foo(){i | print "i = ", i, "\n"} +$block.do(2) + +foo(){i | print "i*2 = ", i*2, "\n"} +$block.do(2) diff --git a/sample/export.rb b/sample/export.rb index ea6c5aeaebe8d2..4046a7ec49f6ef 100644 --- a/sample/export.rb +++ b/sample/export.rb @@ -1,4 +1,4 @@ -# methos access permission +# methods access permission # output: # foobar # foo diff --git a/spec b/spec index ee23c704cdf951..93186dff2eaa05 100644 --- a/spec +++ b/spec @@ -527,11 +527,11 @@ until *** PˤĤ -ifunlesswhileuntilξȽμü黻`...'ξ -μϾPȸƤФ롥PǤʸɽƥϼ$_=~ -ƥפξάǤȤߤʤ롥˱黻`...'ξդǤ -$.==פξάȲᤵ롥P˸黻 `&&', `||', `!' -դμPȤߤʤ롥 +ifunlesswhileuntilξȽμü黻`&&', `||', +`...'ξդμϾPȸƤФ롥PǤʸɽƥ +ϼ$_=~ƥפξάǤȤߤʤ롥˱黻`...'ξդ +$.==פξάȲᤵ롥P˸`!'黻Ҥ +ڥɤPȤߤʤ롥 : 黻`!'ü黻ҤǤϤʤΤǡԤʤ˵Ĥ 뤳ȡP @@ -1412,6 +1412,27 @@ Methods: Ⱦ;2Ǥ֤ +*** Block(饹) + +ƥ졼Ϥ³ޤȤ᤿֥ȡ¹Ԥ륳ɤ +ʤƥ(ѿ)ʤɤ¸롥 + +SuperClass: Object + +Methods: + + do(arg[, ...]) + + ֥å¹Ԥ롥 + +Single Methods: + + new + + ֥å롥yield¹ԤǤǤΥ᥽å + ƤФȡλǼ¹Ԥ٤ɤ߹֥ + (Block)롥 + *** Class(饹) 饹Υ饹긷̩ȥ饹ðۥ᥽åɤѾ뤿 diff --git a/st.c b/st.c index e4e36380e60a95..80f08e9fb6deb5 100644 --- a/st.c +++ b/st.c @@ -2,7 +2,7 @@ static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; #ifndef lint -static char *rcsid = "$Header: /usr/ext/cvsroot/ruby/st.c,v 1.2 1994/08/12 04:47:59 matz Exp $"; +static char *rcsid = "$Header: /usr/ext/cvsroot/ruby/st.c,v 1.3 1994/12/09 01:28:33 matz Exp $"; #endif #include "config.h" diff --git a/string.c b/string.c index 12070809cc1faf..d1dc737f4a1c58 100644 --- a/string.c +++ b/string.c @@ -3,7 +3,7 @@ string.c - $Author: matz $ - $Date: 1994/12/06 09:30:24 $ + $Date: 1994/12/09 09:40:28 $ created at: Mon Aug 9 17:12:58 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -925,7 +925,7 @@ Fstr_inspect(str) *b++ = '\\'; *b++ = 'v'; } - else if (c == '\a') { + else if (c == '\1') { CHECK(2); *b++ = '\\'; *b++ = 'a'; diff --git a/variable.c b/variable.c index ae3163de19c427..aa01b3192198b4 100644 --- a/variable.c +++ b/variable.c @@ -3,7 +3,7 @@ variable.c - $Author: matz $ - $Date: 1994/11/01 08:28:42 $ + $Date: 1994/12/19 08:30:16 $ created at: Tue Apr 19 23:55:15 JST 1994 ************************************************/ @@ -55,9 +55,10 @@ struct global_entry { } v; VALUE (*get_hook)(); VALUE (*set_hook)(); + void *data; }; -static +static mark_global_entry(key, entry) ID key; struct global_entry *entry; @@ -73,9 +74,13 @@ mark_global_entry(key, entry) default: break; } + if (entry->data) { + gc_mark_maybe(entry->data); + } return ST_CONTINUE; } +void gc_mark_global_tbl() { st_foreach(global_tbl, mark_global_entry, 0); @@ -99,11 +104,12 @@ rb_global_entry(id) } void -rb_define_variable(name, var, get_hook, set_hook) +rb_define_variable(name, var, get_hook, set_hook, data) char *name; VALUE *var; VALUE (*get_hook)(); VALUE (*set_hook)(); + void *data; { struct global_entry *entry; ID id; @@ -123,13 +129,15 @@ rb_define_variable(name, var, get_hook, set_hook) entry->v.var = var; entry->get_hook = get_hook; entry->set_hook = set_hook; + entry->data = data; } void -rb_define_varhook(name, get_hook, set_hook) +rb_define_varhook(name, get_hook, set_hook, data) char *name; VALUE (*get_hook)(); VALUE (*set_hook)(); + void *data; { struct global_entry *entry; ID id; @@ -154,6 +162,9 @@ rb_define_varhook(name, get_hook, set_hook) entry->v.val = Qnil; entry->get_hook = get_hook; entry->set_hook = set_hook; + if (data) { + entry->data = data; + } } VALUE @@ -183,7 +194,7 @@ rb_gvar_get(entry) VALUE val; if (entry->get_hook) - val = (*entry->get_hook)(entry->id); + val = (*entry->get_hook)(entry->id, entry->data); switch (entry->mode) { case GLOBAL_VAL: return entry->v.val; @@ -258,7 +269,7 @@ rb_gvar_set(entry, val) VALUE val; { if (entry->set_hook) - (*entry->set_hook)(val, entry->id); + (*entry->set_hook)(val, entry->id, entry->data); if (entry->mode == GLOBAL_VAR) { if (entry->v.var == Qnil) { diff --git a/version.c b/version.c index 17b5af4a209964..aa9028b0e41fc8 100644 --- a/version.c +++ b/version.c @@ -3,8 +3,8 @@ version.c - $Author: matz $ - $Revision: 1.3 $ - $Date: 1994/08/18 07:06:32 $ + $Revision: 1.4 $ + $Date: 1994/12/19 08:30:17 $ created at: Thu Sep 30 20:08:01 JST 1993 Copyright (C) 1994 Yukihiro Matsumoto @@ -22,7 +22,7 @@ VALUE rb_readonly_hook(); Init_version() { rb_version = str_new2(RUBY_VERSION); - rb_define_variable("$VERSION", &rb_version, Qnil, rb_readonly_hook); + rb_define_variable("$VERSION", &rb_version, Qnil, rb_readonly_hook, 0); } show_version() diff --git a/version.h b/version.h index 681475c9535c8a..cfda74e8fb7e52 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.60" -#define VERSION_DATE "94/12/08" +#define RUBY_VERSION "0.62" +#define VERSION_DATE "94/12/19"