2007-06-22 17:34:31 +00:00
|
|
|
/*
|
|
|
|
* $Id:$
|
|
|
|
*
|
|
|
|
* Copyright (c) 2000-2006, Darren Hiebert, Elias Pschernig
|
|
|
|
*
|
|
|
|
* This source code is released for free distribution under the terms of the
|
|
|
|
* GNU General Public License.
|
|
|
|
*
|
|
|
|
* This module contains functions for generating tags for BlitzBasic
|
|
|
|
* (BlitzMax), PureBasic and FreeBasic language files. For now, this is kept
|
|
|
|
* quite simple - but feel free to ask for more things added any time -
|
|
|
|
* patches are of course most welcome.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* INCLUDE FILES
|
|
|
|
*/
|
|
|
|
#include "general.h" /* must always come first */
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "parse.h"
|
|
|
|
#include "read.h"
|
|
|
|
#include "vstring.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DATA DEFINITIONS
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
K_CONST,
|
|
|
|
K_FUNCTION,
|
|
|
|
K_LABEL,
|
|
|
|
K_TYPE,
|
|
|
|
K_VARIABLE,
|
|
|
|
K_ENUM
|
|
|
|
} BasicKind;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char const *token;
|
|
|
|
BasicKind kind;
|
2007-06-23 16:49:15 +00:00
|
|
|
int skip;
|
2007-06-22 17:34:31 +00:00
|
|
|
} KeyWord;
|
|
|
|
|
|
|
|
static kindOption BasicKinds[] = {
|
|
|
|
{TRUE, 'c', "constant", "constants"},
|
|
|
|
{TRUE, 'f', "function", "functions"},
|
|
|
|
{TRUE, 'l', "label", "labels"},
|
|
|
|
{TRUE, 't', "type", "types"},
|
|
|
|
{TRUE, 'v', "variable", "variables"},
|
|
|
|
{TRUE, 'g', "enum", "enumerations"}
|
|
|
|
};
|
|
|
|
|
|
|
|
static KeyWord blitzbasic_keywords[] = {
|
2007-06-23 16:49:15 +00:00
|
|
|
{"const", K_CONST, 0},
|
|
|
|
{"global", K_VARIABLE, 0},
|
|
|
|
{"dim", K_VARIABLE, 0},
|
|
|
|
{"function", K_FUNCTION, 0},
|
|
|
|
{"type", K_TYPE, 0},
|
|
|
|
{NULL, 0, 0}
|
2007-06-22 17:34:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static KeyWord purebasic_keywords[] = {
|
2007-06-23 16:49:15 +00:00
|
|
|
{"newlist", K_VARIABLE, 0},
|
|
|
|
{"global", K_VARIABLE, 0},
|
|
|
|
{"dim", K_VARIABLE, 0},
|
|
|
|
{"procedure", K_FUNCTION, 0},
|
|
|
|
{"interface", K_TYPE, 0},
|
|
|
|
{"structure", K_TYPE, 0},
|
|
|
|
{NULL, 0, 0}
|
2007-06-22 17:34:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static KeyWord freebasic_keywords[] = {
|
2007-06-23 16:49:15 +00:00
|
|
|
{"const", K_CONST, 0},
|
|
|
|
{"dim as", K_VARIABLE, 1},
|
|
|
|
{"dim", K_VARIABLE, 0},
|
|
|
|
{"common", K_VARIABLE, 0},
|
|
|
|
{"function", K_FUNCTION, 0},
|
|
|
|
{"sub", K_FUNCTION, 0},
|
|
|
|
{"private sub", K_FUNCTION, 0},
|
|
|
|
{"public sub", K_FUNCTION, 0},
|
|
|
|
{"private function", K_FUNCTION, 0},
|
|
|
|
{"public function", K_FUNCTION, 0},
|
|
|
|
{"type", K_TYPE, 0},
|
|
|
|
{"enum", K_ENUM, 0},
|
|
|
|
{NULL, 0, 0}
|
2007-06-22 17:34:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION DEFINITIONS
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Match the name of a tag (function, variable, type, ...) starting at pos. */
|
2007-06-23 16:49:15 +00:00
|
|
|
static char const *extract_name (char const *pos, vString * name)
|
2007-06-22 17:34:31 +00:00
|
|
|
{
|
|
|
|
while (isspace (*pos))
|
|
|
|
pos++;
|
|
|
|
vStringClear (name);
|
|
|
|
for (; *pos && !isspace (*pos) && *pos != '(' && *pos != ','; pos++)
|
|
|
|
vStringPut (name, *pos);
|
|
|
|
vStringTerminate (name);
|
2007-06-23 16:49:15 +00:00
|
|
|
return pos;
|
2007-06-22 17:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Match a keyword starting at p (case insensitive). */
|
2007-06-23 16:49:15 +00:00
|
|
|
static int match_keyword (const char *p, KeyWord const *kw)
|
2007-06-22 17:34:31 +00:00
|
|
|
{
|
|
|
|
vString *name;
|
|
|
|
size_t i;
|
2007-06-23 16:49:15 +00:00
|
|
|
int j;
|
|
|
|
for (i = 0; i < strlen (kw->token); i++)
|
2007-06-22 17:34:31 +00:00
|
|
|
{
|
2007-06-23 16:49:15 +00:00
|
|
|
if (tolower (p[i]) != kw->token[i])
|
|
|
|
return 0;
|
2007-06-22 17:34:31 +00:00
|
|
|
}
|
|
|
|
name = vStringNew ();
|
2007-06-23 16:49:15 +00:00
|
|
|
p += i;
|
|
|
|
for (j = 0; j < 1 + kw->skip; j++)
|
2007-06-22 17:34:31 +00:00
|
|
|
{
|
2007-06-23 16:49:15 +00:00
|
|
|
p = extract_name (p, name);
|
|
|
|
}
|
|
|
|
makeSimpleTag (name, BasicKinds, kw->kind);
|
2007-06-22 17:34:31 +00:00
|
|
|
vStringDelete (name);
|
2007-06-23 16:49:15 +00:00
|
|
|
return 1;
|
2007-06-22 17:34:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Match a "label:" style label. */
|
|
|
|
static void match_colon_label (char const *p)
|
|
|
|
{
|
|
|
|
char const *end = p + strlen (p) - 1;
|
|
|
|
while (isspace (*end))
|
|
|
|
end--;
|
|
|
|
if (*end == ':')
|
|
|
|
{
|
|
|
|
vString *name = vStringNew ();
|
|
|
|
vStringNCatS (name, p, end - p);
|
|
|
|
makeSimpleTag (name, BasicKinds, K_LABEL);
|
|
|
|
vStringDelete (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Match a ".label" style label. */
|
|
|
|
static void match_dot_label (char const *p)
|
|
|
|
{
|
|
|
|
if (*p == '.')
|
|
|
|
{
|
|
|
|
vString *name = vStringNew ();
|
|
|
|
extract_name (p + 1, name);
|
|
|
|
makeSimpleTag (name, BasicKinds, K_LABEL);
|
|
|
|
vStringDelete (name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void findBasicTags (KeyWord const keywords[],
|
|
|
|
void (*label) (const char *))
|
|
|
|
{
|
|
|
|
const char *line;
|
|
|
|
|
|
|
|
while ((line = (const char *) fileReadLine ()) != NULL)
|
|
|
|
{
|
|
|
|
const char *p = line;
|
|
|
|
KeyWord const *kw;
|
|
|
|
|
|
|
|
while (isspace (*p))
|
|
|
|
p++;
|
|
|
|
|
|
|
|
/* Empty line? */
|
|
|
|
if (!*p)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* In Basic, keywords always are at the start of the line. */
|
|
|
|
for (kw = keywords; kw->token; kw++)
|
2007-06-23 16:49:15 +00:00
|
|
|
if (match_keyword (p, kw)) break;
|
2007-06-22 17:34:31 +00:00
|
|
|
|
|
|
|
/* Is it a label? */
|
|
|
|
label (p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void findBlitzBasicTags (void)
|
|
|
|
{
|
|
|
|
findBasicTags (blitzbasic_keywords, match_dot_label);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void findPureBasicTags (void)
|
|
|
|
{
|
|
|
|
findBasicTags (purebasic_keywords, match_colon_label);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void findFreeBasicTags (void)
|
|
|
|
{
|
|
|
|
findBasicTags (freebasic_keywords, match_colon_label);
|
|
|
|
}
|
|
|
|
|
|
|
|
parserDefinition *BlitzBasicParser (void)
|
|
|
|
{
|
|
|
|
static char const *extensions[] = { "bb", NULL };
|
|
|
|
parserDefinition *def = parserNew ("BlitzBasic");
|
|
|
|
def->kinds = BasicKinds;
|
|
|
|
def->kindCount = KIND_COUNT (BasicKinds);
|
|
|
|
def->extensions = extensions;
|
|
|
|
def->parser = findBlitzBasicTags;
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
parserDefinition *PureBasicParser (void)
|
|
|
|
{
|
|
|
|
static char const *extensions[] = { "pb", NULL };
|
|
|
|
parserDefinition *def = parserNew ("PureBasic");
|
|
|
|
def->kinds = BasicKinds;
|
|
|
|
def->kindCount = KIND_COUNT (BasicKinds);
|
|
|
|
def->extensions = extensions;
|
|
|
|
def->parser = findPureBasicTags;
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
parserDefinition *FreeBasicParser (void)
|
|
|
|
{
|
|
|
|
static char const *extensions[] = { "bas", "bi", NULL };
|
|
|
|
parserDefinition *def = parserNew ("FreeBasic");
|
|
|
|
def->kinds = BasicKinds;
|
|
|
|
def->kindCount = KIND_COUNT (BasicKinds);
|
|
|
|
def->extensions = extensions;
|
|
|
|
def->parser = findFreeBasicTags;
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vi:set tabstop=4 shiftwidth=4: */
|