Changes in uspace/app/sbi/src/ancr.c [c5cb943d:051bc69a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/ancr.c
rc5cb943d r051bc69a 51 51 #include <assert.h> 52 52 #include "builtin.h" 53 #include "cspan.h"54 53 #include "list.h" 55 54 #include "mytypes.h" … … 62 61 static void ancr_csi_dfs(stree_program_t *prog, stree_csi_t *csi); 63 62 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node); 64 static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi,65 stree_texpr_t *pred_ref);66 63 static void ancr_csi_print_cycle(stree_program_t *prog, stree_csi_t *node); 67 64 … … 131 128 * 132 129 * @param prog Program being processed. 133 * @param csi CSI node to process. 134 */ 135 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *csi) 136 { 130 * @param node CSI node to process. 131 */ 132 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node) 133 { 134 stree_symbol_t *base_sym; 137 135 stree_csi_t *base_csi, *outer_csi; 138 136 stree_csi_t *gf_class; 139 137 140 list_node_t *pred_n; 141 stree_texpr_t *pred; 142 stree_csi_t *pred_csi; 143 144 if (csi->ancr_state == ws_visited) { 138 if (node->ancr_state == ws_visited) { 145 139 /* Node already processed */ 146 140 return; 147 141 } 148 142 149 if ( csi->ancr_state == ws_active) {143 if (node->ancr_state == ws_active) { 150 144 /* Error, closed reference loop. */ 151 145 printf("Error: Circular class, struct or interface chain: "); 152 ancr_csi_print_cycle(prog, csi);146 ancr_csi_print_cycle(prog, node); 153 147 printf(".\n"); 154 148 exit(1); 155 149 } 156 150 157 csi->ancr_state = ws_active;158 159 outer_csi = csi_to_symbol( csi)->outer_csi;151 node->ancr_state = ws_active; 152 153 outer_csi = csi_to_symbol(node)->outer_csi; 160 154 gf_class = builtin_get_gf_class(prog->builtin); 161 155 162 if (csi != gf_class){ 156 /* Process outer CSI */ 157 if (outer_csi != NULL) 158 ancr_csi_process(prog, outer_csi); 159 160 if (node->base_csi_ref != NULL) { 161 /* Resolve base CSI. */ 162 base_sym = symbol_xlookup_in_csi(prog, outer_csi, 163 node->base_csi_ref); 164 base_csi = symbol_to_csi(base_sym); 165 assert(base_csi != NULL); 166 167 /* Process base CSI. */ 168 ancr_csi_process(prog, base_csi); 169 } else if (node != gf_class) { 163 170 /* Implicit inheritance from grandfather class. */ 164 171 base_csi = gf_class; … … 168 175 } 169 176 170 /* Process outer CSI */171 if (outer_csi != NULL)172 ancr_csi_process(prog, outer_csi);173 174 /*175 * Process inheritance list.176 */177 pred_n = list_first(&csi->inherit);178 179 /* For a class node, the first entry can be a class. */180 if (csi->cc == csi_class && pred_n != NULL) {181 pred = list_node_data(pred_n, stree_texpr_t *);182 pred_csi = ancr_csi_get_pred(prog, csi, pred);183 assert(pred_csi != NULL);184 185 if (pred_csi->cc == csi_class) {186 /* Process base class */187 base_csi = pred_csi;188 ancr_csi_process(prog, pred_csi);189 190 pred_n = list_next(&csi->inherit, pred_n);191 }192 }193 194 /* Following entires can only be interfaces. */195 while (pred_n != NULL) {196 pred = list_node_data(pred_n, stree_texpr_t *);197 pred_csi = ancr_csi_get_pred(prog, csi, pred);198 assert(pred_csi != NULL);199 200 /* Process implemented or accumulated interface. */201 ancr_csi_process(prog, pred_csi);202 203 switch (pred_csi->cc) {204 case csi_class:205 switch (csi->cc) {206 case csi_class:207 cspan_print(csi->name->cspan);208 printf(" Error: Only the first predecessor "209 "can be a class. ('");210 symbol_print_fqn(csi_to_symbol(csi));211 printf("' deriving from '");212 symbol_print_fqn(csi_to_symbol(pred_csi));213 printf("').\n");214 exit(1);215 break;216 case csi_struct:217 assert(b_false); /* XXX */218 case csi_interface:219 cspan_print(csi->name->cspan);220 printf(" Error: Interface predecessor must be "221 "an interface ('");222 symbol_print_fqn(csi_to_symbol(csi));223 printf("' deriving from '");224 symbol_print_fqn(csi_to_symbol(pred_csi));225 printf("').\n");226 exit(1);227 break;228 }229 case csi_struct:230 assert(b_false); /* XXX */231 case csi_interface:232 break;233 }234 235 pred_n = list_next(&csi->inherit, pred_n);236 }237 238 177 /* Store base CSI and update node state. */ 239 csi->ancr_state = ws_visited; 240 csi->base_csi = base_csi; 241 } 242 243 /** Resolve CSI predecessor reference. 244 * 245 * Returns the CSI predecessor referenced by @a pred_ref. 246 * If the referenced CSI does not exist, an error is generated. 247 * 248 * @param prog Program being processed. 249 * @param csi CSI node to process. 250 * @param pred_ref Type expression referencing the predecessor. 251 * @return Predecessor CSI. 252 */ 253 static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi, 254 stree_texpr_t *pred_ref) 255 { 256 stree_csi_t *outer_csi; 257 stree_symbol_t *pred_sym; 258 stree_csi_t *pred_csi; 259 260 outer_csi = csi_to_symbol(csi)->outer_csi; 261 pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred_ref); 262 pred_csi = symbol_to_csi(pred_sym); 263 assert(pred_csi != NULL); /* XXX */ 264 265 return pred_csi; 178 node->ancr_state = ws_visited; 179 node->base_csi = base_csi; 266 180 } 267 181 … … 277 191 { 278 192 stree_csi_t *n; 279 stree_symbol_t *pred_sym, *node_sym; 280 stree_csi_t *pred_csi, *outer_csi; 281 stree_texpr_t *pred; 282 list_node_t *pred_n; 193 stree_symbol_t *base_sym, *node_sym; 194 stree_csi_t *base_csi, *outer_csi; 283 195 284 196 n = node; … … 292 204 if (outer_csi != NULL && outer_csi->ancr_state == ws_active) { 293 205 node = outer_csi; 206 } else if (node->base_csi_ref != NULL) { 207 /* Resolve base CSI. */ 208 base_sym = symbol_xlookup_in_csi(prog, outer_csi, 209 node->base_csi_ref); 210 base_csi = symbol_to_csi(base_sym); 211 assert(base_csi != NULL); 212 213 assert(base_csi->ancr_state == ws_active); 214 node = base_csi; 294 215 } else { 295 node = NULL; 296 297 pred_n = list_first(&node->inherit); 298 while (pred_n != NULL) { 299 pred = list_node_data(pred_n, stree_texpr_t *); 300 pred_sym = symbol_xlookup_in_csi(prog, 301 outer_csi, pred); 302 pred_csi = symbol_to_csi(pred_sym); 303 assert(pred_csi != NULL); 304 305 if (pred_csi->ancr_state == ws_active) { 306 node = pred_csi; 307 break; 308 } 309 } 310 311 assert(node != NULL); 216 assert(b_false); 312 217 } 313 218 } while (n != node);
Note:
See TracChangeset
for help on using the changeset viewer.