Changeset 1113c9e in mainline for uspace/app


Ignore:
Timestamp:
2010-06-09T19:03:24Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8eec3c8
Parents:
8f80c77 (diff), c5cb943d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jsvoboda/helenos/sysel.

Location:
uspace/app/sbi
Files:
4 added
35 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/Makefile

    r8f80c77 r1113c9e  
    3535SOURCES = \
    3636        src/builtin/bi_boxed.c \
     37        src/builtin/bi_char.c \
    3738        src/builtin/bi_error.c \
    3839        src/builtin/bi_fun.c \
     40        src/builtin/bi_int.c \
    3941        src/builtin/bi_textfile.c \
    4042        src/builtin/bi_string.c \
  • uspace/app/sbi/src/ancr.c

    r8f80c77 r1113c9e  
    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);
  • uspace/app/sbi/src/bigint.c

    r8f80c77 r1113c9e  
    360360}
    361361
    362 /** Print bigint to standard output. */
    363 void bigint_print(bigint_t *bigint)
    364 {
     362/** Convert bigint to string.
     363 *
     364 * @param bigint        Bigint to convert.
     365 * @param dptr          Place to store pointer to new string.
     366 */
     367void bigint_get_as_string(bigint_t *bigint, char **dptr)
     368{
     369        static const char digits[] = { '0', '1', '2', '3', '4', '5', '6',
     370            '7', '8', '9' };
     371
    365372        bigint_t val, tmp;
    366373        bigint_word_t rem;
    367         size_t ndigits;
    368         int *digits;
    369         size_t idx;
    370 
    371 #ifdef DEBUG_BIGINT_TRACE
    372         printf("Print bigint.\n");
     374        size_t nchars;
     375        char *str;
     376        size_t idx;
     377
     378#ifdef DEBUG_BIGINT_TRACE
     379        printf("Convert bigint to string.\n");
    373380#endif
    374381        assert(BIGINT_BASE >= 10);
    375382
    376         if (bigint_is_zero(bigint)) {
    377                 putchar('0');
    378                 return;
    379         }
    380 
    381         if (bigint->negative)
    382                 putchar('-');
    383 
    384         /* Compute number of digits. */
    385         ndigits = 0;
     383        /* Compute number of characters. */
     384        nchars = 0;
     385
     386        if (bigint_is_zero(bigint) || bigint->negative)
     387                nchars += 1; /* '0' or '-' */
     388
    386389        bigint_clone(bigint, &val);
    387390        while (bigint_is_zero(&val) != b_true) {
     
    390393                bigint_shallow_copy(&tmp, &val);
    391394
    392                 ndigits += 1;
     395                nchars += 1;
    393396        }
    394397        bigint_destroy(&val);
    395398
    396         /* Store digits to array. */
    397 
    398         digits = malloc(ndigits * sizeof(int));
    399         if (digits == NULL) {
     399        /* Store characters to array. */
     400
     401        str = malloc(nchars * sizeof(char) + 1);
     402        if (str == NULL) {
    400403                printf("Memory allocation failed.\n");
    401404                exit(1);
    402405        }
    403406
    404         idx = 0;
     407        if (bigint_is_zero(bigint)) {
     408                str[0] = '0';
     409        } else if (bigint->negative) {
     410                str[0] = '-';
     411        }
     412
     413        idx = 1;
    405414        bigint_clone(bigint, &val);
    406415        while (bigint_is_zero(&val) != b_true) {
     
    409418                bigint_shallow_copy(&tmp, &val);
    410419
    411                 digits[idx++] = (int) rem;
    412         }
     420                str[nchars - idx] = digits[(int) rem];
     421                ++idx;
     422        }
     423
    413424        bigint_destroy(&val);
    414 
    415         for (idx = 0; idx < ndigits; ++idx)
    416                 printf("%u", digits[ndigits - 1 - idx]);
    417 
    418         free(digits);
     425        str[nchars] = '\0';
     426        *dptr = str;
     427}
     428
     429/** Print bigint to standard output.
     430 *
     431 * @param bigint        Bigint to print.
     432 */
     433void bigint_print(bigint_t *bigint)
     434{
     435        char *str;
     436
     437#ifdef DEBUG_BIGINT_TRACE
     438        printf("Print bigint.\n");
     439#endif
     440        bigint_get_as_string(bigint, &str);
     441        printf("%s", str);
     442        free(str);
    419443}
    420444
  • uspace/app/sbi/src/bigint.h

    r8f80c77 r1113c9e  
    4848void bigint_sub(bigint_t *a, bigint_t *b, bigint_t *dest);
    4949void bigint_mul(bigint_t *a, bigint_t *b, bigint_t *dest);
     50
     51void bigint_get_as_string(bigint_t *bigint, char **dptr);
    5052void bigint_print(bigint_t *bigint);
    5153
  • uspace/app/sbi/src/builtin.c

    r8f80c77 r1113c9e  
    4242#include "builtin/bi_boxed.h"
    4343#include "builtin/bi_error.h"
     44#include "builtin/bi_char.h"
    4445#include "builtin/bi_fun.h"
     46#include "builtin/bi_int.h"
    4547#include "builtin/bi_textfile.h"
    4648#include "builtin/bi_string.h"
     
    5254#include "os/os.h"
    5355#include "parse.h"
     56#include "rdata.h"
    5457#include "run.h"
    5558#include "stree.h"
     
    8992
    9093        bi_error_declare(bi);
     94        bi_char_declare(bi);
    9195        bi_fun_declare(bi);
     96        bi_int_declare(bi);
    9297        bi_textfile_declare(bi);
    9398        bi_string_declare(bi);
     
    105110        bi_boxed_bind(bi);
    106111        bi_error_bind(bi);
     112        bi_char_bind(bi);
    107113        bi_fun_bind(bi);
     114        bi_int_bind(bi);
    108115        bi_textfile_bind(bi);
    109116        bi_string_bind(bi);
     
    250257{
    251258        stree_symbol_t *fun_sym;
    252         builtin_t *bi;
    253259        builtin_proc_t bproc;
    254260
     
    257263#endif
    258264        fun_sym = proc->outer_symbol;
    259         bi = run->program->builtin;
    260265
    261266        bproc = proc->bi_handler;
     
    298303}
    299304
    300 /** Declare a builtin function in @a csi.
     305/** Return string value from builtin procedure.
     306 *
     307 * Makes it easy for a builtin procedure to return value of type @c string.
     308 *
     309 * @param run           Runner object
     310 * @param str           String value. Must be allocated from heap and its
     311 *                      ownership is hereby given up.
     312 */
     313void builtin_return_string(run_t *run, const char *astr)
     314{
     315        rdata_string_t *rstring;
     316        rdata_var_t *rvar;
     317        rdata_value_t *rval;
     318        rdata_item_t *ritem;
     319
     320        run_proc_ar_t *proc_ar;
     321
     322#ifdef DEBUG_RUN_TRACE
     323        printf("Return string '%s' from builtin function.\n", astr);
     324#endif
     325        rstring = rdata_string_new();
     326        rstring->value = astr;
     327
     328        rvar = rdata_var_new(vc_string);
     329        rvar->u.string_v = rstring;
     330        rval = rdata_value_new();
     331        rval->var = rvar;
     332
     333        ritem = rdata_item_new(ic_value);
     334        ritem->u.value = rval;
     335
     336        proc_ar = run_get_current_proc_ar(run);
     337        proc_ar->retval = ritem;
     338}
     339
     340/** Declare a static builtin function in @a csi.
    301341 *
    302342 * Declare a builtin function member of CSI @a csi. Deprecated in favor
     
    314354        stree_csimbr_t *csimbr;
    315355        stree_symbol_t *fun_sym;
     356        stree_symbol_attr_t *sym_attr;
    316357
    317358        ident = stree_ident_new();
     
    333374        fun_sym->u.fun = fun;
    334375        fun_sym->outer_csi = csi;
     376
     377        sym_attr = stree_symbol_attr_new(sac_static);
     378        list_append(&fun_sym->attr, sym_attr);
     379
    335380        fun->symbol = fun_sym;
    336381        fun->proc->outer_symbol = fun_sym;
  • uspace/app/sbi/src/builtin.h

    r8f80c77 r1113c9e  
    4040
    4141rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name);
     42void builtin_return_string(run_t *run, const char *str);
    4243
    4344stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name);
  • uspace/app/sbi/src/builtin/bi_fun.c

    r8f80c77 r1113c9e  
    9494        builtin_code_snippet(bi,
    9595                "class Task is\n"
    96                         "fun Exec(args : string[], packed), builtin;\n"
     96                        "fun Exec(args : string[], packed), static, builtin;\n"
    9797                "end\n");
    9898}
  • uspace/app/sbi/src/builtin/bi_string.c

    r8f80c77 r1113c9e  
    116116        rdata_var_t *self_value_var;
    117117        const char *str;
     118        const char *slice;
    118119        size_t str_l;
    119120
     
    125126
    126127        int rc;
    127 
    128         rdata_string_t *rstring;
    129         rdata_var_t *rvar;
    130         rdata_value_t *rval;
    131         rdata_item_t *ritem;
    132 
    133         run_proc_ar_t *proc_ar;
    134128
    135129        /* Extract self.Value */
     
    165159            start, length, str);
    166160#endif
    167         /* Construct return value. */
    168         rstring = rdata_string_new();
    169         rstring->value = os_str_aslice(str, start, length);
     161        slice = os_str_aslice(str, start, length);
    170162
    171         rvar = rdata_var_new(vc_string);
    172         rvar->u.string_v = rstring;
    173         rval = rdata_value_new();
    174         rval->var = rvar;
    175 
    176         ritem = rdata_item_new(ic_value);
    177         ritem->u.value = rval;
    178 
    179         proc_ar = run_get_current_proc_ar(run);
    180         proc_ar->retval = ritem;
     163        /* Ownership of slice is transferred. */
     164        builtin_return_string(run, slice);
    181165}
  • uspace/app/sbi/src/imode.c

    r8f80c77 r1113c9e  
    130130
    131131        /* Construct run context. */
     132        run_gdata_init(&run);
     133
    132134        run.thread_ar = run_thread_ar_new();
    133135        list_init(&run.thread_ar->proc_ar);
    134         run_proc_ar_create(&run, NULL, proc, &proc_ar);
     136        run_proc_ar_create(&run, run.gdata, proc, &proc_ar);
    135137        list_append(&run.thread_ar->proc_ar, proc_ar);
    136138
  • uspace/app/sbi/src/input.c

    r8f80c77 r1113c9e  
    206206                        *dp++ = *sp++;
    207207
    208                 *dp++ = '\0';
     208                *dp = '\0';
    209209                input->str = sp;
    210210                *line = input->buffer;
  • uspace/app/sbi/src/mytypes.h

    r8f80c77 r1113c9e  
    4343} walk_state_t;
    4444
     45/** Static vs. nonstatic */
     46typedef enum {
     47        sn_nonstatic,
     48        sn_static
     49} statns_t;
     50
    4551/** Error return codes. */
    4652#include <errno.h>
  • uspace/app/sbi/src/os/helenos.c

    r8f80c77 r1113c9e  
    173173}
    174174
     175/** Convert character to new string.
     176 *
     177 * @param chr           Character
     178 * @return              Newly allocated string.
     179 */
     180char *os_chr_to_astr(wchar_t chr)
     181{
     182        char *str;
     183        size_t offset;
     184
     185        str = malloc(STR_BOUNDS(1) + 1);
     186        if (str == NULL) {
     187                printf("Memory allocation error.\n");
     188                exit(1);
     189        }
     190
     191        offset = 0;
     192        if (chr_encode(chr, str, &offset, STR_BOUNDS(1)) != EOK) {
     193                /* XXX Should handle gracefully */
     194                printf("String conversion error.\n");
     195                exit(1);
     196        }
     197
     198        str[offset] = '\0';
     199        return str;
     200}
     201
    175202/** Display survival help message. */
    176203void os_input_disp_help(void)
  • uspace/app/sbi/src/os/os.h

    r8f80c77 r1113c9e  
    3636size_t os_str_length(const char *str);
    3737int os_str_get_char(const char *str, int index, int *out_char);
     38char *os_chr_to_astr(wchar_t chr);
    3839void os_input_disp_help(void);
    3940int os_input_line(char **ptr);
  • uspace/app/sbi/src/os/posix.c

    r8f80c77 r1113c9e  
    159159}
    160160
     161/** Convert character to new string.
     162 *
     163 * @param chr           Character
     164 * @return              Newly allocated string.
     165 */
     166char *os_chr_to_astr(wchar_t chr)
     167{
     168        char *str;
     169
     170        str = malloc(2);
     171        if (str == NULL) {
     172                printf("Memory allocation error.\n");
     173                exit(1);
     174        }
     175
     176        str[0] = (char) chr;
     177        str[1] = '\0';
     178
     179        return str;
     180}
     181
    161182#define OS_INPUT_BUFFER_SIZE 256
    162183static char os_input_buffer[OS_INPUT_BUFFER_SIZE];
  • uspace/app/sbi/src/parse.c

    r8f80c77 r1113c9e  
    3535#include <assert.h>
    3636#include <stdlib.h>
     37#include "cspan.h"
    3738#include "debug.h"
    3839#include "lex.h"
     
    6465static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi);
    6566
     67static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol);
    6668static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse);
    6769
     
    7072static stree_fun_sig_t *parse_fun_sig(parse_t *parse);
    7173
     74static void parse_prop_get(parse_t *parse, stree_prop_t *prop);
     75static void parse_prop_set(parse_t *parse, stree_prop_t *prop);
    7276
    7377/*
     
    175179        stree_ident_t *targ_name;
    176180        stree_targ_t *targ;
     181        stree_texpr_t *pref;
    177182
    178183        switch (dclass) {
     
    212217                /* Inheritance list */
    213218                lskip(parse);
    214                 csi->base_csi_ref = parse_texpr(parse);
    215         } else {
    216                 csi->base_csi_ref = NULL;
     219
     220                while (b_true) {
     221                        pref = parse_texpr(parse);
     222                        if (parse_is_error(parse))
     223                                break;
     224
     225                        list_append(&csi->inherit, pref);
     226                        if (lcur_lc(parse) != lc_plus)
     227                                break;
     228
     229                        lskip(parse);
     230                }
    217231        }
    218232
     
    224238                csimbr = parse_csimbr(parse, csi);
    225239                if (csimbr == NULL)
     240                        continue;
     241
     242                list_append(&csi->members, csimbr);
     243        }
     244
     245        lmatch(parse, lc_end);
     246
     247        if (outer_csi != NULL) {
     248                switch (outer_csi->cc) {
     249                case csi_class:
     250                case csi_struct:
    226251                        break;
    227 
    228                 list_append(&csi->members, csimbr);
    229         }
    230 
    231         lmatch(parse, lc_end);
     252                case csi_interface:
     253                        cspan_print(csi->name->cspan);
     254                        printf(" Error: CSI declared inside interface.\n");
     255                        parse_note_error(parse);
     256                        /* XXX Free csi */
     257                        return NULL;
     258                }
     259        }
    232260
    233261        return csi;
     
    253281        stree_prop_t *prop;
    254282
     283        csimbr = NULL;
     284
    255285        switch (lcur_lc(parse)) {
    256286        case lc_class:
     
    258288        case lc_interface:
    259289                csi = parse_csi(parse, lcur_lc(parse), outer_csi);
    260                 csimbr = stree_csimbr_new(csimbr_csi);
    261                 csimbr->u.csi = csi;
     290                if (csi != NULL) {
     291                        csimbr = stree_csimbr_new(csimbr_csi);
     292                        csimbr->u.csi = csi;
     293                }
    262294                break;
    263295        case lc_new:
    264296                ctor = parse_ctor(parse, outer_csi);
    265                 csimbr = stree_csimbr_new(csimbr_ctor);
    266                 csimbr->u.ctor = ctor;
     297                if (ctor != NULL) {
     298                        csimbr = stree_csimbr_new(csimbr_ctor);
     299                        csimbr->u.ctor = ctor;
     300                }
    267301                break;
    268302        case lc_deleg:
    269303                deleg = parse_deleg(parse, outer_csi);
    270                 csimbr = stree_csimbr_new(csimbr_deleg);
    271                 csimbr->u.deleg = deleg;
     304                if (deleg != NULL) {
     305                        csimbr = stree_csimbr_new(csimbr_deleg);
     306                        csimbr->u.deleg = deleg;
     307                }
    272308                break;
    273309        case lc_enum:
    274310                enum_d = parse_enum(parse, outer_csi);
    275                 csimbr = stree_csimbr_new(csimbr_enum);
    276                 csimbr->u.enum_d = enum_d;
     311                if (enum_d != NULL) {
     312                        csimbr = stree_csimbr_new(csimbr_enum);
     313                        csimbr->u.enum_d = enum_d;
     314                }
    277315                break;
    278316        case lc_fun:
     
    283321        case lc_var:
    284322                var = parse_var(parse, outer_csi);
    285                 csimbr = stree_csimbr_new(csimbr_var);
    286                 csimbr->u.var = var;
     323                if (var != NULL) {
     324                        csimbr = stree_csimbr_new(csimbr_var);
     325                        csimbr->u.var = var;
     326                }
    287327                break;
    288328        case lc_prop:
     
    294334                lunexpected_error(parse);
    295335                lex_next(parse->lex);
    296                 csimbr = NULL;
    297336                break;
    298337        }
     
    311350        stree_ctor_t *ctor;
    312351        stree_symbol_t *symbol;
    313         stree_symbol_attr_t *attr;
     352        cspan_t *cspan;
    314353
    315354        ctor = stree_ctor_new();
     
    321360
    322361        lmatch(parse, lc_new);
     362        cspan = lprev_span(parse);
    323363
    324364        /* Fake identifier. */
     
    334374        ctor->sig = parse_fun_sig(parse);
    335375        if (ctor->sig->rtype != NULL) {
    336                 printf("Error: Constructor of CSI '");
     376                cspan_print(cspan);
     377                printf(" Error: Constructor of CSI '");
    337378                symbol_print_fqn(csi_to_symbol(outer_csi));
    338379                printf("' has a return type.\n");
     
    340381        }
    341382
    342         list_init(&symbol->attr);
    343 
    344383        /* Parse attributes. */
    345         while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
    346                 lskip(parse);
    347                 attr = parse_symbol_attr(parse);
    348                 list_append(&symbol->attr, attr);
    349         }
     384        parse_symbol_attrs(parse, symbol);
    350385
    351386        ctor->proc = stree_proc_new();
     
    356391
    357392                /* This constructor has no body. */
    358                 printf("Error: Constructor of CSI '");
     393                cspan_print(cspan);
     394                printf(" Error: Constructor of CSI '");
    359395                symbol_print_fqn(csi_to_symbol(outer_csi));
    360396                printf("' has no body.\n");
     
    368404        }
    369405
     406        switch (outer_csi->cc) {
     407        case csi_class:
     408        case csi_struct:
     409                break;
     410        case csi_interface:
     411                cspan_print(ctor->name->cspan);
     412                printf(" Error: Constructor declared inside interface.\n");
     413                parse_note_error(parse);
     414                /* XXX Free ctor */
     415                return NULL;
     416        }
     417
    370418        return ctor;
    371419}
     
    409457
    410458        if (list_is_empty(&enum_d->members)) {
     459                cspan_print(enum_d->name->cspan);
    411460                printf("Error: Enum type '%s' has no members.\n",
    412461                    strtab_get_str(enum_d->name->sid));
     
    416465        lmatch(parse, lc_end);
    417466
     467        if (outer_csi != NULL) {
     468                switch (outer_csi->cc) {
     469                case csi_class:
     470                case csi_struct:
     471                        break;
     472                case csi_interface:
     473                        cspan_print(enum_d->name->cspan);
     474                        printf(" Error: Enum declared inside interface.\n");
     475                        parse_note_error(parse);
     476                        /* XXX Free enum */
     477                        return NULL;
     478                }
     479        }
     480
    418481        return enum_d;
    419482}
     
    449512        stree_deleg_t *deleg;
    450513        stree_symbol_t *symbol;
    451         stree_symbol_attr_t *attr;
    452514
    453515        deleg = stree_deleg_new();
     
    467529        deleg->sig = parse_fun_sig(parse);
    468530
    469         list_init(&symbol->attr);
    470 
    471531        /* Parse attributes. */
    472         while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
    473                 lskip(parse);
    474                 attr = parse_symbol_attr(parse);
    475                 list_append(&symbol->attr, attr);
    476         }
     532        parse_symbol_attrs(parse, symbol);
    477533
    478534        lmatch(parse, lc_scolon);
     535
     536        switch (outer_csi->cc) {
     537        case csi_class:
     538        case csi_struct:
     539                break;
     540        case csi_interface:
     541                cspan_print(deleg->name->cspan);
     542                printf(" Error: Delegate declared inside interface.\n");
     543                parse_note_error(parse);
     544                /* XXX Free deleg */
     545                return NULL;
     546        }
    479547
    480548        return deleg;
     
    491559        stree_fun_t *fun;
    492560        stree_symbol_t *symbol;
    493         stree_symbol_attr_t *attr;
     561        bool_t body_expected;
    494562
    495563        fun = stree_fun_new();
     
    508576        fun->sig = parse_fun_sig(parse);
    509577
    510         list_init(&symbol->attr);
    511 
    512578        /* Parse attributes. */
    513         while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
    514                 lskip(parse);
    515                 attr = parse_symbol_attr(parse);
    516                 list_append(&symbol->attr, attr);
    517         }
     579        parse_symbol_attrs(parse, symbol);
     580
     581        body_expected = !stree_symbol_has_attr(symbol, sac_builtin) &&
     582            (outer_csi->cc != csi_interface);
    518583
    519584        fun->proc = stree_proc_new();
     
    523588                lskip(parse);
    524589
    525                 /* This function has no body. */
    526                 if (!stree_symbol_has_attr(symbol, sac_builtin)) {
    527                         printf("Error: Function '");
     590                /* Body not present */
     591                if (body_expected) {
     592                        cspan_print(fun->name->cspan);
     593                        printf(" Error: Function '");
    528594                        symbol_print_fqn(symbol);
    529                         printf("' has no body.\n");
     595                        printf("' should have a body.\n");
    530596                        parse_note_error(parse);
    531597                }
     598
    532599                fun->proc->body = NULL;
    533600        } else {
     
    535602                fun->proc->body = parse_block(parse);
    536603                lmatch(parse, lc_end);
     604
     605                /* Body present */
     606                if (!body_expected) {
     607                        cspan_print(fun->name->cspan);
     608                        printf(" Error: Function declaration '");
     609                        symbol_print_fqn(symbol);
     610                        printf("' should not have a body.\n");
     611                        parse_note_error(parse);
     612                }
    537613        }
    538614
     
    561637        lmatch(parse, lc_colon);
    562638        var->type =  parse_texpr(parse);
     639
     640        parse_symbol_attrs(parse, symbol);
     641
    563642        lmatch(parse, lc_scolon);
     643
     644        switch (outer_csi->cc) {
     645        case csi_class:
     646        case csi_struct:
     647                break;
     648        case csi_interface:
     649                cspan_print(var->name->cspan);
     650                printf(" Error: Variable declared inside interface.\n");
     651                parse_note_error(parse);
     652                /* XXX Free var */
     653                return NULL;
     654        }
    564655
    565656        return var;
     
    576667        stree_prop_t *prop;
    577668        stree_symbol_t *symbol;
     669        bool_t body_expected;
    578670
    579671        stree_ident_t *ident;
     
    625717        lmatch(parse, lc_colon);
    626718        prop->type = parse_texpr(parse);
     719
     720        /* Parse attributes. */
     721        parse_symbol_attrs(parse, symbol);
     722
     723        body_expected = (outer_csi->cc != csi_interface);
     724
    627725        lmatch(parse, lc_is);
    628726
     
    630728                switch (lcur_lc(parse)) {
    631729                case lc_get:
    632                         lskip(parse);
    633                         lmatch(parse, lc_is);
    634                         if (prop->getter != NULL) {
    635                                 printf("Error: Duplicate getter.\n");
    636                                 (void) parse_block(parse); /* XXX Free */
    637                                 lmatch(parse, lc_end);
    638                                 parse_note_error(parse);
    639                                 break;
    640                         }
    641 
    642                         /* Create setter procedure */
    643                         prop->getter = stree_proc_new();
    644                         prop->getter->body = parse_block(parse);
    645                         prop->getter->outer_symbol = symbol;
    646 
    647                         lmatch(parse, lc_end);
     730                        parse_prop_get(parse, prop);
    648731                        break;
    649732                case lc_set:
    650                         lskip(parse);
    651                         prop->setter_arg = stree_proc_arg_new();
    652                         prop->setter_arg->name = parse_ident(parse);
    653                         prop->setter_arg->type = prop->type;
    654                         lmatch(parse, lc_is);
    655                         if (prop->setter != NULL) {
    656                                 printf("Error: Duplicate setter.\n");
    657                                 (void) parse_block(parse); /* XXX Free */
    658                                 lmatch(parse, lc_end);
    659                                 parse_note_error(parse);
    660                         }
    661 
    662                         /* Create setter procedure */
    663                         prop->setter = stree_proc_new();
    664                         prop->setter->body = parse_block(parse);
    665                         prop->setter->outer_symbol = symbol;
    666 
    667                         lmatch(parse, lc_end);
     733                        parse_prop_set(parse, prop);
    668734                        break;
    669735                default:
     
    677743}
    678744
     745/** Parse symbol attributes.
     746 *
     747 * Parse list of attributes and add them to @a symbol.
     748 *
     749 * @param parse         Parser object
     750 * @param symbol        Symbol to add these attributes to
     751 */
     752static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol)
     753{
     754        stree_symbol_attr_t *attr;
     755
     756        /* Parse attributes. */
     757        while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
     758                lskip(parse);
     759                attr = parse_symbol_attr(parse);
     760                list_append(&symbol->attr, attr);
     761        }
     762}
     763
    679764/** Parse symbol attribute.
    680765 *
    681  * @param parse         Parser object.
    682  * @param outer_csi     CSI containing this declaration or @c NULL if global.
    683  * @return              New syntax tree node.
     766 * @param parse         Parser object
     767 * @return              New syntax tree node
    684768 */
    685769static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse)
    686770{
    687771        stree_symbol_attr_t *attr;
    688 
    689         if (lcur_lc(parse) != lc_builtin) {
    690                 printf("Error: Unexpected attribute '");
     772        symbol_attr_class_t sac;
     773
     774        /* Make compiler happy. */
     775        sac = 0;
     776
     777        switch (lcur_lc(parse)) {
     778        case lc_builtin: sac = sac_builtin; break;
     779        case lc_static: sac = sac_static; break;
     780        default:
     781                cspan_print(lcur_span(parse));
     782                printf(" Error: Unexpected attribute '");
    691783                lem_print(lcur(parse));
    692784                printf("'.\n");
    693785                parse_note_error(parse);
     786                break;
    694787        }
    695788
    696789        lskip(parse);
    697790
    698         attr = stree_symbol_attr_new(sac_builtin);
     791        attr = stree_symbol_attr_new(sac);
    699792        return attr;
    700793}
     
    718811        printf("Parse procedure argument.\n");
    719812#endif
    720         list_init(&arg->attr);
     813        list_init(&arg->attr);
    721814
    722815        /* Parse attributes. */
     
    740833
    741834        if (lcur_lc(parse) != lc_packed) {
    742                 printf("Error: Unexpected attribute '");
     835                cspan_print(lcur_span(parse));
     836                printf(" Error: Unexpected attribute '");
    743837                lem_print(lcur(parse));
    744838                printf("'.\n");
     
    802896
    803897        return sig;
     898}
     899
     900/** Parse member property getter.
     901 *
     902 * @param parse         Parser object.
     903 * @param prop          Property containing this declaration.
     904 */
     905static void parse_prop_get(parse_t *parse, stree_prop_t *prop)
     906{
     907        cspan_t *cspan;
     908        stree_block_t *block;
     909        stree_proc_t *getter;
     910        bool_t body_expected;
     911
     912        body_expected = (prop->symbol->outer_csi->cc != csi_interface);
     913
     914        lskip(parse);
     915        cspan = lprev_span(parse);
     916
     917        if (prop->getter != NULL) {
     918                cspan_print(cspan);
     919                printf(" Error: Duplicate getter.\n");
     920                parse_note_error(parse);
     921                return;
     922        }
     923
     924        if (lcur_lc(parse) == lc_scolon) {
     925                /* Body not present */
     926                lskip(parse);
     927                block = NULL;
     928
     929                if (body_expected) {
     930                        cspan_print(prop->name->cspan);
     931                        printf(" Error: Property '");
     932                        symbol_print_fqn(prop->symbol);
     933                        printf("' getter should have "
     934                            "a body.\n");
     935                        parse_note_error(parse);
     936                }
     937        } else {
     938                /* Body present */
     939                lmatch(parse, lc_is);
     940                block = parse_block(parse);
     941                lmatch(parse, lc_end);
     942
     943                if (!body_expected) {
     944                        cspan_print(prop->name->cspan);
     945                        printf(" Error: Property '");
     946                        symbol_print_fqn(prop->symbol);
     947                        printf("' getter declaration should "
     948                            "not have a body.\n");
     949                        parse_note_error(parse);
     950
     951                        /* XXX Free block */
     952                        block = NULL;
     953                }
     954        }
     955
     956        /* Create getter procedure */
     957        getter = stree_proc_new();
     958        getter->body = block;
     959        getter->outer_symbol = prop->symbol;
     960
     961        /* Store getter in property. */
     962        prop->getter = getter;
     963}
     964
     965
     966/** Parse member property setter.
     967 *
     968 * @param parse         Parser object.
     969 * @param prop          Property containing this declaration.
     970 */
     971static void parse_prop_set(parse_t *parse, stree_prop_t *prop)
     972{
     973        cspan_t *cspan;
     974        stree_block_t *block;
     975        stree_proc_t *setter;
     976        bool_t body_expected;
     977
     978        body_expected = (prop->symbol->outer_csi->cc != csi_interface);
     979
     980        lskip(parse);
     981        cspan = lprev_span(parse);
     982
     983        if (prop->setter != NULL) {
     984                cspan_print(cspan);
     985                printf(" Error: Duplicate setter.\n");
     986                parse_note_error(parse);
     987                return;
     988        }
     989
     990        prop->setter_arg = stree_proc_arg_new();
     991        prop->setter_arg->name = parse_ident(parse);
     992        prop->setter_arg->type = prop->type;
     993
     994        if (lcur_lc(parse) == lc_scolon) {
     995                /* Body not present */
     996                lskip(parse);
     997
     998                block = NULL;
     999
     1000                if (body_expected) {
     1001                        cspan_print(prop->name->cspan);
     1002                        printf(" Error: Property '");
     1003                        symbol_print_fqn(prop->symbol);
     1004                        printf("' setter should have "
     1005                            "a body.\n");
     1006                        parse_note_error(parse);
     1007                }
     1008        } else {
     1009                /* Body present */
     1010                lmatch(parse, lc_is);
     1011                block = parse_block(parse);
     1012                lmatch(parse, lc_end);
     1013
     1014                if (!body_expected) {
     1015                        cspan_print(prop->name->cspan);
     1016                        printf(" Error: Property '");
     1017                        symbol_print_fqn(prop->symbol);
     1018                        printf("' setter declaration should "
     1019                            "not have a body.\n");
     1020                        parse_note_error(parse);
     1021                }
     1022        }
     1023
     1024
     1025        /* Create setter procedure */
     1026        setter = stree_proc_new();
     1027        setter->body = block;
     1028        setter->outer_symbol = prop->symbol;
     1029
     1030        /* Store setter in property. */
     1031        prop->setter = setter;
    8041032}
    8051033
  • uspace/app/sbi/src/program.c

    r8f80c77 r1113c9e  
    8585 * is read from '<libdir>/libflist'. Each line of the file contains one file
    8686 * name relative to <libdir>.
     87 *
     88 * @param program       The program to which the parsed code is added.
     89 * @return              EOK on success, EIO if some file comprising the
     90 *                      library is not found, EINVAL if the library
     91 *                      has syntax errors.
    8792 */
    8893int program_lib_process(stree_program_t *program)
     
    147152        fclose(f);
    148153
    149         return rc;
     154        return EOK;
    150155}
  • uspace/app/sbi/src/rdata.c

    r8f80c77 r1113c9e  
    609609        (void) src; (void) dest;
    610610        printf("Unimplemented: Copy object.\n");
    611         exit(1);
     611        abort();
    612612}
    613613
  • uspace/app/sbi/src/rdata_t.h

    r8f80c77 r1113c9e  
    7171 *
    7272 * A delegate variable points to a static or non-static symbol. If the
    73  * symbol is non static, @c obj points to the object the symbol instance
     73 * symbol is non static, @c obj points to the object the symbol
    7474 * belongs to.
    7575 */
    7676typedef struct {
    77         /** Object or @c NULL if deleg. points to a CSI or static member. */
     77        /** Object or @c NULL if deleg. points to a static function. */
    7878        struct rdata_var *obj;
    7979
     
    107107        /** Class of this object (symbol) */
    108108        struct stree_symbol *class_sym;
     109
     110        /** @c sn_static if this is a static object (i.e. class object) */
     111        statns_t static_obj;
    109112
    110113        /** Map field name SID to field data */
  • uspace/app/sbi/src/run.c

    r8f80c77 r1113c9e  
    9999        stree_symbol_t *main_fun_sym;
    100100        stree_fun_t *main_fun;
     101        rdata_var_t *main_obj;
    101102        stree_ident_t *fake_ident;
    102103        list_t main_args;
     
    111112        list_init(&run->thread_ar->proc_ar);
    112113        run->thread_ar->bo_mode = bm_none;
     114
     115        /* Initialize global data structure. */
     116        run_gdata_init(run);
    113117
    114118        /*
     
    126130        assert(main_fun != NULL);
    127131
     132        main_obj = run_fun_sobject_find(run, main_fun);
     133
    128134#ifdef DEBUG_RUN_TRACE
    129135        printf("Found function '"); symbol_print_fqn(main_fun_sym);
     
    133139        /* Run function @c main. */
    134140        list_init(&main_args);
    135         run_proc_ar_create(run, NULL, main_fun->proc, &proc_ar);
     141        run_proc_ar_create(run, main_obj, main_fun->proc, &proc_ar);
    136142        run_proc_ar_set_args(run, proc_ar, &main_args);
    137143        run_proc(run, proc_ar, &res);
    138144
    139145        run_exc_check_unhandled(run);
     146}
     147
     148/** Initialize global data.
     149 *
     150 * @param run           Runner object
     151 */
     152void run_gdata_init(run_t *run)
     153{
     154        rdata_object_t *gobject;
     155
     156        run->gdata = rdata_var_new(vc_object);
     157        gobject = rdata_object_new();
     158        run->gdata->u.object_v = gobject;
     159
     160        gobject->class_sym = NULL;
     161        gobject->static_obj = sn_static;
     162        intmap_init(&gobject->fields);
    140163}
    141164
     
    787810        proc_ar = run_get_current_proc_ar(run);
    788811        return proc_ar->proc->outer_symbol->outer_csi;
     812}
     813
     814/** Get static object (i.e. class object).
     815 *
     816 * Looks for a child static object named @a name in static object @a pobject.
     817 * If the child does not exist yet, it is created.
     818 *
     819 * @param run           Runner object
     820 * @param csi           CSI of the static object named @a name
     821 * @param pobject       Parent static object
     822 * @param name          Static object name
     823 *
     824 * @return              Static (class) object of the given name
     825 */
     826rdata_var_t *run_sobject_get(run_t *run, stree_csi_t *csi,
     827    rdata_var_t *pobj_var, sid_t name)
     828{
     829        rdata_object_t *pobject;
     830        rdata_var_t *mbr_var;
     831        rdata_var_t *rvar;
     832        stree_ident_t *ident;
     833
     834        assert(pobj_var->vc == vc_object);
     835        pobject = pobj_var->u.object_v;
     836#ifdef DEBUG_RUN_TRACE
     837        printf("Get static object '%s' in '", strtab_get_str(name));
     838        if (pobject->class_sym != NULL)
     839                symbol_print_fqn(pobject->class_sym);
     840        else
     841                printf("global");
     842#endif
     843
     844        assert(pobject->static_obj == sn_static);
     845
     846        mbr_var = intmap_get(&pobject->fields, name);
     847        if (mbr_var != NULL) {
     848#ifdef DEBUG_RUN_TRACE
     849                printf("Return exising static object (mbr_var=%p).\n", mbr_var);
     850#endif
     851                /* Return existing object. */
     852                return mbr_var;
     853        }
     854
     855        /* Construct new object. */
     856#ifdef DEBUG_RUN_TRACE
     857        printf("Construct new static object.\n");
     858#endif
     859        ident = stree_ident_new();
     860        ident->sid = name;
     861
     862        run_new_csi_inst(run, csi, sn_static, &rvar);
     863
     864        /* Store static object reference for future use. */
     865        intmap_set(&pobject->fields, name, rvar);
     866
     867        return rvar;
     868}
     869
     870/** Get static object for CSI.
     871 *
     872 * In situations where we do not have the parent static object and need
     873 * to find static object for a CSI from the gdata root we use this.
     874 *
     875 * This is only used in special cases such as when invoking the entry
     876 * point. This is too slow to use during normal execution.
     877 *
     878 * @param run           Runner object
     879 * @param csi           CSI to get static object of
     880 *
     881 * @return              Static (class) object
     882 */
     883rdata_var_t *run_sobject_find(run_t *run, stree_csi_t *csi)
     884{
     885        rdata_var_t *pobj_var;
     886
     887        if (csi == NULL)
     888                return run->gdata;
     889
     890        assert(csi->ancr_state == ws_visited);
     891        pobj_var = run_sobject_find(run, csi_to_symbol(csi)->outer_csi);
     892
     893        return run_sobject_get(run, csi, pobj_var, csi->name->sid);
     894}
     895
     896/** Get static object for CSI containing function.
     897 *
     898 * This is used to obtain active object for invoking static function
     899 * @a fun. Only used in cases where we don't already have the object such
     900 * as when running the entry point. Otherwise this would be slow.
     901 *
     902 * @param run           Runner object
     903 * @param fun           Function to get static class object of
     904 *
     905 * @return              Static (class) object
     906 */
     907rdata_var_t *run_fun_sobject_find(run_t *run, stree_fun_t *fun)
     908{
     909        return run_sobject_find(run, fun_to_symbol(fun)->outer_csi);
    789910}
    790911
     
    15121633
    15131634        /* Create exception object. */
    1514         run_new_csi_inst(run, csi, &exc_vi);
     1635        run_new_csi_inst_ref(run, csi, sn_nonstatic, &exc_vi);
    15151636        assert(exc_vi->ic == ic_value);
    15161637
  • uspace/app/sbi/src/run.h

    r8f80c77 r1113c9e  
    3333
    3434void run_init(run_t *run);
     35void run_gdata_init(run_t *run);
    3536void run_program(run_t *run, stree_program_t *prog);
    3637void run_proc(run_t *run, run_proc_ar_t *proc_ar, rdata_item_t **res);
     
    4748run_block_ar_t *run_get_current_block_ar(run_t *run);
    4849stree_csi_t *run_get_current_csi(run_t *run);
     50
     51rdata_var_t *run_sobject_get(run_t *run, stree_csi_t *pcsi,
     52    rdata_var_t *pobj_var, sid_t name);
     53rdata_var_t *run_sobject_find(run_t *run, stree_csi_t *csi);
     54rdata_var_t *run_fun_sobject_find(run_t *run, stree_fun_t *fun);
    4955
    5056void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var);
  • uspace/app/sbi/src/run_expr.c

    r8f80c77 r1113c9e  
    104104static void run_access_object(run_t *run, stree_access_t *access,
    105105    rdata_item_t *arg, rdata_item_t **res);
     106static void run_access_object_static(run_t *run, stree_access_t *access,
     107    rdata_var_t *obj_var, rdata_item_t **res);
     108static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
     109    rdata_var_t *obj_var, rdata_item_t **res);
    106110static void run_access_symbol(run_t *run, stree_access_t *access,
    107111    rdata_item_t *arg, rdata_item_t **res);
     
    207211        rdata_var_t *member_var;
    208212
     213        rdata_var_t *psobj;
     214        rdata_var_t *sobj;
     215        rdata_object_t *aobj;
     216
    209217#ifdef DEBUG_RUN_TRACE
    210218        printf("Run nameref.\n");
     
    238246        /* Determine currently active object or CSI. */
    239247        proc_ar = run_get_current_proc_ar(run);
    240         if (proc_ar->obj != NULL) {
    241                 assert(proc_ar->obj->vc == vc_object);
    242                 obj = proc_ar->obj->u.object_v;
    243                 csi_sym = obj->class_sym;
     248
     249        assert (proc_ar->obj != NULL);
     250        assert(proc_ar->obj->vc == vc_object);
     251        obj = proc_ar->obj->u.object_v;
     252        csi_sym = obj->class_sym;
     253
     254        if (csi_sym != NULL) {
    244255                csi = symbol_to_csi(csi_sym);
    245256                assert(csi != NULL);
    246257        } else {
    247                 csi = proc_ar->proc->outer_symbol->outer_csi;
    248                 obj = NULL;
     258                /* This happens in interactive mode. */
     259                csi = NULL;
    249260        }
    250261
     
    259270                printf("Referencing CSI.\n");
    260271#endif
    261                 item = rdata_item_new(ic_value);
    262                 value = rdata_value_new();
    263                 var = rdata_var_new(vc_deleg);
    264                 deleg_v = rdata_deleg_new();
    265 
    266                 item->u.value = value;
    267                 value->var = var;
    268                 var->u.deleg_v = deleg_v;
    269 
    270                 deleg_v->obj = NULL;
    271                 deleg_v->sym = sym;
    272                 *res = item;
     272                /* Obtain static object for the referenced CSI. */
     273                psobj = run->gdata; /* XXX */
     274                sobj = run_sobject_get(run, sym->u.csi, psobj,
     275                    nameref->name->sid);
     276
     277                /* Return reference to the object. */
     278                run_reference(run, sobj, res);
    273279                break;
    274280        case sc_ctor:
     
    334340                assert(csi != NULL);
    335341
    336                 /* XXX Assume variable is not static for now. */
    337                 assert(obj != NULL);
    338 
    339342                if (symbol_search_csi(run->program, csi, nameref->name)
    340                     == NULL) {
     343                    == NULL && !stree_symbol_is_static(sym)) {
    341344                        /* Variable is not in the current object. */
    342345                        printf("Error: Cannot access non-static member "
     
    349352                }
    350353
     354                if (stree_symbol_is_static(sym)) {
     355                        /*
     356                         * XXX This is too slow!
     357                         *
     358                         * However fixing this is non-trivial. We would
     359                         * have to have pointer to static object available
     360                         * for each object (therefore also for each object
     361                         * type).
     362                         */
     363                        sobj = run_sobject_find(run, sym->outer_csi);
     364                        assert(sobj->vc == vc_object);
     365                        aobj = sobj->u.object_v;
     366                } else {
     367                        aobj = obj;
     368                }
     369
    351370                /* Find member variable in object. */
    352                 member_var = intmap_get(&obj->fields, nameref->name->sid);
     371                member_var = intmap_get(&aobj->fields, nameref->name->sid);
    353372                assert(member_var != NULL);
    354373
     
    13611380
    13621381        /* Create CSI instance. */
    1363         run_new_csi_inst(run, csi, res);
     1382        run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
    13641383
    13651384        /* Run the constructor. */
     
    14671486}
    14681487
    1469 /** Evaluate delegate-member acccess.
     1488/** Evaluate delegate member acccess.
    14701489 *
    14711490 * @param run           Runner object
     
    14771496    rdata_item_t *arg, rdata_item_t **res)
    14781497{
    1479         rdata_item_t *arg_vi;
    1480         rdata_value_t *arg_val;
    1481         rdata_deleg_t *deleg_v;
    1482         stree_symbol_t *member;
    1483 
    1484 #ifdef DEBUG_RUN_TRACE
    1485         printf("Run delegate access operation.\n");
    1486 #endif
    1487         run_cvt_value_item(run, arg, &arg_vi);
    1488         arg_val = arg_vi->u.value;
    1489         assert(arg_val->var->vc == vc_deleg);
    1490 
    1491         deleg_v = arg_val->var->u.deleg_v;
    1492         if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) {
    1493                 printf("Error: Using '.' with delegate to different object "
    1494                     "than a CSI (%d).\n", deleg_v->sym->sc);
    1495                 exit(1);
    1496         }
    1497 
    1498         member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
    1499             access->member_name);
    1500 
    1501         /* Member existence should be ensured by static type checking. */
    1502         assert(member != NULL);
    1503 
    1504 #ifdef DEBUG_RUN_TRACE
    1505         printf("Found member '%s'.\n",
    1506             strtab_get_str(access->member_name->sid));
    1507 #endif
    1508 
    1509         /*
    1510          * Reuse existing item, value, var, deleg.
    1511          * XXX This is maybe not a good idea because it complicates memory
    1512          * management as there is not a single owner
    1513          */
    1514         deleg_v->sym = member;
    1515         *res = arg;
     1498        (void) run;
     1499        (void) access;
     1500        (void) arg;
     1501        (void) res;
     1502
     1503        printf("Error: Using '.' with delegate.\n");
     1504        exit(1);
    15161505}
    15171506
     
    15261515    rdata_item_t *arg, rdata_item_t **res)
    15271516{
     1517        rdata_var_t *obj_var;
     1518        rdata_object_t *object;
     1519
     1520#ifdef DEBUG_RUN_TRACE
     1521        printf("Run object access operation.\n");
     1522#endif
     1523        assert(arg->ic == ic_address);
     1524        assert(arg->u.address->ac == ac_var);
     1525
     1526        obj_var = arg->u.address->u.var_a->vref;
     1527        assert(obj_var->vc == vc_object);
     1528
     1529        object = obj_var->u.object_v;
     1530
     1531        if (object->static_obj == sn_static)
     1532                run_access_object_static(run, access, obj_var, res);
     1533        else
     1534                run_access_object_nonstatic(run, access, obj_var, res);
     1535}
     1536
     1537/** Evaluate static object member acccess.
     1538 *
     1539 * @param run           Runner object
     1540 * @param access        Access operation
     1541 * @param arg           Evaluated base expression
     1542 * @param res           Place to store result
     1543 */
     1544static void run_access_object_static(run_t *run, stree_access_t *access,
     1545    rdata_var_t *obj_var, rdata_item_t **res)
     1546{
     1547        rdata_object_t *object;
    15281548        stree_symbol_t *member;
    1529         rdata_var_t *object_var;
    1530         rdata_object_t *object;
     1549        stree_csi_t *member_csi;
     1550
     1551        rdata_deleg_t *deleg_v;
    15311552        rdata_item_t *ritem;
     1553        rdata_value_t *rvalue;
     1554        rdata_var_t *rvar;
    15321555        rdata_address_t *address;
    15331556        rdata_addr_var_t *addr_var;
     
    15351558        rdata_aprop_named_t *aprop_named;
    15361559        rdata_deleg_t *deleg_p;
    1537 
    1538         rdata_value_t *value;
    1539         rdata_deleg_t *deleg_v;
    1540         rdata_var_t *var;
    1541 
    1542 #ifdef DEBUG_RUN_TRACE
    1543         printf("Run object access operation.\n");
    1544 #endif
    1545         assert(arg->ic == ic_address);
    1546         assert(arg->u.address->ac == ac_var);
    1547         assert(arg->u.address->u.var_a->vref->vc == vc_object);
    1548 
    1549         object_var = arg->u.address->u.var_a->vref;
    1550         object = object_var->u.object_v;
     1560        rdata_var_t *mvar;
     1561
     1562#ifdef DEBUG_RUN_TRACE
     1563        printf("Run static object access operation.\n");
     1564#endif
     1565        assert(obj_var->vc == vc_object);
     1566        object = obj_var->u.object_v;
     1567
     1568        assert(object->static_obj == sn_static);
    15511569
    15521570        member = symbol_search_csi(run->program, object->class_sym->u.csi,
    15531571            access->member_name);
    15541572
    1555         if (member == NULL) {
    1556                 printf("Error: Object of class '");
    1557                 symbol_print_fqn(object->class_sym);
    1558                 printf("' has no member named '%s'.\n",
    1559                     strtab_get_str(access->member_name->sid));
    1560                 exit(1);
    1561         }
     1573        /* Member existence should be ensured by static type checking. */
     1574        assert(member != NULL);
    15621575
    15631576#ifdef DEBUG_RUN_TRACE
     
    15661579#endif
    15671580
    1568         /* Make compiler happy. */
    1569         ritem = NULL;
    1570 
    15711581        switch (member->sc) {
    15721582        case sc_csi:
    1573                 printf("Error: Accessing object member which is nested CSI.\n");
    1574                 exit(1);
     1583                /* Get child static object. */
     1584                member_csi = symbol_to_csi(member);
     1585                assert(member_csi != NULL);
     1586
     1587                mvar = run_sobject_get(run, member_csi, obj_var,
     1588                    access->member_name->sid);
     1589
     1590                ritem = rdata_item_new(ic_address);
     1591                address = rdata_address_new(ac_var);
     1592                ritem->u.address = address;
     1593
     1594                addr_var = rdata_addr_var_new();
     1595                address->u.var_a = addr_var;
     1596                addr_var->vref = mvar;
     1597
     1598                *res = ritem;
     1599                break;
     1600        case sc_ctor:
     1601                /* It is not possible to reference a constructor explicitly. */
     1602                assert(b_false);
    15751603        case sc_deleg:
    15761604                printf("Error: Accessing object member which is a delegate.\n");
     
    15791607                printf("Error: Accessing object member which is an enum.\n");
    15801608                exit(1);
    1581         case sc_ctor:
    1582                 /* It is not possible to reference a constructor explicitly. */
    1583                 assert(b_false);
    15841609        case sc_fun:
    15851610                /* Construct anonymous delegate. */
    15861611                ritem = rdata_item_new(ic_value);
    1587                 value = rdata_value_new();
    1588                 ritem->u.value = value;
    1589 
    1590                 var = rdata_var_new(vc_deleg);
    1591                 value->var = var;
     1612                rvalue = rdata_value_new();
     1613                ritem->u.value = rvalue;
     1614
     1615                rvar = rdata_var_new(vc_deleg);
     1616                rvalue->var = rvar;
     1617
    15921618                deleg_v = rdata_deleg_new();
    1593                 var->u.deleg_v = deleg_v;
    1594 
    1595                 deleg_v->obj = arg->u.address->u.var_a->vref;
     1619                rvar->u.deleg_v = deleg_v;
     1620
     1621                deleg_v->obj = obj_var;
    15961622                deleg_v->sym = member;
     1623                *res = ritem;
    15971624                break;
    15981625        case sc_var:
    1599                 /* Construct variable address item. */
     1626                /* Get static object member variable. */
     1627                mvar = intmap_get(&object->fields, access->member_name->sid);
     1628
    16001629                ritem = rdata_item_new(ic_address);
    16011630                address = rdata_address_new(ac_var);
     1631                ritem->u.address = address;
     1632
    16021633                addr_var = rdata_addr_var_new();
    1603                 ritem->u.address = address;
    16041634                address->u.var_a = addr_var;
    1605 
    1606                 addr_var->vref = intmap_get(&object->fields,
    1607                     access->member_name->sid);
    1608                 assert(addr_var->vref != NULL);
     1635                addr_var->vref = mvar;
     1636
     1637                *res = ritem;
    16091638                break;
    16101639        case sc_prop:
     
    16191648
    16201649                deleg_p = rdata_deleg_new();
    1621                 deleg_p->obj = object_var;
     1650                deleg_p->obj = obj_var;
     1651                deleg_p->sym = member;
     1652                addr_prop->u.named->prop_d = deleg_p;
     1653
     1654                *res = ritem;
     1655                break;
     1656        }
     1657}
     1658
     1659/** Evaluate object member acccess.
     1660 *
     1661 * @param run           Runner object
     1662 * @param access        Access operation
     1663 * @param arg           Evaluated base expression
     1664 * @param res           Place to store result
     1665 */
     1666static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
     1667    rdata_var_t *obj_var, rdata_item_t **res)
     1668{
     1669        rdata_object_t *object;
     1670        stree_symbol_t *member;
     1671        rdata_item_t *ritem;
     1672        rdata_address_t *address;
     1673        rdata_addr_var_t *addr_var;
     1674        rdata_addr_prop_t *addr_prop;
     1675        rdata_aprop_named_t *aprop_named;
     1676        rdata_deleg_t *deleg_p;
     1677
     1678        rdata_value_t *value;
     1679        rdata_deleg_t *deleg_v;
     1680        rdata_var_t *var;
     1681
     1682#ifdef DEBUG_RUN_TRACE
     1683        printf("Run nonstatic object access operation.\n");
     1684#endif
     1685        assert(obj_var->vc == vc_object);
     1686        object = obj_var->u.object_v;
     1687
     1688        assert(object->static_obj == sn_nonstatic);
     1689
     1690        member = symbol_search_csi(run->program, object->class_sym->u.csi,
     1691            access->member_name);
     1692
     1693        if (member == NULL) {
     1694                printf("Error: Object of class '");
     1695                symbol_print_fqn(object->class_sym);
     1696                printf("' has no member named '%s'.\n",
     1697                    strtab_get_str(access->member_name->sid));
     1698                exit(1);
     1699        }
     1700
     1701#ifdef DEBUG_RUN_TRACE
     1702        printf("Found member '%s'.\n",
     1703            strtab_get_str(access->member_name->sid));
     1704#endif
     1705
     1706        /* Make compiler happy. */
     1707        ritem = NULL;
     1708
     1709        switch (member->sc) {
     1710        case sc_csi:
     1711                printf("Error: Accessing object member which is nested CSI.\n");
     1712                exit(1);
     1713        case sc_ctor:
     1714                /* It is not possible to reference a constructor explicitly. */
     1715                assert(b_false);
     1716        case sc_deleg:
     1717                printf("Error: Accessing object member which is a delegate.\n");
     1718                exit(1);
     1719        case sc_enum:
     1720                printf("Error: Accessing object member which is an enum.\n");
     1721                exit(1);
     1722        case sc_fun:
     1723                /* Construct anonymous delegate. */
     1724                ritem = rdata_item_new(ic_value);
     1725                value = rdata_value_new();
     1726                ritem->u.value = value;
     1727
     1728                var = rdata_var_new(vc_deleg);
     1729                value->var = var;
     1730                deleg_v = rdata_deleg_new();
     1731                var->u.deleg_v = deleg_v;
     1732
     1733                deleg_v->obj = obj_var;
     1734                deleg_v->sym = member;
     1735                break;
     1736        case sc_var:
     1737                /* Construct variable address item. */
     1738                ritem = rdata_item_new(ic_address);
     1739                address = rdata_address_new(ac_var);
     1740                addr_var = rdata_addr_var_new();
     1741                ritem->u.address = address;
     1742                address->u.var_a = addr_var;
     1743
     1744                addr_var->vref = intmap_get(&object->fields,
     1745                    access->member_name->sid);
     1746                assert(addr_var->vref != NULL);
     1747                break;
     1748        case sc_prop:
     1749                /* Construct named property address. */
     1750                ritem = rdata_item_new(ic_address);
     1751                address = rdata_address_new(ac_prop);
     1752                addr_prop = rdata_addr_prop_new(apc_named);
     1753                aprop_named = rdata_aprop_named_new();
     1754                ritem->u.address = address;
     1755                address->u.prop_a = addr_prop;
     1756                addr_prop->u.named = aprop_named;
     1757
     1758                deleg_p = rdata_deleg_new();
     1759                deleg_p->obj = obj_var;
    16221760                deleg_p->sym = member;
    16231761                addr_prop->u.named->prop_d = deleg_p;
     
    21682306        rdata_item_t *rdest_i, *rsrc_i;
    21692307        rdata_item_t *rsrc_vi;
    2170         rdata_value_t *src_val;
    21712308
    21722309#ifdef DEBUG_RUN_TRACE
     
    21872324        run_cvt_value_item(run, rsrc_i, &rsrc_vi);
    21882325        assert(rsrc_vi->ic == ic_value);
    2189         src_val = rsrc_vi->u.value;
    21902326
    21912327        if (rdest_i->ic != ic_address) {
     
    23312467
    23322468        /* Construct object of the relevant boxed type. */
    2333         run_new_csi_inst(run, csi, res);
     2469        run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
    23342470
    23352471        /* Set the 'Value' field */
     
    23482484}
    23492485
    2350 /** Create new CSI instance.
     2486/** Create new CSI instance and return reference to it.
    23512487 *
    23522488 * Create a new object, instance of @a csi.
     
    23572493 * run any constructor.
    23582494 *
    2359  * @param run           Runner object
    2360  * @param as_op         @c as conversion expression
    2361  * @param res           Place to store result
    2362  */
    2363 void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
     2495 * If @a sn is @c sn_nonstatic a regular object is created, containing all
     2496 * non-static member variables. If @a sn is @c sn_static a static object
     2497 * is created, containing all static member variables.
     2498 *
     2499 * @param run           Runner object
     2500 * @param csi           CSI to create instance of
     2501 * @param sn            @c sn_static to create a static (class) object,
     2502 *                      @c sn_nonstatic to create a regular object
     2503 * @param res           Place to store result
     2504 */
     2505void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
     2506    rdata_item_t **res)
     2507{
     2508        rdata_var_t *obj_var;
     2509
     2510        /* Create object. */
     2511        run_new_csi_inst(run, csi, sn, &obj_var);
     2512
     2513        /* Create reference to the new object. */
     2514        run_reference(run, obj_var, res);
     2515}
     2516
     2517/** Create new CSI instance.
     2518 *
     2519 * Create a new object, instance of @a csi.
     2520 * XXX This does not work with generics as @a csi cannot specify a generic
     2521 * type.
     2522 *
     2523 * Initialize the fields with default values of their types, but do not
     2524 * run any constructor.
     2525 *
     2526 * If @a sn is @c sn_nonstatic a regular object is created, containing all
     2527 * non-static member variables. If @a sn is @c sn_static a static object
     2528 * is created, containing all static member variables.
     2529 *
     2530 * @param run           Runner object
     2531 * @param csi           CSI to create instance of
     2532 * @param sn            @c sn_static to create a static (class) object,
     2533 *                      @c sn_nonstatic to create a regular object
     2534 * @param res           Place to store result
     2535 */
     2536void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn,
     2537    rdata_var_t **res)
    23642538{
    23652539        rdata_object_t *obj;
     
    23682542        stree_symbol_t *csi_sym;
    23692543        stree_csimbr_t *csimbr;
     2544        stree_var_t *var;
     2545        statns_t var_sn;
    23702546
    23712547        rdata_var_t *mbr_var;
     
    23842560        obj = rdata_object_new();
    23852561        obj->class_sym = csi_sym;
     2562        obj->static_obj = sn;
    23862563        intmap_init(&obj->fields);
    23872564
     
    23892566        obj_var->u.object_v = obj;
    23902567
    2391         /* Create object fields. */
     2568        /* For this CSI and all base CSIs */
    23922569        while (csi != NULL) {
     2570
     2571                /* For all members */
    23932572                node = list_first(&csi->members);
    23942573                while (node != NULL) {
    23952574                        csimbr = list_node_data(node, stree_csimbr_t *);
     2575
     2576                        /* Is it a member variable? */
    23962577                        if (csimbr->cc == csimbr_var) {
    2397                                 /* Compute field type. XXX Memoize. */
    2398                                 run_texpr(run->program, csi,
    2399                                     csimbr->u.var->type,
    2400                                     &field_ti);
    2401 
    2402                                 /* Create and initialize field. */
    2403                                 run_var_new(run, field_ti, &mbr_var);
    2404 
    2405                                 /* Add to field map. */
    2406                                 intmap_set(&obj->fields,
    2407                                     csimbr->u.var->name->sid,
    2408                                     mbr_var);
     2578                                var = csimbr->u.var;
     2579
     2580                                /* Is it static/nonstatic? */
     2581                                var_sn = stree_symbol_has_attr(
     2582                                    var_to_symbol(var), sac_static);
     2583                                if (var_sn == sn) {
     2584                                        /* Compute field type. XXX Memoize. */
     2585                                        run_texpr(run->program, csi, var->type,
     2586                                            &field_ti);
     2587
     2588                                        /* Create and initialize field. */
     2589                                        run_var_new(run, field_ti, &mbr_var);
     2590
     2591                                        /* Add to field map. */
     2592                                        intmap_set(&obj->fields, var->name->sid,
     2593                                            mbr_var);
     2594                                }
    24092595                        }
    24102596
     
    24162602        }
    24172603
    2418         /* Create reference to the new object. */
    2419         run_reference(run, obj_var, res);
     2604        *res = obj_var;
    24202605}
    24212606
  • uspace/app/sbi/src/run_expr.h

    r8f80c77 r1113c9e  
    3434void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res);
    3535
    36 void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res);
     36void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
     37    rdata_item_t **res);
     38void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn,
     39    rdata_var_t **res);
     40
    3741bool_t run_item_boolean_value(run_t *run, rdata_item_t *item);
    3842
  • uspace/app/sbi/src/run_t.h

    r8f80c77 r1113c9e  
    114114        /** Thread-private state */
    115115        run_thread_ar_t *thread_ar;
     116
     117        /** Global state */
     118        struct rdata_var *gdata;
    116119} run_t;
    117120
  • uspace/app/sbi/src/run_texpr.c

    r8f80c77 r1113c9e  
    140140        }
    141141
     142        /* Make compiler happy. */
     143        titem = NULL;
     144
    142145        switch (sym->sc) {
    143146        case sc_csi:
     
    147150                titem->u.tobject = tobject;
    148151
    149                 tobject->static_ref = b_false;
     152                tobject->static_ref = sn_nonstatic;
    150153                tobject->csi = sym->u.csi;
    151154                list_init(&tobject->targs);
     
    278281        (void) tliteral;
    279282
     283        /* Make compiler happy. */
     284        tpc = 0;
     285
    280286        switch (tliteral->tlc) {
    281287        case tlc_bool: tpc = tpc_bool; break;
     
    342348        }
    343349
     350        /* Make compiler happy. */
     351        titem = NULL;
     352
    344353        switch (sym->sc) {
    345354        case sc_csi:
     
    349358                titem->u.tobject = tobject;
    350359
    351                 tobject->static_ref = b_false;
     360                tobject->static_ref = sn_nonstatic;
    352361                tobject->csi = sym->u.csi;
    353362                list_init(&tobject->targs);
     
    429438
    430439        list_node_t *farg_n;
    431         stree_targ_t *farg;
    432440
    433441#ifdef DEBUG_RUN_TRACE
     
    450458        }
    451459
    452         tobject->static_ref = b_false;
     460        tobject->static_ref = sn_nonstatic;
    453461        tobject->csi = base_ti->u.tobject->csi;
    454462        list_init(&tobject->targs);
     
    458466        arg_n = list_first(&tapply->targs);
    459467        while (farg_n != NULL && arg_n != NULL) {
    460                 farg = list_node_data(farg_n, stree_targ_t *);
    461468                arg = list_node_data(arg_n, stree_texpr_t *);
    462469
  • uspace/app/sbi/src/stree.c

    r8f80c77 r1113c9e  
    9292        csi->ancr_state = ws_unvisited;
    9393        csi->name = NULL;
    94         csi->base_csi_ref = NULL;
     94        csi->base_csi = NULL;
     95        list_init(&csi->inherit);
     96        list_init(&csi->impl_if_ti);
    9597        list_init(&csi->members);
     98
    9699        return csi;
    97100}
     
    930933
    931934        symbol->sc = sc;
     935        list_init(&symbol->attr);
     936
    932937        return symbol;
    933938}
     
    10181023
    10191024        /* We went all the way to the root and did not find b. */
     1025        return b_false;
     1026}
     1027
     1028/** Determine if @a symbol is static.
     1029 *
     1030 * @param symbol        Symbol
     1031 * @return              @c b_true if symbol is static, @c b_false otherwise
     1032 */
     1033bool_t stree_symbol_is_static(stree_symbol_t *symbol)
     1034{
     1035        /* Module-wide symbols are static. */
     1036        if (symbol->outer_csi == NULL)
     1037                return b_true;
     1038
     1039        /* Symbols with @c static attribute are static. */
     1040        if (stree_symbol_has_attr(symbol, sac_static))
     1041                return b_true;
     1042
     1043        switch (symbol->sc) {
     1044        case sc_csi:
     1045        case sc_deleg:
     1046        case sc_enum:
     1047                return b_true;
     1048        case sc_ctor:
     1049        case sc_fun:
     1050        case sc_var:
     1051        case sc_prop:
     1052                break;
     1053        }
     1054
    10201055        return b_false;
    10211056}
  • uspace/app/sbi/src/stree.h

    r8f80c77 r1113c9e  
    9696bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac);
    9797bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b);
     98bool_t stree_symbol_is_static(stree_symbol_t *symbol);
    9899stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident);
    99100stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident);
  • uspace/app/sbi/src/stree_t.h

    r8f80c77 r1113c9e  
    639639        /** Variadic argument or @c NULL if none. */
    640640        stree_proc_arg_t *varg;
     641
     642        /** Type of the property */
     643        struct tdata_item *titem;
    641644} stree_prop_t;
    642645
     
    698701        struct stree_symbol *symbol;
    699702
    700         /** Type expression referencing base CSI. */
    701         stree_texpr_t *base_csi_ref;
     703        /** Type expressions referencing inherited CSIs. */
     704        list_t inherit; /* of stree_texpr_t */
    702705
    703706        /** Base CSI. Only available when ancr_state == ws_visited. */
    704707        struct stree_csi *base_csi;
     708
     709        /** Types of implemented or accumulated interfaces. */
     710        list_t impl_if_ti; /* of tdata_item_t */
    705711
    706712        /** Node state for ancr walks. */
     
    736742typedef enum {
    737743        /** Builtin symbol (interpreter hook) */
    738         sac_builtin
     744        sac_builtin,
     745
     746        /** Static symbol */
     747        sac_static
    739748} symbol_attr_class_t;
    740749
  • uspace/app/sbi/src/stype.c

    r8f80c77 r1113c9e  
    6363static void stype_fun_body(stype_t *stype, stree_fun_t *fun);
    6464static void stype_block(stype_t *stype, stree_block_t *block);
     65
     66static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi);
     67static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi,
     68    tdata_item_t *iface_ti);
     69static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi,
     70    tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr);
     71static void stype_class_impl_check_fun(stype_t *stype,
     72    stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym);
     73static void stype_class_impl_check_prop(stype_t *stype,
     74    stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym);
    6575
    6676static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s);
     
    90100static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
    91101    tdata_item_t *dest);
    92 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,
    93     tdata_item_t *dest);
    94102
    95103static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
     
    168176        }
    169177
     178        if (csi->cc == csi_class)
     179                stype_class_impl_check(stype, csi);
     180
    170181        stype->current_csi = prev_ctx;
    171182}
     
    310321
    311322                enum_d->titem = titem;
    312         } else {
    313                 titem = enum_d->titem;
    314323        }
    315324}
     
    453462        assert(stype->proc_vr == NULL);
    454463
    455         /* Builtin functions do not have a body. */
     464        /* Declarations and builtin functions do not have a body. */
    456465        if (fun->proc->body == NULL)
    457466                return;
     
    475484{
    476485        tdata_item_t *titem;
    477 
    478         (void) stype;
    479         (void) var;
    480486
    481487        run_texpr(stype->program, stype->current_csi, var->type,
     
    484490                /* An error occured. */
    485491                stype_note_error(stype);
    486                 return;
    487492        }
    488493}
     
    500505        printf("'.\n");
    501506#endif
     507        if (prop->titem == NULL)
     508                stype_prop_header(stype, prop);
     509
    502510        stype->proc_vr = stype_proc_vr_new();
    503511        list_init(&stype->proc_vr->block_vr);
    504512
    505         if (prop->getter != NULL) {
     513        /* Property declarations do not have a getter body. */
     514        if (prop->getter != NULL && prop->getter->body != NULL) {
    506515                stype->proc_vr->proc = prop->getter;
    507516                stype_block(stype, prop->getter->body);
    508517        }
    509518
    510         if (prop->setter != NULL) {
     519        /* Property declarations do not have a setter body. */
     520        if (prop->setter != NULL && prop->setter->body != NULL) {
    511521                stype->proc_vr->proc = prop->setter;
    512522                stype_block(stype, prop->setter->body);
     
    515525        free(stype->proc_vr);
    516526        stype->proc_vr = NULL;
     527}
     528
     529/** Type property header.
     530 *
     531 * @param stype         Static typing object
     532 * @param prop          Property
     533 */
     534void stype_prop_header(stype_t *stype, stree_prop_t *prop)
     535{
     536        tdata_item_t *titem;
     537
     538#ifdef DEBUG_TYPE_TRACE
     539        printf("Type property '");
     540        symbol_print_fqn(prop_to_symbol(prop));
     541        printf("' header.\n");
     542#endif
     543        run_texpr(stype->program, stype->current_csi, prop->type,
     544            &titem);
     545        if (titem->tic == tic_ignore) {
     546                /* An error occured. */
     547                stype_note_error(stype);
     548                return;
     549        }
     550
     551        prop->titem = titem;
    517552}
    518553
     
    552587        assert(list_node_data(bvr_n, stype_block_vr_t *) == block_vr);
    553588        list_remove(&stype->proc_vr->block_vr, bvr_n);
     589}
     590
     591/** Verify that class fully implements all interfaces as it claims.
     592 *
     593 * @param stype         Static typing object
     594 * @param csi           CSI to check
     595 */
     596static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi)
     597{
     598        list_node_t *pred_n;
     599        stree_texpr_t *pred_te;
     600        tdata_item_t *pred_ti;
     601
     602#ifdef DEBUG_TYPE_TRACE
     603        printf("Verify that class implements all interfaces.\n");
     604#endif
     605        assert(csi->cc == csi_class);
     606
     607        pred_n = list_first(&csi->inherit);
     608        while (pred_n != NULL) {
     609                pred_te = list_node_data(pred_n, stree_texpr_t *);
     610                run_texpr(stype->program, csi, pred_te, &pred_ti);
     611
     612                assert(pred_ti->tic == tic_tobject);
     613                switch (pred_ti->u.tobject->csi->cc) {
     614                case csi_class:
     615                        break;
     616                case csi_struct:
     617                        assert(b_false);
     618                case csi_interface:
     619                        /* Store to impl_if_ti for later use. */
     620                        list_append(&csi->impl_if_ti, pred_ti);
     621
     622                        /* Check implementation of this interface. */
     623                        stype_class_impl_check_if(stype, csi, pred_ti);
     624                        break;
     625                }
     626
     627                pred_n = list_next(&csi->inherit, pred_n);
     628        }
     629}
     630
     631/** Verify that class fully implements an interface.
     632 *
     633 * @param stype         Static typing object
     634 * @param csi           CSI to check
     635 * @param iface         Interface that must be fully implemented
     636 */
     637static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi,
     638    tdata_item_t *iface_ti)
     639{
     640        tdata_tvv_t *iface_tvv;
     641        list_node_t *pred_n;
     642        tdata_item_t *pred_ti;
     643        tdata_item_t *pred_sti;
     644
     645        stree_csi_t *iface;
     646        list_node_t *ifmbr_n;
     647        stree_csimbr_t *ifmbr;
     648
     649        assert(csi->cc == csi_class);
     650
     651        assert(iface_ti->tic == tic_tobject);
     652        iface = iface_ti->u.tobject->csi;
     653        assert(iface->cc = csi_interface);
     654
     655#ifdef DEBUG_TYPE_TRACE
     656        printf("Verify that class fully implements interface.\n");
     657#endif
     658        /* Compute TVV for this interface reference. */
     659        stype_titem_to_tvv(stype, iface_ti, &iface_tvv);
     660
     661        /*
     662         * Recurse to accumulated interfaces.
     663         */
     664        pred_n = list_first(&iface->impl_if_ti);
     665        while (pred_n != NULL) {
     666                pred_ti = list_node_data(pred_n, tdata_item_t *);
     667                assert(pred_ti->tic == tic_tobject);
     668                assert(pred_ti->u.tobject->csi->cc == csi_interface);
     669
     670                /* Substitute real type parameters to predecessor reference. */
     671                tdata_item_subst(pred_ti, iface_tvv, &pred_sti);
     672
     673                /* Check accumulated interface. */
     674                stype_class_impl_check_if(stype, csi, pred_sti);
     675
     676                pred_n = list_next(&iface->impl_if_ti, pred_n);
     677        }
     678
     679        /*
     680         * Check all interface members.
     681         */
     682        ifmbr_n = list_first(&iface->members);
     683        while (ifmbr_n != NULL) {
     684                ifmbr = list_node_data(ifmbr_n, stree_csimbr_t *);
     685                stype_class_impl_check_mbr(stype, csi, iface_tvv, ifmbr);
     686
     687                ifmbr_n = list_next(&iface->members, ifmbr_n);
     688        }
     689}
     690
     691/** Verify that class fully implements an interface member.
     692 *
     693 * @param stype         Static typing object
     694 * @param csi           CSI to check
     695 * @param if_tvv        TVV for @a ifmbr
     696 * @param ifmbr         Interface that must be fully implemented
     697 */
     698static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi,
     699    tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr)
     700{
     701        stree_symbol_t *cmbr_sym;
     702        stree_symbol_t *ifmbr_sym;
     703        stree_ident_t *ifmbr_name;
     704
     705        assert(csi->cc == csi_class);
     706
     707#ifdef DEBUG_TYPE_TRACE
     708        printf("Verify that class implements interface member.\n");
     709#endif
     710        ifmbr_name = stree_csimbr_get_name(ifmbr);
     711
     712        cmbr_sym = symbol_search_csi(stype->program, csi, ifmbr_name);
     713        if (cmbr_sym == NULL) {
     714                printf("Error: CSI '");
     715                symbol_print_fqn(csi_to_symbol(csi));
     716                printf("' should implement '");
     717                symbol_print_fqn(csimbr_to_symbol(ifmbr));
     718                printf("' but it does not.\n");
     719                stype_note_error(stype);
     720                return;
     721        }
     722
     723        ifmbr_sym = csimbr_to_symbol(ifmbr);
     724        if (cmbr_sym->sc != ifmbr_sym->sc) {
     725                printf("Error: CSI '");
     726                symbol_print_fqn(csi_to_symbol(csi));
     727                printf("' implements '");
     728                symbol_print_fqn(csimbr_to_symbol(ifmbr));
     729                printf("' as a different kind of symbol.\n");
     730                stype_note_error(stype);
     731        }
     732
     733        switch (cmbr_sym->sc) {
     734        case sc_csi:
     735        case sc_ctor:
     736        case sc_deleg:
     737        case sc_enum:
     738                /*
     739                 * Checked at parse time. Interface should not have these
     740                 * member types.
     741                 */
     742                assert(b_false);
     743        case sc_fun:
     744                stype_class_impl_check_fun(stype, cmbr_sym, if_tvv, ifmbr_sym);
     745                break;
     746        case sc_var:
     747                /*
     748                 * Checked at parse time. Interface should not have these
     749                 * member types.
     750                 */
     751                assert(b_false);
     752        case sc_prop:
     753                stype_class_impl_check_prop(stype, cmbr_sym, if_tvv, ifmbr_sym);
     754                break;
     755        }
     756}
     757
     758/** Verify that class properly implements a function from an interface.
     759 *
     760 * @param stype         Static typing object
     761 * @param cfun_sym      Function symbol in class
     762 * @param if_tvv        TVV for @a ifun_sym
     763 * @param ifun_sym      Function declaration symbol in interface
     764 */
     765static void stype_class_impl_check_fun(stype_t *stype,
     766    stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym)
     767{
     768        stree_fun_t *cfun;
     769        tdata_fun_t *tcfun;
     770        stree_fun_t *ifun;
     771        tdata_item_t *sifun_ti;
     772        tdata_fun_t *tifun;
     773
     774#ifdef DEBUG_TYPE_TRACE
     775        printf("Verify that class '");
     776        symbol_print_fqn(csi_to_symbol(cfun_sym->outer_csi));
     777        printf("' implements function '");
     778        symbol_print_fqn(ifun_sym);
     779        printf("' properly.\n");
     780#endif
     781        assert(cfun_sym->sc == sc_fun);
     782        cfun = cfun_sym->u.fun;
     783
     784        assert(ifun_sym->sc == sc_fun);
     785        ifun = ifun_sym->u.fun;
     786
     787        assert(cfun->titem->tic == tic_tfun);
     788        tcfun = cfun->titem->u.tfun;
     789
     790        tdata_item_subst(ifun->titem, if_tvv, &sifun_ti);
     791        assert(sifun_ti->tic == tic_tfun);
     792        tifun = sifun_ti->u.tfun;
     793
     794        if (!stype_fun_sig_equal(stype, tcfun->tsig, tifun->tsig)) {
     795                cspan_print(cfun->name->cspan);
     796                printf(" Error: Type of function '");
     797                symbol_print_fqn(cfun_sym);
     798                printf("' (");
     799                tdata_item_print(cfun->titem);
     800                printf(") does not match type of '");
     801                symbol_print_fqn(ifun_sym);
     802                printf("' (");
     803                tdata_item_print(sifun_ti);
     804                printf(") which it should implement.\n");
     805                stype_note_error(stype);
     806        }
     807}
     808
     809/** Verify that class properly implements a function from an interface.
     810 *
     811 * @param stype         Static typing object
     812 * @param cprop_sym     Property symbol in class
     813 * @param if_tvv        TVV for @a ifun_sym
     814 * @param iprop_sym     Property declaration symbol in interface
     815 */
     816static void stype_class_impl_check_prop(stype_t *stype,
     817    stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym)
     818{
     819        stree_prop_t *cprop;
     820        stree_prop_t *iprop;
     821        tdata_item_t *siprop_ti;
     822
     823#ifdef DEBUG_TYPE_TRACE
     824        printf("Verify that class '");
     825        symbol_print_fqn(csi_to_symbol(cprop_sym->outer_csi));
     826        printf("' implements property '");
     827        symbol_print_fqn(iprop_sym);
     828        printf("' properly.\n");
     829#endif
     830        assert(cprop_sym->sc == sc_prop);
     831        cprop = cprop_sym->u.prop;
     832
     833        assert(iprop_sym->sc == sc_prop);
     834        iprop = iprop_sym->u.prop;
     835
     836        tdata_item_subst(iprop->titem, if_tvv, &siprop_ti);
     837
     838        if (!tdata_item_equal(cprop->titem, siprop_ti)) {
     839                cspan_print(cprop->name->cspan);
     840                printf(" Error: Type of property '");
     841                symbol_print_fqn(cprop_sym);
     842                printf("' (");
     843                tdata_item_print(cprop->titem);
     844                printf(") does not match type of '");
     845                symbol_print_fqn(iprop_sym);
     846                printf("' (");
     847                tdata_item_print(siprop_ti);
     848                printf(") which it should implement.\n");
     849                stype_note_error(stype);
     850        }
     851
     852        if (iprop->getter != NULL && cprop->getter == NULL) {
     853                cspan_print(cprop->name->cspan);
     854                printf(" Error: Property '");
     855                symbol_print_fqn(cprop_sym);
     856                printf("' is missing a getter, which is required by '");
     857                symbol_print_fqn(iprop_sym);
     858                printf("'.\n");
     859                stype_note_error(stype);
     860        }
     861
     862        if (iprop->setter != NULL && cprop->setter == NULL) {
     863                cspan_print(cprop->name->cspan);
     864                printf(" Error: Property '");
     865                symbol_print_fqn(cprop_sym);
     866                printf("' is missing a setter, which is required by '");
     867                symbol_print_fqn(iprop_sym);
     868                printf("'.\n");
     869                stype_note_error(stype);
     870        }
    554871}
    555872
     
    8241141        stype_expr(stype, exp_s->expr);
    8251142
    826         if (want_value == b_false && exp_s->expr->titem != NULL)
    827                 printf("Warning: Expression value ignored.\n");
     1143        if (want_value == b_false && exp_s->expr->titem != NULL) {
     1144                cspan_print(exp_s->expr->cspan);
     1145                printf(" Warning: Expression value ignored.\n");
     1146        }
    8281147}
    8291148
     
    9251244
    9261245        if (src->tic == tic_tebase) {
    927                 stype_convert_failure(stype, expr, dest);
     1246                stype_convert_failure(stype, convc_implicit, expr, dest);
    9281247                printf("Invalid use of reference to enum type in "
    9291248                    "expression.\n");
     
    9321251
    9331252        if (src->tic != dest->tic) {
    934                 stype_convert_failure(stype, expr, dest);
     1253                stype_convert_failure(stype, convc_implicit, expr, dest);
    9351254                return expr;
    9361255        }
     
    9871306        /* Check if both have the same tprimitive class. */
    9881307        if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
    989                 stype_convert_failure(stype, expr, dest);
     1308                stype_convert_failure(stype, convc_implicit, expr, dest);
    9901309
    9911310        return expr;
     
    10201339        bi = stype->program->builtin;
    10211340        csi_sym = csi_to_symbol(dest->u.tobject->csi);
     1341
     1342        /* Make compiler happy. */
     1343        bp_sym = NULL;
    10221344
    10231345        switch (src->u.tprimitive->tpc) {
     
    10281350        case tpc_string: bp_sym = bi->boxed_string; break;
    10291351        case tpc_resource:
    1030                 stype_convert_failure(stype, expr, dest);
     1352                stype_convert_failure(stype, convc_implicit, expr, dest);
    10311353                return expr;
    10321354        }
     
    10341356        /* Target type must be boxed @a src or Object */
    10351357        if (csi_sym != bp_sym && csi_sym != bi->gf_class)
    1036                 stype_convert_failure(stype, expr, dest);
     1358                stype_convert_failure(stype, convc_implicit, expr, dest);
    10371359
    10381360        /* Patch the code to box the primitive value */
     
    10581380{
    10591381        tdata_item_t *src;
    1060         tdata_item_t *cur;
    1061         stree_csi_t *cur_csi;
    1062         tdata_tvv_t *tvv;
    1063         tdata_item_t *b_ti, *bs_ti;
     1382        tdata_item_t *pred_ti;
    10641383
    10651384#ifdef DEBUG_TYPE_TRACE
    10661385        printf("Convert object type.\n");
    10671386#endif
    1068         list_node_t *ca_n, *da_n;
    1069         tdata_item_t *carg, *darg;
    1070 
    10711387        src = expr->titem;
    10721388        assert(src->tic == tic_tobject);
    10731389        assert(dest->tic == tic_tobject);
    10741390
    1075         cur = src;
    1076 
    1077         while (cur->u.tobject->csi != dest->u.tobject->csi) {
    1078 
    1079                 cur_csi = cur->u.tobject->csi;
    1080                 stype_titem_to_tvv(stype, cur, &tvv);
    1081 
    1082                 if (cur_csi->base_csi_ref != NULL) {
    1083                         run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti);
    1084                         if (b_ti->tic == tic_ignore) {
    1085                                 /* An error occured. */
    1086                                 stype_note_error(stype);
    1087                                 return expr;
    1088                         }
    1089 
    1090                         tdata_item_subst(b_ti, tvv, &bs_ti);
    1091                         cur = bs_ti;
    1092                         assert(cur->tic == tic_tobject);
    1093 
    1094                 } else if (cur_csi->base_csi != NULL) {
    1095                         /* No explicit reference. Use grandfather class. */
    1096                         cur = tdata_item_new(tic_tobject);
    1097                         cur->u.tobject = tdata_object_new();
    1098                         cur->u.tobject->csi = cur_csi->base_csi;
    1099                         cur->u.tobject->static_ref = b_false;
    1100 
    1101                         list_init(&cur->u.tobject->targs);
    1102                 } else {
    1103                         /* No match */
    1104                         stype_convert_failure(stype, expr, dest);
    1105                         return expr;
    1106                 }
    1107         }
    1108 
    1109         /* Verify that type arguments match */
    1110         ca_n = list_first(&cur->u.tobject->targs);
    1111         da_n = list_first(&dest->u.tobject->targs);
    1112 
    1113         while (ca_n != NULL && da_n != NULL) {
    1114                 carg = list_node_data(ca_n, tdata_item_t *);
    1115                 darg = list_node_data(da_n, tdata_item_t *);
    1116 
    1117                 if (tdata_item_equal(carg, darg) != b_true) {
    1118                         /* Diferent argument type */
    1119                         stype_convert_failure(stype, expr, dest);
    1120                         printf("Different argument type '");
    1121                         tdata_item_print(carg);
    1122                         printf("' vs. '");
    1123                         tdata_item_print(darg);
    1124                         printf("'.\n");
    1125                         return expr;
    1126                 }
    1127 
    1128                 ca_n = list_next(&cur->u.tobject->targs, ca_n);
    1129                 da_n = list_next(&dest->u.tobject->targs, da_n);
    1130         }
    1131 
    1132         if (ca_n != NULL || da_n != NULL) {
    1133                 /* Diferent number of arguments */
    1134                 stype_convert_failure(stype, expr, dest);
    1135                 printf("Different number of arguments.\n");
     1391        /*
     1392         * Find predecessor of the right type. This determines the
     1393         * type arguments that the destination type should have.
     1394         */
     1395        pred_ti = stype_tobject_find_pred(stype, src, dest);
     1396        if (pred_ti == NULL) {
     1397                stype_convert_failure(stype, convc_implicit, expr, dest);
     1398                printf("Not a base class or implemented or accumulated "
     1399                    "interface.\n");
     1400                return expr;
     1401        }
     1402
     1403        /*
     1404         * Verify that type arguments match with those specified for
     1405         * conversion destination.
     1406         */
     1407        if (stype_targs_check_equal(stype, pred_ti, dest) != EOK) {
     1408                stype_convert_failure(stype, convc_implicit, expr, dest);
    11361409                return expr;
    11371410        }
     
    11601433        /* Compare rank and base type. */
    11611434        if (src->u.tarray->rank != dest->u.tarray->rank) {
    1162                 stype_convert_failure(stype, expr, dest);
     1435                stype_convert_failure(stype, convc_implicit, expr, dest);
    11631436                return expr;
    11641437        }
     
    11671440        if (tdata_item_equal(src->u.tarray->base_ti,
    11681441            dest->u.tarray->base_ti) != b_true) {
    1169                 stype_convert_failure(stype, expr, dest);
     1442                stype_convert_failure(stype, convc_implicit, expr, dest);
    11701443        }
    11711444
     
    12051478        /* Both must be the same delegate. */
    12061479        if (sdeleg->deleg != ddeleg->deleg) {
    1207                 stype_convert_failure(stype, expr, dest);
     1480                stype_convert_failure(stype, convc_implicit, expr, dest);
    12081481                return expr;
    12091482        }
     
    12401513        /* Both must be of the same enum type (with the same declaration). */
    12411514        if (senum->enum_d != denum->enum_d) {
    1242                 stype_convert_failure(stype, expr, dest);
     1515                stype_convert_failure(stype, convc_implicit, expr, dest);
    12431516                return expr;
    12441517        }
     
    12791552
    12801553        if (!stype_fun_sig_equal(stype, ssig, dsig)) {
    1281                 stype_convert_failure(stype, expr, dest);
     1554                stype_convert_failure(stype, convc_implicit, expr, dest);
    12821555                return expr;
    12831556        }
     
    13111584        /* Currently only allow if both types are the same. */
    13121585        if (src->u.tvref->targ != dest->u.tvref->targ) {
    1313                 stype_convert_failure(stype, expr, dest);
     1586                stype_convert_failure(stype, convc_implicit, expr, dest);
    13141587                return expr;
    13151588        }
     
    13241597 * @param dest          Destination type
    13251598 */
    1326 static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,
    1327     tdata_item_t *dest)
     1599void stype_convert_failure(stype_t *stype, stype_conv_class_t convc,
     1600    stree_expr_t *expr, tdata_item_t *dest)
    13281601{
    13291602        cspan_print(expr->cspan);
    1330         printf(" Error: Cannot convert ");
     1603        printf(" Error: ");
     1604        switch (convc) {
     1605        case convc_implicit: printf("Cannot implicitly convert '"); break;
     1606        case convc_as: printf("Cannot use 'as' to convert '"); break;
     1607        }
     1608
    13311609        tdata_item_print(expr->titem);
    13321610        printf(" to ");
     
    13971675}
    13981676
     1677/** Find predecessor CSI and return its type item.
     1678 *
     1679 * Looks for predecessor of CSI type @a src that matches @a dest.
     1680 * The type maches if they use the same generic CSI definition, type
     1681 * arguments are ignored. If found, returns the type arguments that
     1682 * @a dest should have in order to be a true predecessor of @a src.
     1683 *
     1684 * @param stype         Static typing object
     1685 * @param src           Source type
     1686 * @param dest          Destination type
     1687 * @return              Type matching @a dest with correct type arguments
     1688 */
     1689tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src,
     1690    tdata_item_t *dest)
     1691{
     1692        stree_csi_t *src_csi;
     1693        tdata_tvv_t *tvv;
     1694        tdata_item_t *b_ti, *bs_ti;
     1695
     1696        list_node_t *pred_n;
     1697        stree_texpr_t *pred_te;
     1698
     1699        tdata_item_t *res_ti;
     1700
     1701#ifdef DEBUG_TYPE_TRACE
     1702        printf("Find CSI predecessor.\n");
     1703#endif
     1704        assert(src->tic == tic_tobject);
     1705        assert(dest->tic == tic_tobject);
     1706
     1707        if (src->u.tobject->csi == dest->u.tobject->csi)
     1708                return src;
     1709
     1710        src_csi = src->u.tobject->csi;
     1711        stype_titem_to_tvv(stype, src, &tvv);
     1712
     1713        res_ti = NULL;
     1714
     1715        switch (dest->u.tobject->csi->cc) {
     1716        case csi_class:
     1717                /* Destination is a class. Look at base class. */
     1718                pred_te = symbol_get_base_class_ref(stype->program,
     1719                    src_csi);
     1720                if (pred_te != NULL) {
     1721                        run_texpr(stype->program, src_csi, pred_te,
     1722                            &b_ti);
     1723                } else if (src_csi->base_csi != NULL &&
     1724                        src->u.tobject->csi->cc == csi_class) {
     1725                        /* No explicit reference. Use grandfather class. */
     1726                        b_ti = tdata_item_new(tic_tobject);
     1727                        b_ti->u.tobject = tdata_object_new();
     1728                        b_ti->u.tobject->csi = src_csi->base_csi;
     1729                        b_ti->u.tobject->static_ref = sn_nonstatic;
     1730
     1731                        list_init(&b_ti->u.tobject->targs);
     1732                } else {
     1733                        /* No match */
     1734                        return NULL;
     1735                }
     1736
     1737                /* Substitute type variables to get predecessor type. */
     1738                tdata_item_subst(b_ti, tvv, &bs_ti);
     1739                assert(bs_ti->tic == tic_tobject);
     1740
     1741                /* Recurse to compute the rest of the path. */
     1742                res_ti = stype_tobject_find_pred(stype, bs_ti, dest);
     1743                if (b_ti->tic == tic_ignore) {
     1744                        /* An error occured. */
     1745                        return NULL;
     1746                }
     1747                break;
     1748        case csi_struct:
     1749                assert(b_false);
     1750        case csi_interface:
     1751                /*
     1752                 * Destination is an interface. Look at implemented
     1753                 * or accumulated interfaces.
     1754                 */
     1755                pred_n = list_first(&src_csi->inherit);
     1756                while (pred_n != NULL) {
     1757                        pred_te = list_node_data(pred_n, stree_texpr_t *);
     1758                        run_texpr(stype->program, src_csi, pred_te,
     1759                            &b_ti);
     1760
     1761                        /* Substitute type variables to get predecessor type. */
     1762                        tdata_item_subst(b_ti, tvv, &bs_ti);
     1763                        assert(bs_ti->tic == tic_tobject);
     1764
     1765                        /* Recurse to compute the rest of the path. */
     1766                        res_ti = stype_tobject_find_pred(stype, bs_ti, dest);
     1767                        if (res_ti != NULL)
     1768                                break;
     1769
     1770                        pred_n = list_next(&src_csi->inherit, pred_n);
     1771                }
     1772                break;
     1773        }
     1774
     1775        return res_ti;
     1776}
     1777
     1778/** Check whether type arguments of expression type and another type are equal.
     1779 *
     1780 * Compare type arguments of the type of @a expr and of type @a b_ti.
     1781 * @a convc denotes the type of conversion for which we perform this check
     1782 * (for sake of error reporting).
     1783 *
     1784 * If the type arguments are not equal a typing error and a conversion error
     1785 * message is generated.
     1786 *
     1787 * @param stype         Static typing object
     1788 * @param expr          Expression
     1789 * @param b_ti          b_tiination type
     1790 * @return              EOK if equal, EINVAL if not.
     1791 */
     1792int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti,
     1793    tdata_item_t *b_ti)
     1794{
     1795        list_node_t *arg_a_n, *arg_b_n;
     1796        tdata_item_t *arg_a, *arg_b;
     1797
     1798        (void) stype;
     1799
     1800#ifdef DEBUG_TYPE_TRACE
     1801        printf("Check if type arguments match.\n");
     1802#endif
     1803        assert(a_ti->tic == tic_tobject);
     1804        assert(b_ti->tic == tic_tobject);
     1805
     1806        /*
     1807         * Verify that type arguments match with those specified for
     1808         * conversion b_tiination.
     1809         */
     1810        arg_a_n = list_first(&a_ti->u.tobject->targs);
     1811        arg_b_n = list_first(&b_ti->u.tobject->targs);
     1812
     1813        while (arg_a_n != NULL && arg_b_n != NULL) {
     1814                arg_a = list_node_data(arg_a_n, tdata_item_t *);
     1815                arg_b = list_node_data(arg_b_n, tdata_item_t *);
     1816
     1817                if (tdata_item_equal(arg_a, arg_b) != b_true) {
     1818                        /* Diferent argument type */
     1819                        printf("Different argument type '");
     1820                        tdata_item_print(arg_a);
     1821                        printf("' vs. '");
     1822                        tdata_item_print(arg_b);
     1823                        printf("'.\n");
     1824                        return EINVAL;
     1825                }
     1826
     1827                arg_a_n = list_next(&a_ti->u.tobject->targs, arg_a_n);
     1828                arg_b_n = list_next(&b_ti->u.tobject->targs, arg_b_n);
     1829        }
     1830
     1831        if (arg_a_n != NULL || arg_b_n != NULL) {
     1832                /* Diferent number of arguments */
     1833                printf("Different number of arguments.\n");
     1834                return EINVAL;
     1835        }
     1836
     1837        return EOK;
     1838}
    13991839
    14001840
     
    14481888
    14491889        /* Compare return type */
    1450         if (!tdata_item_equal(asig->rtype, bsig->rtype))
    1451                 return b_false;
     1890
     1891        if (asig->rtype != NULL || bsig->rtype != NULL) {
     1892                if (asig->rtype == NULL ||
     1893                    bsig->rtype == NULL) {
     1894                        return b_false;
     1895                }
     1896
     1897                if (!tdata_item_equal(asig->rtype, bsig->rtype)) {
     1898                        return b_false;
     1899                }
     1900        }
    14521901
    14531902        return b_true;
  • uspace/app/sbi/src/stype.h

    r8f80c77 r1113c9e  
    3737void stype_enum(stype_t *stype, stree_enum_t *enum_d);
    3838void stype_fun_header(stype_t *stype, stree_fun_t *fun);
     39void stype_prop_header(stype_t *stype, stree_prop_t *prop);
    3940void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value);
    4041
     
    4445stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
    4546    tdata_item_t *dest);
     47void stype_convert_failure(stype_t *stype, stype_conv_class_t convc,
     48    stree_expr_t *expr, tdata_item_t *dest);
    4649stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr);
     50tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src,
     51    tdata_item_t *dest);
     52int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti,
     53    tdata_item_t *b_ti);
    4754
    4855tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg);
  • uspace/app/sbi/src/stype_expr.c

    r8f80c77 r1113c9e  
    9797static void stype_new(stype_t *stype, stree_new_t *new,
    9898    tdata_item_t **rtitem);
    99 static void stype_new_object_args(stype_t *stype, stree_new_t *new_op,
     99static void stype_new_object(stype_t *stype, stree_new_t *new_op,
    100100    tdata_item_t *obj_ti);
    101101
     
    194194        tdata_ebase_t *tebase;
    195195        stree_fun_t *fun;
     196        bool_t static_ctx;
    196197
    197198#ifdef DEBUG_TYPE_TRACE
     
    257258        }
    258259
     260        /* Determine if current procedure is static. */
     261        static_ctx = stree_symbol_is_static(stype->proc_vr->proc->outer_symbol);
     262
     263        /*
     264         * If the symbol is not found in current CSI, then we access it
     265         * in a static context. (Context of current object cannot be used.)
     266         */
     267        if (sym->outer_csi != stype->current_csi)
     268                static_ctx = b_true;
     269
     270        /* Check for referencing non-static symbol in static context. */
     271        if (static_ctx && !stree_symbol_is_static(sym)) {
     272                cspan_print(nameref->expr->cspan);
     273                printf(" Error: Referencing non-static symbol '");
     274                symbol_print_fqn(sym);
     275                printf("' in static context.\n");
     276                stype_note_error(stype);
     277                *rtitem = stype_recovery_titem(stype);
     278                return;
     279        }
     280
     281        /* Referencing static member in non-static context is allowed. */
     282
     283        /* Make compiler happy. */
     284        titem = NULL;
     285
    259286        switch (sym->sc) {
    260287        case sc_var:
     
    263290                break;
    264291        case sc_prop:
    265                 run_texpr(stype->program, stype->current_csi,
    266                     sym->u.prop->type, &titem);
     292                /* Type property header if it has not been typed yet. */
     293                stype_prop_header(stype, sym->u.prop);
     294                titem = sym->u.prop->titem;
    267295                break;
    268296        case sc_csi:
     
    274302                titem->u.tobject = tobject;
    275303
    276                 /* This is a static CSI reference. */
    277                 tobject->static_ref = b_true;
     304                tobject->static_ref = sn_static;
    278305                tobject->csi = csi;
    279306                break;
     
    330357        (void) stype;
    331358
     359        /* Make compiler happy. */
     360        tpc = 0;
     361
    332362        switch (literal->ltc) {
    333363        case ltc_bool: tpc = tpc_bool; break;
     
    375405        titem->u.tobject = tobject;
    376406
    377         tobject->static_ref = b_false;
     407        tobject->static_ref = sn_nonstatic;
    378408        tobject->csi = cur_csi;
    379409        list_init(&tobject->targs);
     
    513543        tdata_item_t *res_ti;
    514544
     545        /* Make compiler happy. */
     546        rtpc = 0;
     547
    515548        switch (binop->bc) {
    516549        case bo_equal:
     
    560593        (void) stype;
    561594
     595        /* Make compiler happy. */
     596        rtpc = 0;
     597
    562598        switch (binop->bc) {
    563599        case bo_equal:
     
    604640        (void) stype;
    605641
     642        /* Make compiler happy. */
     643        rtpc = 0;
     644
    606645        switch (binop->bc) {
    607646        case bo_equal:
     
    666705        tdata_item_t *res_ti;
    667706
     707        /* Make compiler happy. */
     708        rtpc = 0;
     709
    668710        switch (binop->bc) {
    669711        case bo_equal:
     
    941983
    942984        if ((*rtitem)->tic == tic_tobject)
    943                 stype_new_object_args(stype, new_op, *rtitem);
     985                stype_new_object(stype, new_op, *rtitem);
    944986}
    945987
     
    949991 * @param new_op        @c new operation
    950992 */
    951 static void stype_new_object_args(stype_t *stype, stree_new_t *new_op,
     993static void stype_new_object(stype_t *stype, stree_new_t *new_op,
    952994    tdata_item_t *obj_ti)
    953995{
     
    957999        stree_ident_t *ctor_ident;
    9581000        tdata_fun_sig_t *tsig;
     1001        tdata_tvv_t *obj_tvv;
     1002        tdata_item_t *ctor_sti;
    9591003
    9601004        assert(obj_ti->tic == tic_tobject);
    9611005        csi = obj_ti->u.tobject->csi;
     1006
     1007        if (csi->cc == csi_interface) {
     1008                cspan_print(new_op->expr->cspan);
     1009                printf(" Error: Cannot instantiate an interface.\n");
     1010                stype_note_error(stype);
     1011                return;
     1012        }
     1013
    9621014        ctor_ident = stree_ident_new();
    9631015        ctor_ident->sid = strtab_get_sid(CTOR_IDENT);
     
    9861038                return;
    9871039
    988         assert(ctor->titem->tic == tic_tfun);
    989         tsig = ctor->titem->u.tfun->tsig;
     1040        /* Substitute type arguments in constructor type. */
     1041        stype_titem_to_tvv(stype, obj_ti, &obj_tvv);
     1042        tdata_item_subst(ctor->titem, obj_tvv, &ctor_sti);
     1043        /* XXX Free obj_tvv */
     1044
     1045        assert(ctor_sti->tic == tic_tfun);
     1046        tsig = ctor_sti->u.tfun->tsig;
    9901047
    9911048        stype_call_args(stype, new_op->expr->cspan, &tsig->arg_ti,
     
    11041161        tdata_item_t *mtitem;
    11051162        tdata_tvv_t *tvv;
     1163        stree_csi_t *member_csi;
    11061164
    11071165#ifdef DEBUG_TYPE_TRACE
     
    11311189            strtab_get_str(access->member_name->sid));
    11321190#endif
     1191        /* Check for accessing non-static member in static context. */
     1192        if (tobject->static_ref == sn_static &&
     1193            !stree_symbol_is_static(member_sym)) {
     1194                cspan_print(access->member_name->cspan);
     1195                printf(" Error: Accessing non-static member '");
     1196                symbol_print_fqn(member_sym);
     1197                printf("' in static context.\n");
     1198                stype_note_error(stype);
     1199                *rtitem = stype_recovery_titem(stype);
     1200                return;
     1201        }
     1202
     1203        /* Check for accessing static member in non-static context. */
     1204        if (tobject->static_ref != sn_static &&
     1205            stree_symbol_is_static(member_sym)) {
     1206                cspan_print(access->member_name->cspan);
     1207                printf(" Error: Accessing static member '");
     1208                symbol_print_fqn(member_sym);
     1209                printf("' in non-static context.\n");
     1210                stype_note_error(stype);
     1211                *rtitem = stype_recovery_titem(stype);
     1212                return;
     1213        }
     1214
     1215        /* Make compiler happy. */
     1216        mtitem = NULL;
    11331217
    11341218        switch (member_sym->sc) {
    11351219        case sc_csi:
    1136                 cspan_print(access->member_name->cspan);
    1137                 printf(" Error: Accessing object member which is nested "
    1138                     "CSI.\n");
    1139                 stype_note_error(stype);
    1140                 *rtitem = stype_recovery_titem(stype);
    1141                 return;
     1220                member_csi = symbol_to_csi(member_sym);
     1221                assert(member_csi != NULL);
     1222
     1223                mtitem = tdata_item_new(tic_tobject);
     1224                tobject = tdata_object_new();
     1225                mtitem->u.tobject = tobject;
     1226
     1227                tobject->static_ref = sn_static;
     1228                tobject->csi = member_csi;
     1229                break;
    11421230        case sc_ctor:
    11431231                /* It is not possible to reference a constructor explicitly. */
     
    13371425        stree_expr_t *carg;
    13381426
    1339         int cnt;
    1340 
    13411427        /* Type and check regular arguments. */
    13421428        fargt_n = list_first(farg_tis);
    13431429        arg_n = list_first(args);
    13441430
    1345         cnt = 0;
    13461431        while (fargt_n != NULL && arg_n != NULL) {
    13471432                farg_ti = list_node_data(fargt_n, tdata_item_t *);
     
    16561741{
    16571742        tdata_item_t *titem;
     1743        tdata_item_t *pred_ti;
    16581744
    16591745#ifdef DEBUG_TYPE_TRACE
     
    16641750        run_texpr(stype->program, stype->current_csi, as_op->dtype, &titem);
    16651751
    1666         /* Check that target type is derived from argument type. */
    1667         if (tdata_is_ti_derived_from_ti(titem, as_op->arg->titem) != b_true) {
    1668                 cspan_print(as_op->dtype->cspan);
    1669                 printf(" Error: Target of 'as' operator '");
    1670                 tdata_item_print(titem);
    1671                 printf("' is not derived from '");
    1672                 tdata_item_print(as_op->arg->titem);
    1673                 printf("'.\n");
    1674                 stype_note_error(stype);
     1752        pred_ti = stype_tobject_find_pred(stype, titem, as_op->arg->titem);
     1753        if (pred_ti == NULL) {
     1754                /* No CSI match. */
     1755                stype_convert_failure(stype, convc_as, as_op->arg, titem);
     1756                *rtitem = titem;
     1757                return;
     1758        }
     1759
     1760        /*
     1761         * Verify that type arguments match with those specified for
     1762         * conversion destination.
     1763         */
     1764        if (stype_targs_check_equal(stype, pred_ti, as_op->arg->titem)
     1765            != EOK) {
     1766                stype_convert_failure(stype, convc_as, as_op->arg, titem);
     1767                *rtitem = titem;
     1768                return;
    16751769        }
    16761770
     
    17201814
    17211815        btitem->u.tobject = tobject;
    1722         tobject->static_ref = b_false;
     1816        tobject->static_ref = sn_nonstatic;
    17231817        tobject->csi = symbol_to_csi(csi_sym);
    17241818        assert(tobject->csi != NULL);
  • uspace/app/sbi/src/stype_t.h

    r8f80c77 r1113c9e  
    5959} stype_proc_vr_t;
    6060
     61/** Conversion class */
     62typedef enum {
     63        /** Implicit conversion */
     64        convc_implicit,
     65        /** 'as' conversion */
     66        convc_as
     67} stype_conv_class_t;
     68
    6169/** Static typer state object */
    6270typedef struct stype {
  • uspace/app/sbi/src/symbol.c

    r8f80c77 r1113c9e  
    4242static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
    4343    stree_ident_t *name, stree_csi_t *csi);
    44 static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr);
    4544static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
    4645
     
    132131    stree_csi_t *scope, stree_ident_t *name)
    133132{
    134         stree_symbol_t *base_csi_sym;
    135133        stree_csi_t *base_csi;
    136134        stree_symbol_t *symbol;
     
    142140
    143141        /* Try inherited members. */
    144         if (scope->base_csi_ref != NULL) {
    145                 base_csi_sym = symbol_xlookup_in_csi(prog,
    146                     csi_to_symbol(scope)->outer_csi, scope->base_csi_ref);
    147                 base_csi = symbol_to_csi(base_csi_sym);
    148                 assert(base_csi != NULL);
    149 
     142        base_csi = symbol_get_base_class(prog, scope);
     143        if (base_csi != NULL)
    150144                return symbol_search_csi(prog, base_csi, name);
    151         }
    152145
    153146        /* No match */
     
    212205                modm = list_node_data(node, stree_modm_t *);
    213206
     207                /* Make compiler happy. */
     208                mbr_name = NULL;
     209
    214210                switch (modm->mc) {
    215211                case mc_csi: mbr_name = modm->u.csi->name; break;
     
    217213                }
    218214
     215                /* The Clang static analyzer is just too picky. */
     216                assert(mbr_name != NULL);
     217
    219218                if (name->sid == mbr_name->sid) {
     219                        /* Make compiler happy. */
     220                        symbol = NULL;
     221
    220222                        /* Match */
    221223                        switch (modm->mc) {
     
    231233                node = list_next(&prog->module->members, node);
    232234        }
     235
     236        return NULL;
     237}
     238
     239/** Get explicit base class for a CSI.
     240 *
     241 * Note that if there is no explicit base class (class is derived implicitly
     242 * from @c object, then @c NULL is returned.
     243 *
     244 * @param prog  Program to look in
     245 * @param csi   CSI
     246 *
     247 * @return      Base class (CSI) or @c NULL if no explicit base class.
     248 */
     249stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi)
     250{
     251        list_node_t *pred_n;
     252        stree_texpr_t *pred;
     253        stree_symbol_t *pred_sym;
     254        stree_csi_t *pred_csi;
     255        stree_csi_t *outer_csi;
     256
     257        outer_csi = csi_to_symbol(csi)->outer_csi;
     258
     259        pred_n = list_first(&csi->inherit);
     260        if (pred_n == NULL)
     261                return NULL;
     262
     263        pred = list_node_data(pred_n, stree_texpr_t *);
     264        pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
     265        pred_csi = symbol_to_csi(pred_sym);
     266        assert(pred_csi != NULL); /* XXX! */
     267
     268        if (pred_csi->cc == csi_class)
     269                return pred_csi;
     270
     271        return NULL;
     272}
     273
     274/** Get type expression referencing base class for a CSI.
     275 *
     276 * Note that if there is no explicit base class (class is derived implicitly
     277 * from @c object, then @c NULL is returned.
     278 *
     279 * @param prog  Program to look in
     280 * @param csi   CSI
     281 *
     282 * @return      Type expression or @c NULL if no explicit base class.
     283 */
     284stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog,
     285    stree_csi_t *csi)
     286{
     287        list_node_t *pred_n;
     288        stree_texpr_t *pred;
     289        stree_symbol_t *pred_sym;
     290        stree_csi_t *pred_csi;
     291        stree_csi_t *outer_csi;
     292
     293        outer_csi = csi_to_symbol(csi)->outer_csi;
     294
     295        pred_n = list_first(&csi->inherit);
     296        if (pred_n == NULL)
     297                return NULL;
     298
     299        pred = list_node_data(pred_n, stree_texpr_t *);
     300        pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
     301        pred_csi = symbol_to_csi(pred_sym);
     302        assert(pred_csi != NULL); /* XXX! */
     303
     304        if (pred_csi->cc == csi_class)
     305                return pred;
    233306
    234307        return NULL;
     
    286359        stree_csimbr_t *csimbr;
    287360        stree_symbol_t *entry, *etmp;
     361        stree_symbol_t *fun_sym;
    288362
    289363        entry = NULL;
     
    305379                        break;
    306380                case csimbr_fun:
    307                         if (csimbr->u.fun->name->sid == name->sid) {
     381                        fun_sym = fun_to_symbol(csimbr->u.fun);
     382
     383                        if (csimbr->u.fun->name->sid == name->sid &&
     384                            stree_symbol_has_attr(fun_sym, sac_static)) {
    308385                                if (entry != NULL) {
    309386                                        printf("Error: Duplicate entry point.\n");
    310387                                        exit(1);
    311388                                }
    312                                 entry = fun_to_symbol(csimbr->u.fun);
     389                                entry = fun_sym;
    313390                        }
    314391                default:
     
    494571 * @return              Symbol
    495572 */
    496 static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
     573stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
    497574{
    498575        stree_symbol_t *symbol;
     
    569646        stree_ident_t *ident;
    570647
     648        /* Make compiler happy. */
     649        ident = NULL;
     650
    571651        switch (symbol->sc) {
    572652        case sc_csi: ident = symbol->u.csi->name; break;
  • uspace/app/sbi/src/symbol.h

    r8f80c77 r1113c9e  
    4040stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog,
    4141    stree_csi_t *scope, stree_ident_t *name);
     42stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi);
     43stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog,
     44    stree_csi_t *csi);
    4245stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name);
    4346
     
    5760stree_symbol_t *prop_to_symbol(stree_prop_t *prop);
    5861
     62stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr);
     63
    5964void symbol_print_fqn(stree_symbol_t *symbol);
    6065
  • uspace/app/sbi/src/tdata.c

    r8f80c77 r1113c9e  
    343343        /* Plain copy */
    344344        tnew = tdata_ebase_new();
     345        tnew->enum_d = tebase->enum_d;
     346
    345347        *res = tdata_item_new(tic_tebase);
    346         (*res)->u.tebase = tebase;
     348        (*res)->u.tebase = tnew;
    347349}
    348350
     
    362364        /* Plain copy */
    363365        tnew = tdata_enum_new();
     366        tnew->enum_d = tenum->enum_d;
     367
    364368        *res = tdata_item_new(tic_tenum);
    365         (*res)->u.tenum = tenum;
     369        (*res)->u.tenum = tnew;
    366370}
    367371
  • uspace/app/sbi/src/tdata_t.h

    r8f80c77 r1113c9e  
    5858/** Object type. */
    5959typedef struct {
    60         /** @c true if expression is a static CSI reference */
    61         bool_t static_ref;
     60        /** @c sn_static if expression is a static CSI reference */
     61        statns_t static_ref;
    6262
    6363        /** CSI definition */
Note: See TracChangeset for help on using the changeset viewer.