diff options
-rw-r--r-- | CVS/Entries | 51 | ||||
-rw-r--r-- | CVS/Repository | 1 | ||||
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | README | 22 | ||||
-rw-r--r-- | array.c | 12 | ||||
-rw-r--r-- | bignum.c | 2 | ||||
-rw-r--r-- | bring | 57 | ||||
-rw-r--r-- | class.c | 84 | ||||
-rwxr-xr-x | config.status | 72 | ||||
-rw-r--r-- | dict.c | 32 | ||||
-rw-r--r-- | env.h | 33 | ||||
-rw-r--r-- | error.c | 2 | ||||
-rw-r--r-- | etc.c | 16 | ||||
-rw-r--r-- | eval.c | 859 | ||||
-rw-r--r-- | file.c | 4 | ||||
-rw-r--r-- | gc.c | 13 | ||||
-rw-r--r-- | gnuglob.c | 6 | ||||
-rw-r--r-- | inits.c | 1 | ||||
-rw-r--r-- | io.c | 55 | ||||
-rw-r--r-- | math.c | 19 | ||||
-rwxr-xr-x[-rw-r--r--] | newver.rb | 4 | ||||
-rw-r--r-- | node.h | 22 | ||||
-rw-r--r-- | numeric.c | 144 | ||||
-rw-r--r-- | object.c | 100 | ||||
-rw-r--r-- | parse.y | 81 | ||||
-rw-r--r-- | process.c | 50 | ||||
-rw-r--r-- | random.c | 6 | ||||
-rw-r--r-- | re.c | 131 | ||||
-rw-r--r-- | ruby.c | 19 | ||||
-rw-r--r-- | sample/caller.rb | 15 | ||||
-rw-r--r-- | sample/dbm.rb | 2 | ||||
-rw-r--r-- | sample/export.rb | 13 | ||||
-rw-r--r-- | sample/fib.rb | 2 | ||||
-rw-r--r-- | sample/fib.scm | 6 | ||||
-rw-r--r-- | sample/list3.rb | 20 | ||||
-rw-r--r-- | sample/ruby-mode.el | 5 | ||||
-rwxr-xr-x | sample/time.rb | 8 | ||||
-rwxr-xr-x | sample/uumerge.rb | 27 | ||||
-rw-r--r-- | socket.c | 47 | ||||
-rw-r--r-- | spec | 217 | ||||
-rw-r--r-- | string.c | 96 | ||||
-rw-r--r-- | time.c | 12 | ||||
-rw-r--r-- | variable.c | 27 | ||||
-rw-r--r-- | version.h | 4 |
45 files changed, 1501 insertions, 908 deletions
diff --git a/CVS/Entries b/CVS/Entries new file mode 100644 index 0000000000..067e16dd65 --- /dev/null +++ b/CVS/Entries @@ -0,0 +1,51 @@ +/autoexec.c/0.15/Wed Jun 1 23:40:54 1994 Thu Mar 17 18:49:43 1994// +/class.c/0.22/Wed Jun 1 23:40:54 1994 Fri Mar 25 13:12:36 1994// +/compar.c/0.15/Wed Jun 1 23:40:54 1994 Thu Mar 17 18:49:43 1994// +/dln.h/0.14/Wed Jun 1 23:40:57 1994 Thu Mar 17 15:55:00 1994// +/error.c/0.15/Wed Jun 1 23:40:57 1994 Thu Mar 17 18:49:43 1994// +/etc.c/0.22/Wed Jun 1 23:40:58 1994 Fri Mar 25 13:12:36 1994// +/ident.h/0.17/Wed Jun 1 23:41:00 1994 Wed May 25 00:56:16 1994// +/inits.c/0.27/Wed Jun 1 23:41:00 1994 Mon Apr 25 23:30:29 1994// +/io.h/0.14/Wed Jun 1 23:41:01 1994 Thu Mar 17 15:55:00 1994// +/methods.c/0.20/Wed Jun 1 23:41:01 1994 Tue Mar 22 16:58:31 1994// +/missing.c/0.29/Wed Jun 1 23:41:01 1994 Wed Jun 1 23:36:26 1994// +/parse.y/0.35/Wed Jun 1 23:41:08 1994 Wed Jun 1 23:36:30 1994// +/random.c/0.15/Wed Jun 1 23:41:09 1994 Thu Mar 17 18:49:43 1994// +/range.c/0.15/Wed Jun 1 23:41:09 1994 Thu Mar 17 18:49:43 1994// +/re.h/0.15/Wed Jun 1 23:41:10 1994 Thu May 26 00:41:30 1994// +/regex.c/0.15/Wed Jun 1 23:41:12 1994 Wed Jun 1 23:36:35 1994// +/regex.h/0.14/Wed Jun 1 23:41:12 1994 Thu Mar 17 15:55:00 1994// +/st.h/0.14/Wed Jun 1 23:41:14 1994 Thu Mar 17 15:55:00 1994// +/variable.c/0.29/Wed Jun 1 23:41:16 1994 Wed May 25 00:56:35 1994// +/version.c/0.27/Wed Jun 1 23:41:16 1994 Mon Apr 25 23:30:35 1994// +/Makefile/0.32/Fri Jun 3 00:15:00 1994 Fri Jun 3 00:15:00 1994// +/Makefile.in/1.3/Fri Jun 3 00:15:01 1994 Fri Jun 3 00:15:01 1994// +/array.c/0.29/Fri Jun 3 00:15:02 1994 Fri Jun 3 00:15:02 1994// +/configure/1.3/Fri Jun 3 00:15:04 1994 Fri Jun 3 00:15:03 1994// +/configure.in/1.3/Fri Jun 3 00:15:04 1994 Fri Jun 3 00:15:04 1994// +/dbm.c/0.28/Fri Jun 3 00:15:05 1994 Fri Jun 3 00:15:05 1994// +/defines.h/1.4/Fri Jun 3 00:15:06 1994 Fri Jun 3 00:15:06 1994// +/dict.c/0.28/Fri Jun 3 00:15:06 1994 Fri Jun 3 00:15:06 1994// +/dir.c/0.18/Fri Jun 3 00:15:07 1994 Fri Jun 3 00:15:07 1994// +/dln.c/0.29/Fri Jun 3 00:15:08 1994 Fri Jun 3 00:15:08 1994// +/enum.c/0.16/Fri Jun 3 00:15:09 1994 Fri Jun 3 00:15:08 1994// +/eval.c/0.35/Fri Jun 3 00:15:10 1994 Fri Jun 3 00:15:09 1994// +/file.c/0.29/Fri Jun 3 00:15:11 1994 Fri Jun 3 00:15:11 1994// +/gc.c/0.30/Fri Jun 3 00:15:12 1994 Fri Jun 3 00:15:12 1994// +/io.c/0.29/Fri Jun 3 00:15:13 1994 Fri Jun 3 00:15:13 1994// +/math.c/0.28/Fri Jun 3 00:15:14 1994 Fri Jun 3 00:15:14 1994// +/node.h/0.32/Fri Jun 3 00:15:15 1994 Fri Jun 3 00:15:14 1994// +/numeric.c/0.19/Fri Jun 3 00:15:15 1994 Fri Jun 3 00:15:15 1994// +/object.c/0.32/Fri Jun 3 00:15:16 1994 Fri Jun 3 00:15:16 1994// +/pack.c/0.18/Fri Jun 3 00:15:17 1994 Fri Jun 3 00:15:17 1994// +/process.c/0.30/Fri Jun 3 00:15:18 1994 Fri Jun 3 00:15:17 1994// +/re.c/0.32/Fri Jun 3 00:15:19 1994 Fri Jun 3 00:15:18 1994// +/ruby.c/0.34/Fri Jun 3 00:15:19 1994 Fri Jun 3 00:15:19 1994// +/ruby.h/0.30/Fri Jun 3 00:15:20 1994 Fri Jun 3 00:15:20 1994// +/socket.c/0.27/Fri Jun 3 00:15:21 1994 Fri Jun 3 00:15:21 1994// +/sprintf.c/0.23/Fri Jun 3 00:15:22 1994 Fri Jun 3 00:15:21 1994// +/st.c/0.15/Fri Jun 3 00:15:22 1994 Fri Jun 3 00:15:22 1994// +/string.c/0.29/Fri Jun 3 00:15:23 1994 Fri Jun 3 00:15:23 1994// +/struct.c/0.26/Fri Jun 3 00:15:25 1994 Fri Jun 3 00:15:24 1994// +/time.c/0.29/Fri Jun 3 00:15:26 1994 Fri Jun 3 00:15:26 1994// +/version.h/1.7/Fri Jun 3 00:15:27 1994 Fri Jun 3 00:15:27 1994// diff --git a/CVS/Repository b/CVS/Repository new file mode 100644 index 0000000000..b98482fac9 --- /dev/null +++ b/CVS/Repository @@ -0,0 +1 @@ +/work/cvsroot/ruby diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..0908d49776 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +# +# Makefile - +# +# created at: Wed Aug 10 15:21:29 JST 1994 + +all:; @echo "You must run configure first." diff --git a/Makefile.in b/Makefile.in index 4c8b457f6c..6296a5e650 100644 --- a/Makefile.in +++ b/Makefile.in @@ -154,7 +154,7 @@ parse.o : parse.y ruby.h defines.h env.h node.h st.h ident.h regex.h ### array.o : array.c ruby.h defines.h bignum.o : bignum.c ruby.h defines.h -class.o : class.c ruby.h defines.h env.h node.h st.h methods.h +class.o : class.c ruby.h defines.h env.h node.h st.h compar.o : compar.c ruby.h defines.h dbm.o : dbm.c ruby.h defines.h dict.o : dict.c ruby.h defines.h st.h @@ -163,7 +163,7 @@ dln.o : dln.c defines.h dln.h enum.o : enum.c ruby.h defines.h error.o : error.c ruby.h defines.h env.h etc.o : etc.c ruby.h defines.h -eval.o : eval.c ruby.h defines.h ident.h env.h node.h methods.h st.h +eval.o : eval.c ruby.h defines.h ident.h env.h node.h st.h file.o : file.c ruby.h defines.h io.h fnmatch.o : fnmatch.c fnmatch.h gc.o : gc.c ruby.h defines.h env.h st.h @@ -49,3 +49,25 @@ sparc�ʳ��Υ쥸����������ɥ������CPU�Ǥ�, �쥸���������� �ɥ���ե�å��夹�륳���ɤ��ɲä���ɬ�פ����뤫���Τ�ʤ�. + +���۾�� + + Ruby�Ϻǽ�Ū�ˤ�GNU Public License�ˤ������ä��������ۤ� + ���ͽ�����, �������Ǥϰʲ��ξ������ۤ���. + + * ���� + + �����ʤ���Ū�Ǥ��켫ͳ�Ǥ���. ������, �Х������Ϻ�Ԥؤ� + �ե����ɥХå�����Ԥ���(�����ǤϤʤ�) + + * ¾�Υץ������ؤΰ��� + + �����ʤ���Ū�Ǥ��켫ͳ�Ǥ���. ������, ���ۤ��������ɤ˴� + �ޤ��¾�κ�Ԥˤ�륳���ɤ�, ���줾��κ�Ԥΰո��ˤ�� + ���¤��ä�����. + + * ������ + + �ػߤ���. ���ꤷ�����ͤϺ�Ԥ�ľ��Ϣ����Ȥ뤳��. ����� + Ruby�θ�����ͤ�����ʾ��֤Τޤ���ή�ۤ���Τ����¤� + �뤿��Ǥ���, ������ͤ����ꤷ�������Ǻ����ۼ�ͳ�Ȥ���. @@ -456,6 +456,17 @@ Fary_each(ary) } static VALUE +Fary_each_index(ary) + struct RArray *ary; +{ + int i; + + for (i=0; i<ary->len; i++) { + rb_yield(INT2FIX(i)); + } +} + +static VALUE Fary_length(ary) struct RArray *ary; { @@ -870,6 +881,7 @@ Init_Array() rb_define_method(C_Array, "shift", Fary_shift, 0); rb_define_method(C_Array, "unshift", Fary_unshift, 1); rb_define_method(C_Array, "each", Fary_each, 0); + rb_define_method(C_Array, "each_index", Fary_each_index, 0); rb_define_method(C_Array, "length", Fary_length, 0); rb_define_alias(C_Array, "size", "length"); rb_define_method(C_Array, "index", Fary_index, 1); @@ -1075,7 +1075,7 @@ Init_Bignum() { C_Bignum = rb_define_class("Bignum", C_Integer); rb_define_single_method(C_Bignum, "new", Fbig_new, 1); - rb_define_method(C_Bignum, "clone", Fbig_clone, 0); + rb_define_method(C_Bignum, "to_s", Fbig_to_s, 0); rb_define_method(C_Bignum, "coerce", Fbig_coerce, 1); rb_define_method(C_Bignum, "-@", Fbig_uminus, 0); @@ -0,0 +1,57 @@ +#! /usr/bin/bash + +function fdeject() { + if type eject > /dev/null 2>&1; then + eject + fi +} + +function copyfiles() { + for d in . missing sample; do + if [ ! -d $1/$d ];then mkdir $1/$d; fi + for i in $d/*;do + case $i in + */ruby|*.o|*~|*.sav|*.bak|*.orig|*/core|"#"*);; + */Change*|*/config.status|*/Makefile);; + *) + if [ -f $i ]; then + if [ $i -nt $1/$i -o ! -f $1/$i ];then + echo copying $i + cp -p $i $1/$i + fi + fi;; + esac + done + done +} + +if [ ! -d exchange ]; then mkdir exchange; fi + +if [ "$1" = "in" ]; then + + cd exchange + + mread ruby.tgz ruby.tgz + fdeject + tar zxf ruby.tgz + rm -f ruby.tgz + cd ruby + + cp ChangeLog ../../Changes + copyfiles ../.. + +else +# bring out + if [ ! -d exchange/ruby ]; then mkdir exchange/ruby; fi + + cp -p ChangeLog exchange/ruby + copyfiles exchange/ruby + + cd exchange + (cd ruby; make realclean) + + tar zcf ruby.tgz ruby + mwrite ruby.tgz ruby.tgz + fdeject + rm -f ruby.tgz +fi @@ -14,7 +14,6 @@ #include "env.h" #include "node.h" #include "st.h" -#include "methods.h" struct st_table *new_idhash(); @@ -46,6 +45,16 @@ single_class_new(super) return (VALUE)cls; } +static int +clone_method(mid, body, tbl) + ID mid; + NODE *body; + st_table *tbl; +{ + st_insert(tbl, mid, NEW_METHOD(body->nd_body, body->nd_noex)); + return ST_CONTINUE; +} + VALUE single_class_clone(class) struct RClass *class; @@ -54,14 +63,15 @@ single_class_clone(class) return (VALUE)class; else { /* copy single(unnamed) class */ - NEWOBJ(cls, struct RClass); - CLONESETUP(cls, class); - - cls->super = class->super; - cls->m_tbl = st_copy(class->m_tbl); - cls->c_tbl = Qnil; - FL_SET(cls, FL_SINGLE); - return (VALUE)cls; + NEWOBJ(clone, struct RClass); + CLONESETUP(clone, class); + + clone->super = class->super; + clone->m_tbl = new_idhash(); + st_foreach(class->m_tbl, clone_method, clone->m_tbl); + clone->c_tbl = Qnil; + FL_SET(clone, FL_SINGLE); + return (VALUE)clone; } } @@ -169,13 +179,13 @@ rb_include_module(class, module) } void -rb_add_method(class, mid, node, undef) +rb_add_method(class, mid, node, noex) struct RClass *class; ID mid; NODE *node; - int undef; + int noex; { - struct SMethod *body; + NODE *body; if (class == Qnil) class = (struct RClass*)C_Object; if (st_lookup(class->m_tbl, mid, &body)) { @@ -183,17 +193,12 @@ rb_add_method(class, mid, node, undef) Warning("redefine %s", rb_id2name(mid)); } rb_clear_cache(body); - method_free(body); + freenode(body); + } + if (node && node->type != NODE_FBODY) { + node = NEW_FBODY(node, mid); } - body = ALLOC(struct SMethod); - body->node = node; - if (BUILTIN_TYPE(class) == T_MODULE) - body->origin = Qnil; - else - body->origin = class; - body->id = mid; - body->undef = undef; - body->count = 1; + body = NEW_METHOD(node, noex); st_insert(class->m_tbl, mid, body); } @@ -204,9 +209,7 @@ rb_define_method(class, name, func, argc) VALUE (*func)(); int argc; { - NODE *temp = NEW_CFUNC(func, argc); - - rb_add_method(class, rb_intern(name), temp, FALSE); + rb_add_method(class, rb_intern(name), NEW_CFUNC(func, argc), 0); } void @@ -214,7 +217,17 @@ rb_undef_method(class, name) struct RClass *class; char *name; { - rb_add_method(class, rb_intern(name), Qnil, TRUE); + rb_add_method(class, rb_intern(name), Qnil, 0); +} + +void +rb_define_private_method(class, name, func, argc) + struct RClass *class; + char *name; + VALUE (*func)(); + int argc; +{ + rb_add_method(class, rb_intern(name), NEW_CFUNC(func, argc), 1); } VALUE @@ -228,7 +241,7 @@ rb_single_class(obj) case T_STRUCT: break; default: - Fail("can't define single method for built-in classes"); + Fail("can't define single method for built-in class"); break; } @@ -245,7 +258,18 @@ rb_define_single_method(obj, name, func, argc) VALUE (*func)(); int argc; { - rb_define_method(rb_single_class(obj), name, func, argc, FALSE); + rb_define_method(rb_single_class(obj), name, func, argc); +} + +void +rb_define_module_function(module, name, func, argc) + VALUE module; + char *name; + VALUE (*func)(); + int argc; +{ + rb_define_private_method(module, name, func, argc); + rb_define_single_method(module, name, func, argc); } void @@ -272,10 +296,10 @@ rb_define_attr(class, name, pub) sprintf(buf, "@%s", name); attriv = rb_intern(buf); if (rb_method_boundp(class, attr) == Qnil) { - rb_add_method(class, attr, NEW_IVAR(attriv), FALSE); + rb_add_method(class, attr, NEW_IVAR(attriv), 0); } if (pub && rb_method_boundp(class, attreq) == Qnil) { - rb_add_method(class, attreq, NEW_ATTRSET(attriv), FALSE); + rb_add_method(class, attreq, NEW_ATTRSET(attriv), 0); } } diff --git a/config.status b/config.status new file mode 100755 index 0000000000..7bdc7b26ed --- /dev/null +++ b/config.status @@ -0,0 +1,72 @@ +#!/bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host dyna: +# +# ./configure + +for arg +do + case "$arg" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo running ${CONFIG_SHELL-/bin/sh} ./configure + exec ${CONFIG_SHELL-/bin/sh} ./configure ;; + *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; + esac +done + +trap 'rm -f Makefile; exit 1' 1 3 15 +PROGS='ruby' +CC='gcc' +CPP='gcc -E' +DBM='-fpcc-struct-return' +STATIC='' +YACC='bison -y' +INSTALL='/usr/bin/install -c' +INSTALL_PROGRAM='$(INSTALL)' +INSTALL_DATA='$(INSTALL) -m 644' +ALLOCA='' +LIBS=' -lm -ldbm' +srcdir='.' +DEFS=' -DHAVE_UNISTD_H=1 -DHAVE_SYSCALL_H=1 -DHAVE_A_OUT_H=1 -DDIRENT=1 -DGETGROUPS_T=gid_t -DRETSIGTYPE=void -DHAVE_GETOPT_LONG=1 -DHAVE_MEMMOVE=1 -DHAVE_STRERROR=1 -DHAVE_STRTOL=1 -DHAVE_STRTOUL=1 -DHAVE_STRDUP=1 -DHAVE_SETENV=1 -DHAVE_KILLPG=1 -DHAVE_MKDIR=1 -DHAVE_STRFTIME=1 -DHAVE_ALLOCA_H=1' +prefix='' +exec_prefix='' +prsub='' +extrasub='' + +top_srcdir=$srcdir + +CONFIG_FILES=${CONFIG_FILES-"Makefile"} +for file in .. ${CONFIG_FILES}; do if test "x$file" != x..; then + srcdir=$top_srcdir + # Remove last slash and all that follows it. Not all systems have dirname. + dir=`echo $file|sed 's%/[^/][^/]*$%%'` + if test "$dir" != "$file"; then + test "$top_srcdir" != . && srcdir=$top_srcdir/$dir + test ! -d $dir && mkdir $dir + fi + echo creating $file + rm -f $file + echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file + sed -e " +$prsub +$extrasub +s%@PROGS@%$PROGS%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@DBM@%$DBM%g +s%@STATIC@%$STATIC%g +s%@YACC@%$YACC%g +s%@INSTALL@%$INSTALL%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@ALLOCA@%$ALLOCA%g +s%@LIBS@%$LIBS%g +s%@srcdir@%$srcdir%g +s%@DEFS@%$DEFS% +" $top_srcdir/${file}.in >> $file +fi; done + + +exit 0 @@ -13,7 +13,9 @@ #include "ruby.h" #include "st.h" -VALUE C_Dict, C_EnvDict; +VALUE C_Dict; + +static VALUE envtbl; static ID hash, eq; VALUE Fgetenv(), Fsetenv(); @@ -521,11 +523,16 @@ Fsetenv(obj, name, value) return FALSE; /* not reached */ } +static VALUE +Fenv_to_s() +{ + return str_new2("$ENV"); +} + Init_Dict() { - extern VALUE C_Builtin; + extern VALUE C_Kernel; extern VALUE M_Enumerable; - static VALUE envtbl; hash = rb_intern("hash"); eq = rb_intern("=="); @@ -567,17 +574,16 @@ Init_Dict() rb_define_method(C_Dict,"has_value", Fdic_has_value, 1); - C_EnvDict = rb_define_class("EnvDict", C_Object); - - rb_include_module(C_EnvDict, M_Enumerable); + envtbl = obj_alloc(C_Object); + rb_define_single_method(envtbl,"[]", Fgetenv, 1); + rb_define_single_method(envtbl,"[]=", Fsetenv, 2); + rb_define_single_method(envtbl,"each", Fenv_each, 0); + rb_define_single_method(envtbl,"delete", Fenv_delete, 1); + rb_define_single_method(envtbl,"to_s", Fenv_to_s, 0); + rb_include_module(CLASS_OF(envtbl), M_Enumerable); - rb_define_method(C_EnvDict,"[]", Fgetenv, 1); - rb_define_method(C_EnvDict,"[]=", Fsetenv, 2); - rb_define_method(C_EnvDict,"each", Fenv_each, 0); - rb_define_method(C_EnvDict,"delete", Fenv_delete, 1); - envtbl = obj_alloc(C_EnvDict); rb_define_variable("$ENV", &envtbl, Qnil, rb_readonly_hook); - rb_define_method(C_Builtin, "getenv", Fgetenv, 1); - rb_define_method(C_Builtin, "setenv", Fsetenv, 2); + rb_define_private_method(C_Kernel, "getenv", Fgetenv, 1); + rb_define_private_method(C_Kernel, "setenv", Fsetenv, 2); } @@ -15,31 +15,24 @@ extern struct ENVIRON { VALUE self; int argc; VALUE *argv; - struct RClass *current_module; - struct RClass *last_class; -#ifdef USE_CALLER - char *file; - int line; -#endif ID last_func; - ID *local_tbl; - VALUE *local_vars; - int in_eval; - struct BLOCK *block; - int iterator; - int flags; + struct RClass *last_class; struct ENVIRON *prev; } *the_env; -#define ITERATOR_P() (the_env->iterator == 1 || the_env->iterator == 2) - -#undef Qself +#undef Qself #define Qself the_env->self -#define the_class the_env->current_module -#define DURING_ITERATE 1 -#define DURING_RESQUE 2 -#define DURING_CALL 4 -#define VARS_MALLOCED 8 +extern struct SCOPE { + ID *local_tbl; + VALUE *local_vars; + VALUE block; + int flags; + struct SCOPE *prev; +} *the_scope; + +#define VARS_MALLOCED (1<<2) + +extern int rb_in_eval; #endif /* ENV_H */ @@ -40,7 +40,7 @@ err_print(fmt, args) char buf[BUFSIZ]; err_sprintf(buf, fmt, args); - if (the_env->in_eval) { + if (rb_in_eval) { if (errstr == Qnil) { errstr = str_new2(buf); } @@ -178,15 +178,13 @@ Init_Etc() { M_Etc = rb_define_module("Etc"); - rb_define_method(M_Etc, "getlogin", Fetc_getlogin, 0); + rb_define_module_function(M_Etc, "getlogin", Fetc_getlogin, 0); - rb_define_method(M_Etc, "getpwuid", Fetc_getpwuid, -2); - rb_define_method(M_Etc, "getpwnam", Fetc_getpwnam, 1); - rb_define_method(M_Etc, "passwd", Fetc_passwd, 0); + rb_define_module_function(M_Etc, "getpwuid", Fetc_getpwuid, -2); + rb_define_module_function(M_Etc, "getpwnam", Fetc_getpwnam, 1); + rb_define_module_function(M_Etc, "passwd", Fetc_passwd, 0); - rb_define_method(M_Etc, "getgrgid", Fetc_getgrgid, 1); - rb_define_method(M_Etc, "getgrnam", Fetc_getgrnam, 1); - rb_define_method(M_Etc, "group", Fetc_group, 0); - - rb_include_module(CLASS_OF(M_Etc), M_Etc); + rb_define_module_function(M_Etc, "getgrgid", Fetc_getgrgid, 1); + rb_define_module_function(M_Etc, "getgrnam", Fetc_getgrnam, 1); + rb_define_module_function(M_Etc, "group", Fetc_group, 0); } @@ -14,13 +14,11 @@ #include "ident.h" #include "env.h" #include "node.h" -#include "methods.h" #include <stdio.h> #include <setjmp.h> #include "st.h" -void method_free(); void rb_clear_cache(); /* #define TEST /* prints cache miss */ @@ -43,42 +41,38 @@ struct cache_entry { /* method hash table. */ ID mid; /* method's id */ struct RClass *class; /* receiver's class */ struct RClass *origin; /* where method defined */ - struct SMethod *method; - int undef; + NODE *method; + int noex; }; static struct cache_entry cache[CACHE_SIZE]; -static struct SMethod* +static NODE* search_method(class, id, origin) struct RClass *class, **origin; ID id; { - struct SMethod *body; - NODE *list; + NODE *body; while (!st_lookup(class->m_tbl, id, &body)) { class = class->super; if (class == Qnil) return Qnil; } - if (body->origin) - *origin = body->origin; - else - *origin = class; + *origin = class; return body; } static NODE* -rb_get_method_body(classp, idp) +rb_get_method_body(classp, idp, noexp) struct RClass **classp; ID *idp; + int *noexp; { int pos, i; ID id = *idp; struct RClass *class = *classp; - struct SMethod *method; - struct SMethod *body; + NODE *body; struct RClass *origin; struct cache_entry *ent; @@ -96,23 +90,14 @@ rb_get_method_body(classp, idp) ent->mid = id; ent->class = class; ent->origin = origin; - ent->method = body; - ent->undef = body->undef; - - if (ent->undef) return Qnil; - *idp = ent->method->id; - *classp = ent->origin; - return ent->method->node; -} - -VALUE -rb_method_boundp(class, id) - struct RClass *class; - ID id; -{ - if (rb_get_method_body(&class, &id)) - return TRUE; - return FALSE; + ent->method = body->nd_body; + ent->noex = body->nd_noex; + + if (ent->method == Qnil) return Qnil; + *idp = ent->method->nd_mid; + *classp = origin; + if (noexp) *noexp = ent->noex; + return ent->method->nd_head; } void @@ -120,23 +105,65 @@ rb_alias(class, name, def) struct RClass *class; ID name, def; { - struct SMethod *body; + struct RClass *origin; + NODE *body, *old; + + if (name == def) return; + body = search_method(class, def, &origin); + if (body == Qnil) { + 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, &body)) { + if (st_lookup(class->m_tbl, name, &old)) { if (verbose) { Warning("redefine %s", rb_id2name(name)); } - rb_clear_cache(body); - method_free(body); + rb_clear_cache(old->nd_body); + freenode(old); } - body = search_method(class, def, &body); - body->count++; - st_insert(class->m_tbl, name, body); + + st_insert(class->m_tbl, name, NEW_METHOD(body->nd_body, body->nd_noex)); +} + +void +rb_export_method(class, name, noex) + struct RClass *class; + ID name; + int noex; +{ + NODE *body; + struct RClass *origin; + + body = search_method(class, name, &origin); + if (body == Qnil) { + Fail("undefined method `%s' for class `%s'", + rb_id2name(name), rb_class2name(class)); + } + if (body->nd_noex != noex) { + if (class == origin) { + body->nd_noex = noex; + } + else { + rb_add_method(class, name, NEW_ZSUPER(), noex); + } + } +} + +VALUE +rb_method_boundp(class, id) + struct RClass *class; + ID id; +{ + if (rb_get_method_body(&class, &id, 0)) + return TRUE; + return FALSE; } void rb_clear_cache(body) - struct SMethod *body; + NODE *body; { struct cache_entry *ent, *end; @@ -166,17 +193,6 @@ rb_clear_cache2(class) } } -void -method_free(body) - struct SMethod *body; -{ - body->count--; - if (body->count == 0) { - freenode(body->node); - free(body); - } -} - static ID match, each; VALUE errstr, errat; extern NODE *eval_tree; @@ -184,12 +200,17 @@ extern int nerrs; extern VALUE TopSelf; 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;\ - _this.flags = 0;\ the_env = &_this;\ #define POP_ENV() the_env = the_env->prev; } @@ -198,12 +219,22 @@ struct BLOCK { NODE *var; NODE *body; struct ENVIRON env; + struct SCOPE scope; int level; -}; + struct BLOCK *prev; +} *the_block; + +#define PUSH_BLOCK(v,b) { \ + struct BLOCK _this; \ + _this.level = tag_level; \ + _this.var=v; \ + _this.body = b; \ + _this.env = *the_env; \ + _this.scope = *the_scope; \ + _this.prev = the_block; \ + the_block = &_this; \ -#define SET_BLOCK(b,node) (b.level=tag_level,b.var=node->nd_var,\ - b.body=node->nd_body,b.env=*the_env,\ - the_env->block= &b) +#define POP_BLOCK() the_block = the_block->prev; } static int tag_level, target_level; static struct tag { @@ -211,30 +242,24 @@ static struct tag { jmp_buf buf; struct gc_list *gclist; struct ENVIRON *env; - VALUE self; - int ilevel; + struct tag *prev; } *prot_tag; #define PUSH_TAG() {\ struct tag _this;\ - struct tag *_oldtag = prot_tag;\ - &_oldtag;\ _this.level= ++tag_level;\ - _this.env= the_env;\ - _this.self= Qself;\ - _this.ilevel= the_env->iterator;\ + _this.env = the_env;\ + _this.prev = prot_tag;\ prot_tag = &_this;\ #define POP_TAG() \ tag_level--;\ - prot_tag = _oldtag;\ + prot_tag = prot_tag->prev;\ } #define EXEC_TAG() (setjmp(prot_tag->buf)) #define JUMP_TAG(val) {\ the_env = prot_tag->env;\ - the_env->iterator = prot_tag->ilevel;\ - Qself = prot_tag->self;\ longjmp(prot_tag->buf,(val));\ } @@ -248,8 +273,34 @@ static struct tag { #define IN_BLOCK 0x08 +static struct RClass *the_class; +struct class_link { + struct RClass *class; + struct class_link *prev; +} *class_link; + +#define PUSH_CLASS() { \ + struct class_link _link; \ + _link.class = the_class; \ + _link.prev = class_link; \ + class_link = &_link \ + +#define POP_CLASS() \ + the_class = class_link->class; \ + class_link = class_link->prev; } + +#define PUSH_SCOPE() { \ + 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; } + static VALUE rb_eval(); -VALUE Feval(); +static VALUE Feval(); static VALUE rb_call(); VALUE rb_apply(); @@ -266,6 +317,8 @@ extern VALUE rb_stderr; extern int sourceline; extern char *sourcefile; +static int iter_level = 0; + VALUE rb_self() { @@ -302,9 +355,11 @@ ruby_init(argc, argv, envp) char **argv, **envp; { int state; - static struct ENVIRON top_env; - the_env = &top_env; - + static struct ENVIRON env; + static struct SCOPE scope; + the_env = top_env = &env; + the_scope = top_scope = &scope; + PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { ruby_init0(argc, argv, envp); @@ -332,6 +387,8 @@ Eval(toplevel) tree = eval_tree; eval_tree = Qnil; + sourcefile = tree->src; + PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { result = rb_eval(tree); @@ -359,12 +416,8 @@ ruby_run() rb_define_variable("$!", &errstr, Qnil, Qnil); errat = Qnil; /* clear for execution */ - PUSH_ENV(); - top_env = the_env; PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { - int i; - the_class = (struct RClass*)C_Object; Eval(1); } @@ -401,7 +454,6 @@ ruby_run() Bug("Unknown longjmp status %d", state); break; } - POP_ENV(); exit(0); } @@ -409,15 +461,30 @@ void rb_trap_eval(cmd) VALUE cmd; { - PUSH_ENV(); - the_env->self = TopSelf; - the_env->current_module = top_env->current_module; - the_env->local_vars = top_env->local_vars; - the_env->local_tbl = top_env->local_tbl; - the_class = (struct RClass*)C_Object; + int state, go_out; + + DUP_ENV(); + 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; - Feval(Qself, cmd); + Feval(Qself, cmd); + go_out = 0; + } + else { + go_out = 1; + } + POP_SCOPE(); + POP_TAG(); + POP_CLASS(); POP_ENV(); + + if (go_out) JUMP_TAG(state); } #define SETUP_ARGS {\ @@ -451,16 +518,15 @@ rb_eval(node) register NODE *node; { int state; - int go_out = 0; + int go_out; VALUE result; - &go_out; again: if (node == Qnil) return Qnil; sourceline = node->line; - sourcefile = node->src; +#undef SAFE_SIGHANDLE #ifdef SAFE_SIGHANDLE { extern int trap_pending; @@ -529,14 +595,16 @@ rb_eval(node) switch (state = EXEC_TAG()) { case 0: res = rb_eval(node->nd_cond); + go_out = 0; break; case TAG_FAIL: res = Qnil; + go_out = 0; break; default: - go_out++; + go_out = 1; } POP_TAG(); if (go_out) JUMP_TAG(state); @@ -553,14 +621,17 @@ rb_eval(node) while_redo: rb_eval(node->nd_body); } + go_out = 0; break; case TAG_REDO: goto while_redo; case TAG_CONTINUE: goto while_cont; default: - go_out++; + go_out = 1; + break; case TAG_BREAK: + go_out = 0; break; } while_out: @@ -577,13 +648,14 @@ rb_eval(node) while2_redo: rb_eval(node->nd_body); } while (rb_eval(node->nd_cond)); + go_out = 0; break; case TAG_REDO: goto while2_redo; case TAG_CONTINUE: goto while2_cont; default: - go_out++; + go_out = 1; case TAG_BREAK: break; } @@ -592,31 +664,34 @@ rb_eval(node) if (go_out) JUMP_TAG(state); return Qnil; - case NODE_DO: + case NODE_ITER: case NODE_FOR: { - struct BLOCK block; + int iter_saved = iter_level; - PUSH_ENV(); - SET_BLOCK(block, node); + DUP_ENV(); + PUSH_BLOCK(node->nd_var, node->nd_body); PUSH_TAG(); state = EXEC_TAG(); if (state == 0) { - if (node->type == NODE_DO) { - the_env->iterator = 1; + if (node->type == NODE_ITER) { + iter_level = 1; result = rb_eval(node->nd_iter); } else { VALUE recv; + iter_level = 0; recv = rb_eval(node->nd_iter); - the_env->iterator = 1; + iter_level = 1; result = rb_call(CLASS_OF(recv), recv, each, 0, Qnil); } } POP_TAG(); + POP_BLOCK(); POP_ENV(); + iter_level = iter_saved; switch (state) { case 0: break; @@ -626,9 +701,10 @@ rb_eval(node) } result = Qnil; break; + case IN_BLOCK|TAG_RETRY: case IN_BLOCK|TAG_RETURN: if (target_level == tag_level) { - state = TAG_RETURN; + state &= ~IN_BLOCK; } /* fall through */ default: @@ -744,29 +820,78 @@ rb_eval(node) case NODE_CALL2: { VALUE recv, *argv; - int argc, last_iter; + int argc, iter_saved = iter_level; VALUE args = Qnil; /* used in SETUP_ARGS */ + VALUE buf[3]; - last_iter = the_env->iterator; - the_env->iterator = 0; /* recv & args are not iter. */ + iter_level = 0; /* recv & args are not iter. */ recv = node->nd_recv?rb_eval(node->nd_recv):Qself; +#if 0 SETUP_ARGS; - the_env->iterator = last_iter; /* restore iter. level */ +#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); + return rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv, + node->nd_recv?0:1); } break; case NODE_SUPER: case NODE_ZSUPER: { - int last_iter; + int iter_saved = iter_level; int i, argc; VALUE *argv; VALUE args = Qnil; /* used in SETUP_ARGS */ - last_iter = the_env->iterator; /* recv & args are not iter. */ - the_env->iterator = 0; + iter_level = 0; /* recv & args are not iter. */ if (node->type == NODE_ZSUPER) { argc = the_env->argc; @@ -776,19 +901,11 @@ rb_eval(node) SETUP_ARGS; } - /* restore iter. level */ - switch (last_iter) { - case 1: /* SUPER called as iter. */ - case 2: /* iter. called SUPER */ - the_env->iterator = 1; - break; - default: /* otherwise SUPER is not iter. */ - break; - } - + if (iter_saved == 0) iter_level = 1; result = rb_call(the_env->last_class->super, Qself, - the_env->last_func, argc, argv, Qnil); - the_env->iterator = last_iter; + the_env->last_func, argc, argv, 1); + /* restore iter. level */ + iter_level = iter_saved; } return result; @@ -796,23 +913,25 @@ rb_eval(node) { VALUE result; + PUSH_SCOPE(); PUSH_TAG(); if (node->nd_cnt > 0) { - the_env->local_vars = alloca(sizeof(VALUE)*node->nd_cnt); - memset(the_env->local_vars, 0, sizeof(VALUE)*node->nd_cnt); - the_env->local_tbl = node->nd_tbl; + the_scope->local_vars = (VALUE*) + alloca(sizeof(VALUE)*node->nd_cnt); + memset(the_scope->local_vars, 0, sizeof(VALUE)*node->nd_cnt); + the_scope->local_tbl = node->nd_tbl; } else { - the_env->local_vars = Qnil; - the_env->local_tbl = Qnil; + the_scope->local_vars = Qnil; + the_scope->local_tbl = Qnil; } if ((state = EXEC_TAG()) == 0) { result = rb_eval(node->nd_body); } POP_TAG(); - if (the_env->local_vars && (the_env->flags&VARS_MALLOCED)) - free(the_env->local_vars); - the_env->local_vars = Qnil; + if (the_scope->local_vars && (the_scope->flags&VARS_MALLOCED)) + free(the_scope->local_vars); + POP_SCOPE(); if (state != 0) JUMP_TAG(state); return result; @@ -825,9 +944,9 @@ rb_eval(node) } case NODE_LASGN: - if (the_env->local_vars == Qnil) + if (the_scope->local_vars == Qnil) Bug("unexpected local variable asignment"); - return the_env->local_vars[node->nd_cnt] = rb_eval(node->nd_value); + return the_scope->local_vars[node->nd_cnt] = rb_eval(node->nd_value); case NODE_GASGN: { @@ -850,15 +969,15 @@ rb_eval(node) VALUE val; val = rb_eval(node->nd_value); - rb_const_set(node->nd_vid, val); + rb_const_set(the_class, node->nd_vid, val); return val; } break; case NODE_LVAR: - if (the_env->local_vars == Qnil) + if (the_scope->local_vars == Qnil) Bug("unexpected local variable"); - return the_env->local_vars[node->nd_cnt]; + return the_scope->local_vars[node->nd_cnt]; case NODE_GVAR: return rb_gvar_get(node->nd_entry); @@ -980,19 +1099,19 @@ rb_eval(node) Fail("Wrong # of arguments(%d for %d)", len, i); local = node->nd_frml; - if (the_env->local_vars == Qnil) + if (the_scope->local_vars == Qnil) Bug("unexpected local variable asignment"); - for (i=1;local;i++) { - the_env->local_vars[(int)local->nd_head] = the_env->argv[i-1]; + 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_env->local_vars[node->nd_rest] = ary_new(); + the_scope->local_vars[node->nd_rest] = ary_new(); else - the_env->local_vars[node->nd_rest] = - ary_new4(the_env->argc-i+1, the_env->argv+i-1); + the_scope->local_vars[node->nd_rest] = + ary_new4(the_env->argc-i, the_env->argv+i); } } return Qnil; @@ -1000,8 +1119,9 @@ rb_eval(node) case NODE_DEFN: { if (node->nd_defn) { - rb_add_method(the_class,node->nd_mid,node->nd_defn,0); - node->nd_defn = Qnil; + node->nd_defn->nd_cnt++; + rb_add_method(the_class,node->nd_mid,node->nd_defn, + node->nd_noex); } } return Qnil; @@ -1015,16 +1135,16 @@ 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); - node->nd_defn = Qnil; } } return Qnil; case NODE_UNDEF: { - rb_add_method(the_class, node->nd_mid, Qnil, 1); + rb_add_method(the_class, node->nd_mid, Qnil, 0); } return Qnil; @@ -1055,16 +1175,17 @@ rb_eval(node) unliteralize(class); } - PUSH_ENV(); + DUP_ENV(); + 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(); if (state) JUMP_TAG(state); } @@ -1081,15 +1202,16 @@ rb_eval(node) unliteralize(module); } - PUSH_ENV(); + DUP_ENV(); + 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(); if (state) JUMP_TAG(state); } @@ -1144,7 +1266,7 @@ rb_exit(status) exit(FIX2UINT(last_val)); } -VALUE +static VALUE Fexit(obj, args) VALUE obj, args; { @@ -1165,34 +1287,19 @@ Fexit(obj, args) void rb_break() { - if (the_env->flags & DURING_ITERATE) { - JUMP_TAG(TAG_BREAK); - } - else { - Fatal("unexpected break"); - } + JUMP_TAG(TAG_BREAK); } void rb_redo() { - if (the_env->flags & DURING_ITERATE) { - JUMP_TAG(TAG_REDO); - } - else { - Fatal("unexpected redo"); - } + JUMP_TAG(TAG_REDO); } void rb_retry() { - if (the_env->flags & DURING_RESQUE) { - JUMP_TAG(TAG_RETRY); - } - else { - Fatal("unexpected retry"); - } + JUMP_TAG(TAG_RETRY); } void @@ -1226,7 +1333,15 @@ rb_fail(mesg) VALUE iterator_p() { - return ITERATOR_P(); + if (iter_level == 0) return TRUE; + return FALSE; +} + +static VALUE +Fiterator_p() +{ + if (iter_level == -1) return TRUE; + return FALSE; } VALUE @@ -1234,21 +1349,20 @@ rb_yield(val) VALUE val; { struct BLOCK *block; - int state; - int go_out; + NODE *node; + int state, go_out; VALUE result; - int cnt; - &go_out; - block = the_env->block; - if (!ITERATOR_P()) { + if (!iter_level == 0) { Fail("yield called out of iterator"); } - PUSH_ENV(); - block->env.prev = the_env->prev; + block = the_block; + block->env.prev = the_env; the_env = &(block->env); - the_env->flags = the_env->prev->flags; + block->scope.prev = the_scope; + the_scope = &(block->scope); + the_block = block->prev; if (block->var) { if (block->var->type == NODE_MASGN) masign(block->var, val); @@ -1256,33 +1370,37 @@ rb_yield(val) asign(block->var, val); } - go_out = 0; PUSH_TAG(); + node = block->body; switch (state = EXEC_TAG()) { - retry: + redo: case 0: - if (block->body->type == NODE_CFUNC) { - the_env->flags |= DURING_ITERATE; - result = (*block->body->nd_cfnc)(val, block->body->nd_argc); + if (node->type == NODE_CFUNC) { + result = (*node->nd_cfnc)(val,node->nd_argc); } else { - result = rb_eval(block->body); + result = rb_eval(node); } + go_out = 0; break; - case TAG_RETRY: - goto retry; + case TAG_REDO: + goto redo; case TAG_CONTINUE: + go_out = 0; break; + case TAG_RETRY: case TAG_BREAK: case TAG_RETURN: target_level = block->level; state = IN_BLOCK|state; default: - go_out++; + go_out = 1; break; } POP_TAG(); - POP_ENV(); + the_block = block; + the_env = the_env->prev; + the_scope = the_scope->prev; if (go_out) JUMP_TAG(state); return result; @@ -1341,13 +1459,13 @@ asign(lhs, val) break; case NODE_LASGN: - if (the_env->local_vars == Qnil) + if (the_scope->local_vars == Qnil) Bug("unexpected iterator variable asignment"); - the_env->local_vars[lhs->nd_cnt] = val; + the_scope->local_vars[lhs->nd_cnt] = val; break; case NODE_CASGN: - rb_const_set(lhs->nd_vid, val); + rb_const_set(the_class, lhs->nd_vid, val); break; case NODE_CALL: @@ -1380,25 +1498,25 @@ rb_iterate(it_proc, data1, bl_proc, data2) VALUE (*it_proc)(), (*bl_proc)(); char *data1, *data2; { - int state; + int state, iter_saved; VALUE retval; NODE *node = NEW_CFUNC(bl_proc, data2); struct BLOCK block; - PUSH_ENV(); - block.level = tag_level; - block.var = Qnil; - block.body = node; - block.env = *the_env; - the_env->block = █ + DUP_ENV(); + PUSH_BLOCK(Qnil, node); PUSH_TAG(); + iter_saved = iter_level; + iter_level = 1; state = EXEC_TAG(); if (state == 0) { - the_env->iterator = 1; retval = (*it_proc)(data1); } + iter_level = iter_saved; + POP_TAG(); + POP_BLOCK(); POP_ENV(); freenode(node); @@ -1412,9 +1530,10 @@ rb_iterate(it_proc, data1, bl_proc, data2) } retval = Qnil; break; + case IN_BLOCK|TAG_RETRY: case IN_BLOCK|TAG_RETURN: if (target_level == tag_level) { - state = TAG_RETURN; + state &= ~IN_BLOCK; } /* fall through */ default: @@ -1433,13 +1552,12 @@ rb_resque(b_proc, data1, r_proc, data2) int go_out; VALUE result; - &go_out; - go_out = 0; PUSH_TAG(); switch (state = EXEC_TAG()) { case 0: retry_entry: result = (*b_proc)(data1); + go_out = 0; break; case TAG_FAIL: @@ -1447,7 +1565,6 @@ rb_resque(b_proc, data1, r_proc, data2) PUSH_TAG(); state = EXEC_TAG(); if (state == 0) { - the_env->flags |= DURING_RESQUE; result = (*r_proc)(data2); } POP_TAG(); @@ -1455,9 +1572,10 @@ rb_resque(b_proc, data1, r_proc, data2) case TAG_RETRY: goto retry_entry; case 0: + go_out = 0; break; default: - go_out++; + go_out = 1; break; } } @@ -1467,6 +1585,7 @@ rb_resque(b_proc, data1, r_proc, data2) break; default: + go_out = 1; break; } POP_TAG(); @@ -1515,37 +1634,46 @@ rb_undefined(obj, id) } static VALUE -rb_call(class, recv, mid, argc, argv) +rb_call(class, recv, mid, argc, argv, func) struct RClass *class; VALUE recv, *argv; int argc; ID mid; + int func; { NODE *body; + int noex; VALUE result; - VALUE saved_self = Qself; - int saved_ilevel = the_env->iterator; struct cache_entry *ent; - ID id; + PUSH_ENV(); Qself = recv; - if (the_env->iterator != 0) the_env->iterator++; + the_env->last_func = mid; + the_env->argc = argc; + the_env->argv = argv; + iter_level--; /* is it in the method cache? */ ent = cache + EXPR1(class, mid); if (ent->class == class && ent->mid == mid) { - if (ent->undef) rb_undefined(recv, mid); + if (ent->method == Qnil) rb_undefined(recv, mid); class = ent->origin; - id = ent->method->id; - body = ent->method->node; + mid = ent->mid; + body = ent->method->nd_head; + noex = ent->noex; } else { - id = mid; - if ((body = rb_get_method_body(&class, &id)) == Qnil) { + ID id = mid; + + if ((body = rb_get_method_body(&class, &id, &noex)) == Qnil) { rb_undefined(recv, mid); } + mid = id; } + if (!func && noex) rb_undefined(recv, mid); + the_env->last_class = class; + if (body->type == NODE_CFUNC) { int len = body->nd_argc; @@ -1553,125 +1681,112 @@ rb_call(class, recv, mid, argc, argv) Fail("Wrong # of arguments for(%d for %d)", argc, body->nd_argc); } - if (len == -2) { + switch (len) { + case -2: result = (*body->nd_cfnc)(recv, ary_new4(argc, argv)); - } - else if (len == -1) { + break; + case -1: result = (*body->nd_cfnc)(argc, argv); - } - else if (len >= 0) { - switch (argc) { - case 0: - result = (*body->nd_cfnc)(recv); - break; - case 1: - result = (*body->nd_cfnc)(recv, argv[0]); - break; - case 2: - result = (*body->nd_cfnc)(recv, argv[0], argv[1]); - break; - case 3: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2]); - break; - case 4: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3]); - break; - case 5: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4]); - break; - case 6: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5]); - break; - case 7: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6]); - break; - case 8: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7]); - break; - case 9: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8]); - break; - case 10: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8], - argv[6], argv[7], argv[8], - argv[9]); - break; - case 11: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8], - argv[6], argv[7], argv[8], - argv[9], argv[10]); - break; - case 12: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8], - argv[6], argv[7], argv[8], - argv[9], argv[10], argv[11]); - break; - case 13: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8], - argv[6], argv[7], argv[8], - argv[9], argv[10], argv[11], - argv[12]); - break; - case 14: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8], - argv[6], argv[7], argv[8], - argv[9], argv[10], argv[11], - argv[12], argv[13]); - break; - case 15: - result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], - argv[6], argv[7], argv[8], - argv[6], argv[7], argv[8], - argv[9], argv[10], argv[11], - argv[12], argv[13], argv[14]); - break; - default: + break; + case 0: + result = (*body->nd_cfnc)(recv); + break; + case 1: + result = (*body->nd_cfnc)(recv, argv[0]); + break; + case 2: + result = (*body->nd_cfnc)(recv, argv[0], argv[1]); + break; + case 3: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2]); + break; + case 4: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3]); + break; + case 5: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4]); + break; + case 6: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5]); + break; + case 7: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6]); + break; + case 8: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7]); + break; + case 9: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8]); + break; + case 10: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], + argv[6], argv[7], argv[8], + argv[9]); + break; + case 11: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], + argv[6], argv[7], argv[8], + argv[9], argv[10]); + break; + case 12: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], + argv[6], argv[7], argv[8], + argv[9], argv[10], argv[11]); + break; + case 13: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], + argv[6], argv[7], argv[8], + argv[9], argv[10], argv[11], + argv[12]); + break; + case 14: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], + argv[6], argv[7], argv[8], + argv[9], argv[10], argv[11], + argv[12], argv[13]); + break; + case 15: + result = (*body->nd_cfnc)(recv, argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], + argv[6], argv[7], argv[8], + argv[6], argv[7], argv[8], + argv[9], argv[10], argv[11], + argv[12], argv[13], argv[14]); + break; + default: + if (len < 0) { + Bug("bad argc(%d) specified for `%s(%s)'", + len, rb_class2name(class), rb_id2name(mid)); + } + else { Fail("too many arguments(%d)", len); - break; } - } - else { - Bug("bad argc(%d) specified for `%s(%s)'", - len, rb_class2name(class), rb_id2name(mid)); + break; } } else { int state; - PUSH_ENV(); - - the_env->local_vars = Qnil; - the_env->local_tbl = Qnil; - the_env->flags |= DURING_CALL; - the_env->argc = argc; - the_env->argv = argv; - the_env->last_class = class; - the_env->last_func = id; -#ifdef USE_CALLER - the_env->file = sourcefile; - the_env->line = sourceline; -#endif - + sourcefile = body->src; PUSH_TAG(); state = EXEC_TAG(); if (state == 0) { @@ -1699,32 +1814,34 @@ rb_call(class, recv, mid, argc, argv) default: JUMP_TAG(state); } - POP_ENV(); } - Qself = saved_self; - the_env->iterator = saved_ilevel; + iter_level++; + POP_ENV(); return result; } VALUE rb_apply(recv, mid, args) - VALUE recv, args; + VALUE recv; + struct RArray *args; ID mid; { VALUE *argv; int argc, i; - argc = RARRAY(args)->len + 1; - argv = (VALUE*)alloca(sizeof(VALUE)*argc); - for (i=1;i<argc;i++) { - argv[i] = RARRAY(args)->ptr[i-1]; + if (args) { + argc = args->len; + argv = args->ptr; } - argv[0] = Qnil; - return rb_call(CLASS_OF(recv), recv, mid, argc, argv); + else { + argc = 0; + argv = Qnil; + } + return rb_call(CLASS_OF(recv), recv, mid, argc, argv, recv==Qself); } -VALUE +static VALUE Fapply(recv, args) VALUE recv, args; { @@ -1768,49 +1885,12 @@ rb_funcall(recv, mid, n, va_alist) argv = Qnil; } - return rb_call(CLASS_OF(recv), recv, mid, n, argv); + return rb_call(CLASS_OF(recv), recv, mid, n, argv, recv==Qself); } -#ifdef USE_CALLER -VALUE -Fcaller(obj, args) - VALUE obj, args; -{ - VALUE level, file, res, ary; - int lev; - struct ENVIRON *e; - - rb_scan_args(args, "01", &level); - if (level == Qnil) { - lev = 1; - } - else { - lev = FIX2UINT(level); - } - if (lev < 0) Fail("negative level: %d", lev); - - e = the_env; - - while (lev > 0) { - e = e->prev; - if (e == Qnil) Fail("no caller"); - if (!(e->flags & DURING_CALL)) continue; - lev--; - } - if (e->file == Qnil) Fail("initial frame"); - - file = str_new2(e->file); - ary = e->argv?ary_new4(e->argc, e->argv):ary_new2(0); - res = ary_new3(5, file, INT2FIX(e->line), - str_new2(rb_id2name(e->last_func)), Qself, ary); - - return res; -} -#endif +int rb_in_eval = 0; -int in_eval = 0; - -VALUE +static VALUE Feval(obj, src) VALUE obj; struct RString *src; @@ -1822,15 +1902,13 @@ Feval(obj, src) Check_Type(src, T_STRING); PUSH_TAG(); - PUSH_ENV(); - the_env->in_eval = 1; + DUP_ENV(); + rb_in_eval = 1; node = eval_tree; - if (the_env->prev) { - the_class = the_env->prev->current_module; - } - else { - the_class = (struct RClass*)C_Object; + PUSH_CLASS(); + if (TYPE(the_class) == T_ICLASS) { + the_class = (struct RClass*)RBASIC(the_class)->class; } if ((state = EXEC_TAG()) == 0) { @@ -1843,9 +1921,9 @@ Feval(obj, src) } } eval_tree = node; + POP_CLASS(); POP_ENV(); POP_TAG(); - if (state) printf("exception in eval()\n"); if (state) JUMP_TAG(state); if (nerrs > 0) { @@ -1900,7 +1978,7 @@ Fload(obj, fname) VALUE obj; struct RString *fname; { - int state; + int state, in_eval = rb_in_eval; NODE *node; char *file; @@ -1927,13 +2005,13 @@ Fload(obj, fname) #endif PUSH_TAG(); - PUSH_ENV(); + DUP_ENV(); + PUSH_CLASS(); the_class = (struct RClass*)C_Object; Qself = TopSelf; - the_env->current_module = top_env->current_module; - the_env->local_vars = top_env->local_vars; - the_env->local_tbl = top_env->local_tbl; - the_env->in_eval = 1; + the_scope->local_vars = top_scope->local_vars; + the_scope->local_tbl = top_scope->local_tbl; + rb_in_eval = 1; state = EXEC_TAG(); if (state == 0) { rb_load_file(file); @@ -1941,8 +2019,10 @@ Fload(obj, fname) Eval(0); } } + POP_CLASS(); POP_ENV(); POP_TAG(); + rb_in_eval = in_eval; if (nerrs > 0) { rb_fail(errstr); } @@ -2006,9 +2086,10 @@ addpath(path) } } +extern VALUE C_Kernel; + Init_load() { - extern VALUE C_Builtin; extern VALUE rb_check_str(); char *path; @@ -2019,6 +2100,14 @@ Init_load() addpath(getenv("RUBYLIB")); addpath(RUBY_LIB); - rb_define_method(C_Builtin, "load", Fload, 1); - rb_define_method(C_Builtin, "require", Frequire, 1); + rb_define_private_method(C_Kernel, "load", Fload, 1); + rb_define_private_method(C_Kernel, "require", Frequire, 1); +} + +Init_eval() +{ + 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); } @@ -1064,8 +1064,6 @@ Init_File() C_File = rb_define_class("File", C_IO); - rb_include_module(CLASS_OF(C_File), M_FileTest); - rb_define_single_method(C_File, "stat", Ffile_stat, 1); rb_define_single_method(C_File, "lstat", Ffile_lstat, 1); rb_define_single_method(C_File, "type", Ffile_type, 1); @@ -1088,6 +1086,8 @@ Init_File() rb_define_single_method(C_File, "umask", Ffile_umask, -1); rb_define_single_method(C_File, "truncate", Ffile_truncate, 2); + rb_include_module(CLASS_OF(C_File), M_FileTest); + rb_define_method(C_File, "stat", Ffile_stat2, 0); rb_define_method(C_File, "lstat", Ffile_lstat2, 0); @@ -164,7 +164,7 @@ rb_global_variable(var) struct RVALUE { union { struct { - int flag; /* alway 0 for freed obj */ + UINT flag; /* alway 0 for freed obj */ struct RVALUE *next; } free; struct RObject object; @@ -505,7 +505,7 @@ freemethod(key, body) ID key; void *body; { - method_free(body); + freenode(body); return ST_CONTINUE; } @@ -570,6 +570,7 @@ gc() struct literal_list *lit; struct gc_list *list; struct ENVIRON *env; + struct SCOPE *scope; int i, max; jmp_buf save_regs_gc_mark; VALUE stack_end; @@ -582,8 +583,12 @@ gc() gc_mark(env->self); if (env->argv) mark_locations_array(env->argv, env->argc); - if (env->local_vars) - mark_locations_array(env->local_vars, env->local_tbl[0]); + } + + /* 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]); } FLUSH_REGISTER_WINDOWS; @@ -86,6 +86,12 @@ extern void bcopy (); # endif /* !RISC6000 */ #endif /* USG */ +#if defined(sparc) && !defined(__GNUC__) +#include <alloca.h> +#else +char *alloca (); +#endif + #include "fnmatch.h" /* If the opendir () on your system lets you open non-directory files, @@ -18,6 +18,7 @@ rb_call_inits() Init_var_tables(); Init_Object(); Init_GC(); + Init_eval(); Init_Comparable(); Init_Enumerable(); Init_Numeric(); @@ -21,7 +21,7 @@ VALUE rb_ad_string(); -VALUE C_IO, C_ARGFILE; +VALUE C_IO; extern VALUE C_File; VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout; @@ -29,6 +29,8 @@ VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout; VALUE FS, OFS; VALUE RS, ORS; +static VALUE argf; + ID id_write, id_fd, id_print_on; extern char *inplace; @@ -178,7 +180,7 @@ read_all(port) for (;;) { n = fread(buf, 1, BUFSIZ, fptr->f); if (n == 0) { - if (feof(fptr->f)) return Qnil; + if (feof(fptr->f)) break; rb_sys_fail(Qnil); } str_cat(str, buf, n); @@ -1261,26 +1263,26 @@ VALUE rb_readonly_hook(); Init_IO() { - extern VALUE C_Builtin; + extern VALUE C_Kernel; id_write = rb_intern("write"); id_fd = rb_intern("fd"); id_print_on = rb_intern("print_on"); - rb_define_method(C_Builtin, "syscall", Fsyscall, -1); + rb_define_private_method(C_Kernel, "syscall", Fsyscall, -1); - rb_define_method(C_Builtin, "open", Fopen, -2); - rb_define_method(C_Builtin, "printf", Fprintf, -1); - rb_define_method(C_Builtin, "print", Fprint, -1); - rb_define_method(C_Builtin, "gets", Fgets, 0); - rb_define_alias(C_Builtin,"readline", "gets"); - rb_define_method(C_Builtin, "eof", Feof, 0); - rb_define_method(C_Builtin, "getc", Fgetc, 0); - rb_define_method(C_Builtin, "select", Fselect, -2); + rb_define_private_method(C_Kernel, "open", Fopen, -2); + rb_define_private_method(C_Kernel, "printf", Fprintf, -1); + rb_define_private_method(C_Kernel, "gets", Fgets, 0); + rb_define_alias(C_Kernel,"readline", "gets"); + rb_define_private_method(C_Kernel, "eof", Feof, 0); + rb_define_private_method(C_Kernel, "getc", Fgetc, 0); + rb_define_private_method(C_Kernel, "select", Fselect, -2); - rb_define_method(C_Builtin, "readlines", Freadlines, 0); + rb_define_private_method(C_Kernel, "readlines", Freadlines, 0); - rb_define_method(C_Builtin, "print_on", Fprint_on, 1); + rb_define_method(C_Kernel, "print_on", Fprint_on, 1); + rb_define_method(C_Kernel, "print", Fprint, -1); C_IO = rb_define_class("IO", C_Object); rb_include_module(C_IO, M_Enumerable); @@ -1340,22 +1342,21 @@ Init_IO() rb_define_single_method(C_IO, "default", Fio_defget, 0); rb_define_single_method(C_IO, "default=", Fio_defset, 1); - C_ARGFILE = rb_define_class("ARGFILE", C_Object); - rb_include_module(C_ARGFILE, M_Enumerable); - - rb_define_variable("$ARGF", &C_ARGFILE, Qnil, rb_readonly_hook); + argf = obj_alloc(C_Object); + rb_define_variable("$ARGF", &argf, Qnil, rb_readonly_hook); - rb_define_single_method(C_ARGFILE, "each", Farg_each, 0); - rb_define_single_method(C_ARGFILE, "each_byte", Farg_each_byte, 0); + rb_define_single_method(argf, "each", Farg_each, 0); + rb_define_single_method(argf, "each_byte", Farg_each_byte, 0); - rb_define_single_method(C_ARGFILE, "read", Farg_read, 0); - rb_define_single_method(C_ARGFILE, "readlines", Freadlines, 0); - rb_define_single_method(C_ARGFILE, "gets", Fgets, 0); - rb_define_single_method(C_ARGFILE, "realine", Fgets, 0); - rb_define_single_method(C_ARGFILE, "getc", Farg_getc, 0); - rb_define_single_method(C_ARGFILE, "eof", Feof, 0); + rb_define_single_method(argf, "read", Farg_read, 0); + rb_define_single_method(argf, "readlines", Freadlines, 0); + rb_define_single_method(argf, "gets", Fgets, 0); + rb_define_single_method(argf, "realine", Fgets, 0); + rb_define_single_method(argf, "getc", Farg_getc, 0); + rb_define_single_method(argf, "eof", Feof, 0); - rb_define_single_method(C_ARGFILE, "to_s", Farg_to_s, 0); + rb_define_single_method(argf, "to_s", Farg_to_s, 0); + rb_include_module(CLASS_OF(argf), M_Enumerable); Init_File(); } @@ -100,7 +100,6 @@ Fmath_sqrt(obj, x) struct RFloat *x; { Need_Float(x); - return float_new(log10(x->value)); if (x->value < 0.0) Fail("square root for negative number"); return float_new(sqrt(x->value)); @@ -110,15 +109,13 @@ Init_Math() { M_Math = rb_define_module("Math"); - rb_define_method(M_Math, "atan2", Fmath_atan2, 2); - rb_define_method(M_Math, "cos", Fmath_cos, 1); - rb_define_method(M_Math, "sin", Fmath_sin, 1); - rb_define_method(M_Math, "tan", Fmath_tan, 1); - - rb_define_method(M_Math, "exp", Fmath_exp, 1); - rb_define_method(M_Math, "log", Fmath_log, 1); - rb_define_method(M_Math, "log10", Fmath_log10, 1); - rb_define_method(M_Math, "sqrt", Fmath_sqrt, 1); + rb_define_module_function(M_Math, "atan2", Fmath_atan2, 2); + rb_define_module_function(M_Math, "cos", Fmath_cos, 1); + rb_define_module_function(M_Math, "sin", Fmath_sin, 1); + rb_define_module_function(M_Math, "tan", Fmath_tan, 1); - rb_include_module(CLASS_OF(M_Math), M_Math); + rb_define_module_function(M_Math, "exp", Fmath_exp, 1); + rb_define_module_function(M_Math, "log", Fmath_log, 1); + rb_define_module_function(M_Math, "log10", Fmath_log10, 1); + rb_define_module_function(M_Math, "sqrt", Fmath_sqrt, 1); } diff --git a/newver.rb b/newver.rb index a8cad4d83e..884e873ba4 100644..100755 --- a/newver.rb +++ b/newver.rb @@ -9,8 +9,8 @@ if $_ =~ /"(\d+)\.(\d+)"/; if $ARGV[0] == "-f" i += 1 end - date = Time.now.strftime("%d %b %y") - printf("ruby version %d.%0d (%s)\n", $1, i, date) + date = Time.now.strftime("%y/%m/%d") + printf("ruby - version %d.%0d (%s)\n", $1, i, date) printf(f, "#define RUBY_VERSION \"%d.%0d\"\n", $1, i) printf(f, "#define VERSION_DATE \"%s\"\n", date) f.close @@ -14,6 +14,8 @@ #define NODE_H enum node_type { + NODE_METHOD, + NODE_FBODY, NODE_CFUNC, NODE_SCOPE, NODE_BLOCK, @@ -23,7 +25,7 @@ enum node_type { NODE_WHILE, NODE_WHILE2, NODE_EXNOT, - NODE_DO, + NODE_ITER, NODE_FOR, NODE_PROT, NODE_AND, @@ -141,10 +143,11 @@ typedef struct node { #define nd_mid u2.id #define nd_args u3.node +#define nd_noex u1.id #define nd_defn u3.node -#define nd_new u1.id -#define nd_old u2.id +#define nd_new u2.id +#define nd_old u3.id #define nd_cfnc u1.cfunc #define nd_argc u2.argc @@ -157,14 +160,15 @@ typedef struct node { #define nd_beg u1.node #define nd_end u2.node #define nd_state u3.state - #define nd_rval u3.node -#define NEW_DEFN(i,d) newnode(NODE_DEFN,Qnil,i,d) -#define NEW_DEFS(r,i,d) newnode(NODE_DEFS,r,i,d) +#define NEW_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_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_SCOPE(b) newnode(NODE_SCOPE,local_tbl(),(b),local_cnt(0)) #define NEW_BLOCK(a) newnode(NODE_BLOCK,a,Qnil,Qnil) #define NEW_IF(c,t,e) newnode(NODE_IF,c,t,e) #define NEW_EXNOT(c) newnode(NODE_EXNOT,c,Qnil,Qnil) @@ -176,7 +180,7 @@ typedef struct node { #define NEW_WHILE2(c,b) newnode(NODE_WHILE2,c,b,Qnil) #define NEW_UNTIL2(c,b) newnode(NODE_WHILE2,NEW_EXNOT(c),b,Qnil) #define NEW_FOR(v,i,b) newnode(NODE_FOR,v,b,i) -#define NEW_DO(v,i,b) newnode(NODE_DO,v,b,i) +#define NEW_ITER(v,i,b) newnode(NODE_ITER,v,b,i) #define NEW_PROT(b,ex,en) newnode(NODE_PROT,b,ex,en) #define NEW_REDO() newnode(NODE_REDO,Qnil,Qnil,Qnil) #define NEW_BREAK() newnode(NODE_BREAK,Qnil,Qnil,Qnil) @@ -212,7 +216,7 @@ typedef struct node { #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_ALIAS(n,o) newnode(NODE_ALIAS,n,o,Qnil) +#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) #define NEW_MODULE(n,b) newnode(NODE_MODULE,n,NEW_SCOPE(b),Qnil) @@ -11,6 +11,7 @@ ************************************************/ #include "ruby.h" +#include "env.h" #include <math.h> static ID coerce; @@ -36,11 +37,11 @@ float_new(d) } static -num_coerce_bin(x, mid, y) +num_coerce_bin(x, y) VALUE x, y; - ID mid; { - return rb_funcall(rb_funcall(y, coerce, 1, x), mid, 1, y); + return rb_funcall(rb_funcall(y, coerce, 1, x), + the_env->last_func, 1, y); } static VALUE @@ -54,7 +55,7 @@ static VALUE Fnum_uminus(num) VALUE num; { - return rb_funcall(rb_funcall(num, coerce, 1, INT2FIX(0)), '-', 1, num); + return rb_funcall(rb_funcall(num, coerce, 1, INT2FIX(0)), 1, num); } static VALUE @@ -166,20 +167,6 @@ Fnum_is_int(num) } static VALUE -Fflo_new(flt) - struct RFloat *flt; -{ - Check_Type(flt, T_FLOAT); - { - NEWOBJ(flt2, struct RFloat); - CLONESETUP(flt2, flt); - - flt2->value = flt->value; - return (VALUE)flt2; - } -} - -static VALUE Fflo_to_s(flt) struct RFloat *flt; { @@ -229,7 +216,7 @@ Fflo_plus(x, y) case T_STRING: return Fstr_plus(obj_as_string(x), y); default: - return num_coerce_bin(x, '+', y); + return num_coerce_bin(x, y); } } @@ -245,7 +232,7 @@ Fflo_minus(x, y) case T_FLOAT: return float_new(x->value - y->value); default: - return num_coerce_bin(x, '-', y); + return num_coerce_bin(x, y); } } @@ -263,7 +250,7 @@ Fflo_mul(x, y) case T_STRING: return Fstr_times(y, INT2FIX((int)x->value)); default: - return num_coerce_bin(x, '*', y); + return num_coerce_bin(x, y); } } @@ -287,7 +274,7 @@ Fflo_div(x, y) if (y->value == 0.0) Fail("devided by 0"); return float_new(x->value / y->value); default: - return num_coerce_bin(x, '/', y); + return num_coerce_bin(x, y); } } @@ -308,7 +295,7 @@ Fflo_mod(x, y) value = y->value; break; default: - return num_coerce_bin(x, '%', y); + return num_coerce_bin(x, y); } #ifdef HAVE_FMOD { @@ -338,7 +325,7 @@ Fflo_pow(x, y) case T_FLOAT: return float_new(pow(x->value, y->value)); default: - return num_coerce_bin(x, rb_intern("**"), y); + return num_coerce_bin(x, y); } } @@ -357,7 +344,7 @@ Fflo_eq(x, y) case T_FLOAT: return (x->value == y->value)?TRUE:FALSE; default: - return num_coerce_bin(x, rb_intern("=="), y); + return num_coerce_bin(x, y); } } @@ -399,7 +386,7 @@ Fflo_cmp(x, y) break; default: - return num_coerce_bin(x, rb_intern("<=>"), y); + return num_coerce_bin(x, y); } if (a == b) return INT2FIX(0); if (a > b) return INT2FIX(1); @@ -428,15 +415,6 @@ Fflo_to_f(num) } static VALUE -Fflo_clone(flt) - struct RFloat *flt; -{ - VALUE flt2 = float_new(flt->value); - CLONESETUP(flt2, flt); - return flt2; -} - -static VALUE Fflo_abs(flt) struct RFloat *flt; { @@ -529,13 +507,6 @@ Fint_chr(num) return str_new(&c, 1); } -VALUE -Ffix_clone(num) - VALUE num; -{ - return num; -} - static VALUE Ffix_uminus(num) VALUE num; @@ -591,7 +562,7 @@ Ffix_plus(x, y) case T_FLOAT: return float_new((double)FIX2INT(x) + y->value); default: - return num_coerce_bin(x, '+', y); + return num_coerce_bin(x, y); } } @@ -619,7 +590,7 @@ Ffix_minus(x, y) case T_FLOAT: return float_new((double)FIX2INT(x) - y->value); default: - return num_coerce_bin(x, '-', y); + return num_coerce_bin(x, y); } } @@ -643,7 +614,7 @@ Ffix_mul(x, y) case T_FLOAT: return float_new((double)FIX2INT(x) * y->value); default: - return num_coerce_bin(x, '*', y); + return num_coerce_bin(x, y); } } @@ -660,7 +631,7 @@ Ffix_div(x, y) i = FIX2INT(x)/i; return INT2FIX(i); } - return num_coerce_bin(x, '/', y); + return num_coerce_bin(x, y); } static VALUE @@ -675,7 +646,7 @@ Ffix_mod(x, y) i = FIX2INT(x)%i; return INT2FIX(i); } - return num_coerce_bin(x, '%', y); + return num_coerce_bin(x, y); } static VALUE @@ -698,7 +669,7 @@ Ffix_pow(x, y) else if (NIL_P(y)) { return INT2FIX(1); } - return num_coerce_bin(x, rb_intern("**"), y); + return num_coerce_bin(x, y); } static VALUE @@ -712,7 +683,7 @@ Ffix_equal(x, y) return Qnil; } else { - return num_coerce_bin(x, rb_intern("=="), y); + return num_coerce_bin(x, y); } } @@ -728,7 +699,67 @@ Ffix_cmp(x, y) return INT2FIX(-1); } else { - return num_coerce_bin(x, rb_intern("<=>"), y); + return num_coerce_bin(x, y); + } +} + +static VALUE +Ffix_gt(x, y) + VALUE x, y; +{ + if (FIXNUM_P(y)) { + int a = FIX2INT(x), b = FIX2INT(y); + + if (a > b) return TRUE; + return FALSE; + } + else { + return num_coerce_bin(x, y); + } +} + +static VALUE +Ffix_ge(x, y) + VALUE x, y; +{ + if (FIXNUM_P(y)) { + int a = FIX2INT(x), b = FIX2INT(y); + + if (a >= b) return TRUE; + return FALSE; + } + else { + return num_coerce_bin(x, y); + } +} + +static VALUE +Ffix_lt(x, y) + VALUE x, y; +{ + if (FIXNUM_P(y)) { + int a = FIX2INT(x), b = FIX2INT(y); + + if (a < b) return TRUE; + return FALSE; + } + else { + return num_coerce_bin(x, y); + } +} + +static VALUE +Ffix_le(x, y) + VALUE x, y; +{ + if (FIXNUM_P(y)) { + int a = FIX2INT(x), b = FIX2INT(y); + + if (a <= b) return TRUE; + return FALSE; + } + else { + return num_coerce_bin(x, y); } } @@ -891,6 +922,10 @@ Init_Numeric() to_i = rb_intern("to_i"); C_Numeric = rb_define_class("Numeric", C_Object); + + rb_undef_method(CLASS_OF(C_Numeric), "new"); + rb_undef_method(CLASS_OF(C_Numeric), "clone"); + rb_include_module(C_Numeric, M_Comparable); rb_define_method(C_Numeric, "+@", Fnum_uplus, 0); rb_define_method(C_Numeric, "-@", Fnum_uminus, 0); @@ -910,9 +945,9 @@ Init_Numeric() rb_define_method(C_Integer, "chr", Fint_chr, 0); C_Fixnum = rb_define_class("Fixnum", C_Integer); + rb_define_method(C_Fixnum, "to_s", Ffix_to_s, 0); rb_define_method(C_Fixnum, "class", Ffix_class, 0); - rb_define_method(C_Fixnum, "clone", Ffix_clone, 0); rb_define_method(C_Fixnum, "id2name", Ffix_id2name, 0); @@ -928,6 +963,10 @@ Init_Numeric() rb_define_method(C_Fixnum, "==", Ffix_equal, 1); rb_define_method(C_Fixnum, "<=>", Ffix_cmp, 1); + rb_define_method(C_Fixnum, ">", Ffix_gt, 1); + rb_define_method(C_Fixnum, ">=", Ffix_ge, 1); + rb_define_method(C_Fixnum, "<", Ffix_lt, 1); + rb_define_method(C_Fixnum, "<=", Ffix_le, 1); rb_define_method(C_Fixnum, "..", Ffix_dot2, 1); rb_define_method(C_Fixnum, "~", Ffix_rev, 0); @@ -945,8 +984,7 @@ Init_Numeric() rb_define_method(C_Fixnum, "next", Ffix_next, 0); C_Float = rb_define_class("Float", C_Numeric); - rb_define_single_method(C_Float, "new", Fflo_new, 1); - rb_define_method(C_Float, "clone", Fflo_clone, 0); + rb_define_method(C_Float, "to_s", Fflo_to_s, 0); rb_define_method(C_Float, "coerce", Fflo_coerce, 1); rb_define_method(C_Float, "-@", Fflo_uminus, 0); @@ -17,7 +17,6 @@ #include <stdio.h> VALUE C_Kernel; -VALUE C_Builtin; VALUE C_Object; VALUE C_Module; VALUE C_Class; @@ -27,15 +26,10 @@ VALUE C_Data; struct st_table *new_idhash(); VALUE Fsprintf(); -VALUE Fexit(); -VALUE Feval(); -VALUE Fapply(); VALUE Fdefined(); -VALUE Fcaller(); VALUE obj_responds_to(); VALUE obj_alloc(); -VALUE Ffix_clone(); static ID eq, match; @@ -62,13 +56,6 @@ Fkrn_equal(obj, other) } static VALUE -Fkrn_hash(obj) - VALUE obj; -{ - return obj; -} - -static VALUE Fkrn_to_a(obj) VALUE obj; { @@ -228,13 +215,6 @@ Fobj_clone(obj) } static VALUE -Fiterator_p() -{ - if (the_env->iterator > 1 && the_env->iterator < 4) return TRUE; - return FALSE; -} - -static VALUE Fnil_to_s(obj) VALUE obj; { @@ -317,6 +297,45 @@ Fcls_attr(class, args) } static VALUE +Fcls_export_internal(argc, argv, ex) + int argc; + VALUE *argv; + int ex; +{ + VALUE self = Qself; + int i; + ID id; + + for (i=0; i<argc; i++) { + if (FIXNUM_P(argv[i])) { + id = FIX2INT(argv[i]); + } + else { + Check_Type(argv[i], T_STRING); + id = rb_intern(RSTRING(argv[i])->ptr); + } + rb_export_method(self, id, ex); + } + return Qnil; +} + +static VALUE +Fcls_export(argc, argv) + int argc; + VALUE *argv; +{ + Fcls_export_internal(argc, argv, 0); +} + +static VALUE +Fcls_unexport(argc, argv) + int argc; + VALUE *argv; +{ + Fcls_export_internal(argc, argv, 1); +} + +static VALUE Fcant_clone(obj) VALUE obj; { @@ -348,13 +367,11 @@ Init_Object() VALUE metaclass; C_Kernel = boot_defclass("Kernel", Qnil); - C_Builtin = boot_defclass("Builtin", C_Kernel); - C_Object = boot_defclass("Object", C_Builtin); + C_Object = boot_defclass("Object", C_Kernel); C_Module = boot_defclass("Module", C_Object); C_Class = boot_defclass("Class", C_Module); metaclass = RBASIC(C_Kernel)->class = single_class_new(C_Class); - metaclass = RBASIC(C_Builtin)->class = single_class_new(metaclass); metaclass = RBASIC(C_Object)->class = single_class_new(metaclass); metaclass = RBASIC(C_Module)->class = single_class_new(metaclass); metaclass = RBASIC(C_Class)->class = single_class_new(metaclass); @@ -368,13 +385,10 @@ Init_Object() * | Kernel----->(Kernel) | * | ^ ^ ^ ^ | * | | | | | | - * | +---+ +-----+ | +---+ | - * | | +------|---+ | | - * | | | | | | - * +->Nil->(Nil) Builtin--->(Builtin) | - * ^ ^ | - * | | | - * Object---->(Object) | + * | +---+ +----+ | +---+ | + * | | +-----|----+ | | + * | | | | | | + * +->Nil->(Nil) Object---->(Object) | * ^ ^ ^ ^ | * | | | | | * | | +-------+ | | @@ -396,7 +410,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", Fkrn_hash, 0); + rb_define_method(C_Kernel, "hash", rb_self, 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); @@ -407,17 +421,9 @@ Init_Object() rb_define_method(C_Kernel, "to_s", Fkrn_to_s, 0); rb_define_method(C_Kernel, "_inspect", Fkrn_inspect, 0); -#ifdef USE_CALLER - rb_define_method(C_Builtin, "caller", Fcaller, -2); -#endif - rb_define_method(C_Builtin, "exit", Fexit, -2); - rb_define_method(C_Builtin, "eval", Feval, 1); - rb_define_method(C_Builtin, "defined", Fdefined, 1); - rb_define_method(C_Builtin, "sprintf", Fsprintf, -1); - rb_define_alias(C_Builtin, "format", "sprintf"); - rb_define_method(C_Builtin, "iterator_p", Fiterator_p, 0); - - rb_define_method(C_Builtin, "apply", Fapply, -2); + rb_define_private_method(C_Kernel, "defined", Fdefined, 1); + rb_define_private_method(C_Kernel, "sprintf", Fsprintf, -1); + rb_define_alias(C_Kernel, "format", "sprintf"); rb_define_method(C_Object, "_inspect", Fobj_inspect, 0); @@ -428,13 +434,15 @@ Init_Object() rb_define_method(C_Module, "to_s", Fcls_to_s, 0); rb_define_method(C_Module, "clone", Fcant_clone, 0); - rb_define_method(C_Module, "attr", Fcls_attr, -2); + rb_define_private_method(C_Module, "attr", Fcls_attr, -2); + rb_define_method(C_Module, "export", Fcls_export, -1); + rb_define_method(C_Module, "unexport", Fcls_unexport, -1); rb_define_method(C_Class, "new", Fcls_new, -2); 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", Ffix_clone, 0); + rb_define_method(C_Nil, "clone", rb_self, 0); rb_define_method(C_Nil, "class", Fnil_class, 0); rb_define_method(C_Nil, "is_nil", P_true, 0); @@ -455,7 +463,7 @@ Init_Object() TRUE = obj_alloc(C_Object); rb_define_single_method(TRUE, "to_s", Ftrue_to_s, 0); - rb_define_const(C_Builtin, "%TRUE", TRUE); - rb_define_const(C_Builtin, "%FALSE", FALSE); + rb_define_const(C_Kernel, "%TRUE", TRUE); + rb_define_const(C_Kernel, "%FALSE", FALSE); } @@ -29,7 +29,7 @@ #define is_const_id(id) (is_id_nonop(id)&&((id)&ID_SCOPE_MASK)==ID_CONST) struct op_tbl { - ID tok; + ID token; char *name; }; @@ -133,7 +133,7 @@ static void setup_top_local(); %type <node> f_arglist f_args f_arg assoc_list assocs assoc %type <node> mlhs mlhs_head mlhs_tail lhs iter_var opt_iter_var %type <id> superclass variable symbol -%type <id> fname fname0 op rest_arg +%type <id> fname op rest_arg %token UPLUS /* unary+ */ %token UMINUS /* unary- */ @@ -244,10 +244,11 @@ stmt : CLASS IDENTIFIER superclass cur_mid = $2; push_local(); } - f_arglist compstmts + f_arglist + compstmts END { - $$ = NEW_DEFN($2, NEW_RFUNC($4, $5)); + $$ = NEW_DEFN($2, NEW_RFUNC($4, $5), cur_class?0:1); pop_local(); cur_mid = Qnil; } @@ -271,7 +272,7 @@ stmt : CLASS IDENTIFIER superclass } | DEF fname fname { - $$ = NEW_ALIAS($2, $3); + $$ = NEW_ALIAS($2, $3); } | INCLUDE inc_list { @@ -438,10 +439,7 @@ inc_list : IDENTIFIER $$ = $1; } -fname : fname0 - | IVAR - -fname0 : IDENTIFIER +fname : IDENTIFIER | op { lex_state = EXPR_END; @@ -844,10 +842,6 @@ expr0 : literal { $$ = NEW_CALL(Qnil, $1, $3); } - | IVAR '(' call_args rparen - { - $$ = NEW_CALL(Qnil, $1, $3); - } | SUPER '(' call_args rparen { if (!cur_mid && !in_single) @@ -906,7 +900,7 @@ expr0 : literal } | expr0 lbrace opt_iter_var '|' compstmts rbrace { - $$ = NEW_DO($3, $1, $5); + $$ = NEW_ITER($3, $1, $5); } | expr0 '.' IDENTIFIER '(' call_args rparen { @@ -1002,7 +996,7 @@ opt_iter_var : /* none */ | iter_var cases : opt_else - | WHEN args term + | WHEN args then compstmts cases { @@ -1039,7 +1033,7 @@ literal : numeric | GLOB -symbol : fname0 +symbol : fname | IVAR | GVAR | CONSTANT @@ -1856,6 +1850,9 @@ retry: case '.': /* $.: last read line number */ case '_': /* $_: last read line string */ case '&': /* $&: last match */ + case '`': /* $&: string before last match */ + case '\'': /* $&: string after last match */ + case '+': /* $&: string matches last paren. */ case '~': /* $~: match-data */ case '=': /* $=: ignorecase */ tokadd(c); @@ -2286,6 +2283,11 @@ void freenode(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); @@ -2317,7 +2319,7 @@ void freenode(node) freenode(node->nd_head); freenode(node->nd_body); break; - case NODE_DO: + case NODE_ITER: case NODE_FOR: freenode(node->nd_var); freenode(node->nd_ibdy); @@ -2377,6 +2379,7 @@ void freenode(node) break; case NODE_CLASS: case NODE_MODULE: + case NODE_METHOD: freenode(node->nd_body); break; case NODE_CONST: @@ -2670,7 +2673,7 @@ push_local() lvtbl = local; } -void +static void pop_local() { struct local_vars *local = lvtbl; @@ -2726,42 +2729,42 @@ init_top_local() if (lvtbl == Qnil) { push_local(); } - else if (the_env->local_tbl) { - lvtbl->cnt = the_env->local_tbl[0]; + else if (the_scope->local_tbl) { + lvtbl->cnt = the_scope->local_tbl[0]; } else { lvtbl->cnt = 0; } - lvtbl->tbl = the_env->local_tbl; + lvtbl->tbl = the_scope->local_tbl; } static void setup_top_local() { if (lvtbl->cnt > 0) { - if (the_env->local_vars == Qnil) { - the_env->local_vars = ALLOC_N(VALUE, lvtbl->cnt); - memset(the_env->local_vars, 0, lvtbl->cnt * sizeof(VALUE)); + if (the_scope->local_vars == Qnil) { + the_scope->local_vars = ALLOC_N(VALUE, lvtbl->cnt); + memset(the_scope->local_vars, 0, lvtbl->cnt * sizeof(VALUE)); } else if (lvtbl->tbl[0] < lvtbl->cnt) { int i; - if (the_env->flags&VARS_MALLOCED) { - REALLOC_N(the_env->local_vars, VALUE, lvtbl->cnt); + if (the_scope->flags&VARS_MALLOCED) { + REALLOC_N(the_scope->local_vars, VALUE, lvtbl->cnt); } else { - VALUE *vars = the_env->local_vars; - the_env->local_vars = ALLOC_N(VALUE, lvtbl->cnt); - memcpy(the_env->local_vars, vars, sizeof(VALUE)*lvtbl->cnt); - the_env->flags |= VARS_MALLOCED; + VALUE *vars = the_scope->local_vars; + the_scope->local_vars = ALLOC_N(VALUE, lvtbl->cnt); + memcpy(the_scope->local_vars, vars, sizeof(VALUE)*lvtbl->cnt); + the_scope->flags |= VARS_MALLOCED; } - memset(the_env->local_vars+i, 0, lvtbl->cnt-i); + memset(the_scope->local_vars+i, 0, lvtbl->cnt-i); } lvtbl->tbl[0] = lvtbl->cnt; - the_env->local_tbl = lvtbl->tbl; + the_scope->local_tbl = lvtbl->tbl; } else { - the_env->local_vars = Qnil; + the_scope->local_vars = Qnil; } } @@ -2879,9 +2882,9 @@ rb_intern(name) int i; id = Qnil; - for (i=0; rb_op_tbl[i].tok; i++) { + for (i=0; rb_op_tbl[i].token; i++) { if (strcmp(rb_op_tbl[i].name, name) == 0) { - id = rb_op_tbl[i].tok; + id = rb_op_tbl[i].token; break; } } @@ -2931,8 +2934,8 @@ rb_id2name(id) if (id < LAST_TOKEN) { int i = 0; - for (i=0; rb_op_tbl[i].tok; i++) { - if (rb_op_tbl[i].tok == id) + for (i=0; rb_op_tbl[i].token; i++) { + if (rb_op_tbl[i].token == id) return rb_op_tbl[i].name; } } @@ -2966,9 +2969,11 @@ rb_class2name(class) find_ok = Qnil; switch (TYPE(class)) { + case T_ICLASS: + class = (struct RClass*)RBASIC(class)->class; + break; case T_CLASS: case T_MODULE: - case T_ICLASS: break; default: Fail("0x%x is not a class/module", class); @@ -693,7 +693,7 @@ Fsleep(argc, argv) int beg, end; beg = time(0); - if (argc == 1) { + if (argc == 0) { sleep((32767<<16)+32767); } else if (argc == 1) { @@ -832,19 +832,19 @@ VALUE M_Process; Init_process() { - extern VALUE C_Builtin; + extern VALUE C_Kernel; - rb_define_variable("$$", Qnil, get_pid, rb_readonly_hook); + rb_define_variable("$$", Qnil, get_pid, Qnil); rb_define_variable("$?", &status, Qnil, rb_readonly_hook); - rb_define_method(C_Builtin, "exec", Fexec, 1); - rb_define_method(C_Builtin, "fork", Ffork, 0); - rb_define_method(C_Builtin, "_exit", Ffork, 1); - rb_define_method(C_Builtin, "wait", Fwait, 0); - rb_define_method(C_Builtin, "waitpid", Fwaitpid, 2); - rb_define_method(C_Builtin, "system", Fsystem, 1); - rb_define_method(C_Builtin, "kill", Fkill, -1); - rb_define_method(C_Builtin, "trap", Ftrap, -1); - rb_define_method(C_Builtin, "sleep", Fsleep, -1); + 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); + rb_define_private_method(C_Kernel, "wait", Fwait, 0); + rb_define_private_method(C_Kernel, "waitpid", Fwaitpid, 2); + rb_define_private_method(C_Kernel, "system", Fsystem, 1); + rb_define_private_method(C_Kernel, "kill", Fkill, -1); + rb_define_private_method(C_Kernel, "trap", Ftrap, -1); + rb_define_private_method(C_Kernel, "sleep", Fsleep, -1); M_Process = rb_define_module("Process"); @@ -854,27 +854,21 @@ Init_process() rb_define_single_method(M_Process, "waitpid", Fwaitpid, 2); rb_define_single_method(M_Process, "kill", Fkill, -1); - rb_define_method(M_Process, "pid", get_pid, 0); - rb_define_method(M_Process, "ppid", get_ppid, 0); + rb_define_module_function(M_Process, "pid", get_pid, 0); + rb_define_module_function(M_Process, "ppid", get_ppid, 0); - rb_define_method(M_Process, "getpgrp", Fproc_getpgrp, -2); - rb_define_method(M_Process, "setpgrp", Fproc_setpgrp, 2); + rb_define_module_function(M_Process, "getpgrp", Fproc_getpgrp, -2); + rb_define_module_function(M_Process, "setpgrp", Fproc_setpgrp, 2); - rb_define_method(M_Process, "getpriority", Fproc_getpriority, 2); - rb_define_method(M_Process, "setpriority", Fproc_setpriority, 3); + rb_define_module_function(M_Process, "getpriority", Fproc_getpriority, 2); + rb_define_module_function(M_Process, "setpriority", Fproc_setpriority, 3); rb_define_const(M_Process, "%PRIO_PROCESS", INT2FIX(PRIO_PROCESS)); rb_define_const(M_Process, "%PRIO_PGRP", INT2FIX(PRIO_PGRP)); rb_define_const(M_Process, "%PRIO_USER", INT2FIX(PRIO_USER)); - rb_define_single_method(M_Process, "uid", Fproc_getuid, 0); - rb_define_method(M_Process, "uid", Fproc_getuid, 0); - rb_define_single_method(M_Process, "uid=", Fproc_setuid, 1); - rb_define_method(M_Process, "uid=", Fproc_setuid, 1); - rb_define_single_method(M_Process, "euid", Fproc_geteuid, 0); - rb_define_method(M_Process, "euid", Fproc_geteuid, 0); - rb_define_single_method(M_Process, "euid=", Fproc_seteuid, 1); - rb_define_method(M_Process, "euid=", Fproc_seteuid, 1); - - rb_include_module(CLASS_OF(M_Process), M_Process); + rb_define_module_function(M_Process, "uid", Fproc_getuid, 0); + rb_define_module_function(M_Process, "uid=", Fproc_setuid, 1); + rb_define_module_function(M_Process, "euid", Fproc_geteuid, 0); + rb_define_module_function(M_Process, "euid=", Fproc_seteuid, 1); } @@ -73,8 +73,8 @@ Frand(obj, max) Init_Random() { - extern VALUE C_Builtin; + extern VALUE C_Kernel; - rb_define_method(C_Builtin, "srand", Fsrand, -2); - rb_define_method(C_Builtin, "rand", Frand, 1); + rb_define_private_method(C_Kernel, "srand", Fsrand, -2); + rb_define_private_method(C_Kernel, "rand", Frand, 1); } @@ -153,17 +153,13 @@ research(reg, str, start, ignorecase) OBJSETUP(obj, C_Data, T_DATA); obj->dfree = free_match; data = (struct match*)DATA_PTR(obj); - memset(data, 0, sizeof(struct match)); - beg = reg->ptr->regs.start[0]; - data->len = reg->ptr->regs.end[0] - beg; - data->ptr = ALLOC_N(char, data->len+1); - memcpy(data->ptr, str->ptr + beg, data->len); + + data->len = str->len; + data->ptr = ALLOC_N(char, str->len+1); + memcpy(data->ptr, str->ptr, data->len); data->ptr[data->len] = '\0'; - for (i=0; i<RE_NREGS; i++) { - if (reg->ptr->regs.start[i] == -1) break; - data->regs.start[i] = reg->ptr->regs.start[i] - beg; - data->regs.end[i] = reg->ptr->regs.end[i] - beg; - } + data->regs = reg->ptr->regs; + last_match_data = (VALUE)obj; } @@ -182,7 +178,6 @@ nth_match(nth) struct match *match; match = (struct match*)DATA_PTR(last_match_data); - if (nth == 0) return str_new(match->ptr, match->len); start = match->regs.start[nth]; if (start == -1) return Qnil; end = match->regs.end[nth]; @@ -199,6 +194,44 @@ re_last_match(id) return nth_match(0); } +static VALUE +re_match_pre() +{ + struct match *match; + + if (!last_match_data) return Qnil; + + match = (struct match*)DATA_PTR(last_match_data); + return str_new(match->ptr, match->regs.start[0]); +} + +static VALUE +re_match_post() +{ + struct match *match; + + if (!last_match_data) return Qnil; + + match = (struct match*)DATA_PTR(last_match_data); + return str_new(match->ptr+match->regs.end[0], match->ptr+match->len); +} + +static VALUE +re_match_last() +{ + struct match *match; + int i; + + if (!last_match_data) return Qnil; + + match = (struct match*)DATA_PTR(last_match_data); + for (i=0; i<RE_NREGS; i++) { + if (match->regs.start[i] == -1) break; + } + i--; + return nth_match(i); +} + #ifdef __STDC__ #define CONCAT(a,b) a##b #else @@ -405,7 +438,54 @@ re_regsub(str) return val; } -VALUE rb_readonly_hook(); +void +rb_set_kanjicode(code) + char *code; +{ + if (code == Qnil) goto set_no_conversion; + + switch (code[0]) { + case 'E': + case 'e': + obscure_syntax &= ~RE_MBCTYPE_MASK; + obscure_syntax |= RE_MBCTYPE_EUC; + break; + case 'S': + case 's': + obscure_syntax &= ~RE_MBCTYPE_MASK; + obscure_syntax |= RE_MBCTYPE_SJIS; + break; + default: + case 'N': + case 'n': + set_no_conversion: + obscure_syntax &= ~RE_MBCTYPE_MASK; + break; + } + re_set_syntax(obscure_syntax); +} + +static VALUE +kanji_var_get() +{ + switch (obscure_syntax & RE_MBCTYPE_MASK) { + case RE_MBCTYPE_SJIS: + return str_new2("SJIS"); + case RE_MBCTYPE_EUC: + return str_new2("EUC"); + default: + return Qnil; + } +} + +static void +kanji_var_set(val) + struct RString *val; +{ + if (val == Qnil) rb_set_kanjicode(Qnil); + Check_Type(val, T_STRING); + rb_set_kanjicode(val->ptr); +} void Init_Regexp() @@ -417,17 +497,22 @@ Init_Regexp() rb_define_variable("$~", last_match_data, Qnil, store_match_data); - rb_define_variable("$&", Qnil, re_last_match, rb_readonly_hook); - - rb_define_variable("$1", Qnil, GET_MATCH(1), rb_readonly_hook); - rb_define_variable("$2", Qnil, GET_MATCH(2), rb_readonly_hook); - rb_define_variable("$3", Qnil, GET_MATCH(3), rb_readonly_hook); - rb_define_variable("$4", Qnil, GET_MATCH(4), rb_readonly_hook); - rb_define_variable("$5", Qnil, GET_MATCH(5), rb_readonly_hook); - rb_define_variable("$6", Qnil, GET_MATCH(6), rb_readonly_hook); - rb_define_variable("$7", Qnil, GET_MATCH(7), rb_readonly_hook); - rb_define_variable("$8", Qnil, GET_MATCH(8), rb_readonly_hook); - rb_define_variable("$9", Qnil, GET_MATCH(9), rb_readonly_hook); + 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("$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("$KANJI", Qnil, kanji_var_get, kanji_var_set); rb_define_variable("$=", &ignorecase, Qnil, Qnil); @@ -176,24 +176,7 @@ proc_options(argcp, argvp) break; case 'C': - switch (optarg[0]) { - case 'E': - case 'e': - obscure_syntax &= ~RE_MBCTYPE_MASK; - obscure_syntax |= RE_MBCTYPE_EUC; - break; - case 'S': - case 's': - obscure_syntax &= ~RE_MBCTYPE_MASK; - obscure_syntax |= RE_MBCTYPE_SJIS; - break; - default: - case 'N': - case 'n': - obscure_syntax &= ~RE_MBCTYPE_MASK; - break; - } - re_set_syntax(obscure_syntax); + rb_set_kanjicode(optarg); break; case 'S': diff --git a/sample/caller.rb b/sample/caller.rb deleted file mode 100644 index 8988733377..0000000000 --- a/sample/caller.rb +++ /dev/null @@ -1,15 +0,0 @@ -def test - for i in 1..2 - for j in 1..5 - print(j, ": ", caller(j).join(':'), "\n") - end - end -end - -def test2 - print(1, ": ", caller(1).join(':'), "\n") - test() -end - -test2() -caller() diff --git a/sample/dbm.rb b/sample/dbm.rb index 1f2886e026..128391faec 100644 --- a/sample/dbm.rb +++ b/sample/dbm.rb @@ -1,6 +1,6 @@ # ruby # -d = Dbm.open("test") +d = DBM.open("test") for k in d.keys; print(k, "\n"); end for v in d.values; print(v, "\n"); end diff --git a/sample/export.rb b/sample/export.rb new file mode 100644 index 0000000000..3a6a8198df --- /dev/null +++ b/sample/export.rb @@ -0,0 +1,13 @@ +class foo + export(\printf) +end + +def foobar + print "foobar\n" +end + +f = foo.new +#foo.unexport(\printf) +foo.export(\foobar) +f.foobar +f.printf "%s\n", foo diff --git a/sample/fib.rb b/sample/fib.rb index c72f91f2f2..9fb8b24697 100644 --- a/sample/fib.rb +++ b/sample/fib.rb @@ -1,4 +1,4 @@ -def fib (n) +def fib(n) if n<2 n else diff --git a/sample/fib.scm b/sample/fib.scm new file mode 100644 index 0000000000..8eba75bb9e --- /dev/null +++ b/sample/fib.scm @@ -0,0 +1,6 @@ +(define (fib n) + (if (< n 2) + n + (+ (fib (- n 2)) (fib (- n 1))))) + +(fib 20) diff --git a/sample/list3.rb b/sample/list3.rb new file mode 100644 index 0000000000..c38e5bfb43 --- /dev/null +++ b/sample/list3.rb @@ -0,0 +1,20 @@ +# Linked list program -- short version +class Point + def Point.new(x, y) + super.init(x, y) + end + + def init(x, y) + @x = x; @y = y + self + end + + def to_s + sprintf("%d@%d", @x, @y) + end +end + +list1 = [10, 20, Point.new(2, 3), Point.new(4, 5)] +list2 = [20, Point.new(4, 5), list1] +print("list1: ", list1._inspect, "\n") +print("list2: ", list2._inspect, "\n") diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el index 8f864d3846..7f97e71c54 100644 --- a/sample/ruby-mode.el +++ b/sample/ruby-mode.el @@ -18,7 +18,7 @@ (defconst ruby-block-end-re "end") (defconst ruby-delimiter - (concat "[/<(){}#\"'`]\\|\\[\\|\\]\\|\\b\\(" + (concat "[$/<(){}#\"'`]\\|\\[\\|\\]\\|\\b\\(" ruby-block-beg-re "\\|" ruby-block-end-re "\\)\\b") ) @@ -55,6 +55,7 @@ ;;(modify-syntax-entry ?\n ">" ruby-mode-syntax-table) ;;(modify-syntax-entry ?\f ">" ruby-mode-syntax-table) (modify-syntax-entry ?# "<" ruby-mode-syntax-table) + (modify-syntax-entry ?$ "/" ruby-mode-syntax-table) (modify-syntax-entry ?\\ "'" ruby-mode-syntax-table) (modify-syntax-entry ?_ "w" ruby-mode-syntax-table) (modify-syntax-entry ?< "." ruby-mode-syntax-table) @@ -193,6 +194,8 @@ The variable ruby-indent-level controls the amount of indentation. nil (goto-char indent-point) (setq in-string t)))))) + ((string= "$" w) ;skip $char + (forward-char 1)) ((string= "#" w) ;skip comment (forward-line 1)) ((string= "(" w) ;skip to matching paren diff --git a/sample/time.rb b/sample/time.rb new file mode 100755 index 0000000000..b0ef065ce3 --- /dev/null +++ b/sample/time.rb @@ -0,0 +1,8 @@ +#! /usr/local/bin/ruby +cmd = $ARGV.join(" ") +b = Time.now +system(cmd) +e = Time.now +ut, st, cut, cst = Time.times +total = (e - b).to_f +printf $stderr, "%11.1f real %11.1f user %11.1f sys\n", total, cut, cst diff --git a/sample/uumerge.rb b/sample/uumerge.rb new file mode 100755 index 0000000000..420a3924b6 --- /dev/null +++ b/sample/uumerge.rb @@ -0,0 +1,27 @@ +#!/usr/local/bin/ruby + +while gets() + if /^begin\s*(\d*)\s*(\S*)/ + $mode, $file = $1, $2 + $sawbegin+=1 + break + end +end + +fail "missing begin" unless $sawbegin; +OUT = open($file, "w") if $file != ""; + +while gets() + if /^end/ + $sawend+=1 + break + end + sub(/[a-z]+$/, ""); # handle stupid trailing lowercase letters + continue if /[a-z]/ + continue unless ((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4 + OUT << $_.unpack("u"); +end + +fail "missing end" unless $sawend; +File.chmod $mode.oct, $file; +exit 0; @@ -608,15 +608,13 @@ Fsock_accept(sock) { OpenFile *fptr; VALUE addr, sock2; - int fd; char buf[1024]; int len = sizeof buf; GetOpenFile(sock, fptr); - if ((fd = accept(fileno(fptr->f), (struct sockaddr*)buf, &len)) < 0) - rb_sys_fail("listen(2)"); + sock2 = sock_accept(C_Socket,fileno(fptr->f),(struct sockaddr*)buf,&len); - return sock_new(C_Socket, fd); + return assoc_new(sock2, str_new(buf, len)); } static VALUE @@ -651,24 +649,50 @@ Fsock_send(sock, args) } static VALUE -Fsock_recv(sock, len, flags) - VALUE sock, len, flags; +sock_recv(sock, args, from) + VALUE sock, args; + int from; { OpenFile *fptr; FILE f; struct RString *str; char buf[1024]; int fd, alen = sizeof buf; + VALUE len, flg; + int flags; + + rb_scan_args(args, "11", &len, &flg); + + if (flg == Qnil) flags = 0; + else flags = NUM2INT(flg); str = (struct RString*)str_new(0, NUM2INT(len)); GetOpenFile(sock, fptr); fd = fileno(fptr->f); - if (recvfrom(fd, str->ptr, str->len, NUM2INT(flags), - (struct sockaddr*)buf, &alen) < 0) { - rb_sys_fail("recv(2)"); + if ((str->len = recvfrom(fd, str->ptr, str->len, flags, + (struct sockaddr*)buf, &alen)) < 0) { + rb_sys_fail("recvfrom(2)"); } - return assoc_new(str, str_new(buf, alen)); + + if (from) + return assoc_new(str, str_new(buf, alen)); + else + return (VALUE)str; +} + +static VALUE +Fsock_recv(sock, args) + VALUE sock, args; +{ + return sock_recv(sock, args, 0); +} + +static VALUE +Fsock_recvfrom(sock, args) + VALUE sock, args; +{ + return sock_recv(sock, args, 1); } Init_Socket () @@ -715,7 +739,8 @@ Init_Socket () rb_define_method(C_Socket, "accept", Fsock_accept, 0); rb_define_method(C_Socket, "send", Fsock_send, -2); - rb_define_method(C_Socket, "recv", Fsock_recv, 2); + rb_define_method(C_Socket, "recv", Fsock_recv, -2); + rb_define_method(C_Socket, "recvfrom", Fsock_recv, -2); rb_define_single_method(C_Socket, "socketpair", Fsock_socketpair, 3); } @@ -270,11 +270,9 @@ Ruby���ѿ��ϥ�������(ͭ���ϰ�)�ȼ�̿(ͭ������)�ˤ�ä�4�����ʬ�व��, �ߥ���ˤ�����ؿ��Τ褦�ʷ����ǥ�åɤ�ƤӽФ����Ȥ��Ǥ���. �� �ξ�������1�Ĥ�ʤ����Ǥ��̤ξ�ά�ϤǤ��ʤ�. -�ؿ������Ǥ�`@'�ǻϤޤ�̾������ĥ�åɤ�ƤӽФ����Ȥ��Ǥ���. `@'�� -�Ϥޤ��åɤϴؿ������Ǥ����ƤӽФ����Ȥ��Ǥ��ʤ�����, �������륯�� -���ޤ��Ϥ��Υ��֥��饹���餷���ƤФ�ʤ��Τ�, �ץ饤�١��ȥ�åɤȸ� -�Ф��. �ץ饤�١��ȥ�åɤ�C++�ˤ�����protected member function�˳� -������. +���饹���ʸ�γ��ǻ��ꤵ�줿��åɤȥ��饹Module��noexport��åɤ� +���ꤵ�줿��åɤϴؿ�Ū��åɤȸƤФ�, �ؿ������Ǥ����ƤӽФ����� +���Ǥ��ʤ�. *** �����ѡ����饹�Υ�åɸƤӽФ� @@ -458,7 +456,7 @@ unless�� case�� case ��0 - [when ��1 [, ��2]... + [when ��1 [, ��2]... [then] ʸ1 ]... [else ʸn ] @@ -603,10 +601,10 @@ Enumerable�⥸�塼���grep��åɤΤ褦�˥��ƥ졼���Ȥ��ƸƤФ줿���� protect ʸ1 - [ resque + [resque ʸ2 ] - [ ensure - ʸ3 ] + [ensure + ʸ3] end ʸ1��¹Ԥ�, ���μ¹�����㳰��ȯ�������resque��ǻ��ꤵ�줿ʸ2��¹� @@ -712,12 +710,12 @@ yieldʸ *** ��åɸƤӽФ�ʸ -1�İʾ��������ĥ�åɤ�ʸ�Ȥ��ƸƤӽФ����ˤϰ������̤dz��ɬ -�פϤʤ�. ���η����ϰʲ����̤�Ǥ���. +1�İʾ�ΰ�������ĥ�åɸƤӽФ����ˤ�ۣ�椵���ʤ����, ������� +�̤dz��ɬ�פϤʤ�. ���η����ϰʲ����̤�Ǥ���. - �� '.' ��å�̾ ����1 ',' [ ����2... ][ '*' ����n ] - ��å�̾ ����1 ',' [ ����2... ][ '*' ����n ] - super ����1 ',' [ ����2... ][ '*' ����n ] + �� '.' ��å�̾ ����1 ',' [����2...]['*' ����n] + ��å�̾ ����1 ',' [����2...]['*' ����n] + super ����1 ',' [����2... ]['*' ����n] ��ʸ���ϻ���, ���Τ褦�˲��Ǥ�����ϼ��Ȥ��Ƥβ�ͥ�褵���. @@ -726,7 +724,7 @@ yieldʸ foo 1 # ��åɸƤӽФ�foo(1) foo -1 # ���������ѿ�foo - 1 -��åɸƤӽФ�ʸ��ñ��ʸ�Ǥ���. +��̤Τʤ���åɸƤӽФ�ʸ��ñ��ʸ�Ǥ���. *** ���潤���� @@ -786,7 +784,7 @@ yieldʸ ������ϥͥ��ȤǤ��ʤ��Τ�, ��å����ʸ��Ǥϥ�å����ʸ��ƤӸ� �ӽФ��ʤ�. - def ��å�̾ [ '(' ���� [',' ����...][',' '*'���� ] ')' ] + def ��å�̾ ['(' ���� [',' ����...][',' '*'���� ] ')'] ������� end @@ -794,12 +792,19 @@ yieldʸ �ǻ��ꤹ��. �������¤ӤκǸ��`*'��������, ���������¿��Ϳ����줿 �°�����, �Ǹ�ΰ���������Ȥ���Ϳ������(��ʤ����ˤϥ��顼). +��åɤˤϴؿ�Ū��åɤ��̾��åɤ�����. �ؿ�Ū��åɤϴؿ��� +���Ǥ����ƤӽФ����Ȥ��Ǥ���, ��äƳ������륯�饹�Ȥ��Υ��֥��饹�Υ� +���åɤ��餷���ƤӽФ����Ȥ��Ǥ��ʤ�. ���饹���ʸ�γ��ˤ���defʸ�ϴ� +��Ū��åɤ������, ���饹���ʸ����ˤ���defʸ���̾�Υ�åɤ��� +������. ��åɤβĻ�����Module���饹��export/noexport��åɤ�Ȥ� +���ѹ�����. + ** �ðۥ�å����ʸ ��å�����ˤϤ⤦����ðۥ�åɤ����������. �ðۥ�åɤȤϤ��� ����Υ��֥������Ȥ˸�ͭ�Υ�åɤǤ���. �����ϰʲ����̤�Ǥ���. - def �� '.' ��å�̾ [ '(' ���� [',' ����...][',' '*'���� ] ')' ] + def �� '.' ��å�̾ ['(' ���� [',' ����...][',' '*'���� ] ')'] ������� end @@ -845,10 +850,10 @@ Ruby�ˤϽ����Ϥ��Τ�Τ˰ʲ��ε�ǽ���Ȥ߹��ޤ�Ƥ���. �饤�֥������ ** �ؿ� -Ruby�ˤϸ�̩�ʰ�̣�Ǥϴؿ��Ϥʤ���Builtin���饹�Υ�åɤ�(���Ƥ��̾� -���饹����ؿ������ǸƤӽФ���Τ�), �ؿ�Ū���Ѥ�����. �ؿ�Ū���Ѥ� -�����åɤ�ʲ��ˤ�����. �����Υ�åɤ���������ݤˤϸߴ��� -��ͤ��ƹԤʤ��٤��Ǥ���. +Ruby�ˤϸ�̩�ʰ�̣�Ǥϴؿ��Ϥʤ���Kernel���饹�δؿ���åɤ�(���Ƥ� +�̾說�饹����ؿ������ǸƤӽФ���Τ�), �ؿ�Ū���Ѥ�����. �ؿ�Ū�� +�Ѥ������åɤ�ʲ��ˤ�����. �����Υ�åɤ���������ݤˤϸ� +������ͤ��ƹԤʤ��٤��Ǥ���. _exit(status) @@ -1116,8 +1121,7 @@ Ruby�ˤϸ�̩�ʰ�̣�Ǥϴؿ��Ϥʤ���Builtin���饹�Υ�åɤ�(���Ƥ��̾� $ARGV $*��Ʊ��. - $ENV �Ķ��ѿ��˥�����������Ϣ������(EnvDict). �����ѿ����� - ���� `for'��Ԥʤ����ѿ�̾���ͤΥڥ���Ϳ����. + $ENV �Ķ��ѿ��˥�����������Ϣ������. $FILENAME ���ۥե�����$ARGF�Ǹ����ɤ߹�����Υե�����̾. ��� ��gets()�����ɤ�Ǥ���ե�����̾. @@ -1163,67 +1167,6 @@ Ruby�ˤϸ�̩�ʰ�̣�Ǥϴؿ��Ϥʤ���Builtin���饹�Υ�åɤ�(���Ƥ��̾� ** ���饹/�⥸�塼�� -*** ARGFILE(���饹) - -�����ǻ��ꤵ�줿�ե�����(������Ϳ�����Ƥ��ʤ����ˤ�ɸ������)�ǹ����� -��벾�ۥե�������������뤿��Υ��饹. ���������Υ��饹���ðۥ�� -�ɤ���������, �⥸�塼��Ū�ʻȤ������. ���饹̾�����Ǥʤ������ƥ� -�ѿ�$ARGF�Ǥ⻲�ȤǤ���. - - while gets() - ... - end - -�� - - for $_ in $ARGF - ... - end - -������Ʊ����̣����, ��Ԥ��������������, ���䤹��, �����ƥ֥��å� -�����Υ����ȤΤ���㴳�٤�. - -SuperClass: Object - -Included Modules: Enumerable - -Methods: - - each - - �ƹ���˷����֤����ƥ졼�� - - each_byte - - ��ʸ����˷����֤����ƥ졼�� - - eof - - �����ɤ߹���Ǥ���ե�����(���ۥե��������ΤǤϤʤ�)��������� - ã�������˿����֤�. - - getc - - ���ۥե����뤫��1ʸ���ɤ߹���. ����ͤ�ʸ�������ɤ�ɽ�������� - ����. �ե�����ν������ã�������ˤ�nil���֤�. ���Υ�åɤ� - �ɤ߹�������, �����ƥ��ѿ�`$.'���Ѳ����ʤ�. - - gets - readline - - ���ۥե����뤫�����ɤ߹����, �ɤ߹��ߤ������������ˤϤ���ʸ - ������֤�. �ե�����ν������ã�������ˤ�nil���֤�. �Ԥζ��� - ��ϥ����ƥ��ѿ�`$/'�ˤ�ä��ѹ��Ǥ���. �ɤ߹����ʸ����ϥ��� - �ƥ��ѿ�`$_'�ˤ⥻�åȤ����. - - read - - ���ۥե���������Ƥ�����ʸ����Ȥ����ɤ߹���. - - readlines - - ���ۥե�����������ɤ߹����, �ƹԤ����ǤȤ��ƻ���������֤�. - *** Array(���饹) ������ź���Ȥ�������Υ��饹�Ǥ���. �����ϰ���Ū�ˤ�����``[...]''�� @@ -1431,17 +1374,6 @@ Methods: ���Ⱦ�;��2���Ǥ�������֤�. -*** Builtin(���饹) - -���Ƥ��̾說�饹�Υ����ѡ����饹. Ruby�Ȥ߹��ߤ����Ƥδؿ�Ū�˸ƤФ���å� -�Ϥ��Υ��饹���������Ƥ���. - -SuperClass: Kernel - -Methods: - - �ִؿ��פι��ܤȤΤ���. - *** Class(���饹) ���饹�Υ��饹. ��긷̩����������ȥ��饹���ðۥ�åɤ�Ѿ����뤿�� @@ -1453,13 +1385,15 @@ Class�Ϥ��Υ���饹�Υ��饹�Ǥ���(ʬ���ä�����?). ��, ���β��⤬���� SuperClass: Module -Methods: +Private Methods: attr(name[, public]) ���Υ��饹�Υ������Ф���name�ǻ��ꤵ���°�����������. �ܤ�����Module��attr��åɤι�ȤΤ���. +Methods: + new(...) ���饹�Υ�������������. ¿���ξ�礳�Υ�åɤϥ��֥� @@ -1799,34 +1733,6 @@ Methods: ���Ƥ����Ǥ��Ȥ���������֤�. -*** EnvDict(���饹) - -�Ķ��ѿ������뤿��Υ��饹. �����ƥ��ѿ�$ENV��ͣ��Υ����� -��������Ƥ���. - -SuperClass: Object - -Included Modules: Enumerable - -Methods: - - [name] - - �Ķ��ѿ����ͤ��֤�. - - [name]= val - - �Ķ��ѿ����ͤ�val�����ꤹ��. val�Ȥ���nil����ꤷ�����ˤ�, - ��������Ķ��ѿ���������. - - delete(name) - - �Ķ��ѿ���������. - - each - - �Ķ��ѿ���̾�����ͤΥڥ���Ϳ���륤�ƥ졼��. - *** Etc(�⥸�塼��) /etc�ǥ��쥯�ȥ�ʲ��ξ�������뤿��Υ⥸�塼��. ���饹�˥��롼�� @@ -2463,7 +2369,8 @@ Single Methods: *** Kernel(���饹) -���ƤΥ��饹�δ��쥯�饹. +���ƤΥ��饹�δ��쥯�饹. Ruby�Ȥ߹��ߤ����Ƥδؿ���åɤϤ��Υ��饹 +���������Ƥ���. �ؿ���åɤˤĤ��Ƥϡִؿ��פι��ܤȤΤ���. SuperClass: �ʤ� @@ -2533,6 +2440,7 @@ Methods: ����ɬ����A.hash == B.hash�פ���Ω����ɬ�פ�����Τ�, "=="��� ����������ˤ�ɬ��������⤽��˹�碌�ƺ�������뤳��. + *** Math(�⥸�塼��) ��ư�������黻�ݡ��Ȥ��륯�饹. Math�⥸�塼���Ʊ������Υ�å� @@ -2584,19 +2492,21 @@ Single Methods: SuperClass: Object -Methods: +Private Methods: attr(name[, public]) ���Υ⥸�塼��롼�ɤ������饹�Υ������Ф��� name�ǻ��ꤵ���°�����ղä�, °�����Ф��륢��������åɤ��� - ������. attr("attr")�ϰʲ��˼��������ɤȤۤ�Ʊ���Ǥ���. + ������. attr("attr")�ϥ��饹����˰ʲ��˼��������ɤ��ɲä���� + �Ȥۤ�Ʊ���Ǥ���. def attr; @attr; end ��ά��ǽ����2����public��Ϳ������, ���Ĥ����ͤ�nil�Ǥʤ����� ��, ����°���ˤ�°�������åɤ��Ѱդ���, ��������������ǽ�� - �ʤ�. attr("attr", %TRUE)�ϰʲ��Υ����ɤȤۤ�Ʊ���Ǥ���. + �ʤ�. attr("attr", %TRUE)�ϥ��饹����˰ʲ��Υ����ɤ��ɲä��� + �ΤȤۤ�Ʊ���Ǥ���. def attr; @attr; end def attr=(val); @attr = val; end @@ -2614,11 +2524,23 @@ Methods: �ϥ���������åɤ����Ǥ��������Ƥ������, �ǥե���ȤΥ� ��������åɤ�������ʤ�. +Methods: + + export(name[, name..]) + + name�ǻ��ꤵ�줿��åɤ��̾�����ǸƤӽФ���ǽ�ˤ���. ���Ǥ� + �̾��åɤǤ�����ˤϲ��⤷�ʤ�. + to_s �⥸�塼���ʸ����ɽ�����֤�. �⥸�塼��ξ���ʸ����ɽ���ϥ� ���塼��̾�Ǥ���. + unexport(name[, name..]) + + name�ǻ��ꤵ�줿��åɤ�ؿ������Ǥ����ƤӽФ���ǽ�ˤ���. �� + �Ǥ˴ؿ���åɤǤ�����ˤϲ��⤷�ʤ�. + *** Nil(���饹) ����ɽ�����֥�������nil�Υ��饹. ���ѿ�(����)nil��Nil���饹��ͣ��Υ� @@ -2829,8 +2751,8 @@ Methods: accept - ��������³������դ���, ��������³���Ф��륽���åȤ��֤�. - accept(2)��. + ��������³������դ���, ��������³���Ф��륽���åȤȥ��ɥ쥹�� + �ڥ����֤�. accept(2)��. bind(addr) @@ -2846,9 +2768,22 @@ Methods: listen(2)��Ʊ��Ư����. - recv(len, flags) + recv(len[, flags]) + + �����åȤ���ǡ�����������, ʸ����Ȥ����֤�. len�ϼ������ + �����Ĺ������ꤹ��. flags�ˤĤ��Ƥ�recv(2)��. flags�Υ� + �ե�����ͤ�0�Ǥ���. + + recvfrom(len[, flags]) + + recv��Ʊ�ͤ˥����åȤ���ǡ����������뤬, ����ͤ�ʸ������� + ����åȤΥ��ɥ쥹�Υڥ��Ǥ���. �����ˤĤ��Ƥ�recv��Ʊ��. + send(mesg, flags[, to]) - sysread(len) + + �����åȤ�𤷤ƥǡ��������롥flags�˴ؤ��Ƥ�send(2)�Ȥλ��� + connect���Ƥ��ʤ������åȤ��Ф��Ƥ�������Ǥ���to����ꤹ��ɬ + �פ����롥�ºݤ����ä��ǡ�����Ĺ�����֤��� Single Methods: @@ -3044,6 +2979,14 @@ Methods: ʸ�����Ĺ��(�Х��ȿ�)���֤�. + ljust(width) + rjust(width) + center(width) + + ʸ����줾��, ���ͤ�, ���ͤ�, ���������width��ʸ���� + ���֤�. ʸ����Ĺ��width���Ĺ�����ϸ���ʸ������֤�, �ڤ�� + ��ʤ�. + next self����end�ޤǡּ��Ρ�ʸ������֤�. ����ʸ����ȤϿ����Ͽ��� @@ -3117,6 +3060,12 @@ Methods: end sum %= 65536 + swapcase + + ʸ������Υ���ե��٥åȤΤ�����ʸ����ʸ����, ��ʸ������ʸ�� + �ˤ��֤�������. ����ʸ����������뤳�Ȥ�����. ư��Ȥ��Ƥ� + tr("a-zA-Z", "A-Za-z")��꾯��®��. + to_f ʸ�����Float���Ѵ�����. @@ -3127,12 +3076,14 @@ Methods: toupper uc + upcase ʸ������Υ���ե��٥åȤ�������ʸ�����֤�������. ����ʸ���� ��������뤳�Ȥ�����. tr("a-z", "A-Z")��꾯��®��. tolower lc + downcase ʸ������Υ���ե��٥åȤ����ƾ�ʸ�����֤�������. ����ʸ���� ��������뤳�Ȥ�����. tr("A-Z", "a-z")��꾯��®��. @@ -3495,7 +3446,7 @@ Single Methods: end ���֤�ñ�̤��äǤ���, ��ư����������Ϳ������. �ܺ٤� - times(3C)�ȤΤ���. + times(3)�ȤΤ���. *** UNIXserver @@ -1024,6 +1024,28 @@ Fstr_lcfirst(str) return (VALUE)str; } +static VALUE +Fstr_swapcase(str) + struct RString *str; +{ + char *s; + int i; + + str_modify(str); + s = str->ptr; + for (i=0; i < str->len; i++) { + if (isupper(*s)) { + *s = tolower(*s); + } + else if (islower(*s)) { + *s = toupper(*s); + } + *s++; + } + + return (VALUE)str; +} + struct tr { int last, max; char *p, *pend; @@ -1533,7 +1555,67 @@ Fstr_sum(str, args) } } -extern VALUE C_Builtin; +Fstr_ljust(str, w) + struct RString *str; + VALUE w; +{ + int width = NUM2INT(w); + struct RString *res; + char *p, *pend; + + if (str->len >= width) return (VALUE)str; + res = (struct RString*)str_new(0, width); + memcpy(res->ptr, str->ptr, str->len); + p = res->ptr + str->len; pend = res->ptr + width; + while (p < pend) { + *p++ = ' '; + } + return (VALUE)res; +} + +Fstr_rjust(str, w) + struct RString *str; + VALUE w; +{ + int width = NUM2INT(w); + struct RString *res; + char *p, *pend; + + if (str->len >= width) return (VALUE)str; + res = (struct RString*)str_new(0, width); + p = res->ptr; pend = p + width - str->len; + while (p < pend) { + *p++ = ' '; + } + memcpy(pend, str->ptr, str->len); + return (VALUE)res; +} + +Fstr_center(str, w) + struct RString *str; + VALUE w; +{ + int width = NUM2INT(w); + struct RString *res; + char *p, *pend; + int n; + + if (str->len >= width) return (VALUE)str; + res = (struct RString*)str_new(0, width); + n = (width - str->len)/2; + p = res->ptr; pend = p + n; + while (p < pend) { + *p++ = ' '; + } + memcpy(pend, str->ptr, str->len); + p = pend + str->len; pend = res->ptr + width; + while (p < pend) { + *p++ = ' '; + } + return (VALUE)res; +} + +extern VALUE C_Kernel; extern VALUE M_Comparable; extern VALUE M_Enumerable; @@ -1567,11 +1649,15 @@ Init_String() rb_define_method(C_String, "_inspect", Fstr_inspect, 0); rb_define_method(C_String, "toupper", Fstr_toupper, 0); + rb_define_alias(C_String, "upcase", "toupper"); rb_define_alias(C_String, "uc", "toupper"); rb_define_method(C_String, "tolower", Fstr_tolower, 0); + rb_define_alias(C_String, "downcase", "tolower"); rb_define_alias(C_String, "lc", "tolower"); rb_define_method(C_String, "ucfirst", Fstr_ucfirst, 0); rb_define_method(C_String, "lcfirst", Fstr_lcfirst, 0); + rb_define_method(C_String, "swapcase", Fstr_swapcase, 0); + rb_define_method(C_String, "hex", Fstr_hex, 0); rb_define_method(C_String, "oct", Fstr_oct, 0); rb_define_method(C_String, "split", Fstr_split, -2); @@ -1580,6 +1666,10 @@ Init_String() rb_define_method(C_String, "crypt", Fstr_crypt, 1); rb_define_method(C_String, "intern", Fstr_intern, 0); + rb_define_method(C_String, "ljust", Fstr_ljust, 1); + rb_define_method(C_String, "rjust", Fstr_rjust, 1); + rb_define_method(C_String, "center", Fstr_center, 1); + rb_define_method(C_String, "sub", Fstr_sub, 2); rb_define_method(C_String, "gsub", Fstr_gsub, 2); rb_define_method(C_String, "chop", Fstr_chop, 0); @@ -1595,8 +1685,8 @@ Init_String() rb_define_method(C_String, "sum", Fstr_sum, -2); - rb_define_method(C_Builtin, "sub", Fsub, 2); - rb_define_method(C_Builtin, "gsub", Fgsub, 2); + rb_define_private_method(C_Kernel, "sub", Fsub, 2); + rb_define_private_method(C_Kernel, "gsub", Fgsub, 2); pr_str = rb_intern("to_s"); } @@ -128,6 +128,7 @@ Ftime_at(class, time) return time_new_internal(class, tp->tv_sec, tp->tv_usec); } + static VALUE Ftime_to_i(time) VALUE time; @@ -139,6 +140,16 @@ Ftime_to_i(time) } static VALUE +Ftime_to_f(time) + VALUE time; +{ + struct time_object *tobj; + + GetTimeval(time, tobj); + return float_new((double)tobj->tv.tv_sec+(double)tobj->tv.tv_usec/1000000); +} + +static VALUE Ftime_usec(time) VALUE time; { @@ -516,6 +527,7 @@ Init_Time() rb_define_single_method(C_Time, "times", Ftime_times, 0); rb_define_method(C_Time, "to_i", Ftime_to_i, 0); + rb_define_method(C_Time, "to_f", Ftime_to_f, 0); rb_define_method(C_Time, "<=>", Ftime_cmp, 1); rb_define_method(C_Time, "hash", Ftime_hash, 0); diff --git a/variable.c b/variable.c index 70aa959acd..1a06defe5e 100644 --- a/variable.c +++ b/variable.c @@ -260,8 +260,12 @@ rb_gvar_set(entry, val) if (entry->set_hook) (*entry->set_hook)(val, entry->id); - if (entry->mode == GLOBAL_VAR && entry->v.var != Qnil) + if (entry->mode == GLOBAL_VAR) { + if (entry->v.var == Qnil) { + rb_readonly_hook(val, entry->id); + } return *entry->v.var = val; + } else { if (entry->mode == GLOBAL_UNDEF) entry->mode = GLOBAL_VAL; @@ -319,8 +323,8 @@ const_bound(class, id) return FALSE; } -static void -rb_const_set_1(class, id, val) +void +rb_const_set(class, id, val) struct RClass *class; ID id; VALUE val; @@ -334,22 +338,13 @@ rb_const_set_1(class, id, val) st_insert(class->c_tbl, id, val); } -VALUE -rb_const_set(id, val) - ID id; - VALUE val; -{ - rb_const_set_1(the_class, id, val); - return val; -} - void rb_define_const(class, name, val) struct RClass *class; char *name; VALUE val; { - rb_const_set_1(class, rb_intern(name), val); + rb_const_set(class, rb_intern(name), val); } VALUE @@ -410,9 +405,9 @@ Fdefined(obj, name) { int i, max; - if (the_env->local_tbl) { - for (i=1, max=the_env->local_tbl[0]+1; i<max; i++) { - if (the_env->local_tbl[i] == id) return TRUE; + if (the_scope->local_tbl) { + for (i=1, max=the_scope->local_tbl[0]+1; i<max; i++) { + if (the_scope->local_tbl[i] == id) return TRUE; } } } @@ -1,2 +1,2 @@ -#define RUBY_VERSION "0.52" -#define VERSION_DATE "14 Oct 94" +#define RUBY_VERSION "0.54" +#define VERSION_DATE "94/10/26" |