Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/src/ancr.c

    rc5cb943d r051bc69a  
    5151#include <assert.h>
    5252#include "builtin.h"
    53 #include "cspan.h"
    5453#include "list.h"
    5554#include "mytypes.h"
     
    6261static void ancr_csi_dfs(stree_program_t *prog, stree_csi_t *csi);
    6362static 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);
    6663static void ancr_csi_print_cycle(stree_program_t *prog, stree_csi_t *node);
    6764
     
    131128 *
    132129 * @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 */
     132static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node)
     133{
     134        stree_symbol_t *base_sym;
    137135        stree_csi_t *base_csi, *outer_csi;
    138136        stree_csi_t *gf_class;
    139137
    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) {
    145139                /* Node already processed */
    146140                return;
    147141        }
    148142
    149         if (csi->ancr_state == ws_active) {
     143        if (node->ancr_state == ws_active) {
    150144                /* Error, closed reference loop. */
    151145                printf("Error: Circular class, struct or interface chain: ");
    152                 ancr_csi_print_cycle(prog, csi);
     146                ancr_csi_print_cycle(prog, node);
    153147                printf(".\n");
    154148                exit(1);
    155149        }
    156150
    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;
    160154        gf_class = builtin_get_gf_class(prog->builtin);
    161155
    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) {
    163170                /* Implicit inheritance from grandfather class. */
    164171                base_csi = gf_class;
     
    168175        }
    169176
    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 
    238177        /* 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;
    266180}
    267181
     
    277191{
    278192        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;
    283195
    284196        n = node;
     
    292204                if (outer_csi != NULL && outer_csi->ancr_state == ws_active) {
    293205                        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;
    294215                } 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);
    312217                }
    313218        } while (n != node);
Note: See TracChangeset for help on using the changeset viewer.