Changes in uspace/app/sbi/src/ancr.c [051bc69a:c5cb943d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sbi/src/ancr.c
r051bc69a rc5cb943d 51 51 #include <assert.h> 52 52 #include "builtin.h" 53 #include "cspan.h" 53 54 #include "list.h" 54 55 #include "mytypes.h" … … 61 62 static void ancr_csi_dfs(stree_program_t *prog, stree_csi_t *csi); 62 63 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); 63 66 static void ancr_csi_print_cycle(stree_program_t *prog, stree_csi_t *node); 64 67 … … 128 131 * 129 132 * @param prog Program being processed. 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; 133 * @param csi CSI node to process. 134 */ 135 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *csi) 136 { 135 137 stree_csi_t *base_csi, *outer_csi; 136 138 stree_csi_t *gf_class; 137 139 138 if (node->ancr_state == ws_visited) { 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) { 139 145 /* Node already processed */ 140 146 return; 141 147 } 142 148 143 if ( node->ancr_state == ws_active) {149 if (csi->ancr_state == ws_active) { 144 150 /* Error, closed reference loop. */ 145 151 printf("Error: Circular class, struct or interface chain: "); 146 ancr_csi_print_cycle(prog, node);152 ancr_csi_print_cycle(prog, csi); 147 153 printf(".\n"); 148 154 exit(1); 149 155 } 150 156 151 node->ancr_state = ws_active;152 153 outer_csi = csi_to_symbol( node)->outer_csi;157 csi->ancr_state = ws_active; 158 159 outer_csi = csi_to_symbol(csi)->outer_csi; 154 160 gf_class = builtin_get_gf_class(prog->builtin); 155 161 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) { 162 if (csi != gf_class){ 170 163 /* Implicit inheritance from grandfather class. */ 171 164 base_csi = gf_class; … … 175 168 } 176 169 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 177 238 /* Store base CSI and update node state. */ 178 node->ancr_state = ws_visited; 179 node->base_csi = base_csi; 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; 180 266 } 181 267 … … 191 277 { 192 278 stree_csi_t *n; 193 stree_symbol_t *base_sym, *node_sym; 194 stree_csi_t *base_csi, *outer_csi; 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; 195 283 196 284 n = node; … … 204 292 if (outer_csi != NULL && outer_csi->ancr_state == ws_active) { 205 293 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;215 294 } else { 216 assert(b_false); 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); 217 312 } 218 313 } while (n != node);
Note:
See TracChangeset
for help on using the changeset viewer.