Changes in / [1317380:640ffe6] in mainline


Ignore:
Location:
uspace
Files:
9 added
45 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/Makefile

    r1317380 r640ffe6  
    3838        src/builtin/bi_fun.c \
    3939        src/builtin/bi_textfile.c \
     40        src/builtin/bi_string.c \
    4041        src/os/helenos.c \
    4142        src/ancr.c \
    4243        src/bigint.c \
    4344        src/builtin.c \
     45        src/cspan.c \
    4446        src/imode.c \
    4547        src/input.c \
  • uspace/app/sbi/src/ancr.c

    r1317380 r640ffe6  
    8181        while (node != NULL) {
    8282                modm = list_node_data(node, stree_modm_t *);
    83                 assert(modm->mc == mc_csi); /* XXX */
    84                 ancr_csi_dfs(prog, modm->u.csi);
     83
     84                switch (modm->mc) {
     85                case mc_csi:
     86                        ancr_csi_dfs(prog, modm->u.csi);
     87                        break;
     88                case mc_enum:
     89                        break;
     90                }
    8591
    8692                node = list_next(&prog->module->members, node);
  • uspace/app/sbi/src/builtin.c

    r1317380 r640ffe6  
    4444#include "builtin/bi_fun.h"
    4545#include "builtin/bi_textfile.h"
     46#include "builtin/bi_string.h"
    4647#include "input.h"
    4748#include "intmap.h"
     
    9091        bi_fun_declare(bi);
    9192        bi_textfile_declare(bi);
     93        bi_string_declare(bi);
    9294}
    9395
     
    105107        bi_fun_bind(bi);
    106108        bi_textfile_bind(bi);
     109        bi_string_bind(bi);
    107110}
    108111
  • uspace/app/sbi/src/builtin/bi_textfile.c

    r1317380 r640ffe6  
    7171                        "fun WriteLine(line : string), builtin;\n"
    7272                        "\n"
    73                         "prop EOF : int is\n"
     73                        "prop EOF : bool is\n"
    7474                                "get is\n"
    7575                                        "return is_eof();\n"
     
    7777                        "end\n"
    7878                        "\n"
    79                         "fun is_eof() : int, builtin;\n"
     79                        "fun is_eof() : bool, builtin;\n"
    8080                "end\n");
    8181
     
    342342        rdata_var_t *self_f_var;
    343343
    344         int eof_flag;
    345         rdata_int_t *eof_int;
     344        bool_t eof_flag;
     345        rdata_bool_t *eof_bool;
    346346        rdata_var_t *eof_var;
    347347        rdata_value_t *eof_val;
     
    362362        /* Get status of EOF flag. */
    363363
    364         eof_flag = feof(file) ? 1 : 0;
    365 
    366 #ifdef DEBUG_RUN_TRACE
    367         printf("Read EOF flag '%d'.\n", eof_flag);
     364        eof_flag = feof(file) ? b_true : b_false;
     365
     366#ifdef DEBUG_RUN_TRACE
     367        printf("Read EOF flag '%s'.\n", eof_flag ? "true" : "false");
    368368#endif
    369369        /* Construct return value. */
    370         eof_int = rdata_int_new();
    371         bigint_init(&eof_int->value, eof_flag);
    372 
    373         eof_var = rdata_var_new(vc_int);
    374         eof_var->u.int_v = eof_int;
     370        eof_bool = rdata_bool_new();
     371        eof_bool->value = eof_flag;
     372
     373        eof_var = rdata_var_new(vc_bool);
     374        eof_var->u.bool_v = eof_bool;
    375375        eof_val = rdata_value_new();
    376376        eof_val->var = eof_var;
  • uspace/app/sbi/src/imode.c

    r1317380 r640ffe6  
    116116        fun->name = stree_ident_new();
    117117        fun->name->sid = strtab_get_sid("$imode");
     118        fun->sig = stree_fun_sig_new();
    118119
    119120        stype.proc_vr->proc = proc;
  • uspace/app/sbi/src/input.c

    r1317380 r640ffe6  
    118118        }
    119119
     120        input->name = os_str_dup(fname);
    120121        input->str = NULL;
    121122        input->line_no = 0;
     
    136137        }
    137138
     139        input->name = "<user-input>";
    138140        input->str = NULL;
    139141        input->line_no = 0;
     
    154156        }
    155157
     158        input->name = "<builtin>";
    156159        input->str = str;
    157160        input->line_no = 0;
     
    226229/** Get number of the last provided line of input.
    227230 *
    228  * @param input         Input module.
     231 * @param input         Input object.
    229232 * @return              Line number of the last provided input line (counting
    230233 *                      from 1 up).
  • uspace/app/sbi/src/input_t.h

    r1317380 r640ffe6  
    3434/** Input state object */
    3535typedef struct input {
     36        /** Input name (for error output) */
     37        const char *name;
     38
    3639        /** Input file if reading from file. */
    3740        FILE *fin;
  • uspace/app/sbi/src/lex.c

    r1317380 r640ffe6  
    3535#include <stdlib.h>
    3636#include "bigint.h"
     37#include "cspan.h"
    3738#include "mytypes.h"
    3839#include "input.h"
     
    7475/** Keyword names. Used both for printing and recognition. */
    7576static struct lc_name keywords[] = {
     77        { lc_and,       "and" },
    7678        { lc_as,        "as" },
    7779        { lc_bool,      "bool" },
     80        { lc_break,     "break" },
     81        { lc_builtin,   "builtin" },
    7882        { lc_char,      "char" },
    79         { lc_builtin,   "builtin" },
    8083        { lc_class,     "class" },
    81         { lc_constructor,       "constructor" },
    8284        { lc_deleg,     "deleg" },
    8385        { lc_do,        "do" },
     86        { lc_elif,      "elif" },
    8487        { lc_else,      "else" },
    8588        { lc_end,       "end" },
     89        { lc_enum,      "enum" },
    8690        { lc_except,    "except" },
    8791        { lc_false,     "false" },
     
    96100        { lc_is,        "is" },
    97101        { lc_new,       "new" },
     102        { lc_not,       "not" },
    98103        { lc_nil,       "nil" },
     104        { lc_or,        "or" },
    99105        { lc_override,  "override" },
    100106        { lc_packed,    "packed" },
     
    233239void lem_print_coords(lem_t *lem)
    234240{
    235         printf("%d:%d", lem->line_no, lem->col_0);
     241        cspan_print(lem->cspan);
    236242}
    237243
     
    255261        lex->ibp = lex->inbuf;
    256262        lex->col_adj = 0;
     263        lex->prev_valid = b_false;
    257264        lex->current_valid = b_true;
    258265}
     
    279286 * @param lex           Lexer object.
    280287 * @return              Pointer to current lem. Owned by @a lex and only valid
    281  *                      until next call to lex_next().
     288 *                      until next call to lex_xxx().
    282289 */
    283290lem_t *lex_get_current(lex_t *lex)
     
    287294}
    288295
     296/** Get previous lem if valid.
     297 *
     298 * The returned pointer is invalidated by next call to lex_next()
     299 *
     300 * @param lex           Lexer object.
     301 * @return              Pointer to previous lem. Owned by @a lex and only valid
     302 *                      until next call to lex_xxx().
     303 */
     304lem_t *lex_peek_prev(lex_t *lex)
     305{
     306        if (lex->current_valid == b_false) {
     307                /*
     308                 * This means the head is advanced but next lem was not read.
     309                 * Thus the previous lem is still in @a current.
     310                 */
     311                return &lex->current;
     312        }
     313
     314        if (lex->prev_valid != b_true) {
     315                /* Looks like we are still at the first lem. */
     316                return NULL;
     317        }
     318
     319        /*
     320         * Current lem has been read in. Thus the previous lem was moved to
     321         * @a previous.
     322         */
     323        return &lex->prev;
     324}
     325
    289326/** Read in the current lexical element (unless already read in).
    290327 *
     
    297334        if (lex->current_valid == b_true)
    298335                return;
     336
     337        /* Copy previous lem */
     338        lex->prev = lex->current;
     339        lex->prev_valid = b_true;
    299340
    300341        do {
     
    318359static bool_t lex_read_try(lex_t *lex)
    319360{
    320         char *bp;
     361        char *bp, *lsp;
     362        int line0, col0;
    321363
    322364        lex_skip_ws(lex);
     
    328370         * separately using col_adj.
    329371         */
    330         lex->current.line_no = input_get_line_no(lex->input);
    331         lex->current.col_0 = 1 + lex->col_adj + (lex->ibp - lex->inbuf);
    332 
     372        line0 = input_get_line_no(lex->input);
     373        col0 = 1 + lex->col_adj + (lex->ibp - lex->inbuf);
     374
     375        lex->current.cspan = cspan_new(lex->input, line0, col0, line0, col0);
     376
     377        lsp = lex->ibp;
    333378        bp = lex->ibp;
    334379
     
    336381                /* End of input */
    337382                lex->current.lclass = lc_eof;
    338                 return b_true;
     383                goto finish;
    339384        }
    340385
    341386        if (is_wstart(bp[0])) {
    342387                lex_word(lex);
    343                 return b_true;
     388                goto finish;
    344389        }
    345390
    346391        if (bp[0] == '\'') {
    347392                lex_char(lex);
    348                 return b_true;
     393                goto finish;
    349394        }
    350395
    351396        if (is_digit(bp[0])) {
    352397                lex_number(lex);
    353                 return b_true;
     398                goto finish;
    354399        }
    355400
    356401        if (bp[0] == '"') {
    357402                lex_string(lex);
    358                 return b_true;
     403                goto finish;
    359404        }
    360405
    361406        if (bp[0] == '-' && bp[1] == '-') {
    362407                lex_skip_comment(lex);
     408
     409                /* Compute ending column number */
     410                lex->current.cspan->col1 = col0 + (lex->ibp - lsp) - 1;
     411
     412                /* Try again */
    363413                return b_false;
    364414        }
     
    417467
    418468        lex->ibp = bp;
     469
     470finish:
     471        /* Compute ending column number */
     472        lex->current.cspan->col1 = col0 + (lex->ibp - lsp) - 1;
    419473        return b_true;
    420474
  • uspace/app/sbi/src/lex.h

    r1317380 r640ffe6  
    3939void lex_next(lex_t *lex);
    4040lem_t *lex_get_current(lex_t *lex);
     41lem_t *lex_peek_prev(lex_t *lex);
    4142
    4243#endif
  • uspace/app/sbi/src/lex_t.h

    r1317380 r640ffe6  
    4343
    4444        /* Keywords */
     45        lc_and,
    4546        lc_as,
     47        lc_break,
    4648        lc_bool,
    4749        lc_builtin,
    4850        lc_char,
    4951        lc_class,
    50         lc_constructor,
    5152        lc_deleg,
    5253        lc_do,
     54        lc_elif,
    5355        lc_else,
    5456        lc_end,
     57        lc_enum,
    5558        lc_except,
    5659        lc_false,
     
    6669        lc_is,
    6770        lc_nil,
     71        lc_not,
     72        lc_or,
    6873        lc_override,
    6974        lc_packed,
     
    148153
    149154        /** Coordinates of this lexical element */
    150         int line_no, col_0;
     155        struct cspan *cspan;
    151156} lem_t;
    152157
     
    168173        int col_adj;
    169174
    170         /** @c b_true if we have the next lem in @c current */
     175        /** @c b_true if we have the previous lem in @c prev */
     176        bool_t prev_valid;
     177
     178        /** Previous lem (only valid if @c current_valid is true) */
     179        lem_t prev;
     180
     181        /** @c b_true if we have the current lem in @c current */
    171182        bool_t current_valid;
    172183
  • uspace/app/sbi/src/mytypes.h

    r1317380 r640ffe6  
    4949#include "bigint_t.h"
    5050#include "builtin_t.h"
     51#include "cspan_t.h"
    5152#include "input_t.h"
    5253#include "intmap_t.h"
  • uspace/app/sbi/src/os/helenos.c

    r1317380 r640ffe6  
    2929/** @file HelenOS-specific code. */
    3030
     31#include <assert.h>
    3132#include <errno.h>
    3233#include <stdio.h>
     
    7576}
    7677
     78/** Return slice (substring) of a string.
     79 *
     80 * Copies the specified range of characters from @a str and returns it
     81 * as a newly allocated string. @a start + @a length must be less than
     82 * or equal to the length of @a str.
     83 *
     84 * @param str           String
     85 * @param start         Index of first character (starting from zero).
     86 * @param length        Number of characters to copy.
     87 *
     88 * @return              Newly allocated string holding the slice.
     89 */
     90char *os_str_aslice(const char *str, size_t start, size_t length)
     91{
     92        char *slice;
     93        size_t offset;
     94        size_t i;
     95        size_t size;
     96        wchar_t c;
     97
     98        assert(start + length <= str_length(str));
     99
     100        offset = 0;
     101        for (i = 0; i < start; ++i) {
     102                c = str_decode(str, &offset, STR_NO_LIMIT);
     103                assert(c != '\0');
     104                assert(c != U_SPECIAL);
     105                (void) c;
     106        }
     107
     108        size = str_lsize(str, length);
     109        slice = str_ndup(str + offset, size);
     110
     111        return slice;
     112}
     113
    77114/** Compare two strings.
    78115 *
  • uspace/app/sbi/src/os/os.h

    r1317380 r640ffe6  
    3131
    3232char *os_str_acat(const char *a, const char *b);
     33char *os_str_aslice(const char *str, size_t start, size_t length);
    3334int os_str_cmp(const char *a, const char *b);
    3435char *os_str_dup(const char *str);
  • uspace/app/sbi/src/os/posix.c

    r1317380 r640ffe6  
    2929/** @file POSIX-specific code. */
    3030
     31#include <assert.h>
    3132#include <libgen.h>
    3233#include <stdio.h>
     
    7879}
    7980
     81/** Return slice (substring) of a string.
     82 *
     83 * Copies the specified range of characters from @a str and returns it
     84 * as a newly allocated string. @a start + @a length must be less than
     85 * or equal to the length of @a str.
     86 *
     87 * @param str           String
     88 * @param start         Index of first character (starting from zero).
     89 * @param length        Number of characters to copy.
     90 *
     91 * @return              Newly allocated string holding the slice.
     92 */
     93char *os_str_aslice(const char *str, size_t start, size_t length)
     94{
     95        char *slice;
     96
     97        assert(start + length <= strlen(str));
     98        slice = malloc(length + 1);
     99        if (slice == NULL) {
     100                printf("Memory allocation error.\n");
     101                exit(1);
     102        }
     103
     104        strncpy(slice, str + start, length);
     105        slice[length] = '\0';
     106
     107        return slice;
     108}
     109
    80110/** Compare two strings.
    81111 *
  • uspace/app/sbi/src/p_expr.c

    r1317380 r640ffe6  
    3232#include <stdlib.h>
    3333#include "bigint.h"
     34#include "cspan.h"
    3435#include "debug.h"
    3536#include "lex.h"
     
    4344
    4445static stree_expr_t *parse_assign(parse_t *parse);
     46static stree_expr_t *parse_disjunctive(parse_t *parse);
     47static stree_expr_t *parse_conjunctive(parse_t *parse);
    4548static stree_expr_t *parse_comparative(parse_t *parse);
    4649static stree_expr_t *parse_additive(parse_t *parse);
     
    9598        stree_assign_t *assign;
    9699
    97         a = parse_comparative(parse);
     100        a = parse_disjunctive(parse);
    98101
    99102        switch (lcur_lc(parse)) {
     
    109112
    110113        lskip(parse);
    111         b = parse_comparative(parse);
     114        b = parse_disjunctive(parse);
    112115
    113116        assign->dest = a;
     
    116119        tmp = stree_expr_new(ec_assign);
    117120        tmp->u.assign = assign;
     121        tmp->cspan = cspan_merge(a->cspan, b->cspan);
     122
     123        assign->expr = tmp;
     124
    118125        return tmp;
     126}
     127
     128/** Parse disjunctive expression.
     129 *
     130 * @param parse         Parser object.
     131 */
     132static stree_expr_t *parse_disjunctive(parse_t *parse)
     133{
     134        stree_expr_t *a, *b, *tmp;
     135        stree_binop_t *binop;
     136        cspan_t *cs;
     137
     138        a = parse_conjunctive(parse);
     139        cs = a->cspan;
     140
     141        while (lcur_lc(parse) == lc_or) {
     142                if (parse_is_error(parse))
     143                        break;
     144
     145                lskip(parse);
     146                b = parse_conjunctive(parse);
     147
     148                binop = stree_binop_new(bo_or);
     149                binop->arg1 = a;
     150                binop->arg2 = b;
     151
     152                tmp = stree_expr_new(ec_binop);
     153                tmp->u.binop = binop;
     154                tmp->cspan = cspan_merge(cs, b->cspan);
     155                binop->expr = tmp;
     156
     157                a = tmp;
     158                cs = tmp->cspan;
     159        }
     160
     161        return a;
     162}
     163
     164/** Parse conjunctive expression.
     165 *
     166 * @param parse         Parser object.
     167 */
     168static stree_expr_t *parse_conjunctive(parse_t *parse)
     169{
     170        stree_expr_t *a, *b, *tmp;
     171        stree_binop_t *binop;
     172        cspan_t *cs;
     173
     174        a = parse_comparative(parse);
     175        cs = a->cspan;
     176
     177        while (lcur_lc(parse) == lc_and) {
     178                if (parse_is_error(parse))
     179                        break;
     180
     181                lskip(parse);
     182                b = parse_comparative(parse);
     183
     184                binop = stree_binop_new(bo_and);
     185                binop->arg1 = a;
     186                binop->arg2 = b;
     187
     188                tmp = stree_expr_new(ec_binop);
     189                tmp->u.binop = binop;
     190                tmp->cspan = cspan_merge(cs, b->cspan);
     191                binop->expr = tmp;
     192
     193                a = tmp;
     194                cs = tmp->cspan;
     195        }
     196
     197        return a;
    119198}
    120199
     
    128207        stree_binop_t *binop;
    129208        binop_class_t bc;
     209        cspan_t *cs;
    130210
    131211        a = parse_additive(parse);
     212        cs = a->cspan;
    132213
    133214        while (lcur_lc(parse) == lc_equal || lcur_lc(parse) == lc_notequal ||
     
    157238                tmp = stree_expr_new(ec_binop);
    158239                tmp->u.binop = binop;
     240                tmp->cspan = cspan_merge(cs, b->cspan);
     241                binop->expr = tmp;
     242
    159243                a = tmp;
     244                cs = tmp->cspan;
    160245        }
    161246
     
    172257        stree_binop_t *binop;
    173258        binop_class_t bc;
     259        cspan_t *cs;
    174260
    175261        a = parse_multip(parse);
     262        cs = a->cspan;
     263
    176264        while (lcur_lc(parse) == lc_plus || lcur_lc(parse) == lc_minus) {
    177265                if (parse_is_error(parse))
     
    193281                tmp = stree_expr_new(ec_binop);
    194282                tmp->u.binop = binop;
     283                tmp->cspan = cspan_merge(cs, b->cspan);
     284                binop->expr = tmp;
     285
    195286                a = tmp;
     287                cs = tmp->cspan;
    196288        }
    197289
     
    208300        stree_binop_t *binop;
    209301        binop_class_t bc;
     302        cspan_t *cs;
    210303
    211304        a = parse_prefix(parse);
     305        cs = a->cspan;
     306
    212307        while (lcur_lc(parse) == lc_mult) {
    213308                if (parse_is_error(parse))
     
    228323                tmp = stree_expr_new(ec_binop);
    229324                tmp->u.binop = binop;
     325                tmp->cspan = cspan_merge(cs, b->cspan);
     326                binop->expr = tmp;
     327
    230328                a = tmp;
     329                cs = tmp->cspan;
    231330        }
    232331
     
    244343        stree_unop_t *unop;
    245344        unop_class_t uc;
     345        cspan_t *cs0;
    246346
    247347        switch (lcur_lc(parse)) {
    248348        case lc_plus:
    249349        case lc_minus:
     350        case lc_not:
    250351                if (parse_is_error(parse))
    251352                        return parse_recovery_expr(parse);
     
    254355                case lc_plus: uc = uo_plus; break;
    255356                case lc_minus: uc = uo_minus; break;
     357                case lc_not: uc = uo_not; break;
    256358                default: assert(b_false);
    257359                }
    258360
     361                cs0 = lcur_span(parse);
    259362                lskip(parse);
    260363                a = parse_postfix(parse);
     
    265368                tmp = stree_expr_new(ec_unop);
    266369                tmp->u.unop = unop;
     370                tmp->cspan = cspan_merge(cs0, a->cspan);
     371                unop->expr = tmp;
    267372                a = tmp;
    268373                break;
     
    287392        stree_new_t *new_op;
    288393        stree_expr_t *expr;
    289 
     394        stree_expr_t *arg;
     395        cspan_t *cs0, *cs1;
     396
     397        cs0 = lcur_span(parse);
    290398        lmatch(parse, lc_new);
    291399        texpr = parse_texpr(parse);
    292400
    293         /* Parenthesis should be present except for arrays. */
    294         if (texpr->tc != tc_tindex) {
    295                 lmatch(parse, lc_lparen);
    296                 lmatch(parse, lc_rparen);
    297         }
     401        /* XXX Take span from texpr */
     402        cs1 = lprev_span(parse);
    298403
    299404        new_op = stree_new_new();
     
    302407        expr->u.new_op = new_op;
    303408
     409        list_init(&new_op->ctor_args);
     410
     411        /* Parenthesized arguments should be present except for arrays. */
     412        if (texpr->tc != tc_tindex) {
     413                lmatch(parse, lc_lparen);
     414
     415                /* Parse constructor arguments */
     416
     417                if (lcur_lc(parse) != lc_rparen) {
     418                        while (!parse_is_error(parse)) {
     419                                arg = parse_expr(parse);
     420                                list_append(&new_op->ctor_args, arg);
     421
     422                                if (lcur_lc(parse) == lc_rparen)
     423                                        break;
     424                                lmatch(parse, lc_comma);
     425                        }
     426                }
     427
     428                lmatch(parse, lc_rparen);
     429                cs1 = cspan_merge(cs0, lprev_span(parse));
     430        }
     431
     432        expr->cspan = cspan_merge(cs0, cs1);
     433        new_op->expr = expr;
     434
    304435        return expr;
    305436}
     
    354485        stree_expr_t *expr;
    355486        stree_access_t *access;
     487        cspan_t *cs1;
    356488
    357489        lmatch(parse, lc_period);
    358490        ident = parse_ident(parse);
     491
     492        /* XXX Take span from ident */
     493        cs1 = lprev_span(parse);
    359494
    360495        access = stree_access_new();
     
    364499        expr = stree_expr_new(ec_access);
    365500        expr->u.access = access;
     501        expr->cspan = cspan_merge(a->cspan, cs1);
     502
     503        access->expr = expr;
    366504
    367505        return expr;
     
    377515        stree_call_t *call;
    378516        stree_expr_t *arg;
     517        cspan_t *cs1;
    379518
    380519        lmatch(parse, lc_lparen);
     
    398537
    399538        lmatch(parse, lc_rparen);
     539        cs1 = lprev_span(parse);
    400540
    401541        expr = stree_expr_new(ec_call);
    402542        expr->u.call = call;
     543        expr->cspan = cspan_merge(a->cspan, cs1);
     544        call->expr = expr;
    403545
    404546        return expr;
     
    414556        stree_index_t *index;
    415557        stree_expr_t *arg;
     558        cspan_t *cs1;
    416559
    417560        lmatch(parse, lc_lsbr);
     
    435578
    436579        lmatch(parse, lc_rsbr);
     580        cs1 = lprev_span(parse);
    437581
    438582        expr = stree_expr_new(ec_index);
    439583        expr->u.index = index;
     584        expr->cspan = cspan_merge(a->cspan, cs1);
     585        index->expr = expr;
    440586
    441587        return expr;
     
    451597        stree_texpr_t *texpr;
    452598        stree_as_t *as_op;
     599        cspan_t *cs1;
    453600
    454601        lmatch(parse, lc_as);
    455602        texpr = parse_texpr(parse);
     603
     604        /* XXX Take span from texpr */
     605        cs1 = lprev_span(parse);
    456606
    457607        as_op = stree_as_new();
    458608        as_op->arg = a;
    459609        as_op->dtype = texpr;
     610
    460611        expr = stree_expr_new(ec_as);
    461612        expr->u.as_op = as_op;
     613        expr->cspan = cspan_merge(a->cspan, cs1);
     614
     615        as_op->expr = expr;
    462616
    463617        return expr;
     
    471625{
    472626        stree_expr_t *expr;
     627        cspan_t *cs0, *cs1;
    473628
    474629        if (lcur_lc(parse) == lc_lparen) {
     630                cs0 = lcur_span(parse);
    475631                lskip(parse);
    476632                expr = parse_expr(parse);
    477633                lmatch(parse, lc_rparen);
     634                cs1 = lprev_span(parse);
     635
     636                expr->cspan = cspan_merge(cs0, cs1);
    478637        } else {
    479638                expr = parse_primitive(parse);
     
    482641        return expr;
    483642}
    484 
    485643
    486644/** Parse primitive expression.
     
    536694        expr = stree_expr_new(ec_nameref);
    537695        expr->u.nameref = nameref;
     696        expr->cspan = lprev_span(parse);
     697        nameref->expr = expr;
    538698
    539699        return expr;
     
    563723        expr = stree_expr_new(ec_literal);
    564724        expr->u.literal = literal;
     725        expr->cspan = lprev_span(parse);
     726        literal->expr = expr;
    565727
    566728        return expr;
     
    586748        expr = stree_expr_new(ec_literal);
    587749        expr->u.literal = literal;
     750        expr->cspan = lprev_span(parse);
     751        literal->expr = expr;
    588752
    589753        return expr;
     
    609773        expr = stree_expr_new(ec_literal);
    610774        expr->u.literal = literal;
     775        expr->cspan = lprev_span(parse);
     776        literal->expr = expr;
    611777
    612778        return expr;
     
    628794        expr = stree_expr_new(ec_literal);
    629795        expr->u.literal = literal;
     796        expr->cspan = lprev_span(parse);
     797        literal->expr = expr;
    630798
    631799        return expr;
     
    650818        expr = stree_expr_new(ec_literal);
    651819        expr->u.literal = literal;
     820        expr->cspan = lprev_span(parse);
     821        literal->expr = expr;
    652822
    653823        return expr;
     
    669839        expr = stree_expr_new(ec_self_ref);
    670840        expr->u.self_ref = self_ref;
     841        expr->cspan = lprev_span(parse);
     842        self_ref->expr = expr;
    671843
    672844        return expr;
     
    688860        expr = stree_expr_new(ec_literal);
    689861        expr->u.literal = literal;
    690 
    691         return expr;
    692 }
     862        literal->expr = expr;
     863
     864        return expr;
     865}
  • uspace/app/sbi/src/p_type.c

    r1317380 r640ffe6  
    3131#include <assert.h>
    3232#include <stdlib.h>
     33#include "cspan.h"
    3334#include "debug.h"
    3435#include "lex.h"
     
    4546static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a);
    4647static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a);
     48static stree_texpr_t *parse_tparen(parse_t *parse);
    4749static stree_texpr_t *parse_tprimitive(parse_t *parse);
    48 static stree_tliteral_t *parse_tliteral(parse_t *parse);
    49 static stree_tnameref_t *parse_tnameref(parse_t *parse);
     50static stree_texpr_t *parse_tliteral(parse_t *parse);
     51static stree_texpr_t *parse_tnameref(parse_t *parse);
    5052
    5153static stree_texpr_t *parse_recovery_texpr(parse_t *parse);
     
    9193        list_init(&tapply->targs);
    9294
     95        targ = NULL;
     96
    9397        while (lcur_lc(parse) == lc_slash) {
    9498
     
    104108        aexpr = stree_texpr_new(tc_tapply);
    105109        aexpr->u.tapply = tapply;
     110        tapply->texpr = aexpr;
     111
     112        if (targ != NULL)
     113                aexpr->cspan = cspan_merge(gtype->cspan, targ->cspan);
     114        else
     115                aexpr->cspan = gtype->cspan;
     116
    106117        return aexpr;
    107118}
     
    116127        stree_texpr_t *tmp;
    117128
    118         a = parse_tprimitive(parse);
     129        a = parse_tparen(parse);
    119130
    120131        while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lsbr) {
     
    162173        texpr = stree_texpr_new(tc_taccess);
    163174        texpr->u.taccess = taccess;
     175        taccess->texpr = texpr;
     176        texpr->cspan = cspan_merge(a->cspan, ident->cspan);
    164177
    165178        return texpr;
     
    176189        stree_tindex_t *tindex;
    177190        stree_expr_t *expr;
     191        cspan_t *cs1;
    178192
    179193        tindex = stree_tindex_new();
     
    209223
    210224        lmatch(parse, lc_rsbr);
     225        cs1 = lprev_span(parse);
    211226
    212227        texpr = stree_texpr_new(tc_tindex);
    213228        texpr->u.tindex = tindex;
    214 
    215         return texpr;
    216 }
     229        tindex->texpr = texpr;
     230        texpr->cspan = cspan_merge(a->cspan, cs1);
     231
     232        return texpr;
     233}
     234
     235/** Parse possibly partenthesized type expression.
     236 *
     237 * @param parse         Parser object.
     238 */
     239static stree_texpr_t *parse_tparen(parse_t *parse)
     240{
     241        stree_texpr_t *texpr;
     242        cspan_t *cs0, *cs1;
     243
     244        if (lcur_lc(parse) == lc_lparen) {
     245                cs0 = lcur_span(parse);
     246                lskip(parse);
     247                texpr = parse_texpr(parse);
     248                lmatch(parse, lc_rparen);
     249                cs1 = lprev_span(parse);
     250                texpr->cspan = cspan_merge(cs0, cs1);
     251        } else {
     252                texpr = parse_tprimitive(parse);
     253        }
     254
     255        return texpr;
     256}
     257
    217258
    218259/** Parse primitive type expression.
     
    226267        switch (lcur_lc(parse)) {
    227268        case lc_ident:
    228                 texpr = stree_texpr_new(tc_tnameref);
    229                 texpr->u.tnameref = parse_tnameref(parse);
     269                texpr = parse_tnameref(parse);
    230270                break;
    231271        case lc_bool:
     
    234274        case lc_string:
    235275        case lc_resource:
    236                 texpr = stree_texpr_new(tc_tliteral);
    237                 texpr->u.tliteral = parse_tliteral(parse);
     276                texpr = parse_tliteral(parse);
    238277                break;
    239278        default:
     
    250289 * @param parse         Parser object.
    251290 */
    252 static stree_tliteral_t *parse_tliteral(parse_t *parse)
     291static stree_texpr_t *parse_tliteral(parse_t *parse)
    253292{
    254293        stree_tliteral_t *tliteral;
    255294        tliteral_class_t tlc;
     295        stree_texpr_t *texpr;
    256296
    257297        switch (lcur_lc(parse)) {
     
    278318
    279319        tliteral = stree_tliteral_new(tlc);
    280         return tliteral;
     320        texpr = stree_texpr_new(tc_tliteral);
     321        texpr->u.tliteral = tliteral;
     322        tliteral->texpr = texpr;
     323        texpr->cspan = lprev_span(parse);
     324
     325        return texpr;
    281326}
    282327
     
    285330 * @param parse         Parser object.
    286331 */
    287 static stree_tnameref_t *parse_tnameref(parse_t *parse)
     332static stree_texpr_t *parse_tnameref(parse_t *parse)
    288333{
    289334        stree_tnameref_t *tnameref;
     335        stree_texpr_t *texpr;
    290336
    291337        tnameref = stree_tnameref_new();
    292338        tnameref->name = parse_ident(parse);
    293339
    294         return tnameref;
     340        texpr = stree_texpr_new(tc_tnameref);
     341        texpr->u.tnameref = tnameref;
     342        tnameref->texpr = texpr;
     343        texpr->cspan = tnameref->name->cspan;
     344
     345        return texpr;
    295346}
    296347
     
    310361        texpr = stree_texpr_new(tc_tliteral);
    311362        texpr->u.tliteral = tliteral;
    312 
    313         return texpr;
    314 }
     363        tliteral->texpr = texpr;
     364
     365        return texpr;
     366}
  • uspace/app/sbi/src/parse.c

    r1317380 r640ffe6  
    4848
    4949/*
    50  * Module members
     50 * Module and CSI members
    5151 */
    5252static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
    5353    stree_csi_t *outer_csi);
    5454static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi);
     55
     56static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi);
     57
     58static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi);
     59static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum);
    5560
    5661static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi);
     
    7681static stree_for_t *parse_for(parse_t *parse);
    7782static stree_raise_t *parse_raise(parse_t *parse);
     83static stree_break_t *parse_break(parse_t *parse);
    7884static stree_return_t *parse_return(parse_t *parse);
    7985static stree_wef_t *parse_wef(parse_t *parse);
     
    123129{
    124130        stree_csi_t *csi;
     131        stree_enum_t *enum_d;
    125132        stree_modm_t *modm;
    126133
     
    136143                        list_append(&parse->cur_mod->members, modm);
    137144                        break;
     145                case lc_enum:
     146                        enum_d = parse_enum(parse, NULL);
     147                        modm = stree_modm_new(mc_enum);
     148                        modm->u.enum_d = enum_d;
     149
     150                        list_append(&parse->cur_mod->members, modm);
     151                        break;
    138152                default:
    139153                        lunexpected_error(parse);
     
    223237 *
    224238 * @param parse         Parser object.
    225  * @param outer_csi     CSI containing this declaration or @c NULL if global.
     239 * @param outer_csi     CSI containing this declaration.
    226240 * @return              New syntax tree node. In case of parse error,
    227241 *                      @c NULL may (but need not) be returned.
     
    232246
    233247        stree_csi_t *csi;
     248        stree_ctor_t *ctor;
    234249        stree_deleg_t *deleg;
     250        stree_enum_t *enum_d;
    235251        stree_fun_t *fun;
    236252        stree_var_t *var;
     
    245261                csimbr->u.csi = csi;
    246262                break;
     263        case lc_new:
     264                ctor = parse_ctor(parse, outer_csi);
     265                csimbr = stree_csimbr_new(csimbr_ctor);
     266                csimbr->u.ctor = ctor;
     267                break;
    247268        case lc_deleg:
    248269                deleg = parse_deleg(parse, outer_csi);
     
    250271                csimbr->u.deleg = deleg;
    251272                break;
     273        case lc_enum:
     274                enum_d = parse_enum(parse, outer_csi);
     275                csimbr = stree_csimbr_new(csimbr_enum);
     276                csimbr->u.enum_d = enum_d;
     277                break;
    252278        case lc_fun:
    253279                fun = parse_fun(parse, outer_csi);
     
    273299
    274300        return csimbr;
     301}
     302
     303/** Parse constructor.
     304 *
     305 * @param parse         Parser object.
     306 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     307 * @return              New syntax tree node.
     308 */
     309static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi)
     310{
     311        stree_ctor_t *ctor;
     312        stree_symbol_t *symbol;
     313        stree_symbol_attr_t *attr;
     314
     315        ctor = stree_ctor_new();
     316        symbol = stree_symbol_new(sc_ctor);
     317
     318        symbol->u.ctor = ctor;
     319        symbol->outer_csi = outer_csi;
     320        ctor->symbol = symbol;
     321
     322        lmatch(parse, lc_new);
     323
     324        /* Fake identifier. */
     325        ctor->name = stree_ident_new();
     326        ctor->name->sid = strtab_get_sid(CTOR_IDENT);
     327        ctor->name->cspan = lprev_span(parse);
     328
     329#ifdef DEBUG_PARSE_TRACE
     330        printf("Parsing constructor of CSI '");
     331        symbol_print_fqn(csi_to_symbol(outer_csi));
     332        printf("'.\n");
     333#endif
     334        ctor->sig = parse_fun_sig(parse);
     335        if (ctor->sig->rtype != NULL) {
     336                printf("Error: Constructor of CSI '");
     337                symbol_print_fqn(csi_to_symbol(outer_csi));
     338                printf("' has a return type.\n");
     339                parse_note_error(parse);
     340        }
     341
     342        list_init(&symbol->attr);
     343
     344        /* 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        }
     350
     351        ctor->proc = stree_proc_new();
     352        ctor->proc->outer_symbol = symbol;
     353
     354        if (lcur_lc(parse) == lc_scolon) {
     355                lskip(parse);
     356
     357                /* This constructor has no body. */
     358                printf("Error: Constructor of CSI '");
     359                symbol_print_fqn(csi_to_symbol(outer_csi));
     360                printf("' has no body.\n");
     361                parse_note_error(parse);
     362
     363                ctor->proc->body = NULL;
     364        } else {
     365                lmatch(parse, lc_is);
     366                ctor->proc->body = parse_block(parse);
     367                lmatch(parse, lc_end);
     368        }
     369
     370        return ctor;
     371}
     372
     373/** Parse @c enum declaration.
     374 *
     375 * @param parse         Parser object.
     376 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     377 * @return              New syntax tree node.
     378 */
     379static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi)
     380{
     381        stree_enum_t *enum_d;
     382        stree_symbol_t *symbol;
     383        stree_embr_t *embr;
     384
     385        enum_d = stree_enum_new();
     386        symbol = stree_symbol_new(sc_enum);
     387
     388        symbol->u.enum_d = enum_d;
     389        symbol->outer_csi = outer_csi;
     390        enum_d->symbol = symbol;
     391
     392        lmatch(parse, lc_enum);
     393        enum_d->name = parse_ident(parse);
     394        list_init(&enum_d->members);
     395
     396#ifdef DEBUG_PARSE_TRACE
     397        printf("Parse enum '%s'.\n", strtab_get_str(enum_d->name->sid));
     398#endif
     399        lmatch(parse, lc_is);
     400
     401        /* Parse enum members. */
     402        while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
     403                embr = parse_embr(parse, enum_d);
     404                if (embr == NULL)
     405                        break;
     406
     407                list_append(&enum_d->members, embr);
     408        }
     409
     410        if (list_is_empty(&enum_d->members)) {
     411                printf("Error: Enum type '%s' has no members.\n",
     412                    strtab_get_str(enum_d->name->sid));
     413                parse_note_error(parse);
     414        }
     415
     416        lmatch(parse, lc_end);
     417
     418        return enum_d;
     419}
     420
     421/** Parse enum member.
     422 *
     423 * @param parse         Parser object.
     424 * @param outer_enum    Enum containing this declaration.
     425 * @return              New syntax tree node. In case of parse error,
     426 *                      @c NULL may (but need not) be returned.
     427 */
     428static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum)
     429{
     430        stree_embr_t *embr;
     431
     432        embr = stree_embr_new();
     433        embr->outer_enum = outer_enum;
     434        embr->name = parse_ident(parse);
     435
     436        lmatch(parse, lc_scolon);
     437
     438        return embr;
    275439}
    276440
     
    681845        stree_for_t *for_s;
    682846        stree_raise_t *raise_s;
     847        stree_break_t *break_s;
    683848        stree_return_t *return_s;
    684849        stree_wef_t *wef_s;
     
    714879                stat->u.raise_s = raise_s;
    715880                break;
     881        case lc_break:
     882                break_s = parse_break(parse);
     883                stat = stree_stat_new(st_break);
     884                stat->u.break_s = break_s;
     885                break;
    716886        case lc_return:
    717887                return_s = parse_return(parse);
     
    777947{
    778948        stree_if_t *if_s;
     949        stree_if_clause_t *if_c;
    779950
    780951#ifdef DEBUG_PARSE_TRACE
     
    782953#endif
    783954        if_s = stree_if_new();
    784 
     955        list_init(&if_s->if_clauses);
     956
     957        /* Parse @c if clause. */
    785958        lmatch(parse, lc_if);
    786         if_s->cond = parse_expr(parse);
     959
     960        if_c = stree_if_clause_new();
     961        if_c->cond = parse_expr(parse);
    787962        lmatch(parse, lc_then);
    788         if_s->if_block = parse_block(parse);
    789 
     963        if_c->block = parse_block(parse);
     964
     965        list_append(&if_s->if_clauses, if_c);
     966
     967        /* Parse @c elif clauses. */
     968        while (lcur_lc(parse) == lc_elif) {
     969                lskip(parse);
     970                if_c = stree_if_clause_new();
     971                if_c->cond = parse_expr(parse);
     972                lmatch(parse, lc_then);
     973                if_c->block = parse_block(parse);
     974
     975                list_append(&if_s->if_clauses, if_c);
     976        }
     977
     978        /* Parse @c else clause. */
    790979        if (lcur_lc(parse) == lc_else) {
    791980                lskip(parse);
     
    8671056}
    8681057
     1058/** Parse @c break statement.
     1059 *
     1060 * @param parse         Parser object.
     1061 * @return              New syntax tree node.
     1062 */
     1063static stree_break_t *parse_break(parse_t *parse)
     1064{
     1065        stree_break_t *break_s;
     1066
     1067#ifdef DEBUG_PARSE_TRACE
     1068        printf("Parse 'break' statement.\n");
     1069#endif
     1070        break_s = stree_break_new();
     1071
     1072        lmatch(parse, lc_break);
     1073        lmatch(parse, lc_scolon);
     1074
     1075        return break_s;
     1076}
     1077
    8691078/** Parse @c return statement.
    8701079 *
     
    8821091
    8831092        lmatch(parse, lc_return);
    884         return_s->expr = parse_expr(parse);
     1093
     1094        if (lcur_lc(parse) != lc_scolon)
     1095                return_s->expr = parse_expr(parse);
     1096
    8851097        lmatch(parse, lc_scolon);
    8861098
     
    9961208        ident = stree_ident_new();
    9971209        ident->sid = lcur(parse)->u.ident.sid;
     1210        ident->cspan = lcur_span(parse);
    9981211        lskip(parse);
    9991212
     
    10591272/** Return current lem lclass.
    10601273 *
    1061  * @param parse         Parser object.
    1062  * @return              Lclass of the current lem.
     1274 * @param parse         Parser object
     1275 * @return              Lclass of the current lem
    10631276 */
    10641277lclass_t lcur_lc(parse_t *parse)
     
    10811294}
    10821295
     1296/** Return coordinate span of current lem.
     1297 *
     1298 * @param parse         Parser object
     1299 * @return              Coordinate span of current lem or @c NULL if a
     1300 *                      parse error is active
     1301 */
     1302cspan_t *lcur_span(parse_t *parse)
     1303{
     1304        lem_t *lem;
     1305
     1306        if (parse_is_error(parse))
     1307                return NULL;
     1308
     1309        lem = lcur(parse);
     1310        return lem->cspan;
     1311}
     1312
     1313/** Return coordinate span of previous lem.
     1314 *
     1315 * @param parse         Parser object
     1316 * @return              Coordinate span of previous lem or @c NULL if
     1317 *                      parse error is active or previous lem is not
     1318 *                      available.
     1319 */
     1320cspan_t *lprev_span(parse_t *parse)
     1321{
     1322        lem_t *lem;
     1323
     1324        if (parse_is_error(parse))
     1325                return NULL;
     1326
     1327        lem = lex_peek_prev(parse->lex);
     1328        if (lem == NULL)
     1329                return NULL;
     1330
     1331        return lem->cspan;
     1332}
     1333
    10831334/** Skip to next lem.
    10841335 *
     
    11701421{
    11711422        switch (lclass) {
     1423        case lc_elif:
    11721424        case lc_else:
    11731425        case lc_end:
  • uspace/app/sbi/src/parse.h

    r1317380 r640ffe6  
    4848lem_t *lcur(parse_t *parse);
    4949lclass_t lcur_lc(parse_t *parse);
     50cspan_t *lcur_span(parse_t *parse);
     51cspan_t *lprev_span(parse_t *parse);
     52
    5053void lskip(parse_t *parse);
    5154void lcheck(parse_t *parse, lclass_t lc);
  • uspace/app/sbi/src/rdata.c

    r1317380 r640ffe6  
    5252#include "stree.h"
    5353#include "symbol.h"
     54#include "strtab.h"
    5455
    5556#include "rdata.h"
     
    6162static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest);
    6263static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest);
     64static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest);
    6365static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
    6466static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
    6567static void rdata_resource_copy(rdata_resource_t *src,
    6668    rdata_resource_t **dest);
     69static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest);
    6770
    6871static int rdata_array_get_dim(rdata_array_t *array);
     
    247250
    248251        return deleg;
     252}
     253
     254/** Allocate new enum value.
     255 *
     256 * @return      New enum value.
     257 */
     258rdata_enum_t *rdata_enum_new(void)
     259{
     260        rdata_enum_t *enum_v;
     261
     262        enum_v = calloc(1, sizeof(rdata_enum_t));
     263        if (enum_v == NULL) {
     264                printf("Memory allocation failed.\n");
     265                exit(1);
     266        }
     267
     268        return enum_v;
    249269}
    250270
     
    373393
    374394        return resource_v;
     395}
     396
     397/** Allocate new symbol reference.
     398 *
     399 * @return      New symbol reference.
     400 */
     401rdata_symbol_t *rdata_symbol_new(void)
     402{
     403        rdata_symbol_t *symbol_v;
     404
     405        symbol_v = calloc(1, sizeof(rdata_symbol_t));
     406        if (symbol_v == NULL) {
     407                printf("Memory allocation failed.\n");
     408                exit(1);
     409        }
     410
     411        return symbol_v;
    375412}
    376413
     
    453490                rdata_deleg_copy(src->u.deleg_v, &nvar->u.deleg_v);
    454491                break;
     492        case vc_enum:
     493                rdata_enum_copy(src->u.enum_v, &nvar->u.enum_v);
     494                break;
    455495        case vc_array:
    456496                rdata_array_copy(src->u.array_v, &nvar->u.array_v);
     
    461501        case vc_resource:
    462502                rdata_resource_copy(src->u.resource_v, &nvar->u.resource_v);
     503                break;
     504        case vc_symbol:
     505                rdata_symbol_copy(src->u.symbol_v, &nvar->u.symbol_v);
    463506                break;
    464507        }
     
    534577}
    535578
     579/** Copy enum value.
     580 *
     581 * @param src           Source enum value.
     582 * @param dest          Place to store pointer to new enum value.
     583 */
     584static void rdata_enum_copy(rdata_enum_t *src, rdata_enum_t **dest)
     585{
     586        *dest = rdata_enum_new();
     587        (*dest)->value = src->value;
     588}
     589
    536590/** Copy array.
    537591 *
     
    567621        *dest = rdata_resource_new();
    568622        (*dest)->data = src->data;
     623}
     624
     625/** Copy symbol.
     626 *
     627 * @param src           Source symbol.
     628 * @param dest          Place to store pointer to new symbol.
     629 */
     630static void rdata_symbol_copy(rdata_symbol_t *src, rdata_symbol_t **dest)
     631{
     632        *dest = rdata_symbol_new();
     633        (*dest)->sym = src->sym;
    569634}
    570635
     
    621686        case vc_ref: var->u.ref_v = nvar->u.ref_v; break;
    622687        case vc_deleg: var->u.deleg_v = nvar->u.deleg_v; break;
     688        case vc_enum: var->u.enum_v = nvar->u.enum_v; break;
    623689        case vc_array: var->u.array_v = nvar->u.array_v; break;
    624690        case vc_object: var->u.object_v = nvar->u.object_v; break;
    625691        case vc_resource: var->u.resource_v = nvar->u.resource_v; break;
     692        case vc_symbol: var->u.symbol_v = nvar->u.symbol_v; break;
    626693        }
    627694
     
    732799                printf(")");
    733800                break;
     801        case vc_enum:
     802                symbol_print_fqn(
     803                    enum_to_symbol(var->u.enum_v->value->outer_enum));
     804                printf(".%s",
     805                    strtab_get_str(var->u.enum_v->value->name->sid));
     806                break;
    734807        case vc_array:
    735808                printf("array");
     
    741814                printf("resource(%p)", var->u.resource_v->data);
    742815                break;
    743         }
    744 }
     816        case vc_symbol:
     817                printf("symbol(");
     818                if (var->u.symbol_v->sym != NULL) {
     819                        symbol_print_fqn(var->u.symbol_v->sym);
     820                } else {
     821                        printf("nil");
     822                }
     823                printf(")");
     824                break;
     825        }
     826}
  • uspace/app/sbi/src/rdata.h

    r1317380 r640ffe6  
    4343rdata_ref_t *rdata_ref_new(void);
    4444rdata_deleg_t *rdata_deleg_new(void);
     45rdata_enum_t *rdata_enum_new(void);
    4546rdata_array_t *rdata_array_new(int rank);
    4647rdata_object_t *rdata_object_new(void);
     
    5051rdata_string_t *rdata_string_new(void);
    5152rdata_resource_t *rdata_resource_new(void);
     53rdata_symbol_t *rdata_symbol_new(void);
    5254
    5355void rdata_array_alloc_element(rdata_array_t *array);
  • uspace/app/sbi/src/rdata_t.h

    r1317380 r640ffe6  
    8282} rdata_deleg_t;
    8383
     84/** Enumerated type value. */
     85typedef struct {
     86        /** Enum member declaration */
     87        struct stree_embr *value;
     88} rdata_enum_t;
     89
    8490/** Array variable */
    8591typedef struct {
     
    116122} rdata_resource_t;
    117123
     124/** Symbol reference variable
     125 *
     126 * A symbol reference points to a program symbol.
     127 */
     128typedef struct {
     129        /** Program symbol. */
     130        struct stree_symbol *sym;
     131} rdata_symbol_t;
     132
    118133typedef enum var_class {
    119134        /** Boolean */
     
    135150        vc_deleg,
    136151
     152        /** Enumerated type value */
     153        vc_enum,
     154
    137155        /** Array */
    138156        vc_array,
     
    142160
    143161        /** Interpreter builtin resource */
    144         vc_resource
     162        vc_resource,
     163
     164        /** Symbol reference */
     165        vc_symbol
    145166} var_class_t;
    146167
     
    161182                rdata_ref_t *ref_v;
    162183                rdata_deleg_t *deleg_v;
     184                rdata_enum_t *enum_v;
    163185                rdata_array_t *array_v;
    164186                rdata_object_t *object_v;
    165187                rdata_resource_t *resource_v;
     188                rdata_symbol_t *symbol_v;
    166189        } u;
    167190} rdata_var_t;
  • uspace/app/sbi/src/run.c

    r1317380 r640ffe6  
    3434#include "bigint.h"
    3535#include "builtin.h"
     36#include "cspan.h"
    3637#include "debug.h"
    3738#include "intmap.h"
     
    5455static void run_while(run_t *run, stree_while_t *while_s);
    5556static void run_raise(run_t *run, stree_raise_t *raise_s);
     57static void run_break(run_t *run, stree_break_t *break_s);
    5658static void run_return(run_t *run, stree_return_t *return_s);
    5759static void run_wef(run_t *run, stree_wef_t *wef_s);
     
    7173static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar);
    7274static void run_var_new_deleg(run_t *run, rdata_var_t **rvar);
    73 
     75static void run_var_new_enum(run_t *run, tdata_enum_t *tenum,
     76    rdata_var_t **rvar);
    7477
    7578/** Initialize runner instance.
     
    177180        switch (run->thread_ar->bo_mode) {
    178181        case bm_stat:
    179                 printf("Error: Misplaced 'break' statement.\n");
    180                 exit(1);
     182                /* Break bailout was not caught. */
     183                assert(b_false);
    181184        case bm_proc:
    182185                run->thread_ar->bo_mode = bm_none;
     
    283286                run_raise(run, stat->u.raise_s);
    284287                break;
     288        case st_break:
     289                run_break(run, stat->u.break_s);
     290                break;
    285291        case st_return:
    286292                run_return(run, stat->u.return_s);
     
    292298                printf("Ignoring unimplemented statement type %d.\n", stat->sc);
    293299                break;
    294         default:
    295                 assert(b_false);
    296300        }
    297301}
     
    364368{
    365369        rdata_item_t *rcond;
     370        list_node_t *ifc_node;
     371        stree_if_clause_t *ifc;
     372        bool_t clause_fired;
    366373
    367374#ifdef DEBUG_RUN_TRACE
    368375        printf("Executing if statement.\n");
    369376#endif
    370         run_expr(run, if_s->cond, &rcond);
    371         if (run_is_bo(run))
    372                 return;
    373 
    374         if (run_item_boolean_value(run, rcond) == b_true) {
    375 #ifdef DEBUG_RUN_TRACE
    376                 printf("Taking true path.\n");
    377 #endif
    378                 run_block(run, if_s->if_block);
    379         } else {
    380 #ifdef DEBUG_RUN_TRACE
    381                 printf("Taking false path.\n");
    382 #endif
    383                 if (if_s->else_block != NULL)
    384                         run_block(run, if_s->else_block);
     377        clause_fired = b_false;
     378        ifc_node = list_first(&if_s->if_clauses);
     379
     380        /* Walk through all if/elif clauses and see if they fire. */
     381
     382        while (ifc_node != NULL) {
     383                /* Get if/elif clause */
     384                ifc = list_node_data(ifc_node, stree_if_clause_t *);
     385
     386                run_expr(run, ifc->cond, &rcond);
     387                if (run_is_bo(run))
     388                        return;
     389
     390                if (run_item_boolean_value(run, rcond) == b_true) {
     391#ifdef DEBUG_RUN_TRACE
     392                        printf("Taking non-default path.\n");
     393#endif
     394                        run_block(run, ifc->block);
     395                        clause_fired = b_true;
     396                        break;
     397                }
     398
     399                ifc_node = list_next(&if_s->if_clauses, ifc_node);
     400        }
     401
     402        /* If no if/elif clause fired, invoke the else clause. */
     403        if (clause_fired == b_false && if_s->else_block != NULL) {
     404#ifdef DEBUG_RUN_TRACE
     405                printf("Taking default path.\n");
     406#endif
     407                run_block(run, if_s->else_block);
    385408        }
    386409
     
    410433                run_expr(run, while_s->cond, &rcond);
    411434                if (run_is_bo(run))
    412                         return;
    413 
    414                 if (run->thread_ar->bo_mode != bm_none)
    415435                        break;
     436        }
     437
     438        if (run->thread_ar->bo_mode == bm_stat) {
     439                /* Bailout due to break statement */
     440                run->thread_ar->bo_mode = bm_none;
    416441        }
    417442
     
    440465        run_cvt_value_item(run, rexpr, &rexpr_vi);
    441466
     467        /* Store expression cspan in thread AR. */
     468        run->thread_ar->exc_cspan = raise_s->expr->cspan;
     469
    442470        /* Store expression result in thread AR. */
    443471        run->thread_ar->exc_payload = rexpr_vi->u.value;
     
    447475}
    448476
     477/** Run @c break statement.
     478 *
     479 * Forces control to return from the active breakable statement by setting
     480 * bailout mode to @c bm_stat.
     481 *
     482 * @param run           Runner object
     483 * @param break_s       Break statement to run
     484 */
     485static void run_break(run_t *run, stree_break_t *break_s)
     486{
     487#ifdef DEBUG_RUN_TRACE
     488        printf("Executing 'break' statement.\n");
     489#endif
     490        (void) break_s;
     491
     492        /* Force control to ascend and leave the procedure. */
     493        if (run->thread_ar->bo_mode == bm_none)
     494                run->thread_ar->bo_mode = bm_stat;
     495}
     496
    449497/** Run @c return statement.
    450498 *
     
    453501 *
    454502 * @param run           Runner object
    455  * @param raise_s       Return statement to run
     503 * @param return_s      Return statement to run
    456504 */
    457505static void run_return(run_t *run, stree_return_t *return_s)
     
    464512        printf("Executing return statement.\n");
    465513#endif
    466         run_expr(run, return_s->expr, &rexpr);
    467         if (run_is_bo(run))
    468                 return;
    469 
    470         run_cvt_value_item(run, rexpr, &rexpr_vi);
    471 
    472         /* Store expression result in procedure AR. */
    473         proc_ar = run_get_current_proc_ar(run);
    474         proc_ar->retval = rexpr_vi;
     514        if (return_s->expr != NULL) {
     515                run_expr(run, return_s->expr, &rexpr);
     516                if (run_is_bo(run))
     517                        return;
     518
     519                run_cvt_value_item(run, rexpr, &rexpr_vi);
     520
     521                /* Store expression result in procedure AR. */
     522                proc_ar = run_get_current_proc_ar(run);
     523                proc_ar->retval = rexpr_vi;
     524        }
    475525
    476526        /* Force control to ascend and leave the procedure. */
     
    632682                exc_csi = run_exc_payload_get_csi(run);
    633683
     684                if (run->thread_ar->exc_cspan != NULL) {
     685                        cspan_print(run->thread_ar->exc_cspan);
     686                        putchar(' ');
     687                }
     688
    634689                printf("Error: Unhandled exception '");
    635690                symbol_print_fqn(csi_to_symbol(exc_csi));
     
    749804        rdata_char_t *char_v;
    750805        rdata_deleg_t *deleg_v;
     806        rdata_enum_t *enum_v;
    751807        rdata_int_t *int_v;
    752808        rdata_string_t *string_v;
     
    780836                deleg_v->obj = item->u.value->var->u.deleg_v->obj;
    781837                deleg_v->sym = item->u.value->var->u.deleg_v->sym;
     838                break;
     839        case vc_enum:
     840                *var = rdata_var_new(vc_enum);
     841                enum_v = rdata_enum_new();
     842
     843                (*var)->u.enum_v = enum_v;
     844                enum_v->value = item->u.value->var->u.enum_v->value;
    782845                break;
    783846        case vc_int:
     
    854917void run_proc_ar_set_args(run_t *run, run_proc_ar_t *proc_ar, list_t *arg_vals)
    855918{
     919        stree_ctor_t *ctor;
    856920        stree_fun_t *fun;
    857921        stree_prop_t *prop;
     
    878942        outer_symbol = proc_ar->proc->outer_symbol;
    879943
     944        /* Make compiler happy. */
     945        args = NULL;
     946        varg = NULL;
     947
    880948        /*
    881949         * The procedure being activated should belong to a member function or
     
    883951         */
    884952        switch (outer_symbol->sc) {
     953        case sc_ctor:
     954                ctor = symbol_to_ctor(outer_symbol);
     955                args = &ctor->sig->args;
     956                varg = ctor->sig->varg;
     957                break;
    885958        case sc_fun:
    886959                fun = symbol_to_fun(outer_symbol);
     
    893966                varg = prop->varg;
    894967                break;
    895         default:
     968        case sc_csi:
     969        case sc_deleg:
     970        case sc_enum:
     971        case sc_var:
    896972                assert(b_false);
    897973        }
     
    13771453 * @param run           Runner object
    13781454 * @param ref           Reference
     1455 * @param cspan         Cspan to put into exception if reference is nil
     1456 *                      or @c NULL if no cspan is provided.
    13791457 * @param rtitem        Place to store pointer to the resulting address.
    13801458 */
    1381 void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem)
     1459void run_dereference(run_t *run, rdata_item_t *ref, cspan_t *cspan,
     1460    rdata_item_t **ritem)
    13821461{
    13831462        rdata_item_t *ref_val;
     
    14041483#endif
    14051484                /* Raise Error.NilReference */
    1406                 run_raise_exc(run, run->program->builtin->error_nilreference);
     1485                run_raise_exc(run, run->program->builtin->error_nilreference,
     1486                    cspan);
    14071487                *ritem = run_recovery_item(run);
    14081488                return;
     
    14221502 * @param run           Runner object
    14231503 * @param csi           Exception class
    1424  */
    1425 void run_raise_exc(run_t *run, stree_csi_t *csi)
     1504 * @param cspan         Cspan of code that caused exception (for debugging)
     1505 */
     1506void run_raise_exc(run_t *run, stree_csi_t *csi, cspan_t *cspan)
    14261507{
    14271508        rdata_item_t *exc_vi;
     1509
     1510        /* Store exception cspan in thread AR. */
     1511        run->thread_ar->exc_cspan = cspan;
    14281512
    14291513        /* Create exception object. */
     
    14721556                break;
    14731557        case tic_tdeleg:
     1558                run_var_new_deleg(run, rvar);
     1559                break;
     1560        case tic_tebase:
     1561                /*
     1562                 * One cannot declare variable of ebase type. It is just
     1563                 * type of expressions referring to enum types.
     1564                 */
     1565                assert(b_false);
     1566        case tic_tenum:
     1567                run_var_new_enum(run, ti->u.tenum, rvar);
     1568                break;
    14741569        case tic_tfun:
    14751570                run_var_new_deleg(run, rvar);
     
    15781673}
    15791674
     1675/** Construct a new variable containing default value of an enum type.
     1676 *
     1677 * @param run           Runner object
     1678 * @param rvar          Place to store pointer to new variable
     1679 */
     1680static void run_var_new_enum(run_t *run, tdata_enum_t *tenum,
     1681    rdata_var_t **rvar)
     1682{
     1683        rdata_var_t *var;
     1684        list_node_t *embr_n;
     1685        stree_embr_t *embr;
     1686
     1687        (void) run;
     1688
     1689        /* Get first member of enum which will serve as default value. */
     1690        embr_n = list_first(&tenum->enum_d->members);
     1691        assert(embr_n != NULL);
     1692
     1693        embr = list_node_data(embr_n, stree_embr_t *);
     1694
     1695        /* Return null reference. */
     1696        var = rdata_var_new(vc_enum);
     1697        var->u.enum_v = rdata_enum_new();
     1698        var->u.enum_v->value = embr;
     1699
     1700        *rvar = var;
     1701}
     1702
    15801703/** Construct a new thread activation record.
    15811704 *
  • uspace/app/sbi/src/run.h

    r1317380 r640ffe6  
    6363    rdata_value_t *value);
    6464void run_reference(run_t *run, rdata_var_t *var, rdata_item_t **res);
    65 void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem);
     65void run_dereference(run_t *run, rdata_item_t *ref, cspan_t *cspan,
     66    rdata_item_t **ritem);
    6667
    67 void run_raise_exc(run_t *run, stree_csi_t *csi);
     68void run_raise_exc(run_t *run, stree_csi_t *csi, cspan_t *cspan);
    6869bool_t run_is_bo(run_t *run);
    6970
  • uspace/app/sbi/src/run_expr.c

    r1317380 r640ffe6  
    7878static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    7979    rdata_value_t *v2, rdata_item_t **res);
     80static void run_binop_enum(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     81    rdata_value_t *v2, rdata_item_t **res);
    8082
    8183static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
     84static void run_unop_bool(run_t *run, stree_unop_t *unop, rdata_value_t *val,
     85    rdata_item_t **res);
    8286static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
    8387    rdata_item_t **res);
     
    8892static void run_new_object(run_t *run, stree_new_t *new_op,
    8993    tdata_item_t *titem, rdata_item_t **res);
     94
     95static void run_object_ctor(run_t *run, rdata_var_t *obj, list_t *arg_vals);
    9096
    9197static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res);
     
    98104static void run_access_object(run_t *run, stree_access_t *access,
    99105    rdata_item_t *arg, rdata_item_t **res);
     106static void run_access_symbol(run_t *run, stree_access_t *access,
     107    rdata_item_t *arg, rdata_item_t **res);
    100108
    101109static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res);
     110static void run_call_args(run_t *run, list_t *args, list_t *arg_vals);
     111
    102112static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res);
    103113static void run_index_array(run_t *run, stree_index_t *index,
     
    189199        rdata_var_t *var;
    190200        rdata_deleg_t *deleg_v;
     201        rdata_symbol_t *symbol_v;
    191202
    192203        run_proc_ar_t *proc_ar;
     
    246257        case sc_csi:
    247258#ifdef DEBUG_RUN_TRACE
    248                 printf("Referencing class.\n");
     259                printf("Referencing CSI.\n");
    249260#endif
    250261                item = rdata_item_new(ic_value);
     
    260271                deleg_v->sym = sym;
    261272                *res = item;
     273                break;
     274        case sc_ctor:
     275                /* It is not possible to reference a constructor explicitly. */
     276                assert(b_false);
     277        case sc_enum:
     278#ifdef DEBUG_RUN_TRACE
     279                printf("Referencing enum.\n");
     280#endif
     281                item = rdata_item_new(ic_value);
     282                value = rdata_value_new();
     283                var = rdata_var_new(vc_symbol);
     284                symbol_v = rdata_symbol_new();
     285
     286                item->u.value = value;
     287                value->var = var;
     288                var->u.symbol_v = symbol_v;
     289
     290                symbol_v->sym = sym;
     291                *res = item;
     292                break;
     293        case sc_deleg:
     294                /* XXX TODO */
     295                printf("Unimplemented: Delegate name reference.\n");
     296                abort();
    262297                break;
    263298        case sc_fun:
     
    329364                *res = item;
    330365                break;
    331         default:
    332                 printf("Referencing symbol class %d unimplemented.\n", sym->sc);
    333                 *res = NULL;
     366        case sc_prop:
     367                /* XXX TODO */
     368                printf("Unimplemented: Property name reference.\n");
     369                abort();
    334370                break;
    335371        }
     
    571607        }
    572608
    573         switch (binop->bc) {
    574         case bo_plus:
    575         case bo_minus:
    576         case bo_mult:
    577         case bo_equal:
    578         case bo_notequal:
    579         case bo_lt:
    580         case bo_gt:
    581         case bo_lt_equal:
    582         case bo_gt_equal:
    583                 /* These are implemented so far. */
    584                 break;
    585         default:
    586                 printf("Unimplemented: Binary operation type %d.\n",
    587                     binop->bc);
    588                 exit(1);
    589         }
    590 
    591609#ifdef DEBUG_RUN_TRACE
    592610        printf("Check binop argument results.\n");
     
    621639                run_binop_ref(run, binop, v1, v2, res);
    622640                break;
     641        case vc_enum:
     642                run_binop_enum(run, binop, v1, v2, res);
     643                break;
    623644        case vc_deleg:
    624645        case vc_array:
    625646        case vc_object:
    626647        case vc_resource:
     648        case vc_symbol:
    627649                assert(b_false);
    628650        }
     
    685707                bool_v->value = (b1 == b_true) || (b2 == b_false);
    686708                break;
     709
     710        case bo_and:
     711                bool_v->value = (b1 == b_true) && (b2 == b_true);
     712                break;
     713        case bo_or:
     714                bool_v->value = (b1 == b_true) || (b2 == b_true);
     715                break;
    687716        }
    688717
     
    753782                bool_v->value = !nf;
    754783                break;
    755         default:
     784
     785        case bo_and:
     786        case bo_or:
    756787                assert(b_false);
    757788        }
     
    832863
    833864        switch (binop->bc) {
     865        case bo_plus:
     866        case bo_minus:
     867        case bo_mult:
     868                assert(b_false);
     869
    834870        case bo_equal:
    835871                bool_v->value = zf;
     
    850886                bool_v->value = !nf;
    851887                break;
    852         default:
     888        case bo_and:
     889        case bo_or:
    853890                assert(b_false);
    854891        }
     
    872909        rdata_var_t *var;
    873910        rdata_string_t *string_v;
     911        rdata_bool_t *bool_v;
     912        bool_t done;
     913        bool_t zf;
    874914
    875915        const char *s1, *s2;
     
    879919        item = rdata_item_new(ic_value);
    880920        value = rdata_value_new();
    881         var = rdata_var_new(vc_string);
    882         string_v = rdata_string_new();
    883921
    884922        item->u.value = value;
    885         value->var = var;
    886         var->u.string_v = string_v;
    887923
    888924        s1 = v1->var->u.string_v->value;
    889925        s2 = v2->var->u.string_v->value;
     926
     927        done = b_true;
    890928
    891929        switch (binop->bc) {
    892930        case bo_plus:
    893931                /* Concatenate strings. */
     932                string_v = rdata_string_new();
    894933                string_v->value = os_str_acat(s1, s2);
     934                break;
     935        default:
     936                done = b_false;
     937                break;
     938        }
     939
     940        if (done) {
     941                var = rdata_var_new(vc_string);
     942                var->u.string_v = string_v;
     943                value->var = var;
     944                *res = item;
     945                return;
     946        }
     947
     948        var = rdata_var_new(vc_bool);
     949        bool_v = rdata_bool_new();
     950        var->u.bool_v = bool_v;
     951        value->var = var;
     952
     953        /* Relational operation. */
     954
     955        zf = os_str_cmp(s1, s2) == 0;
     956
     957        switch (binop->bc) {
     958        case bo_equal:
     959                bool_v->value = zf;
     960                break;
     961        case bo_notequal:
     962                bool_v->value = !zf;
    895963                break;
    896964        default:
     
    9511019}
    9521020
     1021/** Evaluate binary operation on enum arguments.
     1022 *
     1023 * @param run           Runner object
     1024 * @param binop         Binary operation
     1025 * @param v1            Value of first argument
     1026 * @param v2            Value of second argument
     1027 * @param res           Place to store result
     1028 */
     1029static void run_binop_enum(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     1030    rdata_value_t *v2, rdata_item_t **res)
     1031{
     1032        rdata_item_t *item;
     1033        rdata_value_t *value;
     1034        rdata_var_t *var;
     1035        rdata_bool_t *bool_v;
     1036
     1037        rdata_var_t *ref1, *ref2;
     1038
     1039        (void) run;
     1040
     1041        item = rdata_item_new(ic_value);
     1042        value = rdata_value_new();
     1043        var = rdata_var_new(vc_bool);
     1044        bool_v = rdata_bool_new();
     1045
     1046        item->u.value = value;
     1047        value->var = var;
     1048        var->u.bool_v = bool_v;
     1049
     1050        ref1 = v1->var->u.ref_v->vref;
     1051        ref2 = v2->var->u.ref_v->vref;
     1052
     1053        switch (binop->bc) {
     1054        case bo_equal:
     1055                bool_v->value = (ref1 == ref2);
     1056                break;
     1057        case bo_notequal:
     1058                bool_v->value = (ref1 != ref2);
     1059                break;
     1060        default:
     1061                /* Should have been caught by static typing. */
     1062                assert(b_false);
     1063        }
     1064
     1065        *res = item;
     1066}
    9531067
    9541068/** Evaluate unary operation.
     
    9811095
    9821096        switch (val->var->vc) {
     1097        case vc_bool:
     1098                run_unop_bool(run, unop, val, res);
     1099                break;
    9831100        case vc_int:
    9841101                run_unop_int(run, unop, val, res);
     
    9931110}
    9941111
     1112/** Evaluate unary operation on bool argument.
     1113 *
     1114 * @param run           Runner object
     1115 * @param unop          Unary operation
     1116 * @param val           Value of argument
     1117 * @param res           Place to store result
     1118 */
     1119static void run_unop_bool(run_t *run, stree_unop_t *unop, rdata_value_t *val,
     1120    rdata_item_t **res)
     1121{
     1122        rdata_item_t *item;
     1123        rdata_value_t *value;
     1124        rdata_var_t *var;
     1125        rdata_bool_t *bool_v;
     1126
     1127        (void) run;
     1128
     1129        item = rdata_item_new(ic_value);
     1130        value = rdata_value_new();
     1131        var = rdata_var_new(vc_bool);
     1132        bool_v = rdata_bool_new();
     1133
     1134        item->u.value = value;
     1135        value->var = var;
     1136        var->u.bool_v = bool_v;
     1137
     1138        switch (unop->uc) {
     1139        case uo_plus:
     1140        case uo_minus:
     1141                assert(b_false);
     1142
     1143        case uo_not:
     1144                bool_v->value = !val->var->u.bool_v->value;
     1145                break;
     1146        }
     1147
     1148        *res = item;
     1149}
     1150
    9951151/** Evaluate unary operation on int argument.
    9961152 *
     
    10271183                    &int_v->value);
    10281184                break;
     1185        case uo_not:
     1186                assert(b_false);
    10291187        }
    10301188
    10311189        *res = item;
    10321190}
    1033 
    10341191
    10351192/** Evaluate @c new operation.
     
    11861343{
    11871344        stree_csi_t *csi;
     1345        rdata_item_t *obj_i;
     1346        list_t arg_vals;
    11881347
    11891348#ifdef DEBUG_RUN_TRACE
    11901349        printf("Create new object.\n");
    11911350#endif
    1192         (void) new_op;
    1193 
    11941351        /* Lookup object CSI. */
    11951352        assert(titem->tic == tic_tobject);
    11961353        csi = titem->u.tobject->csi;
    11971354
     1355        /* Evaluate constructor arguments. */
     1356        run_call_args(run, &new_op->ctor_args, &arg_vals);
     1357        if (run_is_bo(run)) {
     1358                *res = NULL;
     1359                return;
     1360        }
     1361
    11981362        /* Create CSI instance. */
    11991363        run_new_csi_inst(run, csi, res);
     1364
     1365        /* Run the constructor. */
     1366        run_dereference(run, *res, NULL, &obj_i);
     1367        assert(obj_i->ic == ic_address);
     1368        assert(obj_i->u.address->ac == ac_var);
     1369        run_object_ctor(run, obj_i->u.address->u.var_a->vref, &arg_vals);
    12001370}
    12011371
     
    12561426                run_access_object(run, access, arg, res);
    12571427                break;
    1258         default:
     1428        case vc_symbol:
     1429                run_access_symbol(run, access, arg, res);
     1430                break;
     1431
     1432        case vc_bool:
     1433        case vc_char:
     1434        case vc_enum:
     1435        case vc_int:
     1436        case vc_string:
     1437        case vc_array:
     1438        case vc_resource:
    12591439                printf("Unimplemented: Using access operator ('.') "
    12601440                    "with unsupported data type (value/%d).\n", vc);
     
    12761456
    12771457        /* Implicitly dereference. */
    1278         run_dereference(run, arg, &darg);
     1458        run_dereference(run, arg, access->arg->cspan, &darg);
    12791459
    12801460        if (run->thread_ar->bo_mode != bm_none) {
     
    13961576                printf("Error: Accessing object member which is a delegate.\n");
    13971577                exit(1);
     1578        case sc_enum:
     1579                printf("Error: Accessing object member which is an enum.\n");
     1580                exit(1);
     1581        case sc_ctor:
     1582                /* It is not possible to reference a constructor explicitly. */
     1583                assert(b_false);
    13981584        case sc_fun:
    13991585                /* Construct anonymous delegate. */
     
    14421628}
    14431629
     1630/** Evaluate symbol member acccess.
     1631 *
     1632 * @param run           Runner object
     1633 * @param access        Access operation
     1634 * @param arg           Evaluated base expression
     1635 * @param res           Place to store result
     1636 */
     1637static void run_access_symbol(run_t *run, stree_access_t *access,
     1638    rdata_item_t *arg, rdata_item_t **res)
     1639{
     1640        rdata_item_t *arg_vi;
     1641        rdata_value_t *arg_val;
     1642        rdata_symbol_t *symbol_v;
     1643        stree_embr_t *embr;
     1644
     1645        rdata_item_t *ritem;
     1646        rdata_value_t *rvalue;
     1647        rdata_var_t *rvar;
     1648        rdata_enum_t *enum_v;
     1649
     1650#ifdef DEBUG_RUN_TRACE
     1651        printf("Run symbol access operation.\n");
     1652#endif
     1653        run_cvt_value_item(run, arg, &arg_vi);
     1654        arg_val = arg_vi->u.value;
     1655        assert(arg_val->var->vc == vc_symbol);
     1656
     1657        symbol_v = arg_val->var->u.symbol_v;
     1658
     1659        /* XXX Port CSI symbol reference to using vc_symbol */
     1660        assert(symbol_v->sym->sc == sc_enum);
     1661
     1662        embr = stree_enum_find_mbr(symbol_v->sym->u.enum_d,
     1663            access->member_name);
     1664
     1665        /* Member existence should be ensured by static type checking. */
     1666        assert(embr != NULL);
     1667
     1668#ifdef DEBUG_RUN_TRACE
     1669        printf("Found enum member '%s'.\n",
     1670            strtab_get_str(access->member_name->sid));
     1671#endif
     1672        ritem = rdata_item_new(ic_value);
     1673        rvalue = rdata_value_new();
     1674        rvar = rdata_var_new(vc_enum);
     1675        enum_v = rdata_enum_new();
     1676
     1677        ritem->u.value = rvalue;
     1678        rvalue->var = rvar;
     1679        rvar->u.enum_v = enum_v;
     1680        enum_v->value = embr;
     1681
     1682        *res = ritem;
     1683}
     1684
    14441685/** Call a function.
    14451686 *
     
    14551696        rdata_deleg_t *deleg_v;
    14561697        list_t arg_vals;
    1457         list_node_t *node;
    1458         stree_expr_t *arg;
    1459         rdata_item_t *rarg_i, *rarg_vi;
    14601698
    14611699        stree_fun_t *fun;
     
    14991737#endif
    15001738        /* Evaluate function arguments. */
     1739        run_call_args(run, &call->args, &arg_vals);
     1740        if (run_is_bo(run)) {
     1741                *res = NULL;
     1742                return;
     1743        }
     1744
     1745        fun = symbol_to_fun(deleg_v->sym);
     1746        assert(fun != NULL);
     1747
     1748        /* Create procedure activation record. */
     1749        run_proc_ar_create(run, deleg_v->obj, fun->proc, &proc_ar);
     1750
     1751        /* Fill in argument values. */
     1752        run_proc_ar_set_args(run, proc_ar, &arg_vals);
     1753
     1754        /* Run the function. */
     1755        run_proc(run, proc_ar, res);
     1756
     1757        if (!run_is_bo(run) && fun->sig->rtype != NULL && *res == NULL) {
     1758                printf("Error: Function '");
     1759                symbol_print_fqn(deleg_v->sym);
     1760                printf("' did not return a value.\n");
     1761                exit(1);
     1762        }
     1763
     1764#ifdef DEBUG_RUN_TRACE
     1765        printf("Returned from function call.\n");
     1766#endif
     1767}
     1768
     1769/** Evaluate call arguments.
     1770 *
     1771 * Evaluate arguments to function or constructor.
     1772 *
     1773 * @param run           Runner object
     1774 * @param args          Real arguments (list of stree_expr_t)
     1775 * @param arg_vals      Address of uninitialized list to store argument values
     1776 *                      (list of rdata_item_t).
     1777 */
     1778static void run_call_args(run_t *run, list_t *args, list_t *arg_vals)
     1779{
     1780        list_node_t *arg_n;
     1781        stree_expr_t *arg;
     1782        rdata_item_t *rarg_i, *rarg_vi;
     1783
     1784        /* Evaluate function arguments. */
     1785        list_init(arg_vals);
     1786        arg_n = list_first(args);
     1787
     1788        while (arg_n != NULL) {
     1789                arg = list_node_data(arg_n, stree_expr_t *);
     1790                run_expr(run, arg, &rarg_i);
     1791                if (run_is_bo(run))
     1792                        return;
     1793
     1794                run_cvt_value_item(run, rarg_i, &rarg_vi);
     1795
     1796                list_append(arg_vals, rarg_vi);
     1797                arg_n = list_next(args, arg_n);
     1798        }
     1799}
     1800
     1801/** Run index operation.
     1802 *
     1803 * Evaluate operation per the indexing ('[', ']') operator.
     1804 *
     1805 * @param run           Runner object
     1806 * @param index         Index operation
     1807 * @param res           Place to store result
     1808 */
     1809static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res)
     1810{
     1811        rdata_item_t *rbase;
     1812        rdata_item_t *base_i;
     1813        list_node_t *node;
     1814        stree_expr_t *arg;
     1815        rdata_item_t *rarg_i, *rarg_vi;
     1816        var_class_t vc;
     1817        list_t arg_vals;
     1818
     1819#ifdef DEBUG_RUN_TRACE
     1820        printf("Run index operation.\n");
     1821#endif
     1822        run_expr(run, index->base, &rbase);
     1823        if (run_is_bo(run)) {
     1824                *res = NULL;
     1825                return;
     1826        }
     1827
     1828        vc = run_item_get_vc(run, rbase);
     1829
     1830        /* Implicitly dereference. */
     1831        if (vc == vc_ref) {
     1832                run_dereference(run, rbase, index->base->cspan, &base_i);
     1833                if (run_is_bo(run)) {
     1834                        *res = NULL;
     1835                        return;
     1836                }
     1837        } else {
     1838                base_i = rbase;
     1839        }
     1840
     1841        vc = run_item_get_vc(run, base_i);
     1842
     1843        /* Evaluate arguments (indices). */
     1844        node = list_first(&index->args);
    15011845        list_init(&arg_vals);
    1502         node = list_first(&call->args);
    15031846
    15041847        while (node != NULL) {
     
    15131856
    15141857                list_append(&arg_vals, rarg_vi);
    1515                 node = list_next(&call->args, node);
    1516         }
    1517 
    1518         fun = symbol_to_fun(deleg_v->sym);
    1519         assert(fun != NULL);
    1520 
    1521         /* Create procedure activation record. */
    1522         run_proc_ar_create(run, deleg_v->obj, fun->proc, &proc_ar);
    1523 
    1524         /* Fill in argument values. */
    1525         run_proc_ar_set_args(run, proc_ar, &arg_vals);
    1526 
    1527         /* Run the function. */
    1528         run_proc(run, proc_ar, res);
    1529 
    1530 #ifdef DEBUG_RUN_TRACE
    1531         printf("Returned from function call.\n");
    1532 #endif
    1533 }
    1534 
    1535 /** Run index operation.
    1536  *
    1537  * Evaluate operation per the indexing ('[', ']') operator.
    1538  *
    1539  * @param run           Runner object
    1540  * @param index         Index operation
    1541  * @param res           Place to store result
    1542  */
    1543 static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res)
    1544 {
    1545         rdata_item_t *rbase;
    1546         rdata_item_t *base_i;
    1547         list_node_t *node;
    1548         stree_expr_t *arg;
    1549         rdata_item_t *rarg_i, *rarg_vi;
    1550         var_class_t vc;
    1551         list_t arg_vals;
    1552 
    1553 #ifdef DEBUG_RUN_TRACE
    1554         printf("Run index operation.\n");
    1555 #endif
    1556         run_expr(run, index->base, &rbase);
    1557         if (run_is_bo(run)) {
    1558                 *res = NULL;
    1559                 return;
    1560         }
    1561 
    1562         vc = run_item_get_vc(run, rbase);
    1563 
    1564         /* Implicitly dereference. */
    1565         if (vc == vc_ref) {
    1566                 run_dereference(run, rbase, &base_i);
    1567         } else {
    1568                 base_i = rbase;
    1569         }
    1570 
    1571         vc = run_item_get_vc(run, base_i);
    1572 
    1573         /* Evaluate arguments (indices). */
    1574         node = list_first(&index->args);
    1575         list_init(&arg_vals);
    1576 
    1577         while (node != NULL) {
    1578                 arg = list_node_data(node, stree_expr_t *);
    1579                 run_expr(run, arg, &rarg_i);
    1580                 if (run_is_bo(run)) {
    1581                         *res = NULL;
    1582                         return;
    1583                 }
    1584 
    1585                 run_cvt_value_item(run, rarg_i, &rarg_vi);
    1586 
    1587                 list_append(&arg_vals, rarg_vi);
    15881858
    15891859                node = list_next(&index->args, node);
     
    16341904#endif
    16351905        (void) run;
    1636         (void) index;
    16371906
    16381907        assert(base->ic == ic_address);
     
    16761945                        /* Raise Error.OutOfBounds */
    16771946                        run_raise_exc(run,
    1678                             run->program->builtin->error_outofbounds);
     1947                            run->program->builtin->error_outofbounds,
     1948                            index->expr->cspan);
     1949                        /* XXX It should be cspan of the argument. */
    16791950                        *res = run_recovery_item(run);
    16801951                        return;
     
    18142085#endif
    18152086        (void) run;
    1816         (void) index;
    18172087
    18182088        run_cvt_value_item(run, base, &base_vi);
     
    18662136#endif
    18672137                /* Raise Error.OutOfBounds */
    1868                 run_raise_exc(run, run->program->builtin->error_outofbounds);
     2138                run_raise_exc(run, run->program->builtin->error_outofbounds,
     2139                    index->expr->cspan);
    18692140                *res = run_recovery_item(run);
    18702141                return;
     
    19702241        }
    19712242
    1972         run_dereference(run, rarg_vi, &rarg_di);
     2243        run_dereference(run, rarg_vi, NULL, &rarg_di);
    19732244
    19742245        /* Now we should have a variable address. */
     
    20482319        case vc_ref:
    20492320        case vc_deleg:
     2321        case vc_enum:
    20502322        case vc_array:
    20512323        case vc_object:
    20522324        case vc_resource:
     2325        case vc_symbol:
    20532326                assert(b_false);
    20542327        }
     
    21472420}
    21482421
     2422/** Run constructor on an object.
     2423 *
     2424 * @param run           Runner object
     2425 * @param obj           Object to run constructor on
     2426 * @param arg_vals      Argument values (list of rdata_item_t)
     2427 */
     2428static void run_object_ctor(run_t *run, rdata_var_t *obj, list_t *arg_vals)
     2429{
     2430        stree_ident_t *ctor_ident;
     2431        stree_symbol_t *csi_sym;
     2432        stree_csi_t *csi;
     2433        stree_symbol_t *ctor_sym;
     2434        stree_ctor_t *ctor;
     2435        run_proc_ar_t *proc_ar;
     2436        rdata_item_t *res;
     2437
     2438        csi_sym = obj->u.object_v->class_sym;
     2439        csi = symbol_to_csi(csi_sym);
     2440        assert(csi != NULL);
     2441
     2442#ifdef DEBUG_RUN_TRACE
     2443        printf("Run object constructor from CSI '");
     2444        symbol_print_fqn(csi_sym);
     2445        printf("'.\n");
     2446#endif
     2447        ctor_ident = stree_ident_new();
     2448        ctor_ident->sid = strtab_get_sid(CTOR_IDENT);
     2449
     2450        /* Find constructor. */
     2451        ctor_sym = symbol_search_csi_no_base(run->program, csi, ctor_ident);
     2452        if (ctor_sym == NULL) {
     2453#ifdef DEBUG_RUN_TRACE
     2454                printf("No constructor found.\n");
     2455#endif
     2456                return;
     2457        }
     2458
     2459        ctor = symbol_to_ctor(ctor_sym);
     2460        assert(ctor != NULL);
     2461
     2462        /* Create procedure activation record. */
     2463        run_proc_ar_create(run, obj, ctor->proc, &proc_ar);
     2464
     2465        /* Fill in argument values. */
     2466        run_proc_ar_set_args(run, proc_ar, arg_vals);
     2467
     2468        /* Run the procedure. */
     2469        run_proc(run, proc_ar, &res);
     2470
     2471        /* Constructor does not return a value. */
     2472        assert(res == NULL);
     2473
     2474#ifdef DEBUG_RUN_TRACE
     2475        printf("Returned from constructor..\n");
     2476#endif
     2477}
     2478
    21492479/** Return boolean value of an item.
    21502480 *
  • uspace/app/sbi/src/run_t.h

    r1317380 r640ffe6  
    9797        run_bailout_mode_t bo_mode;
    9898
     99        /** Exception cspan */
     100        struct cspan *exc_cspan;
     101
    99102        /** Exception payload */
    100103        struct rdata_value *exc_payload;
  • uspace/app/sbi/src/run_texpr.c

    r1317380 r640ffe6  
    3131#include <assert.h>
    3232#include <stdlib.h>
     33#include "cspan.h"
    3334#include "debug.h"
    3435#include "list.h"
     
    102103        tdata_deleg_t *tdeleg;
    103104        stree_csi_t *base_csi;
     105        stree_deleg_t *deleg;
     106        stree_enum_t *enum_d;
     107        tdata_enum_t *tenum;
    104108
    105109#ifdef DEBUG_RUN_TRACE
     
    115119
    116120        if (targ_i->tic != tic_tobject) {
    117                 printf("Error: Using '.' with type which is not an object.\n");
     121                cspan_print(taccess->texpr->cspan);
     122                printf(" Error: Using '.' with type which is not an "
     123                    "object.\n");
    118124                *res = tdata_item_new(tic_ignore);
    119125                return;
     
    125131        sym = symbol_lookup_in_csi(prog, base_csi, taccess->member_name);
    126132        if (sym == NULL) {
    127                 printf("Error: CSI '");
     133                cspan_print(taccess->member_name->cspan);
     134                printf(" Error: CSI '");
    128135                symbol_print_fqn(csi_to_symbol(base_csi));
    129136                printf("' has no member named '%s'.\n",
     
    142149                tobject->static_ref = b_false;
    143150                tobject->csi = sym->u.csi;
    144                 list_init(&tobject->targs); /* XXX */
    145                 break;
    146         case sc_deleg:
    147                 /* Construct type item. */
    148                 titem = tdata_item_new(tic_tdeleg);
    149                 tdeleg = tdata_deleg_new();
    150                 titem->u.tdeleg = tdeleg;
    151 
    152                 tdeleg->deleg = sym->u.deleg;
    153                 break;
    154         case sc_fun:
    155         case sc_var:
    156         case sc_prop:
    157                 printf("Error: Symbol '");
    158                 symbol_print_fqn(sym);
    159                 printf("' is not a type.\n");
    160                 titem = tdata_item_new(tic_ignore);
    161                 break;
    162         }
    163 
    164         *res = titem;
    165 }
    166 
    167 /** Evaluate type indexing expression.
    168  *
    169  * Evaluate operation per the type indexing ('[', ']') operator.
    170  * A type indexing operation may have extents specified or only rank
    171  * specified.
    172  *
    173  * @param prog          Program
    174  * @param ctx           Current CSI (context)
    175  * @param tindex        Type indexing expression to evaluate
    176  * @param res           Place to store type result
    177  */
    178 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
    179     stree_tindex_t *tindex, tdata_item_t **res)
    180 {
    181         tdata_item_t *base_ti;
    182         tdata_item_t *titem;
    183         tdata_array_t *tarray;
    184         stree_expr_t *arg_expr;
    185         list_node_t *arg_node;
    186 
    187 #ifdef DEBUG_RUN_TRACE
    188         printf("Evaluating type index operation.\n");
    189 #endif
    190         /* Evaluate base type. */
    191         run_texpr(prog, ctx, tindex->base_type, &base_ti);
    192 
    193         if (base_ti->tic == tic_ignore) {
    194                 *res = tdata_item_new(tic_ignore);
    195                 return;
    196         }
    197 
    198         /* Construct type item. */
    199         titem = tdata_item_new(tic_tarray);
    200         tarray = tdata_array_new();
    201         titem->u.tarray = tarray;
    202 
    203         tarray->base_ti = base_ti;
    204         tarray->rank = tindex->n_args;
    205 
    206         /* Copy extents. */
    207         list_init(&tarray->extents);
    208         arg_node = list_first(&tindex->args);
    209 
    210         while (arg_node != NULL) {
    211                 arg_expr = list_node_data(arg_node, stree_expr_t *);
    212                 list_append(&tarray->extents, arg_expr);
    213                 arg_node = list_next(&tindex->args, arg_node);
    214         }
    215 
    216         *res = titem;
    217 }
    218 
    219 /** Evaluate type literal expression.
    220  *
    221  * @param prog          Program
    222  * @param ctx           Current CSI (context)
    223  * @param tliteral      Type literal
    224  * @param res           Place to store type result
    225  */
    226 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
    227     stree_tliteral_t *tliteral, tdata_item_t **res)
    228 {
    229         tdata_item_t *titem;
    230         tdata_primitive_t *tprimitive;
    231         tprimitive_class_t tpc;
    232 
    233 #ifdef DEBUG_RUN_TRACE
    234         printf("Evaluating type literal.\n");
    235 #endif
    236         (void) prog;
    237         (void) ctx;
    238         (void) tliteral;
    239 
    240         switch (tliteral->tlc) {
    241         case tlc_bool: tpc = tpc_bool; break;
    242         case tlc_char: tpc = tpc_char; break;
    243         case tlc_int: tpc = tpc_int; break;
    244         case tlc_string: tpc = tpc_string; break;
    245         case tlc_resource: tpc = tpc_resource; break;
    246         }
    247 
    248         /* Construct type item. */
    249         titem = tdata_item_new(tic_tprimitive);
    250         tprimitive = tdata_primitive_new(tpc);
    251         titem->u.tprimitive = tprimitive;
    252 
    253         *res = titem;
    254 }
    255 
    256 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
    257     stree_tnameref_t *tnameref, tdata_item_t **res)
    258 {
    259         stree_symbol_t *sym;
    260         tdata_item_t *titem;
    261         tdata_object_t *tobject;
    262         stree_targ_t *targ;
    263         tdata_vref_t *tvref;
    264         stree_deleg_t *deleg;
    265         tdata_deleg_t *tdeleg;
    266 
    267 #ifdef DEBUG_RUN_TRACE
    268         printf("Evaluating type name reference.\n");
    269         printf("'%s'\n", strtab_get_str(tnameref->name->sid));
    270 #endif
    271         /* In interactive mode we are not in a class */
    272         if (ctx != NULL) {
    273                 /* Look for type argument */
    274                 targ = stree_csi_find_targ(ctx, tnameref->name);
    275 
    276                 if (targ != NULL) {
    277                         /* Found type argument */
    278 #ifdef DEBUG_RUN_TRACE
    279                         printf("Found type argument '%s'.\n",
    280                             strtab_get_str(tnameref->name->sid));
    281 #endif
    282                         titem = tdata_item_new(tic_tvref);
    283                         tvref = tdata_vref_new();
    284                         titem->u.tvref = tvref;
    285                         tvref->targ = targ;
    286 
    287                         *res = titem;
    288                         return;
    289                 }
    290         }
    291 
    292         /* Look for symbol */
    293         sym = symbol_lookup_in_csi(prog, ctx, tnameref->name);
    294         if (sym == NULL) {
    295                 printf("Error: Symbol '%s' not found.\n",
    296                     strtab_get_str(tnameref->name->sid));
    297                 *res = tdata_item_new(tic_ignore);
    298                 return;
    299         }
    300 
    301         switch (sym->sc) {
    302         case sc_csi:
    303                 /* Construct type item. */
    304                 titem = tdata_item_new(tic_tobject);
    305                 tobject = tdata_object_new();
    306                 titem->u.tobject = tobject;
    307 
    308                 tobject->static_ref = b_false;
    309                 tobject->csi = sym->u.csi;
    310                 list_init(&tobject->targs); /* XXX */
    311                 break;
     151                list_init(&tobject->targs);
     152                break;
     153        case sc_ctor:
     154                /* It is not possible to reference a constructor explicitly. */
     155                assert(b_false);
    312156        case sc_deleg:
    313157                /* Fetch stored delegate type. */
     
    330174                }
    331175                break;
     176        case sc_enum:
     177                /* Fetch stored enum type. */
     178                enum_d = symbol_to_enum(sym);
     179                assert(enum_d != NULL);
     180                if (enum_d->titem == NULL) {
     181                        /*
     182                         * Prepare a partial enum whic will be completed
     183                         * later.
     184                         */
     185                        titem = tdata_item_new(tic_tenum);
     186                        tenum = tdata_enum_new();
     187                        titem->u.tenum = tenum;
     188                        tenum->enum_d = enum_d;
     189                } else {
     190                        titem = enum_d->titem;
     191                }
     192                break;
    332193        case sc_fun:
    333194        case sc_var:
    334195        case sc_prop:
    335                 printf("Error: Symbol '");
     196                cspan_print(taccess->member_name->cspan);
     197                printf(" Error: Symbol '");
     198                symbol_print_fqn(sym);
     199                printf("' is not a type.\n");
     200                titem = tdata_item_new(tic_ignore);
     201                break;
     202        }
     203
     204        *res = titem;
     205}
     206
     207/** Evaluate type indexing expression.
     208 *
     209 * Evaluate operation per the type indexing ('[', ']') operator.
     210 * A type indexing operation may have extents specified or only rank
     211 * specified.
     212 *
     213 * @param prog          Program
     214 * @param ctx           Current CSI (context)
     215 * @param tindex        Type indexing expression to evaluate
     216 * @param res           Place to store type result
     217 */
     218static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
     219    stree_tindex_t *tindex, tdata_item_t **res)
     220{
     221        tdata_item_t *base_ti;
     222        tdata_item_t *titem;
     223        tdata_array_t *tarray;
     224        stree_expr_t *arg_expr;
     225        list_node_t *arg_node;
     226
     227#ifdef DEBUG_RUN_TRACE
     228        printf("Evaluating type index operation.\n");
     229#endif
     230        /* Evaluate base type. */
     231        run_texpr(prog, ctx, tindex->base_type, &base_ti);
     232
     233        if (base_ti->tic == tic_ignore) {
     234                *res = tdata_item_new(tic_ignore);
     235                return;
     236        }
     237
     238        /* Construct type item. */
     239        titem = tdata_item_new(tic_tarray);
     240        tarray = tdata_array_new();
     241        titem->u.tarray = tarray;
     242
     243        tarray->base_ti = base_ti;
     244        tarray->rank = tindex->n_args;
     245
     246        /* Copy extents. */
     247        list_init(&tarray->extents);
     248        arg_node = list_first(&tindex->args);
     249
     250        while (arg_node != NULL) {
     251                arg_expr = list_node_data(arg_node, stree_expr_t *);
     252                list_append(&tarray->extents, arg_expr);
     253                arg_node = list_next(&tindex->args, arg_node);
     254        }
     255
     256        *res = titem;
     257}
     258
     259/** Evaluate type literal expression.
     260 *
     261 * @param prog          Program
     262 * @param ctx           Current CSI (context)
     263 * @param tliteral      Type literal
     264 * @param res           Place to store type result
     265 */
     266static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
     267    stree_tliteral_t *tliteral, tdata_item_t **res)
     268{
     269        tdata_item_t *titem;
     270        tdata_primitive_t *tprimitive;
     271        tprimitive_class_t tpc;
     272
     273#ifdef DEBUG_RUN_TRACE
     274        printf("Evaluating type literal.\n");
     275#endif
     276        (void) prog;
     277        (void) ctx;
     278        (void) tliteral;
     279
     280        switch (tliteral->tlc) {
     281        case tlc_bool: tpc = tpc_bool; break;
     282        case tlc_char: tpc = tpc_char; break;
     283        case tlc_int: tpc = tpc_int; break;
     284        case tlc_string: tpc = tpc_string; break;
     285        case tlc_resource: tpc = tpc_resource; break;
     286        }
     287
     288        /* Construct type item. */
     289        titem = tdata_item_new(tic_tprimitive);
     290        tprimitive = tdata_primitive_new(tpc);
     291        titem->u.tprimitive = tprimitive;
     292
     293        *res = titem;
     294}
     295
     296static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
     297    stree_tnameref_t *tnameref, tdata_item_t **res)
     298{
     299        stree_symbol_t *sym;
     300        tdata_item_t *titem;
     301        tdata_object_t *tobject;
     302        stree_targ_t *targ;
     303        tdata_vref_t *tvref;
     304        stree_deleg_t *deleg;
     305        tdata_deleg_t *tdeleg;
     306        stree_enum_t *enum_d;
     307        tdata_enum_t *tenum;
     308
     309#ifdef DEBUG_RUN_TRACE
     310        printf("Evaluating type name reference.\n");
     311        printf("'%s'\n", strtab_get_str(tnameref->name->sid));
     312#endif
     313        /* In interactive mode we are not in a class */
     314        if (ctx != NULL) {
     315                /* Look for type argument */
     316                targ = stree_csi_find_targ(ctx, tnameref->name);
     317
     318                if (targ != NULL) {
     319                        /* Found type argument */
     320#ifdef DEBUG_RUN_TRACE
     321                        printf("Found type argument '%s'.\n",
     322                            strtab_get_str(tnameref->name->sid));
     323#endif
     324                        titem = tdata_item_new(tic_tvref);
     325                        tvref = tdata_vref_new();
     326                        titem->u.tvref = tvref;
     327                        tvref->targ = targ;
     328
     329                        *res = titem;
     330                        return;
     331                }
     332        }
     333
     334        /* Look for symbol */
     335        sym = symbol_lookup_in_csi(prog, ctx, tnameref->name);
     336        if (sym == NULL) {
     337                cspan_print(tnameref->texpr->cspan);
     338                printf(" Error: Symbol '%s' not found.\n",
     339                    strtab_get_str(tnameref->name->sid));
     340                *res = tdata_item_new(tic_ignore);
     341                return;
     342        }
     343
     344        switch (sym->sc) {
     345        case sc_csi:
     346                /* Construct type item. */
     347                titem = tdata_item_new(tic_tobject);
     348                tobject = tdata_object_new();
     349                titem->u.tobject = tobject;
     350
     351                tobject->static_ref = b_false;
     352                tobject->csi = sym->u.csi;
     353                list_init(&tobject->targs);
     354                break;
     355        case sc_ctor:
     356                /* It is not possible to reference a constructor explicitly. */
     357                assert(b_false);
     358        case sc_deleg:
     359                /* Fetch stored delegate type. */
     360                deleg = symbol_to_deleg(sym);
     361                assert(deleg != NULL);
     362                if (deleg->titem == NULL) {
     363                        /*
     364                         * Prepare a partial delegate which will be completed
     365                         * later.
     366                         */
     367                        titem = tdata_item_new(tic_tdeleg);
     368                        tdeleg = tdata_deleg_new();
     369                        titem->u.tdeleg = tdeleg;
     370                        tdeleg->deleg = deleg;
     371                        tdeleg->tsig = NULL;
     372
     373                        deleg->titem = titem;
     374                } else {
     375                        titem = deleg->titem;
     376                }
     377                break;
     378        case sc_enum:
     379                /* Fetch stored enum type. */
     380                enum_d = symbol_to_enum(sym);
     381                assert(enum_d != NULL);
     382                if (enum_d->titem == NULL) {
     383                        /*
     384                         * Prepare a partial enum whic will be completed
     385                         * later.
     386                         */
     387                        titem = tdata_item_new(tic_tenum);
     388                        tenum = tdata_enum_new();
     389                        titem->u.tenum = tenum;
     390                        tenum->enum_d = enum_d;
     391                } else {
     392                        titem = enum_d->titem;
     393                }
     394                break;
     395        case sc_fun:
     396        case sc_var:
     397        case sc_prop:
     398                cspan_print(tnameref->texpr->cspan);
     399                printf(" Error: Symbol '");
    336400                symbol_print_fqn(sym);
    337401                printf("' is not a type.\n");
     
    379443
    380444        if (base_ti->tic != tic_tobject) {
    381                 printf("Error: Base type of generic application is not "
     445                cspan_print(tapply->gtype->cspan);
     446                printf(" Error: Base type of generic application is not "
    382447                    "a CSI.\n");
    383448                *res = tdata_item_new(tic_ignore);
     
    410475
    411476        if (farg_n != NULL || arg_n != NULL) {
    412                 printf("Error: Incorrect number of type arguments.\n");
     477                cspan_print(tapply->texpr->cspan);
     478                printf(" Error: Incorrect number of type arguments.\n");
    413479                *res = tdata_item_new(tic_ignore);
    414480                return;
  • uspace/app/sbi/src/stree.c

    r1317380 r640ffe6  
    116116}
    117117
     118/** Allocate new constructor.
     119 *
     120 * @return      New constructor
     121 */
     122stree_ctor_t *stree_ctor_new(void)
     123{
     124        stree_ctor_t *ctor;
     125
     126        ctor = calloc(1, sizeof(stree_ctor_t));
     127        if (ctor == NULL) {
     128                printf("Memory allocation failed.\n");
     129                exit(1);
     130        }
     131
     132        return ctor;
     133}
     134
    118135/** Allocate new member delegate.
    119136 *
     
    133150}
    134151
     152/** Allocate new enum.
     153 *
     154 * @return      New enum
     155 */
     156stree_enum_t *stree_enum_new(void)
     157{
     158        stree_enum_t *enum_d;
     159
     160        enum_d = calloc(1, sizeof(stree_enum_t));
     161        if (enum_d == NULL) {
     162                printf("Memory allocation failed.\n");
     163                exit(1);
     164        }
     165
     166        return enum_d;
     167}
     168
     169/** Allocate new enum member.
     170 *
     171 * @return      New enum member
     172 */
     173stree_embr_t *stree_embr_new(void)
     174{
     175        stree_embr_t *embr;
     176
     177        embr = calloc(1, sizeof(stree_embr_t));
     178        if (embr == NULL) {
     179                printf("Memory allocation failed.\n");
     180                exit(1);
     181        }
     182
     183        return embr;
     184}
     185
    135186/** Allocate new member function.
    136187 *
     
    394445}
    395446
     447/** Allocate new @c break statement.
     448 *
     449 * @return      New @c break statement
     450 */
     451stree_break_t *stree_break_new(void)
     452{
     453        stree_break_t *break_s;
     454
     455        break_s = calloc(1, sizeof(stree_break_t));
     456        if (break_s == NULL) {
     457                printf("Memory allocation failed.\n");
     458                exit(1);
     459        }
     460
     461        return break_s;
     462}
     463
    396464/** Allocate new @c return statement.
    397465 *
     
    462530}
    463531
     532/** Allocate new @c if/elif clause.
     533 *
     534 * @return      New @c if/elif clause
     535 */
     536stree_if_clause_t *stree_if_clause_new(void)
     537{
     538        stree_if_clause_t *if_clause;
     539
     540        if_clause = calloc(1, sizeof(stree_if_clause_t));
     541        if (if_clause == NULL) {
     542                printf("Memory allocation failed.\n");
     543                exit(1);
     544        }
     545
     546        return if_clause;
     547}
     548
    464549/** Allocate new statement block.
    465550 *
     
    869954 * @param symbol        Symbol
    870955 * @param sac           Symbol attribute class
    871  * @return              @c b_true if yes, @c b_false if no.
     956 * @return              @c b_true if yes, @c b_false if no
    872957 */
    873958bool_t stree_symbol_has_attr(stree_symbol_t *symbol, symbol_attr_class_t sac)
     
    9381023/** Search for CSI type argument of the given name.
    9391024 *
    940  * @param csi           CSI to look in.
    941  * @param ident         Identifier of the type argument.
    942  * @return              Type argument definition or @c NULL if not found.
     1025 * @param csi           CSI to look in
     1026 * @param ident         Identifier of the type argument
     1027 * @return              Type argument declaration or @c NULL if not found
    9431028 */
    9441029stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident)
     
    9591044        return NULL;
    9601045}
     1046
     1047/** Search for enum member of the given name.
     1048 *
     1049 * @param enum_d        Enum to look in
     1050 * @param ident         Identifier of the enum member
     1051 * @return              Enum member declaration or @c NULL if not found
     1052 */
     1053stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident)
     1054{
     1055        list_node_t *embr_n;
     1056        stree_embr_t *embr;
     1057
     1058        embr_n = list_first(&enum_d->members);
     1059        while (embr_n != NULL) {
     1060                embr = list_node_data(embr_n, stree_embr_t *);
     1061                if (embr->name->sid == ident->sid)
     1062                        return embr;
     1063
     1064                embr_n = list_next(&enum_d->members, embr_n);
     1065        }
     1066
     1067        /* No match */
     1068        return NULL;
     1069}
     1070
     1071/** Get CSI member name.
     1072 *
     1073 * @param csimbr        CSI member
     1074 * @return              Member name
     1075 */
     1076stree_ident_t *stree_csimbr_get_name(stree_csimbr_t *csimbr)
     1077{
     1078        stree_ident_t *mbr_name;
     1079
     1080        /* Keep compiler happy. */
     1081        mbr_name = NULL;
     1082
     1083        switch (csimbr->cc) {
     1084        case csimbr_csi: mbr_name = csimbr->u.csi->name; break;
     1085        case csimbr_ctor: mbr_name = csimbr->u.ctor->name; break;
     1086        case csimbr_deleg: mbr_name = csimbr->u.deleg->name; break;
     1087        case csimbr_enum: mbr_name = csimbr->u.enum_d->name; break;
     1088        case csimbr_fun: mbr_name = csimbr->u.fun->name; break;
     1089        case csimbr_var: mbr_name = csimbr->u.var->name; break;
     1090        case csimbr_prop: mbr_name = csimbr->u.prop->name; break;
     1091        }
     1092
     1093        return mbr_name;
     1094}
  • uspace/app/sbi/src/stree.h

    r1317380 r640ffe6  
    3636stree_csi_t *stree_csi_new(csi_class_t cc);
    3737stree_csimbr_t *stree_csimbr_new(csimbr_class_t cc);
     38stree_ctor_t *stree_ctor_new(void);
    3839stree_deleg_t *stree_deleg_new(void);
     40stree_enum_t *stree_enum_new(void);
     41stree_embr_t *stree_embr_new(void);
    3942stree_fun_t *stree_fun_new(void);
    4043stree_var_t *stree_var_new(void);
     
    5558stree_for_t *stree_for_new(void);
    5659stree_raise_t *stree_raise_new(void);
     60stree_break_t *stree_break_new(void);
    5761stree_return_t *stree_return_new(void);
    5862stree_wef_t *stree_wef_new(void);
     
    6064
    6165stree_except_t *stree_except_new(void);
     66stree_if_clause_t *stree_if_clause_new(void);
    6267stree_block_t *stree_block_new(void);
    6368
     
    9297bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b);
    9398stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident);
     99stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident);
     100stree_ident_t *stree_csimbr_get_name(stree_csimbr_t *csimbr);
    94101
    95102#endif
  • uspace/app/sbi/src/stree_t.h

    r1317380 r640ffe6  
    4343typedef struct {
    4444        int sid;
     45        struct cspan *cspan;
    4546} stree_ident_t;
    4647
    4748/** Name reference */
    4849typedef struct {
     50        /** Expression backlink */
     51        struct stree_expr *expr;
     52
    4953        stree_ident_t *name;
    5054} stree_nameref_t;
    51 
    52 /** Reference to currently active object. */
    53 typedef struct {
    54 } stree_self_ref_t;
    5555
    5656/** Boolean literal */
     
    8888/** Literal */
    8989typedef struct {
     90        /** Expression backlink */
     91        struct stree_expr *expr;
     92
    9093        literal_class_t ltc;
    9194        union {
     
    98101} stree_literal_t;
    99102
     103/** Reference to currently active object. */
     104typedef struct {
     105        /** Expression backlink */
     106        struct stree_expr *expr;
     107} stree_self_ref_t;
     108
    100109/** Binary operation class */
    101110typedef enum {
     
    108117        bo_plus,
    109118        bo_minus,
    110         bo_mult
     119        bo_mult,
     120        bo_and,
     121        bo_or
    111122} binop_class_t;
    112123
     
    115126        uo_plus,
    116127        uo_minus,
     128        uo_not
    117129} unop_class_t;
    118130
    119131/** Binary operation */
    120132typedef struct {
     133        /** Expression backlink */
     134        struct stree_expr *expr;
     135
    121136        /** Binary operation class */
    122137        binop_class_t bc;
     
    128143/** Unary operation */
    129144typedef struct {
     145        /** Expression backlink */
     146        struct stree_expr *expr;
     147
    130148        /** Operation class */
    131149        unop_class_t uc;
     
    137155/** New operation */
    138156typedef struct {
     157        /** Expression backlink */
     158        struct stree_expr *expr;
     159
    139160        /** Type of object to construct. */
    140161        struct stree_texpr *texpr;
     162
     163        /** Constructor arguments */
     164        list_t ctor_args; /* of stree_expr_t */
    141165} stree_new_t;
    142166
    143167/** Member access operation */
    144168typedef struct {
     169        /** Expression backlink */
     170        struct stree_expr *expr;
     171
    145172        /** Argument */
    146173        struct stree_expr *arg;
     
    151178/** Function call operation */
    152179typedef struct {
     180        /** Expression backlink */
     181        struct stree_expr *expr;
     182
    153183        /** Function */
    154184        struct stree_expr *fun;
     
    165195/** Assignment */
    166196typedef struct {
     197        /** Expression backlink */
     198        struct stree_expr *expr;
     199
    167200        assign_class_t ac;
    168201        struct stree_expr *dest, *src;
     
    171204/** Indexing operation */
    172205typedef struct {
     206        /** Expression backlink */
     207        struct stree_expr *expr;
     208
    173209        /** Base */
    174210        struct stree_expr *base;
     
    180216/** @c as conversion operation */
    181217typedef struct {
     218        /** Expression backlink */
     219        struct stree_expr *expr;
     220
    182221        /** Expression to convert */
    183222        struct stree_expr *arg;
     223
    184224        /** Destination type of conversion. */
    185225        struct stree_texpr *dtype;
     
    193233 */
    194234typedef struct {
     235        /** Expression backlink */
     236        struct stree_expr *expr;
     237
    195238        /* Primitive type expression */
    196239        struct stree_expr *arg;
     
    217260        expr_class_t ec;
    218261
     262        /** Type of this expression or @c NULL if not typed yet */
    219263        struct tdata_item *titem;
     264
     265        /** Coordinate span */
     266        struct cspan *cspan;
    220267
    221268        union {
     
    252299/** Type literal */
    253300typedef struct {
     301        /** Type expression backlink */
     302        struct stree_texpr *texpr;
     303
    254304        tliteral_class_t tlc;
    255305} stree_tliteral_t;
     
    257307/** Type name reference */
    258308typedef struct {
     309        /** Type expression backlink */
     310        struct stree_texpr *texpr;
     311
    259312        stree_ident_t *name;
    260313} stree_tnameref_t;
     
    262315/** Type member access operation */
    263316typedef struct {
     317        /** Type expression backlink */
     318        struct stree_texpr *texpr;
     319
    264320        /** Argument */
    265321        struct stree_texpr *arg;
     322
    266323        /** Name of member being accessed. */
    267324        stree_ident_t *member_name;
     
    270327/** Type application operation */
    271328typedef struct {
     329        /** Type expression backlink */
     330        struct stree_texpr *texpr;
     331
    272332        /* Base type */
    273333        struct stree_texpr *gtype;
     
    279339/** Type index operation */
    280340typedef struct {
     341        /** Type expression backlink */
     342        struct stree_texpr *texpr;
     343
    281344        /** Base type */
    282345        struct stree_texpr *base_type;
     
    304367typedef struct stree_texpr {
    305368        texpr_class_t tc;
     369
     370        /** Coordinate span */
     371        struct cspan *cspan;
    306372
    307373        union {
     
    337403} stree_except_t;
    338404
     405/** @c if or @c elif clause */
     406typedef struct {
     407        stree_expr_t *cond;
     408        stree_block_t *block;
     409} stree_if_clause_t;
     410
    339411/** If statement */
    340412typedef struct {
    341         stree_expr_t *cond;
    342         stree_block_t *if_block;
     413        /** If and elif clauses */
     414        list_t if_clauses; /* of stree_if_clause_t */
     415
     416        /** Else block */
    343417        stree_block_t *else_block;
    344418} stree_if_t;
     
    359433        stree_expr_t *expr;
    360434} stree_raise_t;
     435
     436/** Break statement */
     437typedef struct {
     438} stree_break_t;
    361439
    362440/** Return statement */
     
    384462        st_for,
    385463        st_raise,
     464        st_break,
    386465        st_return,
    387466        st_exps,
     
    399478                stree_for_t *for_s;
    400479                stree_raise_t *raise_s;
     480                stree_break_t *break_s;
    401481                stree_return_t *return_s;
    402482                stree_exps_t *exp_s;
     
    461541} stree_proc_t;
    462542
     543/** Constructor declaration */
     544typedef struct stree_ctor {
     545        /** Constructor 'name'. Points to the @c new keyword. */
     546        stree_ident_t *name;
     547
     548        /** Symbol */
     549        struct stree_symbol *symbol;
     550
     551        /** Signature (arguments, return type is always none) */
     552        stree_fun_sig_t *sig;
     553
     554        /** Constructor implementation */
     555        stree_proc_t *proc;
     556
     557        /** Type item describing the constructor */
     558        struct tdata_item *titem;
     559} stree_ctor_t;
     560
    463561/** Delegate declaration */
    464562typedef struct stree_deleg {
     
    476574} stree_deleg_t;
    477575
     576/** Enum member */
     577typedef struct stree_embr {
     578        /** Enum containing this declaration */
     579        struct stree_enum *outer_enum;
     580
     581        /** Enum member name */
     582        stree_ident_t *name;
     583} stree_embr_t;
     584
     585/** Enum declaration */
     586typedef struct stree_enum {
     587        /** Enum name */
     588        stree_ident_t *name;
     589
     590        /** Symbol */
     591        struct stree_symbol *symbol;
     592
     593        /** List of enum members */
     594        list_t members; /* of stree_embr_t */
     595
     596        /** Type item describing the enum */
     597        struct tdata_item *titem;
     598} stree_enum_t;
     599
    478600/** Member function declaration */
    479601typedef struct stree_fun {
     
    521643/**
    522644 * Fake identifiers used with symbols that do not really have one.
    523  * (Mostly for error messages.)
    524645 */
     646#define CTOR_IDENT "$ctor"
    525647#define INDEXER_IDENT "$indexer"
    526648
    527649typedef enum {
    528650        csimbr_csi,
     651        csimbr_ctor,
    529652        csimbr_deleg,
     653        csimbr_enum,
    530654        csimbr_fun,
    531655        csimbr_var,
     
    539663        union {
    540664                struct stree_csi *csi;
     665                stree_ctor_t *ctor;
    541666                stree_deleg_t *deleg;
     667                stree_enum_t *enum_d;
    542668                stree_fun_t *fun;
    543669                stree_var_t *var;
     
    587713typedef enum {
    588714        /* Class, struct or interface declaration */
    589         mc_csi
     715        mc_csi,
     716        /* Enum declaration */
     717        mc_enum
    590718} modm_class_t;
    591719
     
    595723        union {
    596724                stree_csi_t *csi;
     725                stree_enum_t *enum_d;
    597726        } u;
    598727} stree_modm_t;
     
    618747        /** CSI (class, struct or interface) */
    619748        sc_csi,
     749        /** Constructor */
     750        sc_ctor,
    620751        /** Member delegate */
    621752        sc_deleg,
     753        /** Enum */
     754        sc_enum,
    622755        /** Member function */
    623756        sc_fun,
     
    638771        union {
    639772                struct stree_csi *csi;
     773                stree_ctor_t *ctor;
    640774                stree_deleg_t *deleg;
     775                stree_enum_t *enum_d;
    641776                stree_fun_t *fun;
    642777                stree_var_t *var;
  • uspace/app/sbi/src/stype.c

    r1317380 r640ffe6  
    3838#include <stdlib.h>
    3939#include <assert.h>
     40#include "cspan.h"
    4041#include "debug.h"
    4142#include "intmap.h"
     
    5253
    5354static void stype_csi(stype_t *stype, stree_csi_t *csi);
     55static void stype_ctor(stype_t *stype, stree_ctor_t *ctor);
     56static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor);
    5457static void stype_fun(stype_t *stype, stree_fun_t *fun);
    5558static void stype_var(stype_t *stype, stree_var_t *var);
     
    6669static void stype_for(stype_t *stype, stree_for_t *for_s);
    6770static void stype_raise(stype_t *stype, stree_raise_t *raise_s);
     71static void stype_break(stype_t *stype, stree_break_t *break_s);
    6872static void stype_return(stype_t *stype, stree_return_t *return_s);
    6973static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value);
     
    8084static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
    8185    tdata_item_t *dest);
     86static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr,
     87    tdata_item_t *dest);
    8288static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
    8389    stree_expr_t *expr, tdata_item_t *dest);
    8490static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
    8591    tdata_item_t *dest);
    86 static void stype_convert_failure(stype_t *stype, tdata_item_t *src,
     92static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,
    8793    tdata_item_t *dest);
    8894
     
    112118        while (mbr_n != NULL) {
    113119                mbr = list_node_data(mbr_n, stree_modm_t *);
    114                 assert(mbr->mc == mc_csi);
    115 
    116                 stype_csi(stype, mbr->u.csi);
     120
     121                switch (mbr->mc) {
     122                case mc_csi:
     123                        stype_csi(stype, mbr->u.csi);
     124                        break;
     125                case mc_enum:
     126                        stype_enum(stype, mbr->u.enum_d);
     127                        break;
     128                }
    117129
    118130                mbr_n = list_next(&module->members, mbr_n);
     
    145157                switch (csimbr->cc) {
    146158                case csimbr_csi: stype_csi(stype, csimbr->u.csi); break;
     159                case csimbr_ctor: stype_ctor(stype, csimbr->u.ctor); break;
    147160                case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break;
     161                case csimbr_enum: stype_enum(stype, csimbr->u.enum_d); break;
    148162                case csimbr_fun: stype_fun(stype, csimbr->u.fun); break;
    149163                case csimbr_var: stype_var(stype, csimbr->u.var); break;
     
    155169
    156170        stype->current_csi = prev_ctx;
     171}
     172
     173/** Type a constructor.
     174 *
     175 * @param stype         Static typing object.
     176 * @param ctor          Constructor to type.
     177 */
     178static void stype_ctor(stype_t *stype, stree_ctor_t *ctor)
     179{
     180#ifdef DEBUG_TYPE_TRACE
     181        printf("Type constructor '");
     182        symbol_print_fqn(ctor_to_symbol(ctor));
     183        printf("'.\n");
     184#endif
     185        if (ctor->titem == NULL)
     186                stype_ctor_header(stype, ctor);
     187
     188        stype_ctor_body(stype, ctor);
     189}
     190
     191/** Type constructor header.
     192 *
     193 * @param stype         Static typing object.
     194 * @param ctor          Constructor to type.
     195 */
     196void stype_ctor_header(stype_t *stype, stree_ctor_t *ctor)
     197{
     198        stree_symbol_t *ctor_sym;
     199        tdata_item_t *ctor_ti;
     200        tdata_fun_t *tfun;
     201        tdata_fun_sig_t *tsig;
     202
     203#ifdef DEBUG_TYPE_TRACE
     204        printf("Type constructor '");
     205        symbol_print_fqn(ctor_to_symbol(ctor));
     206        printf("' header.\n");
     207#endif
     208        if (ctor->titem != NULL)
     209                return; /* Constructor header has already been typed. */
     210
     211        ctor_sym = ctor_to_symbol(ctor);
     212
     213        /* Type function signature. */
     214        stype_fun_sig(stype, ctor_sym->outer_csi, ctor->sig, &tsig);
     215
     216        ctor_ti = tdata_item_new(tic_tfun);
     217        tfun = tdata_fun_new();
     218        ctor_ti->u.tfun = tfun;
     219        tfun->tsig = tsig;
     220
     221        ctor->titem = ctor_ti;
     222}
     223
     224/** Type constructor body.
     225 *
     226 * @param stype         Static typing object
     227 * @param ctor          Constructor
     228 */
     229static void stype_ctor_body(stype_t *stype, stree_ctor_t *ctor)
     230{
     231#ifdef DEBUG_TYPE_TRACE
     232        printf("Type constructor '");
     233        symbol_print_fqn(ctor_to_symbol(ctor));
     234        printf("' body.\n");
     235#endif
     236        assert(stype->proc_vr == NULL);
     237
     238        stype->proc_vr = stype_proc_vr_new();
     239        stype->proc_vr->proc = ctor->proc;
     240        list_init(&stype->proc_vr->block_vr);
     241
     242        stype_block(stype, ctor->proc->body);
     243
     244        free(stype->proc_vr);
     245        stype->proc_vr = NULL;
    157246}
    158247
     
    197286}
    198287
     288/** Type enum.
     289 *
     290 * @param stype         Static typing object
     291 * @param enum_d        Enum to type
     292 */
     293void stype_enum(stype_t *stype, stree_enum_t *enum_d)
     294{
     295        tdata_item_t *titem;
     296        tdata_enum_t *tenum;
     297
     298        (void) stype;
     299
     300#ifdef DEBUG_TYPE_TRACE
     301        printf("Type enum '");
     302        symbol_print_fqn(enum_to_symbol(enum_d));
     303        printf("'.\n");
     304#endif
     305        if (enum_d->titem == NULL) {
     306                titem = tdata_item_new(tic_tenum);
     307                tenum = tdata_enum_new();
     308                titem->u.tenum = tenum;
     309                tenum->enum_d = enum_d;
     310
     311                enum_d->titem = titem;
     312        } else {
     313                titem = enum_d->titem;
     314        }
     315}
     316
    199317/** Type function.
    200318 *
     
    457575        case st_for: stype_for(stype, stat->u.for_s); break;
    458576        case st_raise: stype_raise(stype, stat->u.raise_s); break;
     577        case st_break: stype_break(stype, stat->u.break_s); break;
    459578        case st_return: stype_return(stype, stat->u.return_s); break;
    460579        case st_exps: stype_exps(stype, stat->u.exp_s, want_value); break;
     
    506625{
    507626        stree_expr_t *ccond;
     627        list_node_t *ifc_node;
     628        stree_if_clause_t *ifc;
    508629
    509630#ifdef DEBUG_TYPE_TRACE
    510631        printf("Type 'if' statement.\n");
    511632#endif
    512         /* Convert condition to boolean type. */
    513         stype_expr(stype, if_s->cond);
    514         ccond = stype_convert(stype, if_s->cond, stype_boolean_titem(stype));
    515 
    516         /* Patch code with augmented expression. */
    517         if_s->cond = ccond;
    518 
    519         /* Type the @c if block */
    520         stype_block(stype, if_s->if_block);
     633        ifc_node = list_first(&if_s->if_clauses);
     634
     635        /* Walk through all if/elif clauses. */
     636
     637        while (ifc_node != NULL) {
     638                /* Get if/elif clause */
     639                ifc = list_node_data(ifc_node, stree_if_clause_t *);
     640
     641                /* Convert condition to boolean type. */
     642                stype_expr(stype, ifc->cond);
     643                ccond = stype_convert(stype, ifc->cond,
     644                    stype_boolean_titem(stype));
     645
     646                /* Patch code with augmented expression. */
     647                ifc->cond = ccond;
     648
     649                /* Type the @c if/elif block */
     650                stype_block(stype, ifc->block);
     651
     652                ifc_node = list_next(&if_s->if_clauses, ifc_node);
     653        }
    521654
    522655        /* Type the @c else block */
     
    545678        while_s->cond = ccond;
    546679
     680        /* While is a breakable statement. Increment counter. */
     681        stype->proc_vr->bstat_cnt += 1;
     682
    547683        /* Type the body of the loop */
    548684        stype_block(stype, while_s->body);
     685
     686        stype->proc_vr->bstat_cnt -= 1;
    549687}
    550688
     
    559697        printf("Type 'for' statement.\n");
    560698#endif
     699        /* For is a breakable statement. Increment counter. */
     700        stype->proc_vr->bstat_cnt += 1;
     701
    561702        stype_block(stype, for_s->body);
     703
     704        stype->proc_vr->bstat_cnt -= 1;
    562705}
    563706
     
    573716#endif
    574717        stype_expr(stype, raise_s->expr);
     718}
     719
     720/** Type @c break statement */
     721static void stype_break(stype_t *stype, stree_break_t *break_s)
     722{
     723#ifdef DEBUG_TYPE_TRACE
     724        printf("Type 'break' statement.\n");
     725#endif
     726        (void) break_s;
     727
     728        /* Check whether there is an active statement to break from. */
     729        if (stype->proc_vr->bstat_cnt == 0) {
     730                printf("Error: Break statement outside of while or for.\n");
     731                stype_note_error(stype);
     732        }
    575733}
    576734
     
    588746        printf("Type 'return' statement.\n");
    589747#endif
    590         stype_expr(stype, return_s->expr);
     748        if (return_s->expr != NULL)
     749                stype_expr(stype, return_s->expr);
    591750
    592751        /* Determine the type we need to return. */
     
    599758
    600759                /* XXX Memoize to avoid recomputing. */
    601                 run_texpr(stype->program, outer_sym->outer_csi,
    602                     fun->sig->rtype, &dtype);
     760                if (fun->sig->rtype != NULL) {
     761                        run_texpr(stype->program, outer_sym->outer_csi,
     762                            fun->sig->rtype, &dtype);
     763
     764                        if (return_s->expr == NULL) {
     765                                printf("Error: Return without a value in "
     766                                    "function returning value.\n");
     767                                stype_note_error(stype);
     768                        }
     769                } else {
     770                        dtype = NULL;
     771
     772                        if (return_s->expr != NULL) {
     773                                printf("Error: Return with a value in "
     774                                    "value-less function.\n");
     775                                stype_note_error(stype);
     776                        }
     777                }
    603778                break;
    604779        case sc_prop:
     
    606781                assert(prop != NULL);
    607782
    608                 if (stype->proc_vr->proc != prop->getter) {
    609                         printf("Error: Return statement in "
    610                             "setter.\n");
    611                         stype_note_error(stype);
     783                if (stype->proc_vr->proc == prop->getter) {
     784                        if (return_s->expr == NULL) {
     785                                printf("Error: Return without a value in "
     786                                    "getter.\n");
     787                                stype_note_error(stype);
     788                        }
     789                } else {
     790                        if (return_s->expr == NULL) {
     791                                printf("Error: Return with a value in "
     792                                    "setter.\n");
     793                                stype_note_error(stype);
     794                        }
    612795                }
    613796
     
    620803        }
    621804
    622         /* Convert to the return type. */
    623         cexpr = stype_convert(stype, return_s->expr, dtype);
    624 
    625         /* Patch code with the augmented expression. */
    626         return_s->expr = cexpr;
     805        if (dtype != NULL && return_s->expr != NULL) {
     806                /* Convert to the return type. */
     807                cexpr = stype_convert(stype, return_s->expr, dtype);
     808
     809                /* Patch code with the augmented expression. */
     810                return_s->expr = cexpr;
     811        }
    627812}
    628813
     
    714899
    715900        if (src == NULL) {
    716                 printf("Error: Conversion source is not valid.\n");
     901                cspan_print(expr->cspan);
     902                printf(" Error: Conversion source is not valid.\n");
    717903                stype_note_error(stype);
    718904                return expr;
     
    738924        }
    739925
     926        if (src->tic == tic_tebase) {
     927                stype_convert_failure(stype, expr, dest);
     928                printf("Invalid use of reference to enum type in "
     929                    "expression.\n");
     930                return expr;
     931        }
     932
    740933        if (src->tic != dest->tic) {
    741                 stype_convert_failure(stype, src, dest);
     934                stype_convert_failure(stype, expr, dest);
    742935                return expr;
    743936        }
     
    756949                expr = stype_convert_tdeleg(stype, expr, dest);
    757950                break;
     951        case tic_tebase:
     952                /* Conversion destination should never be enum-base */
     953                assert(b_false);
     954        case tic_tenum:
     955                expr = stype_convert_tenum(stype, expr, dest);
     956                break;
    758957        case tic_tfun:
    759958                assert(b_false);
     
    788987        /* Check if both have the same tprimitive class. */
    789988        if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
    790                 stype_convert_failure(stype, src, dest);
     989                stype_convert_failure(stype, expr, dest);
    791990
    792991        return expr;
     
    795994/** Convert expression of primitive type to object type.
    796995 *
    797  * This function implements autoboxing. It modified the code.
     996 * This function implements autoboxing. It modifies the code by inserting
     997 * the boxing operation.
    798998 *
    799999 * @param stype         Static typing object
     
    8281028        case tpc_string: bp_sym = bi->boxed_string; break;
    8291029        case tpc_resource:
    830                 stype_convert_failure(stype, src, dest);
     1030                stype_convert_failure(stype, expr, dest);
    8311031                return expr;
    8321032        }
     
    8341034        /* Target type must be boxed @a src or Object */
    8351035        if (csi_sym != bp_sym && csi_sym != bi->gf_class)
    836                 stype_convert_failure(stype, src, dest);
     1036                stype_convert_failure(stype, expr, dest);
    8371037
    8381038        /* Patch the code to box the primitive value */
     
    8411041        bexpr = stree_expr_new(ec_box);
    8421042        bexpr->u.box = box;
     1043        bexpr->titem = dest;
    8431044
    8441045        /* No action needed to optionally convert boxed type to Object */
     
    9011102                } else {
    9021103                        /* No match */
    903                         stype_convert_failure(stype, src, dest);
     1104                        stype_convert_failure(stype, expr, dest);
    9041105                        return expr;
    9051106                }
     
    9161117                if (tdata_item_equal(carg, darg) != b_true) {
    9171118                        /* Diferent argument type */
    918                         stype_convert_failure(stype, src, dest);
     1119                        stype_convert_failure(stype, expr, dest);
    9191120                        printf("Different argument type '");
    9201121                        tdata_item_print(carg);
     
    9311132        if (ca_n != NULL || da_n != NULL) {
    9321133                /* Diferent number of arguments */
    933                 stype_convert_failure(stype, src, dest);
     1134                stype_convert_failure(stype, expr, dest);
    9341135                printf("Different number of arguments.\n");
    9351136                return expr;
     
    9591160        /* Compare rank and base type. */
    9601161        if (src->u.tarray->rank != dest->u.tarray->rank) {
    961                 stype_convert_failure(stype, src, dest);
     1162                stype_convert_failure(stype, expr, dest);
    9621163                return expr;
    9631164        }
     
    9661167        if (tdata_item_equal(src->u.tarray->base_ti,
    9671168            dest->u.tarray->base_ti) != b_true) {
    968                 stype_convert_failure(stype, src, dest);
     1169                stype_convert_failure(stype, expr, dest);
    9691170        }
    9701171
     
    10041205        /* Both must be the same delegate. */
    10051206        if (sdeleg->deleg != ddeleg->deleg) {
    1006                 stype_convert_failure(stype, src, dest);
     1207                stype_convert_failure(stype, expr, dest);
     1208                return expr;
     1209        }
     1210
     1211        return expr;
     1212}
     1213
     1214/** Convert expression of enum type to enum type.
     1215 *
     1216 * @param stype         Static typing object
     1217 * @param expr          Expression
     1218 * @param dest          Destination type
     1219 */
     1220static stree_expr_t *stype_convert_tenum(stype_t *stype, stree_expr_t *expr,
     1221    tdata_item_t *dest)
     1222{
     1223        tdata_item_t *src;
     1224        tdata_enum_t *senum, *denum;
     1225
     1226#ifdef DEBUG_TYPE_TRACE
     1227        printf("Convert enum type.\n");
     1228#endif
     1229        src = expr->titem;
     1230        assert(src->tic == tic_tenum);
     1231        assert(dest->tic == tic_tenum);
     1232
     1233        senum = src->u.tenum;
     1234        denum = dest->u.tenum;
     1235
     1236        /*
     1237         * XXX How should enum types interact with generics?
     1238         */
     1239
     1240        /* Both must be of the same enum type (with the same declaration). */
     1241        if (senum->enum_d != denum->enum_d) {
     1242                stype_convert_failure(stype, expr, dest);
    10071243                return expr;
    10081244        }
     
    10431279
    10441280        if (!stype_fun_sig_equal(stype, ssig, dsig)) {
    1045                 stype_convert_failure(stype, src, dest);
     1281                stype_convert_failure(stype, expr, dest);
    10461282                return expr;
    10471283        }
     
    10751311        /* Currently only allow if both types are the same. */
    10761312        if (src->u.tvref->targ != dest->u.tvref->targ) {
    1077                 stype_convert_failure(stype, src, dest);
     1313                stype_convert_failure(stype, expr, dest);
    10781314                return expr;
    10791315        }
     
    10851321 *
    10861322 * @param stype         Static typing object
    1087  * @param src           Original type
     1323 * @param expr          Original expression
    10881324 * @param dest          Destination type
    10891325 */
    1090 static void stype_convert_failure(stype_t *stype, tdata_item_t *src,
     1326static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,
    10911327    tdata_item_t *dest)
    10921328{
    1093         printf("Error: Cannot convert ");
    1094         tdata_item_print(src);
     1329        cspan_print(expr->cspan);
     1330        printf(" Error: Cannot convert ");
     1331        tdata_item_print(expr->titem);
    10951332        printf(" to ");
    10961333        tdata_item_print(dest);
     
    10991336        stype_note_error(stype);
    11001337}
     1338
     1339/** Box value.
     1340 *
     1341 * This function implements implicit boxing. It modifies the code by inserting
     1342 * the boxing operation.
     1343 *
     1344 * @param stype         Static typing object
     1345 * @param expr          Expression
     1346 * @return              Modified expression.
     1347 */
     1348stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr)
     1349{
     1350        tdata_item_t *src;
     1351        builtin_t *bi;
     1352        stree_symbol_t *bp_sym;
     1353        stree_box_t *box;
     1354        stree_expr_t *bexpr;
     1355        tdata_object_t *tobject;
     1356
     1357#ifdef DEBUG_TYPE_TRACE
     1358        printf("Boxing.\n");
     1359#endif
     1360        src = expr->titem;
     1361        assert(src->tic == tic_tprimitive);
     1362
     1363        bi = stype->program->builtin;
     1364
     1365        /* Make compiler happy. */
     1366        bp_sym = NULL;
     1367
     1368        switch (src->u.tprimitive->tpc) {
     1369        case tpc_bool: bp_sym = bi->boxed_bool; break;
     1370        case tpc_char: bp_sym = bi->boxed_char; break;
     1371        case tpc_int: bp_sym = bi->boxed_int; break;
     1372        case tpc_nil: assert(b_false);
     1373        case tpc_string: bp_sym = bi->boxed_string; break;
     1374        case tpc_resource:
     1375                cspan_print(expr->cspan);
     1376                printf(" Error: Cannot use ");
     1377                tdata_item_print(expr->titem);
     1378                printf(" as an object.\n");
     1379
     1380                stype_note_error(stype);
     1381                return expr;
     1382        }
     1383
     1384        /* Patch the code to box the primitive value */
     1385        box = stree_box_new();
     1386        box->arg = expr;
     1387        bexpr = stree_expr_new(ec_box);
     1388        bexpr->u.box = box;
     1389        bexpr->titem = tdata_item_new(tic_tobject);
     1390        tobject = tdata_object_new();
     1391        bexpr->titem->u.tobject = tobject;
     1392
     1393        tobject->csi = symbol_to_csi(bp_sym);
     1394        assert(tobject->csi != NULL);
     1395
     1396        return bexpr;
     1397}
     1398
     1399
    11011400
    11021401/** Determine if two type signatures are equal.
     
    12961595
    12971596        stree_symbol_t *outer_sym;
     1597        stree_ctor_t *ctor;
    12981598        stree_fun_t *fun;
    12991599        stree_prop_t *prop;
     
    13141614#endif
    13151615
     1616        /* Make compiler happy. */
     1617        args = NULL;
     1618        varg = NULL;
     1619
    13161620        switch (outer_sym->sc) {
     1621        case sc_ctor:
     1622                ctor = symbol_to_ctor(outer_sym);
     1623                assert(ctor != NULL);
     1624                args = &ctor->sig->args;
     1625                varg = ctor->sig->varg;
     1626                break;
    13171627        case sc_fun:
    13181628                fun = symbol_to_fun(outer_sym);
     
    13311641                        setter_arg = prop->setter_arg;
    13321642                break;
    1333         default:
     1643        case sc_csi:
     1644        case sc_deleg:
     1645        case sc_enum:
     1646        case sc_var:
    13341647                assert(b_false);
    13351648        }
  • uspace/app/sbi/src/stype.h

    r1317380 r640ffe6  
    3333
    3434void stype_module(stype_t *stype, stree_module_t *module);
     35void stype_ctor_header(stype_t *stype, stree_ctor_t *ctor);
    3536void stype_deleg(stype_t *stype, stree_deleg_t *deleg);
     37void stype_enum(stype_t *stype, stree_enum_t *enum_d);
    3638void stype_fun_header(stype_t *stype, stree_fun_t *fun);
    3739void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value);
     
    4244stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
    4345    tdata_item_t *dest);
     46stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr);
    4447
    4548tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg);
  • uspace/app/sbi/src/stype_expr.c

    r1317380 r640ffe6  
    4646#include <stdlib.h>
    4747#include <assert.h>
     48#include "cspan.h"
    4849#include "debug.h"
    4950#include "list.h"
     
    8586static void stype_binop_tobject(stype_t *stype, stree_binop_t *binop,
    8687    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
     88static void stype_binop_tenum(stype_t *stype, stree_binop_t *binop,
     89    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
     90static void stype_binop_tvref(stype_t *stype, stree_binop_t *binop,
     91    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem);
    8792
    8893static void stype_unop(stype_t *stype, stree_unop_t *unop,
     
    9297static void stype_new(stype_t *stype, stree_new_t *new,
    9398    tdata_item_t **rtitem);
     99static void stype_new_object_args(stype_t *stype, stree_new_t *new_op,
     100    tdata_item_t *obj_ti);
    94101
    95102static void stype_access(stype_t *stype, stree_access_t *access,
     
    101108static void stype_access_tarray(stype_t *stype, stree_access_t *access,
    102109    tdata_item_t *arg_ti, tdata_item_t **rtitem);
     110static void stype_access_tebase(stype_t *stype, stree_access_t *access,
     111    tdata_item_t *arg_ti, tdata_item_t **rtitem);
    103112
    104113static void stype_call(stype_t *stype, stree_call_t *call,
    105114    tdata_item_t **rtitem);
     115static void stype_call_args(stype_t *stype, cspan_t *cspan, list_t *farg_tis,
     116    tdata_item_t *fvarg_ti, list_t *args);
    106117
    107118static void stype_index(stype_t *stype, stree_index_t *index,
     
    133144
    134145#ifdef DEBUG_TYPE_TRACE
    135         printf("Type expression.\n");
     146        cspan_print(expr->cspan);
     147        printf(" Type expression.\n");
    136148#endif
    137149        /* Silence warning. */
     
    156168
    157169#ifdef DEBUG_TYPE_TRACE
    158         printf("Expression type is '");
     170        cspan_print(expr->cspan);
     171        printf(" Expression type is '");
    159172        tdata_item_print(et);
    160173        printf("'.\n");
     
    178191        stree_csi_t *csi;
    179192        stree_deleg_t *deleg;
     193        stree_enum_t *enum_d;
     194        tdata_ebase_t *tebase;
    180195        stree_fun_t *fun;
    181196
    182197#ifdef DEBUG_TYPE_TRACE
    183         printf("Evaluate type of name reference '%s'.\n",
     198        cspan_print(nameref->expr->cspan);
     199        printf(" Evaluate type of name reference '%s'.\n",
    184200            strtab_get_str(nameref->name->sid));
    185201#endif
     
    226242                /* Not found. */
    227243                if (stype->current_csi != NULL) {
    228                         printf("Error: Symbol '%s' not found in '",
     244                        cspan_print(nameref->expr->cspan);
     245                        printf(" Error: Symbol '%s' not found in '",
    229246                            strtab_get_str(nameref->name->sid));
    230247                        symbol_print_fqn(csi_to_symbol(stype->current_csi));
    231248                        printf("'.\n");
    232249                } else {
    233                         printf("Error: Symbol '%s' not found.\n",
     250                        cspan_print(nameref->expr->cspan);
     251                        printf(" Error: Symbol '%s' not found.\n",
    234252                            strtab_get_str(nameref->name->sid));
    235253                }
     
    260278                tobject->csi = csi;
    261279                break;
     280        case sc_ctor:
     281                /* It is not possible to reference a constructor explicitly. */
     282                assert(b_false);
    262283        case sc_deleg:
    263                 printf("referenced name is deleg\n");
    264284                deleg = symbol_to_deleg(sym);
    265285                assert(deleg != NULL);
     
    267287                stype_deleg(stype, deleg);
    268288                titem = deleg->titem;
     289                break;
     290        case sc_enum:
     291                enum_d = symbol_to_enum(sym);
     292                assert(enum_d != NULL);
     293
     294                titem = tdata_item_new(tic_tebase);
     295                tebase = tdata_ebase_new();
     296                titem->u.tebase = tebase;
     297
     298                /* This is an enum base reference. */
     299                tebase->enum_d = enum_d;
    269300                break;
    270301        case sc_fun:
     
    294325
    295326#ifdef DEBUG_TYPE_TRACE
    296         printf("Evaluate type of literal.\n");
     327        cspan_print(literal->expr->cspan);
     328        printf(" Evaluate type of literal.\n");
    297329#endif
    298330        (void) stype;
     
    322354    tdata_item_t **rtitem)
    323355{
     356        stree_csi_t *cur_csi;
     357        tdata_item_t *titem;
     358        tdata_object_t *tobject;
     359
    324360#ifdef DEBUG_TYPE_TRACE
    325         printf("Evaluate type of self reference.\n");
     361        cspan_print(self_ref->expr->cspan);
     362        printf(" Evaluate type of self reference.\n");
    326363#endif
    327364        (void) stype;
    328365        (void) self_ref;
    329366
    330         *rtitem = NULL;
     367        cur_csi = stype->proc_vr->proc->outer_symbol->outer_csi;
     368
     369        /* No global symbols should have procedures. */
     370        assert(cur_csi != NULL);
     371
     372        /* Construct type item. */
     373        titem = tdata_item_new(tic_tobject);
     374        tobject = tdata_object_new();
     375        titem->u.tobject = tobject;
     376
     377        tobject->static_ref = b_false;
     378        tobject->csi = cur_csi;
     379        list_init(&tobject->targs);
     380
     381        *rtitem = titem;
    331382}
    332383
     
    344395
    345396#ifdef DEBUG_TYPE_TRACE
    346         printf("Evaluate type of binary operation.\n");
     397        cspan_print(binop->expr->cspan);
     398        printf(" Evaluate type of binary operation.\n");
    347399#endif
    348400        stype_expr(stype, binop->arg1);
     
    352404        titem2 = binop->arg2->titem;
    353405
    354         if (titem1 == NULL || titem2 == NULL) {
    355                 printf("Error: Binary operand has no value.\n");
     406        if (titem1 == NULL) {
     407                cspan_print(binop->arg1->cspan);
     408                printf(" Error: Binary operand has no value.\n");
     409                stype_note_error(stype);
     410                *rtitem = stype_recovery_titem(stype);
     411                return;
     412        }
     413
     414        if (titem2 == NULL) {
     415                cspan_print(binop->arg2->cspan);
     416                printf(" Error: Binary operand has no value.\n");
    356417                stype_note_error(stype);
    357418                *rtitem = stype_recovery_titem(stype);
     
    366427        equal = tdata_item_equal(titem1, titem2);
    367428        if (equal != b_true) {
    368                 printf("Error: Binary operation arguments "
     429                cspan_print(binop->expr->cspan);
     430                printf(" Error: Binary operation arguments "
    369431                    "have different types ('");
    370432                tdata_item_print(titem1);
     
    384446                stype_binop_tobject(stype, binop, titem1, titem2, rtitem);
    385447                break;
     448        case tic_tenum:
     449                stype_binop_tenum(stype, binop, titem1, titem2, rtitem);
     450                break;
     451        case tic_tvref:
     452                stype_binop_tvref(stype, binop, titem1, titem2, rtitem);
     453                break;
    386454        default:
    387                 printf("Error: Binary operation on value which is not of a "
     455                cspan_print(binop->expr->cspan);
     456                printf(" Error: Binary operation on value which is not of a "
    388457                    "supported type (found '");
    389458                tdata_item_print(titem1);
     
    458527        case bo_mult:
    459528                /* Arithmetic -> error */
    460                 printf("Error: Binary operation (%d) on booleans.\n",
     529                cspan_print(binop->expr->cspan);
     530                printf(" Error: Binary operation (%d) on booleans.\n",
    461531                    binop->bc);
    462532                stype_note_error(stype);
    463533                *rtitem = stype_recovery_titem(stype);
    464534                return;
     535        case bo_and:
     536        case bo_or:
     537                /* Boolean -> boolean type */
     538                rtpc = tpc_bool;
     539                break;
    465540        }
    466541
     
    498573        case bo_minus:
    499574        case bo_mult:
    500                 /* Arithmetic -> error */
    501                 printf("Error: Binary operation (%d) on characters.\n",
     575        case bo_and:
     576        case bo_or:
     577                /* Arithmetic, boolean -> error */
     578                cspan_print(binop->expr->cspan);
     579                printf(" Error: Binary operation (%d) on characters.\n",
    502580                    binop->bc);
    503581                stype_note_error(stype);
     
    542620                rtpc = tpc_int;
    543621                break;
     622        case bo_and:
     623        case bo_or:
     624                /* Boolean -> error */
     625                cspan_print(binop->expr->cspan);
     626                printf(" Error: Binary operation (%d) on integers.\n",
     627                    binop->bc);
     628                stype_note_error(stype);
     629                rtpc = tpc_char;
     630                break;
    544631        }
    545632
     
    561648        (void) binop;
    562649
    563         printf("Unimplemented; Binary operation on nil.\n");
     650        cspan_print(binop->expr->cspan);
     651        printf(" Unimplemented: Binary operation on nil.\n");
    564652        stype_note_error(stype);
    565653        *rtitem = stype_recovery_titem(stype);
     
    578666        tdata_item_t *res_ti;
    579667
    580         if (binop->bc != bo_plus) {
    581                 printf("Unimplemented: Binary operation(%d) "
    582                     "on strings.\n", binop->bc);
    583                 stype_note_error(stype);
    584                 *rtitem = stype_recovery_titem(stype);
    585                 return;
    586         }
    587 
    588         rtpc = tpc_string;
     668        switch (binop->bc) {
     669        case bo_equal:
     670        case bo_notequal:
     671                /* Comparison -> boolean type */
     672                rtpc = tpc_bool;
     673                break;
     674        case bo_plus:
     675                /* Concatenation -> string type */
     676                rtpc = tpc_string;
     677                break;
     678
     679        case bo_lt:
     680        case bo_gt:
     681        case bo_lt_equal:
     682        case bo_gt_equal:
     683
     684        case bo_minus:
     685        case bo_mult:
     686        case bo_and:
     687        case bo_or:
     688                /* Ordering, arithmetic, boolean -> error */
     689                cspan_print(binop->expr->cspan);
     690                printf(" Error: Binary operation (%d) on strings.\n",
     691                    binop->bc);
     692                stype_note_error(stype);
     693                rtpc = tpc_char;
     694                break;
     695        }
    589696
    590697        res_ti = tdata_item_new(tic_tprimitive);
     
    608715        (void) binop;
    609716
    610         printf("Error: Cannot apply operator to resource type.\n");
     717        cspan_print(binop->expr->cspan);
     718        printf(" Error: Cannot apply operator to resource type.\n");
    611719        stype_note_error(stype);
    612720        rtpc = tpc_resource;
     
    645753                break;
    646754        default:
    647                 printf("Error: Binary operation (%d) on objects.\n",
     755                cspan_print(binop->expr->cspan);
     756                printf(" Error: Binary operation (%d) on objects.\n",
    648757                    binop->bc);
    649758                stype_note_error(stype);
     
    655764}
    656765
     766/** Type a binary operation with arguments of an enum type.
     767 *
     768 * @param stype         Static typing object
     769 * @param binop         Binary operation
     770 * @param ta            Type of first argument
     771 * @param tb            Type of second argument
     772 * @param rtitem        Place to store result type
     773 */
     774static void stype_binop_tenum(stype_t *stype, stree_binop_t *binop,
     775    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
     776{
     777        tdata_item_t *res_ti;
     778
     779        assert(ta->tic == tic_tenum);
     780        assert(tb->tic == tic_tenum);
     781
     782        switch (binop->bc) {
     783        case bo_equal:
     784        case bo_notequal:
     785                /* Comparison -> boolean type */
     786                res_ti = stype_boolean_titem(stype);
     787                break;
     788        default:
     789                cspan_print(binop->expr->cspan);
     790                printf(" Error: Binary operation (%d) on values of enum "
     791                    "type.\n", binop->bc);
     792                stype_note_error(stype);
     793                *rtitem = stype_recovery_titem(stype);
     794                return;
     795        }
     796
     797        *rtitem = res_ti;
     798}
     799
     800/** Type a binary operation with arguments of a variable type.
     801 *
     802 * @param stype         Static typing object
     803 * @param binop         Binary operation
     804 * @param ta            Type of first argument
     805 * @param tb            Type of second argument
     806 * @param rtitem        Place to store result type
     807 */
     808static void stype_binop_tvref(stype_t *stype, stree_binop_t *binop,
     809    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
     810{
     811        tdata_item_t *res_ti;
     812
     813        assert(ta->tic == tic_tvref || (ta->tic == tic_tprimitive &&
     814            ta->u.tprimitive->tpc == tpc_nil));
     815        assert(tb->tic == tic_tvref || (tb->tic == tic_tprimitive &&
     816            tb->u.tprimitive->tpc == tpc_nil));
     817
     818        switch (binop->bc) {
     819        case bo_equal:
     820        case bo_notequal:
     821                /* Comparison -> boolean type */
     822                res_ti = stype_boolean_titem(stype);
     823                break;
     824        default:
     825                cspan_print(binop->expr->cspan);
     826                printf(" Error: Binary operation (%d) on variable types.\n",
     827                    binop->bc);
     828                stype_note_error(stype);
     829                *rtitem = stype_recovery_titem(stype);
     830                return;
     831        }
     832
     833        *rtitem = res_ti;
     834}
    657835
    658836/** Type a unary operation.
     
    668846
    669847#ifdef DEBUG_TYPE_TRACE
    670         printf("Evaluate type of unary operation.\n");
     848        cspan_print(unop->expr->cspan);
     849        printf(" Evaluate type of unary operation.\n");
    671850#endif
    672851        stype_expr(stype, unop->arg);
     
    684863                break;
    685864        default:
    686                 printf("Error: Unary operation on value which is not of a "
     865                cspan_print(unop->arg->cspan);
     866                printf(" Error: Unary operation on value which is not of a "
    687867                    "supported type (found '");
    688868                tdata_item_print(titem);
     
    720900                break;
    721901        default:
    722                 printf("Error: Unary operator applied on unsupported "
     902                cspan_print(unop->arg->cspan);
     903                printf(" Error: Unary operator applied on unsupported "
    723904                    "primitive type %d.\n", ta->u.tprimitive->tpc);
    724905                stype_note_error(stype);
     
    743924{
    744925#ifdef DEBUG_TYPE_TRACE
     926        cspan_print(new_op->expr->cspan);
    745927        printf("Evaluate type of 'new' operation.\n");
    746928#endif
     
    754936                /* An error occured when evaluating the type expression. */
    755937                stype_note_error(stype);
    756         }
     938                *rtitem = stype_recovery_titem(stype);
     939                return;
     940        }
     941
     942        if ((*rtitem)->tic == tic_tobject)
     943                stype_new_object_args(stype, new_op, *rtitem);
     944}
     945
     946/** Type a new object operation arguments.
     947 *
     948 * @param stype         Static typing object
     949 * @param new_op        @c new operation
     950 */
     951static void stype_new_object_args(stype_t *stype, stree_new_t *new_op,
     952    tdata_item_t *obj_ti)
     953{
     954        stree_csi_t *csi;
     955        stree_ctor_t *ctor;
     956        stree_symbol_t *ctor_sym;
     957        stree_ident_t *ctor_ident;
     958        tdata_fun_sig_t *tsig;
     959
     960        assert(obj_ti->tic == tic_tobject);
     961        csi = obj_ti->u.tobject->csi;
     962        ctor_ident = stree_ident_new();
     963        ctor_ident->sid = strtab_get_sid(CTOR_IDENT);
     964
     965        /* Find constructor. */
     966        ctor_sym = symbol_search_csi_no_base(stype->program, csi,
     967            ctor_ident);
     968
     969        if (ctor_sym == NULL && !list_is_empty(&new_op->ctor_args)) {
     970                cspan_print(new_op->expr->cspan);
     971                printf(" Error: Passing arguments to 'new' but no "
     972                    "constructor found.\n");
     973                stype_note_error(stype);
     974                return;
     975        }
     976
     977        if (ctor_sym == NULL)
     978                return;
     979
     980        ctor = symbol_to_ctor(ctor_sym);
     981        assert(ctor != NULL);
     982
     983        /* Type constructor header if it has not been typed yet. */
     984        stype_ctor_header(stype, ctor);
     985        if (ctor->titem->tic == tic_ignore)
     986                return;
     987
     988        assert(ctor->titem->tic == tic_tfun);
     989        tsig = ctor->titem->u.tfun->tsig;
     990
     991        stype_call_args(stype, new_op->expr->cspan, &tsig->arg_ti,
     992            tsig->varg_ti, &new_op->ctor_args);
    757993}
    758994
     
    7691005
    7701006#ifdef DEBUG_TYPE_TRACE
    771         printf("Evaluate type of access operation.\n");
     1007        cspan_print(access->expr->cspan);
     1008        printf(" Evaluate type of access operation.\n");
    7721009#endif
    7731010        stype_expr(stype, access->arg);
     
    7751012
    7761013        if (arg_ti == NULL) {
    777                 printf("Error: Argument of access has no value.\n");
     1014                cspan_print(access->arg->cspan);
     1015                printf(" Error: Argument of access operation has no value.\n");
    7781016                stype_note_error(stype);
    7791017                *rtitem = stype_recovery_titem(stype);
     
    7921030                break;
    7931031        case tic_tdeleg:
    794                 printf("Error: Using '.' operator on a function.\n");
     1032                cspan_print(access->arg->cspan);
     1033                printf(" Error: Using '.' operator on a delegate.\n");
     1034                stype_note_error(stype);
     1035                *rtitem = stype_recovery_titem(stype);
     1036                break;
     1037        case tic_tebase:
     1038                stype_access_tebase(stype, access, arg_ti, rtitem);
     1039                break;
     1040        case tic_tenum:
     1041                cspan_print(access->arg->cspan);
     1042                printf(" Error: Using '.' operator on expression of enum "
     1043                    "type.\n");
    7951044                stype_note_error(stype);
    7961045                *rtitem = stype_recovery_titem(stype);
    7971046                break;
    7981047        case tic_tfun:
    799                 printf("Error: Using '.' operator on a delegate.\n");
     1048                cspan_print(access->arg->cspan);
     1049                printf(" Error: Using '.' operator on a function.\n");
    8001050                stype_note_error(stype);
    8011051                *rtitem = stype_recovery_titem(stype);
     
    8031053        case tic_tvref:
    8041054                /* Cannot allow this without some constraint. */
    805                 printf("Error: Using '.' operator on generic data.\n");
     1055                cspan_print(access->arg->cspan);
     1056                printf(" Error: Using '.' operator on generic data.\n");
    8061057                *rtitem = stype_recovery_titem(stype);
    8071058                break;
     
    8221073    tdata_item_t *arg_ti, tdata_item_t **rtitem)
    8231074{
    824         (void) stype;
    825         (void) access;
    826         (void) rtitem;
    827 
    828         printf("Error: Unimplemented: Accessing primitive type '");
    829         tdata_item_print(arg_ti);
    830         printf("'.\n");
    831         stype_note_error(stype);
    832         *rtitem = stype_recovery_titem(stype);
     1075        (void) arg_ti;
     1076
     1077        /* Box the value. */
     1078        access->arg = stype_box_expr(stype, access->arg);
     1079        if (access->arg->titem->tic == tic_ignore) {
     1080                *rtitem = stype_recovery_titem(stype);
     1081                return;
     1082        }
     1083
     1084        /* Access the boxed object. */
     1085        stype_access_tobject(stype, access, access->arg->titem, rtitem);
    8331086}
    8341087
     
    8451098        stree_symbol_t *member_sym;
    8461099        stree_var_t *var;
     1100        stree_enum_t *enum_d;
    8471101        stree_fun_t *fun;
    8481102        stree_prop_t *prop;
     
    8631117        if (member_sym == NULL) {
    8641118                /* No such member found. */
    865                 printf("Error: CSI '");
     1119                cspan_print(access->member_name->cspan);
     1120                printf(" Error: CSI '");
    8661121                symbol_print_fqn(csi_to_symbol(tobject->csi));
    8671122                printf("' has no member named '%s'.\n",
     
    8791134        switch (member_sym->sc) {
    8801135        case sc_csi:
    881                 printf("Error: Accessing object member which is nested "
     1136                cspan_print(access->member_name->cspan);
     1137                printf(" Error: Accessing object member which is nested "
    8821138                    "CSI.\n");
    8831139                stype_note_error(stype);
    8841140                *rtitem = stype_recovery_titem(stype);
    8851141                return;
     1142        case sc_ctor:
     1143                /* It is not possible to reference a constructor explicitly. */
     1144                assert(b_false);
    8861145        case sc_deleg:
    887                 printf("Error: Accessing object member which is a "
     1146                cspan_print(access->member_name->cspan);
     1147                printf(" Error: Accessing object member which is a "
    8881148                    "delegate.\n");
    8891149                stype_note_error(stype);
    8901150                *rtitem = stype_recovery_titem(stype);
    8911151                return;
     1152        case sc_enum:
     1153                enum_d = symbol_to_enum(member_sym);
     1154                assert(enum_d != NULL);
     1155                /* Type enum if it has not been typed yet. */
     1156                stype_enum(stype, enum_d);
     1157                mtitem = enum_d->titem;
     1158                break;
    8921159        case sc_fun:
    8931160                fun = symbol_to_fun(member_sym);
     
    9371204        (void) rtitem;
    9381205
    939         printf("Error: Unimplemented: Accessing array type '");
     1206        cspan_print(access->arg->cspan);
     1207        printf(" Error: Unimplemented: Accessing array type '");
    9401208        tdata_item_print(arg_ti);
    9411209        printf("'.\n");
     
    9441212}
    9451213
     1214/** Type an enum access operation.
     1215 *
     1216 * @param stype         Static typing object
     1217 * @param access        Member access operation
     1218 * @param arg_ti        Base type
     1219 * @param rtitem        Place to store result type
     1220*/
     1221static void stype_access_tebase(stype_t *stype, stree_access_t *access,
     1222    tdata_item_t *arg_ti, tdata_item_t **rtitem)
     1223{
     1224        tdata_ebase_t *tebase;
     1225        tdata_enum_t *tenum;
     1226        tdata_item_t *mtitem;
     1227        stree_embr_t *embr;
     1228
     1229#ifdef DEBUG_TYPE_TRACE
     1230        printf("Type an ebase access operation.\n");
     1231#endif
     1232        assert(arg_ti->tic == tic_tebase);
     1233        tebase = arg_ti->u.tebase;
     1234
     1235        /* Look for a member with the specified name. */
     1236        embr = stree_enum_find_mbr(tebase->enum_d, access->member_name);
     1237
     1238        if (embr == NULL) {
     1239                /* No such member found. */
     1240                cspan_print(access->member_name->cspan);
     1241                printf(" Error: Enum type '");
     1242                symbol_print_fqn(enum_to_symbol(tebase->enum_d));
     1243                printf("' has no member named '%s'.\n",
     1244                    strtab_get_str(access->member_name->sid));
     1245                stype_note_error(stype);
     1246                *rtitem = stype_recovery_titem(stype);
     1247                return;
     1248        }
     1249
     1250#ifdef DEBUG_RUN_TRACE
     1251        printf("Found member '%s'.\n",
     1252            strtab_get_str(access->member_name->sid));
     1253#endif
     1254
     1255        mtitem = tdata_item_new(tic_tenum);
     1256        tenum = tdata_enum_new();
     1257        mtitem->u.tenum = tenum;
     1258        tenum->enum_d = tebase->enum_d;
     1259
     1260        *rtitem = mtitem;
     1261}
     1262
     1263
    9461264/** Type a call operation.
    9471265 *
     
    9531271    tdata_item_t **rtitem)
    9541272{
    955         list_node_t *fargt_n;
    956         tdata_item_t *farg_ti;
    957         tdata_item_t *varg_ti;
    958 
    959         list_node_t *arg_n;
    960         stree_expr_t *arg;
    961         stree_expr_t *carg;
    962 
    9631273        tdata_item_t *fun_ti;
    9641274        tdata_fun_sig_t *tsig;
    9651275
    966         int cnt;
    967 
    9681276#ifdef DEBUG_TYPE_TRACE
    969         printf("Evaluate type of call operation.\n");
     1277        cspan_print(call->expr->cspan);
     1278        printf(" Evaluate type of call operation.\n");
    9701279#endif
    9711280        /* Type the function */
     
    9861295                return;
    9871296        default:
    988                 printf("Error: Calling something which is not a function ");
     1297                cspan_print(call->fun->cspan);
     1298                printf(" Error: Calling something which is not a function ");
    9891299                printf("(found '");
    9901300                tdata_item_print(fun_ti);
     
    9951305        }
    9961306
    997         /* Type and check the arguments. */
    998         fargt_n = list_first(&tsig->arg_ti);
    999         arg_n = list_first(&call->args);
     1307        /* Type call arguments. */
     1308        stype_call_args(stype, call->expr->cspan, &tsig->arg_ti, tsig->varg_ti,
     1309            &call->args);
     1310
     1311        if (tsig->rtype != NULL) {
     1312                /* XXX Might be better to clone here. */
     1313                *rtitem = tsig->rtype;
     1314        } else {
     1315                *rtitem = NULL;
     1316        }
     1317}
     1318
     1319/** Type call arguments.
     1320 *
     1321 * Type arguments in call to a function or constructor.
     1322 *
     1323 * @param stype         Static typing object
     1324 * @param cpsan         Cspan to print in case of error.
     1325 * @param farg_tis      Formal argument types (list of tdata_item_t)
     1326 * @param args          Real arguments (list of stree_expr_t)
     1327 */
     1328static void stype_call_args(stype_t *stype, cspan_t *cspan, list_t *farg_tis,
     1329    tdata_item_t *fvarg_ti, list_t *args)
     1330{
     1331        list_node_t *fargt_n;
     1332        tdata_item_t *farg_ti;
     1333        tdata_item_t *varg_ti;
     1334
     1335        list_node_t *arg_n;
     1336        stree_expr_t *arg;
     1337        stree_expr_t *carg;
     1338
     1339        int cnt;
     1340
     1341        /* Type and check regular arguments. */
     1342        fargt_n = list_first(farg_tis);
     1343        arg_n = list_first(args);
    10001344
    10011345        cnt = 0;
     
    10081352                if (farg_ti == NULL) {
    10091353                        /* Skip the check */
    1010                         fargt_n = list_next(&tsig->arg_ti, fargt_n);
    1011                         arg_n = list_next(&call->args, arg_n);
     1354                        fargt_n = list_next(farg_tis, fargt_n);
     1355                        arg_n = list_next(args, arg_n);
    10121356                        continue;
    10131357                }
     
    10191363                list_node_setdata(arg_n, carg);
    10201364
    1021                 fargt_n = list_next(&tsig->arg_ti, fargt_n);
    1022                 arg_n = list_next(&call->args, arg_n);
     1365                fargt_n = list_next(farg_tis, fargt_n);
     1366                arg_n = list_next(args, arg_n);
    10231367        }
    10241368
    10251369        /* Type and check variadic arguments. */
    1026         if (tsig->varg_ti != NULL) {
     1370        if (fvarg_ti != NULL) {
    10271371                /* Obtain type of packed argument. */
    1028                 farg_ti = tsig->varg_ti;
     1372                farg_ti = fvarg_ti;
    10291373
    10301374                /* Get array element type */
     
    10421386                        list_node_setdata(arg_n, carg);
    10431387
    1044                         arg_n = list_next(&call->args, arg_n);
     1388                        arg_n = list_next(args, arg_n);
    10451389                }
    10461390        }
    10471391
    10481392        if (fargt_n != NULL) {
    1049                 printf("Error: Too few arguments to function.\n");
     1393                cspan_print(cspan);
     1394                printf(" Error: Too few arguments.\n");
    10501395                stype_note_error(stype);
    10511396        }
    10521397
    10531398        if (arg_n != NULL) {
    1054                 printf("Error: Too many arguments to function.\n");
    1055                 stype_note_error(stype);
    1056         }
    1057 
    1058         if (tsig->rtype != NULL) {
    1059                 /* XXX Might be better to clone here. */
    1060                 *rtitem = tsig->rtype;
    1061         } else {
    1062                 *rtitem = NULL;
     1399                cspan_print(cspan);
     1400                printf(" Error: Too many arguments.\n");
     1401                stype_note_error(stype);
    10631402        }
    10641403}
     
    10781417
    10791418#ifdef DEBUG_TYPE_TRACE
    1080         printf("Evaluate type of index operation.\n");
     1419        cspan_print(index->expr->cspan);
     1420        printf(" Evaluate type of index operation.\n");
    10811421#endif
    10821422        stype_expr(stype, index->base);
     
    11031443                break;
    11041444        case tic_tdeleg:
    1105                 printf("Error: Indexing a delegate.\n");
     1445                cspan_print(index->base->cspan);
     1446                printf(" Error: Indexing a delegate.\n");
     1447                stype_note_error(stype);
     1448                *rtitem = stype_recovery_titem(stype);
     1449                break;
     1450        case tic_tebase:
     1451                cspan_print(index->base->cspan);
     1452                printf(" Error: Indexing an enum declaration.\n");
     1453                stype_note_error(stype);
     1454                *rtitem = stype_recovery_titem(stype);
     1455                break;
     1456        case tic_tenum:
     1457                cspan_print(index->base->cspan);
     1458                printf(" Error: Indexing an enum value.\n");
    11061459                stype_note_error(stype);
    11071460                *rtitem = stype_recovery_titem(stype);
    11081461                break;
    11091462        case tic_tfun:
    1110                 printf("Error: Indexing a function.\n");
     1463                cspan_print(index->base->cspan);
     1464                printf(" Error: Indexing a function.\n");
    11111465                stype_note_error(stype);
    11121466                *rtitem = stype_recovery_titem(stype);
     
    11141468        case tic_tvref:
    11151469                /* Cannot allow this without some constraint. */
    1116                 printf("Error: Indexing generic data.\n");
     1470                cspan_print(index->base->cspan);
     1471                printf(" Error: Indexing generic data.\n");
    11171472                *rtitem = stype_recovery_titem(stype);
    11181473                break;
     
    11491504        }
    11501505
    1151         printf("Error: Indexing primitive type '");
     1506        cspan_print(index->base->cspan);
     1507        printf(" Error: Indexing primitive type '");
    11521508        tdata_item_print(base_ti);
    11531509        printf("'.\n");
     
    11761532
    11771533#ifdef DEBUG_TYPE_TRACE
    1178         printf("Indexing object type '");
     1534        cspan_print(index->expr->cspan);
     1535        printf(" Indexing object type '");
    11791536        tdata_item_print(base_ti);
    11801537        printf("'.\n");
     
    11901547
    11911548        if (idx_sym == NULL) {
    1192                 printf("Error: Indexing object of type '");
     1549                cspan_print(index->base->cspan);
     1550                printf(" Error: Indexing object of type '");
    11931551                tdata_item_print(base_ti);
    11941552                printf("' which does not have an indexer.\n");
     
    12461604                    arg->titem->u.tprimitive->tpc != tpc_int) {
    12471605
    1248                         printf("Error: Array index is not an integer.\n");
     1606                        cspan_print(arg->cspan);
     1607                        printf(" Error: Array index is not an integer.\n");
    12491608                        stype_note_error(stype);
    12501609                }
     
    12541613
    12551614        if (arg_count != base_ti->u.tarray->rank) {
    1256                 printf("Error: Using %d indices with array of rank %d.\n",
     1615                cspan_print(index->expr->cspan);
     1616                printf(" Error: Using %d indices with array of rank %d.\n",
    12571617                    arg_count, base_ti->u.tarray->rank);
    12581618                stype_note_error(stype);
     
    12741634
    12751635#ifdef DEBUG_TYPE_TRACE
    1276         printf("Evaluate type of assignment.\n");
     1636        cspan_print(assign->expr->cspan);
     1637        printf(" Evaluate type of assignment.\n");
    12771638#endif
    12781639        stype_expr(stype, assign->dest);
     
    12971658
    12981659#ifdef DEBUG_TYPE_TRACE
    1299         printf("Evaluate type of @c as conversion.\n");
     1660        cspan_print(as_op->expr->cspan);
     1661        printf(" Evaluate type of @c as conversion.\n");
    13001662#endif
    13011663        stype_expr(stype, as_op->arg);
     
    13041666        /* Check that target type is derived from argument type. */
    13051667        if (tdata_is_ti_derived_from_ti(titem, as_op->arg->titem) != b_true) {
    1306                 printf("Error: Target of 'as' operator '");
     1668                cspan_print(as_op->dtype->cspan);
     1669                printf(" Error: Target of 'as' operator '");
    13071670                tdata_item_print(titem);
    13081671                printf("' is not derived from '");
     
    13321695
    13331696#ifdef DEBUG_TYPE_TRACE
    1334         printf("Evaluate type of boxing operation.\n");
     1697        cspan_print(box->expr->cspan);
     1698        printf(" Evaluate type of boxing operation.\n");
    13351699#endif
    13361700        bi = stype->program->builtin;
  • uspace/app/sbi/src/stype_t.h

    r1317380 r640ffe6  
    5454        /** Block activation records */
    5555        list_t block_vr; /* of run_block_ar_t */
     56
     57        /** Number of active breakable statements (for break checking). */
     58        int bstat_cnt;
    5659} stype_proc_vr_t;
    5760
  • uspace/app/sbi/src/symbol.c

    r1317380 r640ffe6  
    4242static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
    4343    stree_ident_t *name, stree_csi_t *csi);
     44static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr);
    4445static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
    4546
     
    8889/** Lookup symbol reference in CSI.
    8990 *
     91 * XXX These functions should take just an sid, not a full identifier.
     92 * Sometimes we search for a name which has no associated cspan.
     93 *
    9094 * @param prog  Program to look in
    9195 * @param scope CSI in @a prog which is the base for references
     
    128132    stree_csi_t *scope, stree_ident_t *name)
    129133{
    130         list_node_t *node;
    131         stree_csimbr_t *csimbr;
    132         stree_symbol_t *symbol;
    133         stree_ident_t *mbr_name;
    134134        stree_symbol_t *base_csi_sym;
    135135        stree_csi_t *base_csi;
    136 
    137         (void) prog;
     136        stree_symbol_t *symbol;
    138137
    139138        /* Look in new members in this class. */
    140 
    141         node = list_first(&scope->members);
    142         while (node != NULL) {
    143                 csimbr = list_node_data(node, stree_csimbr_t *);
    144 
    145                 /* Keep compiler happy. */
    146                 mbr_name = NULL;
    147 
    148                 switch (csimbr->cc) {
    149                 case csimbr_csi: mbr_name = csimbr->u.csi->name; break;
    150                 case csimbr_deleg: mbr_name = csimbr->u.deleg->name; break;
    151                 case csimbr_fun: mbr_name = csimbr->u.fun->name; break;
    152                 case csimbr_var: mbr_name = csimbr->u.var->name; break;
    153                 case csimbr_prop: mbr_name = csimbr->u.prop->name; break;
    154                 }
    155 
    156                 if (name->sid == mbr_name->sid) {
    157                         /* Match */
    158                         switch (csimbr->cc) {
    159                         case csimbr_csi:
    160                                 symbol = csi_to_symbol(csimbr->u.csi);
    161                                 break;
    162                         case csimbr_deleg:
    163                                 symbol = deleg_to_symbol(csimbr->u.deleg);
    164                                 break;
    165                         case csimbr_fun:
    166                                 symbol = fun_to_symbol(csimbr->u.fun);
    167                                 break;
    168                         case csimbr_var:
    169                                 symbol = var_to_symbol(csimbr->u.var);
    170                                 break;
    171                         case csimbr_prop:
    172                                 symbol = prop_to_symbol(csimbr->u.prop);
    173                                 break;
    174                         default:
    175                                 assert(b_false);
    176                         }
    177                         return symbol;
    178                 }
    179                 node = list_next(&scope->members, node);
    180         }
     139        symbol = symbol_search_csi_no_base(prog, scope, name);
     140        if (symbol != NULL)
     141                return symbol;
    181142
    182143        /* Try inherited members. */
     
    194155}
    195156
     157/** Look for symbol strictly in CSI.
     158 *
     159 * Look for symbol in definition of a CSI and its ancestors. (But not
     160 * in lexically enclosing CSI or in base CSI.)
     161 *
     162 * @param prog  Program to look in
     163 * @param scope CSI in which to look
     164 * @param name  Identifier of the symbol
     165 *
     166 * @return      Symbol or @c NULL if symbol not found.
     167 */
     168stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog,
     169    stree_csi_t *scope, stree_ident_t *name)
     170{
     171        list_node_t *node;
     172        stree_csimbr_t *csimbr;
     173        stree_ident_t *mbr_name;
     174
     175        (void) prog;
     176
     177        /* Look in new members in this class. */
     178
     179        node = list_first(&scope->members);
     180        while (node != NULL) {
     181                csimbr = list_node_data(node, stree_csimbr_t *);
     182                mbr_name = stree_csimbr_get_name(csimbr);
     183
     184                if (name->sid == mbr_name->sid) {
     185                        /* Match */
     186                        return csimbr_to_symbol(csimbr);
     187                }
     188
     189                node = list_next(&scope->members, node);
     190        }
     191        /* No match */
     192        return NULL;
     193}
     194
    196195/** Look for symbol in global scope.
    197196 *
     
    207206        stree_modm_t *modm;
    208207        stree_symbol_t *symbol;
     208        stree_ident_t *mbr_name;
    209209
    210210        node = list_first(&prog->module->members);
    211211        while (node != NULL) {
    212212                modm = list_node_data(node, stree_modm_t *);
    213                 if (name->sid == modm->u.csi->name->sid) {
     213
     214                switch (modm->mc) {
     215                case mc_csi: mbr_name = modm->u.csi->name; break;
     216                case mc_enum: mbr_name = modm->u.enum_d->name; break;
     217                }
     218
     219                if (name->sid == mbr_name->sid) {
    214220                        /* Match */
    215221                        switch (modm->mc) {
     
    217223                                symbol = csi_to_symbol(modm->u.csi);
    218224                                break;
    219                         default:
    220                                 assert(b_false);
     225                        case mc_enum:
     226                                symbol = enum_to_symbol(modm->u.enum_d);
     227                                break;
    221228                        }
    222229                        return symbol;
     
    346353}
    347354
     355/** Convert symbol to enum (base to derived).
     356 *
     357 * @param symbol        Symbol
     358 * @return              Enum or @c NULL if symbol is not a enum
     359 */
     360stree_enum_t *symbol_to_enum(stree_symbol_t *symbol)
     361{
     362        if (symbol->sc != sc_enum)
     363                return NULL;
     364
     365        return symbol->u.enum_d;
     366}
     367
     368/** Convert enum to symbol (derived to base).
     369 *
     370 * @param deleg         Enum
     371 * @return              Symbol
     372 */
     373stree_symbol_t *enum_to_symbol(stree_enum_t *enum_d)
     374{
     375        assert(enum_d->symbol);
     376        return enum_d->symbol;
     377}
     378
    348379/** Convert symbol to CSI (base to derived).
    349380 *
     
    370401}
    371402
     403/** Convert symbol to constructor (base to derived).
     404 *
     405 * @param symbol        Symbol
     406 * @return              Constructor or @c NULL if symbol is not a constructor
     407 */
     408stree_ctor_t *symbol_to_ctor(stree_symbol_t *symbol)
     409{
     410        if (symbol->sc != sc_ctor)
     411                return NULL;
     412
     413        return symbol->u.ctor;
     414}
     415
     416/** Convert constructor to symbol (derived to base).
     417 *
     418 * @param ctor          Constructor
     419 * @return              Symbol
     420 */
     421stree_symbol_t *ctor_to_symbol(stree_ctor_t *ctor)
     422{
     423        assert(ctor->symbol);
     424        return ctor->symbol;
     425}
     426
     427
    372428/** Convert symbol to function (base to derived).
    373429 *
     
    430486        return symbol->u.prop;
    431487}
     488
     489/** Get symbol from CSI member.
     490 *
     491 * A symbol corresponds to any CSI member. Return it.
     492 *
     493 * @param csimbr        CSI member
     494 * @return              Symbol
     495 */
     496static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
     497{
     498        stree_symbol_t *symbol;
     499
     500        /* Keep compiler happy. */
     501        symbol = NULL;
     502
     503        /* Match */
     504        switch (csimbr->cc) {
     505        case csimbr_csi:
     506                symbol = csi_to_symbol(csimbr->u.csi);
     507                break;
     508        case csimbr_ctor:
     509                symbol = ctor_to_symbol(csimbr->u.ctor);
     510                break;
     511        case csimbr_deleg:
     512                symbol = deleg_to_symbol(csimbr->u.deleg);
     513                break;
     514        case csimbr_enum:
     515                symbol = enum_to_symbol(csimbr->u.enum_d);
     516                break;
     517        case csimbr_fun:
     518                symbol = fun_to_symbol(csimbr->u.fun);
     519                break;
     520        case csimbr_var:
     521                symbol = var_to_symbol(csimbr->u.var);
     522                break;
     523        case csimbr_prop:
     524                symbol = prop_to_symbol(csimbr->u.prop);
     525                break;
     526        }
     527
     528        return symbol;
     529}
     530
    432531
    433532/** Convert property to symbol (derived to base).
     
    472571        switch (symbol->sc) {
    473572        case sc_csi: ident = symbol->u.csi->name; break;
     573        case sc_ctor: ident = symbol->u.ctor->name; break;
    474574        case sc_deleg: ident = symbol->u.deleg->name; break;
     575        case sc_enum: ident = symbol->u.enum_d->name; break;
    475576        case sc_fun: ident = symbol->u.fun->name; break;
    476577        case sc_var: ident = symbol->u.var->name; break;
  • uspace/app/sbi/src/symbol.h

    r1317380 r640ffe6  
    3838stree_symbol_t *symbol_search_csi(stree_program_t *prog, stree_csi_t *scope,
    3939    stree_ident_t *name);
     40stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog,
     41    stree_csi_t *scope, stree_ident_t *name);
    4042stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name);
    4143
     
    4446stree_csi_t *symbol_to_csi(stree_symbol_t *symbol);
    4547stree_symbol_t *csi_to_symbol(stree_csi_t *csi);
     48stree_ctor_t *symbol_to_ctor(stree_symbol_t *symbol);
     49stree_symbol_t *ctor_to_symbol(stree_ctor_t *ctor);
     50stree_enum_t *symbol_to_enum(stree_symbol_t *symbol);
     51stree_symbol_t *enum_to_symbol(stree_enum_t *enum_d);
    4652stree_fun_t *symbol_to_fun(stree_symbol_t *symbol);
    4753stree_symbol_t *fun_to_symbol(stree_fun_t *fun);
  • uspace/app/sbi/src/tdata.c

    r1317380 r640ffe6  
    4848static void tdata_item_subst_tdeleg(tdata_deleg_t *torig,
    4949    tdata_tvv_t *tvv, tdata_item_t **res);
     50static void tdata_item_subst_tebase(tdata_ebase_t *tebase,
     51    tdata_tvv_t *tvv, tdata_item_t **res);
     52static void tdata_item_subst_tenum(tdata_enum_t *tenum,
     53    tdata_tvv_t *tvv, tdata_item_t **res);
    5054static void tdata_item_subst_tfun(tdata_fun_t *torig,
    5155    tdata_tvv_t *tvv, tdata_item_t **res);
     
    6064static void tdata_tarray_print(tdata_array_t *tarray);
    6165static void tdata_tdeleg_print(tdata_deleg_t *tdeleg);
     66static void tdata_tebase_print(tdata_ebase_t *tebase);
     67static void tdata_tenum_print(tdata_enum_t *tenum);
    6268static void tdata_tfun_print(tdata_fun_t *tfun);
    6369static void tdata_tvref_print(tdata_vref_t *tvref);
     
    157163                return tdata_item_equal(a->u.tarray->base_ti,
    158164                    b->u.tarray->base_ti);
     165        case tic_tenum:
     166                /* Check if both use the same enum definition. */
     167                return (a->u.tenum->enum_d == b->u.tenum->enum_d);
    159168        case tic_tvref:
    160169                /* Check if both refer to the same type argument. */
     
    196205                tdata_item_subst_tdeleg(ti->u.tdeleg, tvv, res);
    197206                break;
     207        case tic_tebase:
     208                tdata_item_subst_tebase(ti->u.tebase, tvv, res);
     209                break;
     210        case tic_tenum:
     211                tdata_item_subst_tenum(ti->u.tenum, tvv, res);
     212                break;
    198213        case tic_tfun:
    199214                tdata_item_subst_tfun(ti->u.tfun, tvv, res);
     
    313328}
    314329
     330/** Substitute type variables in a enum-base type item.
     331 *
     332 * @param torig Type item to substitute into.
     333 * @param tvv   Type variable valuation (values of type variables).
     334 * @param res   Place to store pointer to new type item.
     335 */
     336static void tdata_item_subst_tebase(tdata_ebase_t *tebase,
     337    tdata_tvv_t *tvv, tdata_item_t **res)
     338{
     339        tdata_ebase_t *tnew;
     340
     341        (void) tvv;
     342
     343        /* Plain copy */
     344        tnew = tdata_ebase_new();
     345        *res = tdata_item_new(tic_tebase);
     346        (*res)->u.tebase = tebase;
     347}
     348
     349/** Substitute type variables in a enum type item.
     350 *
     351 * @param torig Type item to substitute into.
     352 * @param tvv   Type variable valuation (values of type variables).
     353 * @param res   Place to store pointer to new type item.
     354 */
     355static void tdata_item_subst_tenum(tdata_enum_t *tenum,
     356    tdata_tvv_t *tvv, tdata_item_t **res)
     357{
     358        tdata_enum_t *tnew;
     359
     360        (void) tvv;
     361
     362        /* Plain copy */
     363        tnew = tdata_enum_new();
     364        *res = tdata_item_new(tic_tenum);
     365        (*res)->u.tenum = tenum;
     366}
     367
    315368/** Substitute type variables in a functional type item.
    316369 *
     
    417470        case tic_tdeleg:
    418471                tdata_tdeleg_print(titem->u.tdeleg);
     472                break;
     473        case tic_tebase:
     474                tdata_tebase_print(titem->u.tebase);
     475                break;
     476        case tic_tenum:
     477                tdata_tenum_print(titem->u.tenum);
    419478                break;
    420479        case tic_tfun:
     
    497556}
    498557
     558/** Print enum-base type item.
     559 *
     560 * @param tebase                Enum-base type item
     561 */
     562static void tdata_tebase_print(tdata_ebase_t *tebase)
     563{
     564        stree_symbol_t *enum_sym;
     565
     566        enum_sym = enum_to_symbol(tebase->enum_d);
     567
     568        printf("typeref(");
     569        symbol_print_fqn(enum_sym);
     570        printf(")");
     571}
     572
     573/** Print enum type item.
     574 *
     575 * @param tenum         Enum type item
     576 */
     577static void tdata_tenum_print(tdata_enum_t *tenum)
     578{
     579        stree_symbol_t *enum_sym;
     580
     581        enum_sym = enum_to_symbol(tenum->enum_d);
     582        symbol_print_fqn(enum_sym);
     583}
     584
    499585/** Print function type item.
    500586 *
     
    624710}
    625711
     712/** Allocate new enum-base type item.
     713 *
     714 * @return      New enum type item
     715 */
     716tdata_ebase_t *tdata_ebase_new(void)
     717{
     718        tdata_ebase_t *tebase;
     719
     720        tebase = calloc(1, sizeof(tdata_ebase_t));
     721        if (tebase == NULL) {
     722                printf("Memory allocation failed.\n");
     723                exit(1);
     724        }
     725
     726        return tebase;
     727}
     728
     729/** Allocate new enum type item.
     730 *
     731 * @return      New enum type item
     732 */
     733tdata_enum_t *tdata_enum_new(void)
     734{
     735        tdata_enum_t *tenum;
     736
     737        tenum = calloc(1, sizeof(tdata_enum_t));
     738        if (tenum == NULL) {
     739                printf("Memory allocation failed.\n");
     740                exit(1);
     741        }
     742
     743        return tenum;
     744}
     745
    626746/** Allocate new functional type item.
    627747 *
     
    707827}
    708828
    709 /** Set tyoe variable value.
     829/** Set type variable value.
    710830 *
    711831 * Sets the value of variable with name SID @a name in type variable
  • uspace/app/sbi/src/tdata.h

    r1317380 r640ffe6  
    3737tdata_primitive_t *tdata_primitive_new(tprimitive_class_t tpc);
    3838tdata_deleg_t *tdata_deleg_new(void);
     39tdata_ebase_t *tdata_ebase_new(void);
     40tdata_enum_t *tdata_enum_new(void);
    3941tdata_fun_t *tdata_fun_new(void);
    4042tdata_vref_t *tdata_vref_new(void);
  • uspace/app/sbi/src/tdata_t.h

    r1317380 r640ffe6  
    104104} tdata_deleg_t;
    105105
     106/** Enum-base type.
     107 *
     108 * Type for expression which reference an enum declaration. In run time
     109 * enum type reference is represented by @c rdata_deleg_t. (Which is used
     110 * for any symbol references).
     111 */
     112typedef struct {
     113        /** Enum definition */
     114        struct stree_enum *enum_d;
     115} tdata_ebase_t;
     116
     117/** Enum type. */
     118typedef struct {
     119        /** Enum definition */
     120        struct stree_enum *enum_d;
     121} tdata_enum_t;
     122
    106123/** Functional type. */
    107124typedef struct {
     
    128145        /** Delegate type item */
    129146        tic_tdeleg,
     147        /** Enum-base type item */
     148        tic_tebase,
     149        /** Enum type item */
     150        tic_tenum,
    130151        /** Function type item */
    131152        tic_tfun,
     
    145166                tdata_array_t *tarray;
    146167                tdata_deleg_t *tdeleg;
     168                tdata_ebase_t *tebase;
     169                tdata_enum_t *tenum;
    147170                tdata_fun_t *tfun;
    148171                tdata_vref_t *tvref;
  • uspace/dist/src/sysel/demos/htxtfile.sy

    r1317380 r640ffe6  
    4343                out_file.OpenWrite("/out.txt");
    4444
    45                 while in_file.EOF != 1 do
     45                while not in_file.EOF do
    4646                        line = in_file.ReadLine();
    4747                        Builtin.WriteLine(name + ": " + line);
  • uspace/dist/src/sysel/demos/list.sy

    r1317380 r640ffe6  
    3333
    3434                list = new List/int();
    35                 list.Init();
    3635
    3736                list.Append(5);
     
    4443                n = list.First;
    4544                while n != nil do
    46                         Builtin.WriteLine(n.Value);
     45                        Builtin.WriteLine(n.Data);
    4746                        n = n.Next;
    4847                end
  • uspace/dist/src/sysel/demos/string.sy

    r1317380 r640ffe6  
    3939                        i = i + 1;
    4040                end
     41
     42                Builtin.WriteLine("Abracadabra".Slice(2, 4));
    4143        end
    4244end
  • uspace/dist/src/sysel/demos/varargs.sy

    r1317380 r640ffe6  
    3535        fun Print(args : string[], packed) is
    3636                var i : int;
    37                 var error : int;
     37                var error : bool;
    3838
    39                 error = 0;
     39                error = false;
    4040                i = 0;
    41                 while error == 0 do
     41                while not error do
    4242                        -- This is definitely the wrong way to determine
    4343                        -- array bounds, but until a better one is
     
    4646                                Builtin.WriteLine(args[i]);
    4747                        except e : Error.OutOfBounds do
    48                                 error = 1;
     48                                error = true;
    4949                        end
    5050
  • uspace/dist/src/sysel/lib/boxed.sy

    r1317380 r640ffe6  
    4646class String is
    4747        var Value : string;
     48
     49        fun get_length() : int, builtin;
     50
     51        -- Length of string.
     52        prop Length : int is
     53                get is
     54                        return get_length();
     55                end
     56        end
     57
     58        -- Slice (sub-string).
     59        fun Slice(start : int; length : int) : string, builtin;
    4860end
  • uspace/dist/src/sysel/lib/libflist

    r1317380 r640ffe6  
    22boxed.sy
    33list.sy
     4map.sy
  • uspace/dist/src/sysel/lib/list.sy

    r1317380 r640ffe6  
    3131        var head : ListNode/t;
    3232
    33         -- Initialize list.
    34         fun Init() is
     33        -- New empty list.
     34        new() is
    3535                head = new ListNode/t();
    3636                head.prev = head;
     
    4646
    4747                n = new ListNode/t();
    48                 n.value = data;
     48                n.data = data;
    4949
    5050                n.prev = ntl;
     
    7474
    7575class ListNode/t is
    76         var value : t;
     76        var data : t;
    7777
    7878        var prev : ListNode/t;
     
    8080        var head : ListNode/t;
    8181
    82         -- Value stored in this node.
    83         prop Value : t is
     82        -- Data stored in this node.
     83        prop Data : t is
    8484                get is
    85                         return value;
     85                        return data;
    8686                end
    8787        end
     
    9999                        return get_next();
    100100                end
     101        end
     102
     103        -- Remove node from list.
     104        fun Remove() is
     105                var p : ListNode/t;
     106                var n : ListNode/t;
     107
     108                p = prev; n = next;
     109                p.next = n;
     110                n.prev = p;
     111
     112                prev = nil;
     113                next = nil;
    101114        end
    102115
Note: See TracChangeset for help on using the changeset viewer.