home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / intercal.zip / intercal.el < prev    next >
Lisp/Scheme  |  1994-09-22  |  7KB  |  177 lines

  1. ;;; intercal.el -- mode for editing INTERCAL code
  2.  
  3. ;; This mode was written by Eric S. Raymond <esr@snark.thyrsus.com>
  4. ;; for the C-INTERCAL distribution, and is copyrighted by him 1992.  Free
  5. ;; redistribution encouraged.  Someday, maybe, this will be made part of GNU.
  6.  
  7. ;; This mode provides abbrevs for C-INTERCAL's statements, including COME FROM.
  8. ;; These abbrevs are context-sensitive and will generate either verb or gerund
  9. ;; form as appropriate.  The keys RET, ( and * are also bound in useful ways.
  10.  
  11. ;; The intercal-politesse-level adjustment purports to assist the hapless
  12. ;; INTERCAL programmer in meeting INTERCAL's Miss Manners requirement.  In
  13. ;; INTERCAL-72 and C-INTERCAL releases after 0.7, no fewer than 1/5 and no
  14. ;; more than 1/3 of the program statements must contain a PLEASE to gratify
  15. ;; the iron whim of the INTERCAL compiler; this mode assists by randomly
  16. ;; expanding some fraction of the "do" abbrevs typed to PLEASE DO or DO PLEASE.
  17. ;; The intercal-politesse-level constant is the denominator of this fraction.
  18.  
  19. ;;     $Id: intercal.el,v 1.4 1994/09/22 09:08:00 esr Exp $
  20.  
  21. (defconst intercal-politesse-level 4
  22.   "Fraction of DOs that are automagically expanded to PLEASE DO, DO PLEASE.")
  23.  
  24. (defvar intercal-mode-map nil 
  25.   "Keymap for INTERCAL mode.")
  26. (if intercal-mode-map
  27.     nil
  28.   (setq intercal-mode-map (make-sparse-keymap))
  29.   (define-key intercal-mode-map "\t" 'tab-to-tab-stop)
  30.   (define-key intercal-mode-map "\r" 'intercal-return)
  31.   (define-key intercal-mode-map "(" 'intercal-paren)
  32.   (define-key intercal-mode-map "*" 'intercal-splat)
  33.   (define-key intercal-mode-map "\177" 'backward-delete-char-untabify)
  34.   )
  35.  
  36. (defvar intercal-mode-syntax-table nil
  37.   "Syntax table in use in Intercal-mode buffers.")
  38.  
  39. (if intercal-mode-syntax-table
  40.     nil
  41.   (let ((table (make-syntax-table)))
  42.     (modify-syntax-entry ?\\ "\\" table)
  43.     (modify-syntax-entry ?+ "." table)
  44.     (modify-syntax-entry ?- "." table)
  45.     (modify-syntax-entry ?= "." table)
  46.     (modify-syntax-entry ?% "." table)
  47.     (modify-syntax-entry ?< "." table)
  48.     (modify-syntax-entry ?> "." table)
  49.     (modify-syntax-entry ?& "." table)
  50.     (modify-syntax-entry ?| "." table)
  51.     (modify-syntax-entry ?\' "\"" table)
  52.     (setq intercal-mode-syntax-table table)))
  53.  
  54. (defvar intercal-mode-abbrev-table nil
  55.   "*Abbrev table in use in Intercal-mode buffers.")
  56. (if intercal-mode-abbrev-table
  57.     nil
  58.   (define-abbrev-table 'intercal-mode-abbrev-table ())
  59.   (define-abbrev intercal-mode-abbrev-table "pl"  "PLEASE" nil)
  60.   (define-abbrev intercal-mode-abbrev-table "ne"  "" 'intercal-ne-abbrev)
  61.   (define-abbrev intercal-mode-abbrev-table "fo"  "" 'intercal-fo-abbrev)
  62.   (define-abbrev intercal-mode-abbrev-table "res" "" 'intercal-res-abbrev)
  63.   (define-abbrev intercal-mode-abbrev-table "st"  "" 'intercal-st-abbrev)
  64.   (define-abbrev intercal-mode-abbrev-table "ret" "" 'intercal-ret-abbrev)
  65.   (define-abbrev intercal-mode-abbrev-table "ig"  "" 'intercal-ig-abbrev)
  66.   (define-abbrev intercal-mode-abbrev-table "rem" "" 'intercal-rem-abbrev)
  67.   (define-abbrev intercal-mode-abbrev-table "ab"  "" 'intercal-ab-abbrev)
  68.   (define-abbrev intercal-mode-abbrev-table "rei" "" 'intercal-rei-abbrev)
  69.   (define-abbrev intercal-mode-abbrev-table "gi"  "" 'intercal-gi-abbrev)
  70.   (define-abbrev intercal-mode-abbrev-table "rea" "" 'intercal-rea-abbrev)
  71.   (define-abbrev intercal-mode-abbrev-table "wr"  "" 'intercal-wr-abbrev)
  72.   (define-abbrev intercal-mode-abbrev-table "co"  "" 'intercal-co-abbrev)
  73.   (define-abbrev intercal-mode-abbrev-table "do"  "" 'intercal-do-abbrev)
  74.  )
  75.  
  76. (defun use-gerund ()
  77.   (save-excursion
  78.     (beginning-of-line)
  79.     (or (looking-at ".*ABSTAIN") (looking-at ".*REINSTATE"))))
  80.  
  81. (defmacro make-intercal-abbrev (sym gerund verb)
  82.   (list 'defun sym '() (list 'insert (list 'if '(use-gerund) gerund verb))))
  83.  
  84. (make-intercal-abbrev intercal-ne-abbrev "NEXTING" "NEXT")
  85. (make-intercal-abbrev intercal-fo-abbrev "FORGETTING" "FORGET")
  86. (make-intercal-abbrev intercal-res-abbrev "RESUMING" "RESUME")
  87. (make-intercal-abbrev intercal-st-abbrev "STASHING" "STASH")
  88. (make-intercal-abbrev intercal-ret-abbrev "RETRIEVING" "RETRIEVE")
  89. (make-intercal-abbrev intercal-ig-abbrev "IGNORING" "IGNORE")
  90. (make-intercal-abbrev intercal-rem-abbrev "REMEMBERING" "REMEMBER")
  91. (make-intercal-abbrev intercal-ab-abbrev "ABSTAINING" "ABSTAIN FROM")
  92. (make-intercal-abbrev intercal-rei-abbrev "REINSTATING" "REINSTATE")
  93. (make-intercal-abbrev intercal-gi-abbrev "GIVING UP" "GIVE UP")
  94. (make-intercal-abbrev intercal-rea-abbrev "READING IN" "READ IN")
  95. (make-intercal-abbrev intercal-wr-abbrev "WRITING OUT" "WRITE OUT")
  96. (make-intercal-abbrev intercal-co-abbrev "COMING FROM" "COME FROM")
  97.  
  98. (defun intercal-do-abbrev ()
  99.   "Emit a DO (usually).  Occasionally, emit DO PLEASE or PLEASE DO."
  100.   (insert
  101.    (if (zerop (% (random) intercal-politesse-level))
  102.        (if (% (random) 2) "PLEASE DO" "DO PLEASE")
  103.      "DO")
  104.    ))
  105.  
  106. (defun intercal-return ()
  107.   "Insert LFD + tab, to bring us back to code-indent level."
  108.   (interactive)
  109.   (if (eolp) (delete-horizontal-space))
  110.   (insert "\n")
  111.   (tab-to-tab-stop)
  112.   )
  113.  
  114. (defun intercal-paren ()
  115.   "Generate an INTERCAL label."
  116.   (interactive)
  117.   (if (and (bolp) (looking-at "[ \t]\\|$"))
  118.     (insert (format "(%d)"
  119.             (save-restriction
  120.                    (widen)
  121.                    (save-excursion
  122.                  (beginning-of-line)
  123.                  (1+ (count-lines 1 (point))))))
  124.             "\t")
  125.     (insert "(")))
  126.  
  127. (defun intercal-splat ()
  128.   "Begin an INTERCAL comment."
  129.   (interactive)
  130.   (insert "*")
  131.   (forward-char -1)
  132.   (delete-horizontal-space)
  133.   (forward-char 1)
  134.   (insert " ")
  135. )
  136.  
  137. (defun intercal-mode ()
  138.   "A major editing mode for the language Intercal.
  139. It activates the following abbrevs (each one appropriately modified to a
  140. gerund if it occurs on a line with ABSTAIN or REINSTATE).
  141.  
  142. ab   ABSTAIN    co   COME FROM    fo   FORGET    
  143. gi   GIVE UP    ig   IGNORE    ne   NEXT    
  144. rea  READ IN    rei  REINSTATE    rem  REMEMBER    
  145. res  RESUME    ret  RETRIEVE    st   STASH    
  146. wr   WRITE OUT    pl   PLEASE
  147.  
  148. Carriage return takes you to the first tab stop (code indent level).
  149. Certain other single keys are bound to things which may or may not be useful.  
  150. You may consider discovering these one of the pleasures awaiting you in your
  151. discovery of INTERCAL's unique ambience.
  152.  
  153. Turning on Intercal mode calls the value of the variable intercal-mode-hook
  154. with no args, if that value is non-nil."
  155.   (interactive)
  156.   (kill-all-local-variables)
  157.   (use-local-map intercal-mode-map)
  158.   (setq major-mode 'intercal-mode)
  159.   (setq mode-name "Intercal")
  160.   (setq local-abbrev-table intercal-mode-abbrev-table)
  161.   (set-syntax-table intercal-mode-syntax-table)
  162.   (make-local-variable 'comment-start)
  163.   (setq comment-start "* ")
  164.   (make-local-variable 'comment-end)
  165.   (setq comment-end "")
  166.   (make-local-variable 'comment-column)
  167.   (setq comment-column 32)
  168.   (make-local-variable 'require-final-newline)
  169.   (setq require-final-newline t)
  170.   (setq abbrev-mode t)
  171.   (setq abbrev-all-caps t)
  172.   (run-hooks 'intercal-mode-hook))
  173.  
  174. (provide 'intercal-mode)
  175.  
  176. ;;; intercal.el ends here
  177.