2
* $Id: asm.c,v 1.18 2006/05/30 04:37:11 darren Exp $
4
* Copyright (c) 2000-2003, Darren Hiebert
6
* This source code is released for free distribution under the terms of the
7
* GNU General Public License.
9
* This module contains functions for generating tags for assembly language
16
#include "general.h" /* must always come first */
31
K_NONE = -1, K_DEFINE, K_LABEL, K_MACRO, K_TYPE
56
const char *_operator;
68
static langType Lang_asm;
70
static kindOption AsmKinds [] = {
71
{ TRUE, 'd', "define", "defines" },
72
{ TRUE, 'l', "label", "labels" },
73
{ TRUE, 'm', "macro", "macros" },
74
{ TRUE, 't', "type", "types (structs and records)" }
77
static const asmKeyword AsmKeywords [] = {
78
{ "align", OP_ALIGN },
79
{ "endmacro", OP_ENDMACRO },
85
{ "label", OP_LABEL },
86
{ "macro", OP_MACRO },
87
{ ":=", OP_COLON_EQUAL },
90
{ "record", OP_RECORD },
91
{ "sections", OP_SECTIONS },
93
{ "struct", OP_STRUCT }
96
static const opKind OpKinds [] = {
97
/* must be ordered same as opKeyword enumeration */
99
{ OP_COLON_EQUAL, K_DEFINE },
102
{ OP_ENDMACRO, K_NONE },
105
{ OP_EQU, K_DEFINE },
106
{ OP_EQUAL, K_DEFINE },
107
{ OP_LABEL, K_LABEL },
108
{ OP_MACRO, K_MACRO },
109
{ OP_PROC, K_LABEL },
110
{ OP_RECORD, K_TYPE },
111
{ OP_SECTIONS, K_NONE },
112
{ OP_SET, K_DEFINE },
113
{ OP_STRUCT, K_TYPE }
117
* FUNCTION DEFINITIONS
119
static void buildAsmKeywordHash (void)
121
const size_t count = sizeof (AsmKeywords) / sizeof (AsmKeywords [0]);
123
for (i = 0 ; i < count ; ++i)
125
const asmKeyword* const p = AsmKeywords + i;
126
addKeyword (p->_operator, Lang_asm, (int) p->keyword);
130
static opKeyword analyzeOperator (const vString *const op)
132
static vString *keyword = NULL;
133
opKeyword result = OP_UNDEFINED;
136
keyword = vStringNew ();
137
vStringCopyToLower (keyword, op);
138
result = (opKeyword) lookupKeyword (vStringValue (keyword), Lang_asm);
142
static boolean isInitialSymbolCharacter (int c)
144
return (boolean) (c != '\0' && (isalpha (c) || strchr ("_$", c) != NULL));
147
static boolean isSymbolCharacter (int c)
149
/* '?' character is allowed in AMD 29K family */
150
return (boolean) (c != '\0' && (isalnum (c) || strchr ("_$?", c) != NULL));
153
static boolean readPreProc (const unsigned char *const line)
156
const unsigned char *cp = line;
157
vString *name = vStringNew ();
158
while (isSymbolCharacter ((int) *cp))
160
vStringPut (name, *cp);
163
vStringTerminate (name);
164
result = (boolean) (strcmp (vStringValue (name), "define") == 0);
167
while (isspace ((int) *cp))
170
while (isSymbolCharacter ((int) *cp))
172
vStringPut (name, *cp);
175
vStringTerminate (name);
176
makeSimpleTag (name, AsmKinds, K_DEFINE);
178
vStringDelete (name);
182
static AsmKind operatorKind (
183
const vString *const _operator,
184
boolean *const found)
186
AsmKind result = K_NONE;
187
const opKeyword kw = analyzeOperator (_operator);
188
*found = (boolean) (kw != OP_UNDEFINED);
191
result = OpKinds [kw].kind;
192
Assert (OpKinds [kw].keyword == kw);
197
/* We must check for "DB", "DB.L", "DCB.W" (68000)
199
static boolean isDefineOperator (const vString *const _operator)
201
const unsigned char *const op =
202
(unsigned char*) vStringValue (_operator);
203
const size_t length = vStringLength (_operator);
204
const boolean result = (boolean) (length > 0 &&
205
toupper ((int) *op) == 'D' &&
207
(length == 4 && (int) op [2] == '.') ||
208
(length == 5 && (int) op [3] == '.')));
212
static void makeAsmTag (
213
const vString *const name,
214
const vString *const _operator,
215
const boolean labelCandidate,
216
const boolean nameFollows)
218
if (vStringLength (name) > 0)
221
const AsmKind kind = operatorKind (_operator, &found);
225
makeSimpleTag (name, AsmKinds, kind);
227
else if (isDefineOperator (_operator))
230
makeSimpleTag (name, AsmKinds, K_DEFINE);
232
else if (labelCandidate)
234
operatorKind (name, &found);
236
makeSimpleTag (name, AsmKinds, K_LABEL);
241
static const unsigned char *readSymbol (
242
const unsigned char *const start,
245
const unsigned char *cp = start;
247
if (isInitialSymbolCharacter ((int) *cp))
249
while (isSymbolCharacter ((int) *cp))
251
vStringPut (sym, *cp);
254
vStringTerminate (sym);
259
static const unsigned char *readOperator (
260
const unsigned char *const start,
261
vString *const _operator)
263
const unsigned char *cp = start;
264
vStringClear (_operator);
265
while (*cp != '\0' && ! isspace ((int) *cp))
267
vStringPut (_operator, *cp);
270
vStringTerminate (_operator);
274
static void findAsmTags (void)
276
vString *name = vStringNew ();
277
vString *_operator = vStringNew ();
278
const unsigned char *line;
279
boolean inCComment = FALSE;
281
while ((line = fileReadLine ()) != NULL)
283
const unsigned char *cp = line;
284
boolean labelCandidate = (boolean) (! isspace ((int) *cp));
285
boolean nameFollows = FALSE;
286
const boolean isComment = (boolean)
287
(*cp != '\0' && strchr (";*@", *cp) != NULL);
290
if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0)
299
if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0)
306
} while (*cp != '\0');
308
if (isComment || inCComment)
311
/* read preprocessor defines */
319
/* skip white space */
320
while (isspace ((int) *cp))
324
cp = readSymbol (cp, name);
325
if (vStringLength (name) > 0 && *cp == ':')
327
labelCandidate = TRUE;
331
if (! isspace ((int) *cp) && *cp != '\0')
334
/* skip white space */
335
while (isspace ((int) *cp))
338
/* skip leading dot */
344
cp = readOperator (cp, _operator);
346
/* attempt second read of symbol */
347
if (vStringLength (name) == 0)
349
while (isspace ((int) *cp))
351
cp = readSymbol (cp, name);
354
makeAsmTag (name, _operator, labelCandidate, nameFollows);
356
vStringDelete (name);
357
vStringDelete (_operator);
360
static void initialize (const langType language)
363
buildAsmKeywordHash ();
366
extern parserDefinition* AsmParser (void)
368
static const char *const extensions [] = {
369
"asm", "ASM", "s", "S", NULL
371
static const char *const patterns [] = {
374
"*.[68][68][kKsSxX]",
378
parserDefinition* def = parserNew ("Asm");
379
def->kinds = AsmKinds;
380
def->kindCount = KIND_COUNT (AsmKinds);
381
def->extensions = extensions;
382
def->patterns = patterns;
383
def->parser = findAsmTags;
384
def->initialize = initialize;
388
/* vi:set tabstop=4 shiftwidth=4: */