home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / p / plbin.zip / pl / lisp / qpfindpred.el < prev    next >
Lisp/Scheme  |  1992-05-26  |  10KB  |  362 lines

  1. ;;;  SCCS: @(#)90/12/04 qpfindpred.el    2.3
  2. ;;;            Quintus Prolog - GNU Emacs Interface
  3. ;;;                         Support Functions
  4. ;;;
  5. ;;;                Consolidated by Sitaram Muralidhar
  6. ;;;
  7. ;;;                   sitaram@quintus.com
  8. ;;;              Quintus Computer Systems, Inc.
  9. ;;;                  2 May 1989       
  10. ;;;
  11. ;;; This file defines functions that support the Quintus Prolog - GNU Emacs
  12. ;;; interface.
  13. ;;;
  14. ;;;                   Acknowledgements
  15. ;;;
  16. ;;;
  17. ;;; This interface was made possible by contributions from Fernando
  18. ;;; Pereira and various customers of Quintus Computer Systems, Inc.,
  19. ;;; based on code for Quintus's Unipress Emacs interface.
  20. ;;; 
  21.  
  22. (defmacro error-occurred (&rest body)
  23.   (list 'condition-case nil (cons 'progn (append body '(nil))) '(error t)))
  24.  
  25. (defun find-pred ()
  26.   (interactive)
  27.   (let 
  28.       (term-start
  29.        term-type
  30.        target-functor
  31.        target-arity 
  32.        backward-predicate-beginning
  33.        backward-predicate-end 
  34.        (continue t)
  35.        (saw-first-clause (find-potential-clause)))
  36.  
  37.     (get-clause-info)
  38.     (setq target-functor *functor*)
  39.     (setq target-arity *arity*)
  40.  
  41.     (setq backward-predicate-end (mark))
  42.     (setq backward-predicate-beginning (dot))
  43.  
  44.     (previous-line 1)
  45.     (while (and continue
  46.                 (not saw-first-clause)
  47.                 (not (error-occurred
  48.                       (setq saw-first-clause (find-potential-clause))
  49.                       (get-clause-info)))
  50.                 )
  51.       (if (and (string-equal *functor* target-functor) 
  52.                (= *arity* target-arity))
  53.           (progn 
  54.             (setq backward-predicate-beginning (dot))
  55.             (previous-line 1))
  56.         (setq continue nil)
  57.         )
  58.       )
  59.  
  60.     (goto-char backward-predicate-end)
  61.     (setq continue t)
  62.     (while (and continue
  63.                 (not (error-occurred (get-clause-info)))
  64.                 )
  65.       (if (and (string-equal *functor* target-functor)
  66.                (= *arity* target-arity))
  67.           (progn 
  68.             (setq backward-predicate-end (mark))
  69.             (exchange-dot-and-mark))
  70.         (setq continue nil)))
  71.  
  72.     (goto-char backward-predicate-beginning)
  73.     (set-mark (point))
  74.     (goto-char backward-predicate-end)
  75.     )
  76.   )
  77.  
  78. (defun forward-to-clause-end  (term-start)
  79.   (let ((continue t)
  80.         (token-type (next-token)))
  81.     (while continue
  82.       (cond 
  83.        ((string-equal token-type "eof")
  84.         (goto-char term-start)
  85.         (BadFind "Can't find the end of this term"))
  86.         ((string-equal token-type "stop")
  87.         (setq continue nil))
  88.         (t (setq token-type (next-token)))
  89.         )
  90.       )
  91.     )
  92.   )
  93.  
  94. (defun forward-to-clause-end-heuristic (term-start)
  95.   (if (not (re-search-forward "[^-+*/\\^<>=`~:.?@#$&]\\.[\001- \177]" nil t))
  96.       (progn
  97.         (goto-char term-start)
  98.         (BadFind "Can't find the end of this term")
  99.         )
  100.     )
  101.   (while (within-comment)               ;  doesn't work with '%' style comments
  102.     (if (not (re-search-forward "[^-+*/\\^<>=`~:.?@#$&]\\.[\001- \177]" nil t))
  103.         (progn
  104.           (goto-char term-start)
  105.           (BadFind "Can't find the end of this term")
  106.           )
  107.       )
  108.     )
  109.   )
  110.  
  111.  
  112. (defun arity-overhead-for-grammar-rule  (term-start)
  113.   (let
  114.       ((token-type (next-token))
  115.        (token (region-to-string))
  116.        return)
  117.  
  118.     (cond 
  119.      ((string-equal token ":-")
  120.       (forward-to-clause-end term-start)
  121.       (setq return 0))
  122.      ((string-equal token-type "stop")
  123.       (setq return 0))
  124.      (t
  125.       (if (grammar-rule token-type token)
  126.           (progn 
  127.             (forward-to-clause-end term-start)
  128.             (setq return 2)
  129.             )
  130.         (progn 
  131.           (goto-char term-start)
  132.           (BadFind "Can't determine what type of clause this is")
  133.           )
  134.         )
  135.       )
  136.      )
  137.     return
  138.     )
  139.   )
  140.  
  141. (defun BadFind (message)
  142.   (sleep-for-millisecs 10)
  143.   (error message))
  144.  
  145. (defun grammar-rule  (mgr-token-type mgr-token)
  146.   (let (return
  147.         (continue t))
  148.     (while continue
  149.       (cond
  150.        ((string-equal mgr-token "-->")
  151.         (setq continue nil)
  152.         (setq return t))
  153.        ((or (string-equal mgr-token-type "stop")
  154.             (string-equal mgr-token-type "eof"))
  155.         (setq continue nil)
  156.         (setq return nil))
  157.         (t
  158.          (setq mgr-token-type (next-token))
  159.          (setq mgr-token (region-to-string))
  160.          )
  161.     )
  162.     )
  163.     return
  164. ))
  165.  
  166. ; The following code finds the first line less than or equal to the current
  167. ;    line which has a non-layout character in the first column or the
  168. ;    first column does not start a comment ('%' or '/*'), end a comment
  169. ;    ('*/'), or is within a comment.
  170. ;
  171.  
  172. (defun find-potential-clause ()
  173.   (let
  174.       ((continue t)
  175.        (original-dot (dot))
  176.        char 
  177.        (return))
  178.     (while continue
  179.       (beginning-of-line)
  180.       (setq char (following-char))
  181.       (if (or 
  182.            (or (and (>= char ?\001) (<= char ?  )) (= char ?\177))  ; layout
  183.            (looking-at "%\\|/\\*\\|\\*/")  ; '%' or '/*' or '*/'
  184.            (within-comment)
  185.            (eobp)
  186.            )
  187.           (if (bobp)
  188.               (progn 
  189.                 (goto-char original-dot)
  190.                 (BadFind "Cannot find a valid line to start the procedure, command or query")
  191.                 )
  192.             (previous-line 1)
  193.             )
  194.         (progn 
  195.           (if (bobp)
  196.               (setq return t)
  197.            )
  198.            (setq continue nil)
  199.        )
  200.     )
  201.     )
  202.     return
  203. ))
  204.  
  205. (defun get-clause-info ()
  206.   (let ((term-start (dot))
  207.         (token-type (next-token))
  208.         (token (region-to-string)))
  209.     (cond 
  210.      ((string-equal token-type "atom")
  211.       (if (or (string-equal token ":-")
  212.               (string-equal token "?-"))
  213.           (progn 
  214.             (setq *functor* token)
  215.             (setq *arity* 1)
  216.             (forward-to-clause-end term-start)
  217.             (set-mark (point))
  218.             (goto-char term-start)
  219.             )
  220.         (progn 
  221.           (setq *functor* token)
  222.           (setq *arity* 0)
  223.           (setq *arity* 
  224.                 (+ *arity* (arity-overhead-for-grammar-rule term-start)))
  225.           (set-mark (point))
  226.           (goto-char term-start)
  227.           )
  228.         )
  229.       )
  230.      ((string-equal token-type "functor")
  231.       (setq *functor* token)
  232.       (setq *arity* (all-arity term-start))
  233.       (set-mark (point))
  234.       (goto-char term-start)
  235.       )
  236.       ((string-equal token-type "eof")
  237.        (setq *functor* "end_of_file")
  238.        (setq *arity* -1)
  239.        (set-mark (point))
  240.        (goto-char term-start)
  241.        )
  242.       (t (BadFind "Wrong term type to start clause, command, or query"))
  243.       )
  244.     )
  245. )
  246.  
  247. (defun BadArity (message)
  248.   (error message)
  249. )
  250.  
  251. (defun all-arity (term-start)
  252.   (let ((temp-arity (head-arity)))
  253.     (+ temp-arity (arity-overhead-for-grammar-rule term-start))
  254.   )
  255. )
  256.  
  257. ; This function assumes that you are looking at the left parenthesis
  258. ; immediately following the atom of a complex predicate.  It knows that
  259. ; it's looking at the parenthesis because the tokenizer looks ahead to
  260. ; it, '(', to determine that it is just read a "functor" instead of just an 
  261. ; "atom".
  262. ;        foo(X,Y) ...
  263. ;           ^
  264.  
  265. (defun head-arity ()
  266.   (let  ((state 0)
  267.          (stack)
  268.          (arity 1)
  269.          token-type
  270.          token
  271.          (original-dot (dot)))
  272.  
  273.     (if (= (following-char) ?\( )
  274.     (forward-char)
  275.       (BadArity "Can't start calculating arity at this point")
  276.       )
  277.  
  278.     (while (not (= state 2))
  279.       (setq token-type (next-token))
  280.       (setq token (region-to-string))
  281.  
  282.       (if (or (string-equal token-type "stop")
  283.               (string-equal token-type "eof")
  284.               )
  285.           (progn 
  286.             (goto-char original-dot)
  287.             (BadArity "Unclosed parenthesis.")
  288.             )
  289.         )
  290.       (cond 
  291.        ((= state 0)
  292.         (cond
  293.          ((string-equal token "(")
  294.           (progn 
  295.             (setq stack (cons ")" stack))
  296.             (setq state 1)
  297.             ))
  298.          ((string-equal token "[")
  299.           (progn 
  300.             (setq stack (cons "]" stack))
  301.             (setq state 1)
  302.             ))
  303.          ((string-equal token "{")
  304.           (progn 
  305.             (setq stack (cons "}" stack))
  306.             (setq state 1)
  307.             ))
  308.          ((string-equal token ")")
  309.           (setq state 2))
  310.          ((or (string-equal token "]") (string-equal token "}"))
  311.           (BadArity "Mismatched parentheses."))
  312.          ((string-equal token ",")
  313.           (setq arity (+ arity 1)))
  314.      ))
  315.        ((= state 1)
  316.         (cond
  317.          ((string-equal token "(") (setq stack (cons ")" stack)))
  318.          ((string-equal token "[") (setq stack (cons "]" stack)))
  319.          ((string-equal token "{") (setq stack (cons "}" stack)))
  320.          ((or 
  321.            (string-equal token ")") 
  322.            (string-equal token "]") 
  323.            (string-equal token "}"))
  324.           (if (not (string-equal (car stack) token))
  325.               (BadArity "Mismatched parentheses.")
  326.             )
  327.           (setq stack (cdr stack))
  328.           (if (null stack)
  329.               (setq state 0)
  330.             )
  331.           )
  332.      )
  333.         )
  334.        )
  335.       )
  336.     arity
  337.     )
  338.   )
  339.  
  340. (defun within-comment ()
  341.   (let ((original-dot (dot)) (return))
  342.     (if (not (re-search-backward "/\\*\\|\\*/" nil t)) ; '/*' or '*/'
  343.         (setq return nil)
  344.         (if (= (following-char) ?*)      ; found '*/'
  345.             (progn 
  346.               (goto-char original-dot)
  347.               (setq return nil)
  348.               )
  349.           (progn
  350.             (goto-char original-dot)
  351.             (setq return (search-forward "*/" nil t))
  352.             (goto-char original-dot)
  353.             )
  354.           )
  355.       )
  356.     return
  357.     )
  358. )
  359.