Commit | Line | Data |
---|---|---|
a2095e2e CY |
1 | ;;; semantic/ede-grammar.el --- EDE support for Semantic Grammar Files |
2 | ||
acaf905b | 3 | ;; Copyright (C) 2003-2004, 2007-2012 Free Software Foundation, Inc. |
a2095e2e CY |
4 | |
5 | ;; Author: Eric M. Ludlam <zappo@gnu.org> | |
6 | ;; Keywords: project, make | |
7 | ||
8 | ;; This file is part of GNU Emacs. | |
9 | ||
10 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
11 | ;; it under the terms of the GNU General Public License as published by | |
12 | ;; the Free Software Foundation, either version 3 of the License, or | |
13 | ;; (at your option) any later version. | |
14 | ||
15 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
22 | ||
23 | ;;; Commentary: | |
24 | ;; | |
25 | ;; Handle .by or .wy files. | |
26 | ||
27 | (require 'semantic) | |
28 | (require 'ede/proj) | |
29 | (require 'ede/pmake) | |
30 | (require 'ede/pconf) | |
31 | (require 'ede/proj-elisp) | |
32 | (require 'semantic/grammar) | |
33 | ||
34 | ;;; Code: | |
62a81506 | 35 | (defclass semantic-ede-proj-target-grammar (ede-proj-target-elisp) |
a2095e2e CY |
36 | ((menu :initform nil) |
37 | (keybindings :initform nil) | |
38 | (phony :initform t) | |
39 | (sourcetype :initform | |
40 | (semantic-ede-source-grammar-wisent | |
41 | semantic-ede-source-grammar-bovine | |
42 | )) | |
43 | (availablecompilers :initform | |
44 | (semantic-ede-grammar-compiler-wisent | |
45 | semantic-ede-grammar-compiler-bovine | |
46 | )) | |
62a81506 CY |
47 | (aux-packages :initform '("semantic" "cedet-compat")) |
48 | (pre-load-packages :initform '("cedet-compat" "semantic/grammar" "semantic/bovine/grammar" "semantic/wisent/grammar")) | |
a2095e2e CY |
49 | ) |
50 | "This target consists of a group of grammar files. | |
51 | A grammar target consists of grammar files that build Emacs Lisp programs for | |
52 | parsing different languages.") | |
53 | ||
62a81506 CY |
54 | (defmethod ede-proj-makefile-dependencies ((this semantic-ede-proj-target-grammar)) |
55 | "Return a string representing the dependencies for THIS. | |
56 | Some compilers only use the first element in the dependencies, others | |
57 | have a list of intermediates (object files), and others don't care. | |
58 | This allows customization of how these elements appear. | |
59 | For Emacs Lisp, return addsuffix command on source files." | |
60 | (let ((source (car (oref this source)))) | |
61 | (cond | |
62 | ((string-match "\\.wy$" source) | |
63 | (format "$(addsuffix -wy.elc, $(basename $(%s)))" | |
64 | (ede-proj-makefile-sourcevar this))) | |
65 | ((string-match "\\.by$" source) | |
66 | (format "$(addsuffix -by.elc, $(basename $(%s)))" | |
67 | (ede-proj-makefile-sourcevar this)))))) | |
68 | ||
a2095e2e CY |
69 | (defvar semantic-ede-source-grammar-wisent |
70 | (ede-sourcecode "semantic-ede-grammar-source-wisent" | |
71 | :name "Wisent Grammar" | |
72 | :sourcepattern "\\.wy$" | |
62a81506 | 73 | :garbagepattern '("*-wy.el") |
a2095e2e CY |
74 | ) |
75 | "Semantic Grammar source code definition for wisent.") | |
76 | ||
77 | (defclass semantic-ede-grammar-compiler-class (ede-compiler) | |
78 | nil | |
79 | "Specialized compiler for semantic grammars.") | |
80 | ||
81 | (defvar semantic-ede-grammar-compiler-wisent | |
82 | (semantic-ede-grammar-compiler-class | |
83 | "ede-emacs-wisent-compiler" | |
84 | :name "emacs" | |
62a81506 CY |
85 | :variables '(("EMACS" . "emacs") |
86 | ("EMACSFLAGS" . "-batch --no-site-file --eval '(setq debug-on-error t)'") | |
87 | ("require" . "$(foreach r,$(1),(require (quote $(r))))")) | |
88 | :rules (list (ede-makefile-rule | |
89 | "elisp-inference-rule" | |
90 | :target "%-wy.el" | |
91 | :dependencies "%.wy" | |
92 | :rules '("$(EMACS) $(EMACSFLAGS) $(addprefix -L ,$(LOADPATH)) \ | |
93 | --eval '(progn $(call require,$(PRELOADS)))' -f semantic-grammar-batch-build-packages $^"))) | |
a2095e2e | 94 | :sourcetype '(semantic-ede-source-grammar-wisent) |
62a81506 | 95 | :objectextention "-wy.el" |
a2095e2e CY |
96 | ) |
97 | "Compile Emacs Lisp programs.") | |
98 | ||
99 | ||
100 | (defvar semantic-ede-source-grammar-bovine | |
101 | (ede-sourcecode "semantic-ede-grammar-source-bovine" | |
102 | :name "Bovine Grammar" | |
103 | :sourcepattern "\\.by$" | |
62a81506 | 104 | :garbagepattern '("*-by.el") |
a2095e2e CY |
105 | ) |
106 | "Semantic Grammar source code definition for the bovinator.") | |
107 | ||
108 | (defvar semantic-ede-grammar-compiler-bovine | |
109 | (semantic-ede-grammar-compiler-class | |
110 | "ede-emacs-wisent-compiler" | |
111 | :name "emacs" | |
62a81506 CY |
112 | :variables '(("EMACS" . "emacs") |
113 | ("EMACSFLAGS" . "-batch --no-site-file --eval '(setq debug-on-error t)'") | |
114 | ("require" . "$(foreach r,$(1),(require (quote $(r))))")) | |
115 | :rules (list (ede-makefile-rule | |
116 | "elisp-inference-rule" | |
117 | :target "%-by.el" | |
118 | :dependencies "%.by" | |
119 | :rules '("$(EMACS) $(EMACSFLAGS) $(addprefix -L ,$(LOADPATH)) \ | |
120 | --eval '(progn $(call require,$(PRELOADS)))' -f semantic-grammar-batch-build-packages $^"))) | |
a2095e2e | 121 | :sourcetype '(semantic-ede-source-grammar-bovine) |
62a81506 | 122 | :objectextention "-by.el" |
a2095e2e CY |
123 | ) |
124 | "Compile Emacs Lisp programs.") | |
125 | ||
126 | ;;; Target options. | |
127 | (defmethod ede-buffer-mine ((this semantic-ede-proj-target-grammar) buffer) | |
128 | "Return t if object THIS lays claim to the file in BUFFER. | |
129 | Lays claim to all -by.el, and -wy.el files." | |
130 | ;; We need to be a little more careful than this, but at the moment it | |
131 | ;; is common to have only one target of this class per directory. | |
132 | (if (string-match "-[bw]y\\.elc?$" (buffer-file-name buffer)) | |
133 | t | |
134 | (call-next-method) ; The usual thing. | |
135 | )) | |
136 | ||
137 | (defmethod project-compile-target ((obj semantic-ede-proj-target-grammar)) | |
138 | "Compile all sources in a Lisp target OBJ." | |
139 | (let* ((cb (current-buffer)) | |
140 | (proj (ede-target-parent obj)) | |
62a81506 CY |
141 | (default-directory (oref proj directory)) |
142 | (comp 0) | |
143 | (utd 0)) | |
a2095e2e | 144 | (mapc (lambda (src) |
0816d744 | 145 | (with-current-buffer (find-file-noselect src) |
a2095e2e CY |
146 | (save-excursion |
147 | (semantic-grammar-create-package)) | |
62a81506 CY |
148 | ;; After compile, the current buffer is the compiled grammar. |
149 | ;; Save and compile it. | |
a2095e2e | 150 | (save-buffer) |
62a81506 CY |
151 | (let* ((src (buffer-file-name)) |
152 | (csrc (concat (file-name-sans-extension src) ".elc"))) | |
153 | (if (< emacs-major-version 24) | |
154 | ;; Does not have `byte-recompile-file' | |
155 | (if (or (not (file-exists-p csrc)) | |
156 | (file-newer-than-file-p src csrc)) | |
157 | (progn | |
158 | (setq comp (1+ comp)) | |
159 | (byte-compile-file src)) | |
160 | (setq utd (1+ utd))) | |
161 | ;; Emacs 24 and newer | |
162 | (with-no-warnings | |
163 | (if (eq (byte-recompile-file src nil 0) t) | |
164 | (setq comp (1+ comp)) | |
165 | (setq utd (1+ utd)))))))) | |
166 | (oref obj source)) | |
167 | (message "All Semantic Grammar sources are up to date in %s" (object-name obj)) | |
168 | (cons comp utd))) | |
a2095e2e CY |
169 | |
170 | ;;; Makefile generation functions | |
171 | ;; | |
172 | (defmethod ede-proj-makefile-sourcevar ((this semantic-ede-proj-target-grammar)) | |
173 | "Return the variable name for THIS's sources." | |
174 | (cond ((ede-proj-automake-p) | |
175 | (error "No Automake support for Semantic Grammars")) | |
176 | (t (concat (ede-pmake-varname this) "_SEMANTIC_GRAMMAR")))) | |
177 | ||
178 | (defmethod ede-proj-makefile-insert-variables :AFTER ((this semantic-ede-proj-target-grammar)) | |
179 | "Insert variables needed by target THIS." | |
180 | (ede-proj-makefile-insert-loadpath-items | |
181 | (ede-proj-elisp-packages-to-loadpath | |
182 | (list "eieio" "semantic" "inversion" "ede"))) | |
183 | ;; eieio for object system needed in ede | |
184 | ;; semantic because it is | |
185 | ;; Inversion for versioning system. | |
186 | ;; ede for project regeneration | |
187 | (ede-pmake-insert-variable-shared | |
188 | (concat (ede-pmake-varname this) "_SEMANTIC_GRAMMAR_EL") | |
189 | (insert | |
190 | (mapconcat (lambda (src) | |
0816d744 | 191 | (with-current-buffer (find-file-noselect src) |
a2095e2e CY |
192 | (concat (semantic-grammar-package) ".el"))) |
193 | (oref this source) | |
194 | " "))) | |
195 | ) | |
196 | ||
62a81506 CY |
197 | (defmethod ede-proj-makefile-insert-rules :after ((this semantic-ede-proj-target-grammar)) |
198 | "Insert rules needed by THIS target. | |
199 | This raises `max-specpdl-size' and `max-lisp-eval-depth', which can be | |
200 | needed for the compilation of the resulting parsers." | |
201 | (insert (format "%s: EMACSFLAGS+= --eval '(setq max-specpdl-size 1500 \ | |
202 | max-lisp-eval-depth 700)'\n" | |
203 | (oref this name)))) | |
a2095e2e CY |
204 | |
205 | (defmethod ede-proj-makefile-insert-dist-dependencies ((this semantic-ede-proj-target-grammar)) | |
206 | "Insert dist dependencies, or intermediate targets. | |
207 | This makes sure that all grammar lisp files are created before the dist | |
208 | runs, so they are always up to date. | |
209 | Argument THIS is the target that should insert stuff." | |
210 | (call-next-method) | |
211 | (insert " $(" (ede-pmake-varname this) "_SEMANTIC_GRAMMAR_EL)") | |
212 | ) | |
213 | ||
214 | ;; (autoload 'ede-proj-target-elisp "ede/proj-elisp" | |
215 | ;; "Target class for Emacs/Semantic grammar files." nil nil) | |
216 | ||
217 | (ede-proj-register-target "semantic grammar" | |
218 | semantic-ede-proj-target-grammar) | |
219 | ||
220 | (provide 'semantic/ede-grammar) | |
221 | ||
222 | ;;; semantic/ede-grammar.el ends here |