summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYukihiro Matsumoto <matz@ruby-lang.org>1994-12-19 03:01:10 (GMT)
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-17 13:09:31 (GMT)
commitb3f9ba5a3720de81a9a14d9d906509f81abeef7a (patch)
treeb5203ba2322aeb4ba05df7ddeb4d17369bd3e63a
parent00e36aa09f54925c2f9c30524b48f4f54a9adb23 (diff)
version 0.62v0_62
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で回収される.
-rw-r--r--ChangeLog42
-rw-r--r--Makefile.in7
-rw-r--r--class.c7
-rw-r--r--configure.in22
-rw-r--r--defines.h2
-rw-r--r--dict.c16
-rw-r--r--dir.c4
-rw-r--r--dln.c2
-rw-r--r--env.h14
-rw-r--r--eval.c558
-rw-r--r--file.c6
-rw-r--r--gc.c133
-rw-r--r--glob.c6
-rw-r--r--inits.c3
-rw-r--r--io.c32
-rw-r--r--methods.h22
-rw-r--r--missing/strdup.c4
-rw-r--r--missing/strftime.c6
-rw-r--r--node.h40
-rw-r--r--object.c6
-rw-r--r--pack.c6
-rw-r--r--parse.y380
-rw-r--r--process.c6
-rw-r--r--re.c69
-rw-r--r--ruby.c14
-rw-r--r--ruby.h85
-rw-r--r--sample/blk.rb9
-rw-r--r--sample/export.rb2
-rw-r--r--spec31
-rw-r--r--st.c2
-rw-r--r--string.c4
-rw-r--r--variable.c23
-rw-r--r--version.c6
-rw-r--r--version.h4
34 files changed, 804 insertions, 769 deletions
diff --git a/ChangeLog b/ChangeLog
index 52af56f..dfa5c85 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 3a88a99..a63ee53 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 4a36f0e..fa18600 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 9eec8ad..5ee5463 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 <pwd.h>],
[struct passwd pw; pw.pw_comment;], AC_DEFINE(PW_COMMENT))
AC_COMPILE_CHECK([pw_expire in struct passwd], [#include <pwd.h>],
[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 d5e8607..4928db7 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 74bfc22..3db2501 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 f139c40..8429912 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 <sys/param.h>
#include "ruby.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#include <sys/param.h>
/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
#if defined(DIRENT) || defined(_POSIX_VERSION)
diff --git a/dln.c b/dln.c
index b15c01b..44179ec 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 ebf3780..ebed038 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 fac6866..e40d781 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;i<argc;i++) {\
+ argv[i] = rb_eval(n->nd_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 1fc3447..8fd04bc 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 <sys/param.h>
+#include <sys/time.h>
#include "ruby.h"
#include "io.h"
-#include <sys/time.h>
-#include <sys/param.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/gc.c b/gc.c
index 5c1d27e..780d190 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 <stdio.h>
#include <setjmp.h>
@@ -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;
}
@@ -384,6 +339,15 @@ mark_dict(tbl)
}
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 bc4ad8a..74dfe52 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 <sys/param.h>
#include "ruby.h"
#include "fnmatch.h"
-#include <sys/param.h>
char *strdup();
diff --git a/inits.c b/inits.c
index 6b227fb..9a5b208 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 27563c2..2b73d89 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 dffd701..0000000
--- 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 2e1fe90..875290c 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 313b9d0..1e668ef 100644
--- a/missing/strftime.c
+++ b/missing/strftime.c
@@ -39,7 +39,11 @@
#include <stdio.h>
#include <ctype.h>
-#include <string.h>
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
diff --git a/node.h b/node.h
index 608c78c..a032ee2 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 decb070..4fa7f10 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 af7f8c2..e0c6e67 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 5fc35a5..ec5030f 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 <node> compstmts stmts stmt stmt0 expr expr0 var_ref
%type <node> if_tail opt_else cases resque ensure
%type <node> call_args call_args0 opt_args args args2
-%type <node> f_arglist f_args f_arg assoc_list assocs assoc
+%type <node> f_arglist f_args assoc_list assocs assoc
%type <node> mlhs mlhs_head mlhs_tail lhs iter_var opt_iter_var
%type <id> superclass variable symbol
%type <id> fname op rest_arg
-
+%type <num> 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 <id> SELF_ASGN /* +=, -= etc. */
+%token <id> 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];i<len;i++) {
+ ary_push(the_scope->var_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 c4e46e0..e0eb419 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 ce79c90..06770ab 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 cb5f8c6..b4212a3 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 f513557..d20ed77 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 <limits.h>
#else
# ifndef LONG_MAX
-# define LONG_MAX ((long)((unsigned long)~0L>>1))
+# if !defined(LONG_MAX) || !defined(CHAR_BIT)
+# include <limits.h>
+# 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 0000000..4e618bc
--- /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 ea6c5ae..4046a7e 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 ee23c70..93186df 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 e4e3638..80f08e9 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 1207080..d1dc737 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 ae3163d..aa01b31 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 17b5af4..aa9028b 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 681475c..cfda74e 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"