1 ;;; fuel-syntax.el --- auxiliar definitions for factor code navigation.
3 ;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
4 ;; See http://factorcode.org/license.txt for BSD license.
6 ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
11 ;; Auxiliar constants and functions to parse factor code.
18 ;;; Thing-at-point support for factor symbols:
20 (defun fuel-syntax--beginning-of-symbol ()
21 "Move point to the beginning of the current symbol."
22 (while (eq (char-before) ?:) (backward-char))
23 (skip-syntax-backward "w_"))
25 (defsubst fuel-syntax--symbol-start ()
26 (save-excursion (fuel-syntax--beginning-of-symbol) (point)))
28 (defun fuel-syntax--end-of-symbol ()
29 "Move point to the end of the current symbol."
30 (skip-syntax-forward "w_")
31 (while (looking-at ":") (forward-char)))
33 (defsubst fuel-syntax--symbol-end ()
34 (save-excursion (fuel-syntax--end-of-symbol) (point)))
36 (put 'factor-symbol 'end-op 'fuel-syntax--end-of-symbol)
37 (put 'factor-symbol 'beginning-op 'fuel-syntax--beginning-of-symbol)
39 (defsubst fuel-syntax-symbol-at-point ()
40 (let ((s (substring-no-properties (thing-at-point 'factor-symbol))))
41 (and (> (length s) 0) s)))
47 (defconst fuel-syntax--parsing-words
48 '("{" "}" "^:" "^::" ";" "<<" "<PRIVATE" ">>"
49 "BIN:" "BV{" "B{" "C:" "C-STRUCT:" "C-UNION:" "CHAR:" "CS{" "C{"
50 "DEFER:" "ERROR:" "EXCLUDE:" "FORGET:"
51 "GENERIC#" "GENERIC:" "HEX:" "HOOK:" "H{"
52 "IN:" "INSTANCE:" "INTERSECTION:"
53 "M:" "MACRO:" "MACRO::" "MAIN:" "MATH:" "MEMO:" "METHOD:" "MIXIN:"
54 "OCT:" "POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
55 "REQUIRE:" "REQUIRES:" "SINGLETON:" "SLOT:" "SYMBOL:" "SYMBOLS:"
56 "TUPLE:" "T{" "t\\??" "TYPEDEF:"
57 "UNION:" "USE:" "USING:" "V{" "VARS:" "W{"))
59 (defconst fuel-syntax--parsing-words-ext-regex
60 (regexp-opt '("B" "call-next-method" "delimiter" "f" "initial:" "read-only")
63 (defconst fuel-syntax--declaration-words
64 '("flushable" "foldable" "inline" "parsing" "recursive"))
66 (defconst fuel-syntax--declaration-words-regex
67 (regexp-opt fuel-syntax--declaration-words 'words))
69 (defsubst fuel-syntax--second-word-regex (prefixes)
70 (format "^%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
72 (defconst fuel-syntax--method-definition-regex
73 "^M: +\\([^ ]+\\) +\\([^ ]+\\)")
75 (defconst fuel-syntax--word-definition-regex
76 (fuel-syntax--second-word-regex '(":" "::" "GENERIC:")))
78 (defconst fuel-syntax--type-definition-regex
79 (fuel-syntax--second-word-regex '("TUPLE:" "SINGLETON:")))
81 (defconst fuel-syntax--parent-type-regex "^TUPLE: +[^ ]+ +< +\\([^ ]+\\)")
83 (defconst fuel-syntax--constructor-regex "<[^ >]+>")
85 (defconst fuel-syntax--setter-regex "\\W>>[^ ]+\\b")
87 (defconst fuel-syntax--symbol-definition-regex
88 (fuel-syntax--second-word-regex '("SYMBOL:" "VAR:")))
90 (defconst fuel-syntax--stack-effect-regex " ( .* )")
92 (defconst fuel-syntax--using-lines-regex "^USING: +\\([^;]+\\);")
94 (defconst fuel-syntax--use-line-regex "^USE: +\\(.*\\)$")
96 (defconst fuel-syntax--current-vocab-regex "^IN: +\\([^ \r\n\f]+\\)")
98 (defconst fuel-syntax--sub-vocab-regex "^<\\([^ \n]+\\) *$")
100 (defconst fuel-syntax--definition-starters-regex
101 (regexp-opt '("VARS" "TUPLE" "MACRO" "MACRO:" "M" "MEMO" "METHOD" ":" "")))
103 (defconst fuel-syntax--definition-start-regex
104 (format "^\\(%s:\\) " fuel-syntax--definition-starters-regex))
106 (defconst fuel-syntax--definition-end-regex
107 (format "\\(\\(^\\| +\\);\\( +%s\\)*\\($\\| +\\)\\)"
108 fuel-syntax--declaration-words-regex))
110 (defconst fuel-syntax--single-liner-regex
111 (format "^%s" (regexp-opt '("C:" "DEFER:" "GENERIC:" "IN:"
112 "PRIVATE>" "<PRIVATE"
113 "SINGLETON:" "SYMBOL:" "USE:" "VAR:"))))
115 (defconst fuel-syntax--begin-of-def-regex
116 (format "^USING: \\|\\(%s\\)\\|\\(%s .*\\)"
117 fuel-syntax--definition-start-regex
118 fuel-syntax--single-liner-regex))
120 (defconst fuel-syntax--end-of-def-line-regex
121 (format "^.*%s" fuel-syntax--definition-end-regex))
123 (defconst fuel-syntax--end-of-def-regex
124 (format "\\(%s\\)\\|\\(%s .*\\)"
125 fuel-syntax--end-of-def-line-regex
126 fuel-syntax--single-liner-regex))
128 ;;; Factor syntax table
130 (defvar fuel-syntax--syntax-table
132 (table (make-syntax-table)))
133 ;; Default is atom-constituent
135 (modify-syntax-entry i "_ " table)
141 (modify-syntax-entry i "w " table)
145 (modify-syntax-entry i "w " table)
149 (modify-syntax-entry i "w " table)
153 (modify-syntax-entry ?\t " " table)
154 (modify-syntax-entry ?\f " " table)
155 (modify-syntax-entry ?\r " " table)
156 (modify-syntax-entry ? " " table)
159 (modify-syntax-entry ?\n ">" table)
162 (modify-syntax-entry ?\[ "(] " table)
163 (modify-syntax-entry ?\] ")[ " table)
164 (modify-syntax-entry ?{ "(} " table)
165 (modify-syntax-entry ?} "){ " table)
167 (modify-syntax-entry ?\( "()" table)
168 (modify-syntax-entry ?\) ")(" table)
171 (modify-syntax-entry ?\" "\"" table)
172 (modify-syntax-entry ?\\ "/" table)
174 "Syntax table used while in Factor mode.")
176 (defconst fuel-syntax--syntactic-keywords
177 `(("\\(#!\\)" (1 "<"))
180 ("\\(!(\\) .* \\()\\)" (1 "<") (2 ">"))
181 ("\\([[({]\\)\\([^ \"\n]\\)" (1 "_") (2 "_"))
182 ("\\([^ \"\n]\\)\\([])}]\\)" (1 "_") (2 "_"))))
185 ;;; Source code analysis:
187 (defsubst fuel-syntax--brackets-depth ()
188 (nth 0 (syntax-ppss)))
190 (defsubst fuel-syntax--brackets-start ()
191 (nth 1 (syntax-ppss)))
193 (defun fuel-syntax--brackets-end ()
195 (goto-char (fuel-syntax--brackets-start))
197 (progn (forward-sexp)
201 (defsubst fuel-syntax--indentation-at (pos)
202 (save-excursion (goto-char pos) (current-indentation)))
204 (defsubst fuel-syntax--increased-indentation (&optional i)
205 (+ (or i (current-indentation)) factor-indent-width))
206 (defsubst fuel-syntax--decreased-indentation (&optional i)
207 (- (or i (current-indentation)) factor-indent-width))
209 (defsubst fuel-syntax--at-begin-of-def ()
210 (looking-at fuel-syntax--begin-of-def-regex))
212 (defsubst fuel-syntax--at-end-of-def ()
213 (looking-at fuel-syntax--end-of-def-regex))
215 (defsubst fuel-syntax--looking-at-emptiness ()
216 (looking-at "^[ \t]*$"))
218 (defun fuel-syntax--at-setter-line ()
221 (if (not (fuel-syntax--looking-at-emptiness))
222 (re-search-forward fuel-syntax--setter-regex (line-end-position) t)
224 (or (fuel-syntax--at-constructor-line)
225 (fuel-syntax--at-setter-line)))))
227 (defun fuel-syntax--at-constructor-line ()
230 (re-search-forward fuel-syntax--constructor-regex (line-end-position) t)))
232 (defsubst fuel-syntax--at-using ()
233 (looking-at fuel-syntax--using-lines-regex))
235 (defsubst fuel-syntax--beginning-of-defun (&optional times)
236 (re-search-backward fuel-syntax--begin-of-def-regex nil t times))
238 (defsubst fuel-syntax--end-of-defun ()
239 (re-search-forward fuel-syntax--end-of-def-regex nil t))
244 (make-variable-buffer-local
245 (defvar fuel-syntax--current-vocab-function 'fuel-syntax--find-in))
247 (defsubst fuel-syntax--current-vocab ()
248 (funcall fuel-syntax--current-vocab-function))
250 (defun fuel-syntax--find-in ()
254 (when (re-search-backward fuel-syntax--current-vocab-regex nil t)
255 (setq vocab (match-string-no-properties 1))
258 (let ((pp (save-excursion
259 (when (re-search-backward fuel-syntax--sub-vocab-regex ip t)
261 (when (and pp (> pp ip))
262 (let ((sub (match-string-no-properties 1)))
263 (unless (save-excursion (search-backward (format "%s>" sub) pp t))
264 (setq vocab (format "%s.%s" vocab (downcase sub))))))))
267 (make-variable-buffer-local
268 (defvar fuel-syntax--usings-function 'fuel-syntax--find-usings))
270 (defsubst fuel-syntax--usings ()
271 (funcall fuel-syntax--usings-function))
273 (defun fuel-syntax--find-usings ()
276 (in (fuel-syntax--current-vocab)))
277 (when in (setq usings (list in)))
278 (goto-char (point-max))
279 (while (re-search-backward fuel-syntax--using-lines-regex nil t)
280 (dolist (u (split-string (match-string-no-properties 1) nil t))
285 (provide 'fuel-syntax)
286 ;;; fuel-syntax.el ends here