X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=lexer.c;h=9ed9c39f25742afd29caff28e37578e3bfb6aebe;hp=03d1308597d0fa0ec94b8e1e67b9afa20f2d95d3;hb=624e6201e8c512725f8ee7a9168b21def43df45a;hpb=1d347eaf664ab3656e60b8434f46d6826dd58483 diff --git a/lexer.c b/lexer.c index 03d1308..9ed9c39 100644 --- a/lexer.c +++ b/lexer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 + * Copyright (C) 2012, 2013, 2014 * Wolfgang Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -82,91 +82,8 @@ static bool lexwarn(lex_file *lex, int warntype, const char *fmt, ...) return r; } - -#if 0 -token* token_new() -{ - token *tok = (token*)mem_a(sizeof(token)); - if (!tok) - return NULL; - memset(tok, 0, sizeof(*tok)); - return tok; -} - -void token_delete(token *self) -{ - if (self->next && self->next->prev == self) - self->next->prev = self->prev; - if (self->prev && self->prev->next == self) - self->prev->next = self->next; - MEM_VECTOR_CLEAR(self, value); - mem_d(self); -} - -token* token_copy(const token *cp) -{ - token* self = token_new(); - if (!self) - return NULL; - /* copy the value */ - self->value_alloc = cp->value_count + 1; - self->value_count = cp->value_count; - self->value = (char*)mem_a(self->value_alloc); - if (!self->value) { - mem_d(self); - return NULL; - } - memcpy(self->value, cp->value, cp->value_count); - self->value[self->value_alloc-1] = 0; - - /* rest */ - self->ctx = cp->ctx; - self->ttype = cp->ttype; - memcpy(&self->constval, &cp->constval, sizeof(self->constval)); - return self; -} - -void token_delete_all(token *t) -{ - token *n; - - do { - n = t->next; - token_delete(t); - t = n; - } while(t); -} - -token* token_copy_all(const token *cp) -{ - token *cur; - token *out; - - out = cur = token_copy(cp); - if (!out) - return NULL; - - while (cp->next) { - cp = cp->next; - cur->next = token_copy(cp); - if (!cur->next) { - token_delete_all(out); - return NULL; - } - cur->next->prev = cur; - cur = cur->next; - } - - return out; -} -#else static void lex_token_new(lex_file *lex) { -#if 0 - if (lex->tok) - token_delete(lex->tok); - lex->tok = token_new(); -#else if (lex->tok.value) vec_shrinkto(lex->tok.value, 0); @@ -174,9 +91,7 @@ static void lex_token_new(lex_file *lex) lex->tok.ctx.line = lex->sline; lex->tok.ctx.file = lex->name; lex->tok.ctx.column = lex->column; -#endif } -#endif static void lex_ungetch(lex_file *lex, int ch); static int lex_getch(lex_file *lex); @@ -273,12 +188,9 @@ void lex_close(lex_file *lex) if (lex->file) fs_file_close(lex->file); -#if 0 - if (lex->tok) - token_delete(lex->tok); -#else + vec_free(lex->tok.value); -#endif + /* mem_d(lex->name); collected in lex_filenames */ mem_d(lex); } @@ -624,10 +536,6 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) if (lex->flags.preprocessing) { haswhite = true; - /* - lex_tokench(lex, '/'); - lex_tokench(lex, '/'); - */ lex_tokench(lex, ' '); lex_tokench(lex, ' '); } @@ -649,10 +557,6 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) /* multiline comment */ if (lex->flags.preprocessing) { haswhite = true; - /* - lex_tokench(lex, '/'); - lex_tokench(lex, '*'); - */ lex_tokench(lex, ' '); lex_tokench(lex, ' '); } @@ -664,10 +568,6 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) ch = lex_getch(lex); if (ch == '/') { if (lex->flags.preprocessing) { - /* - lex_tokench(lex, '*'); - lex_tokench(lex, '/'); - */ lex_tokench(lex, ' '); lex_tokench(lex, ' '); } @@ -679,7 +579,7 @@ static int lex_skipwhite(lex_file *lex, bool hadwhite) if (ch == '\n') lex_tokench(lex, '\n'); else - lex_tokench(lex, ' '); /* ch); */ + lex_tokench(lex, ' '); } } ch = ' '; /* cause TRUE in the isspace check */ @@ -781,7 +681,7 @@ static bool lex_finish_frames(lex_file *lex) static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) { utf8ch_t chr = 0; - int ch = 0; + int ch = 0, texttype = 0; int nextch; bool hex; bool oct; @@ -816,13 +716,12 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) case '\\': break; case '\'': break; case '"': break; - case 'a': ch = '\a'; break; - case 'b': ch = '\b'; break; - case 'r': ch = '\r'; break; - case 'n': ch = '\n'; break; - case 't': ch = '\t'; break; - case 'f': ch = '\f'; break; - case 'v': ch = '\v'; break; + case 'a': ch = '\a'; break; + case 'r': ch = '\r'; break; + case 'n': ch = '\n'; break; + case 't': ch = '\t'; break; + case 'f': ch = '\f'; break; + case 'v': ch = '\v'; break; case 'x': case 'X': /* same procedure as in fteqcc */ @@ -925,7 +824,15 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) else ch = chr; break; - case '\n': ch = '\n'; break; + + /* high bit text */ + case 'b': case 's': + texttype ^= 128; + continue; + + case '\n': + ch = '\n'; + break; default: lexwarn(lex, WARN_UNKNOWN_CONTROL_SEQUENCE, "unrecognized control sequence: \\%c", ch); @@ -933,7 +840,7 @@ static int GMQCC_WARN lex_finish_string(lex_file *lex, int quote) lex_tokench(lex, '\\'); } /* add the character finally */ - lex_tokench(lex, ch); + lex_tokench(lex, ch | texttype); } else lex_tokench(lex, ch); @@ -1026,10 +933,6 @@ int lex_do(lex_file *lex) bool hadwhite = false; lex_token_new(lex); -#if 0 - if (!lex->tok) - return TOKEN_FATAL; -#endif while (true) { ch = lex_skipwhite(lex, hadwhite); @@ -1274,10 +1177,6 @@ int lex_do(lex_file *lex) */ switch (ch) { - /* - case '+': - case '-': - */ case '*': case '/': case '<': @@ -1341,12 +1240,16 @@ int lex_do(lex_file *lex) ch == '~' || ch == '^' /* ~=, ~, ^ */ ) { lex_tokench(lex, ch); - nextch = lex_getch(lex); - if ((nextch == '=' && ch != '<') || - (nextch == ch && ch != '!') || - (nextch == '<' && ch == '>')) { + + if ((nextch == '=' && ch != '<') || (nextch == '<' && ch == '>')) + lex_tokench(lex, nextch); + else if (nextch == ch && ch != '!') { 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); if ((thirdch = lex_getch(lex)) == '>') @@ -1385,15 +1288,6 @@ int lex_do(lex_file *lex) return (lex->tok.ttype = TOKEN_OPERATOR); } - /* - if (ch == '^' || ch == '~' || ch == '!') - { - lex_tokench(lex, ch); - lex_endtoken(lex); - return (lex->tok.ttype = TOKEN_OPERATOR); - } - */ - if (ch == '*' || ch == '/') /* *=, /= */ { lex_tokench(lex, ch); @@ -1445,6 +1339,8 @@ 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, "_length")) { + lex->tok.ttype = TOKEN_OPERATOR; } else { size_t kw; for (kw = 0; kw < GMQCC_ARRAY_COUNT(keywords_qc); ++kw) {