Mercurial > hg > index.cgi
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 } |