3 * Copyright (c) 2003, Peter Strand <peter@zarquon.se>
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License.
8 * This module contains functions for generating tags for Haskell language
13 * Does not handle operators or infix definitions like:
23 #include "general.h" /* must always come first */
36 K_TYPE
, K_CONSTRUCTOR
, K_FUNCTION
, K_MODULE
39 static kindOption HaskellKinds
[] = {
40 { TRUE
, 't', "typedef", "types" },
41 { TRUE
, 'c', "macro", "type constructors" },
42 { TRUE
, 'f', "function", "functions" },
43 { TRUE
, 'm', "namespace", "modules"}
47 typedef const unsigned char *custr
;
50 * FUNCTION DEFINITIONS
54 static void skip_rest_of_line(void)
59 } while (c
!= EOF
&& c
!= '\n');
62 static int get_line(char *buf
)
69 } while (c
!= EOF
&& c
!= '\n' && i
< 1000);
74 static int get_next_char(void)
85 if (c
== '-' && nxt
== '-') {
87 return get_next_char();
89 if (c
== '{' && nxt
== '-') {
94 } while (! (c
== EOF
|| (last
== '-' && c
== '}')));
95 return get_next_char();
100 static void add_tag(const char *token
, haskellKind kind
, vString
*name
)
103 for (i
= 0; token
[i
] != '\0'; ++i
)
104 vStringPut(name
, token
[i
]);
106 vStringTerminate(name
);
107 makeSimpleTag(name
, HaskellKinds
, kind
);
111 static int isident(char c
)
113 return isalnum(c
) || c
== '_' || c
== '\'' || c
== '$';
116 static int get_token(char *token
, int n
)
120 while (c
!= EOF
&& isident(c
) && i
< 1000) {
136 enum Find_State
{ Find_Eq
, Find_Constr
, Get_Extr
, Find_Extr
, Find_Bar
};
138 static int inside_datatype(vString
*name
)
140 enum Find_State st
= Find_Eq
;
151 if (! (c
== ' ' || c
== '\t')) {
155 } while (c
!= EOF
&& c
!= '=');
158 else if (st
== Find_Constr
)
162 } while (isspace(c
));
168 if (!get_token(token
, 1))
170 add_tag(token
, K_CONSTRUCTOR
, name
);
173 else if (st
== Find_Extr
)
180 else if (c
== '\n') {
182 if (! (c
== ' ' || c
== '\t')) {
186 else if (!isspace(c
))
189 else if (st
== Get_Extr
)
193 } while (isspace(c
));
198 add_tag(token
, K_FUNCTION
, name
);
205 } while (c
!= EOF
&& c
!= ',');
207 else if (st
== Find_Bar
)
213 if (! (c
== ' ' || c
== '\t')) {
217 } while (c
!= EOF
&& c
!= '|');
224 static void findHaskellTags (int is_literate
)
226 vString
*name
= vStringNew ();
227 char token
[1001], arg
[1001];
229 int in_tex_lit_code
= 0;
244 if (is_literate
&& !in_tex_lit_code
) {
259 } else if (c
== '\\') {
260 int n
= get_line(token
);
261 if (strncmp(token
, "begin{code}", 11) == 0) {
266 if (n
> 0 && token
[n
-1] != '\n')
278 if (is_literate
&& in_tex_lit_code
&& c
== '\\') {
279 if (strncmp(token
, "end{code}", 9) == 0) {
292 if (!get_token(token
, 1)) {
297 if ((c
= fileGetc()) == EOF
)
299 } while (c
== ' ' || c
== '\t');
302 if (strcmp(token
, "data") == 0 || strcmp(token
, "newtype") == 0) {
303 add_tag(arg
, K_TYPE
, name
);
304 c
= inside_datatype(name
);
307 if (strcmp(token
, "type") == 0)
308 add_tag(arg
, K_TYPE
, name
);
309 else if (strcmp(token
, "module") == 0)
310 add_tag(arg
, K_MODULE
, name
);
311 else if (strcmp(token
, "instance") == 0 ||
312 strcmp(token
, "foreign") == 0 ||
313 strcmp(token
, "import") == 0)
317 add_tag(token
, K_FUNCTION
, name
);
325 static void findNormalHaskellTags (void)
330 static void findLiterateHaskellTags (void)
335 extern parserDefinition
* HaskellParser (void)
337 static const char *const extensions
[] = { "hs", NULL
};
338 parserDefinition
* def
= parserNew ("Haskell");
340 def
->kinds
= HaskellKinds
;
341 def
->kindCount
= KIND_COUNT(HaskellKinds
);
342 def
->extensions
= extensions
;
343 def
->parser
= findNormalHaskellTags
;
347 extern parserDefinition
* LiterateHaskellParser (void)
349 static const char *const extensions
[] = { "lhs", NULL
};
350 parserDefinition
* def
= parserNew ("Literate Haskell");
351 def
->kinds
= HaskellKinds
;
352 def
->kindCount
= KIND_COUNT(HaskellKinds
);
353 def
->extensions
= extensions
;
354 def
->parser
= findLiterateHaskellTags
;
358 /* vi:set expandtab tabstop=8 shiftwidth=4: */