Changeset c5cb943d in mainline for uspace/app/sbi/src/ancr.c


Ignore:
Timestamp:
2010-06-09T19:01:08Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1113c9e
Parents:
051bc69a
Message:

Update SBI to rev. 291.

File:
1 edited

Legend:

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

    r051bc69a rc5cb943d  
    5151#include <assert.h>
    5252#include "builtin.h"
     53#include "cspan.h"
    5354#include "list.h"
    5455#include "mytypes.h"
     
    6162static void ancr_csi_dfs(stree_program_t *prog, stree_csi_t *csi);
    6263static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node);
     64static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi,
     65    stree_texpr_t *pred_ref);
    6366static void ancr_csi_print_cycle(stree_program_t *prog, stree_csi_t *node);
    6467
     
    128131 *
    129132 * @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 */
     135static void ancr_csi_process(stree_program_t *prog, stree_csi_t *csi)
     136{
    135137        stree_csi_t *base_csi, *outer_csi;
    136138        stree_csi_t *gf_class;
    137139
    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) {
    139145                /* Node already processed */
    140146                return;
    141147        }
    142148
    143         if (node->ancr_state == ws_active) {
     149        if (csi->ancr_state == ws_active) {
    144150                /* Error, closed reference loop. */
    145151                printf("Error: Circular class, struct or interface chain: ");
    146                 ancr_csi_print_cycle(prog, node);
     152                ancr_csi_print_cycle(prog, csi);
    147153                printf(".\n");
    148154                exit(1);
    149155        }
    150156
    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;
    154160        gf_class = builtin_get_gf_class(prog->builtin);
    155161
    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){
    170163                /* Implicit inheritance from grandfather class. */
    171164                base_csi = gf_class;
     
    175168        }
    176169
     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
    177238        /* 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 */
     253static 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;
    180266}
    181267
     
    191277{
    192278        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;
    195283
    196284        n = node;
     
    204292                if (outer_csi != NULL && outer_csi->ancr_state == ws_active) {
    205293                        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;
    215294                } 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);
    217312                }
    218313        } while (n != node);
Note: See TracChangeset for help on using the changeset viewer.