Mercurial > hg > index.cgi
diff lwcc/token.c @ 495:5b8871fd7503
Merged previous lwcc development branch into mainline.
author | William Astle <lost@l-w.ca> |
---|---|
date | Mon, 05 Aug 2019 21:27:09 -0600 |
parents | 54f213c8fb81 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lwcc/token.c Mon Aug 05 21:27:09 2019 -0600 @@ -0,0 +1,248 @@ +/* +lwcc/token.c + +Copyright © 2013 William Astle + +This file is part of LWTOOLS. + +LWTOOLS is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> + +#include <lw_alloc.h> +#include <lw_string.h> + +#include "token.h" + +struct token *token_create(int ttype, char *strval, int row, int col, const char *fn) +{ + struct token *t; + + t = lw_alloc(sizeof(struct token)); + t -> ttype = ttype; + if (strval) + t -> strval = lw_strdup(strval); + else + t -> strval = NULL; + t -> lineno = row; + t -> column = col; + t -> fn = fn; + t -> next = NULL; + t -> prev = NULL; + t -> list = NULL; + return t; +} + +void token_free(struct token *t) +{ + lw_free(t -> strval); + lw_free(t); +} + +struct token *token_dup(struct token *t) +{ + struct token *t2; + + t2 = lw_alloc(sizeof(struct token)); + t2 -> ttype = t -> ttype; + t2 -> lineno = t -> lineno; + t2 -> column = t -> column; + t2 -> list = NULL; + t2 -> next = NULL; + t2 -> prev = NULL; + if (t -> strval) + t2 -> strval = lw_strdup(t -> strval); + else + t2 -> strval = NULL; + return t2; +} + +static struct { int ttype; char *tstr; } tok_strs[] = +{ + { TOK_WSPACE, " " }, + { TOK_EOL, "\n" }, + { TOK_DIV, "/" }, + { TOK_ADD, "+" }, + { TOK_SUB, "-" }, + { TOK_OPAREN, "(" }, + { TOK_CPAREN, ")" }, + { TOK_NE, "!=" }, + { TOK_EQ, "==" }, + { TOK_LE, "<=" }, + { TOK_LT, "<" }, + { TOK_GE, ">=" }, + { TOK_GT, ">" }, + { TOK_BAND, "&&" }, + { TOK_BOR, "||" }, + { TOK_BNOT, "!" }, + { TOK_MOD, "%"}, + { TOK_COMMA, "," }, + { TOK_ELLIPSIS, "..." }, + { TOK_QMARK, "?" }, + { TOK_COLON, ":" }, + { TOK_OBRACE, "{" }, + { TOK_CBRACE, "}" }, + { TOK_OSQUARE, "[" }, + { TOK_CSQUARE, "]" }, + { TOK_COM, "~" }, + { TOK_EOS, ";" }, + { TOK_HASH, "#" }, + { TOK_DBLHASH, "##" }, + { TOK_XOR, "^" }, + { TOK_XORASS, "^=" }, + { TOK_STAR, "*" }, + { TOK_MULASS, "*=" }, + { TOK_DIVASS, "/=" }, + { TOK_ASS, "=" }, + { TOK_MODASS, "%=" }, + { TOK_SUBASS, "-=" }, + { TOK_DBLSUB, "--" }, + { TOK_ADDASS, "+=" }, + { TOK_DBLADD, "++" }, + { TOK_BWAND, "&" }, + { TOK_BWANDASS, "&=" }, + { TOK_BWOR, "|" }, + { TOK_BWORASS, "|=" }, + { TOK_LSH, "<<" }, + { TOK_LSHASS, "<<=" }, + { TOK_RSH, ">>" }, + { TOK_RSHASS, ">>=" }, + { TOK_DOT, "." }, + { TOK_ARROW, "->" }, + { TOK_NONE, "" } +}; + +void token_print(struct token *t, FILE *f) +{ + int i; + for (i = 0; tok_strs[i].ttype != TOK_NONE; i++) + { + if (tok_strs[i].ttype == t -> ttype) + { + fprintf(f, "%s", tok_strs[i].tstr); + break; + } + } + if (t -> strval) + fprintf(f, "%s", t -> strval); +} + +/* token list management */ +struct token_list *token_list_create(void) +{ + struct token_list *tl; + tl = lw_alloc(sizeof(struct token_list)); + tl -> head = NULL; + tl -> tail = NULL; + return tl; +} + +void token_list_destroy(struct token_list *tl) +{ + if (tl == NULL) + return; + while (tl -> head) + { + tl -> tail = tl -> head; + tl -> head = tl -> head -> next; + token_free(tl -> tail); + } + lw_free(tl); +} + +void token_list_append(struct token_list *tl, struct token *tok) +{ + tok -> list = tl; + if (tl -> head == NULL) + { + tl -> head = tl -> tail = tok; + tok -> next = tok -> prev = NULL; + return; + } + tl -> tail -> next = tok; + tok -> prev = tl -> tail; + tl -> tail = tok; + tok -> next = NULL; + return; +} + +void token_list_remove(struct token *tok) +{ + if (tok -> list == NULL) + return; + + if (tok -> prev) + tok -> prev -> next = tok -> next; + if (tok -> next) + tok -> next -> prev = tok -> prev; + if (tok == tok -> list -> head) + tok -> list -> head = tok -> next; + if (tok == tok -> list -> tail) + tok -> list -> tail = tok -> prev; + tok -> list = NULL; +} + +void token_list_prepend(struct token_list *tl, struct token *tok) +{ + tok -> list = tl; + if (tl -> head == NULL) + { + tl -> head = tl -> tail = tok; + tok -> next = tok -> prev = NULL; + } + tl -> head -> prev = tok; + tok -> next = tl -> head; + tl -> head = tok; + tok -> prev = NULL; +} + +void token_list_insert(struct token_list *tl, struct token *after, struct token *newt) +{ + struct token *t; + + if (after == NULL || tl -> head == NULL) + { + token_list_prepend(tl, newt); + return; + } + + for (t = tl -> head; t && t != after; t = t -> next) + /* do nothing */ ; + if (!t) + { + token_list_append(tl, newt); + return; + } + newt -> prev = t; + newt -> next = t -> next; + if (t -> next) + t -> next -> prev = newt; + else + tl -> tail = newt; + t -> next = newt; +} + +struct token_list *token_list_dup(struct token_list *tl) +{ + struct token_list *nl; + struct token *t; + + nl = token_list_create(); + for (t = tl -> head; t; t = t -> next) + { + token_list_append(nl, token_dup(t)); + } + return nl; +}