1 ;; Copyright (C) 2005 Vesa Karvonen
3 ;; MLton is released under a BSD-style license.
4 ;; See the file MLton-LICENSE for details.
11 ;; Push the path to this file (and `esml-util.el') to `load-path' and use
12 ;; (require 'esml-gen).
14 ;; Ideas for future development
15 ;; ============================
19 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21 (defgroup esml-gen nil
22 "Code generation functions for Standard ML."
25 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;; TBD: Consider moving these to another place if/when it makes sense.
30 (defun esml-extract-field-names (pattern-or-type)
33 (insert pattern-or-type
)
35 (skip-chars-forward " \t\n{},")
37 (let ((start (point)))
38 (if (find (char-after) esml-sml-symbolic-chars
)
39 (skip-chars-forward esml-sml-symbolic-chars
)
40 (skip-chars-forward esml-sml-alphanumeric-chars
))
41 (push (buffer-substring start
(point)) fields
))
42 (skip-chars-forward " \t\n")
43 (when (and (not (eobp))
45 (let ((open-parens 0))
46 (while (not (or (eobp)
47 (and (zerop open-parens
)
48 (= ?\
, (char-after)))))
49 (cond ((or (= ?\
( (char-after))
51 (setq open-parens
(1+ open-parens
)))
52 ((or (= ?\
) (char-after))
54 (setq open-parens
(1- open-parens
))))
56 (skip-chars-forward "^,(){}"))))
57 (skip-chars-forward " \t\n{},")))
60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
61 ;; Functional Record Update (see http://mlton.org/FunctionalRecordUpdate)
63 (defcustom esml-gen-fru-setter-template
64 '("fun set f =\nlet\nfun t2r (%1) = {%2}\nfun r2t {%3} = (%4)
65 in\nRecords.wrapSet (Tuples.set%n, t2r, t2r, r2t) f\nend\n"
70 "Template for `esml-gen-fru-setter'. Indentation is automatic. The last
71 two characters of a pattern are deleted at the end."
72 :type
'(list :tag
"Template"
73 (string :tag
"Code (`%1' = 1., `%2' = 2., ..., `%n' = n)")
74 (string :tag
"1. pattern (`%i' = index, `%f' = field)")
75 (string :tag
"2. pattern (`%i' = index, `%f' = field)")
76 (string :tag
"3. pattern (`%i' = index, `%f' = field)")
77 (string :tag
"4. pattern (`%i' = index, `%f' = field)"))
80 (defun esml-gen-fru-setter (pattern-or-type)
81 "Generates a functional record update function. The parameter must be in
82 the format `[{]id[: ty][,] ...[,] id[}]' where `[]' marks optional parts."
83 (interactive "sSimple record pattern or type: ")
84 (let* ((fields (esml-extract-field-names pattern-or-type
))
87 (compat-error "%s" "Record must have at least two fields")
88 (let ((fields (sort fields
'string-lessp
))
90 (labels ((format-fields
98 (result (compat-replace-regexp-in-string
100 (result (compat-replace-regexp-in-string
101 result
"\\%i" (int-to-string i
))))
103 (delete-char -
2) ;; TBD
106 (let* ((result (nth 0 esml-gen-fru-setter-template
))
107 (result (compat-replace-regexp-in-string
108 result
"%1" (format-fields (nth 1 esml-gen-fru-setter-template
))))
109 (result (compat-replace-regexp-in-string
110 result
"%2" (format-fields (nth 2 esml-gen-fru-setter-template
))))
111 (result (compat-replace-regexp-in-string
112 result
"%3" (format-fields (nth 3 esml-gen-fru-setter-template
))))
113 (result (compat-replace-regexp-in-string
114 result
"%4" (format-fields (nth 4 esml-gen-fru-setter-template
))))
115 (result (compat-replace-regexp-in-string
116 result
"%n" (int-to-string n
))))
118 (indent-region start
(point) nil
))))))
120 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
121 ;; Functional Tuple Update (see http://mlton.org/FunctionalRecordUpdate)
123 (defcustom esml-gen-ftu-setters-template
124 '("fun set%n f v (%1) =\nlet\ndatatype (%2) t =\n%3
125 fun g h v =\n(%4)\nin\nf (%5) v\nend\n"
129 "case h v of V%i v%i => v%i | _ => v%i,\n"
131 "Template for `esml-gen-ftu-setters'. Indentation is automatic. The last
132 two characters of a pattern are deleted at the end."
133 :type
'(list :tag
"Format"
134 (string :tag
"Code (`%1' = 1., `%2' = 2., ..., `%n' = n)")
135 (string :tag
"1. pattern (`%i' = index)")
136 (string :tag
"2. pattern (`%i' = index)")
137 (string :tag
"3. pattern (`%i' = index)")
138 (string :tag
"4. pattern (`%i' = index)")
139 (string :tag
"5. pattern (`%i' = index)"))
142 (defun esml-gen-ftu-setters (n)
143 "Generates functional tuple update, or `set<N>', functions."
144 (interactive "nMaximum number of fields [2-100]: ")
145 (if (not (and (<= 2 n
)
147 (compat-error "%s" "Number of fields must be between 2 and 100")
148 (labels ((format-fields
151 (loop for i from
1 to n
154 (result (compat-replace-regexp-in-string
155 result
"%i" (int-to-string i
))))
157 (delete-char -
2) ;; TBD
159 (let ((start (point)))
160 (loop for i from
2 to n do
164 (let* ((result (nth 0 esml-gen-ftu-setters-template
))
165 (result (compat-replace-regexp-in-string
166 result
"%1" (format-fields (nth 1 esml-gen-ftu-setters-template
) i
)))
167 (result (compat-replace-regexp-in-string
168 result
"%2" (format-fields (nth 2 esml-gen-ftu-setters-template
) i
)))
169 (result (compat-replace-regexp-in-string
170 result
"%3" (format-fields (nth 3 esml-gen-ftu-setters-template
) i
)))
171 (result (compat-replace-regexp-in-string
172 result
"%4" (format-fields (nth 4 esml-gen-ftu-setters-template
) i
)))
173 (result (compat-replace-regexp-in-string
174 result
"%5" (format-fields (nth 5 esml-gen-ftu-setters-template
) i
)))
175 (result (compat-replace-regexp-in-string
176 result
"%n" (int-to-string i
))))
178 (indent-region start
(point) nil
)))))
180 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;