modula2.el 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. ; Modula-2 editing support package
  2. ; Author Mick Jordan
  3. ; amended Peter Robinson
  4. ; ported to GNU Michael Schmidt
  5. ;;;From: "Michael Schmidt" <michael@pbinfo.UUCP>
  6. ;;;Modified by Tom Perrine <Perrin@LOGICON.ARPA> (TEP)
  7. ;;; Added by TEP
  8. (defvar m2-mode-syntax-table nil
  9. "Syntax table in use in Modula-2-mode buffers.")
  10. (if m2-mode-syntax-table
  11. ()
  12. (let ((table (make-syntax-table)))
  13. (modify-syntax-entry ?\\ "\\" table)
  14. (modify-syntax-entry ?\( ". 1" table)
  15. (modify-syntax-entry ?\) ". 4" table)
  16. (modify-syntax-entry ?* ". 23" table)
  17. (modify-syntax-entry ?+ "." table)
  18. (modify-syntax-entry ?- "." table)
  19. (modify-syntax-entry ?= "." table)
  20. (modify-syntax-entry ?% "." table)
  21. (modify-syntax-entry ?< "." table)
  22. (modify-syntax-entry ?> "." table)
  23. (modify-syntax-entry ?\' "\"" table)
  24. (setq m2-mode-syntax-table table)))
  25. ;;; Added by TEP
  26. (defvar m2-mode-map nil
  27. "Keymap used in Modula-2 mode.")
  28. (if m2-mode-map ()
  29. (let ((map (make-sparse-keymap)))
  30. (define-key map "\^i" 'm2-tab)
  31. (define-key map "\C-cb" 'm2-begin)
  32. (define-key map "\C-cc" 'm2-case)
  33. (define-key map "\C-cd" 'm2-definition)
  34. (define-key map "\C-ce" 'm2-else)
  35. (define-key map "\C-cf" 'm2-for)
  36. (define-key map "\C-ch" 'm2-header)
  37. (define-key map "\C-ci" 'm2-if)
  38. (define-key map "\C-cm" 'm2-module)
  39. (define-key map "\C-cl" 'm2-loop)
  40. (define-key map "\C-co" 'm2-or)
  41. (define-key map "\C-cp" 'm2-procedure)
  42. (define-key map "\C-c\C-w" 'm2-with)
  43. (define-key map "\C-cr" 'm2-record)
  44. (define-key map "\C-cs" 'm2-stdio)
  45. (define-key map "\C-ct" 'm2-type)
  46. (define-key map "\C-cu" 'm2-until)
  47. (define-key map "\C-cv" 'm2-var)
  48. (define-key map "\C-cw" 'm2-while)
  49. (define-key map "\C-cx" 'm2-export)
  50. (define-key map "\C-cy" 'm2-import)
  51. (define-key map "\C-c{" 'm2-begin-comment)
  52. (define-key map "\C-c}" 'm2-end-comment)
  53. (define-key map "\C-c\C-z" 'suspend-emacs)
  54. (define-key map "\C-c\C-v" 'm2-visit)
  55. (define-key map "\C-c\C-t" 'm2-toggle)
  56. (define-key map "\C-c\C-l" 'm2-link)
  57. (define-key map "\C-c\C-c" 'm2-compile)
  58. (setq m2-mode-map map)))
  59. (defvar m2-indent 5 "*This variable gives the indentation in Modula-2-Mode")
  60. (defun modula-2-mode ()
  61. "This is a mode intended to support program development in Modula-2.
  62. All control constructs of Modula-2 can be reached by typing
  63. Control-C followed by the first character of the construct.
  64. \\{m2-mode-map}
  65. Control-c b begin Control-c c case
  66. Control-c d definition Control-c e else
  67. Control-c f for Control-c h header
  68. Control-c i if Control-c m module
  69. Control-c l loop Control-c o or
  70. Control-c p procedure Control-c Control-w with
  71. Control-c r record Control-c s stdio
  72. Control-c t type Control-c u until
  73. Control-c v var Control-c w while
  74. Control-c x export Control-c y import
  75. Control-c { begin-comment Control-c } end-comment
  76. Control-c Control-z suspend-emacs Control-c Control-t toggle
  77. Control-c Control-c compile Control-x ` next-error
  78. Control-c Control-l link
  79. m2-indent controls the number of spaces for each indentation."
  80. (interactive)
  81. (kill-all-local-variables)
  82. (use-local-map m2-mode-map)
  83. (setq major-mode 'modula-2-mode)
  84. (setq mode-name "Modula-2")
  85. (make-local-variable 'comment-column)
  86. (setq comment-column 41)
  87. (make-local-variable 'end-comment-column)
  88. (setq end-comment-column 75)
  89. (set-syntax-table m2-mode-syntax-table)
  90. (make-local-variable 'paragraph-start)
  91. (setq paragraph-start (concat "^$\\|" page-delimiter))
  92. (make-local-variable 'paragraph-separate)
  93. (setq paragraph-separate paragraph-start)
  94. ; (make-local-variable 'indent-line-function)
  95. ; (setq indent-line-function 'c-indent-line)
  96. (make-local-variable 'require-final-newline)
  97. (setq require-final-newline t)
  98. (make-local-variable 'comment-start)
  99. (setq comment-start "(* ")
  100. (make-local-variable 'comment-end)
  101. (setq comment-end " *)")
  102. (make-local-variable 'comment-column)
  103. (setq comment-column 41)
  104. (make-local-variable 'comment-start-skip)
  105. (setq comment-start-skip "/\\*+ *")
  106. (make-local-variable 'comment-indent-hook)
  107. (setq comment-indent-hook 'c-comment-indent)
  108. (make-local-variable 'parse-sexp-ignore-comments)
  109. (setq parse-sexp-ignore-comments t)
  110. (run-hooks 'm2-mode-hook))
  111. (defun m2-tab ()
  112. "Indent to next tab stop."
  113. (interactive)
  114. (indent-to (* (1+ (/ (current-indentation) m2-indent)) m2-indent)))
  115. (defun m2-begin ()
  116. "Insert a BEGIN keyword and indent for the next line."
  117. (interactive)
  118. (insert "BEGIN")
  119. (m2-newline)
  120. (m2-tab))
  121. (defun m2-case ()
  122. "Build skeleton CASE statment, prompting for the <expression>."
  123. (interactive)
  124. (insert "CASE " (read-string ": ") " OF")
  125. (m2-newline)
  126. (m2-newline)
  127. (insert "END (* case *);")
  128. (end-of-line 0)
  129. (m2-tab))
  130. (defun m2-definition ()
  131. "Build skeleton DEFINITION MODULE, prompting for the <module name>."
  132. (interactive)
  133. (insert "DEFINITION MODULE ")
  134. (let ((name (read-string "Name: ")))
  135. (insert name ";\n\n\n\nEND " name ".\n"))
  136. (previous-line 3))
  137. (defun m2-else ()
  138. "Insert ELSE keyword and indent for next line."
  139. (interactive)
  140. (m2-newline)
  141. (backward-delete-char-untabify m2-indent ())
  142. (insert "ELSE")
  143. (m2-newline)
  144. (m2-tab))
  145. (defun m2-for ()
  146. "Build skeleton FOR loop statment, prompting for the loop parameters."
  147. (interactive)
  148. (insert "FOR " (read-string ": ") " TO " ": ")
  149. (let ((by (read-string ": ")))
  150. (if (not (string-equal by ""))
  151. (insert " BY " by)))
  152. (insert " DO")
  153. (m2-newline)
  154. (m2-newline)
  155. (insert "END (* for *);")
  156. (end-of-line 0)
  157. (m2-tab))
  158. (defun m2-header ()
  159. "Insert a comment block containing the module title, author, etc."
  160. (interactive)
  161. (insert "(*\n Title: \t")
  162. (insert (read-string "Title: "))
  163. (insert "\n Created:\t")
  164. (insert (current-time-string))
  165. (insert "\n Author: \t")
  166. (insert (user-full-name))
  167. (insert (concat "\n\t\t<" (user-login-name) "@" (system-name) ">\n"))
  168. (insert "*)\n\n"))
  169. (defun m2-if ()
  170. "Insert skeleton IF statment, prompting for <boolean-expression>."
  171. (interactive)
  172. (insert "IF " (read-string "<boolean-expression>: ") " THEN")
  173. (m2-newline)
  174. (m2-newline)
  175. (insert "END (* if *);")
  176. (end-of-line 0)
  177. (m2-tab))
  178. (defun m2-loop ()
  179. "Build skeleton LOOP (with END)."
  180. (interactive)
  181. (insert "LOOP")
  182. (m2-newline)
  183. (m2-newline)
  184. (insert "END (* loop *);")
  185. (end-of-line 0)
  186. (m2-tab))
  187. (defun m2-module ()
  188. "Build skeleton IMPLEMENTATION MODULE, prompting for <module-name>."
  189. (interactive)
  190. (insert "IMPLEMENTATION MODULE ")
  191. (let ((name (read-string "Name: ")))
  192. (insert name ";\n\n\n\nEND " name ".\n"))
  193. (previous-line 3))
  194. (defun m2-or ()
  195. (interactive)
  196. (m2-newline)
  197. (backward-delete-char-untabify m2-indent)
  198. (insert "|")
  199. (m2-newline)
  200. (m2-tab))
  201. (defun m2-procedure ()
  202. (interactive)
  203. (insert "PROCEDURE ")
  204. (let ((name (read-string "Name: " ))
  205. args)
  206. (insert name " (")
  207. (insert (read-string "Arguments: ") ")")
  208. (setq args (read-string "Result Type: "))
  209. (if (not (string-equal args ""))
  210. (insert " : " args))
  211. (insert ";")
  212. (m2-newline)
  213. (insert "BEGIN")
  214. (m2-newline)
  215. (m2-newline)
  216. (insert "END ")
  217. (insert name)
  218. (insert ";")
  219. (end-of-line 0)
  220. (m2-tab)))
  221. (defun m2-with ()
  222. (interactive)
  223. (insert "WITH ")
  224. (insert (read-string ": "))
  225. (insert " DO")
  226. (m2-newline)
  227. (m2-newline)
  228. (insert "END (* with *);")
  229. (end-of-line 0)
  230. (m2-tab))
  231. (defun m2-record ()
  232. (interactive)
  233. (insert "RECORD")
  234. (m2-newline)
  235. (m2-newline)
  236. (insert "END (* record *);")
  237. (end-of-line 0)
  238. (m2-tab))
  239. (defun m2-stdio ()
  240. (interactive)
  241. (insert "
  242. >FROM TextIO IMPORT
  243. WriteCHAR, ReadCHAR, WriteINTEGER, ReadINTEGER,
  244. WriteCARDINAL, ReadCARDINAL, WriteBOOLEAN, ReadBOOLEAN,
  245. WriteREAL, ReadREAL, WriteBITSET, ReadBITSET,
  246. WriteBasedCARDINAL, ReadBasedCARDINAL, WriteChars, ReadChars,
  247. WriteString, ReadString, WhiteSpace, EndOfLine;
  248. >FROM SysStreams IMPORT sysIn, sysOut, sysErr;
  249. "))
  250. (defun m2-type ()
  251. (interactive)
  252. (insert "TYPE")
  253. (m2-newline)
  254. (m2-tab))
  255. (defun m2-until ()
  256. (interactive)
  257. (insert "REPEAT")
  258. (m2-newline)
  259. (m2-newline)
  260. (insert "UNTIL ")
  261. (insert (read-string ": ") ";")
  262. (end-of-line 0)
  263. (m2-tab))
  264. (defun m2-var ()
  265. (interactive)
  266. (m2-newline)
  267. (insert "VAR")
  268. (m2-newline)
  269. (m2-tab))
  270. (defun m2-while ()
  271. (interactive)
  272. (insert "WHILE ")
  273. (insert (read-string ": "))
  274. (insert " DO")
  275. (m2-newline)
  276. (m2-newline)
  277. (insert "END (* while *);")
  278. (end-of-line 0)
  279. (m2-tab))
  280. (defun m2-export ()
  281. (interactive)
  282. (insert "EXPORT QUALIFIED "))
  283. (defun m2-import ()
  284. (interactive)
  285. (insert "FROM ")
  286. (insert (read-string "Module: "))
  287. (insert " IMPORT "))
  288. (defun m2-begin-comment ()
  289. (interactive)
  290. (if (not (bolp))
  291. (indent-to comment-column 0))
  292. (insert "(* "))
  293. (defun m2-end-comment ()
  294. (interactive)
  295. (if (not (bolp))
  296. (indent-to end-comment-column))
  297. (insert "*)"))
  298. (defun m2-compile ()
  299. (interactive)
  300. (setq modulename (buffer-name))
  301. (compile (concat "m2c " modulename)))
  302. (defun m2-link ()
  303. (interactive)
  304. (setq modulename (buffer-name))
  305. (compile (concat "m2l " (substring modulename 0 -4))))
  306. (defun execute-monitor-command (command)
  307. (let* ((shell shell-file-name)
  308. (csh (equal (file-name-nondirectory shell) "csh")))
  309. (call-process shell nil t t "-cf" (concat "exec " command))))
  310. (defun m2-visit ()
  311. (interactive)
  312. (let ((deffile nil)
  313. (modfile nil)
  314. modulename)
  315. (save-excursion
  316. (setq modulename
  317. (read-string "Module name: "))
  318. (switch-to-buffer "*Command Execution*")
  319. (execute-monitor-command (concat "m2whereis " modulename))
  320. (goto-char (point-min))
  321. (condition-case ()
  322. (progn (re-search-forward "\\(.*\\.def\\) *$")
  323. (setq deffile (buffer-substring (match-beginning 1)
  324. (match-end 1))))
  325. (search-failed ()))
  326. (condition-case ()
  327. (progn (re-search-forward "\\(.*\\.mod\\) *$")
  328. (setq modfile (buffer-substring (match-beginning 1)
  329. (match-end 1))))
  330. (search-failed ()))
  331. (if (not (or deffile modfile))
  332. (error "I can find neither definition nor implementation of %s"
  333. modulename)))
  334. (cond (deffile
  335. (find-file deffile)
  336. (if modfile
  337. (save-excursion
  338. (find-file modfile))))
  339. (modfile
  340. (find-file modfile)))))
  341. (defun m2-toggle ()
  342. "Toggle between .mod and .def files for the module."
  343. (interactive)
  344. (cond ((string-equal (substring (buffer-name) -4) ".def")
  345. (find-file-other-window
  346. (concat (substring (buffer-name) 0 -4) ".mod")))
  347. ((string-equal (substring (buffer-name) -4) ".mod")
  348. (find-file-other-window
  349. (concat (substring (buffer-name) 0 -4) ".def")))))