egg-980703.
[elisp/egg.git] / its.el
diff --git a/its.el b/its.el
index b01b06b..4f9d71c 100644 (file)
--- a/its.el
+++ b/its.el
     map))
 
 (defmacro define-its-state-machine (map name indicator lang doc &rest exprs)
-  `(progn
-     (eval-when (eval compile)
-       (let ((its-current-map 'its-temporaly-map)
-            (its-temporaly-map (its-new-map ,name ,indicator ,lang)))
-        ,@exprs
-        (setq ,map its-temporaly-map)))
-     (define-its-compiled-map ,map ,doc)))
-
-(defmacro define-its-compiled-map (map doc)
+  (let ((its-current-map map))
+    (set map (its-new-map name indicator
+                          (if (eq (car-safe lang) 'quote) (nth 1 lang) lang)))
+    (eval (cons 'progn exprs)))
   `(defconst ,map ',(symbol-value map) ,doc))
 
 (defmacro define-its-state-machine-append (map &rest exprs)
-  (append
-   `(let ((its-current-map 'its-temporaly-map)
-         (its-temporaly-map ,map)))
-   exprs
-   (list `(setq ,map its-temporaly-map))))
+  `(let ((its-current-map ',map))
+     ,@exprs))
 
 ;;
 ;; Construct State Machine
@@ -579,27 +571,51 @@ BACK \e$B$,\e(B(\e$BIi$N\e(B)\e$B@0?t$N;~$O\e(B, OUTPUT \e$B$r=PNO$7$?8e\e(B, BACK \e$B$N
 \e$BLa$C$FF0$/$b$N$H$9$k!#JQ495,B'$O$b$C$H$b:G6a$K\e(B its-define-state-machine
 \e$B$5$l$?JQ49I=$KEPO?$5$l$k!#\e(B
 Return last state."
-  (let ((state (its-goto-state (substring input 0 -1) nil t))
-       (key (aref input (1- (length input)))))
-    (if (and (its-get-next-state state key) (not enable-overwrite))
-       (error "Duplicated definition (%s)" input)
-      (its-make-next-state state key input output back))))
+  (let ((state (its-goto-state input (if enable-overwrite t 'dup-check))))
+    (its-set-output state output)
+    (its-set-kst state back)
+    state))
+
+(defun its-defrule* (input output &optional enable-overwrite)
+  (let* ((state (its-goto-state input (if enable-overwrite t 'dup-check))))
+    (its-set-kst state nil)
+    (its-set-interim-terminal-state state output)
+    state))
+
+(defvar its-parent-states)
 
-(defun its-goto-state (input &optional initial-state build-if-none)
+(defun its-goto-state (input &optional build-if-none)
   (let ((len (length input))
        (i 0)
-       (state (or initial-state
-                  (its-get-start-state (symbol-value its-current-map)))))
+       (state (its-get-start-state (symbol-value its-current-map)))
+       brand-new next-state key)
+    (setq its-parent-states nil)
     (while (< i len)
-      (setq state
-           (or (its-get-next-state state (aref input i))
-               (if build-if-none
-                   (let ((keyseq (substring input 0 (1+ i))))
-                     (its-make-next-state state (aref input i) keyseq keyseq))
-                  (error "No such state (%s)" input)))
-           i (1+ i)))
+      (setq its-parent-states (cons state its-parent-states)
+           key (aref input i)
+           i (1+ i)
+           next-state (its-get-next-state state key))
+      (cond
+       (next-state
+       (setq state next-state))
+       ((null build-if-none)
+       (error "No such state (%s)" input))
+       (t 
+       (if (not (or brand-new (= i 1) (its-get-kst/t state)))
+           (its-set-interim-terminal-state state))
+       (setq state (its-make-next-state state key
+                                        (concat (its-get-output state)
+                                                (list key)))
+             brand-new t))))
+    (if (and (eq build-if-none 'dup-check) (null brand-new))
+       (error "Duplicated definition (%s)" input))
     state))
 
+(defun its-set-interim-terminal-state (state &optional output)
+  (or output (setq output (its-get-output state)))
+  (its-make-next-state state -1 output)
+  (its-defrule-otherwise state output))
+
 (defun its-defoutput (input display)
   (let ((state (its-goto-state input)))
     (its-set-output state display)))
@@ -621,12 +637,11 @@ Return last state."
     (its-define-otherwise state
                          (its-make-otherwise output class+back))))
 
-(defun its-defrule* (input output)
-  (let ((state (its-defrule input output)))
-    (its-defrule-otherwise state output)))
-
-(defun its-make-next-state (state key keyseq output &optional back)
-  (let ((next-state (its-new-state output keyseq back))
+(defun its-make-next-state (state key output &optional back)
+  (let ((next-state (its-new-state output
+                                  (concat (its-get-keyseq state)
+                                          (if (> key 0) (list key)))
+                                  back))
        (kst (its-get-kst/t state)))
     (cond
      ((null kst)