#include "gmqcc.h"
#include "lexer.h"
+/*
+ * List of Keywords
+ */
+
+/* original */
+static const char *keywords_qc[] = {
+ "for", "do", "while",
+ "if", "else",
+ "local",
+ "return",
+ "const"
+};
+static size_t num_keywords_qc = sizeof(keywords_qc) / sizeof(keywords_qc[0]);
+
+/* For fte/gmgqcc */
+static const char *keywords_fg[] = {
+ "var",
+ "switch", "case", "default",
+ "struct", "union",
+ "break", "continue"
+};
+static size_t num_keywords_fg = sizeof(keywords_fg) / sizeof(keywords_fg[0]);
+
+/*
+ * Lexer code
+ */
+
char* *lex_filenames;
void lexerror(lex_file *lex, const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- va_start(ap, fmt);
- if (lex)
+ va_start(ap, fmt);
+ if (lex)
con_vprintmsg(LVL_ERROR, lex->name, lex->sline, "parse error", fmt, ap);
else
con_vprintmsg(LVL_ERROR, "", 0, "parse error", fmt, ap);
- va_end(ap);
+ va_end(ap);
}
bool lexwarn(lex_file *lex, int warntype, const char *fmt, ...)
{
- va_list ap;
- int lvl = LVL_WARNING;
+ va_list ap;
+ int lvl = LVL_WARNING;
if (!OPTS_WARN(warntype))
return false;
if (opts_werror)
- lvl = LVL_ERROR;
+ lvl = LVL_ERROR;
- va_start(ap, fmt);
+ va_start(ap, fmt);
con_vprintmsg(lvl, lex->name, lex->sline, "warning", fmt, ap);
- va_end(ap);
+ va_end(ap);
- return opts_werror;
+ return opts_werror;
}
goto unroll;
lex->line = line;
- while (ch != '\n')
+ while (ch != '\n' && ch != EOF)
ch = lex_getch(lex);
return true;
{
case '[':
case '(':
+ case ':':
+ case '?':
lex_tokench(lex, ch);
lex_endtoken(lex);
if (lex->flags.noops)
return (lex->tok.ttype = TOKEN_OPERATOR);
case ')':
case ';':
- case ':':
case '{':
case '}':
case ']':
} else if (!strcmp(v, "vector")) {
lex->tok.ttype = TOKEN_TYPENAME;
lex->tok.constval.t = TYPE_VECTOR;
- } else if (!strcmp(v, "for") ||
- !strcmp(v, "while") ||
- !strcmp(v, "do") ||
- !strcmp(v, "if") ||
- !strcmp(v, "else") ||
- !strcmp(v, "local") ||
- !strcmp(v, "return") ||
- !strcmp(v, "not") ||
- !strcmp(v, "const"))
- {
- lex->tok.ttype = TOKEN_KEYWORD;
- }
- else if (opts_standard != COMPILER_QCC)
- {
- /* other standards reserve these keywords */
- if (!strcmp(v, "switch") ||
- !strcmp(v, "struct") ||
- !strcmp(v, "union") ||
- !strcmp(v, "break") ||
- !strcmp(v, "continue") ||
- !strcmp(v, "var"))
- {
- lex->tok.ttype = TOKEN_KEYWORD;
+ } else {
+ size_t kw;
+ for (kw = 0; kw < num_keywords_qc; ++kw) {
+ if (!strcmp(v, keywords_qc[kw]))
+ return (lex->tok.ttype = TOKEN_KEYWORD);
+ }
+ if (opts_standard != COMPILER_QCC) {
+ for (kw = 0; kw < num_keywords_fg; ++kw) {
+ if (!strcmp(v, keywords_fg[kw]))
+ return (lex->tok.ttype = TOKEN_KEYWORD);
+ }
}
}