1 ;;; sml-nj.el: Modifies inferior-sml-mode defaults for SML/NJ.
3 ;; Copyright (C) 1997, Matthew J. Morley
8 ;; This file is not part of GNU Emacs, but it is distributed under the
11 ;; ====================================================================
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 2, or (at
16 ;; your option) any later version.
18 ;; This program is distributed in the hope that it will be useful, but
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 ;; General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
25 ;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 ;; ====================================================================
31 ;; To use this library just put
33 ;;(autoload 'sml-smlnj "sml-nj" "Set up and run SML/NJ." t)
35 ;; in your .emacs file. If you only ever use the New Jersey compiler
36 ;; then you might as well put something like
39 ;; '(lambda() "SML mode defaults to SML/NJ"
40 ;; (define-key sml-mode-map "\C-cp" 'sml-smlnj)))
42 ;; for your sml-mode-hook. The command prompts for the program name
43 ;; and any command line options.
45 ;; If you need to reset the default value of sml-program-name, or any
46 ;; of the other compiler variables, put something like
48 ;;(eval-after-load "sml-nj" '(setq sml-program-name "whatever"))
50 ;; in your .emacs -- or (better) you can use the inferior-sml-{load,
51 ;; mode}-hooks to achieve the same ends.
57 ;; std_in:2.1-4.3 Error: operator and operand don't agree (tycon mismatch)
58 ;; std_in:2.1 Error: operator and operand don't agree (tycon mismatch)
60 (defconst sml-smlnj-error-regexp
62 "^[-= ]*\\(.+\\):" ;file name
63 "\\([0-9]+\\)\\.\\([0-9]+\\)" ;start line.column
64 "\\(-\\([0-9]+\\)\\.\\([0-9]+\\)\\)?" ;end line.colum
65 ".+\\(\\(Error\\|Warning\\): .*\\)") ;the message
67 "Default regexp matching SML/NJ error and warning messages.
69 There should be no need to customise this, though you might decide
70 that you aren't interested in Warnings -- my advice would be to modify
71 `sml-error-regexp' explicitly to do that though.
73 If you do customise `sml-smlnj-error-regexp' you may need to modify
74 the function `sml-smlnj-error-parser' (qv).")
76 (defun sml-smlnj-error-parser (pt)
77 "This parses the SML/NJ error message at PT into a 5 element list
79 \(file start-line start-col end-of-err msg\)
81 where FILE is the file in which the error occurs\; START-LINE is the line
82 number in the file where the error occurs\; START-COL is the character
83 position on that line where the error occurs.
85 If present, the fourth return value is a simple Emacs Lisp expression that
86 will move point to the end of the errorful text, assuming that point is at
87 \(start-line,start-col\) to begin with\; and MSG is the text of the error
88 message given by the compiler."
90 ;; This function uses `sml-smlnj-error-regexp' to do the parsing, and
91 ;; assumes that regexp groups 1, 2, and 3 correspond to the first three
92 ;; elements of the list returned\; and groups 5, 6 and 7 correspond to the
93 ;; optional elements in that order.
97 (if (not (looking-at sml-smlnj-error-regexp))
98 ;; the user loses big time.
100 (let ((file (match-string 1)) ; the file
101 (slin (string-to-int (match-string 2))) ; the start line
102 (scol (string-to-int (match-string 3))) ; the start col
103 (msg (if (match-beginning 7) (match-string 7))))
104 ;; another loss: buggy sml/nj's produce nonsense like file:0.0 Error
105 (if (zerop slin) (list file nil scol)
106 ;; ok, was a range of characters mentioned?
107 (if (match-beginning 4)
108 ;; assume m-b 4 implies m-b 5 and m-b 6 (sml-smlnj-error-regexp)
109 (let* ((elin (string-to-int (match-string 5))) ; end line
110 (ecol (string-to-int (match-string 6))) ; end col
111 (jump (if (= elin slin)
112 ;; move forward on the same line
113 `(forward-char ,(1+ (- ecol scol)))
114 ;; otherwise move down, and over to ecol
116 (forward-line ,(- elin slin))
117 (forward-char ,ecol)))))
118 ;; nconc glues lists together. jump & msg aren't lists
119 (nconc (list file slin scol) (list jump) (list msg)))
120 (nconc (list file slin scol) (list nil) (list msg))))))))
123 (defun sml-smlnj (pfx)
124 "Set up and run Standard ML of New Jersey.
125 Prefix argument means accept the defaults below.
127 Note: defaults set here will be clobbered if you setq them in the
128 inferior-sml-mode-hook.
130 sml-program-name <option> \(default \"sml\"\)
131 sml-default-arg <option> \(default \"\"\)
132 sml-use-command \"use \\\"%s\\\"\"
133 sml-cd-command \"OS.FileSys.chDir \\\"%s\\\"\"
134 sml-prompt-regexp \"^[\\-=] *\"
135 sml-error-regexp sml-sml-nj-error-regexp
136 sml-error-parser 'sml-sml-nj-error-parser"
138 (let ((cmd (if pfx "sml"
139 (read-string "Command name: " sml-program-name)))
141 (read-string "Any arguments or options (default none): "))))
142 ;; sml-mode global variables
143 (setq sml-program-name cmd)
144 (setq sml-default-arg arg)
145 ;; buffer-local (compiler-local) variables
146 (setq-default sml-use-command "use \"%s\""
147 sml-cd-command "OS.FieSys.chDir \"%s\""
148 sml-prompt-regexp "^[\-=] *"
149 sml-error-regexp sml-smlnj-error-regexp
150 sml-error-parser 'sml-smlnj-error-parser)
151 (sml-run cmd sml-default-arg)))
153 ;;; Do the default setup on loading this file.
155 ;; setqing these two may override user's hooked defaults. users
156 ;; therefore need load this file before setting sml-program-name or
157 ;; sml-default-arg in their inferior-sml-load-hook. sorry.
159 (setq sml-program-name "sml"
162 ;; same sort of problem here too: users should to setq-default these
163 ;; after this file is loaded, on inferior-sml-load-hook. as these are
164 ;; buffer-local, users can instead set them on inferior-sml-mode-hook.
166 (setq-default sml-use-command "use \"%s\""
167 sml-cd-command "OS.FileSys.chDir \"%s\""
168 sml-prompt-regexp "^[\-=] *"
169 sml-error-regexp sml-smlnj-error-regexp
170 sml-error-parser 'sml-smlnj-error-parser)
172 ;;; sml-nj.el endeded