1 /* Lists of symbols for Bison 2 3 Copyright (C) 2002, 2005-2007, 2009-2012 Free Software Foundation, 4 Inc. 5 6 This file is part of Bison, the GNU Compiler Compiler. 7 8 This program is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include <config.h> 22 #include "system.h" 23 24 #include "complain.h" 25 #include "symlist.h" 26 27 28 /*--------------------------------------. 29 | Create a list containing SYM at LOC. | 30 `--------------------------------------*/ 31 32 symbol_list * 33 symbol_list_sym_new (symbol *sym, location loc) 34 { 35 symbol_list *res = xmalloc (sizeof *res); 36 37 res->content_type = SYMLIST_SYMBOL; 38 res->content.sym = sym; 39 res->location = res->sym_loc = loc; 40 41 res->midrule = NULL; 42 res->midrule_parent_rule = NULL; 43 res->midrule_parent_rhs_index = 0; 44 45 code_props_none_init (&res->action_props); 46 47 res->ruleprec = NULL; 48 res->dprec = 0; 49 res->merger = 0; 50 51 res->named_ref = NULL; 52 53 res->next = NULL; 54 55 return res; 56 } 57 58 59 /*--------------------------------------------. 60 | Create a list containing TYPE_NAME at LOC. | 61 `--------------------------------------------*/ 62 63 symbol_list * 64 symbol_list_type_new (uniqstr type_name, location loc) 65 { 66 symbol_list *res = xmalloc (sizeof *res); 67 68 res->content_type = SYMLIST_TYPE; 69 res->content.type_name = type_name; 70 res->location = res->sym_loc = loc; 71 res->named_ref = NULL; 72 res->next = NULL; 73 74 return res; 75 } 76 77 78 /*----------------------------------------. 79 | Create a list containing a <*> at LOC. | 80 `----------------------------------------*/ 81 82 symbol_list * 83 symbol_list_default_tagged_new (location loc) 84 { 85 symbol_list *res = xmalloc (sizeof *res); 86 87 res->content_type = SYMLIST_DEFAULT_TAGGED; 88 res->location = res->sym_loc = loc; 89 res->named_ref = NULL; 90 res->next = NULL; 91 92 return res; 93 } 94 95 96 /*---------------------------------------. 97 | Create a list containing a <> at LOC. | 98 `---------------------------------------*/ 99 100 symbol_list * 101 symbol_list_default_tagless_new (location loc) 102 { 103 symbol_list *res = xmalloc (sizeof *res); 104 105 res->content_type = SYMLIST_DEFAULT_TAGLESS; 106 res->location = res->sym_loc = loc; 107 res->named_ref = NULL; 108 res->next = NULL; 109 110 return res; 111 } 112 113 114 /*-----------------------------------------------------------------------. 115 | Print this list, for which every content_type must be SYMLIST_SYMBOL. | 116 `-----------------------------------------------------------------------*/ 117 118 void 119 symbol_list_syms_print (const symbol_list *l, FILE *f) 120 { 121 for (/* Nothing. */; l && l->content.sym; l = l->next) 122 { 123 symbol_print (l->content.sym, f); 124 fprintf (stderr, l->action_props.is_value_used ? " used" : " unused"); 125 if (l && l->content.sym) 126 fprintf (f, ", "); 127 } 128 } 129 130 131 /*---------------------------. 132 | Prepend NODE to the LIST. | 133 `---------------------------*/ 134 135 symbol_list * 136 symbol_list_prepend (symbol_list *list, symbol_list *node) 137 { 138 node->next = list; 139 return node; 140 } 141 142 143 /*-----------------------------------------------. 144 | Free the LIST, but not the items it contains. | 145 `-----------------------------------------------*/ 146 147 void 148 symbol_list_free (symbol_list *list) 149 { 150 symbol_list *node, *next; 151 for (node = list; node; node = next) 152 { 153 next = node->next; 154 named_ref_free (node->named_ref); 155 free (node); 156 } 157 } 158 159 160 /*--------------------. 161 | Return its length. | 162 `--------------------*/ 163 164 int 165 symbol_list_length (symbol_list const *l) 166 { 167 int res = 0; 168 for (/* Nothing. */; 169 l && !(l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL); 170 l = l->next) 171 ++res; 172 return res; 173 } 174 175 176 /*------------------------------. 177 | Get item N in symbol list L. | 178 `------------------------------*/ 179 180 symbol_list * 181 symbol_list_n_get (symbol_list *l, int n) 182 { 183 int i; 184 185 if (n < 0) 186 return NULL; 187 188 for (i = 0; i < n; ++i) 189 { 190 l = l->next; 191 if (l == NULL 192 || (l->content_type == SYMLIST_SYMBOL && l->content.sym == NULL)) 193 return NULL; 194 } 195 196 return l; 197 } 198 199 200 /*--------------------------------------------------------------. 201 | Get the data type (alternative in the union) of the value for | 202 | symbol N in symbol list L. | 203 `--------------------------------------------------------------*/ 204 205 uniqstr 206 symbol_list_n_type_name_get (symbol_list *l, location loc, int n) 207 { 208 l = symbol_list_n_get (l, n); 209 if (!l) 210 { 211 complain_at (loc, _("invalid $ value: $%d"), n); 212 return NULL; 213 } 214 aver (l->content_type == SYMLIST_SYMBOL); 215 return l->content.sym->type_name; 216 } 217 218 bool 219 symbol_list_null (symbol_list *node) 220 { 221 return !node || 222 (node->content_type == SYMLIST_SYMBOL && !(node->content.sym)); 223 } 224 225 void 226 symbol_list_destructor_set (symbol_list *node, code_props const *destructor) 227 { 228 switch (node->content_type) 229 { 230 case SYMLIST_SYMBOL: 231 symbol_destructor_set (node->content.sym, destructor); 232 break; 233 case SYMLIST_TYPE: 234 semantic_type_destructor_set ( 235 semantic_type_get (node->content.type_name), destructor); 236 break; 237 case SYMLIST_DEFAULT_TAGGED: 238 default_tagged_destructor_set (destructor); 239 break; 240 case SYMLIST_DEFAULT_TAGLESS: 241 default_tagless_destructor_set (destructor); 242 break; 243 } 244 } 245 246 void 247 symbol_list_printer_set (symbol_list *node, code_props const *printer) 248 { 249 switch (node->content_type) 250 { 251 case SYMLIST_SYMBOL: 252 symbol_printer_set (node->content.sym, printer); 253 break; 254 case SYMLIST_TYPE: 255 semantic_type_printer_set ( 256 semantic_type_get (node->content.type_name), printer); 257 break; 258 case SYMLIST_DEFAULT_TAGGED: 259 default_tagged_printer_set (printer); 260 break; 261 case SYMLIST_DEFAULT_TAGLESS: 262 default_tagless_printer_set (printer); 263 break; 264 } 265 } 266