2000-05-12
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@687 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
014f2164ed
commit
9da4f78db4
55
ChangeLog
55
ChangeLog
@ -1,6 +1,57 @@
|
|||||||
Tue May 9 17:08:43 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
Fri May 12 17:33:44 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
* array.c (Init_Array): prepare 'append' as alias to `push'.
|
* regex.c (re_compile_pattern): charset_not should not exclude
|
||||||
|
newline from matching set.
|
||||||
|
|
||||||
|
Thu May 11 22:51:05 2000 Ryunosuke Ohshima <ryu@jaist.ac.jp>
|
||||||
|
|
||||||
|
* pack.c (pack_pack): Bignum support.
|
||||||
|
|
||||||
|
* pack.c (pack_unpack): ditto.
|
||||||
|
|
||||||
|
Thu May 11 21:19:29 2000 Hiroshi Igarashi <iga@ruby-lang.org>
|
||||||
|
|
||||||
|
* intern.h: add missing declarations of ruby API functions.
|
||||||
|
|
||||||
|
* ruby.h: fix function name in declarations.
|
||||||
|
|
||||||
|
Thu May 11 22:29:25 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
|
||||||
|
|
||||||
|
* ext/md5/depend: add $(topdir)/config.h dependency to md5c.o.
|
||||||
|
|
||||||
|
* ext/md5/extconf.rb: new file to add -DHAVE_CONFIG_H flag for Alpha.
|
||||||
|
|
||||||
|
Thu May 11 10:55:52 2000 Ryunosuke Ohshima <ryu@jaist.ac.jp>
|
||||||
|
|
||||||
|
* pack.c (pack_pack): packing BER compressed integer by `w'.
|
||||||
|
|
||||||
|
* pack.c (pack_unpack): unpacking BER.
|
||||||
|
|
||||||
|
Thu May 11 00:37:55 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
|
* parse.y (parse_regx): remove in_brack.
|
||||||
|
|
||||||
|
Wed May 10 12:51:18 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
|
* ruby.c (proc_options): move adding RUBYLIB and "." to the load
|
||||||
|
path after #! line parsing.
|
||||||
|
|
||||||
|
* parse.y (parse_regx): should parse backslash escape like `\c['
|
||||||
|
here to avoid causing `unterminated regexp' error.
|
||||||
|
|
||||||
|
Wed May 10 00:19:53 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
|
||||||
|
|
||||||
|
* MANIFEST, beos/GNUmakefile.in, configure.in: no longer need
|
||||||
|
beos/GNUmakefile.in to support BeOS R4.5.2 (Intel) as a result
|
||||||
|
of eban's Makefile.in change.
|
||||||
|
|
||||||
|
* io.c: NOFILE is already defined on BeOS R4.5 (Intel) or later.
|
||||||
|
|
||||||
|
* lib/matrix.rb: remove debug print.
|
||||||
|
|
||||||
|
* regex.c: don't use nested comment.
|
||||||
|
|
||||||
|
Tue May 9 17:08:43 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||||
|
|
||||||
* eval.c (massign): no longer convert nil into empty array.
|
* eval.c (massign): no longer convert nil into empty array.
|
||||||
|
|
||||||
|
1
MANIFEST
1
MANIFEST
@ -75,7 +75,6 @@ util.c
|
|||||||
variable.c
|
variable.c
|
||||||
version.c
|
version.c
|
||||||
version.h
|
version.h
|
||||||
beos/GNUmakefile.in
|
|
||||||
cygwin/GNUmakefile.in
|
cygwin/GNUmakefile.in
|
||||||
ext/Setup
|
ext/Setup
|
||||||
ext/Setup.dj
|
ext/Setup.dj
|
||||||
|
2
ToDo
2
ToDo
@ -41,6 +41,7 @@ Hacking Interpreter
|
|||||||
* scrambled script, or script filter
|
* scrambled script, or script filter
|
||||||
* setuid ruby
|
* setuid ruby
|
||||||
* performance tune for in-block (dynamic) local variables.
|
* performance tune for in-block (dynamic) local variables.
|
||||||
|
* generational GC ?? (is it possible?)
|
||||||
|
|
||||||
Standard Libraries
|
Standard Libraries
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ Standard Libraries
|
|||||||
- Kernel#scan
|
- Kernel#scan
|
||||||
- call initialize for builtin classes too (not yet: Regexp, Class, Module)
|
- call initialize for builtin classes too (not yet: Regexp, Class, Module)
|
||||||
- performance tune for String's non-bang methods.
|
- performance tune for String's non-bang methods.
|
||||||
|
- 'w' template for pack/unpack
|
||||||
* String#scanf(?)
|
* String#scanf(?)
|
||||||
* Object#fmt(?)
|
* Object#fmt(?)
|
||||||
* Integer#{bin,oct,hex,heX}
|
* Integer#{bin,oct,hex,heX}
|
||||||
|
1
array.c
1
array.c
@ -1601,7 +1601,6 @@ Init_Array()
|
|||||||
rb_define_method(rb_cArray, "last", rb_ary_last, 0);
|
rb_define_method(rb_cArray, "last", rb_ary_last, 0);
|
||||||
rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);
|
rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);
|
||||||
rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
|
rb_define_method(rb_cArray, "<<", rb_ary_push, 1);
|
||||||
rb_define_method(rb_cArray, "append", rb_ary_push_m, -1);
|
|
||||||
rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
|
rb_define_method(rb_cArray, "push", rb_ary_push_m, -1);
|
||||||
rb_define_method(rb_cArray, "pop", rb_ary_pop, 0);
|
rb_define_method(rb_cArray, "pop", rb_ary_pop, 0);
|
||||||
rb_define_method(rb_cArray, "shift", rb_ary_shift, 0);
|
rb_define_method(rb_cArray, "shift", rb_ary_shift, 0);
|
||||||
|
3
bignum.c
3
bignum.c
@ -423,6 +423,7 @@ rb_big2ulong(x)
|
|||||||
unsigned long num = big2ulong(x, "unsigned long");
|
unsigned long num = big2ulong(x, "unsigned long");
|
||||||
|
|
||||||
if (!RBIGNUM(x)->sign) return -num;
|
if (!RBIGNUM(x)->sign) return -num;
|
||||||
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
long
|
long
|
||||||
@ -944,7 +945,7 @@ rb_big_remainder(x, y)
|
|||||||
return rb_big_modulo(x, y, 0);
|
return rb_big_modulo(x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
rb_big_divmod(x, y)
|
rb_big_divmod(x, y)
|
||||||
VALUE x, y;
|
VALUE x, y;
|
||||||
{
|
{
|
||||||
|
1
configure
vendored
1
configure
vendored
@ -4870,7 +4870,6 @@ if test "$target_os" = "beos"; then
|
|||||||
;;
|
;;
|
||||||
i586*)
|
i586*)
|
||||||
LDFLAGS="$LDFLAGS -L."
|
LDFLAGS="$LDFLAGS -L."
|
||||||
FIRSTMAKEFILE=GNUmakefile:beos/GNUmakefile.in
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo EXPORTS > ruby.def
|
echo EXPORTS > ruby.def
|
||||||
|
@ -707,7 +707,6 @@ if test "$target_os" = "beos"; then
|
|||||||
;;
|
;;
|
||||||
i586*)
|
i586*)
|
||||||
LDFLAGS="$LDFLAGS -L."
|
LDFLAGS="$LDFLAGS -L."
|
||||||
FIRSTMAKEFILE=GNUmakefile:beos/GNUmakefile.in
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo EXPORTS > ruby.def
|
echo EXPORTS > ruby.def
|
||||||
|
1
dln.c
1
dln.c
@ -15,6 +15,7 @@
|
|||||||
#include "dln.h"
|
#include "dln.h"
|
||||||
|
|
||||||
char *dln_argv0;
|
char *dln_argv0;
|
||||||
|
void rb_loaderror();
|
||||||
|
|
||||||
#ifdef _AIX
|
#ifdef _AIX
|
||||||
#pragma alloca
|
#pragma alloca
|
||||||
|
18
eval.c
18
eval.c
@ -1362,7 +1362,6 @@ ev_const_set(cref, id, val)
|
|||||||
VALUE val;
|
VALUE val;
|
||||||
{
|
{
|
||||||
NODE *cbase = cref;
|
NODE *cbase = cref;
|
||||||
VALUE tmp;
|
|
||||||
|
|
||||||
while (cbase && cbase->nd_clss != rb_cObject) {
|
while (cbase && cbase->nd_clss != rb_cObject) {
|
||||||
struct RClass *klass = RCLASS(cbase->nd_clss);
|
struct RClass *klass = RCLASS(cbase->nd_clss);
|
||||||
@ -2760,9 +2759,12 @@ rb_eval(self, n)
|
|||||||
else if (SCOPE_TEST(SCOPE_PROTECTED)) {
|
else if (SCOPE_TEST(SCOPE_PROTECTED)) {
|
||||||
noex = NOEX_PROTECTED;
|
noex = NOEX_PROTECTED;
|
||||||
}
|
}
|
||||||
else {
|
else if (ruby_class == rb_cObject) {
|
||||||
noex = node->nd_noex;
|
noex = node->nd_noex;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
noex = NOEX_PUBLIC;
|
||||||
|
}
|
||||||
if (body && origin == ruby_class && body->nd_noex & NOEX_UNDEF) {
|
if (body && origin == ruby_class && body->nd_noex & NOEX_UNDEF) {
|
||||||
noex |= NOEX_UNDEF;
|
noex |= NOEX_UNDEF;
|
||||||
}
|
}
|
||||||
@ -4552,7 +4554,7 @@ rb_f_eval(argc, argv, self)
|
|||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
VALUE src, scope, vfile, vline, val;
|
VALUE src, scope, vfile, vline;
|
||||||
char *file = "(eval)";
|
char *file = "(eval)";
|
||||||
int line = 1;
|
int line = 1;
|
||||||
|
|
||||||
@ -4660,7 +4662,7 @@ yield_under_i(self)
|
|||||||
if (ruby_block->flags & BLOCK_DYNAMIC) {
|
if (ruby_block->flags & BLOCK_DYNAMIC) {
|
||||||
struct BLOCK * volatile old_block = ruby_block;
|
struct BLOCK * volatile old_block = ruby_block;
|
||||||
struct BLOCK block;
|
struct BLOCK block;
|
||||||
volatile VALUE cbase = ruby_block->frame.cbase;
|
|
||||||
/* cbase should be pointed from volatile local variable */
|
/* cbase should be pointed from volatile local variable */
|
||||||
/* to be protected from GC. */
|
/* to be protected from GC. */
|
||||||
VALUE result;
|
VALUE result;
|
||||||
@ -4977,9 +4979,8 @@ rb_f_require(obj, fname)
|
|||||||
buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5);
|
buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5);
|
||||||
strcpy(buf, RSTRING(fname)->ptr);
|
strcpy(buf, RSTRING(fname)->ptr);
|
||||||
strcat(buf, ".rb");
|
strcat(buf, ".rb");
|
||||||
file = rb_find_file(buf);
|
if (rb_find_file(buf)) {
|
||||||
if (file) {
|
fname = rb_str_new2(buf);
|
||||||
fname = rb_str_new2(file);
|
|
||||||
feature = buf;
|
feature = buf;
|
||||||
goto load_rb;
|
goto load_rb;
|
||||||
}
|
}
|
||||||
@ -6490,8 +6491,9 @@ thread_switch(n)
|
|||||||
break;
|
break;
|
||||||
case RESTORE_NORMAL:
|
case RESTORE_NORMAL:
|
||||||
default:
|
default:
|
||||||
return 1;
|
break;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define THREAD_SAVE_CONTEXT(th) \
|
#define THREAD_SAVE_CONTEXT(th) \
|
||||||
|
@ -10,6 +10,11 @@
|
|||||||
|
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GETPWENT
|
#ifdef HAVE_GETPWENT
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
md5c.o: md5c.c md5.h
|
md5c.o: md5c.c md5.h $(topdir)/config.h
|
||||||
md5init.o: md5init.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h md5.h
|
md5init.o: md5init.c $(hdrdir)/ruby.h $(topdir)/config.h $(hdrdir)/defines.h md5.h
|
||||||
|
@ -15,6 +15,11 @@
|
|||||||
#include "rubysig.h"
|
#include "rubysig.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NT
|
#ifndef NT
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -538,7 +543,7 @@ ip_addrsetup(host, port)
|
|||||||
portp = 0;
|
portp = 0;
|
||||||
}
|
}
|
||||||
else if (FIXNUM_P(port)) {
|
else if (FIXNUM_P(port)) {
|
||||||
snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port));
|
snprintf(pbuf, sizeof(pbuf), "%ld", FIX2INT(port));
|
||||||
portp = pbuf;
|
portp = pbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -726,7 +731,7 @@ open_inet(class, h, serv, type)
|
|||||||
host = NULL;
|
host = NULL;
|
||||||
}
|
}
|
||||||
if (FIXNUM_P(serv)) {
|
if (FIXNUM_P(serv)) {
|
||||||
snprintf(pbuf, sizeof(pbuf), "%d", FIX2UINT(serv));
|
snprintf(pbuf, sizeof(pbuf), "%ld", FIX2UINT(serv));
|
||||||
portp = pbuf;
|
portp = pbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1748,7 +1753,7 @@ sock_s_getaddrinfo(argc, argv)
|
|||||||
pptr = NULL;
|
pptr = NULL;
|
||||||
}
|
}
|
||||||
else if (FIXNUM_P(port)) {
|
else if (FIXNUM_P(port)) {
|
||||||
snprintf(pbuf, sizeof(pbuf), "%d", FIX2INT(port));
|
snprintf(pbuf, sizeof(pbuf), "%ld", FIX2INT(port));
|
||||||
pptr = pbuf;
|
pptr = pbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1788,7 +1793,7 @@ sock_s_getnameinfo(argc, argv)
|
|||||||
int argc;
|
int argc;
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
{
|
{
|
||||||
VALUE sa, af, host, port, flags;
|
VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags;
|
||||||
static char hbuf[1024], pbuf[1024];
|
static char hbuf[1024], pbuf[1024];
|
||||||
char *hptr, *pptr;
|
char *hptr, *pptr;
|
||||||
int fl;
|
int fl;
|
||||||
@ -1824,6 +1829,10 @@ sock_s_getnameinfo(argc, argv)
|
|||||||
host = RARRAY(sa)->ptr[2];
|
host = RARRAY(sa)->ptr[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
rb_raise(rb_eArgError, "array size should be 3 or 4, %d given",
|
||||||
|
RARRAY(sa)->len);
|
||||||
|
}
|
||||||
if (NIL_P(host)) {
|
if (NIL_P(host)) {
|
||||||
hptr = NULL;
|
hptr = NULL;
|
||||||
}
|
}
|
||||||
@ -1837,7 +1846,7 @@ sock_s_getnameinfo(argc, argv)
|
|||||||
pptr = NULL;
|
pptr = NULL;
|
||||||
}
|
}
|
||||||
else if (!NIL_P(port)) {
|
else if (!NIL_P(port)) {
|
||||||
snprintf(pbuf, sizeof(pbuf), "%d", NUM2INT(port));
|
snprintf(pbuf, sizeof(pbuf), "%ld", NUM2INT(port));
|
||||||
pptr = pbuf;
|
pptr = pbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1872,7 +1881,6 @@ sock_s_getnameinfo(argc, argv)
|
|||||||
fl = NUM2INT(flags);
|
fl = NUM2INT(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
gotsap:
|
|
||||||
error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),
|
error = getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),
|
||||||
pbuf, sizeof(pbuf), fl);
|
pbuf, sizeof(pbuf), fl);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
# define SET_SIN_LEN(si,len) (si)->sin_len = (len)
|
# define SET_SIN_LEN(si,len) (si)->sin_len = (len)
|
||||||
#else
|
#else
|
||||||
# define SIN_LEN(si) sizeof(struct sockaddr_in)
|
# define SIN_LEN(si) sizeof(struct sockaddr_in)
|
||||||
# define SET_SIN_LEN(si,len) (len)
|
# define SET_SIN_LEN(si,len)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
9
file.c
9
file.c
@ -25,6 +25,12 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_FILE_H
|
||||||
|
# include <sys/file.h>
|
||||||
|
#else
|
||||||
|
int flock _((int, int));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
#else
|
#else
|
||||||
@ -875,6 +881,7 @@ rb_file_s_chmod(argc, argv)
|
|||||||
VALUE rest;
|
VALUE rest;
|
||||||
int mode, n;
|
int mode, n;
|
||||||
|
|
||||||
|
rb_secure(2);
|
||||||
rb_scan_args(argc, argv, "1*", &vmode, &rest);
|
rb_scan_args(argc, argv, "1*", &vmode, &rest);
|
||||||
mode = NUM2INT(vmode);
|
mode = NUM2INT(vmode);
|
||||||
|
|
||||||
@ -927,6 +934,7 @@ rb_file_s_chown(argc, argv)
|
|||||||
struct chown_args arg;
|
struct chown_args arg;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
rb_secure(2);
|
||||||
rb_scan_args(argc, argv, "2*", &o, &g, &rest);
|
rb_scan_args(argc, argv, "2*", &o, &g, &rest);
|
||||||
if (NIL_P(o)) {
|
if (NIL_P(o)) {
|
||||||
arg.owner = -1;
|
arg.owner = -1;
|
||||||
@ -1377,6 +1385,7 @@ static VALUE
|
|||||||
rb_file_s_truncate(obj, path, len)
|
rb_file_s_truncate(obj, path, len)
|
||||||
VALUE obj, path, len;
|
VALUE obj, path, len;
|
||||||
{
|
{
|
||||||
|
rb_secure(2);
|
||||||
Check_SafeStr(path);
|
Check_SafeStr(path);
|
||||||
|
|
||||||
#ifdef HAVE_TRUNCATE
|
#ifdef HAVE_TRUNCATE
|
||||||
|
7
gc.c
7
gc.c
@ -52,7 +52,6 @@ static unsigned long malloc_memories = 0;
|
|||||||
static unsigned long alloc_objects = 0;
|
static unsigned long alloc_objects = 0;
|
||||||
|
|
||||||
static int malloc_called = 0;
|
static int malloc_called = 0;
|
||||||
static int second_mem_error = 0;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mem_error(mesg)
|
mem_error(mesg)
|
||||||
@ -947,11 +946,7 @@ rb_gc()
|
|||||||
setjmp(save_regs_gc_mark);
|
setjmp(save_regs_gc_mark);
|
||||||
mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
|
mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
|
||||||
rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
|
rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
|
||||||
#if defined(THINK_C) || defined(__human68k__)
|
#if defined(__human68k__)
|
||||||
#ifndef __human68k__
|
|
||||||
mark_locations_array((VALUE*)((char*)save_regs_gc_mark+2),
|
|
||||||
sizeof(save_regs_gc_mark) / sizeof(VALUE *));
|
|
||||||
#endif
|
|
||||||
rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2),
|
rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2),
|
||||||
(VALUE*)((char*)STACK_END + 2));
|
(VALUE*)((char*)STACK_END + 2));
|
||||||
#endif
|
#endif
|
||||||
|
4
hash.c
4
hash.c
@ -688,8 +688,6 @@ static VALUE
|
|||||||
rb_hash_to_s(hash)
|
rb_hash_to_s(hash)
|
||||||
VALUE hash;
|
VALUE hash;
|
||||||
{
|
{
|
||||||
VALUE str;
|
|
||||||
|
|
||||||
if (rb_inspecting_p(hash)) return rb_str_new2("{...}");
|
if (rb_inspecting_p(hash)) return rb_str_new2("{...}");
|
||||||
return rb_protect_inspect(to_s_hash, hash, 0);
|
return rb_protect_inspect(to_s_hash, hash, 0);
|
||||||
}
|
}
|
||||||
@ -929,8 +927,6 @@ env_fetch(argc, argv)
|
|||||||
char *nam, *env;
|
char *nam, *env;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
VALUE val;
|
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &key, &if_none);
|
rb_scan_args(argc, argv, "11", &key, &if_none);
|
||||||
nam = rb_str2cstr(key, &len);
|
nam = rb_str2cstr(key, &len);
|
||||||
if (strlen(nam) != len) {
|
if (strlen(nam) != len) {
|
||||||
|
8
intern.h
8
intern.h
@ -68,6 +68,7 @@ double rb_big2dbl _((VALUE));
|
|||||||
VALUE rb_big_plus _((VALUE, VALUE));
|
VALUE rb_big_plus _((VALUE, VALUE));
|
||||||
VALUE rb_big_minus _((VALUE, VALUE));
|
VALUE rb_big_minus _((VALUE, VALUE));
|
||||||
VALUE rb_big_mul _((VALUE, VALUE));
|
VALUE rb_big_mul _((VALUE, VALUE));
|
||||||
|
VALUE rb_big_divmod _((VALUE, VALUE));
|
||||||
VALUE rb_big_pow _((VALUE, VALUE));
|
VALUE rb_big_pow _((VALUE, VALUE));
|
||||||
VALUE rb_big_and _((VALUE, VALUE));
|
VALUE rb_big_and _((VALUE, VALUE));
|
||||||
VALUE rb_big_or _((VALUE, VALUE));
|
VALUE rb_big_or _((VALUE, VALUE));
|
||||||
@ -105,6 +106,7 @@ VALUE rb_exc_new3 _((VALUE, VALUE));
|
|||||||
void rb_loaderror __((const char*, ...)) NORETURN;
|
void rb_loaderror __((const char*, ...)) NORETURN;
|
||||||
void rb_compile_error __((const char*, ...));
|
void rb_compile_error __((const char*, ...));
|
||||||
void rb_compile_error_append __((const char*, ...));
|
void rb_compile_error_append __((const char*, ...));
|
||||||
|
void rb_error_frozen _((char*));
|
||||||
/* eval.c */
|
/* eval.c */
|
||||||
void rb_exc_raise _((VALUE)) NORETURN;
|
void rb_exc_raise _((VALUE)) NORETURN;
|
||||||
void rb_exc_fatal _((VALUE)) NORETURN;
|
void rb_exc_fatal _((VALUE)) NORETURN;
|
||||||
@ -219,6 +221,7 @@ VALUE rb_obj_clone _((VALUE));
|
|||||||
VALUE rb_obj_taint _((VALUE));
|
VALUE rb_obj_taint _((VALUE));
|
||||||
VALUE rb_obj_tainted _((VALUE));
|
VALUE rb_obj_tainted _((VALUE));
|
||||||
VALUE rb_obj_untaint _((VALUE));
|
VALUE rb_obj_untaint _((VALUE));
|
||||||
|
VALUE rb_obj_freeze _((VALUE));
|
||||||
VALUE rb_obj_id _((VALUE));
|
VALUE rb_obj_id _((VALUE));
|
||||||
VALUE rb_convert_type _((VALUE,int,const char*,const char*));
|
VALUE rb_convert_type _((VALUE,int,const char*,const char*));
|
||||||
VALUE rb_Integer _((VALUE));
|
VALUE rb_Integer _((VALUE));
|
||||||
@ -240,6 +243,7 @@ void rb_parser_append_print _((void));
|
|||||||
void rb_parser_while_loop _((int, int));
|
void rb_parser_while_loop _((int, int));
|
||||||
int rb_is_const_id _((ID));
|
int rb_is_const_id _((ID));
|
||||||
int rb_is_instance_id _((ID));
|
int rb_is_instance_id _((ID));
|
||||||
|
int rb_is_class_id _((ID));
|
||||||
VALUE rb_backref_get _((void));
|
VALUE rb_backref_get _((void));
|
||||||
void rb_backref_set _((VALUE));
|
void rb_backref_set _((VALUE));
|
||||||
VALUE rb_lastline_get _((void));
|
VALUE rb_lastline_get _((void));
|
||||||
@ -352,8 +356,12 @@ int rb_const_defined _((VALUE, ID));
|
|||||||
VALUE rb_const_get _((VALUE, ID));
|
VALUE rb_const_get _((VALUE, ID));
|
||||||
VALUE rb_const_get_at _((VALUE, ID));
|
VALUE rb_const_get_at _((VALUE, ID));
|
||||||
void rb_const_set _((VALUE, ID, VALUE));
|
void rb_const_set _((VALUE, ID, VALUE));
|
||||||
|
void rb_const_assign _((VALUE, ID, VALUE));
|
||||||
VALUE rb_mod_constants _((VALUE));
|
VALUE rb_mod_constants _((VALUE));
|
||||||
void rb_autoload_load _((ID));
|
void rb_autoload_load _((ID));
|
||||||
|
void rb_cvar_declare _((VALUE, ID, VALUE));
|
||||||
|
VALUE rb_cvar_get _((VALUE, ID));
|
||||||
|
void rb_cvar_set _((VALUE, ID, VALUE));
|
||||||
/* version.c */
|
/* version.c */
|
||||||
void ruby_show_version _((void));
|
void ruby_show_version _((void));
|
||||||
void ruby_show_copyright _((void));
|
void ruby_show_copyright _((void));
|
||||||
|
49
io.c
49
io.c
@ -63,7 +63,7 @@ char *strdup();
|
|||||||
extern void Init_File _((void));
|
extern void Init_File _((void));
|
||||||
|
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
# ifdef _X86_
|
# ifdef NOFILE
|
||||||
# define NOFILE (OPEN_MAX)
|
# define NOFILE (OPEN_MAX)
|
||||||
# endif
|
# endif
|
||||||
#include <net/socket.h>
|
#include <net/socket.h>
|
||||||
@ -170,6 +170,25 @@ rb_read_check(fp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rb_dup(orig)
|
||||||
|
int orig;
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = dup(orig);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (errno == EMFILE || errno == ENFILE) {
|
||||||
|
rb_gc();
|
||||||
|
fd = dup(orig);
|
||||||
|
}
|
||||||
|
if (fd < 0) {
|
||||||
|
rb_sys_fail(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
/* writing functions */
|
/* writing functions */
|
||||||
static VALUE
|
static VALUE
|
||||||
io_write(io, str)
|
io_write(io, str)
|
||||||
@ -1893,10 +1912,10 @@ rb_io_clone(io)
|
|||||||
else mode = "r+";
|
else mode = "r+";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fd = dup(fileno(orig->f));
|
fd = rb_dup(fileno(orig->f));
|
||||||
fptr->f = rb_fdopen(fd, mode);
|
fptr->f = rb_fdopen(fd, mode);
|
||||||
if (fptr->f2) {
|
if (fptr->f2) {
|
||||||
fd = dup(fileno(orig->f2));
|
fd = rb_dup(fileno(orig->f2));
|
||||||
fptr->f = rb_fdopen(fd, "w");
|
fptr->f = rb_fdopen(fd, "w");
|
||||||
}
|
}
|
||||||
if (fptr->mode & FMODE_BINMODE) {
|
if (fptr->mode & FMODE_BINMODE) {
|
||||||
@ -2126,25 +2145,6 @@ rb_io_defset(val, id)
|
|||||||
rb_defout = val;
|
rb_defout = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
rb_dup(orig)
|
|
||||||
int orig;
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = dup(orig);
|
|
||||||
if (fd < 0) {
|
|
||||||
if (errno == EMFILE || errno == ENFILE) {
|
|
||||||
rb_gc();
|
|
||||||
fd = dup(orig);
|
|
||||||
}
|
|
||||||
if (fd < 0) {
|
|
||||||
rb_sys_fail(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_stdin(val, id, var)
|
set_stdin(val, id, var)
|
||||||
VALUE val;
|
VALUE val;
|
||||||
@ -2152,8 +2152,6 @@ set_stdin(val, id, var)
|
|||||||
VALUE *var;
|
VALUE *var;
|
||||||
{
|
{
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
int fd;
|
|
||||||
char *mode;
|
|
||||||
|
|
||||||
if (val == *var) return;
|
if (val == *var) return;
|
||||||
if (TYPE(val) != T_FILE) {
|
if (TYPE(val) != T_FILE) {
|
||||||
@ -2180,8 +2178,6 @@ set_outfile(val, var, orig, stdf)
|
|||||||
{
|
{
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int fd;
|
|
||||||
char *mode;
|
|
||||||
|
|
||||||
if (val == *var) return;
|
if (val == *var) return;
|
||||||
|
|
||||||
@ -2247,7 +2243,6 @@ rb_io_s_new(argc, argv, klass)
|
|||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
{
|
{
|
||||||
OpenFile *fp;
|
|
||||||
NEWOBJ(io, struct RFile);
|
NEWOBJ(io, struct RFile);
|
||||||
OBJSETUP(io, klass, T_FILE);
|
OBJSETUP(io, klass, T_FILE);
|
||||||
|
|
||||||
|
47
lib/irb/completion.rb
Normal file
47
lib/irb/completion.rb
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
require "readline"
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
module InputCompletion
|
||||||
|
ReservedWords = [
|
||||||
|
"BEGIN", "END",
|
||||||
|
"alias", "and",
|
||||||
|
"begin", "break",
|
||||||
|
"case", "class",
|
||||||
|
"def", "defined", "do",
|
||||||
|
"else", "elsif", "end", "ensure",
|
||||||
|
"false", "for",
|
||||||
|
"if", "in",
|
||||||
|
"module",
|
||||||
|
"next", "nil", "not",
|
||||||
|
"or",
|
||||||
|
"redo", "rescue", "retry", "return",
|
||||||
|
"self", "super",
|
||||||
|
"then", "true",
|
||||||
|
"undef", "unless", "until",
|
||||||
|
"when", "while",
|
||||||
|
"yield"
|
||||||
|
]
|
||||||
|
|
||||||
|
CompletionProc = proc { |input|
|
||||||
|
case input
|
||||||
|
when /^([^.]+)\.([^.]*)$/
|
||||||
|
receiver = $1
|
||||||
|
message = $2
|
||||||
|
if eval("(local_variables|#{receiver}.type.constants).include?('#{receiver}')",
|
||||||
|
IRB.conf[:MAIN_CONTEXT].bind)
|
||||||
|
candidates = eval("#{receiver}.methods", IRB.conf[:MAIN_CONTEXT].bind)
|
||||||
|
else
|
||||||
|
candidates = []
|
||||||
|
end
|
||||||
|
candidates.grep(/^#{Regexp.quote(message)}/).collect{|e| receiver + "." + e}
|
||||||
|
else
|
||||||
|
candidates = eval("methods | private_methods | local_variables | type.constants",
|
||||||
|
IRB.conf[:MAIN_CONTEXT].bind)
|
||||||
|
(candidates|ReservedWords).grep(/^#{Regexp.quote(input)}/)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Readline.completion_proc = IRB::InputCompletion::CompletionProc
|
67
lib/irb/frame.rb
Normal file
67
lib/irb/frame.rb
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#
|
||||||
|
# frame.rb -
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
require "e2mmap"
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
class Frame
|
||||||
|
extend Exception2MessageMapper
|
||||||
|
def_exception :FrameOverflow, "frame overflow"
|
||||||
|
def_exception :FrameUnderflow, "frame underflow"
|
||||||
|
|
||||||
|
INIT_STACK_TIMES = 3
|
||||||
|
CALL_STACK_OFFSET = 3
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace_func(event, file, line, id, binding)
|
||||||
|
case event
|
||||||
|
when 'call', 'class'
|
||||||
|
@frames.push binding
|
||||||
|
when 'return', 'end'
|
||||||
|
@frames.pop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def top(n = 0)
|
||||||
|
bind = @frames[-(n + CALL_STACK_OFFSET)]
|
||||||
|
Fail FrameUnderflow unless bind
|
||||||
|
bind
|
||||||
|
end
|
||||||
|
|
||||||
|
def bottom(n = 0)
|
||||||
|
bind = @frames[n]
|
||||||
|
Fail FrameOverflow unless bind
|
||||||
|
bind
|
||||||
|
end
|
||||||
|
|
||||||
|
# singleton functions
|
||||||
|
def Frame.bottom(n = 0)
|
||||||
|
@backtrace.bottom(n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def Frame.top(n = 0)
|
||||||
|
@backtrace.top(n)
|
||||||
|
end
|
||||||
|
|
||||||
|
def Frame.sender
|
||||||
|
eval "self", @backtrace.top
|
||||||
|
end
|
||||||
|
|
||||||
|
@backtrace = Frame.new
|
||||||
|
set_trace_func proc{|event, file, line, id, binding|
|
||||||
|
@backtrace.trace_func(event, file, line, id, binding)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
118
lib/irb/input-method.rb
Normal file
118
lib/irb/input-method.rb
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#
|
||||||
|
# input-method.rb - input methods using irb
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
module IRB
|
||||||
|
#
|
||||||
|
# InputMethod
|
||||||
|
# StdioInputMethod
|
||||||
|
# FileInputMethod
|
||||||
|
# (ReadlineInputMethod)
|
||||||
|
#
|
||||||
|
STDIN_FILE_NAME = "(line)"
|
||||||
|
class InputMethod
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
def initialize(file = STDIN_FILE_NAME)
|
||||||
|
@file_name = file
|
||||||
|
end
|
||||||
|
attr :file_name
|
||||||
|
|
||||||
|
attr :prompt, true
|
||||||
|
|
||||||
|
def gets
|
||||||
|
IRB.fail NotImplementError, "gets"
|
||||||
|
end
|
||||||
|
public :gets
|
||||||
|
|
||||||
|
def readable_atfer_eof?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class StdioInputMethod < InputMethod
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
@line_no = 0
|
||||||
|
@line = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def gets
|
||||||
|
print @prompt
|
||||||
|
@line[@line_no += 1] = $stdin.gets
|
||||||
|
end
|
||||||
|
|
||||||
|
def eof?
|
||||||
|
$stdin.eof?
|
||||||
|
end
|
||||||
|
|
||||||
|
def readable_atfer_eof?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def line(line_no)
|
||||||
|
@line[line_no]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class FileInputMethod < InputMethod
|
||||||
|
def initialize(file)
|
||||||
|
super
|
||||||
|
@io = open(file)
|
||||||
|
end
|
||||||
|
attr :file_name
|
||||||
|
|
||||||
|
def eof?
|
||||||
|
@io.eof?
|
||||||
|
end
|
||||||
|
|
||||||
|
def gets
|
||||||
|
l = @io.gets
|
||||||
|
print @prompt, l
|
||||||
|
l
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
require "readline"
|
||||||
|
class ReadlineInputMethod < InputMethod
|
||||||
|
include Readline
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
|
||||||
|
@line_no = 0
|
||||||
|
@line = []
|
||||||
|
@eof = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def gets
|
||||||
|
if l = readline(@prompt, true)
|
||||||
|
@line[@line_no += 1] = l + "\n"
|
||||||
|
else
|
||||||
|
@eof = true
|
||||||
|
l
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def eof?
|
||||||
|
@eof
|
||||||
|
end
|
||||||
|
|
||||||
|
def readable_atfer_eof?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def line(line_no)
|
||||||
|
@line[line_no]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
end
|
118
lib/irb/loader.rb
Normal file
118
lib/irb/loader.rb
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#
|
||||||
|
# irb-loader.rb -
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
class LoadAbort < GlobalExit;end
|
||||||
|
|
||||||
|
module Loader
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
alias ruby_load load
|
||||||
|
alias ruby_require require
|
||||||
|
|
||||||
|
def irb_load(file_name)
|
||||||
|
return ruby_load(file_name) unless IRB.conf[:USE_LOADER]
|
||||||
|
|
||||||
|
load_sub(file_name)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
def irb_require(file_name)
|
||||||
|
return ruby_require(file_name) unless IRB.conf[:USE_LOADER]
|
||||||
|
|
||||||
|
rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?")
|
||||||
|
return false if $".find{|f| f =~ rex}
|
||||||
|
|
||||||
|
case file_name
|
||||||
|
when /\.rb$/
|
||||||
|
begin
|
||||||
|
load_sub(file_name)
|
||||||
|
$".push file_name
|
||||||
|
return true
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
when /\.(so|o|sl)$/
|
||||||
|
return ruby_require(file_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
load_sub(f = file_name + ".rb")
|
||||||
|
$".push f
|
||||||
|
return true
|
||||||
|
rescue LoadError
|
||||||
|
return ruby_require(file_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_sub(fn)
|
||||||
|
if fn =~ /^#{Regexp.quote(File::Separator)}/
|
||||||
|
return false unless File.exist?(fn)
|
||||||
|
return irb_context.load_file(fn)
|
||||||
|
end
|
||||||
|
|
||||||
|
for path in $:
|
||||||
|
if File.exist?(f = File.join(path, fn))
|
||||||
|
return irb_context.load_file(f)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
raise LoadError, "No such file to load -- #{file_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
alias load irb_load
|
||||||
|
alias require irb_require
|
||||||
|
end
|
||||||
|
|
||||||
|
# class Context
|
||||||
|
# def load_from(file_name)
|
||||||
|
# io = FileInputMethod.new(file_name)
|
||||||
|
# @irb.signal_status(:IN_LOAD) do
|
||||||
|
# switch_io(io, file_name) do
|
||||||
|
# eval_input
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
class Context
|
||||||
|
def load_file(path)
|
||||||
|
back_io = @io
|
||||||
|
back_path = @irb_path
|
||||||
|
back_name = @irb_name
|
||||||
|
back_scanner = @irb.scanner
|
||||||
|
begin
|
||||||
|
@io = FileInputMethod.new(path)
|
||||||
|
@irb_name = File.basename(path)
|
||||||
|
@irb_path = path
|
||||||
|
@irb.signal_status(:IN_LOAD) do
|
||||||
|
if back_io.kind_of?(FileInputMethod)
|
||||||
|
@irb.eval_input
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
@irb.eval_input
|
||||||
|
rescue LoadAbort
|
||||||
|
print "load abort!!\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
@io = back_io
|
||||||
|
@irb_name = back_name
|
||||||
|
@irb_path = back_path
|
||||||
|
@irb.scanner = back_scanner
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ExtendCommand
|
||||||
|
include Loader
|
||||||
|
end
|
||||||
|
end
|
867
lib/irb/main.rb
Normal file
867
lib/irb/main.rb
Normal file
@ -0,0 +1,867 @@
|
|||||||
|
#
|
||||||
|
# main.rb - irb main module
|
||||||
|
# $Release Version: 0.6 $
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
require "e2mmap"
|
||||||
|
require "irb/ruby-lex"
|
||||||
|
require "irb/input-method"
|
||||||
|
require "irb/workspace-binding"
|
||||||
|
|
||||||
|
STDOUT.sync = true
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
# exceptions
|
||||||
|
extend Exception2MessageMapper
|
||||||
|
def_exception :UnrecognizedSwitch, "Unrecognized switch: %s"
|
||||||
|
def_exception :NotImplementError, "Need to define `%s'"
|
||||||
|
def_exception :CantRetuenNormalMode, "Can't return normal mode."
|
||||||
|
def_exception :IllegalParameter, "Illegal parameter(%s)."
|
||||||
|
def_exception :IrbAlreadyDead, "Irb is already dead."
|
||||||
|
def_exception :IrbSwitchToCurrentThread, "Change to current thread."
|
||||||
|
def_exception :NoSuchJob, "No such job(%s)."
|
||||||
|
def_exception :CanNotGoMultiIrbMode, "Can't go multi irb mode."
|
||||||
|
def_exception :CanNotChangeBinding, "Can't change binding to (%s)."
|
||||||
|
def_exception :UndefinedPromptMode, "Undefined prompt mode(%s)."
|
||||||
|
|
||||||
|
class Abort < Exception;end
|
||||||
|
|
||||||
|
# initialize IRB and start TOP_LEVEL irb
|
||||||
|
def IRB.start(ap_path = nil)
|
||||||
|
$0 = File::basename(ap_path, ".rb") if ap_path
|
||||||
|
|
||||||
|
IRB.initialize(ap_path)
|
||||||
|
IRB.parse_opts
|
||||||
|
IRB.load_modules
|
||||||
|
|
||||||
|
bind = workspace_binding
|
||||||
|
main = eval("self", bind)
|
||||||
|
|
||||||
|
if @CONF[:SCRIPT]
|
||||||
|
irb = Irb.new(main, bind, @CONF[:SCRIPT])
|
||||||
|
else
|
||||||
|
irb = Irb.new(main, bind)
|
||||||
|
end
|
||||||
|
|
||||||
|
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
||||||
|
@CONF[:MAIN_CONTEXT] = irb.context
|
||||||
|
|
||||||
|
trap("SIGINT") do
|
||||||
|
irb.signal_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
catch(:IRB_EXIT) do
|
||||||
|
irb.eval_input
|
||||||
|
end
|
||||||
|
print "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
# initialize config
|
||||||
|
def IRB.initialize(ap_path)
|
||||||
|
IRB.init_config(ap_path)
|
||||||
|
IRB.run_config
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# @CONF functions
|
||||||
|
#
|
||||||
|
@CONF = {}
|
||||||
|
# @CONF default setting
|
||||||
|
def IRB.init_config(ap_path)
|
||||||
|
# class instance variables
|
||||||
|
@TRACER_INITIALIZED = false
|
||||||
|
@MATHN_INITIALIZED = false
|
||||||
|
|
||||||
|
# default configurations
|
||||||
|
unless ap_path and @CONF[:AP_NAME]
|
||||||
|
ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb")
|
||||||
|
end
|
||||||
|
@CONF[:AP_NAME] = File::basename(ap_path, ".rb")
|
||||||
|
|
||||||
|
@CONF[:IRB_NAME] = "irb"
|
||||||
|
@CONF[:IRB_LIB_PATH] = File.dirname(__FILE__)
|
||||||
|
|
||||||
|
@CONF[:RC] = true
|
||||||
|
@CONF[:LOAD_MODULES] = []
|
||||||
|
@CONF[:IRB_RC] = nil
|
||||||
|
|
||||||
|
@CONF[:MATH_MODE] = false
|
||||||
|
@CONF[:USE_READLINE] = false unless defined?(ReadlineInputMethod)
|
||||||
|
@CONF[:INSPECT_MODE] = nil
|
||||||
|
@CONF[:USE_TRACER] = false
|
||||||
|
@CONF[:USE_LOADER] = false
|
||||||
|
@CONF[:IGNORE_SIGINT] = true
|
||||||
|
@CONF[:IGNORE_EOF] = false
|
||||||
|
|
||||||
|
@CONF[:BACK_TRACE_LIMIT] = 16
|
||||||
|
|
||||||
|
@CONF[:PROMPT] = {
|
||||||
|
:NULL => {
|
||||||
|
:PROMPT_I => nil,
|
||||||
|
:PROMPT_S => nil,
|
||||||
|
:PROMPT_C => nil,
|
||||||
|
:RETURN => "%s\n"
|
||||||
|
},
|
||||||
|
:DEFAULT => {
|
||||||
|
:PROMPT_I => "%N(%m):%03n:%i> ",
|
||||||
|
:PROMPT_S => "%N(%m):%03n:%i%l ",
|
||||||
|
:PROMPT_C => "%N(%m):%03n:%i* ",
|
||||||
|
:RETURN => "%s\n"
|
||||||
|
},
|
||||||
|
:SIMPLE => {
|
||||||
|
:PROMPT_I => ">> ",
|
||||||
|
:PROMPT_S => nil,
|
||||||
|
:PROMPT_C => "?> ",
|
||||||
|
:RETURN => "=> %s\n"
|
||||||
|
},
|
||||||
|
:INF_RUBY => {
|
||||||
|
:PROMPT_I => "%N(%m):%03n:%i> ",
|
||||||
|
:PROMPT_S => nil,
|
||||||
|
:PROMPT_C => nil,
|
||||||
|
:RETURN => "%s\n",
|
||||||
|
:AUTO_INDENT => true
|
||||||
|
},
|
||||||
|
:XMP => {
|
||||||
|
:PROMPT_I => nil,
|
||||||
|
:PROMPT_S => nil,
|
||||||
|
:PROMPT_C => nil,
|
||||||
|
:RETURN => " ==>%s\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CONF[:PROMPT_MODE] = :DEFAULT
|
||||||
|
@CONF[:AUTO_INDENT] = false
|
||||||
|
|
||||||
|
@CONF[:CONTEXT_MODE] = 3
|
||||||
|
@CONF[:SINGLE_IRB] = false
|
||||||
|
|
||||||
|
@CONF[:DEBUG_LEVEL] = 1
|
||||||
|
@CONF[:VERBOSE] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# IRB version method
|
||||||
|
def IRB.version
|
||||||
|
if v = @CONF[:VERSION] then return v end
|
||||||
|
|
||||||
|
require "irb/version"
|
||||||
|
rv = @RELEASE_VERSION.sub(/\.0/, "")
|
||||||
|
@CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
|
||||||
|
end
|
||||||
|
|
||||||
|
def IRB.conf
|
||||||
|
@CONF
|
||||||
|
end
|
||||||
|
|
||||||
|
# option analyzing
|
||||||
|
def IRB.parse_opts
|
||||||
|
while opt = ARGV.shift
|
||||||
|
case opt
|
||||||
|
when "-f"
|
||||||
|
opt = ARGV.shift
|
||||||
|
@CONF[:RC] = false
|
||||||
|
when "-m"
|
||||||
|
@CONF[:MATH_MODE] = true
|
||||||
|
when "-d"
|
||||||
|
$DEBUG = true
|
||||||
|
when "-r"
|
||||||
|
opt = ARGV.shift
|
||||||
|
@CONF[:LOAD_MODULES].push opt if opt
|
||||||
|
when "--inspect"
|
||||||
|
@CONF[:INSPECT_MODE] = true
|
||||||
|
when "--noinspect"
|
||||||
|
@CONF[:INSPECT_MODE] = false
|
||||||
|
when "--readline"
|
||||||
|
@CONF[:USE_READLINE] = true
|
||||||
|
when "--noreadline"
|
||||||
|
@CONF[:USE_READLINE] = false
|
||||||
|
when "--prompt-mode", "--prompt"
|
||||||
|
prompt_mode = ARGV.shift.upcase.tr("-", "_").intern
|
||||||
|
IRB.fail(UndefinedPromptMode,
|
||||||
|
prompt_mode.id2name) unless @CONF[:PROMPT][prompt_mode]
|
||||||
|
@CONF[:PROMPT_MODE] = prompt_mode
|
||||||
|
when "--noprompt"
|
||||||
|
@CONF[:PROMPT_MODE] = :NULL
|
||||||
|
when "--inf-ruby-mode"
|
||||||
|
@CONF[:PROMPT_MODE] = :INF_RUBY
|
||||||
|
when "--sample-book-mode", "--simple-prompt"
|
||||||
|
@CONF[:PROMPT_MODE] = :SIMPLE
|
||||||
|
when "--tracer"
|
||||||
|
@CONF[:USE_TRACER] = true
|
||||||
|
when "--back-trace-limit"
|
||||||
|
@CONF[:BACK_TRACE_LIMIT] = ARGV.shift.to_i
|
||||||
|
when "--context-mode"
|
||||||
|
@CONF[:CONTEXT_MODE] = ARGV.shift.to_i
|
||||||
|
when "--single-irb"
|
||||||
|
@CONF[:SINGLE_IRB] = true
|
||||||
|
when "--irb_debug"
|
||||||
|
@CONF[:DEBUG_LEVEL] = ARGV.shift.to_i
|
||||||
|
when "-v", "--version"
|
||||||
|
print IRB.version, "\n"
|
||||||
|
exit(0)
|
||||||
|
when /^-/
|
||||||
|
IRB.fail UnrecognizedSwitch, opt
|
||||||
|
else
|
||||||
|
@CONF[:USE_READLINE] = false
|
||||||
|
@CONF[:SCRIPT] = opt
|
||||||
|
$0 = opt
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# running config
|
||||||
|
def IRB.run_config
|
||||||
|
if @CONF[:RC]
|
||||||
|
rcs = []
|
||||||
|
rcs.push File.expand_path("~/.irbrc") if ENV.key?("HOME")
|
||||||
|
rcs.push ".irbrc"
|
||||||
|
rcs.push "irb.rc"
|
||||||
|
rcs.push "_irbrc"
|
||||||
|
rcs.push "$irbrc"
|
||||||
|
catch(:EXIT) do
|
||||||
|
for rc in rcs
|
||||||
|
begin
|
||||||
|
load rc
|
||||||
|
throw :EXIT
|
||||||
|
rescue LoadError, Errno::ENOENT
|
||||||
|
rescue
|
||||||
|
print "load error: #{rc}\n"
|
||||||
|
print $!.type, ": ", $!, "\n"
|
||||||
|
for err in $@[0, $@.size - 2]
|
||||||
|
print "\t", err, "\n"
|
||||||
|
end
|
||||||
|
throw :EXIT
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# loading modules
|
||||||
|
def IRB.load_modules
|
||||||
|
for m in @CONF[:LOAD_MODULES]
|
||||||
|
begin
|
||||||
|
require m
|
||||||
|
rescue
|
||||||
|
print $@[0], ":", $!.type, ": ", $!, "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# initialize tracing function
|
||||||
|
def IRB.initialize_tracer
|
||||||
|
unless @TRACER_INITIALIZED
|
||||||
|
require("tracer")
|
||||||
|
Tracer.verbose = false
|
||||||
|
Tracer.add_filter {
|
||||||
|
|event, file, line, id, binding|
|
||||||
|
File::dirname(file) != @CONF[:IRB_LIB_PATH]
|
||||||
|
}
|
||||||
|
@TRACER_INITIALIZED = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# initialize mathn function
|
||||||
|
def IRB.initialize_mathn
|
||||||
|
unless @MATHN_INITIALIZED
|
||||||
|
require "mathn"
|
||||||
|
@MATHN_INITIALIZED = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# initialize loader function
|
||||||
|
def IRB.initialize_loader
|
||||||
|
unless @LOADER_INITIALIZED
|
||||||
|
require "irb/loader"
|
||||||
|
@LOADER_INITIALIZED = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def IRB.irb_exit(irb, ret)
|
||||||
|
throw :IRB_EXIT, ret
|
||||||
|
end
|
||||||
|
|
||||||
|
def IRB.irb_abort(irb, exception = Abort)
|
||||||
|
if defined? Thread
|
||||||
|
irb.context.thread.raise exception, "abort then interrupt!!"
|
||||||
|
else
|
||||||
|
raise exception, "abort then interrupt!!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# irb interpriter main routine
|
||||||
|
#
|
||||||
|
class Irb
|
||||||
|
def initialize(main, bind, input_method = nil)
|
||||||
|
@context = Context.new(self, main, bind, input_method)
|
||||||
|
main.extend ExtendCommand
|
||||||
|
@signal_status = :IN_IRB
|
||||||
|
|
||||||
|
@scanner = RubyLex.new
|
||||||
|
@scanner.exception_on_syntax_error = false
|
||||||
|
end
|
||||||
|
attr :context
|
||||||
|
attr :scanner, true
|
||||||
|
|
||||||
|
def eval_input
|
||||||
|
# @scanner = RubyLex.new
|
||||||
|
@scanner.set_input(@context.io) do
|
||||||
|
signal_status(:IN_INPUT) do
|
||||||
|
unless l = @context.io.gets
|
||||||
|
if @context.ignore_eof? and @context.io.readable_atfer_eof?
|
||||||
|
l = "\n"
|
||||||
|
if @context.verbose?
|
||||||
|
printf "Use \"exit\" to leave %s\n", @context.ap_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
l
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@scanner.set_prompt do
|
||||||
|
|ltype, indent, continue, line_no|
|
||||||
|
if ltype
|
||||||
|
f = @context.prompt_s
|
||||||
|
elsif continue
|
||||||
|
f = @context.prompt_c
|
||||||
|
else @context.prompt_i
|
||||||
|
f = @context.prompt_i
|
||||||
|
end
|
||||||
|
f = "" unless f
|
||||||
|
@context.io.prompt = p = prompt(f, ltype, indent, line_no)
|
||||||
|
if @context.auto_indent_mode
|
||||||
|
unless ltype
|
||||||
|
ind = prompt(@context.prompt_i, ltype, indent, line_no).size +
|
||||||
|
indent * 2 - p.size
|
||||||
|
ind += 2 if continue
|
||||||
|
@context.io.prompt = p + " " * ind if ind > 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@scanner.each_top_level_statement do
|
||||||
|
|line, line_no|
|
||||||
|
signal_status(:IN_EVAL) do
|
||||||
|
begin
|
||||||
|
trace_in do
|
||||||
|
@context._ = eval(line, @context.bind, @context.irb_path, line_no)
|
||||||
|
# @context._ = irb_eval(line, @context.bind, @context.irb_path, line_no)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @context.inspect?
|
||||||
|
printf @context.return_format, @context._.inspect
|
||||||
|
else
|
||||||
|
printf @context.return_format, @context._
|
||||||
|
end
|
||||||
|
rescue StandardError, ScriptError, Abort
|
||||||
|
$! = RuntimeError.new("unknown exception raised") unless $!
|
||||||
|
print $!.type, ": ", $!, "\n"
|
||||||
|
if $@[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && $!.type.to_s !~ /^IRB/
|
||||||
|
irb_bug = true
|
||||||
|
else
|
||||||
|
irb_bug = false
|
||||||
|
end
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
lasts = []
|
||||||
|
levels = 0
|
||||||
|
for m in $@
|
||||||
|
if m !~ /irb2?(\/.*|-.*|\.rb)?:/ or irb_bug
|
||||||
|
if messages.size < @context.back_trace_limit
|
||||||
|
messages.push m
|
||||||
|
else
|
||||||
|
lasts.push m
|
||||||
|
if lasts.size > @context.back_trace_limit
|
||||||
|
lasts.shift
|
||||||
|
levels += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print messages.join("\n"), "\n"
|
||||||
|
unless lasts.empty?
|
||||||
|
printf "... %d levels...\n", levels if levels > 0
|
||||||
|
print lasts.join("\n")
|
||||||
|
end
|
||||||
|
print "Maybe IRB bug!!\n" if irb_bug
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# def irb_eval(line, bind, path, line_no)
|
||||||
|
# id, str = catch(:IRB_TOPLEVEL_EVAL){
|
||||||
|
# return eval(line, bind, path, line_no)
|
||||||
|
# }
|
||||||
|
# case id
|
||||||
|
# when :EVAL_TOPLEVEL
|
||||||
|
# eval(str, bind, "(irb_internal)", 1)
|
||||||
|
# when :EVAL_CONTEXT
|
||||||
|
# @context.instance_eval(str)
|
||||||
|
# else
|
||||||
|
# IRB.fail IllegalParameter
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
def signal_handle
|
||||||
|
unless @context.ignore_sigint?
|
||||||
|
print "\nabort!!\n" if @context.verbose?
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
|
||||||
|
case @signal_status
|
||||||
|
when :IN_INPUT
|
||||||
|
print "^C\n"
|
||||||
|
@scanner.initialize_input
|
||||||
|
print @context.io.prompt
|
||||||
|
when :IN_EVAL
|
||||||
|
IRB.irb_abort(self)
|
||||||
|
when :IN_LOAD
|
||||||
|
IRB.irb_abort(self, LoadAbort)
|
||||||
|
when :IN_IRB
|
||||||
|
# ignore
|
||||||
|
else
|
||||||
|
# ignore
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def signal_status(status)
|
||||||
|
return yield if @signal_status == :IN_LOAD
|
||||||
|
|
||||||
|
signal_status_back = @signal_status
|
||||||
|
@signal_status = status
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
@signal_status = signal_status_back
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def trace_in
|
||||||
|
Tracer.on if @context.use_tracer?
|
||||||
|
begin
|
||||||
|
yield
|
||||||
|
ensure
|
||||||
|
Tracer.off if @context.use_tracer?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def prompt(prompt, ltype, indent, line_no)
|
||||||
|
p = prompt.dup
|
||||||
|
p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
|
||||||
|
case $2
|
||||||
|
when "N"
|
||||||
|
@context.irb_name
|
||||||
|
when "m"
|
||||||
|
@context.main.to_s
|
||||||
|
when "M"
|
||||||
|
@context.main.inspect
|
||||||
|
when "l"
|
||||||
|
ltype
|
||||||
|
when "i"
|
||||||
|
if $1
|
||||||
|
format("%" + $1 + "d", indent)
|
||||||
|
else
|
||||||
|
indent.to_s
|
||||||
|
end
|
||||||
|
when "n"
|
||||||
|
if $1
|
||||||
|
format("%" + $1 + "d", line_no)
|
||||||
|
else
|
||||||
|
line_no.to_s
|
||||||
|
end
|
||||||
|
when "%"
|
||||||
|
"%"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
p
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
ary = []
|
||||||
|
for iv in instance_variables
|
||||||
|
case iv
|
||||||
|
when "@signal_status"
|
||||||
|
ary.push format("%s=:%s", iv, @signal_status.id2name)
|
||||||
|
when "@context"
|
||||||
|
ary.push format("%s=%s", iv, eval(iv).__to_s__)
|
||||||
|
else
|
||||||
|
ary.push format("%s=%s", iv, eval(iv))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
format("#<%s: %s>", type, ary.join(", "))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# irb context
|
||||||
|
#
|
||||||
|
class Context
|
||||||
|
#
|
||||||
|
# Arguments:
|
||||||
|
# input_method: nil -- stdin or readline
|
||||||
|
# String -- File
|
||||||
|
# other -- using this as InputMethod
|
||||||
|
#
|
||||||
|
def initialize(irb, main, bind, input_method = nil)
|
||||||
|
@irb = irb
|
||||||
|
@main = main
|
||||||
|
@bind = bind
|
||||||
|
@thread = Thread.current if defined? Thread
|
||||||
|
@irb_level = 0
|
||||||
|
|
||||||
|
# copy of default configuration
|
||||||
|
@ap_name = IRB.conf[:AP_NAME]
|
||||||
|
@rc = IRB.conf[:RC]
|
||||||
|
@load_modules = IRB.conf[:LOAD_MODULES]
|
||||||
|
|
||||||
|
self.math_mode = IRB.conf[:MATH_MODE]
|
||||||
|
@use_readline = IRB.conf[:USE_READLINE]
|
||||||
|
@inspect_mode = IRB.conf[:INSPECT_MODE]
|
||||||
|
@use_tracer = IRB.conf[:USE_TRACER]
|
||||||
|
# @use_loader = IRB.conf[:USE_LOADER]
|
||||||
|
|
||||||
|
self.prompt_mode = IRB.conf[:PROMPT_MODE]
|
||||||
|
|
||||||
|
@ignore_sigint = IRB.conf[:IGNORE_SIGINT]
|
||||||
|
@ignore_eof = IRB.conf[:IGNORE_EOF]
|
||||||
|
|
||||||
|
@back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT]
|
||||||
|
|
||||||
|
debug_level = IRB.conf[:DEBUG_LEVEL]
|
||||||
|
@verbose = IRB.conf[:VERBOSE]
|
||||||
|
|
||||||
|
@tracer_initialized = false
|
||||||
|
|
||||||
|
if IRB.conf[:SINGLE_IRB] or !defined?(JobManager)
|
||||||
|
@irb_name = IRB.conf[:IRB_NAME]
|
||||||
|
else
|
||||||
|
@irb_name = "irb#"+IRB.JobManager.n_jobs.to_s
|
||||||
|
end
|
||||||
|
@irb_path = "(" + @irb_name + ")"
|
||||||
|
|
||||||
|
case input_method
|
||||||
|
when nil
|
||||||
|
if (use_readline.nil? && IRB.conf[:PROMPT_MODE] != :INF_RUBY ||
|
||||||
|
use_readline?)
|
||||||
|
@io = ReadlineInputMethod.new
|
||||||
|
else
|
||||||
|
@io = StdioInputMethod.new
|
||||||
|
end
|
||||||
|
when String
|
||||||
|
@io = FileInputMethod.new(input_method)
|
||||||
|
@irb_name = File.basename(input_method)
|
||||||
|
@irb_path = input_method
|
||||||
|
else
|
||||||
|
@io = input_method
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
attr :bind, true
|
||||||
|
attr :main, true
|
||||||
|
attr :thread
|
||||||
|
attr :io, true
|
||||||
|
|
||||||
|
attr :_
|
||||||
|
|
||||||
|
attr :irb
|
||||||
|
attr :ap_name
|
||||||
|
attr :rc
|
||||||
|
attr :load_modules
|
||||||
|
attr :irb_name
|
||||||
|
attr :irb_path
|
||||||
|
|
||||||
|
attr :math_mode, true
|
||||||
|
attr :use_readline, true
|
||||||
|
attr :inspect_mode
|
||||||
|
attr :use_tracer
|
||||||
|
# attr :use_loader
|
||||||
|
|
||||||
|
attr :debug_level
|
||||||
|
attr :verbose, true
|
||||||
|
|
||||||
|
attr :prompt_mode
|
||||||
|
attr :prompt_i, true
|
||||||
|
attr :prompt_s, true
|
||||||
|
attr :prompt_c, true
|
||||||
|
attr :auto_indent_mode, true
|
||||||
|
attr :return_format, true
|
||||||
|
|
||||||
|
attr :ignore_sigint, true
|
||||||
|
attr :ignore_eof, true
|
||||||
|
|
||||||
|
attr :back_trace_limit
|
||||||
|
|
||||||
|
# alias use_loader? use_loader
|
||||||
|
alias use_tracer? use_tracer
|
||||||
|
alias use_readline? use_readline
|
||||||
|
alias rc? rc
|
||||||
|
alias math? math_mode
|
||||||
|
alias verbose? verbose
|
||||||
|
alias ignore_sigint? ignore_sigint
|
||||||
|
alias ignore_eof? ignore_eof
|
||||||
|
|
||||||
|
def _=(value)
|
||||||
|
@_ = value
|
||||||
|
eval "_ = IRB.conf[:MAIN_CONTEXT]._", @bind
|
||||||
|
end
|
||||||
|
|
||||||
|
def irb_name
|
||||||
|
if @irb_level == 0
|
||||||
|
@irb_name
|
||||||
|
elsif @irb_name =~ /#[0-9]*$/
|
||||||
|
@irb_name + "." + @irb_level.to_s
|
||||||
|
else
|
||||||
|
@irb_name + "#0." + @irb_level.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def prompt_mode=(mode)
|
||||||
|
@prompt_mode = mode
|
||||||
|
pconf = IRB.conf[:PROMPT][mode]
|
||||||
|
@prompt_i = pconf[:PROMPT_I]
|
||||||
|
@prompt_s = pconf[:PROMPT_S]
|
||||||
|
@prompt_c = pconf[:PROMPT_C]
|
||||||
|
@return_format = pconf[:RETURN]
|
||||||
|
if ai = pconf.include?(:AUTO_INDENT)
|
||||||
|
@auto_indent_mode = ai
|
||||||
|
else
|
||||||
|
@auto_indent_mode = IRB.conf[:AUTO_INDENT]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect?
|
||||||
|
@inspect_mode.nil? && !@math_mode or @inspect_mode
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_input?
|
||||||
|
@io.type == FileInputMethod
|
||||||
|
end
|
||||||
|
|
||||||
|
def use_tracer=(opt)
|
||||||
|
if opt
|
||||||
|
IRB.initialize_tracer
|
||||||
|
unless @tracer_initialized
|
||||||
|
Tracer.set_get_line_procs(@irb_path) {
|
||||||
|
|line_no|
|
||||||
|
@io.line(line_no)
|
||||||
|
}
|
||||||
|
@tracer_initialized = true
|
||||||
|
end
|
||||||
|
elsif !opt && @use_tracer
|
||||||
|
Tracer.off
|
||||||
|
end
|
||||||
|
@use_tracer=opt
|
||||||
|
end
|
||||||
|
|
||||||
|
def use_loader
|
||||||
|
IRB.conf[:USE_LOADER]
|
||||||
|
end
|
||||||
|
|
||||||
|
def use_loader=(opt)
|
||||||
|
IRB.conf[:USE_LOADER] = opt
|
||||||
|
if opt
|
||||||
|
IRB.initialize_loader
|
||||||
|
end
|
||||||
|
print "Switch to load/require#{unless use_loader; ' non';end} trace mode.\n" if verbose?
|
||||||
|
opt
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect_mode=(opt)
|
||||||
|
if opt
|
||||||
|
@inspect_mode = opt
|
||||||
|
else
|
||||||
|
@inspect_mode = !@inspect_mode
|
||||||
|
end
|
||||||
|
print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose?
|
||||||
|
@inspect_mode
|
||||||
|
end
|
||||||
|
|
||||||
|
def math_mode=(opt)
|
||||||
|
if @math_mode == true && opt == false
|
||||||
|
IRB.fail CantRetuenNormalMode
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@math_mode = opt
|
||||||
|
if math_mode
|
||||||
|
IRB.initialize_mathn
|
||||||
|
@main.instance_eval("include Math")
|
||||||
|
print "start math mode\n" if verbose?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def use_readline=(opt)
|
||||||
|
@use_readline = opt
|
||||||
|
print "use readline module\n" if @use_readline
|
||||||
|
end
|
||||||
|
|
||||||
|
def debug_level=(value)
|
||||||
|
@debug_level = value
|
||||||
|
RubyLex.debug_level = value
|
||||||
|
SLex.debug_level = value
|
||||||
|
end
|
||||||
|
|
||||||
|
def debug?
|
||||||
|
@debug_level > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_binding(*main)
|
||||||
|
back = [@bind, @main]
|
||||||
|
@bind = IRB.workspace_binding(*main)
|
||||||
|
unless main.empty?
|
||||||
|
@main = eval("self", @bind)
|
||||||
|
begin
|
||||||
|
@main.extend ExtendCommand
|
||||||
|
rescue
|
||||||
|
print "can't change binding to: ", @main.inspect, "\n"
|
||||||
|
@bind, @main = back
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@irb_level += 1
|
||||||
|
begin
|
||||||
|
catch(:SU_EXIT) do
|
||||||
|
@irb.eval_input
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
@irb_level -= 1
|
||||||
|
@bind, @main = back
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias __exit__ exit
|
||||||
|
def exit(ret = 0)
|
||||||
|
if @irb_level == 0
|
||||||
|
IRB.irb_exit(@irb, ret)
|
||||||
|
else
|
||||||
|
throw :SU_EXIT, ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
NOPRINTING_IVARS = ["@_"]
|
||||||
|
NO_INSPECTING_IVARS = ["@irb", "@io"]
|
||||||
|
IDNAME_IVARS = ["@prompt_mode"]
|
||||||
|
|
||||||
|
alias __inspect__ inspect
|
||||||
|
def inspect
|
||||||
|
array = []
|
||||||
|
for ivar in instance_variables.sort{|e1, e2| e1 <=> e2}
|
||||||
|
name = ivar.sub(/^@(.*)$/){$1}
|
||||||
|
val = instance_eval(ivar)
|
||||||
|
case ivar
|
||||||
|
when *NOPRINTING_IVARS
|
||||||
|
next
|
||||||
|
when *NO_INSPECTING_IVARS
|
||||||
|
array.push format("conf.%s=%s", name, val.to_s)
|
||||||
|
when *IDNAME_IVARS
|
||||||
|
array.push format("conf.%s=:%s", name, val.id2name)
|
||||||
|
else
|
||||||
|
array.push format("conf.%s=%s", name, val.inspect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
array.join("\n")
|
||||||
|
end
|
||||||
|
alias __to_s__ to_s
|
||||||
|
alias to_s inspect
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# IRB extended command
|
||||||
|
#
|
||||||
|
module Loader; end
|
||||||
|
module ExtendCommand
|
||||||
|
include Loader
|
||||||
|
|
||||||
|
alias irb_exit_org exit
|
||||||
|
def irb_exit(ret = 0)
|
||||||
|
irb_context.exit(ret)
|
||||||
|
end
|
||||||
|
alias exit irb_exit
|
||||||
|
alias quit irb_exit
|
||||||
|
|
||||||
|
alias irb_fork fork
|
||||||
|
def fork(&block)
|
||||||
|
unless irb_fork
|
||||||
|
eval "alias exit irb_exit_org"
|
||||||
|
instance_eval "alias exit irb_exit_org"
|
||||||
|
if iterator?
|
||||||
|
yield
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def irb_change_binding(*main)
|
||||||
|
irb_context.change_binding(*main)
|
||||||
|
end
|
||||||
|
alias cb irb_change_binding
|
||||||
|
|
||||||
|
def irb_source(file)
|
||||||
|
irb_context.source(file)
|
||||||
|
end
|
||||||
|
alias source irb_source
|
||||||
|
|
||||||
|
def irb(*obj)
|
||||||
|
require "irb/multi-irb"
|
||||||
|
IRB.irb(nil, *obj)
|
||||||
|
end
|
||||||
|
|
||||||
|
def irb_context
|
||||||
|
IRB.conf[:MAIN_CONTEXT]
|
||||||
|
end
|
||||||
|
alias conf irb_context
|
||||||
|
|
||||||
|
def irb_jobs
|
||||||
|
require "irb/multi-irb"
|
||||||
|
IRB.JobManager
|
||||||
|
end
|
||||||
|
alias jobs irb_jobs
|
||||||
|
|
||||||
|
def irb_fg(key)
|
||||||
|
require "irb/multi-irb"
|
||||||
|
IRB.JobManager.switch(key)
|
||||||
|
end
|
||||||
|
alias fg irb_fg
|
||||||
|
|
||||||
|
def irb_kill(*keys)
|
||||||
|
require "irb/multi-irb"
|
||||||
|
IRB.JobManager.kill(*keys)
|
||||||
|
end
|
||||||
|
alias kill irb_kill
|
||||||
|
end
|
||||||
|
|
||||||
|
# Singleton method
|
||||||
|
def @CONF.inspect
|
||||||
|
IRB.version unless self[:VERSION]
|
||||||
|
|
||||||
|
array = []
|
||||||
|
for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
|
||||||
|
case k
|
||||||
|
when :MAIN_CONTEXT
|
||||||
|
next
|
||||||
|
when :PROMPT
|
||||||
|
s = v.collect{
|
||||||
|
|kk, vv|
|
||||||
|
ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
|
||||||
|
format(":%s=>{%s}", kk.id2name, ss.join(", "))
|
||||||
|
}
|
||||||
|
array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
|
||||||
|
else
|
||||||
|
array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
array.join("\n")
|
||||||
|
end
|
||||||
|
end
|
212
lib/irb/multi-irb.rb
Normal file
212
lib/irb/multi-irb.rb
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
#
|
||||||
|
# multi-irb.rb - multiple irb module
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
IRB.fail CanNotGoMultiIrbMode unless defined?(Thread)
|
||||||
|
require "thread"
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
# job management class
|
||||||
|
class JobManager
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
# @jobs = [[thread, irb],...]
|
||||||
|
@jobs = []
|
||||||
|
@current_job = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
attr :current_job, true
|
||||||
|
|
||||||
|
def n_jobs
|
||||||
|
@jobs.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def thread(key)
|
||||||
|
th, irb = search(key)
|
||||||
|
irb
|
||||||
|
end
|
||||||
|
|
||||||
|
def irb(key)
|
||||||
|
th, irb = search(key)
|
||||||
|
irb
|
||||||
|
end
|
||||||
|
|
||||||
|
def main_thread
|
||||||
|
@jobs[0][0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def main_irb
|
||||||
|
@jobs[0][1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert(irb)
|
||||||
|
@jobs.push [Thread.current, irb]
|
||||||
|
end
|
||||||
|
|
||||||
|
def switch(key)
|
||||||
|
th, irb = search(key)
|
||||||
|
IRB.fail IrbAlreadyDead unless th.alive?
|
||||||
|
IRB.fail IrbSwitchToCurrentThread if th == Thread.current
|
||||||
|
@current_job = irb
|
||||||
|
th.run
|
||||||
|
Thread.stop
|
||||||
|
@current_job = irb(Thread.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
def kill(*keys)
|
||||||
|
for key in keys
|
||||||
|
th, irb = search(key)
|
||||||
|
IRB.fail IrbAlreadyDead unless th.alive?
|
||||||
|
th.exit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(key)
|
||||||
|
case key
|
||||||
|
when Integer
|
||||||
|
@jobs[key]
|
||||||
|
when Irb
|
||||||
|
@jobs.find{|k, v| v.equal?(irb)}
|
||||||
|
when Thread
|
||||||
|
@jobs.assoc(key)
|
||||||
|
else
|
||||||
|
assoc = @jobs.find{|k, v| v.context.main.equal?(key)}
|
||||||
|
IRB.fail NoSuchJob, key if assoc.nil?
|
||||||
|
assoc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(key)
|
||||||
|
case key
|
||||||
|
when Integer
|
||||||
|
IRB.fail NoSuchJob, key unless @jobs[key]
|
||||||
|
@jobs[key] = nil
|
||||||
|
else
|
||||||
|
catch (:EXISTS) do
|
||||||
|
@jobs.each_index do
|
||||||
|
|i|
|
||||||
|
if @jobs[i] and (@jobs[i][0] == key ||
|
||||||
|
@jobs[i][1] == key ||
|
||||||
|
@jobs[i][1].context.main.equal?(key))
|
||||||
|
@jobs[i] = nil
|
||||||
|
throw :EXISTS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
IRB.fail NoSuchJob, key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
until assoc = @jobs.pop; end unless @jobs.empty?
|
||||||
|
@jobs.push assoc
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
ary = []
|
||||||
|
@jobs.each_index do
|
||||||
|
|i|
|
||||||
|
th, irb = @jobs[i]
|
||||||
|
next if th.nil?
|
||||||
|
|
||||||
|
if th.alive?
|
||||||
|
if th.stop?
|
||||||
|
t_status = "stop"
|
||||||
|
else
|
||||||
|
t_status = "running"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
t_status = "exited"
|
||||||
|
end
|
||||||
|
ary.push format("#%d->%s on %s (%s: %s)",
|
||||||
|
i,
|
||||||
|
irb.context.irb_name,
|
||||||
|
irb.context.main,
|
||||||
|
th,
|
||||||
|
t_status)
|
||||||
|
end
|
||||||
|
ary.join("\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@JobManager = JobManager.new
|
||||||
|
|
||||||
|
def IRB.JobManager
|
||||||
|
@JobManager
|
||||||
|
end
|
||||||
|
|
||||||
|
# invoke multiple irb
|
||||||
|
def IRB.irb(file = nil, *main)
|
||||||
|
workspace = IRB.workspace_binding(*main)
|
||||||
|
if main.empty?
|
||||||
|
main = eval("self", workspace)
|
||||||
|
else
|
||||||
|
main = main[0]
|
||||||
|
end
|
||||||
|
parent_thread = Thread.current
|
||||||
|
Thread.start do
|
||||||
|
begin
|
||||||
|
irb = Irb.new(main, workspace, file)
|
||||||
|
rescue
|
||||||
|
print "Subirb can't start with context(self): ", main.inspect, "\n"
|
||||||
|
print "return to main irb\n"
|
||||||
|
Thread.pass
|
||||||
|
Thread.main.wakeup
|
||||||
|
Thread.exit
|
||||||
|
end
|
||||||
|
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
||||||
|
@JobManager.insert(irb)
|
||||||
|
begin
|
||||||
|
system_exit = false
|
||||||
|
catch(:IRB_EXIT) do
|
||||||
|
irb.eval_input
|
||||||
|
end
|
||||||
|
rescue SystemExit
|
||||||
|
system_exit = true
|
||||||
|
raise
|
||||||
|
#fail
|
||||||
|
ensure
|
||||||
|
unless system_exit
|
||||||
|
@JobManager.delete(irb)
|
||||||
|
if parent_thread.alive?
|
||||||
|
@JobManager.current_job = @JobManager.irb(parent_thread)
|
||||||
|
parent_thread.run
|
||||||
|
else
|
||||||
|
@JobManager.current_job = @JobManager.main_irb
|
||||||
|
@JobManager.main_thread.run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Thread.stop
|
||||||
|
@JobManager.current_job = @JobManager.irb(Thread.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
class Context
|
||||||
|
def _=(value)
|
||||||
|
@_ = value
|
||||||
|
eval "_ = IRB.JobManager.irb(Thread.current).context._", @bind
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ExtendCommand
|
||||||
|
def irb_context
|
||||||
|
IRB.JobManager.irb(Thread.current).context
|
||||||
|
end
|
||||||
|
alias conf irb_context
|
||||||
|
end
|
||||||
|
|
||||||
|
@CONF[:SINGLE_IRB_MODE] = false
|
||||||
|
@JobManager.insert(@CONF[:MAIN_CONTEXT].irb)
|
||||||
|
@JobManager.current_job = @CONF[:MAIN_CONTEXT].irb
|
||||||
|
|
||||||
|
trap("SIGINT") do
|
||||||
|
@JobManager.current_job.signal_handle
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
955
lib/irb/ruby-lex.rb
Normal file
955
lib/irb/ruby-lex.rb
Normal file
@ -0,0 +1,955 @@
|
|||||||
|
#
|
||||||
|
# ruby-lex.rb - ruby lexcal analizer
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
require "e2mmap"
|
||||||
|
require "irb/slex"
|
||||||
|
require "irb/ruby-token"
|
||||||
|
|
||||||
|
class RubyLex
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
extend Exception2MessageMapper
|
||||||
|
def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
|
||||||
|
def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
|
||||||
|
def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
|
||||||
|
def_exception(:TkReading2TokenDuplicateError,
|
||||||
|
"key duplicate(token_n='%s', key='%s')")
|
||||||
|
def_exception(:SyntaxError, "%s")
|
||||||
|
|
||||||
|
include RubyToken
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr :debug_level, TRUE
|
||||||
|
def debug?
|
||||||
|
@debug_level > 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@debug_level = 0
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
lex_init
|
||||||
|
set_input(STDIN)
|
||||||
|
|
||||||
|
@seek = 0
|
||||||
|
@exp_line_no = @line_no = 1
|
||||||
|
@base_char_no = 0
|
||||||
|
@char_no = 0
|
||||||
|
@rests = []
|
||||||
|
@readed = []
|
||||||
|
@here_readed = []
|
||||||
|
|
||||||
|
@indent = 0
|
||||||
|
|
||||||
|
@skip_space = false
|
||||||
|
@readed_auto_clean_up = false
|
||||||
|
@exception_on_syntax_error = true
|
||||||
|
end
|
||||||
|
|
||||||
|
attr :skip_space, true
|
||||||
|
attr :readed_auto_clean_up, true
|
||||||
|
attr :exception_on_syntax_error, true
|
||||||
|
|
||||||
|
attr :seek
|
||||||
|
attr :char_no
|
||||||
|
attr :line_no
|
||||||
|
attr :indent
|
||||||
|
|
||||||
|
# io functions
|
||||||
|
def set_input(io, p = nil)
|
||||||
|
@io = io
|
||||||
|
if p.kind_of?(Proc)
|
||||||
|
@input = p
|
||||||
|
elsif iterator?
|
||||||
|
@input = proc
|
||||||
|
else
|
||||||
|
@input = proc{@io.gets}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_readed
|
||||||
|
if idx = @readed.reverse.index("\n")
|
||||||
|
@base_char_no = idx
|
||||||
|
else
|
||||||
|
@base_char_no += @readed.size
|
||||||
|
end
|
||||||
|
|
||||||
|
readed = @readed.join("")
|
||||||
|
@readed = []
|
||||||
|
readed
|
||||||
|
end
|
||||||
|
|
||||||
|
def getc
|
||||||
|
while @rests.empty?
|
||||||
|
return nil unless buf_input
|
||||||
|
end
|
||||||
|
c = @rests.shift
|
||||||
|
if @here_header
|
||||||
|
@here_readed.push c
|
||||||
|
else
|
||||||
|
@readed.push c
|
||||||
|
end
|
||||||
|
@seek += 1
|
||||||
|
if c == "\n"
|
||||||
|
@line_no += 1
|
||||||
|
@char_no = 0
|
||||||
|
else
|
||||||
|
@char_no += 1
|
||||||
|
end
|
||||||
|
c
|
||||||
|
end
|
||||||
|
|
||||||
|
def gets
|
||||||
|
l = ""
|
||||||
|
while c = getc
|
||||||
|
l.concat c
|
||||||
|
break if c == "\n"
|
||||||
|
end
|
||||||
|
l
|
||||||
|
end
|
||||||
|
|
||||||
|
def eof?
|
||||||
|
@io.eof?
|
||||||
|
end
|
||||||
|
|
||||||
|
def getc_of_rests
|
||||||
|
if @rests.empty?
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
getc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def ungetc(c = nil)
|
||||||
|
if @here_readed.empty?
|
||||||
|
c2 = @readed.pop
|
||||||
|
else
|
||||||
|
c2 = @here_readed.pop
|
||||||
|
end
|
||||||
|
c = c2 unless c
|
||||||
|
@rests.unshift c #c =
|
||||||
|
@seek -= 1
|
||||||
|
if c == "\n"
|
||||||
|
@line_no -= 1
|
||||||
|
if idx = @readed.reverse.index("\n")
|
||||||
|
@char_no = @readed.size - idx
|
||||||
|
else
|
||||||
|
@char_no = @base_char_no + @readed.size
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@char_no -= 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def peek_equal?(str)
|
||||||
|
chrs = str.split(//)
|
||||||
|
until @rests.size >= chrs.size
|
||||||
|
return false unless buf_input
|
||||||
|
end
|
||||||
|
@rests[0, chrs.size] == chrs
|
||||||
|
end
|
||||||
|
|
||||||
|
def peek_match?(regexp)
|
||||||
|
while @rests.empty?
|
||||||
|
return false unless buf_input
|
||||||
|
end
|
||||||
|
regexp =~ @rests.join("")
|
||||||
|
end
|
||||||
|
|
||||||
|
def peek(i = 0)
|
||||||
|
while @rests.size <= i
|
||||||
|
return nil unless buf_input
|
||||||
|
end
|
||||||
|
@rests[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
def buf_input
|
||||||
|
prompt
|
||||||
|
line = @input.call
|
||||||
|
return nil unless line
|
||||||
|
@rests.concat line.split(//)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
private :buf_input
|
||||||
|
|
||||||
|
def set_prompt(p = proc)
|
||||||
|
if p.kind_of?(Proc)
|
||||||
|
@prompt = p
|
||||||
|
else
|
||||||
|
@prompt = proc{print p}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def prompt
|
||||||
|
if @prompt
|
||||||
|
@prompt.call(@ltype, @indent, @continue, @line_no)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_input
|
||||||
|
@ltype = nil
|
||||||
|
@quoted = nil
|
||||||
|
@indent = 0
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
@space_seen = false
|
||||||
|
@here_header = false
|
||||||
|
|
||||||
|
prompt
|
||||||
|
@continue = FALSE
|
||||||
|
|
||||||
|
@line = ""
|
||||||
|
@exp_line_no = @line_no
|
||||||
|
end
|
||||||
|
|
||||||
|
def each_top_level_statement
|
||||||
|
initialize_input
|
||||||
|
loop do
|
||||||
|
@continue = FALSE
|
||||||
|
prompt
|
||||||
|
unless l = lex
|
||||||
|
break if @line == ''
|
||||||
|
else
|
||||||
|
# p l
|
||||||
|
@line.concat l
|
||||||
|
if @ltype or @continue or @indent > 0
|
||||||
|
next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @line != "\n"
|
||||||
|
yield @line, @exp_line_no
|
||||||
|
end
|
||||||
|
break unless l
|
||||||
|
@line = ''
|
||||||
|
@exp_line_no = @line_no
|
||||||
|
|
||||||
|
@indent = 0
|
||||||
|
prompt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def lex
|
||||||
|
until (((tk = token).kind_of?(TkNL) || tk.kind_of?(TkEND_OF_SCRIPT)) &&
|
||||||
|
!@continue or
|
||||||
|
tk.nil?)
|
||||||
|
# p tk
|
||||||
|
# p self
|
||||||
|
end
|
||||||
|
line = get_readed
|
||||||
|
# print self.inspect
|
||||||
|
if line == "" and tk.kind_of?(TkEND_OF_SCRIPT) || tk.nil?
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def token
|
||||||
|
# require "tracer"
|
||||||
|
# Tracer.on
|
||||||
|
@prev_seek = @seek
|
||||||
|
@prev_line_no = @line_no
|
||||||
|
@prev_char_no = @char_no
|
||||||
|
begin
|
||||||
|
begin
|
||||||
|
tk = @OP.match(self)
|
||||||
|
@space_seen = tk.kind_of?(TkSPACE)
|
||||||
|
rescue SyntaxError
|
||||||
|
abort if @exception_on_syntax_error
|
||||||
|
tk = TkError.new(@seek, @line_no, @char_no)
|
||||||
|
end
|
||||||
|
end while @skip_space and tk.kind_of?(TkSPACE)
|
||||||
|
if @readed_auto_clean_up
|
||||||
|
get_readed
|
||||||
|
end
|
||||||
|
# Tracer.off
|
||||||
|
tk
|
||||||
|
end
|
||||||
|
|
||||||
|
ENINDENT_CLAUSE = [
|
||||||
|
"case", "class", "def", "do", "for", "if",
|
||||||
|
"module", "unless", "until", "while", "begin" #, "when"
|
||||||
|
]
|
||||||
|
DEINDENT_CLAUSE = ["end" #, "when"
|
||||||
|
]
|
||||||
|
|
||||||
|
PERCENT_LTYPE = {
|
||||||
|
"q" => "\'",
|
||||||
|
"Q" => "\"",
|
||||||
|
"x" => "\`",
|
||||||
|
"r" => "\/",
|
||||||
|
"w" => "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
PERCENT_PAREN = {
|
||||||
|
"{" => "}",
|
||||||
|
"[" => "]",
|
||||||
|
"<" => ">",
|
||||||
|
"(" => ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
Ltype2Token = {
|
||||||
|
"\'" => TkSTRING,
|
||||||
|
"\"" => TkSTRING,
|
||||||
|
"\`" => TkXSTRING,
|
||||||
|
"\/" => TkREGEXP,
|
||||||
|
"]" => TkDSTRING
|
||||||
|
}
|
||||||
|
DLtype2Token = {
|
||||||
|
"\"" => TkDSTRING,
|
||||||
|
"\`" => TkDXSTRING,
|
||||||
|
"\/" => TkDREGEXP,
|
||||||
|
}
|
||||||
|
|
||||||
|
def lex_init()
|
||||||
|
@OP = SLex.new
|
||||||
|
@OP.def_rules("\0", "\004", "\032") do
|
||||||
|
Token(TkEND_OF_SCRIPT)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules(" ", "\t", "\f", "\r", "\13") do
|
||||||
|
@space_seen = TRUE
|
||||||
|
while getc =~ /[ \t\f\r\13]/; end
|
||||||
|
ungetc
|
||||||
|
Token(TkSPACE)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("#") do
|
||||||
|
|op, io|
|
||||||
|
identify_comment
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("=begin", proc{@prev_char_no == 0 && peek(0) =~ /\s/}) do
|
||||||
|
|op, io|
|
||||||
|
@ltype = "="
|
||||||
|
until getc == "\n"; end
|
||||||
|
until peek_equal?("=end") && peek(4) =~ /\s/
|
||||||
|
until getc == "\n"; end
|
||||||
|
end
|
||||||
|
getc; getc; getc; getc
|
||||||
|
@ltype = nil
|
||||||
|
Token(TkRD_COMMENT)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("\n") do
|
||||||
|
print "\\n\n" if RubyLex.debug?
|
||||||
|
case @lex_state
|
||||||
|
when EXPR_BEG, EXPR_FNAME, EXPR_DOT
|
||||||
|
@continue = TRUE
|
||||||
|
else
|
||||||
|
@continue = FALSE
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
end
|
||||||
|
@here_header = false
|
||||||
|
@here_readed = []
|
||||||
|
Token(TkNL)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("*", "**",
|
||||||
|
"!", "!=", "!~",
|
||||||
|
"=", "==", "===",
|
||||||
|
"=~", "<=>",
|
||||||
|
"<", "<=",
|
||||||
|
">", ">=", ">>") do
|
||||||
|
|op, io|
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(op)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("<<") do
|
||||||
|
|op, io|
|
||||||
|
if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
|
||||||
|
(@lex_state != EXPR_ARG || @space_seen)
|
||||||
|
c = peek(0)
|
||||||
|
if /\S/ =~ c && (/["'`]/ =~ c || /[\w_]/ =~ c)
|
||||||
|
tk = identify_here_document;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tk = Token(op)
|
||||||
|
end
|
||||||
|
tk
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("'", '"') do
|
||||||
|
|op, io|
|
||||||
|
identify_string(op)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("`") do
|
||||||
|
|op, io|
|
||||||
|
if @lex_state == EXPR_FNAME
|
||||||
|
Token(op)
|
||||||
|
else
|
||||||
|
identify_string(op)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules('?') do
|
||||||
|
|op, io|
|
||||||
|
if @lex_state == EXPR_END
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(TkQUESTION)
|
||||||
|
else
|
||||||
|
ch = getc
|
||||||
|
if @lex_state == EXPR_ARG && ch !~ /\s/
|
||||||
|
ungetc
|
||||||
|
@lex_state = EXPR_BEG;
|
||||||
|
Token(TkQUESTION)
|
||||||
|
else
|
||||||
|
if (ch == '\\')
|
||||||
|
read_escape
|
||||||
|
end
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
Token(TkINTEGER)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("&", "&&", "|", "||") do
|
||||||
|
|op, io|
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(op)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("+=", "-=", "*=", "**=",
|
||||||
|
"&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
|
||||||
|
|op, io|
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
op =~ /^(.*)=$/
|
||||||
|
Token(TkOPASGN, $1)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("+@", proc{@lex_state == EXPR_FNAME}) do
|
||||||
|
Token(TkUPLUS)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("-@", proc{@lex_state == EXPR_FNAME}) do
|
||||||
|
Token(TkUMINUS)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("+", "-") do
|
||||||
|
|op, io|
|
||||||
|
catch(:RET) do
|
||||||
|
if @lex_state == EXPR_ARG
|
||||||
|
if @space_seen and peek(0) =~ /[0-9]/
|
||||||
|
throw :RET, identify_number
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
end
|
||||||
|
elsif @lex_state != EXPR_END and peek(0) =~ /[0-9]/
|
||||||
|
throw :RET, identify_number
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
end
|
||||||
|
Token(op)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule(".") do
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
if peek(0) =~ /[0-9]/
|
||||||
|
ungetc
|
||||||
|
identify_number
|
||||||
|
else
|
||||||
|
# for obj.if
|
||||||
|
@lex_state = EXPR_DOT
|
||||||
|
Token(TkDOT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("..", "...") do
|
||||||
|
|op, io|
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(op)
|
||||||
|
end
|
||||||
|
|
||||||
|
lex_int2
|
||||||
|
end
|
||||||
|
|
||||||
|
def lex_int2
|
||||||
|
@OP.def_rules("]", "}", ")") do
|
||||||
|
|op, io|
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
@indent -= 1
|
||||||
|
Token(op)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule(":") do
|
||||||
|
if @lex_state == EXPR_END || peek(0) =~ /\s/
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(TkCOLON)
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_FNAME;
|
||||||
|
Token(TkSYMBEG)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("::") do
|
||||||
|
# p @lex_state.id2name, @space_seen
|
||||||
|
if @lex_state == EXPR_BEG or @lex_state == EXPR_ARG && @space_seen
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(TkCOLON3)
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_DOT
|
||||||
|
Token(TkCOLON2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("/") do
|
||||||
|
|op, io|
|
||||||
|
if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
|
||||||
|
identify_string(op)
|
||||||
|
elsif peek(0) == '='
|
||||||
|
getc
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(TkOPASGN, :/) #/)
|
||||||
|
elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
|
||||||
|
identify_string(op)
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token("/") #/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rules("^") do
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token("^")
|
||||||
|
end
|
||||||
|
|
||||||
|
# @OP.def_rules("^=") do
|
||||||
|
# @lex_state = EXPR_BEG
|
||||||
|
# Token(OP_ASGN, :^)
|
||||||
|
# end
|
||||||
|
|
||||||
|
@OP.def_rules(",", ";") do
|
||||||
|
|op, io|
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(op)
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("~") do
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token("~")
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("~@", proc{@lex_state = EXPR_FNAME}) do
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token("~")
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("(") do
|
||||||
|
@indent += 1
|
||||||
|
if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(TkfLPAREN)
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token(TkLPAREN)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("[]", proc{@lex_state == EXPR_FNAME}) do
|
||||||
|
Token("[]")
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("[]=", proc{@lex_state == EXPR_FNAME}) do
|
||||||
|
Token("[]=")
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("[") do
|
||||||
|
@indent += 1
|
||||||
|
if @lex_state == EXPR_FNAME
|
||||||
|
Token(TkfLBRACK)
|
||||||
|
else
|
||||||
|
if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
|
||||||
|
t = Token(TkLBRACK)
|
||||||
|
elsif @lex_state == EXPR_ARG && @space_seen
|
||||||
|
t = Token(TkLBRACK)
|
||||||
|
else
|
||||||
|
t = Token(TkfLBRACK)
|
||||||
|
end
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
t
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule("{") do
|
||||||
|
@indent += 1
|
||||||
|
if @lex_state != EXPR_END && @lex_state != EXPR_ARG
|
||||||
|
t = Token(TkLBRACE)
|
||||||
|
else
|
||||||
|
t = Token(TkfLBRACE)
|
||||||
|
end
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
t
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule('\\') do
|
||||||
|
if getc == "\n"
|
||||||
|
@space_seen = true
|
||||||
|
@continue = true
|
||||||
|
Token(TkSPACE)
|
||||||
|
else
|
||||||
|
ungetc
|
||||||
|
Token("\\")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule('%') do
|
||||||
|
|op, io|
|
||||||
|
if @lex_state == EXPR_BEG || @lex_state == EXPR_MID
|
||||||
|
identify_quotation
|
||||||
|
elsif peek(0) == '='
|
||||||
|
getc
|
||||||
|
Token(OP_ASGIN, "%")
|
||||||
|
elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
|
||||||
|
identify_quotation
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_BEG
|
||||||
|
Token("%") #))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule('$') do
|
||||||
|
identify_gvar
|
||||||
|
end
|
||||||
|
|
||||||
|
@OP.def_rule('@') do
|
||||||
|
if peek(0) =~ /[\w_]/
|
||||||
|
ungetc
|
||||||
|
identify_identifier
|
||||||
|
else
|
||||||
|
Token("@")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do
|
||||||
|
# |op, io|
|
||||||
|
# @indent += 1
|
||||||
|
# @lex_state = EXPR_FNAME
|
||||||
|
# # @lex_state = EXPR_END
|
||||||
|
# # until @rests[0] == "\n" or @rests[0] == ";"
|
||||||
|
# # rests.shift
|
||||||
|
# # end
|
||||||
|
# end
|
||||||
|
|
||||||
|
@OP.def_rule("") do
|
||||||
|
|op, io|
|
||||||
|
printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
|
||||||
|
if peek(0) =~ /[0-9]/
|
||||||
|
t = identify_number
|
||||||
|
elsif peek(0) =~ /[\w_]/
|
||||||
|
t = identify_identifier
|
||||||
|
end
|
||||||
|
printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
|
||||||
|
t
|
||||||
|
end
|
||||||
|
|
||||||
|
p @OP if RubyLex.debug?
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_gvar
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
|
||||||
|
case ch = getc
|
||||||
|
when /[~_*$?!@/\\;,=:<>".]/ #"
|
||||||
|
Token(TkGVAR, "$" + ch)
|
||||||
|
when "-"
|
||||||
|
Token(TkGVAR, "$-" + getc)
|
||||||
|
when "&", "`", "'", "+"
|
||||||
|
Token(TkBACK_REF, "$"+ch)
|
||||||
|
when /[1-9]/
|
||||||
|
while getc =~ /[0-9]/; end
|
||||||
|
ungetc
|
||||||
|
Token(TkNTH_REF)
|
||||||
|
when /\w/
|
||||||
|
ungetc
|
||||||
|
ungetc
|
||||||
|
identify_identifier
|
||||||
|
else
|
||||||
|
ungetc
|
||||||
|
Token("$")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_identifier
|
||||||
|
token = ""
|
||||||
|
token.concat getc if peek(0) =~ /[$@]/
|
||||||
|
while (ch = getc) =~ /\w|_/
|
||||||
|
print ":", ch, ":" if RubyLex.debug?
|
||||||
|
token.concat ch
|
||||||
|
end
|
||||||
|
ungetc
|
||||||
|
|
||||||
|
if ch == "!" or ch == "?"
|
||||||
|
token.concat getc
|
||||||
|
end
|
||||||
|
# fix token
|
||||||
|
|
||||||
|
case token
|
||||||
|
when /^\$/
|
||||||
|
return Token(TkGVAR, token)
|
||||||
|
when /^\@/
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
return Token(TkIVAR, token)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @lex_state != EXPR_DOT
|
||||||
|
print token, "\n" if RubyLex.debug?
|
||||||
|
|
||||||
|
token_c, *trans = TkReading2Token[token]
|
||||||
|
if token_c
|
||||||
|
# reserved word?
|
||||||
|
|
||||||
|
if (@lex_state != EXPR_BEG &&
|
||||||
|
@lex_state != EXPR_FNAME &&
|
||||||
|
trans[1])
|
||||||
|
# modifiers
|
||||||
|
token_c = TkSymbol2Token[trans[1]]
|
||||||
|
@lex_state = trans[0]
|
||||||
|
else
|
||||||
|
if @lex_state != EXPR_FNAME
|
||||||
|
if ENINDENT_CLAUSE.include?(token)
|
||||||
|
@indent += 1
|
||||||
|
elsif DEINDENT_CLAUSE.include?(token)
|
||||||
|
@indent -= 1
|
||||||
|
end
|
||||||
|
@lex_state = trans[0]
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Token(token_c, token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if @lex_state == EXPR_FNAME
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
if peek(0) == '='
|
||||||
|
token.concat getc
|
||||||
|
end
|
||||||
|
elsif @lex_state == EXPR_BEG || @lex_state == EXPR_DOT
|
||||||
|
@lex_state = EXPR_ARG
|
||||||
|
else
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
end
|
||||||
|
|
||||||
|
if token[0, 1] =~ /[A-Z]/
|
||||||
|
return Token(TkCONSTANT, token)
|
||||||
|
elsif token[token.size - 1, 1] =~ /[!?]/
|
||||||
|
return Token(TkFID, token)
|
||||||
|
else
|
||||||
|
return Token(TkIDENTIFIER, token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_here_document
|
||||||
|
ch = getc
|
||||||
|
if lt = PERCENT_LTYPE[ch]
|
||||||
|
quoted = ""
|
||||||
|
while (c = getc) && c != lt
|
||||||
|
quoted.concat c
|
||||||
|
end
|
||||||
|
else
|
||||||
|
lt = '"'
|
||||||
|
quoted = ch.dup
|
||||||
|
while (c = getc) && c =~ /\w/
|
||||||
|
quoted.concat c
|
||||||
|
end
|
||||||
|
ungetc
|
||||||
|
end
|
||||||
|
|
||||||
|
ltback, @ltype = @ltype, lt
|
||||||
|
reserve = []
|
||||||
|
while ch = getc
|
||||||
|
reserve.push ch
|
||||||
|
if ch == "\\"
|
||||||
|
reserve.push ch = getc
|
||||||
|
elsif ch == "\n"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@here_header = false
|
||||||
|
while (l = gets.chomp) && l != quoted
|
||||||
|
end
|
||||||
|
|
||||||
|
@here_header = true
|
||||||
|
@here_readed.concat reserve
|
||||||
|
while ch = reserve.pop
|
||||||
|
ungetc ch
|
||||||
|
end
|
||||||
|
|
||||||
|
@ltype = ltback
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
Token(Ltype2Token[lt])
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_quotation
|
||||||
|
ch = getc
|
||||||
|
if lt = PERCENT_LTYPE[ch]
|
||||||
|
ch = getc
|
||||||
|
elsif ch =~ /\W/
|
||||||
|
lt = "\""
|
||||||
|
else
|
||||||
|
RubyLex.fail SyntaxError, "unknown type of %string"
|
||||||
|
end
|
||||||
|
# if ch !~ /\W/
|
||||||
|
# ungetc
|
||||||
|
# next
|
||||||
|
# end
|
||||||
|
#@ltype = lt
|
||||||
|
@quoted = ch unless @quoted = PERCENT_PAREN[ch]
|
||||||
|
identify_string(lt, @quoted)
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_number
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
|
||||||
|
if ch = getc
|
||||||
|
if peek(0) == "x"
|
||||||
|
ch = getc
|
||||||
|
match = /[0-9a-f_]/
|
||||||
|
else
|
||||||
|
match = /[0-7_]/
|
||||||
|
end
|
||||||
|
while ch = getc
|
||||||
|
if ch !~ match
|
||||||
|
ungetc
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Token(TkINTEGER)
|
||||||
|
end
|
||||||
|
|
||||||
|
type = TkINTEGER
|
||||||
|
allow_point = TRUE
|
||||||
|
allow_e = TRUE
|
||||||
|
while ch = getc
|
||||||
|
case ch
|
||||||
|
when /[0-9_]/
|
||||||
|
when allow_point && "."
|
||||||
|
type = TkFLOAT
|
||||||
|
if peek(0) !~ /[0-9]/
|
||||||
|
ungetc
|
||||||
|
break
|
||||||
|
end
|
||||||
|
allow_point = false
|
||||||
|
when allow_e && "e", allow_e && "E"
|
||||||
|
type = TkFLOAT
|
||||||
|
if peek(0) =~ /[+-]/
|
||||||
|
getc
|
||||||
|
end
|
||||||
|
allow_e = false
|
||||||
|
allow_point = false
|
||||||
|
else
|
||||||
|
ungetc
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Token(type)
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_string(ltype, quoted = ltype)
|
||||||
|
@ltype = ltype
|
||||||
|
@quoted = quoted
|
||||||
|
subtype = nil
|
||||||
|
begin
|
||||||
|
while ch = getc
|
||||||
|
if @quoted == ch
|
||||||
|
break
|
||||||
|
elsif @ltype != "'" && @ltype != "]" and ch == "#"
|
||||||
|
subtype = true
|
||||||
|
elsif ch == '\\' #'
|
||||||
|
read_escape
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if @ltype == "/"
|
||||||
|
if peek(0) =~ /i|o|n|e|s/
|
||||||
|
getc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if subtype
|
||||||
|
Token(DLtype2Token[ltype])
|
||||||
|
else
|
||||||
|
Token(Ltype2Token[ltype])
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
@ltype = nil
|
||||||
|
@quoted = nil
|
||||||
|
@lex_state = EXPR_END
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_comment
|
||||||
|
@ltype = "#"
|
||||||
|
|
||||||
|
while ch = getc
|
||||||
|
if ch == "\\" #"
|
||||||
|
read_escape
|
||||||
|
end
|
||||||
|
if ch == "\n"
|
||||||
|
@ltype = nil
|
||||||
|
ungetc
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Token(TkCOMMENT)
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_escape
|
||||||
|
case ch = getc
|
||||||
|
when "\n", "\r", "\f"
|
||||||
|
when "\\", "n", "t", "r", "f", "v", "a", "e", "b" #"
|
||||||
|
when /[0-7]/
|
||||||
|
ungetc ch
|
||||||
|
3.times do
|
||||||
|
case ch = getc
|
||||||
|
when /[0-7]/
|
||||||
|
when nil
|
||||||
|
break
|
||||||
|
else
|
||||||
|
ungetc
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
when "x"
|
||||||
|
2.times do
|
||||||
|
case ch = getc
|
||||||
|
when /[0-9a-fA-F]/
|
||||||
|
when nil
|
||||||
|
break
|
||||||
|
else
|
||||||
|
ungetc
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
when "M"
|
||||||
|
if (ch = getc) != '-'
|
||||||
|
ungetc
|
||||||
|
else
|
||||||
|
if (ch = getc) == "\\" #"
|
||||||
|
read_escape(chrs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
when "C", "c", "^"
|
||||||
|
if ch == "C" and (ch = getc) != "-"
|
||||||
|
ungetc
|
||||||
|
elsif (ch = getc) == "\\" #"
|
||||||
|
read_escape(chrs)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# other characters
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
266
lib/irb/ruby-token.rb
Normal file
266
lib/irb/ruby-token.rb
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
#
|
||||||
|
# ruby-token.rb - ruby tokens
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
module RubyToken
|
||||||
|
EXPR_BEG = :EXPR_BEG
|
||||||
|
EXPR_MID = :EXPR_MID
|
||||||
|
EXPR_END = :EXPR_END
|
||||||
|
EXPR_ARG = :EXPR_ARG
|
||||||
|
EXPR_FNAME = :EXPR_FNAME
|
||||||
|
EXPR_DOT = :EXPR_DOT
|
||||||
|
EXPR_CLASS = :EXPR_CLASS
|
||||||
|
|
||||||
|
class Token
|
||||||
|
def initialize(seek, line_no, char_no)
|
||||||
|
@seek = seek
|
||||||
|
@line_no = line_no
|
||||||
|
@char_no = char_no
|
||||||
|
end
|
||||||
|
attr :seek
|
||||||
|
attr :line_no
|
||||||
|
attr :char_no
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkNode < Token
|
||||||
|
def initialize(seek, line_no, char_no)
|
||||||
|
super
|
||||||
|
end
|
||||||
|
attr :node
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkId < Token
|
||||||
|
def initialize(seek, line_no, char_no, name)
|
||||||
|
super(seek, line_no, char_no)
|
||||||
|
@name = name
|
||||||
|
end
|
||||||
|
attr :name
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkVal < Token
|
||||||
|
def initialize(seek, line_no, char_no, value = nil)
|
||||||
|
super(seek, line_no, char_no)
|
||||||
|
@value = value
|
||||||
|
end
|
||||||
|
attr :value
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkOp < Token
|
||||||
|
attr :name, true
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkOPASGN < TkOp
|
||||||
|
def initialize(seek, line_no, char_no, op)
|
||||||
|
super(seek, line_no, char_no)
|
||||||
|
op = TkReading2Token[op] unless op.kind_of?(Symbol)
|
||||||
|
@op = op
|
||||||
|
end
|
||||||
|
attr :op
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkUnknownChar < Token
|
||||||
|
def initialize(seek, line_no, char_no, id)
|
||||||
|
super(seek, line_no, char_no)
|
||||||
|
@name = name
|
||||||
|
end
|
||||||
|
attr :name
|
||||||
|
end
|
||||||
|
|
||||||
|
class TkError < Token
|
||||||
|
end
|
||||||
|
|
||||||
|
def Token(token, value = nil)
|
||||||
|
case token
|
||||||
|
when String
|
||||||
|
if (tk = TkReading2Token[token]).nil?
|
||||||
|
IRB.fail TkReading2TokenNoKey, token
|
||||||
|
end
|
||||||
|
tk = Token(tk[0], value)
|
||||||
|
if tk.kind_of?(TkOp)
|
||||||
|
tk.name = token
|
||||||
|
end
|
||||||
|
return tk
|
||||||
|
when Symbol
|
||||||
|
if (tk = TkSymbol2Token[token]).nil?
|
||||||
|
IRB.fail TkSymbol2TokenNoKey, token
|
||||||
|
end
|
||||||
|
return Token(tk[0], value)
|
||||||
|
else
|
||||||
|
if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
|
||||||
|
token.new(@prev_seek, @prev_line_no, @prev_char_no)
|
||||||
|
else
|
||||||
|
token.new(@prev_seek, @prev_line_no, @prev_char_no, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
TokenDefinitions = [
|
||||||
|
[:TkCLASS, TkId, "class", EXPR_CLASS],
|
||||||
|
[:TkMODULE, TkId, "module", EXPR_BEG],
|
||||||
|
[:TkDEF, TkId, "def", EXPR_FNAME],
|
||||||
|
[:TkUNDEF, TkId, "undef", EXPR_FNAME],
|
||||||
|
[:TkBEGIN, TkId, "begin", EXPR_BEG],
|
||||||
|
[:TkRESCUE, TkId, "rescue", EXPR_MID],
|
||||||
|
[:TkENSURE, TkId, "ensure", EXPR_BEG],
|
||||||
|
[:TkEND, TkId, "end", EXPR_END],
|
||||||
|
[:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD],
|
||||||
|
[:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD],
|
||||||
|
[:TkTHEN, TkId, "then", EXPR_BEG],
|
||||||
|
[:TkELSIF, TkId, "elsif", EXPR_BEG],
|
||||||
|
[:TkELSE, TkId, "else", EXPR_BEG],
|
||||||
|
[:TkCASE, TkId, "case", EXPR_BEG],
|
||||||
|
[:TkWHEN, TkId, "when", EXPR_BEG],
|
||||||
|
[:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD],
|
||||||
|
[:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD],
|
||||||
|
[:TkFOR, TkId, "for", EXPR_BEG],
|
||||||
|
[:TkBREAK, TkId, "break", EXPR_END],
|
||||||
|
[:TkNEXT, TkId, "next", EXPR_END],
|
||||||
|
[:TkREDO, TkId, "redo", EXPR_END],
|
||||||
|
[:TkRETRY, TkId, "retry", EXPR_END],
|
||||||
|
[:TkIN, TkId, "in", EXPR_BEG],
|
||||||
|
[:TkDO, TkId, "do", EXPR_BEG],
|
||||||
|
[:TkRETURN, TkId, "return", EXPR_MID],
|
||||||
|
[:TkYIELD, TkId, "yield", EXPR_END],
|
||||||
|
[:TkSUPER, TkId, "super", EXPR_END],
|
||||||
|
[:TkSELF, TkId, "self", EXPR_END],
|
||||||
|
[:TkNIL, TkId, "nil", EXPR_END],
|
||||||
|
[:TkTRUE, TkId, "true", EXPR_END],
|
||||||
|
[:TkFALSE, TkId, "false", EXPR_END],
|
||||||
|
[:TkAND, TkId, "and", EXPR_BEG],
|
||||||
|
[:TkOR, TkId, "or", EXPR_BEG],
|
||||||
|
[:TkNOT, TkId, "not", EXPR_BEG],
|
||||||
|
[:TkIF_MOD, TkId],
|
||||||
|
[:TkUNLESS_MOD, TkId],
|
||||||
|
[:TkWHILE_MOD, TkId],
|
||||||
|
[:TkUNTIL_MOD, TkId],
|
||||||
|
[:TkALIAS, TkId, "alias", EXPR_FNAME],
|
||||||
|
[:TkDEFINED, TkId, "defined?", EXPR_END],
|
||||||
|
[:TklBEGIN, TkId, "BEGIN", EXPR_END],
|
||||||
|
[:TklEND, TkId, "END", EXPR_END],
|
||||||
|
[:Tk__LINE__, TkId, "__LINE__", EXPR_END],
|
||||||
|
[:Tk__FILE__, TkId, "__FILE__", EXPR_END],
|
||||||
|
|
||||||
|
[:TkIDENTIFIER, TkId],
|
||||||
|
[:TkFID, TkId],
|
||||||
|
[:TkGVAR, TkId],
|
||||||
|
[:TkIVAR, TkId],
|
||||||
|
[:TkCONSTANT, TkId],
|
||||||
|
|
||||||
|
[:TkINTEGER, TkVal],
|
||||||
|
[:TkFLOAT, TkVal],
|
||||||
|
[:TkSTRING, TkVal],
|
||||||
|
[:TkXSTRING, TkVal],
|
||||||
|
[:TkREGEXP, TkVal],
|
||||||
|
|
||||||
|
[:TkDSTRING, TkNode],
|
||||||
|
[:TkDXSTRING, TkNode],
|
||||||
|
[:TkDREGEXP, TkNode],
|
||||||
|
[:TkNTH_REF, TkNode],
|
||||||
|
[:TkBACK_REF, TkNode],
|
||||||
|
|
||||||
|
[:TkUPLUS, TkOp, "+@"],
|
||||||
|
[:TkUMINUS, TkOp, "-@"],
|
||||||
|
[:TkPOW, TkOp, "**"],
|
||||||
|
[:TkCMP, TkOp, "<=>"],
|
||||||
|
[:TkEQ, TkOp, "=="],
|
||||||
|
[:TkEQQ, TkOp, "==="],
|
||||||
|
[:TkNEQ, TkOp, "!="],
|
||||||
|
[:TkGEQ, TkOp, ">="],
|
||||||
|
[:TkLEQ, TkOp, "<="],
|
||||||
|
[:TkANDOP, TkOp, "&&"],
|
||||||
|
[:TkOROP, TkOp, "||"],
|
||||||
|
[:TkMATCH, TkOp, "=~"],
|
||||||
|
[:TkNMATCH, TkOp, "!~"],
|
||||||
|
[:TkDOT2, TkOp, ".."],
|
||||||
|
[:TkDOT3, TkOp, "..."],
|
||||||
|
[:TkAREF, TkOp, "[]"],
|
||||||
|
[:TkASET, TkOp, "[]="],
|
||||||
|
[:TkLSHFT, TkOp, "<<"],
|
||||||
|
[:TkRSHFT, TkOp, ">>"],
|
||||||
|
[:TkCOLON2, TkOp],
|
||||||
|
[:TkCOLON3, TkOp],
|
||||||
|
# [:OPASGN, TkOp], # +=, -= etc. #
|
||||||
|
[:TkASSOC, TkOp, "=>"],
|
||||||
|
[:TkQUESTION, TkOp, "?"], #?
|
||||||
|
[:TkCOLON, TkOp, ":"], #:
|
||||||
|
|
||||||
|
[:TkfLPAREN], # func( #
|
||||||
|
[:TkfLBRACK], # func[ #
|
||||||
|
[:TkfLBRACE], # func{ #
|
||||||
|
[:TkSTAR], # *arg
|
||||||
|
[:TkAMPER], # &arg #
|
||||||
|
[:TkSYMBEG], # :SYMBOL
|
||||||
|
|
||||||
|
[:TkGT, TkOp, ">"],
|
||||||
|
[:TkLT, TkOp, "<"],
|
||||||
|
[:TkPLUS, TkOp, "+"],
|
||||||
|
[:TkMINUS, TkOp, "-"],
|
||||||
|
[:TkMULT, TkOp, "*"],
|
||||||
|
[:TkDIV, TkOp, "/"],
|
||||||
|
[:TkMOD, TkOp, "%"],
|
||||||
|
[:TkBITOR, TkOp, "|"],
|
||||||
|
[:TkBITXOR, TkOp, "^"],
|
||||||
|
[:TkBITAND, TkOp, "&"],
|
||||||
|
[:TkBITNOT, TkOp, "~"],
|
||||||
|
[:TkNOTOP, TkOp, "!"],
|
||||||
|
|
||||||
|
[:TkBACKQUOTE, TkOp, "`"],
|
||||||
|
|
||||||
|
[:TkASSGIN, Token, "="],
|
||||||
|
[:TkDOT, Token, "."],
|
||||||
|
[:TkLPAREN, Token, "("], #(exp)
|
||||||
|
[:TkLBRACK, Token, "["], #[arry]
|
||||||
|
[:TkLBRACE, Token, "{"], #{hash}
|
||||||
|
[:TkRPAREN, Token, ")"],
|
||||||
|
[:TkRBRACK, Token, "]"],
|
||||||
|
[:TkRBRACE, Token, "}"],
|
||||||
|
[:TkCOMMA, Token, ","],
|
||||||
|
[:TkSEMICOLON, Token, ";"],
|
||||||
|
|
||||||
|
[:TkCOMMENT],
|
||||||
|
[:TkRD_COMMENT],
|
||||||
|
[:TkSPACE],
|
||||||
|
[:TkNL],
|
||||||
|
[:TkEND_OF_SCRIPT],
|
||||||
|
|
||||||
|
[:TkBACKSLASH, TkUnknownChar, "\\"],
|
||||||
|
[:TkAT, TkUnknownChar, "@"],
|
||||||
|
[:TkDOLLAR, TkUnknownChar, "$"],
|
||||||
|
]
|
||||||
|
|
||||||
|
# {reading => token_class}
|
||||||
|
# {reading => [token_class, *opt]}
|
||||||
|
TkReading2Token = {}
|
||||||
|
TkSymbol2Token = {}
|
||||||
|
|
||||||
|
def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
|
||||||
|
token_n = token_n.id2name unless token_n.kind_of?(String)
|
||||||
|
if RubyToken.const_defined?(token_n)
|
||||||
|
IRB.fail AlreadyDefinedToken, token_n
|
||||||
|
end
|
||||||
|
token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
|
||||||
|
|
||||||
|
if reading
|
||||||
|
if TkReading2Token[reading]
|
||||||
|
IRB.fail TkReading2TokenDuplicateError, token_n, reading
|
||||||
|
end
|
||||||
|
if opts.empty?
|
||||||
|
TkReading2Token[reading] = [token_c]
|
||||||
|
else
|
||||||
|
TkReading2Token[reading] = [token_c].concat(opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
TkSymbol2Token[token_n.intern] = token_c
|
||||||
|
end
|
||||||
|
|
||||||
|
for defs in TokenDefinitions
|
||||||
|
def_token(*defs)
|
||||||
|
end
|
||||||
|
end
|
279
lib/irb/slex.rb
Normal file
279
lib/irb/slex.rb
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
#
|
||||||
|
# irb-slex.rb - symple lex analizer
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
require "e2mmap"
|
||||||
|
|
||||||
|
class SLex
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
extend Exception2MessageMapper
|
||||||
|
def_exception :ErrNodeNothing, "node nothing"
|
||||||
|
def_exception :ErrNodeAlreadyExists, "node already exists"
|
||||||
|
|
||||||
|
class << self
|
||||||
|
attr :debug_level, TRUE
|
||||||
|
def debug?
|
||||||
|
debug_level > 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@debug_level = 0
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@head = Node.new("")
|
||||||
|
end
|
||||||
|
|
||||||
|
def def_rule(token, preproc = nil, postproc = nil)
|
||||||
|
# print node.inspect, "\n" if SLex.debug?
|
||||||
|
postproc = proc if iterator?
|
||||||
|
node = create(token, preproc, postproc)
|
||||||
|
end
|
||||||
|
|
||||||
|
def def_rules(*tokens)
|
||||||
|
if iterator?
|
||||||
|
p = proc
|
||||||
|
end
|
||||||
|
for token in tokens
|
||||||
|
def_rule(token, nil, p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def preporc(token, proc)
|
||||||
|
node = search(token)
|
||||||
|
node.preproc=proc
|
||||||
|
end
|
||||||
|
|
||||||
|
def postproc(token)
|
||||||
|
node = search(token, proc)
|
||||||
|
node.postproc=proc
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(token)
|
||||||
|
@head.search(token.split(//))
|
||||||
|
end
|
||||||
|
|
||||||
|
def create(token, preproc = nil, postproc = nil)
|
||||||
|
@head.create_subnode(token.split(//), preproc, postproc)
|
||||||
|
end
|
||||||
|
|
||||||
|
def match(token)
|
||||||
|
case token
|
||||||
|
when Array
|
||||||
|
when String
|
||||||
|
token = token.split(//)
|
||||||
|
match(token.split(//))
|
||||||
|
else
|
||||||
|
return @head.match_io(token)
|
||||||
|
end
|
||||||
|
ret = @head.match(token)
|
||||||
|
printf "match end: %s:%s", ret, token.inspect if SLex.debug?
|
||||||
|
ret
|
||||||
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
format("<SLex: @head = %s>", @head.inspect)
|
||||||
|
end
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# class Node -
|
||||||
|
#
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
class Node
|
||||||
|
# if postproc no exist, this node is abstract node.
|
||||||
|
# if postproc isn't nil, this node is real node.
|
||||||
|
def initialize(preproc = nil, postproc = nil)
|
||||||
|
@Tree = {}
|
||||||
|
@preproc = preproc
|
||||||
|
@postproc = postproc
|
||||||
|
end
|
||||||
|
|
||||||
|
attr :preproc, TRUE
|
||||||
|
attr :postproc, TRUE
|
||||||
|
|
||||||
|
def search(chrs, opt = nil)
|
||||||
|
return self if chrs.empty?
|
||||||
|
ch = chrs.shift
|
||||||
|
if node = @Tree[ch]
|
||||||
|
node.search(chrs, opt)
|
||||||
|
else
|
||||||
|
if opt
|
||||||
|
chrs.unshift ch
|
||||||
|
self.create_subnode(chrs)
|
||||||
|
else
|
||||||
|
SLex.fail ErrNodeNothing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_subnode(chrs, preproc = nil, postproc = nil)
|
||||||
|
if chrs.empty?
|
||||||
|
if @postproc
|
||||||
|
p node
|
||||||
|
SLex.fail ErrNodeAlreadyExists
|
||||||
|
else
|
||||||
|
print "Warn: change abstruct node to real node\n" if SLex.debug?
|
||||||
|
@preproc = preproc
|
||||||
|
@postproc = postproc
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
ch = chrs.shift
|
||||||
|
if node = @Tree[ch]
|
||||||
|
if chrs.empty?
|
||||||
|
if node.postproc
|
||||||
|
p node
|
||||||
|
p self
|
||||||
|
p ch
|
||||||
|
p chrs
|
||||||
|
SLex.fail ErrNodeAlreadyExists
|
||||||
|
else
|
||||||
|
print "Warn: change abstruct node to real node\n" if SLex.debug?
|
||||||
|
node.preproc = preproc
|
||||||
|
node.postproc = postproc
|
||||||
|
end
|
||||||
|
else
|
||||||
|
node.create_subnode(chrs, preproc, postproc)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if chrs.empty?
|
||||||
|
node = Node.new(preproc, postproc)
|
||||||
|
else
|
||||||
|
node = Node.new
|
||||||
|
node.create_subnode(chrs, preproc, postproc)
|
||||||
|
end
|
||||||
|
@Tree[ch] = node
|
||||||
|
end
|
||||||
|
node
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# chrs: String
|
||||||
|
# character array
|
||||||
|
# io It must have getc()/ungetc(), and ungetc() can be
|
||||||
|
# called any number of times.
|
||||||
|
#
|
||||||
|
def match(chrs, op = "")
|
||||||
|
print "match>: ", chrs, "op:", op, "\n" if SLex.debug?
|
||||||
|
if chrs.empty?
|
||||||
|
if @preproc.nil? || @preproc.call(op, chrs)
|
||||||
|
printf "op1: %s\n", op if SLex.debug?
|
||||||
|
@postproc.call(op, chrs)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ch = chrs.shift
|
||||||
|
if node = @Tree[ch]
|
||||||
|
if ret = node.match(chrs, op+ch)
|
||||||
|
return ret
|
||||||
|
else
|
||||||
|
chrs.unshift ch
|
||||||
|
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
|
||||||
|
printf "op2: %s\n", op.inspect if SLex.debug?
|
||||||
|
ret = @postproc.call(op, chrs)
|
||||||
|
return ret
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
chrs.unshift ch
|
||||||
|
if @postproc and @preproc.nil? || @preproc.call(op, chrs)
|
||||||
|
printf "op3: %s\n", op if SLex.debug?
|
||||||
|
@postproc.call(op, chrs)
|
||||||
|
return ""
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def match_io(io, op = "")
|
||||||
|
if op == ""
|
||||||
|
ch = io.getc
|
||||||
|
if ch == nil
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ch = io.getc_of_rests
|
||||||
|
end
|
||||||
|
if ch.nil?
|
||||||
|
if @preproc.nil? || @preproc.call(op, io)
|
||||||
|
printf "op1: %s\n", op if SLex.debug?
|
||||||
|
@postproc.call(op, io)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if node = @Tree[ch]
|
||||||
|
if ret = node.match_io(io, op+ch)
|
||||||
|
ret
|
||||||
|
else
|
||||||
|
io.ungetc ch
|
||||||
|
if @postproc and @preproc.nil? || @preproc.call(op, io)
|
||||||
|
printf "op2: %s\n", op.inspect if SLex.debug?
|
||||||
|
@postproc.call(op, io)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
io.ungetc ch
|
||||||
|
if @postproc and @preproc.nil? || @preproc.call(op, io)
|
||||||
|
printf "op3: %s\n", op if SLex.debug?
|
||||||
|
@postproc.call(op, io)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if $0 == __FILE__
|
||||||
|
# Tracer.on
|
||||||
|
case $1
|
||||||
|
when "1"
|
||||||
|
tr = SLex.new
|
||||||
|
print "0: ", tr.inspect, "\n"
|
||||||
|
tr.def_rule("=") {print "=\n"}
|
||||||
|
print "1: ", tr.inspect, "\n"
|
||||||
|
tr.def_rule("==") {print "==\n"}
|
||||||
|
print "2: ", tr.inspect, "\n"
|
||||||
|
|
||||||
|
print "case 1:\n"
|
||||||
|
print tr.match("="), "\n"
|
||||||
|
print "case 2:\n"
|
||||||
|
print tr.match("=="), "\n"
|
||||||
|
print "case 3:\n"
|
||||||
|
print tr.match("=>"), "\n"
|
||||||
|
|
||||||
|
when "2"
|
||||||
|
tr = SLex.new
|
||||||
|
print "0: ", tr.inspect, "\n"
|
||||||
|
tr.def_rule("=") {print "=\n"}
|
||||||
|
print "1: ", tr.inspect, "\n"
|
||||||
|
tr.def_rule("==", proc{FALSE}) {print "==\n"}
|
||||||
|
print "2: ", tr.inspect, "\n"
|
||||||
|
|
||||||
|
print "case 1:\n"
|
||||||
|
print tr.match("="), "\n"
|
||||||
|
print "case 2:\n"
|
||||||
|
print tr.match("=="), "\n"
|
||||||
|
print "case 3:\n"
|
||||||
|
print tr.match("=>"), "\n"
|
||||||
|
end
|
||||||
|
exit
|
||||||
|
end
|
16
lib/irb/version.rb
Normal file
16
lib/irb/version.rb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#
|
||||||
|
# version.rb - irb version definition file
|
||||||
|
# $Release Version: 0.6.1$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
@RELEASE_VERSION = "0.6.1"
|
||||||
|
@LAST_UPDATE_DATE = "99/09/16"
|
||||||
|
end
|
15
lib/irb/workspace-binding-2.rb
Normal file
15
lib/irb/workspace-binding-2.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#
|
||||||
|
# bind.rb -
|
||||||
|
# $Release Version: $
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
while true
|
||||||
|
IRB::BINDING_QUEUE.push b = binding
|
||||||
|
end
|
77
lib/irb/workspace-binding.rb
Normal file
77
lib/irb/workspace-binding.rb
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#
|
||||||
|
# workspace-binding.rb -
|
||||||
|
# $Release Version: $
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
module IRB
|
||||||
|
# create new workspace.
|
||||||
|
def IRB.workspace_binding(*main)
|
||||||
|
if @CONF[:SINGLE_IRB]
|
||||||
|
bind = TOPLEVEL_BINDING
|
||||||
|
else
|
||||||
|
case @CONF[:CONTEXT_MODE]
|
||||||
|
when 0
|
||||||
|
bind = eval("proc{binding}.call",
|
||||||
|
TOPLEVEL_BINDING,
|
||||||
|
"(irb_local_binding)",
|
||||||
|
1)
|
||||||
|
when 1
|
||||||
|
require "tempfile"
|
||||||
|
f = Tempfile.open("irb-binding")
|
||||||
|
f.print <<EOF
|
||||||
|
$binding = binding
|
||||||
|
EOF
|
||||||
|
f.close
|
||||||
|
load f.path
|
||||||
|
bind = $binding
|
||||||
|
|
||||||
|
when 2
|
||||||
|
unless defined? BINDING_QUEUE
|
||||||
|
require "thread"
|
||||||
|
|
||||||
|
IRB.const_set("BINDING_QUEUE", SizedQueue.new(1))
|
||||||
|
Thread.abort_on_exception = true
|
||||||
|
Thread.start do
|
||||||
|
eval "require \"irb/workspace-binding-2\"", TOPLEVEL_BINDING, __FILE__, __LINE__
|
||||||
|
end
|
||||||
|
Thread.pass
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
bind = BINDING_QUEUE.pop
|
||||||
|
|
||||||
|
when 3
|
||||||
|
bind = eval("def irb_binding; binding; end; irb_binding",
|
||||||
|
TOPLEVEL_BINDING,
|
||||||
|
__FILE__,
|
||||||
|
__LINE__ - 3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
unless main.empty?
|
||||||
|
@CONF[:__MAIN__] = main[0]
|
||||||
|
case main[0]
|
||||||
|
when Module
|
||||||
|
bind = eval("IRB.conf[:__MAIN__].module_eval('binding')", bind)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
bind = eval("IRB.conf[:__MAIN__].instance_eval('binding')", bind)
|
||||||
|
rescue TypeError
|
||||||
|
IRB.fail CanNotChangeBinding, main[0].inspect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
eval("_=nil", bind)
|
||||||
|
bind
|
||||||
|
end
|
||||||
|
|
||||||
|
def IRB.delete_caller
|
||||||
|
end
|
||||||
|
end
|
84
lib/irb/xmp.rb
Normal file
84
lib/irb/xmp.rb
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#
|
||||||
|
# xmp.rb - irb version of gotoken xmp
|
||||||
|
# $Release Version: 0.6$
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
require "irb/irb"
|
||||||
|
require "irb/frame"
|
||||||
|
|
||||||
|
class XMP
|
||||||
|
@RCS_ID='-$Id$-'
|
||||||
|
|
||||||
|
def initialize(bind = nil)
|
||||||
|
#IRB.parse_opts
|
||||||
|
#IRB.load_modules
|
||||||
|
|
||||||
|
bind = IRB::Frame.top(1) unless bind
|
||||||
|
main = eval("self", bind)
|
||||||
|
@io = StringInputMethod.new
|
||||||
|
@irb = IRB::Irb.new(main, bind, @io)
|
||||||
|
@irb.context.prompt_mode = :XMP
|
||||||
|
@irb.context.ignore_sigint = false
|
||||||
|
|
||||||
|
# IRB.conf[:IRB_RC].call(@irb.context) if IRB.conf[:IRB_RC]
|
||||||
|
IRB.conf[:MAIN_CONTEXT] = @irb.context
|
||||||
|
end
|
||||||
|
|
||||||
|
def puts(exps)
|
||||||
|
@io.puts exps
|
||||||
|
|
||||||
|
if @irb.context.ignore_sigint
|
||||||
|
begin
|
||||||
|
trap_proc_b = trap("SIGINT"){@irb.signal_handle}
|
||||||
|
catch(:IRB_EXIT) do
|
||||||
|
@irb.eval_input
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
trap("SIGINT", trap_proc_b)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
catch(:IRB_EXIT) do
|
||||||
|
@irb.eval_input
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class StringInputMethod < IRB::InputMethod
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
@exps = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def eof?
|
||||||
|
@exps.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def gets
|
||||||
|
while l = @exps.shift
|
||||||
|
next if /^\s+$/ =~ l
|
||||||
|
l.concat "\n"
|
||||||
|
print @prompt, l
|
||||||
|
break
|
||||||
|
end
|
||||||
|
l
|
||||||
|
end
|
||||||
|
|
||||||
|
def puts(exps)
|
||||||
|
@exps.concat exps.split(/\n/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def xmp(exps, bind = nil)
|
||||||
|
bind = IRB::Frame.top(1) unless bind
|
||||||
|
xmp = XMP.new(bind)
|
||||||
|
xmp.puts exps
|
||||||
|
xmp
|
||||||
|
end
|
@ -420,7 +420,6 @@ class Matrix
|
|||||||
vij = 0
|
vij = 0
|
||||||
0.upto(column_size - 1) do
|
0.upto(column_size - 1) do
|
||||||
|k|
|
|k|
|
||||||
p [k,j,m[k,j]]
|
|
||||||
vij += self[i, k] * m[k, j]
|
vij += self[i, k] * m[k, j]
|
||||||
end
|
end
|
||||||
vij
|
vij
|
||||||
|
@ -157,9 +157,11 @@ class Queue
|
|||||||
t.wakeup if t
|
t.wakeup if t
|
||||||
rescue ThreadError
|
rescue ThreadError
|
||||||
retry
|
retry
|
||||||
end
|
ensure
|
||||||
Thread.critical = false
|
Thread.critical = false
|
||||||
end
|
end
|
||||||
|
t.run if t
|
||||||
|
end
|
||||||
alias enq push
|
alias enq push
|
||||||
|
|
||||||
def pop non_block=false
|
def pop non_block=false
|
||||||
@ -250,10 +252,13 @@ class SizedQueue<Queue
|
|||||||
if @que.length < @max
|
if @que.length < @max
|
||||||
begin
|
begin
|
||||||
t = @queue_wait.shift
|
t = @queue_wait.shift
|
||||||
t.run if t
|
t.wakeup if t
|
||||||
rescue ThreadError
|
rescue ThreadError
|
||||||
retry
|
retry
|
||||||
|
ensure
|
||||||
|
Thread.critical = false
|
||||||
end
|
end
|
||||||
|
t.run if t
|
||||||
end
|
end
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
@ -208,8 +208,6 @@ w_ivar(tbl, arg)
|
|||||||
st_table *tbl;
|
st_table *tbl;
|
||||||
struct dump_call_arg *arg;
|
struct dump_call_arg *arg;
|
||||||
{
|
{
|
||||||
struct dump_call_arg c_arg;
|
|
||||||
|
|
||||||
if (tbl) {
|
if (tbl) {
|
||||||
w_long(tbl->num_entries, arg->arg);
|
w_long(tbl->num_entries, arg->arg);
|
||||||
st_foreach(tbl, obj_each, arg);
|
st_foreach(tbl, obj_each, arg);
|
||||||
|
78
pack.c
78
pack.c
@ -843,6 +843,53 @@ pack_pack(ary, fmt)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
while (len-- > 0) {
|
||||||
|
unsigned long ul;
|
||||||
|
VALUE buf = rb_str_new(0, 0);
|
||||||
|
char c, *bufs, *bufe;
|
||||||
|
|
||||||
|
from = NEXTFROM;
|
||||||
|
|
||||||
|
if (TYPE(from) == T_BIGNUM) {
|
||||||
|
VALUE big128 = rb_uint2big(128);
|
||||||
|
while (TYPE(from) == T_BIGNUM) {
|
||||||
|
from = rb_big_divmod(from, big128);
|
||||||
|
c = NUM2INT(RARRAY(from)->ptr[1]) | 0x80; /* mod */
|
||||||
|
rb_str_cat(buf, &c, sizeof(char));
|
||||||
|
from = RARRAY(from)->ptr[0]; /* div */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NIL_P(from)) ul = 0;
|
||||||
|
else {
|
||||||
|
ul = NUM2ULONG(from);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ul) {
|
||||||
|
c = ((ul & 0x7f) | 0x80);
|
||||||
|
rb_str_cat(buf, &c, sizeof(char));
|
||||||
|
ul >>= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RSTRING(buf)->len) {
|
||||||
|
bufs = RSTRING(buf)->ptr;
|
||||||
|
bufe = bufs + RSTRING(buf)->len - 1;
|
||||||
|
*bufs &= 0x7f; /* clear continue bit */
|
||||||
|
while (bufs < bufe) { /* reverse */
|
||||||
|
c = *bufs;
|
||||||
|
*bufs++ = *bufe;
|
||||||
|
*bufe-- = c;
|
||||||
|
}
|
||||||
|
rb_str_cat(res, RSTRING(buf)->ptr, RSTRING(buf)->len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c = 0;
|
||||||
|
rb_str_cat(res, &c, sizeof(char));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1573,6 +1620,37 @@ pack_unpack(str, fmt)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
{
|
||||||
|
unsigned long ul = 0;
|
||||||
|
unsigned long ulmask = 0xfe << ((sizeof(unsigned long) - 1) * 8);
|
||||||
|
|
||||||
|
while (len > 0 && s < send) {
|
||||||
|
ul <<= 7;
|
||||||
|
ul |= (*s & 0x7f);
|
||||||
|
if (!(*s++ & 0x80)) {
|
||||||
|
rb_ary_push(ary, rb_uint2inum(ul));
|
||||||
|
len--;
|
||||||
|
ul = 0;
|
||||||
|
}
|
||||||
|
else if (ul & ulmask) {
|
||||||
|
VALUE big = rb_uint2big(ul);
|
||||||
|
VALUE big128 = rb_uint2big(128);
|
||||||
|
while (s < send) {
|
||||||
|
big = rb_big_mul(big, big128);
|
||||||
|
big = rb_big_plus(big, rb_uint2big(*s & 0x7f));
|
||||||
|
if (!(*s++ & 0x80)) {
|
||||||
|
rb_ary_push(ary, big);
|
||||||
|
len--;
|
||||||
|
ul = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
137
parse.y
137
parse.y
@ -2124,6 +2124,84 @@ read_escape()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tokadd_escape()
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
switch (c = nextc()) {
|
||||||
|
case '\n':
|
||||||
|
return 0; /* just ignore */
|
||||||
|
|
||||||
|
case '0': case '1': case '2': case '3': /* octal constant */
|
||||||
|
case '4': case '5': case '6': case '7':
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tokadd('\\');
|
||||||
|
tokadd(c);
|
||||||
|
for (i=0; i<2; i++) {
|
||||||
|
c = nextc();
|
||||||
|
if (c == -1) goto eof;
|
||||||
|
if (c < '0' || '7' < c) {
|
||||||
|
pushback(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tokadd(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'x': /* hex constant */
|
||||||
|
{
|
||||||
|
int numlen;
|
||||||
|
|
||||||
|
scan_hex(lex_p, 2, &numlen);
|
||||||
|
while (numlen--)
|
||||||
|
tokadd(nextc());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
if ((c = nextc()) != '-') {
|
||||||
|
yyerror("Invalid escape character syntax");
|
||||||
|
pushback(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tokadd('\\'); tokadd('M'); tokadd('-');
|
||||||
|
goto escaped;
|
||||||
|
|
||||||
|
case 'C':
|
||||||
|
if ((c = nextc()) != '-') {
|
||||||
|
yyerror("Invalid escape character syntax");
|
||||||
|
pushback(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tokadd('\\'); tokadd('C'); tokadd('-');
|
||||||
|
goto escaped;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
tokadd('\\'); tokadd('c');
|
||||||
|
escaped:
|
||||||
|
if ((c = nextc()) == '\\') {
|
||||||
|
return tokadd_escape();
|
||||||
|
}
|
||||||
|
else if (c == -1) goto eof;
|
||||||
|
tokadd(c);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
eof:
|
||||||
|
case -1:
|
||||||
|
yyerror("Invalid escape character syntax");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
tokadd('\\');
|
||||||
|
tokadd(c);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_regx(term, paren)
|
parse_regx(term, paren)
|
||||||
int term, paren;
|
int term, paren;
|
||||||
@ -2133,78 +2211,31 @@ parse_regx(term, paren)
|
|||||||
int once = 0;
|
int once = 0;
|
||||||
int nest = 0;
|
int nest = 0;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
int in_brack = 0;
|
|
||||||
int re_start = ruby_sourceline;
|
int re_start = ruby_sourceline;
|
||||||
NODE *list = 0;
|
NODE *list = 0;
|
||||||
|
|
||||||
newtok();
|
newtok();
|
||||||
while ((c = nextc()) != -1) {
|
while ((c = nextc()) != -1) {
|
||||||
if (!in_brack && c == term && nest == 0) {
|
if (c == term && nest == 0) {
|
||||||
goto regx_end;
|
goto regx_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '[':
|
|
||||||
in_brack = 1;
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
in_brack = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
list = str_extend(list, term);
|
list = str_extend(list, term);
|
||||||
if (list == (NODE*)-1) return 0;
|
if (list == (NODE*)-1) return 0;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '\\':
|
case '\\':
|
||||||
switch (c = nextc()) {
|
if (tokadd_escape() < 0)
|
||||||
case -1:
|
|
||||||
ruby_sourceline = re_start;
|
|
||||||
rb_compile_error("unterminated regexp meets end of file");
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case '\n':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
case '^':
|
|
||||||
case 's':
|
|
||||||
tokadd('\\');
|
|
||||||
tokadd(c);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '1': case '2': case '3':
|
|
||||||
case '4': case '5': case '6':
|
|
||||||
case '7': case '8': case '9':
|
|
||||||
case '0': case 'x':
|
|
||||||
tokadd('\\');
|
|
||||||
tokadd(c);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'b':
|
|
||||||
if (!in_brack) {
|
|
||||||
tokadd('\\');
|
|
||||||
tokadd('b');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* fall through */
|
|
||||||
default:
|
|
||||||
if (c == term) {
|
|
||||||
tokadd(c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tokadd('\\');
|
|
||||||
tokadd(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
rb_compile_error("unterminated regexp");
|
goto unterminated;
|
||||||
return 0;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (paren && !in_brack) {
|
if (paren) {
|
||||||
if (c == paren) nest++;
|
if (c == paren) nest++;
|
||||||
if (c == term) nest--;
|
if (c == term) nest--;
|
||||||
}
|
}
|
||||||
@ -2272,7 +2303,9 @@ parse_regx(term, paren)
|
|||||||
}
|
}
|
||||||
tokadd(c);
|
tokadd(c);
|
||||||
}
|
}
|
||||||
rb_compile_error("unterminated regexp");
|
unterminated:
|
||||||
|
ruby_sourceline = re_start;
|
||||||
|
rb_compile_error("unterminated regexp meets end of file");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
regex.c
41
regex.c
@ -22,13 +22,11 @@
|
|||||||
/* UTF-8 extension added Jan 16 1999 by Yoshida Masato <yoshidam@tau.bekkoame.ne.jp> */
|
/* UTF-8 extension added Jan 16 1999 by Yoshida Masato <yoshidam@tau.bekkoame.ne.jp> */
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#ifdef RUBY_PLATFORM
|
|
||||||
# define RUBY
|
#ifdef HAVE_STRING_H
|
||||||
extern int rb_prohibit_interrupt;
|
# include <string.h>
|
||||||
extern int rb_trap_pending;
|
#else
|
||||||
# define CHECK_INTS if (!rb_prohibit_interrupt) {\
|
# include <strings.h>
|
||||||
if (rb_trap_pending) rb_trap_exec();\
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We write fatal error messages on standard error. */
|
/* We write fatal error messages on standard error. */
|
||||||
@ -63,6 +61,17 @@ extern int rb_trap_pending;
|
|||||||
# define _(args) ()
|
# define _(args) ()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef RUBY_PLATFORM
|
||||||
|
# define RUBY
|
||||||
|
extern int rb_prohibit_interrupt;
|
||||||
|
extern int rb_trap_pending;
|
||||||
|
void rb_trap_exec _((void));
|
||||||
|
|
||||||
|
# define CHECK_INTS if (!rb_prohibit_interrupt) {\
|
||||||
|
if (rb_trap_pending) rb_trap_exec();\
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef xmalloc
|
#ifndef xmalloc
|
||||||
void *xmalloc _((size_t));
|
void *xmalloc _((size_t));
|
||||||
void *xcalloc _((size_t,size_t));
|
void *xcalloc _((size_t,size_t));
|
||||||
@ -70,7 +79,7 @@ void *xrealloc _((void*,size_t));
|
|||||||
void free _((void*));
|
void free _((void*));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NO_ALLOCA /* /* try it out for now */
|
#define NO_ALLOCA /* try it out for now */
|
||||||
#ifndef NO_ALLOCA
|
#ifndef NO_ALLOCA
|
||||||
/* Make alloca work the best possible way. */
|
/* Make alloca work the best possible way. */
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -474,7 +483,7 @@ utf8_firstbyte(c)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
print_mbc(c)
|
print_mbc(c)
|
||||||
unsigned long c;
|
unsigned int c;
|
||||||
{
|
{
|
||||||
if (current_mbctype == MBCTYPE_UTF8) {
|
if (current_mbctype == MBCTYPE_UTF8) {
|
||||||
if (c < 0x80)
|
if (c < 0x80)
|
||||||
@ -587,13 +596,13 @@ print_mbc(c)
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EXTRACT_MBC(p) \
|
#define EXTRACT_MBC(p) \
|
||||||
((unsigned long)((unsigned char)(p)[0] << 24 | \
|
((unsigned int)((unsigned char)(p)[0] << 24 | \
|
||||||
(unsigned char)(p)[1] << 16 | \
|
(unsigned char)(p)[1] << 16 | \
|
||||||
(unsigned char)(p)[2] << 8 | \
|
(unsigned char)(p)[2] << 8 | \
|
||||||
(unsigned char)(p)[3]))
|
(unsigned char)(p)[3]))
|
||||||
|
|
||||||
#define EXTRACT_MBC_AND_INCR(p) \
|
#define EXTRACT_MBC_AND_INCR(p) \
|
||||||
((unsigned long)((p) += 4, \
|
((unsigned int)((p) += 4, \
|
||||||
(unsigned char)(p)[-4] << 24 | \
|
(unsigned char)(p)[-4] << 24 | \
|
||||||
(unsigned char)(p)[-3] << 16 | \
|
(unsigned char)(p)[-3] << 16 | \
|
||||||
(unsigned char)(p)[-2] << 8 | \
|
(unsigned char)(p)[-2] << 8 | \
|
||||||
@ -1398,12 +1407,6 @@ re_compile_pattern(pattern, size, bufp)
|
|||||||
had_num_literal = 0;
|
had_num_literal = 0;
|
||||||
had_char_class = 0;
|
had_char_class = 0;
|
||||||
|
|
||||||
/* charset_not matches newline according to a syntax bit. */
|
|
||||||
if ((enum regexpcode)b[-2] == charset_not) {
|
|
||||||
if (bufp->options & RE_OPTION_POSIXLINE)
|
|
||||||
SET_LIST_BIT ('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read in characters and ranges, setting map bits. */
|
/* Read in characters and ranges, setting map bits. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int size;
|
int size;
|
||||||
@ -2325,6 +2328,8 @@ re_compile_pattern(pattern, size, bufp)
|
|||||||
case dummy_failure_jump:
|
case dummy_failure_jump:
|
||||||
bufp->options |= RE_OPTIMIZE_ANCHOR;
|
bufp->options |= RE_OPTIMIZE_ANCHOR;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*laststart == charset || *laststart == charset_not) {
|
else if (*laststart == charset || *laststart == charset_not) {
|
||||||
@ -3004,6 +3009,7 @@ re_compile_fastmap(bufp)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case begpos:
|
||||||
case unused: /* pacify gcc -Wall */
|
case unused: /* pacify gcc -Wall */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4247,7 +4253,6 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
p1 = p;
|
p1 = p;
|
||||||
/* If failed to a backwards jump that's part of a repetition
|
/* If failed to a backwards jump that's part of a repetition
|
||||||
loop, need to pop this failure point and use the next one. */
|
loop, need to pop this failure point and use the next one. */
|
||||||
pop_loop:
|
|
||||||
switch ((enum regexpcode)*p1) {
|
switch ((enum regexpcode)*p1) {
|
||||||
case jump_n:
|
case jump_n:
|
||||||
case finalize_push_n:
|
case finalize_push_n:
|
||||||
|
16
ruby.c
16
ruby.c
@ -291,7 +291,7 @@ static char*
|
|||||||
moreswitches(s)
|
moreswitches(s)
|
||||||
char *s;
|
char *s;
|
||||||
{
|
{
|
||||||
int argc; char *argv[3]; char **argvp = argv;
|
int argc; char *argv[3];
|
||||||
char *p = s;
|
char *p = s;
|
||||||
|
|
||||||
argc = 2; argv[0] = argv[2] = 0;
|
argc = 2; argv[0] = argv[2] = 0;
|
||||||
@ -636,6 +636,12 @@ proc_options(argc, argv)
|
|||||||
load_file(script, 1);
|
load_file(script, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rb_safe_level() == 0) {
|
||||||
|
rb_ary_push(rb_load_path, rb_str_new2("."));
|
||||||
|
addpath(getenv("RUBYLIB"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
process_sflag();
|
process_sflag();
|
||||||
xflag = 0;
|
xflag = 0;
|
||||||
}
|
}
|
||||||
@ -917,10 +923,6 @@ ruby_prog_init()
|
|||||||
rb_define_readonly_variable("$-p", &do_print);
|
rb_define_readonly_variable("$-p", &do_print);
|
||||||
rb_define_readonly_variable("$-l", &do_line);
|
rb_define_readonly_variable("$-l", &do_line);
|
||||||
|
|
||||||
if (rb_safe_level() == 0) {
|
|
||||||
addpath(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
addpath(RUBY_LIB);
|
addpath(RUBY_LIB);
|
||||||
#if defined(_WIN32) || defined(DJGPP)
|
#if defined(_WIN32) || defined(DJGPP)
|
||||||
addpath(ruby_libpath());
|
addpath(ruby_libpath());
|
||||||
@ -942,10 +944,6 @@ ruby_prog_init()
|
|||||||
addpath(RUBY_SEARCH_PATH);
|
addpath(RUBY_SEARCH_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rb_safe_level() == 0) {
|
|
||||||
addpath(getenv("RUBYLIB"));
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
|
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
|
||||||
|
|
||||||
rb_argv = rb_ary_new();
|
rb_argv = rb_ary_new();
|
||||||
|
12
ruby.h
12
ruby.h
@ -358,13 +358,13 @@ struct RBignum {
|
|||||||
|
|
||||||
#define FL_ABLE(x) (!SPECIAL_CONST_P(x))
|
#define FL_ABLE(x) (!SPECIAL_CONST_P(x))
|
||||||
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
|
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
|
||||||
#define FL_SET(x,f) (FL_ABLE(x) && (RBASIC(x)->flags |= (f)))
|
#define FL_SET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags |= (f);} while (0)
|
||||||
#define FL_UNSET(x,f) (FL_ABLE(x) && (RBASIC(x)->flags &= ~(f)))
|
#define FL_UNSET(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags &= ~(f);} while (0)
|
||||||
#define FL_REVERSE(x,f) (FL_ABLE(x) && (RBASIC(x)->flags ^= (f)))
|
#define FL_REVERSE(x,f) do {if (FL_ABLE(x)) RBASIC(x)->flags ^= (f);} while (0)
|
||||||
|
|
||||||
#define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT)
|
#define OBJ_TAINTED(x) FL_TEST((x), FL_TAINT)
|
||||||
#define OBJ_TAINT(x) FL_SET((x), FL_TAINT)
|
#define OBJ_TAINT(x) FL_SET((x), FL_TAINT)
|
||||||
#define OBJ_INFECT(x,s) (FL_ABLE(x) && FL_ABLE(s) && (RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT))
|
#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & FL_TAINT;} while (0)
|
||||||
|
|
||||||
#define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE)
|
#define OBJ_FROZEN(x) FL_TEST((x), FL_FREEZE)
|
||||||
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
|
#define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
|
||||||
@ -394,8 +394,8 @@ void rb_define_variable _((const char*,VALUE*));
|
|||||||
void rb_define_virtual_variable _((const char*,VALUE(*)(),void(*)()));
|
void rb_define_virtual_variable _((const char*,VALUE(*)(),void(*)()));
|
||||||
void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(),void(*)()));
|
void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(),void(*)()));
|
||||||
void rb_define_readonly_variable _((const char*,VALUE*));
|
void rb_define_readonly_variable _((const char*,VALUE*));
|
||||||
void rb_define_constants _((VALUE,const char*,VALUE));
|
void rb_define_const _((VALUE,const char*,VALUE));
|
||||||
void rb_define_global_constants _((const char*,VALUE));
|
void rb_define_global_const _((const char*,VALUE));
|
||||||
|
|
||||||
void rb_define_method _((VALUE,const char*,VALUE(*)(),int));
|
void rb_define_method _((VALUE,const char*,VALUE(*)(),int));
|
||||||
void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int));
|
void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int));
|
||||||
|
28
sample/irb.rb
Normal file
28
sample/irb.rb
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
#
|
||||||
|
# irb.rb - intaractive ruby
|
||||||
|
# $Release Version: 0.6 $
|
||||||
|
# $Revision$
|
||||||
|
# $Date$
|
||||||
|
# by Keiju ISHITSUKA(Nippon Rational Inc.)
|
||||||
|
#
|
||||||
|
# --
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# irb.rb [options] file_name opts
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
require "irb/main"
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
IRB.start(__FILE__)
|
||||||
|
else
|
||||||
|
# check -e option
|
||||||
|
tmp = ENV["TMP"] || ENV["TMPDIR"] || "/tmp"
|
||||||
|
if %r|#{tmp}/rb| =~ $0
|
||||||
|
IRB.start(__FILE__)
|
||||||
|
else
|
||||||
|
IRB.initialize(__FILE__)
|
||||||
|
end
|
||||||
|
end
|
@ -413,7 +413,7 @@ module BC_APPLICATION__
|
|||||||
|
|
||||||
ch = chrs.shift
|
ch = chrs.shift
|
||||||
case ch
|
case ch
|
||||||
when /[_~*$?!@/\\;,.=:<>"]/ #"
|
when /[_~*$?!@\/\\;,.=:<>"]/ #"
|
||||||
return
|
return
|
||||||
|
|
||||||
when "-"
|
when "-"
|
||||||
|
4
string.c
4
string.c
@ -766,7 +766,7 @@ static VALUE
|
|||||||
rb_str_succ(orig)
|
rb_str_succ(orig)
|
||||||
VALUE orig;
|
VALUE orig;
|
||||||
{
|
{
|
||||||
VALUE str, str2;
|
VALUE str;
|
||||||
char *sbeg, *s;
|
char *sbeg, *s;
|
||||||
int c = -1;
|
int c = -1;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@ -1039,7 +1039,7 @@ rb_str_slice_bang(argc, argv, str)
|
|||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
VALUE arg1, arg2;
|
VALUE arg1, arg2;
|
||||||
long pos, len, i;
|
long pos, len;
|
||||||
|
|
||||||
rb_str_modify(str);
|
rb_str_modify(str);
|
||||||
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
|
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
|
||||||
|
6
time.c
6
time.c
@ -79,12 +79,6 @@ time_s_new(argc, argv, klass)
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
time_initialize()
|
|
||||||
{
|
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
time_new_internal(klass, sec, usec)
|
time_new_internal(klass, sec, usec)
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
|
22
util.c
22
util.c
@ -593,28 +593,6 @@ static void mmswap(a, b) register char *a, *b;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mmswapblock(a, b, size) register char *a, *b; int size;
|
|
||||||
{
|
|
||||||
register int s;
|
|
||||||
if (mmkind >= 0) {
|
|
||||||
register char *t = a + (size & (-16)); register int lo = (size & 0x0C);
|
|
||||||
if (size >= 16) {
|
|
||||||
do {
|
|
||||||
s = A[0]; A[0] = B[0]; B[0] = s;
|
|
||||||
s = A[1]; A[1] = B[1]; B[1] = s;
|
|
||||||
s = A[2]; A[2] = B[2]; B[2] = s;
|
|
||||||
s = A[3]; A[3] = B[3]; B[3] = s; a += 16; b += 16;
|
|
||||||
}while (a < t);
|
|
||||||
}
|
|
||||||
if (lo != 0) { s = A[0]; A[0] = B[0]; B[0] = s;
|
|
||||||
if (lo >= 8) { s = A[1]; A[1] = B[1]; B[1] = s;
|
|
||||||
if (lo == 12) {s = A[2]; A[2] = B[2]; B[2] = s;}}}
|
|
||||||
}else{
|
|
||||||
register char *t = a + size;
|
|
||||||
do {s = *a; *a++ = *b; *b++ = s;} while (a < t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mmrot3(a, b, c) register char *a, *b, *c;
|
static void mmrot3(a, b, c) register char *a, *b, *c;
|
||||||
{
|
{
|
||||||
register int s;
|
register int s;
|
||||||
|
@ -724,7 +724,6 @@ rb_generic_ivar_table(obj)
|
|||||||
VALUE obj;
|
VALUE obj;
|
||||||
{
|
{
|
||||||
st_table *tbl;
|
st_table *tbl;
|
||||||
VALUE val;
|
|
||||||
|
|
||||||
if (!generic_iv_tbl) return 0;
|
if (!generic_iv_tbl) return 0;
|
||||||
if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0;
|
if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0;
|
||||||
@ -1336,7 +1335,6 @@ rb_cvar_set(klass, id, val)
|
|||||||
ID id;
|
ID id;
|
||||||
VALUE val;
|
VALUE val;
|
||||||
{
|
{
|
||||||
VALUE value;
|
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
|
|
||||||
if (FL_TEST(klass, FL_SINGLETON)) {
|
if (FL_TEST(klass, FL_SINGLETON)) {
|
||||||
@ -1382,7 +1380,6 @@ rb_cvar_defined(klass, id)
|
|||||||
VALUE klass;
|
VALUE klass;
|
||||||
ID id;
|
ID id;
|
||||||
{
|
{
|
||||||
VALUE value;
|
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
|
|
||||||
if (FL_TEST(klass, FL_SINGLETON)) {
|
if (FL_TEST(klass, FL_SINGLETON)) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#define RUBY_VERSION "1.5.3"
|
#define RUBY_VERSION "1.5.4"
|
||||||
#define RUBY_RELEASE_DATE "2000-05-10"
|
#define RUBY_RELEASE_DATE "2000-05-12"
|
||||||
#define RUBY_VERSION_CODE 153
|
#define RUBY_VERSION_CODE 154
|
||||||
#define RUBY_RELEASE_CODE 20000510
|
#define RUBY_RELEASE_CODE 20000512
|
||||||
|
Loading…
x
Reference in New Issue
Block a user