From 10d21745c8c1c3c78678ea7e0b62c0a7433ccfce Mon Sep 17 00:00:00 2001 From: Yukihiro Matsumoto Date: Thu, 2 Oct 1997 17:59:18 +0900 Subject: version 1.0-971002 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://cache.ruby-lang.org/pub/ruby/1.0/ruby-1.0-971002.tar.gz Thu Oct 2 17:59:18 1997 Yukihiro Matsumoto * version 1.0-971002 Wed Oct 1 14:01:49 1997 WATANABE Hirofumi * ext/marshal/marshal.c (w_byte): argument must be char. Wed Oct 1 10:30:22 1997 Yukihiro Matsumoto * ext/marshal/marshal.c (marshal_dump): try to set binmode. * ext/marshal/marshal.c (r_object): forgot to re-regist structs in the object table. * eval.c (ruby_options): call Init_ext() before any require() calls by `-r'. Tue Sep 30 14:51:07 1997 Yukihiro Matsumoto * version 1.0-970930 Fri Sep 30 14:29:22 1997 WATANABE Hirofumi * ext/marshal/marshal.c (w_object): marshal dumped core. Tue Sep 30 10:27:39 1997 Yukihiro Matsumoto * sample/test.rb: bignum test suits added. Mon Sep 29 13:37:58 1997 Yukihiro Matsumoto * ruby.c (forbid_setid): forbid some options in suid mode. Mon Sep 27 09:53:48 1997 EGUCHI Matsumoto * bignum.c: modified for speeding. Fri Sep 26 18:27:59 1997 WATANABE Hirofumi * sample/from.rb: some extensions. Mon Sep 29 13:15:56 1997 Yukihiro Matsumoto * parse.y (lhs): no more syntax error on `obj.CONSTANT = value'. Fri Sep 26 14:41:46 1997 Yukihiro Matsumoto * eval.c (ruby_run): deferred calling Init_ext() just before eval_node. Fri Sep 26 13:27:24 1997 WATANABE Hirofumi * io.c (io_isatty): forgot to return TRUE value. Fri Sep 25 11:10:58 1997 EGUCHI Osamu * eval.c: use _setjmp/_longjmp instead of setjmp/longjmp on some platforms. Wed Sep 24 17:43:13 1997 Yukihiro Matsumoto * string.c (Init_String): String#taint and String#taint? added. Wed Sep 24 00:57:00 1997 Katsuyuki Okabe * X68000 patch. Tue Sep 23 20:42:30 1997 EGUCHI Osamu * parse.y (node_newnode): SEGV on null node setup. Mon Sep 22 11:22:46 1997 Yukihiro Matsumoto * ruby.c (ruby_prog_init): wrong safe condition check. Sun Sep 21 14:46:02 1997 MAEDA shugo * error.c (exc_inspect): garbage added to classpath. Fri Sep 19 11:49:23 1997 * version 1.0-970919 * parse.y (newtok): forgot to adjust buffer size when shrinking the token buffer. * enum.c (enum_find): rb_eval_cmd() does not return value. * io.c (pipe_open): close fds on pipe exec. fcntl(fd, F_SETFD, 1) no longer used. Tue Sep 16 17:54:25 1997 Yukihiro Matsumoto * file.c (f_test): problem if wrong command specified. * ruby.c (ruby_prog_init): close stdaux and stdprn for MSDOS. * ruby.c (ruby_prog_init): should not add path from environment variable, if ruby is running under seuid. * process.c (init_ids): check suid check for setuid/seteuid etc. Mon Sep 15 00:42:04 1997 WATANABE Hirofumi * regex.c (re_compile_pattern): \w{3} and \W{3} did not work. Thu Sep 11 10:31:48 1997 Yukihiro Matsumoto * version 1.0-970911 * ext/socket/socket.c (sock_new): no setbuf() for NT. * io.c (rb_fopen,rb_fdopen): set close-on-exec for every fd. Wed Sep 10 15:55:31 1997 Yukihiro Matsumoto * version 1.0-970910 * ext/marshal/marshal.c (r_bytes0): extra big length check. Tue Sep 9 16:27:14 1997 Yukihiro Matsumoto * io.c (pipe_fptr_atexit): clean up popen()'ed fptr. * error.c (set_syserr): some system has error code that is bigger than sys_nerr. grrr. Tue Sep 9 16:27:14 1997 Yukihiro Matsumoto * version 1.0-970909 * error.c (set_syserr): some system has error code that is bigger than sys_nerr. grrr. Wed Sep 3 18:11:00 1997 Yukihiro Matsumoto * version 1.0-970903 * eval.c (f_load): expand path if fname begins with `~'. Mon Sep 1 13:42:48 1997 Yukihiro Matsumoto * eval.c (rb_call): alias occured in the module body caused SEGV. Fri Aug 29 11:10:21 1997 Yukihiro Matsumoto * parse.y (yylex): spaces can follow =begin/=end. * variable.c (find_class_path): look for class_tbl also for unnamed fundamental classes, such as Object, String, etc. * variable.c (rb_name_class): can't name class before String class is initilialized. * inits.c (rb_call_inits): unrecognized dependency from GC to Array. * variable.c (find_class_path): could not find class if Object's iv_tbl is NULL. Thu Aug 28 13:12:05 1997 Yukihiro Matsumoto * parse.y (yylex): revised `=begin' skip code. * eval.c (is_defined): separated from rb_eval(). Wed Aug 27 11:32:42 1997 Yukihiro Matsumoto * variable.c (fc_i): some classes/modules does not have iv_tbl. * variable.c (find_class_path): avoid inifinite loop. Tue Aug 26 13:43:47 1997 Yukihiro Matsumoto * eval.c (rb_eval): undef'ing non-existing method will raise NameError exception. * object.c (class_s_new): needed to create metaclass too. * eval.c (error_print): no class name print for anonymous class. * eval.c (rb_longjmp): proper exception raised if raise() called without arguments, with $! or $@ set. * object.c (Init_Object): superclass()'s method argument setting was wrong again. Mon Aug 25 11:53:11 1997 Yukihiro Matsumoto * sample/ruby-mode.el (ruby-parse-region): auto-indent now supports "\\" in the strings. * struct.c (struct_getmember): new API to get member value from C language side. Fri Aug 22 14:26:40 1997 Yukihiro Matsumoto * eval.c (error_print): modified exception print format. Thu Aug 21 16:10:58 1997 Yukihiro Matsumoto * sample/ruby-mode.el (ruby-calculate-indent): wrong indent level calculated with keyword operators. Thu Aug 21 11:55:41 1997 Yukihiro Matsumoto * version 1.0-970821 Thu Aug 21 11:36:58 1997 WATANABE Hirofumi * parse.y (arg): ary[0] += 1 cause SEGV Wed Aug 20 14:24:42 1997 Yukihiro Matsumoto * version 1.0-970820 * eval.c (rb_call): infinite loop bug Tue Aug 19 00:15:38 1997 Yukihiro Matsumoto * version 1.0-970819 * eval.c (rb_call): did not raise ArgumentError if too many arguments more than optional arguments (without rest arg). * eval.c (rb_eval): did not work well for op_asgn2 (attribute self assignment). Mon Aug 18 09:25:56 1997 Yukihiro Matsumoto * object.c (inspect_i): did not display T_DATA instance variables. * parse.y: provides more accurate line number information. * eval.c (thread_value): include value's backtrace information in the variable `$@'. * eval.c (f_abort): print backtrace and exit. Sat Aug 16 00:17:44 1997 Yukihiro Matsumoto * object.c (class_s_new): do not make subclass of singleton class. Fri Aug 15 15:49:46 1997 Yukihiro Matsumoto * eval.c (call_trace_func): block context switch in the trace function. * eval.c (rb_eval): clear method cache at class extention. Fri Aug 15 19:40:43 1997 WATANABE Hirofumi * ext/socket/socket.c (Init_socket): small typo caused SEGV. Tue Aug 12 16:02:18 1997 Yukihiro Matsumoto * variable.c: option variables: $-0, $-p(readonly), $-v, $-I(load_path), $-a(readonly), $-K, $-d, $-F, $-i, $-l. * parse.y (yylex): ignore rd (ruby document) in the code. Mon Aug 11 12:37:58 1997 Yukihiro Matsumoto * re.c (Init_Regexp): $-K as alias to the $KCODE. * io.c (Init_IO): new virtual variable $-i for the value of -i option. * enum.c (Init_Enumerable): include? as alias of member? Fri Aug 8 11:16:50 1997 Yukihiro Matsumoto * io.c (io_foreach): now the record separator can be specified. * io.c (io_s_readlines): new method to read in whole file (or command output) from path. * ext/socket/socket.c (Init_socket): recvfrom did not work. * ext/socket/socket.c (sock_send): forgot to check nil for false value. Thu Aug 7 11:40:01 1997 Yukihiro Matsumoto * object.c (Init_Object): remove private_attr/public_attr. Wed Aug 6 14:21:36 1997 Yukihiro Matsumoto * object.c (mod_attr): forgot to check nil for false value. Mon Aug 4 11:50:28 1997 Yukihiro Matsumoto * variable.c (rb_class_path): scan class constants for anonymous classes/modules to make up pathes. Wed Jul 30 08:45:12 1997 Yukihiro Matsumoto * eval.c (rb_eval): stop to cache const value in nodes. Sat Jul 26 03:17:22 1997 WATANABE Hirofumi * numeric.c (flo_to_s): wrong .0 at end. Sat Jul 26 00:36:36 1997 Yukihiro Matsumoto * eval.c (error_print): always print exception type in the toplevel exception handler. * string.c (str_hash): wrong hash value. Thu Jul 24 11:05:51 1997 Yukihiro Matsumoto * string.c (uscore_get): proper error message for unset $_. Wed Jul 23 09:56:55 1997 Yukihiro Matsumoto * object.c (obj_methods): returns list of method names of the specified object. * class.c (mod_instance_methods): returns list of method names of the class instnace. Fri Jul 11 22:38:55 1997 Yukihiro Matsumoto * object.c (class_superclass): returns class's superclass itself. (1.1) * object.c (obj_type): returns object's class itself. (1.1) * class.c (mod_included_modules): list included modules. * object.c (class_superclass): raises error for Object. Thu Jul 3 09:54:02 1997 Yukihiro Matsumoto * eval.c (SETUP_ARGS): save source position, remove nd_line(). * eval.c (rb_call): replace modulo by bit-masking. * eval.c (POP_SCOPE): force recycle scope object to reduce gc rate. * gc.c (obj_free): aboid calling run_final() when no finalizer is set. * eval.c (PUSH_VARS): do not allocate the dynamic scope's end-mark object. Wed Jul 2 14:25:07 1997 KIMURA Koichi * Native mswin32 support. Tue Jul 1 09:59:00 1997 Yukihiro Matsumoto * version 1.0-970701 * parse.y (mrhs): allow rest-star(*) in right hand side. Tue Jun 24 19:04:31 1997 Yukihiro Matsumoto * version 1.0-970624 Sat Jun 20 22:22:51 1997 Michio "Karl" Jinbo * eval.c: freebsd 3.0 support. Fri Jun 20 01:24:45 1997 Yukihiro Matsumoto * version 1.0-970620 * gc.c: eliminate uninitilalized field of Hash, Array etc., to avoid dumping core. Thu Jun 19 01:29:44 1997 Yukihiro Matsumoto * version 1.0-970619 * string.c (str_split_method): wrong limit. Sat Jun 14 01:54:16 1997 Yukihiro Matsumoto * class.c (rb_singleton_class): no singleton for special constants (now raises exception). * eval.c (ruby_init): cbase in TOPLEVEL_BINDING need to be initialized. Sat Jun 14 01:01:16 1997 maeda shugo * array.c (sort_2): wrong comparison. Sat Jun 14 00:53:44 1997 Yukihiro Matsumoto * hash.c (hash_foreach): safe iteration. Fri Jun 13 14:04:56 1997 Michio "Karl" Jinbo * configure.in: -Bshareable option for netbsd. Fri Jun 13 01:16:22 1997 WATANABE Hirofumi * io.c (pipe_open): call io_unbuffered() only for writable pipes. Thu Jun 12 01:14:15 1997 Yukihiro Matsumoto * version 1.0-970612 * ext/socket/socket.c (sock_new): use io_unbuffered(). * ext/marshal/marshal.c (w_long): compact long format, which supports 64 bit architectures (unless longs are >32 bit size). * ext/marshal/marshal.c: allows recursive data for marshaling. * parse.y (rb_intern): raise exception for non-internable string. * ext/marshal/marshal.c (marshal_load): allows direct loading from strings. * ext/marshal/marshal.c (marshal_dump): allows direct dump to strings. * ext/marshal/marshal.c (marshal_dump): interface changed. Wed Jun 11 18:26:00 1997 Yukihiro Matsumoto * gc.c (rb_newobj): remove needless memset(). Mon Jun 9 13:03:43 1997 Yukihiro Matsumoto * eval.c (rb_eval): reduce condition checks from while/until loop. * eval.c (rb_eval): wrong jump point for `next'. Fri Jun 6 11:47:39 1997 Yukihiro Matsumoto * ruby.c (ruby_set_argv): initialize dln_argv0 for dln_a_out. * ext/socket/socket.c (open_unix): display path name for exceptions. * ruby.c (proc_options): option -S did not work well. Fri May 30 02:14:44 1997 Yukihiro Matsumoto * version 1.0-970530 * eval.c (eval): set $! properly if exception raised in eval(). * io.c (io_write): now handles non T_FILE object. * io.c (io_defset): $< can be anything which has `write' method. Thu May 29 15:40:22 1997 Yukihiro Matsumoto * eval.c (eval): $@ is always an array (not string). * pack.c (pack_unpack): avoid corrupting memory for unexpected input strings. Wed May 28 12:46:13 1997 Yukihiro Matsumoto * version 1.0-970528 * process.c (rb_waitpid): do not block other threads. Tue May 27 12:02:31 1997 Yukihiro Matsumoto * eval.c (ruby_init): split initialize and processing command line options. * ruby.c (ruby_options): ruby_init(0, 0, envp) dumps core. Tue May 20 18:59:45 1997 Yukihiro Matsumoto * variable.c (rb_ivar_set): invalid instance variable access for built-in object raises TypeError. Fri May 16 17:32:21 1997 Yukihiro Matsumoto * version 1.0-970516 * dir.c (push_globs): was freeing non heap pointer. * gc.c: remove some duplicated prototypes. * ext/kconv/kconv.c: fix prototypes. Fri May 9 11:38:59 1997 Yukihiro Matsumoto * version 1.0-970509 * gc.c (obj_free): avoid free(NULL). * eval.c (rb_check_safe_str): argument missing for TypeError(). Thu May 8 01:14:28 1997 Yukihiro Matsumoto * file.c (file_s_dirname): need to return "." for path without slashes. Wed May 7 19:18:48 1997 Yukihiro Matsumoto * process.c (f_fork): child processe does not inherit parent's itimer setting on linux. call setitimer() again in the child process. Sat May 3 02:49:43 1997 Yukihiro Matsumoto * ext/curses/curses.c: modified for portability and add to the standard distribution. Wed Apr 30 00:34:00 1997 Yukihiro Matsumoto * file.c (file_s_size): returns 0 for empty files (not FALSE). Fri Apr 25 02:17:50 1997 Yukihiro Matsumoto * version 1.0-970425 * eval.c (f_load): free unused name-table. * eval.c (f_load): copy local variable name-table. * gc.c (obj_free): avoid free(NULL). * eval.c (rb_eval): forgot to make link from the scope object to NODE_SCOPE. It may crash the interpreter. Thu Apr 24 00:35:09 1997 Yukihiro Matsumoto * random.c (f_srand): save old seed anyway. srand() returns no value on some systems. * gc.c (obj_free): avoid double free of the local variable name table. * parse.y (top_local_setup): modify realloc to handle offset. Tue Apr 22 12:58:26 1997 Yukihiro Matsumoto * version 1.0-970422 Thu Apr 17 00:40:51 1997 Yukihiro Matsumoto * configure.in (rb_cv_bsdpgrp): proper check for BSD setpgrp/setpgrp. Wed Apr 16 16:14:02 1997 Yukihiro Matsumoto * eval.c (proc_call): proc called in other thread must be orphan. Tue Apr 15 10:46:31 1997 Yukihiro Matsumoto * version 1.0-970415 * gc.c (obj_free): NODE_SCOPE marked from SCOPE object. * gc.c (gc_mark): some nodes marked wrong. * process.c (proc_getpgrp): wrong argument Fri Apr 14 18:32:42 1997 Yukihiro Matsumoto * version 1.0-970414 Fri Apr 12 01:20:12 1997 Yukihiro Matsumoto * ruby.h: String pointer changed to unsigned char. Fri Apr 11 10:27:29 1997 Yukihiro Matsumoto * version 1.0-970411 * Makefile.in: create libruby.a before linking ruby. * string.c (str_strip_bang): >0x80 characters for isspace(). * eval.c (proc_call): set safe-level temporally * eval.c (proc_s_new): save safe-level in the proc context. * eval.c (rb_eval): no class/module extention in safe mode. Thu Apr 10 02:10:41 1997 Yukihiro Matsumoto * gc.c (gc_mark): remove some pointer checks for speeding up. * ruby.c (ruby_options): set $0 temporally for -r option. * eval.c: built-in security feature. * gc.c (gc_sweep): do not free nodes during compile. * parse.y (yycompile): set flag when compiling. Wed Apr 9 10:19:02 1997 Yukihiro Matsumoto * ruby.c: forgot to include for isspace(). * file.c: provide S_ISREG for some platforms. * io.c (Init_IO): added some $< operations. * lib/ping.rb: check host upness using TCP echo. Tue Apr 8 00:10:15 1997 Yukihiro Matsumoto * io.c (arg_read): bug with 0 length input. Mon Apr 7 11:36:16 1997 Yukihiro Matsumoto * ext/fcntl/fcntl.c: module for fcntl constants. * eval.c (rb_alias): bug when original was an alias. * parse.y (primary): syntax to access singleton class. * eval.c (mod_public_method): method's to specify visibitily of the class methods. make_method_{public,private} removed. Fri Apr 4 21:43:57 1997 Yukihiro Matsumoto * version 1.0-970404 * gc.c (obj_free): finalizer added for experiment. Thu Apr 3 02:12:31 1997 Yukihiro Matsumoto * eval.c (thread_schedule): make Fatal rise on main_thread on deadlocks. * eval.c (thread_join): raise ThreadError instead of Fatal, in case of deadlock. * regex.c (re_compile_fastmap): uninitialized local variable. * parse.y (parse_regx): new option //[nes] to specify character code for regexp literals. Last specified code option is valid. * re.c (reg_s_new): addtional 3rd argument to specify compiled regexp's character code. * re.c (reg_new_1): regexp character code can be specified for each regexp object. Wed Apr 2 14:51:06 1997 Yukihiro Matsumoto * eval.c (thread_create): handle uncaught throw. * eval.c (thread_create): halt on some deadlock conditions. * regex.c (is_in_list): wrong result for non-mbc higher-byte characters. * regex.c (re_match): wrong skip for multi-byte characters. * regex.c (re_compile_fastmap): wrong fastmap in non-mbc mode. * hash.c (Init_Hash): hash compatible features added to ENV. Tue Apr 1 15:24:06 1997 Yukihiro Matsumoto * eval.c (obj_extend): remove Object#extend as an iterator which is in experimental state, since it unveils internal singleton classes. Mon Mar 31 14:29:39 1997 Yukihiro Matsumoto * version 1.0-970331 Sun Mar 30 19:40:57 1997 WATANABE Hirofumi * parse.y (terms): avoided win32 gcc's optimization bug. Sat Mar 29 11:21:58 1997 Yukihiro Matsumoto * struct.c (make_struct): St[val,..] creates new structure. Fri Mar 28 11:24:51 1997 Yukihiro Matsumoto * eval.c (obj_make_private): new method make_method_{public,private} to change visibility of singleton methods. * regex.c (re_compile_pattern): enables numeric literal >= 0x80 in the character class. * regex.c (re_compile_pattern): enabled numeric literal >= 0x80, in multibyte mode. * regex.c (re_compile_fastmap): modified exantn and charset(_not) to set fastmap for higher bytes properly. * regex.c (is_in_list): now matches numeric literals. Thu Mar 27 13:34:20 1997 WATANABE Hirofumi * pack.c (pack_unpack): extra null byte after unpacked string. Wed Mar 26 15:20:34 1997 Yukihiro Matsumoto * regex.c (re_compile_pattern): register numbers must be fit in a byte (0 <= regnum <= 0xff). * regex.c (re_compile_fastmap): forgot to set mbchar map for charset_not if RE_MBCTYPE is on. * regex.c (re_compile_pattern): set list bits for multi-byte characters for \W, \S, \D in range expression. * object.c (obj_is_kind_of): defined that nil itself is kind of nil. TRUE is kind of TRUE, FALSE is kind of FALSE likewise. This change makes `obj.kind_of?(eval(obj.type))' always true. Tue Mar 25 14:08:43 1997 Yukihiro Matsumoto * lib/English.rb: provides nicer English alias for the variables. * parse.y (expr): alias $var1 $var2 makes alias of the global variable. Mon Mar 24 18:23:20 1997 Yukihiro Matsumoto * version 1.0-970324 Thu Mar 20 22:04:59 1997 Yukihiro Matsumoto * eval.c (mod_modfunc): forget to clear method cache. Wed Mar 19 17:06:55 1997 Yukihiro Matsumoto * parse.y (program): set methods' default private/public status correctly under eval(). * eval.c (eval): set the_class correctly while evaluating string. Tue Mar 18 12:23:53 1997 Yukihiro Matsumoto * eval.c (eval): yield can be called from eval(). * version 1.0-970318 * parse.y (program): regexp in condition expression should do matching operation with $_. * re.c (reg_regsub): wrong substitution. Fri Mar 14 14:36:28 1997 Yukihiro Matsumoto * hash.c (hash_invert): returns value to key mapping of the associative array. * ext/socket/extconf.rb: set environment variable SOCKS_SERVER to compile with libsocks.a. * ext/socket/socket.c (socks_s_open): SOCKSsocket class to access internet via SOCKS library. * sprintf.c (f_sprintf): unsigned formats display leading double dots for imaginary sequence of signed bit to the left. * sprintf.c (f_sprintf): correct width and precision formatting for big integers. * parse.y (yylex): enables negative hex/octal numbers and `_' in non-decimal numbers. * sprintf.c (f_sprintf): %u added for unsigned decimal format. Thu Mar 13 10:24:27 1997 Yukihiro Matsumoto * sprintf.c (f_sprintf): wrong output for bignums. * array.c (ary_reverse_each): iterates in reverse order. * pack.c (pack_unpack): L unpacked signed long. * io.c (f_backquote): now returns an empty string for no output. Wed Mar 12 10:20:30 1997 Yukihiro Matsumoto * ext/socks/socks.c: socket module with socks library. Mon Mar 10 20:44:22 1997 Yukihiro Matsumoto * re.c (reg_regsub): \& for substitution. \`, \', and \+ are avaiable also. Thu Mar 6 01:47:03 1997 Yukihiro Matsumoto * version 1.0-970306 * sample/rubydb.el (gud): ruby debugger emacs interface * lib/debug.rb: ruby debugger * parse.y (exprs): more accurate line number display. Wed Mar 5 21:31:46 1997 Yukihiro Matsumoto * version 1.0-970305 Tue Mar 4 12:28:32 1997 Yukihiro Matsumoto * ruby.c (proc_options): search through RUBYPATH and PATH for option -S. Mon Mar 3 22:44:55 1997 Yukihiro Matsumoto * eval.c (thread_status): returns nil for exception terminated threads. * eval.c (thread_value): re-raise exceptions. Sat Mar 1 00:59:47 1997 Yukihiro Matsumoto * eval.c (rb_eval): restore $! value after rescue clause, to re-raise exceptions correctly. Fri Feb 28 16:43:38 1997 Yukihiro Matsumoto * version 1.0-970228 Thu Feb 27 11:23:41 1997 Yukihiro Matsumoto * eval.c (rb_yield_0): redo raises exception * eval.c (thread_schedule): bug in interrupt handling by rescue. Wed Feb 26 00:55:36 1997 Yukihiro Matsumoto * eval.c (eval): forgot to restore dynamic local variable bindings. Tue Feb 25 11:22:08 1997 Yukihiro Matsumoto * ext/aix_ld.rb: AIX dynamic load support (not tested). * eval.c (rb_eval): wrong return value for defined? super. * error.c (exception): more error check. * re.c (reg_regsub): wrong substitution when sub expanded to null string. Fri Feb 21 13:01:47 1997 Yukihiro Matsumoto * version 1.0-970221 * eval.c (f_require): volatile added. register variable was recycled, so that GC did not mark that variable. * object.c (Init_Object): forget to mark main object (was mostly ok, but made trouble with early GC.) Thu Feb 20 11:50:50 1997 Yukihiro Matsumoto * version 1.0-970220 Thu Feb 20 11:25:50 1997 Yasuo OHBA * lib/date.rb: update Thu Feb 20 08:25:57 1997 Yukihiro Matsumoto * parse.y (yylex): forgot tokfix() before rb_intern(). * lib/tk.rb (TkVariable): give up using trace_var. Wed Feb 19 00:24:35 1997 Yukihiro Matsumoto * version 1.0-970219 * pack.c (pack_pack): packed by null for A specifier. must be space filled. * pack.c (pack_unpack): bug in skipping spaces * gc.c (xmalloc): garbage collect for every 4 Meg. allocation. * string.c (str_split_method): limit worked wrong way. * io.c (io_gets_method): misunderstand 0xff in binary files when $/ == nil. * re.c (reg_regsub): re-implement. * ext/socket/socket.c (thread_connect): remove O_NONBLOCK, which is not defined on some platform like NeXT. Mon Feb 17 13:08:30 1997 Yukihiro Matsumoto * version 1.0-970217 * object.c (mod_eqq): === extended for subclass check (to use case as typecase). Sat Feb 15 02:07:22 1997 Yukihiro Matsumoto * regex.c (re_compile_pattern): wrong match backref at end of pattern. * io.c (arg_read): now works beyond end of file. Thu Feb 13 16:21:24 1997 Yukihiro Matsumoto * parse.y (expr): return/yield now accept normal argument format. * parse.y (yylex): a star in `yield *x' must not be multiplication operator. Wed Feb 12 15:06:44 1997 Yukihiro Matsumoto * time.c (time_plus): bug in simple addition. * eval.c (thread_raise): raise exceptions from outside. * eval.c (Init_Thread): Thread#alive? -- alias for Thread#status. Mon Feb 10 00:38:55 1997 Yukihiro Matsumoto * ruby.h (Data_Make_Struct): rename macros. Sun Feb 8 11:48:13 1997 Yukihiro Matsumoto * io.c (f_syscall): argument offset was wrong. Fri Feb 7 18:01:17 1997 Yukihiro Matsumoto * version 1.0-970207 * eval.c: add volatiles to avoid variable crobbering by longjmp(). * eval.c (f_raise): 1st argument can be the GlobalExit object now. * array.c (ary_unshift): no longer accept more than 2 args. * eval.c (f_raise): bug if 2nd argument is the exception. Tue Feb 4 00:37:29 1997 Yukihiro Matsumoto * version 1.0-970204 * eval.c (eval): check compile errors by nerrs. * eval.c (rb_eval): check syntax error by nerrs, not by the return value, which may be NULL. * eval.c (compile): Do not clear errinfo. Mon Feb 3 10:13:06 1997 Yukihiro Matsumoto * eval.c (obj_extend): move real inclusion to Module#extend_object to allow redfinition. * object.c (Init_Object): Kernel class is now Module. Object class became the true root class. * object.c (obj_inspect): remove useless buffer. * hash.c (any_cmp): disable interrupts and context switching. * st.c: remove ALLOW_INTS to disable interrupt during operations. Fri Jan 31 22:10:08 1997 Yukihiro Matsumoto * hash.c (hash_rehash): re-register all key-value. Thu Jan 30 02:14:49 1997 Yukihiro Matsumoto * io.c (io_reopen): re-implement according to clone() way. * io.c (io_clone): copy IO object. * struct.c (struct_eql): compare elements by eql?. * io.c (io_mode_flags): detect "rb", "wb" etc. * io.h (FMODE_BINMODE): added. * ext/socket/socket.c (Init_socket): undef BasicSocket.new * file.c (Init_File): File.new(path[,mode]) * io.c (Init_IO): IO.new(fd[,mode]) * eval.c (rb_method_boundp): forgot to enable priv argument. * object.c (Init_Object): remove `=~' from Kernel class. * ext/socket/socket.c (open_inet): initialize sockaddr before calling bind(2). * sample/ruby-mode.el (ruby-calculate-indent): skip comment lines Wed Jan 29 18:43:22 1997 Yukihiro Matsumoto * eval.c (Init_Thread): DEFER_INTS during initializing threads. * hash.c (Init_Hash): Hash#eql? checks for object identity. * eval.c (thread_set_critical): wrong value assigned. Mon Jan 27 16:10:51 1997 Yukihiro Matsumoto * io.c (io_print): remove print_on(). * eval.c (f_missing): proper error message for undefined method without argument Sat Jan 25 23:32:32 1997 Yukihiro Matsumoto * string.c (str_sub_s): false alert - sub() does not modify string. * array.c (ary_times): negative multiplication detected * string.c (str_times): negative multiplication detected Fri Jan 24 10:51:39 1997 Yukihiro Matsumoto * time.c (time_arg): month -> 0 == "jan" == "1" == "01", little bit confusing but wanted to conform japanese style. * version 1.0-970124 Fri Jan 24 09:52:49 1997 WATANABE Hirofumi * util.c (_fixpath): supports SJIS filenames on DJGPP. Thu Jan 23 16:52:06 1997 Yukihiro Matsumoto * README.EXT: update. partially translated into English. * ext/extmk.rb.in: inherit $LDFLAGS to the final link. * ext/socket/socket.c (Init_socket): add various constants. Mon Jan 23 11:40:59 1997 WATANABE Hirofumi * eval.c (Init_Thread): allocate main_thread first to avoid crash. Thu Jan 23 02:09:26 1997 Yukihiro Matsumoto * gc.c (ObjectSpace): API modified. each_object method will do all the iteration. * eval.c (proc_call): wrong return from nested lambda. * ext/GD/GD.c: debugged. Wed Jan 22 16:12:25 1997 Yukihiro Matsumoto * version 1.0-970122 * gc.c (gc_mark): forgot to mark match->str. * ext/GD/GD.c: GD interface module. * eval.c (PUSH_BLOCK): wrong value pushed as the block level. Mon Jan 20 14:01:31 1997 Yukihiro Matsumoto * eval.c (thread_run): no context switch in the critical section. Mon Jan 20 09:40:59 1997 WATANABE Hirofumi * utils.c: supports 8+3 filenames Sat Jan 18 01:23:03 1997 Yukihiro Matsumoto * version 1.0-970118 * regex.c (PATFETCH): need cast to unsigned char. * io.c (io_ctl): bug in case when arg is not a string. * lib/tk.rb: forgot that Kernel#type returns the class name now. * regex.c (re_search): "abc\n" =~ "^$" should not match. Fri Jan 17 12:31:37 1997 Yukihiro Matsumoto * version 1.0-970117 * ruby.c (ruby_options): constant PLATFORM, which is in the {cpu}-{os} form, defined. * configure.in: platform infomation embedded in the interpreter. * regex.c (re_search): /^$/ did not match to "" by wrong exit condition. * lib/thread.rb: re-write Mutex/Queue based on Thread.critical. * eval.c (thread_set_critical): remove Thread.exclusive, add Thread.critical = TRUE/FALSE instead. * re.c (reg_search): re-compile pattern if needed * regex.c (PATFETCH): do translate at compile time Thu Jan 16 00:49:10 1997 Yukihiro Matsumoto * gc.c (gc_mark_frame): forgot to mark frame->cbase. * regex.c (re_compile_pattern): /a$|b)/ causes error. * regex.c (re_compile_pattern): /(^|b)/ causes error. * version 1.0-970116 * re.c (Init_Regexp): set RE_CONTEXTUAL_INVALID_OPS flag. Tue Jan 14 02:09:06 1997 Yukihiro Matsumoto * eval.c (proc_call): Proc#callをイテレータとして呼んだ時に対応 * configure.in: nextstep対応? * eval.c (rb_eval): a[b]=cで無駄な配列を割り当てない * eval.c (f_send): イテレータとして呼ばれたらイテレータとしてメソッ ドを呼ぶ. * string.c (str_new4): match共有用の生成関数 * re.c (reg_search): matchの実体(文字列)をマッチを行った文字列と copy-on-writeで共有 * string.c (str_hash): toupperをかける条件が違っていた * array.c (sort_2): FixnumとStringを特別扱いして高速化 Mon Jan 13 11:03:53 1997 Yukihiro Matsumoto * eval.c (thread_create): threadが生成されるまで割込みを設定しない * eval.c (Init_Thread): 割込みタイミングを100msecに Sat Jan 11 00:17:05 1997 Yukihiro Matsumoto * regex.c (re_search): マッチに失敗する場合があった(本当に直ったか?) * io.c (io_ioctl,io_fcntl): 第2引数を省略可能に * io.c (io_ioctl,io_fcntl): 戻り値がIOだった.整数(システムコール の戻り値)を返すようにした. * io.c (io_ctl): 引数が整数の時に対応 * io.c (io_fcntl): file.cから移動 Fri Jan 10 17:01:47 1997 Yukihiro Matsumoto * version 1.0-970110 * ext/socket/socket.c (thread_connect): open(connect(2))で他の threadをブロックしないように * eval.c (thread_create): exitでないときにexitだと思い込む Mon Jan 6 17:42:22 1997 Yukihiro Matsumoto * string.c (str_sub_s): 文字列長より長いoffsetの検出 * regex.c (re_search): 空にマッチするパターン後の$で失敗 Thu Jan 2 16:36:23 1997 Yukihiro Matsumoto * file.c (file_reopen): Fileのreopen(pathまたはIOで指定). * io.c (io_reopen): IOのreopen(IOで指定) -- change classつき Wed Jan 1 11:09:01 1997 Yukihiro Matsumoto * io.c (f_select): timeoutでnilを返す Fri Dec 27 13:06:44 1996 Yukihiro Matsumoto * file.c (file_s_open): サブクラスではそのクラスのインスタンスを返 すように. Fri Dec 27 08:58:27 1996 ono@isl.nara.sharp.co.jp * numeric.c (flo_to_s): index()を使わない.strstr()に. Thu Dec 26 01:34:17 1996 Yukihiro Matsumoto * lib/tk.rb: placeが使えるように * pack.c (endian): マクロDYNAMIC_ENDIANを指定すると実行時にendian を判定するように. * eval.c (thread_alloc): 初期化忘れのメンバがあった. Co-authored-by: EGUCHI Matsumoto Co-authored-by: EGUCHI Osamu Co-authored-by: KIMURA Koichi Co-authored-by: Katsuyuki Okabe Co-authored-by: MAEDA shugo Co-authored-by: Michio "Karl" Jinbo Co-authored-by: WATANABE Hirofumi Co-authored-by: Yasuo OHBA Co-authored-by: maeda shugo Co-authored-by: ono --- parse.y | 510 +++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 377 insertions(+), 133 deletions(-) (limited to 'parse.y') diff --git a/parse.y b/parse.y index 350c83a7ca..50e6db2b39 100644 --- a/parse.y +++ b/parse.y @@ -56,7 +56,7 @@ static enum lex_state { EXPR_BEG, /* ignore newline, +/- is a sign. */ EXPR_MID, /* newline significant, +/- is a sign. */ EXPR_END, /* newline significant, +/- is a operator. */ - EXPR_ARG, /* newline significant, +/- is a sign(meybe). */ + EXPR_ARG, /* newline significant, +/- may be a sign. */ EXPR_FNAME, /* ignore newline, +/- is a operator. */ } lex_state; @@ -68,16 +68,17 @@ static int value_expr(); static NODE *cond(); static NODE *logop(); +static NODE *newline_node(); +static void fixpos(); + static NODE *block_append(); static NODE *list_append(); static NODE *list_concat(); -static NODE *list_copy(); -static NODE *expand_op(); static NODE *call_op(); static int in_defined = 0; static NODE *gettable(); -static NODE *asignable(); +static NODE *assignable(); static NODE *aryset(); static NODE *attrset(); static void backref_error(); @@ -154,7 +155,7 @@ static void top_local_setup(); %type literal numeric %type compexpr exprs expr arg primary command_call method_call %type if_tail opt_else case_body cases rescue ensure iterator -%type call_args call_args0 args args2 opt_args var_ref +%type call_args call_args0 ret_args args mrhs opt_args var_ref %type superclass f_arglist f_args f_optarg f_opt %type array assoc_list assocs assoc undef_list %type iter_var opt_iter_var iter_block iter_do_block @@ -214,12 +215,15 @@ program : { lex_state = EXPR_BEG; top_local_init(); NEW_CREF0(); /* initialize constant c-ref */ + if ((VALUE)the_class == cObject) class_nest = 0; + else class_nest = 1; } compexpr { eval_tree = block_append(eval_tree, $2); top_local_setup(); cur_cref = 0; + class_nest = 0; } compexpr : exprs opt_terms @@ -229,16 +233,19 @@ exprs : /* none */ $$ = 0; } | expr + { + $$ = newline_node($1); + } | exprs terms expr { - $$ = block_append($1, $3); + $$ = block_append($1, newline_node($3)); } | error expr { $$ = $2; } -expr : mlhs '=' args2 +expr : mlhs '=' mrhs { value_expr($3); $1->nd_value = $3; @@ -248,14 +255,14 @@ expr : mlhs '=' args2 { $$ = NEW_HASH($1); } - | RETURN args2 + | RETURN ret_args { value_expr($2); if (!cur_mid && !in_single) yyerror("return appeared outside of method"); $$ = NEW_RET($2); } - | YIELD args2 + | YIELD ret_args { value_expr($2); $$ = NEW_YIELD($2); @@ -265,11 +272,40 @@ expr : mlhs '=' args2 { $2->nd_iter = $1; $$ = $2; + fixpos($$, $2); } | ALIAS fname {lex_state = EXPR_FNAME;} fname { + if (cur_mid || in_single) + yyerror("alias within method"); $$ = NEW_ALIAS($2, $4); } + | ALIAS GVAR GVAR + { + if (cur_mid || in_single) + yyerror("alias within method"); + $$ = NEW_VALIAS($2, $3); + } + | ALIAS GVAR BACK_REF + { + char buf[3]; + + if (cur_mid || in_single) + yyerror("alias within method"); + sprintf(buf, "$%c", $3->nd_nth); + $$ = NEW_VALIAS($2, rb_intern(buf)); + } + | ALIAS GVAR NTH_REF + { + yyerror("can't make alias for the number variables"); + $$ = 0; + } + | UNDEF undef_list + { + if (cur_mid || in_single) + yyerror("undef within method"); + $$ = $2; + } | expr IF_MOD expr { value_expr($3); @@ -323,21 +359,20 @@ expr : mlhs '=' args2 command_call : operation call_args0 { $$ = NEW_FCALL($1, $2); + fixpos($$, $2); } | primary '.' operation call_args0 { value_expr($1); $$ = NEW_CALL($1, $3, $4); + fixpos($$, $1); } | SUPER call_args0 { if (!cur_mid && !in_single && !in_defined) yyerror("super called outside of method"); $$ = NEW_SUPER($2); - } - | UNDEF undef_list - { - $$ = $2; + fixpos($$, $2); } mlhs : mlhs_head @@ -374,7 +409,7 @@ mlhs_tail : lhs lhs : variable { - $$ = asignable($1, 0); + $$ = assignable($1, 0); } | primary '[' opt_args opt_nl ']' { @@ -384,6 +419,10 @@ lhs : variable { $$ = attrset($1, $3, 0); } + | primary '.' CONSTANT + { + $$ = attrset($1, $3, 0); + } | backref { backref_error($1); @@ -445,15 +484,23 @@ op : DOT2 { $$ = DOT2; } arg : variable '=' arg { value_expr($3); - $$ = asignable($1, $3); + $$ = assignable($1, $3); + fixpos($$, $3); } | primary '[' opt_args opt_nl ']' '=' arg { $$ = aryset($1, $3, $7); + fixpos($$, $7); } | primary '.' IDENTIFIER '=' arg { $$ = attrset($1, $3, $5); + fixpos($$, $5); + } + | primary '.' CONSTANT '=' arg + { + $$ = attrset($1, $3, $5); + fixpos($$, $5); } | backref '=' arg { @@ -466,18 +513,22 @@ arg : variable '=' arg value_expr($3); if (is_local_id($1)&&!local_id($1)&&dyna_in_block()) dyna_var_asgn($1, TRUE); - $$ = asignable($1, call_op(gettable($1), $2, 1, $3)); + $$ = assignable($1, call_op(gettable($1), $2, 1, $3)); + fixpos($$, $3); } | primary '[' opt_args opt_nl ']' OP_ASGN arg { NODE *args = NEW_LIST($7); - if ($3) list_concat(args, $3); + list_append($3, NEW_NIL()); + list_concat(args, $3); $$ = NEW_OP_ASGN1($1, $6, args); + fixpos($$, $7); } | primary '.' IDENTIFIER OP_ASGN arg { $$ = NEW_OP_ASGN2($1, $3, $4, $5); + fixpos($$, $5); } | backref OP_ASGN arg { @@ -570,10 +621,12 @@ arg : variable '=' arg } | arg MATCH arg { + local_cnt('~'); $$ = NEW_CALL($1, MATCH, NEW_LIST($3)); } | arg NMATCH arg { + local_cnt('~'); $$ = NEW_NOT(NEW_CALL($1, MATCH, NEW_LIST($3))); } | '!' arg @@ -601,10 +654,10 @@ arg : variable '=' arg { $$ = logop(NODE_OR, $1, $3); } - | DEFINED {in_defined = 1;} arg + | DEFINED opt_nl {in_defined = 1;} arg { in_defined = 0; - $$ = NEW_DEFINED($3); + $$ = NEW_DEFINED($4); } | primary { @@ -627,10 +680,6 @@ call_args0 : args { $$ = NEW_LIST(NEW_HASH($1)); } - | args ',' command_call - { - $$ = list_append($1, $3); - } | args ',' assocs { $$ = list_append($1, NEW_HASH($3)); @@ -666,7 +715,25 @@ args : arg $$ = list_append($1, $3); } -args2 : args +mrhs : args + { + if ($1 && $1->nd_next == 0) { + $$ = $1->nd_head; + } + else { + $$ = $1; + } + } + | args ',' STAR arg + { + $$ = call_op($1, '+', 1, $4); + } + | STAR arg + { + $$ = $2; + } + +ret_args : call_args0 { if ($1 && $1->nd_next == 0) { $$ = $1->nd_head; @@ -732,13 +799,26 @@ primary : literal { $$ = NEW_HASH($2); } + | RETURN '(' ret_args ')' + { + if (!cur_mid && !in_single) + yyerror("return appeared outside of method"); + value_expr($3); + $$ = NEW_RET($3); + } + | RETURN '(' ')' + { + if (!cur_mid && !in_single) + yyerror("return appeared outside of method"); + $$ = NEW_RET(0); + } | RETURN { if (!cur_mid && !in_single) yyerror("return appeared outside of method"); $$ = NEW_RET(0); } - | YIELD '(' args2 ')' + | YIELD '(' ret_args ')' { value_expr($3); $$ = NEW_YIELD($3); @@ -750,11 +830,11 @@ primary : literal | YIELD { $$ = NEW_YIELD(0); - } - | DEFINED '(' {in_defined = 1;} expr ')' + } + | DEFINED opt_nl '(' {in_defined = 1;} expr ')' { in_defined = 0; - $$ = NEW_DEFINED($4); + $$ = NEW_DEFINED($5); } | FID { @@ -770,6 +850,7 @@ primary : literal { $2->nd_iter = $1; $$ = $2; + fixpos($$, $1); } | IF expr then compexpr @@ -778,6 +859,7 @@ primary : literal { value_expr($2); $$ = NEW_IF(cond($2), $4, $5); + fixpos($$, $2); } | UNLESS expr then compexpr @@ -786,16 +868,19 @@ primary : literal { value_expr($2); $$ = NEW_UNLESS(cond($2), $4, $5); + fixpos($$, $2); } | WHILE expr term compexpr END { value_expr($2); $$ = NEW_WHILE(cond($2), $4, 1); + fixpos($$, $2); } | UNTIL expr term compexpr END { value_expr($2); $$ = NEW_UNTIL(cond($2), $4, 1); + fixpos($$, $2); } | CASE compexpr case_body @@ -803,11 +888,13 @@ primary : literal { value_expr($2); $$ = NEW_CASE($2, $3); + fixpos($$, $2); } | FOR iter_var IN expr term compexpr END { value_expr($2); $$ = NEW_FOR($2, $4, $6); + fixpos($$, $2); } | BEGIN compexpr @@ -822,6 +909,7 @@ primary : literal if ($4) $2 = NEW_ENSURE($2, $4); $$ = $2; } + fixpos($$, $2); } | LPAREN compexpr ')' { @@ -840,6 +928,25 @@ primary : literal END { $$ = NEW_CLASS($2, $5, $3); + fixpos($$, $3); + local_pop(); + cref_pop(); + class_nest--; + } + | CLASS LSHFT expr term + { + if (cur_mid || in_single) + yyerror("class definition in method body"); + + class_nest++; + cref_push(); + local_push(); + } + compexpr + END + { + $$ = NEW_SCLASS($3, $6); + fixpos($$, $3); local_pop(); cref_pop(); class_nest--; @@ -856,6 +963,7 @@ primary : literal END { $$ = NEW_MODULE($2, $4); + fixpos($$, $4); local_pop(); cref_pop(); class_nest--; @@ -872,6 +980,7 @@ primary : literal END { $$ = NEW_DEFN($2, $4, $5, class_nest?0:1); + fixpos($$, $4); local_pop(); cur_mid = 0; } @@ -887,6 +996,7 @@ primary : literal END { $$ = NEW_DEFS($2, $5, $7, $8); + fixpos($$, $2); local_pop(); in_single--; } @@ -902,6 +1012,7 @@ if_tail : opt_else { value_expr($2); $$ = NEW_IF(cond($2), $4, $5); + fixpos($$, $2); } opt_else : /* none */ @@ -942,6 +1053,7 @@ iter_do_block : DO END { $$ = NEW_ITER($3, 0, $4); + fixpos($$, $3?$3:$4); dyna_pop($2); } @@ -953,6 +1065,7 @@ iter_block : '{' compexpr '}' { $$ = NEW_ITER($3, 0, $4); + fixpos($$, $3?$3:$4); dyna_pop($2); } @@ -974,11 +1087,13 @@ iterator : IDENTIFIER method_call : operation '(' call_args ')' { $$ = NEW_FCALL($1, $3); + fixpos($$, $3); } | primary '.' operation '(' call_args ')' { value_expr($1); $$ = NEW_CALL($1, $3, $5); + fixpos($$, $1); } | primary '.' operation { @@ -989,6 +1104,7 @@ method_call : operation '(' call_args ')' { value_expr($1); $$ = NEW_CALL($1, $3, $5); + fixpos($$, $1); } case_body : WHEN args then @@ -1005,6 +1121,7 @@ rescue : RESCUE opt_args term compexpr rescue { $$ = NEW_RESBODY($2, $4, $5); + fixpos($$, $2?$2:$4); } | /* none */ { @@ -1131,12 +1248,13 @@ f_opt : IDENTIFIER '=' arg { if (!is_local_id($1)) yyerror("formal argument must be local variable"); - $$ = asignable($1, $3); + $$ = assignable($1, $3); } f_optarg : f_opt { $$ = NEW_BLOCK($1); + $$->nd_end = $$; } | f_optarg ',' f_opt { @@ -1298,6 +1416,8 @@ yyerror(msg) static int newline_seen; +int rb_in_compile = 0; + static NODE* yycompile(f) char *f; @@ -1307,7 +1427,9 @@ yycompile(f) newline_seen = 0; sourcefile = strdup(f); eval_tree = 0; + rb_in_compile = 1; n = yyparse(); + rb_in_compile = 0; if (n == 0) return eval_tree; return 0; @@ -1340,7 +1462,7 @@ compile_file(f, file, start) return yycompile(f); } -int +static int nextc() { int c; @@ -1357,7 +1479,7 @@ nextc() return -1; } } - c = *lex_p++; + c = (unsigned char)*lex_p++; return c; } @@ -1375,7 +1497,7 @@ pushback(c) #define toklen() tokidx #define toklast() (tokidx>0?tokenbuf[tokidx-1]:0) -char* +static char* newtok() { tokidx = 0; @@ -1384,12 +1506,13 @@ newtok() tokenbuf = ALLOC_N(char, 60); } if (toksiz > 1024) { + toksiz = 60; REALLOC_N(tokenbuf, char, 60); } return tokenbuf; } -void +static void tokadd(c) char c; { @@ -1432,18 +1555,19 @@ read_escape() case '0': case '1': case '2': case '3': /* octal constant */ case '4': case '5': case '6': case '7': - pushback(c); { char buf[3]; int i; + pushback(c); for (i=0; i<3; i++) { - buf[i] = nextc(); - if (buf[i] == -1) goto eof; - if (buf[i] < '0' || '7' < buf[i]) { - pushback(buf[i]); + c = nextc(); + if (c == -1) goto eof; + if (c < '0' || '7' < c) { + pushback(c); break; } + buf[i] = c; } c = scan_oct(buf, i+1, &i); } @@ -1514,11 +1638,11 @@ parse_regx(term) int term; { register int c; + char kcode = 0; + int once = 0; int casefold = 0; int in_brack = 0; int re_start = sourceline; - int once = 0; - int quote = 0; NODE *list = 0; newtok(); @@ -1604,19 +1728,29 @@ parse_regx(term) regx_end: for (;;) { - c = nextc(); - if (c == 'i') { + switch (c = nextc()) { + case 'i': casefold = 1; - } - else if (c == 'o') { + break; + case 'o': once = 1; - } - else { - pushback(c); break; + case 'n': + kcode = 2; + break; + case 'e': + kcode = 4; + break; + case 's': + kcode = 6; + break; + default: + pushback(c); + goto end_options; } } + end_options: tokfix(); lex_state = EXPR_END; if (list) { @@ -1625,12 +1759,12 @@ parse_regx(term) list_append(list, NEW_STR(ss)); } nd_set_type(list, once?NODE_DREGX_ONCE:NODE_DREGX); - list->nd_cflag = casefold; + list->nd_cflag = kcode | casefold; yylval.node = list; return DREGEXP; } else { - yylval.val = reg_new(tok(), toklen(), casefold); + yylval.val = reg_new(tok(), toklen(), kcode | casefold); return REGEXP; } } @@ -1715,14 +1849,12 @@ static int parse_qstring(term) int term; { - int quote = 0; int strstart; int c; strstart = sourceline; newtok(); while ((c = nextc()) != term) { - qstr_retry: if (c == -1) { sourceline = strstart; Error("unterminated string meets end of file"); @@ -1811,6 +1943,10 @@ arg_ambiguous() Warning("ambiguous first argument; make sure"); } +#ifndef atof +double atof(); +#endif + static int yylex() { @@ -1819,7 +1955,7 @@ yylex() struct kwtable *low = kwtable, *mid, *high = LAST(kwtable); if (newline_seen) { - sourceline++; + sourceline+=newline_seen; newline_seen = 0; } @@ -1848,6 +1984,27 @@ retry: } /* fall through */ case '\n': + /* skip embedded rd document */ + if ((c = nextc()) == '=' && + strncmp(lex_p, "begin", 5) == 0 && + (lex_p[5] == '\n' || lex_p[5] == '\r')) { + for (;;) { + if (c == -1) return 0; + c = nextc(); + if (c != '\n') continue; + c = nextc(); + if (c != '=') continue; + if (strncmp(lex_p, "end", 3) == 0 && + (lex_p[3] == '\n' || lex_p[3] == '\r')) { + lex_p += 3; /* sizeof "end" */ + break; + } + } + } + else { + pushback(c); + } + if (lex_state == EXPR_BEG || lex_state == EXPR_FNAME) { sourceline++; goto retry; @@ -1877,7 +2034,7 @@ retry: lex_state = EXPR_BEG; return STAR; } - if (lex_state == EXPR_BEG) { + if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { return STAR; } lex_state = EXPR_BEG; @@ -1895,6 +2052,25 @@ retry: return '!'; case '=': + if (lex_p == lex_pbeg + 1) { + /* skip embedded rd document */ + if (strncmp(lex_p, "begin", 5) == 0 && isspace(lex_p[5])) { + lex_p = lex_pend; + for (;;) { + if (c == -1) return 0; + c = nextc(); + if (c != '\n') continue; + c = nextc(); + if (c != '=') continue; + if (strncmp(lex_p, "end", 3) == 0 && isspace(lex_p[3])) { + lex_p = lex_pend; + break; + } + } + goto retry; + } + } + lex_state = EXPR_BEG; if ((c = nextc()) == '=') { if ((c = nextc()) == '=') { @@ -2085,11 +2261,16 @@ retry: is_float = seen_point = seen_e = 0; lex_state = EXPR_END; newtok(); + if (c == '-' || c == '+') { + tokadd(c); + c = nextc(); + } if (c == '0') { c = nextc(); if (c == 'x' || c == 'X') { /* hexadecimal */ while (c = nextc()) { + if (c == '_') continue; if (!isxdigit(c)) break; tokadd(c); } @@ -2102,7 +2283,8 @@ retry: /* octal */ do { tokadd(c); - c = nextc(); + while ((c = nextc()) == '_') + ; } while (c >= '0' && c <= '9'); pushback(c); tokfix(); @@ -2121,10 +2303,6 @@ retry: return INTEGER; } } - if (c == '-' || c == '+') { - tokadd(c); - c = nextc(); - } for (;;) { switch (c) { @@ -2178,8 +2356,6 @@ retry: pushback(c); tokfix(); if (is_float) { - double atof(); - yylval.val = float_new(atof(tok())); return FLOAT; } @@ -2248,7 +2424,7 @@ retry: } } lex_state = EXPR_BEG; - return c; + return '~'; case '(': if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { @@ -2311,7 +2487,16 @@ retry: quotation: if (!isalnum(c)) { term = c; - c = '"'; + switch (c) { + case '\'': + c = 'q'; break; + case '/': + c = 'r'; break; + case '`': + c = 'x'; break; + default: + c = 'Q';break; + } } else { term = nextc(); @@ -2387,6 +2572,15 @@ retry: yylval.id = rb_intern(tok()); return GVAR; + case '-': + tokadd('$'); + tokadd(c); + c = nextc(); + tokadd(c); + tokfix(); + yylval.id = rb_intern(tok()); + return GVAR; + case '&': /* $&: last match */ case '`': /* $`: string before last match */ case '\'': /* $': string after last match */ @@ -2468,11 +2662,10 @@ retry: /* See if it is a reserved word. */ while (low <= high) { mid = low + (high - low)/2; - if (( c = strcmp(mid->name, tok())) == 0) { + if ((c = strcmp(mid->name, tok())) == 0) { enum lex_state state = lex_state; lex_state = mid->state; - if (state != EXPR_BEG - && state != EXPR_BEG) { + if (state != EXPR_BEG) { if (mid->id == IF) return IF_MOD; if (mid->id == UNLESS) return UNLESS_MOD; if (mid->id == WHILE) return WHILE_MOD; @@ -2512,6 +2705,7 @@ retry: result = IDENTIFIER; } } + tokfix(); yylval.id = rb_intern(tok()); return result; } @@ -2525,7 +2719,6 @@ str_extend(list, term) int c; VALUE ss; NODE *node; - ID id; int nest; c = nextc(); @@ -2579,6 +2772,7 @@ str_extend(list, term) if (c == term) { list_append(list, NEW_STR(str_new2("#$"))); pushback(c); + newtok(); return list; } switch (c) { @@ -2618,7 +2812,6 @@ str_extend(list, term) switch (c) { case -1: if (nest > 0) { - bad_sub: Error("bad substitution in string"); newtok(); return list; @@ -2647,7 +2840,6 @@ str_extend(list, term) newtok(); return list; } - add_char: default: tokadd(c); break; @@ -2665,11 +2857,11 @@ str_extend(list, term) } NODE* -newnode(type, a0, a1, a2) +node_newnode(type, a0, a1, a2) enum node_type type; NODE *a0, *a1, *a2; { - NODE *n = (NODE*)newobj(); + NODE *n = (NODE*)rb_newobj(); n->flags |= T_NODE; nd_set_type(n, type); @@ -2690,41 +2882,79 @@ nodetype(node) /* for debug */ return (enum node_type)nd_type(node); } +int +nodeline(node) + NODE *node; +{ + return nd_line(node); +} + +static NODE* +newline_node(node) + NODE *node; +{ + NODE *nl = 0; + if (node) { + nl = NEW_NEWLINE(node); + fixpos(nl, node); + nl->nd_nth = nd_line(node); + } + return nl; +} + +static void +fixpos(node, orig) + NODE *node, *orig; +{ + if (!node) return; + if (!orig) return; + node->file = orig->file; + nd_set_line(node, nd_line(orig)); +} + static NODE* block_append(head, tail) NODE *head, *tail; { extern int verbose; - NODE *last; + NODE *end; if (tail == 0) return head; if (head == 0) return tail; - if (nd_type(head) != NODE_BLOCK) - head = last = NEW_BLOCK(head); + if (nd_type(head) != NODE_BLOCK) { + end = NEW_BLOCK(head); + end->nd_end = end; + fixpos(end, head); + head = end; + } else { - last = head; - while (last->nd_next) { - last = last->nd_next; - } + end = head->nd_end; } if (verbose) { - switch (nd_type(last->nd_head)) { + NODE *nd = end->nd_head; + newline: + switch (nd_type(nd)) { case NODE_RETURN: Warning("statement not reached"); break; + case NODE_NEWLINE: + nd = nd->nd_next; + goto newline; + default: break; } } - + if (nd_type(tail) != NODE_BLOCK) { tail = NEW_BLOCK(tail); + tail->nd_end = tail; } - last->nd_next = tail; - head->nd_alen += tail->nd_alen; + end->nd_next = tail; + head->nd_end = tail->nd_end; return head; } @@ -2792,7 +3022,7 @@ gettable(id) if (local_id(id)) return NEW_LVAR(id); if (dyna_var_defined(id)) return NEW_DVAR(id); /* method call without arguments */ - return NEW_FCALL(id, 0); + return NEW_VCALL(id); } else if (is_global_id(id)) { return NEW_GVAR(id); @@ -2808,7 +3038,7 @@ gettable(id) } static NODE* -asignable(id, val) +assignable(id, val) ID id; NODE *val; { @@ -2818,11 +3048,12 @@ asignable(id, val) yyerror("Can't change the value of self"); } else if (id == NIL) { - yyerror("Can't asign to nil"); + yyerror("Can't assign to nil"); } else if (is_local_id(id)) { - if (local_id(id) || !dyna_in_block()) + if (local_id(id) || !dyna_in_block()) { lhs = NEW_LASGN(id, val); + } else{ dyna_var_asgn(id, TRUE); lhs = NEW_DASGN(id, val); @@ -2836,7 +3067,7 @@ asignable(id, val) } else if (is_const_id(id)) { if (cur_mid || in_single) - yyerror("dynamic constant asignment"); + yyerror("dynamic constant assignment"); lhs = NEW_CASGN(id, val); } else { @@ -2918,6 +3149,9 @@ value_expr(node) case NODE_IF: return value_expr(node->nd_body) && value_expr(node->nd_else); + case NODE_NEWLINE: + return value_expr(node->nd_next); + default: return TRUE; } @@ -2934,6 +3168,8 @@ cond0(node) switch (type) { case NODE_DREGX: case NODE_DREGX_ONCE: + local_cnt('_'); + local_cnt('~'); return call_op(NEW_GVAR(rb_intern("$_")),MATCH,1,node); case NODE_DOT2: @@ -2946,6 +3182,8 @@ cond0(node) case NODE_LIT: if (TYPE(node->nd_lit) == T_REGEXP) { + local_cnt('_'); + local_cnt('~'); return NEW_MATCH(node); } default: @@ -2966,26 +3204,28 @@ cond(node) case NODE_GASGN: case NODE_IASGN: case NODE_CASGN: - Warning("asignment in condition"); + Warning("assignment in condition"); break; + case NODE_NEWLINE: + node->nd_next = cond0(node->nd_next); + return node; + default: + break; } - node = cond0(node); - if (type == NODE_CALL && node->nd_mid == '!') { - if (node->nd_args || node->nd_recv == 0) { - Bug("method `!' called with wrong # of operand"); - } - node->nd_recv = cond0(node->nd_recv); - } - return node; + return cond0(node); } static NODE* cond2(node) NODE *node; { + enum node_type type; + node = cond(node); - if (nd_type(node) == NODE_LIT && FIXNUM_P(node->nd_lit)) { + type = nd_type(node); + if (type == NODE_NEWLINE) node = node->nd_next; + if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) { return call_op(node,EQ,1,NEW_GVAR(rb_intern("$."))); } return node; @@ -2998,13 +3238,14 @@ logop(type, left, right) { value_expr(left); - return newnode(type, cond(left), cond(right)); + return node_newnode(type, cond(left), cond(right)); } st_table *new_idhash(); static struct local_vars { ID *tbl; + int nofree; int cnt; int dlev; struct local_vars *prev; @@ -3017,6 +3258,7 @@ local_push() local = ALLOC(struct local_vars); local->prev = lvtbl; + local->nofree = 0; local->cnt = 0; local->tbl = 0; local->dlev = 0; @@ -3029,13 +3271,17 @@ local_pop() struct local_vars *local = lvtbl; lvtbl = local->prev; - if (local->tbl) local->tbl[0] = local->cnt; + if (local->tbl) { + local->tbl[0] = local->cnt; + if (!local->nofree) free(local->tbl); + } free(local); } static ID* local_tbl() { + lvtbl->nofree = 1; return lvtbl->tbl; } @@ -3051,6 +3297,7 @@ local_cnt(id) if (lvtbl->tbl[cnt] == id) return cnt-1; } + if (lvtbl->tbl == 0) { lvtbl->tbl = ALLOC_N(ID, 2); lvtbl->tbl[0] = 0; @@ -3080,12 +3327,7 @@ static void top_local_init() { local_push(); - if (the_scope->local_tbl) { - lvtbl->cnt = the_scope->local_tbl[0]; - } - else { - lvtbl->cnt = 0; - } + lvtbl->cnt = the_scope->local_tbl?the_scope->local_tbl[0]:0; if (lvtbl->cnt > 0) { lvtbl->tbl = ALLOC_N(ID, lvtbl->cnt+1); MEMCPY(lvtbl->tbl, the_scope->local_tbl, ID, lvtbl->cnt+1); @@ -3109,25 +3351,33 @@ top_local_setup() i = lvtbl->tbl[0]; if (i < len) { - if (the_scope->flag == SCOPE_ALLOCA) { - VALUE *vars = the_scope->local_vars; - the_scope->local_vars = ALLOC_N(VALUE, len); - if (vars) { - MEMCPY(the_scope->local_vars, vars, VALUE, i); - memclear(the_scope->local_vars+i, len-i); + if (i == 0 || the_scope->flag == SCOPE_ALLOCA) { + VALUE *vars = ALLOC_N(VALUE, len+1); + if (the_scope->local_vars) { + *vars++ = the_scope->local_vars[-1]; + MEMCPY(vars, the_scope->local_vars, VALUE, i); + memclear(vars+i, len-i); } else { - memclear(the_scope->local_vars, len); + *vars++ = 0; + memclear(vars, len); } - the_scope->flag = SCOPE_MALLOC; + the_scope->local_vars = vars; + the_scope->flag |= SCOPE_MALLOC; } else { - REALLOC_N(the_scope->local_vars, VALUE, len); + VALUE *vars = the_scope->local_vars-1; + REALLOC_N(vars, VALUE, len+1); + the_scope->local_vars = vars+1; memclear(the_scope->local_vars+i, len-i); - free(the_scope->local_tbl); } lvtbl->tbl[0] = len; + if (the_scope->local_tbl && the_scope->local_vars[-1] == 0) { + free(the_scope->local_tbl); + } + the_scope->local_vars[-1] = 0; the_scope->local_tbl = lvtbl->tbl; + lvtbl->nofree = 1; } } local_pop(); @@ -3157,8 +3407,6 @@ dyna_in_block() static void cref_pop() { - NODE *cref = cur_cref; - cur_cref = cur_cref->nd_next; } @@ -3199,10 +3447,10 @@ static struct op_tbl rb_op_tbl[] = { '/', "/", '%', "%", POW, "**", - UPLUS, "+(unary)", - UMINUS, "-(unary)", UPLUS, "+@", UMINUS, "-@", + UPLUS, "+(unary)", + UMINUS, "-(unary)", '|', "|", '^', "^", '&', "&", @@ -3280,13 +3528,13 @@ rb_intern(name) break; } } - if (id == 0) Bug("Unknown operator `%s'", name); + if (id == 0) NameError("Unknown operator `%s'", name); break; } last = strlen(name)-1; if (name[last] == '=') { - /* attribute asignment */ + /* attribute assignment */ char *buf = ALLOCA_N(char,last+1); strncpy(buf, name, last); @@ -3362,24 +3610,20 @@ rb_id2name(id) return ok.name; } -static int -const_check(id, val, class) +int +rb_is_const_id(id) ID id; - VALUE val; - struct RClass *class; { - if (is_const_id(id) && rb_const_defined(class, id)) { - Warning("constant redefined for %s", rb_class2name(class)); - return ST_STOP; - } - return ST_CONTINUE; + if (is_const_id(id)) return TRUE; + return FALSE; } -void -rb_const_check(class, module) - struct RClass *class, *module; +int +rb_is_instance_id(id) + ID id; { - st_foreach(module->iv_tbl, const_check, class); + if (is_instance_id(id)) return TRUE; + return FALSE; } void -- cgit v1.2.3