X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=lexer.c;h=d39a0e5633a1a0392cfebdb00ec9e72de9052387;hb=23d16b303d6b2c3c2fa375a2163519b23f4541cb;hp=25cf4e180a1aa4a842ba6affad71d3d5561937c4;hpb=e4998e0798c8e66fa0a50ea591fed8a2d03645b5;p=xonotic%2Fgmqcc.git diff --git a/lexer.c b/lexer.c index 25cf4e1..d39a0e5 100644 --- a/lexer.c +++ b/lexer.c @@ -1,3 +1,25 @@ +/* + * Copyright (C) 2012 + * Wolfgang Bumiller + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ #include #include #include @@ -6,36 +28,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[] = { + "switch", "case", "default", + "struct", "union", + "break", "continue", + "typedef" +}; +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; } @@ -577,9 +626,13 @@ static int lex_skipwhite(lex_file *lex) } break; } + lex_ungetch(lex, ch); } if (lex->flags.preprocessing) { - lex_tokench(lex, ' '); /* ch); */ + if (ch == '\n') + lex_tokench(lex, '\n'); + else + lex_tokench(lex, ' '); /* ch); */ } } ch = ' '; /* cause TRUE in the isspace check */ @@ -807,7 +860,7 @@ static int GMQCC_WARN lex_finish_digit(lex_file *lex, int lastch) int lex_do(lex_file *lex) { - int ch, nextch; + int ch, nextch, thirdch; lex_token_new(lex); #if 0 @@ -953,9 +1006,9 @@ int lex_do(lex_file *lex) if (!strcmp(v, "flush")) { - size_t frame; - for (frame = 0; frame < vec_size(lex->frames); ++frame) - mem_d(lex->frames[frame].name); + size_t fi; + for (fi = 0; fi < vec_size(lex->frames); ++fi) + mem_d(lex->frames[fi].name); vec_free(lex->frames); /* skip line (fteqcc does it too) */ ch = lex_getch(lex); @@ -994,6 +1047,8 @@ int lex_do(lex_file *lex) { case '[': case '(': + case ':': + case '?': lex_tokench(lex, ch); lex_endtoken(lex); if (lex->flags.noops) @@ -1002,7 +1057,6 @@ int lex_do(lex_file *lex) return (lex->tok.ttype = TOKEN_OPERATOR); case ')': case ';': - case ':': case '{': case '}': case ']': @@ -1086,6 +1140,16 @@ int lex_do(lex_file *lex) lex_tokench(lex, nextch); } else if (ch == '-' && nextch == '>') { lex_tokench(lex, nextch); + } else if (ch == '&' && nextch == '~') { + thirdch = lex_getch(lex); + if (thirdch != '=') { + lex_ungetch(lex, thirdch); + lex_ungetch(lex, nextch); + } + else { + lex_tokench(lex, nextch); + lex_tokench(lex, thirdch); + } } else lex_ungetch(lex, nextch); @@ -1147,29 +1211,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); + } } }