diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | bignum.c | 7 | ||||
-rw-r--r-- | eval.c | 10 | ||||
-rw-r--r-- | gc.c | 2 | ||||
-rw-r--r-- | numeric.c | 34 | ||||
-rw-r--r-- | parse.y | 14 | ||||
-rw-r--r-- | re.c | 4 | ||||
-rw-r--r-- | ruby.h | 4 | ||||
-rw-r--r-- | sample/inf-ruby.el | 280 | ||||
-rw-r--r-- | sample/ruby-mode.el | 33 | ||||
-rw-r--r-- | string.c | 7 |
12 files changed, 357 insertions, 51 deletions
@@ -1,5 +1,17 @@ +Thu Apr 9 18:24:58 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * string.c (str_cmp): do not depend on sentinel at the end of the + strings. + + * string.c (str_chomp_bang): forgot to set the sentinel. + Wed Apr 8 00:59:13 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + * bignum.c (big2int): converted int may be too big to fit in + signed int. + + * parse.y (arg): `foo += 1' should not cause an error. + * variable.c (rb_const_defined): returned false even if the constant is defined at the top level. @@ -169,6 +169,7 @@ sample/from.rb sample/fullpath.rb sample/getopts.test sample/goodfriday.rb +sample/inf-ruby.el sample/less.rb sample/list.rb sample/list2.rb @@ -350,14 +350,17 @@ big2int(x) UINT len = RBIGNUM(x)->len; USHORT *ds; - if (len > sizeof(long)/sizeof(USHORT)) - ArgError("Bignum too big to convert into fixnum"); + if (len > sizeof(INT)/sizeof(USHORT)) + ArgError("bignum too big to convert into `int'"); ds = BDIGITS(x); num = 0; while (len--) { num = BIGUP(num); num += ds[len]; } + if ((INT)num < 0) { + ArgError("bignum too big to convert into `int'"); + } if (!RBIGNUM(x)->sign) return -num; return num; } @@ -3831,17 +3831,21 @@ f_eval(argc, argv, self) VALUE *argv; VALUE self; { - VALUE src, scope, vfile, line; + VALUE src, scope, vfile, vline; char *file = "(eval)"; + int line = 0; - rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &line); + rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline); if (!NIL_P(vfile)) { Check_Type(vfile, T_STRING); file = RSTRING(vfile)->ptr; } + if (!NIL_P(vline)) { + line = NUM2INT(vline); + } Check_SafeStr(src); - return eval(self, src, scope, file, NUM2INT(line)); + return eval(self, src, scope, file, line); } static VALUE @@ -49,10 +49,12 @@ xmalloc(size) void *mem; if (size == 0) size = 1; +#if 0 malloc_memories += size; if (malloc_memories > GC_MALLOC_LIMIT) { gc_gc(); } +#endif mem = malloc(size); if (!mem) { gc_gc(); @@ -612,21 +612,16 @@ fail_to_integer(val) rb_class2name(CLASS_OF(val))); } -int +INT num2int(val) VALUE val; { - if (NIL_P(val)) return 0; + if (NIL_P(val)) { + TypeError("no implicit conversion from nil"); + } switch (TYPE(val)) { case T_FIXNUM: - if (sizeof(int) < sizeof(INT)) { - INT i = FIX2INT(val); - if (INT_MIN < i && i < INT_MAX) { - return i; - } - TypeError("Fixnum too big to convert into `int'"); - } return FIX2INT(val); case T_FLOAT: @@ -645,10 +640,6 @@ num2int(val) TypeError("no implicit conversion from string"); return Qnil; /* not reached */ - case T_NIL: - TypeError("no implicit conversion from nil"); - return Qnil; /* not reached */ - default: val = rb_rescue(to_integer, val, fail_to_integer, val); if (!obj_is_kind_of(val, cInteger)) { @@ -664,19 +655,12 @@ num2fix(val) { INT v; - if (NIL_P(val)) return INT2FIX(0); - switch (TYPE(val)) { - case T_FIXNUM: - return val; + if (FIXNUM_P(val)) return val; - case T_FLOAT: - case T_BIGNUM: - default: - v = num2int(val); - if (!FIXABLE(v)) - Fail("integer %d out of range of Fixnum", v); - return INT2FIX(v); - } + v = num2int(val); + if (!FIXABLE(v)) + Fail("integer %d out of range of fixnum", v); + return INT2FIX(v); } static VALUE @@ -570,10 +570,16 @@ arg : variable '=' arg | variable OP_ASGN arg { value_expr($3); - if (is_local_id($1)&&!local_id($1)&&dyna_in_block()) - dyna_var_asgn($1, TRUE); - $$ = assignable($1, call_op(gettable($1), $2, 1, $3)); - fixpos($$, $3); + if (is_local_id($1)) { + if (local_id($1)||!dyna_in_block()) { + local_cnt($1); + } + else if (!dyna_var_defined($1)) { + dyna_var_asgn($1, TRUE); + } + } + $$ = assignable($1,call_op(gettable($1),$2,1,$3)); + fixpos($$, $3); } | primary '[' aref_args ']' OP_ASGN arg { @@ -913,6 +913,10 @@ reg_regsub(str, src, regs) if (no == 0) continue; break; + case '\\': + str_cat(val, s-1, 1); + continue; + default: str_cat(val, s-2, 2); continue; @@ -170,8 +170,8 @@ void rb_check_safe_str _((VALUE)); #define Check_SafeStr(v) rb_check_safe_str((VALUE)(v)) void rb_secure _((int)); -int num2int _((VALUE)); -#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int(x)) +INT num2int _((VALUE)); +#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int((VALUE)x)) double num2dbl _((VALUE)); #define NUM2DBL(x) num2dbl((VALUE)(x)) diff --git a/sample/inf-ruby.el b/sample/inf-ruby.el new file mode 100644 index 0000000000..c7d5d363d7 --- /dev/null +++ b/sample/inf-ruby.el @@ -0,0 +1,280 @@ +;;; -*-Emacs-Lisp-*- +;;; +;;; $Id: inf-ruby.el,v 1.2 1998/04/09 07:53:42 senda Exp $ +;;; $Author: senda $ +;;; $Date: 1998/04/09 07:53:42 $ +;;; +;;; Inferior Ruby Mode - ruby process in a buffer. +;;; adapted from cmuscheme.el +;;; +;;; +;;; How to use it ? +;;; +;;; (0) this program need 'rbc.rb'. It must install as named 'rbc', +;;; set mode to executable (ex. chmod a+x rbc) and place in your +;;; command search path. +;;; +;;; (1) modify .emacs to use ruby-mode +;;; +;;; ex) +;;; +;;; (autoload 'ruby-mode "ruby-mode" +;;; "Mode for editing ruby source files") +;;; (setq auto-mode-alist +;;; (append '(("\\.rb$" . ruby-mode)) auto-mode-alist)) +;;; (setq interpreter-mode-alist (append '(("^#!.*ruby" . ruby-mode)) +;;; interpreter-mode-alist)) +;;; +;;; (2) set to road inf-ruby and set inf-ruby key definition in ruby-mode. +;;; +;;; (autoload 'run-ruby "inf-ruby" +;;; "Run an inferior Ruby process") +;;; (autoload 'inf-ruby-keys "inf-ruby" +;;; "Set local key defs for inf-ruby in ruby-mode") +;;; (add-hook 'ruby-mode-hook +;;; '(lambda () +;;; (inf-ruby-keys) +;;; )) +;;; +;;; HISTORY +;;; senda - 8 Apr 1998: Created. +;;; $Log: inf-ruby.el,v $ +;;; Revision 1.2 1998/04/09 07:53:42 senda +;;; remove M-C-x in inferior-ruby-mode +;;; +;;; Revision 1.1 1998/04/09 07:28:36 senda +;;; Initial revision +;;; +;;; + +(require 'comint) + +(require 'ruby-mode) +(autoload 'ruby-beginning-of-defun "ruby-mode") +(autoload 'ruby-end-of-defun "ruby-mode") + +(defvar inferior-ruby-mode-hook nil + "*Hook for customising inferior-ruby mode.") +(defvar inferior-ruby-mode-map nil + "*Mode map for inferior-ruby-mode") + +(cond ((not inferior-ruby-mode-map) + (setq inferior-ruby-mode-map + (copy-keymap comint-mode-map)) +; (define-key inferior-ruby-mode-map "\M-\C-x" ;gnu convention +; 'ruby-send-definition) +; (define-key inferior-ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp) + (define-key inferior-ruby-mode-map "\C-c\C-l" 'ruby-load-file) +)) + +(defun inf-ruby-keys () + "Set local key defs for inf-ruby in ruby-mode" + (define-key ruby-mode-map "\M-\C-x" 'ruby-send-definition) +; (define-key ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp) + (define-key ruby-mode-map "\C-c\C-e" 'ruby-send-definition) + (define-key ruby-mode-map "\C-c\M-e" 'ruby-send-definition-and-go) + (define-key ruby-mode-map "\C-c\C-r" 'ruby-send-region) + (define-key ruby-mode-map "\C-c\M-r" 'ruby-send-region-and-go) + (define-key ruby-mode-map "\C-c\C-z" 'switch-to-ruby) + (define-key ruby-mode-map "\C-c\C-l" 'ruby-load-file) +) + +(defvar ruby-buffer nil "current ruby (actually rbc) process buffer.") + +(defun inferior-ruby-mode () + "Major mode for interacting with an inferior ruby (rbc) process. + +The following commands are available: +\\{inferior-ruby-mode-map} + +A ruby process can be fired up with M-x run-ruby. + +Customisation: Entry to this mode runs the hooks on comint-mode-hook and +inferior-ruby-mode-hook (in that order). + +You can send text to the inferior ruby process from other buffers containing +Ruby source. + switch-to-ruby switches the current buffer to the ruby process buffer. + ruby-send-definition sends the current definition to the ruby process. + ruby-send-region sends the current region to the ruby process. + + ruby-send-definition-and-go, ruby-send-region-and-go, + switch to the ruby process buffer after sending their text. +For information on running multiple processes in multiple buffers, see +documentation for variable ruby-buffer. + +Commands: +Return after the end of the process' output sends the text from the + end of process to point. +Return before the end of the process' output copies the sexp ending at point + to the end of the process' output, and sends it. +Delete converts tabs to spaces as it moves back. +Tab indents for ruby; with argument, shifts rest + of expression rigidly with the current line. +C-M-q does Tab on each line starting within following expression. +Paragraphs are separated only by blank lines. # start comments. +If you accidentally suspend your process, use \\[comint-continue-subjob] +to continue it." + (interactive) + (comint-mode) + ;; Customise in inferior-ruby-mode-hook + ;(setq comint-prompt-regexp "^[^>\n]*>+ *") + (setq comint-prompt-regexp "^rbc.> *") ; rbc prompt ..... + ;;(scheme-mode-variables) + (ruby-mode-variables) + (setq major-mode 'inferior-ruby-mode) + (setq mode-name "Inferior Ruby") + (setq mode-line-process '(":%s")) + (use-local-map inferior-ruby-mode-map) + (setq comint-input-filter (function ruby-input-filter)) + (setq comint-get-old-input (function ruby-get-old-input)) + (run-hooks 'inferior-ruby-mode-hook)) + +(defvar inferior-ruby-filter-regexp "" ;;"\\`\\s *\\S ?\\S ?\\s *\\'" + "*Input matching this regexp are not saved on the history list. +Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters.") + +(defun ruby-input-filter (str) + "Don't save anything matching inferior-ruby-filter-regexp" + (not (string-match inferior-ruby-filter-regexp str))) + +(defun ruby-rbc-backward-sexp () + "backward-sexp for ruby. +it search rbc0> prompt and set point to the beginning of prompt. +so it only valid in rbc." + (let ((P "^rbc0> *")) + (re-search-backward P) + )) + +(defun ruby-get-old-input () + "Snarf the sexp ending at point" + (save-excursion + (let ((end (point))(P "^rbc.> *")) + (ruby-rbc-backward-sexp) + (replace-in-string (buffer-substring (point) end) P "") + ))) + +(defun ruby-args-to-list (string) + (let ((where (string-match "[ \t]" string))) + (cond ((null where) (list string)) + ((not (= where 0)) + (cons (substring string 0 where) + (ruby-args-to-list (substring string (+ 1 where) + (length string))))) + (t (let ((pos (string-match "[^ \t]" string))) + (if (null pos) + nil + (ruby-args-to-list (substring string pos + (length string))))))))) + +(defvar ruby-program-name "rbc --noreadline" + "*Program invoked by the run-ruby command") + +(defun run-ruby (cmd) + "Run an inferior Ruby process, input and output via buffer *ruby*. +If there is a process already running in `*ruby*', switch to that buffer. +With argument, allows you to edit the command line (default is value +of `ruby-program-name'). Runs the hooks `inferior-ruby-mode-hook' +\(after the `comint-mode-hook' is run). +\(Type \\[describe-mode] in the process buffer for a list of commands.)" + + (interactive (list (if current-prefix-arg + (read-string "Run Ruby: " ruby-program-name) + ruby-program-name))) + (if (not (comint-check-proc "*ruby*")) + (let ((cmdlist (ruby-args-to-list cmd))) + (set-buffer (apply 'make-comint "ruby" (car cmdlist) + nil (cdr cmdlist))) + (inferior-ruby-mode))) + (setq ruby-program-name cmd) + (setq ruby-buffer "*ruby*") + (pop-to-buffer "*ruby*")) + +(defun ruby-send-region (start end) + "Send the current region to the inferior Ruby process." + (interactive "r") + (comint-send-region (ruby-proc) start end) + (comint-send-string (ruby-proc) "\n")) + +(defun ruby-send-definition () + "Send the current definition to the inferior Ruby process." + (interactive) + (save-excursion + (ruby-end-of-defun) + (let ((end (point))) + (ruby-beginning-of-defun) + (ruby-send-region (point) end)))) + +;(defun ruby-send-last-sexp () +; "Send the previous sexp to the inferior Ruby process." +; (interactive) +; (ruby-send-region (save-excursion (backward-sexp) (point)) (point))) + +(defun switch-to-ruby (eob-p) + "Switch to the ruby process buffer. +With argument, positions cursor at end of buffer." + (interactive "P") + (if (get-buffer ruby-buffer) + (pop-to-buffer ruby-buffer) + (error "No current process buffer. See variable ruby-buffer.")) + (cond (eob-p + (push-mark) + (goto-char (point-max))))) + +(defun ruby-send-region-and-go (start end) + "Send the current region to the inferior Ruby process. +Then switch to the process buffer." + (interactive "r") + (ruby-send-region start end) + (switch-to-ruby t)) + +(defun ruby-send-definition-and-go () + "Send the current definition to the inferior Ruby. +Then switch to the process buffer." + (interactive) + (ruby-send-definition) + (switch-to-ruby t)) + +(defvar ruby-source-modes '(ruby-mode) + "*Used to determine if a buffer contains Ruby source code. +If it's loaded into a buffer that is in one of these major modes, it's +considered a ruby source file by ruby-load-file. +Used by these commands to determine defaults.") + +(defvar ruby-prev-l/c-dir/file nil + "Caches the last (directory . file) pair. +Caches the last pair used in the last ruby-load-file command. +Used for determining the default in the +next one.") + +(defun ruby-load-file (file-name) + "Load a Ruby file into the inferior Ruby process." + (interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file + ruby-source-modes t)) ; T because LOAD + ; needs an exact name + (comint-check-source file-name) ; Check to see if buffer needs saved. + (setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name) + (file-name-nondirectory file-name))) + (comint-send-string (ruby-proc) (concat "(load \"" + file-name + "\"\)\n"))) + +(defun ruby-proc () + "Returns the current ruby process. See variable ruby-buffer." + (let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode) + (current-buffer) + ruby-buffer)))) + (or proc + (error "No current process. See variable ruby-buffer")))) + +;;; Do the user's customisation... + +(defvar inf-ruby-load-hook nil + "This hook is run when inf-ruby is loaded in. +This is a good place to put keybindings.") + +(run-hooks 'inf-ruby-load-hook) + +(provide 'inf-ruby) + +;;; inf-ruby.el ends here diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el index 5d5af3437d..e33a164bd9 100644 --- a/sample/ruby-mode.el +++ b/sample/ruby-mode.el @@ -110,19 +110,7 @@ (defvar ruby-indent-level 2 "*Indentation of ruby statements.") -(defun ruby-mode () - "Major mode for editing ruby scripts. -\\[ruby-indent-command] properly indents subexpressions of multi-line -class, module, def, if, while, for, do, and case statements, taking -nesting into account. - -The variable ruby-indent-level controls the amount of indentation. -\\{ruby-mode-map}" - (interactive) - (kill-all-local-variables) - (use-local-map ruby-mode-map) - (setq mode-name "ruby") - (setq major-mode 'ruby-mode) +(defun ruby-mode-variables () (set-syntax-table ruby-mode-syntax-table) (setq local-abbrev-table ruby-mode-abbrev-table) (make-local-variable 'indent-line-function) @@ -138,7 +126,22 @@ The variable ruby-indent-level controls the amount of indentation. (make-variable-buffer-local 'comment-start-skip) (setq comment-start-skip "\\(^\\|\\s-\\);?#+ *") (make-local-variable 'parse-sexp-ignore-comments) - (setq parse-sexp-ignore-comments t) + (setq parse-sexp-ignore-comments t)) + +(defun ruby-mode () + "Major mode for editing ruby scripts. +\\[ruby-indent-command] properly indents subexpressions of multi-line +class, module, def, if, while, for, do, and case statements, taking +nesting into account. + +The variable ruby-indent-level controls the amount of indentation. +\\{ruby-mode-map}" + (interactive) + (kill-all-local-variables) + (use-local-map ruby-mode-map) + (setq mode-name "ruby") + (setq major-mode 'ruby-mode) + (ruby-mode-variable) (run-hooks 'ruby-mode-hook)) (defun ruby-current-indentation () @@ -666,3 +669,5 @@ An end of a defun is found by moving forward from the beginning of one." (add-hook 'ruby-mode-hook (lambda () (setq font-lock-keywords ruby-font-lock-keywords)))))) + +(provide 'ruby-mode) @@ -44,6 +44,7 @@ str_new(ptr, len) if (rb_safe_level() >= 3) { FL_SET(str, STR_TAINT); } + str->ptr = 0; str->len = len; str->orig = 0; str->ptr = ALLOC_N(char,len+1); @@ -483,7 +484,9 @@ str_cmp(str1, str2) len = min(RSTRING(str1)->len, RSTRING(str2)->len); retval = memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr, len); if (retval == 0) { - retval = RSTRING(str1)->ptr[len] - RSTRING(str2)->ptr[len]; + if (RSTRING(str1)->len == RSTRING(str2)->len) return 0; + if (RSTRING(str1)->len > RSTRING(str2)->len) return 1; + return -1; } if (retval == 0) return 0; if (retval > 0) return 1; @@ -2288,6 +2291,7 @@ str_chomp_bang(argc, argv, str) } if (len < RSTRING(str)->len) { RSTRING(str)->len = len; + RSTRING(str)->ptr[len] = '\0'; return str; } return Qnil; @@ -2299,6 +2303,7 @@ str_chomp_bang(argc, argv, str) (rslen <= 1 || memcmp(RSTRING(rs)->ptr, p+len-rslen, rslen) == 0)) { RSTRING(str)->len -= rslen; + RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; return str; } return Qnil; |