X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=lexer.c;h=c6e8552c063a89df6cf23a9ac411afe23653f9eb;hb=f4043faf0b4963550463a3b81dc38b12c6f5d91f;hp=c28ad8815e49edfde9d5b3d204c938ef49faa37e;hpb=79619fbf50c473672f268b27b8c667f0a2e83271;p=xonotic%2Fgmqcc.git diff --git a/lexer.c b/lexer.c index c28ad88..c6e8552 100644 --- a/lexer.c +++ b/lexer.c @@ -6,36 +6,63 @@ #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; } @@ -353,10 +380,13 @@ static bool lex_try_pragma(lex_file *lex) char *pragma = NULL; char *command = NULL; char *param = NULL; + size_t line; if (lex->flags.preprocessing) return false; + line = lex->line; + ch = lex_getch(lex); if (ch != '#') { lex_ungetch(lex, ch); @@ -393,7 +423,7 @@ static bool lex_try_pragma(lex_file *lex) if (!strcmp(command, "push")) { if (!strcmp(param, "line")) { lex->push_line++; - lex->line--; + --line; } else goto unroll; @@ -402,15 +432,23 @@ static bool lex_try_pragma(lex_file *lex) if (!strcmp(param, "line")) { if (lex->push_line) lex->push_line--; - lex->line--; + --line; } else goto unroll; } + else if (!strcmp(command, "file")) { + lex->name = util_strdup(param); + vec_push(lex_filenames, lex->name); + } + else if (!strcmp(command, "line")) { + line = strtol(param, NULL, 0)-1; + } else goto unroll; - while (ch != '\n') + lex->line = line; + while (ch != '\n' && ch != EOF) ch = lex_getch(lex); return true; @@ -440,6 +478,8 @@ unroll: vec_free(pragma); } lex_ungetch(lex, '#'); + + lex->line = line; return false; } @@ -485,10 +525,8 @@ static int lex_skipwhite(lex_file *lex) ch = lex_getch(lex); while (ch != EOF && isspace(ch)) { if (ch == '\n') { - if (lex_try_pragma(lex)) { - ch = lex_getch(lex); + if (lex_try_pragma(lex)) continue; - } } if (lex->flags.preprocessing) { if (ch == '\n') { @@ -1136,29 +1174,17 @@ int lex_do(lex_file *lex) } 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); + } } }