comparison 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
comparison
equal deleted inserted replaced
493:6073f4a33475 495:5b8871fd7503
1 /*
2 lwcc/token.c
3
4 Copyright © 2013 William Astle
5
6 This file is part of LWTOOLS.
7
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation, either version 3 of the License, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 You should have received a copy of the GNU General Public License along with
19 this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <stdlib.h>
23
24 #include <lw_alloc.h>
25 #include <lw_string.h>
26
27 #include "token.h"
28
29 struct token *token_create(int ttype, char *strval, int row, int col, const char *fn)
30 {
31 struct token *t;
32
33 t = lw_alloc(sizeof(struct token));
34 t -> ttype = ttype;
35 if (strval)
36 t -> strval = lw_strdup(strval);
37 else
38 t -> strval = NULL;
39 t -> lineno = row;
40 t -> column = col;
41 t -> fn = fn;
42 t -> next = NULL;
43 t -> prev = NULL;
44 t -> list = NULL;
45 return t;
46 }
47
48 void token_free(struct token *t)
49 {
50 lw_free(t -> strval);
51 lw_free(t);
52 }
53
54 struct token *token_dup(struct token *t)
55 {
56 struct token *t2;
57
58 t2 = lw_alloc(sizeof(struct token));
59 t2 -> ttype = t -> ttype;
60 t2 -> lineno = t -> lineno;
61 t2 -> column = t -> column;
62 t2 -> list = NULL;
63 t2 -> next = NULL;
64 t2 -> prev = NULL;
65 if (t -> strval)
66 t2 -> strval = lw_strdup(t -> strval);
67 else
68 t2 -> strval = NULL;
69 return t2;
70 }
71
72 static struct { int ttype; char *tstr; } tok_strs[] =
73 {
74 { TOK_WSPACE, " " },
75 { TOK_EOL, "\n" },
76 { TOK_DIV, "/" },
77 { TOK_ADD, "+" },
78 { TOK_SUB, "-" },
79 { TOK_OPAREN, "(" },
80 { TOK_CPAREN, ")" },
81 { TOK_NE, "!=" },
82 { TOK_EQ, "==" },
83 { TOK_LE, "<=" },
84 { TOK_LT, "<" },
85 { TOK_GE, ">=" },
86 { TOK_GT, ">" },
87 { TOK_BAND, "&&" },
88 { TOK_BOR, "||" },
89 { TOK_BNOT, "!" },
90 { TOK_MOD, "%"},
91 { TOK_COMMA, "," },
92 { TOK_ELLIPSIS, "..." },
93 { TOK_QMARK, "?" },
94 { TOK_COLON, ":" },
95 { TOK_OBRACE, "{" },
96 { TOK_CBRACE, "}" },
97 { TOK_OSQUARE, "[" },
98 { TOK_CSQUARE, "]" },
99 { TOK_COM, "~" },
100 { TOK_EOS, ";" },
101 { TOK_HASH, "#" },
102 { TOK_DBLHASH, "##" },
103 { TOK_XOR, "^" },
104 { TOK_XORASS, "^=" },
105 { TOK_STAR, "*" },
106 { TOK_MULASS, "*=" },
107 { TOK_DIVASS, "/=" },
108 { TOK_ASS, "=" },
109 { TOK_MODASS, "%=" },
110 { TOK_SUBASS, "-=" },
111 { TOK_DBLSUB, "--" },
112 { TOK_ADDASS, "+=" },
113 { TOK_DBLADD, "++" },
114 { TOK_BWAND, "&" },
115 { TOK_BWANDASS, "&=" },
116 { TOK_BWOR, "|" },
117 { TOK_BWORASS, "|=" },
118 { TOK_LSH, "<<" },
119 { TOK_LSHASS, "<<=" },
120 { TOK_RSH, ">>" },
121 { TOK_RSHASS, ">>=" },
122 { TOK_DOT, "." },
123 { TOK_ARROW, "->" },
124 { TOK_NONE, "" }
125 };
126
127 void token_print(struct token *t, FILE *f)
128 {
129 int i;
130 for (i = 0; tok_strs[i].ttype != TOK_NONE; i++)
131 {
132 if (tok_strs[i].ttype == t -> ttype)
133 {
134 fprintf(f, "%s", tok_strs[i].tstr);
135 break;
136 }
137 }
138 if (t -> strval)
139 fprintf(f, "%s", t -> strval);
140 }
141
142 /* token list management */
143 struct token_list *token_list_create(void)
144 {
145 struct token_list *tl;
146 tl = lw_alloc(sizeof(struct token_list));
147 tl -> head = NULL;
148 tl -> tail = NULL;
149 return tl;
150 }
151
152 void token_list_destroy(struct token_list *tl)
153 {
154 if (tl == NULL)
155 return;
156 while (tl -> head)
157 {
158 tl -> tail = tl -> head;
159 tl -> head = tl -> head -> next;
160 token_free(tl -> tail);
161 }
162 lw_free(tl);
163 }
164
165 void token_list_append(struct token_list *tl, struct token *tok)
166 {
167 tok -> list = tl;
168 if (tl -> head == NULL)
169 {
170 tl -> head = tl -> tail = tok;
171 tok -> next = tok -> prev = NULL;
172 return;
173 }
174 tl -> tail -> next = tok;
175 tok -> prev = tl -> tail;
176 tl -> tail = tok;
177 tok -> next = NULL;
178 return;
179 }
180
181 void token_list_remove(struct token *tok)
182 {
183 if (tok -> list == NULL)
184 return;
185
186 if (tok -> prev)
187 tok -> prev -> next = tok -> next;
188 if (tok -> next)
189 tok -> next -> prev = tok -> prev;
190 if (tok == tok -> list -> head)
191 tok -> list -> head = tok -> next;
192 if (tok == tok -> list -> tail)
193 tok -> list -> tail = tok -> prev;
194 tok -> list = NULL;
195 }
196
197 void token_list_prepend(struct token_list *tl, struct token *tok)
198 {
199 tok -> list = tl;
200 if (tl -> head == NULL)
201 {
202 tl -> head = tl -> tail = tok;
203 tok -> next = tok -> prev = NULL;
204 }
205 tl -> head -> prev = tok;
206 tok -> next = tl -> head;
207 tl -> head = tok;
208 tok -> prev = NULL;
209 }
210
211 void token_list_insert(struct token_list *tl, struct token *after, struct token *newt)
212 {
213 struct token *t;
214
215 if (after == NULL || tl -> head == NULL)
216 {
217 token_list_prepend(tl, newt);
218 return;
219 }
220
221 for (t = tl -> head; t && t != after; t = t -> next)
222 /* do nothing */ ;
223 if (!t)
224 {
225 token_list_append(tl, newt);
226 return;
227 }
228 newt -> prev = t;
229 newt -> next = t -> next;
230 if (t -> next)
231 t -> next -> prev = newt;
232 else
233 tl -> tail = newt;
234 t -> next = newt;
235 }
236
237 struct token_list *token_list_dup(struct token_list *tl)
238 {
239 struct token_list *nl;
240 struct token *t;
241
242 nl = token_list_create();
243 for (t = tl -> head; t; t = t -> next)
244 {
245 token_list_append(nl, token_dup(t));
246 }
247 return nl;
248 }