X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=lexer.c;h=8d6f09442bb0d2b76e4ba6e314d923d17a2743ec;hp=5e0414b5b9f075868ed9cf45852977e7240b6ed1;hb=18fad16a7d5bc7e981e2824c7a5ade68ce9a2064;hpb=0d839bd13872ef5ebd9bc47e5c094b431c870c78 diff --git a/lexer.c b/lexer.c index 5e0414b..8d6f094 100644 --- a/lexer.c +++ b/lexer.c @@ -184,7 +184,7 @@ static void lex_token_new(lex_file *lex) lex_file* lex_open(const char *file) { lex_file *lex; - FILE *in = file_open(file, "rb"); + FILE *in = fs_file_open(file, "rb"); if (!in) { lexerror(NULL, "open failed: '%s'\n", file); @@ -193,7 +193,7 @@ lex_file* lex_open(const char *file) lex = (lex_file*)mem_a(sizeof(*lex)); if (!lex) { - file_close(in); + fs_file_close(in); lexerror(NULL, "out of memory\n"); return NULL; } @@ -258,7 +258,7 @@ void lex_close(lex_file *lex) vec_free(lex->modelname); if (lex->file) - file_close(lex->file); + fs_file_close(lex->file); #if 0 if (lex->tok) token_delete(lex->tok); @@ -272,7 +272,7 @@ void lex_close(lex_file *lex) static int lex_fgetc(lex_file *lex) { if (lex->file) - return fgetc(lex->file); + return fs_file_getc(lex->file); if (lex->open_string) { if (lex->open_string_pos >= lex->open_string_length) return EOF; @@ -291,12 +291,16 @@ static int lex_try_trigraph(lex_file *lex, int old) { int c2, c3; c2 = lex_fgetc(lex); + if (!lex->push_line && c2 == '\n') + lex->line++; if (c2 != '?') { lex_ungetch(lex, c2); return old; } c3 = lex_fgetc(lex); + if (!lex->push_line && c3 == '\n') + lex->line++; switch (c3) { case '=': return '#'; case '/': return '\\'; @@ -988,6 +992,8 @@ int lex_do(lex_file *lex) if (!lex->flags.mergelines || ch != '\\') break; ch = lex_getch(lex); + if (ch == '\r') + ch = lex_getch(lex); if (ch != '\n') { lex_ungetch(lex, ch); ch = '\\'; @@ -1226,7 +1232,7 @@ int lex_do(lex_file *lex) /* case '+': case '-': - */ + */ case '*': case '/': case '<': @@ -1244,31 +1250,37 @@ int lex_do(lex_file *lex) default: break; } + } - if (ch == '.') - { - lex_tokench(lex, ch); - /* peak ahead once */ - nextch = lex_getch(lex); - if (nextch != '.') { - lex_ungetch(lex, nextch); - lex_endtoken(lex); - return (lex->tok.ttype = ch); - } - /* peak ahead again */ - nextch = lex_getch(lex); - if (nextch != '.') { - lex_ungetch(lex, nextch); - lex_ungetch(lex, '.'); - lex_endtoken(lex); + if (ch == '.') + { + lex_tokench(lex, ch); + /* peak ahead once */ + nextch = lex_getch(lex); + if (nextch != '.') { + lex_ungetch(lex, nextch); + lex_endtoken(lex); + if (lex->flags.noops) return (lex->tok.ttype = ch); - } - /* fill the token to be "..." */ - lex_tokench(lex, ch); - lex_tokench(lex, ch); + else + return (lex->tok.ttype = TOKEN_OPERATOR); + } + /* peak ahead again */ + nextch = lex_getch(lex); + if (nextch != '.') { + lex_ungetch(lex, nextch); + lex_ungetch(lex, '.'); lex_endtoken(lex); - return (lex->tok.ttype = TOKEN_DOTS); + if (lex->flags.noops) + return (lex->tok.ttype = ch); + else + return (lex->tok.ttype = TOKEN_OPERATOR); } + /* fill the token to be "..." */ + lex_tokench(lex, ch); + lex_tokench(lex, ch); + lex_endtoken(lex); + return (lex->tok.ttype = TOKEN_DOTS); } if (ch == ',' || ch == '.') { @@ -1278,15 +1290,23 @@ int lex_do(lex_file *lex) } if (ch == '+' || ch == '-' || /* ++, --, +=, -= and -> as well! */ - ch == '>' || ch == '<' || /* <<, >>, <=, >= */ - ch == '=' || ch == '!' || /* ==, != */ - ch == '&' || ch == '|') /* &&, ||, &=, |= */ - { + ch == '>' || ch == '<' || /* <<, >>, <=, >= */ + ch == '=' || ch == '!' || /* <=>, ==, != */ + ch == '&' || ch == '|' || /* &&, ||, &=, |= */ + ch == '~' /* ~=, ~ */ + ) { lex_tokench(lex, ch); nextch = lex_getch(lex); - if (nextch == '=' || (nextch == ch && ch != '!')) { + if ((nextch == '=' && ch != '<') || (nextch == ch && ch != '!')) { + lex_tokench(lex, nextch); + } else if (ch == '<' && nextch == '=') { lex_tokench(lex, nextch); + if ((thirdch = lex_getch(lex)) == '>') + lex_tokench(lex, thirdch); + else + lex_ungetch(lex, thirdch); + } else if (ch == '-' && nextch == '>') { lex_tokench(lex, nextch); } else if (ch == '&' && nextch == '~') { @@ -1299,8 +1319,20 @@ int lex_do(lex_file *lex) lex_tokench(lex, nextch); lex_tokench(lex, thirdch); } - } else + } + else if (lex->flags.preprocessing && + ch == '-' && isdigit(nextch)) + { + lex->tok.ttype = lex_finish_digit(lex, nextch); + if (lex->tok.ttype == TOKEN_INTCONST) + lex->tok.constval.i = -lex->tok.constval.i; + else + lex->tok.constval.f = -lex->tok.constval.f; + lex_endtoken(lex); + return lex->tok.ttype; + } else { lex_ungetch(lex, nextch); + } lex_endtoken(lex); return (lex->tok.ttype = TOKEN_OPERATOR); @@ -1320,7 +1352,7 @@ int lex_do(lex_file *lex) lex_tokench(lex, ch); nextch = lex_getch(lex); - if (nextch == '=') { + if (nextch == '=' || nextch == '*') { lex_tokench(lex, nextch); } else lex_ungetch(lex, nextch); @@ -1329,6 +1361,12 @@ int lex_do(lex_file *lex) return (lex->tok.ttype = TOKEN_OPERATOR); } + if (ch == '%') { + lex_tokench(lex, ch); + lex_endtoken(lex); + return (lex->tok.ttype = TOKEN_OPERATOR); + } + if (isident_start(ch)) { const char *v; @@ -1366,7 +1404,7 @@ int lex_do(lex_file *lex) if (!strcmp(v, keywords_qc[kw])) return (lex->tok.ttype = TOKEN_KEYWORD); } - if (opts.standard != COMPILER_QCC) { + if (OPTS_OPTION_U32(OPTION_STANDARD) != COMPILER_QCC) { for (kw = 0; kw < num_keywords_fg; ++kw) { if (!strcmp(v, keywords_fg[kw])) return (lex->tok.ttype = TOKEN_KEYWORD); @@ -1463,6 +1501,6 @@ int lex_do(lex_file *lex) return (lex->tok.ttype = ch); } - lexerror(lex, "unknown token"); + lexerror(lex, "unknown token: `%s`", lex->tok.value); return (lex->tok.ttype = TOKEN_ERROR); }