Changeset 94d484a in mainline


Ignore:
Timestamp:
2010-03-07T17:45:33Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d0febca
Parents:
fa36f29
Message:

Update SBI to rev. 90.

Location:
uspace
Files:
10 added
24 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/Makefile

    rfa36f29 r94d484a  
    3434
    3535SOURCES = \
     36        src/os/helenos.c \
    3637        src/ancr.c \
    3738        src/builtin.c \
     
    4748        src/run.c \
    4849        src/run_expr.c \
     50        src/run_texpr.c \
    4951        src/stree.c \
    5052        src/strtab.c \
  • uspace/app/sbi/src/ancr.c

    rfa36f29 r94d484a  
    151151                /* Process base CSI. */
    152152                ancr_csi_process(prog, base_csi);
     153        } else {
     154                base_csi = NULL;
    153155        }
    154156
     157        /* Store base CSI and update node state. */
    155158        node->ancr_state = ws_visited;
     159        node->base_csi = base_csi;
    156160}
    157161
  • uspace/app/sbi/src/builtin.c

    rfa36f29 r94d484a  
    3434#include "list.h"
    3535#include "mytypes.h"
     36#include "os/os.h"
    3637#include "run.h"
    3738#include "stree.h"
    3839#include "strtab.h"
     40#include "symbol.h"
    3941
    4042#include "builtin.h"
    4143
     44static stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, char *name);
     45static void builtin_fun_add_arg(stree_symbol_t *fun_sym, char *name);
     46static void builtin_fun_add_vararg(stree_symbol_t *fun_sym, char *name);
     47
    4248static void builtin_write_line(run_t *run);
     49static void builtin_exec(run_t *run);
    4350
    4451static stree_symbol_t *bi_write_line;
     52static stree_symbol_t *bi_exec;
    4553
    4654/** Declare builtin symbols in the program.
     
    5361        stree_csi_t *csi;
    5462        stree_ident_t *ident;
    55         stree_csimbr_t *csimbr;
    56         stree_fun_t *fun;
    57         stree_fun_arg_t *fun_arg;
    5863        stree_symbol_t *symbol;
    5964
     
    7681
    7782        /* Declare builtin functions. */
    78         ident = stree_ident_new();
    79         ident->sid = strtab_get_sid("WriteLine");
    80 
    81         fun = stree_fun_new();
    82         fun->name = ident;
    83         fun->body = NULL;
    84         list_init(&fun->args);
    85 
    86         csimbr = stree_csimbr_new(csimbr_fun);
    87         csimbr->u.fun = fun;
    88 
    89         symbol = stree_symbol_new(sc_fun);
    90         symbol->u.fun = fun;
    91         symbol->outer_csi = csi;
    92         fun->symbol = symbol;
    93 
    94         list_append(&csi->members, csimbr);
    95 
    96         fun_arg = stree_fun_arg_new();
    97         fun_arg->name = stree_ident_new();
    98         fun_arg->name->sid = strtab_get_sid("arg");
    99         fun_arg->type = NULL; /* XXX */
    100 
    101         list_append(&fun->args, fun_arg);
    102 
    103         bi_write_line = symbol;
     83
     84        bi_write_line = builtin_declare_fun(csi, "WriteLine");
     85        builtin_fun_add_arg(bi_write_line, "arg");
     86
     87        bi_exec = builtin_declare_fun(csi, "Exec");
     88        builtin_fun_add_vararg(bi_exec, "args");
    10489}
    10590
     
    11196        if (fun_sym == bi_write_line) {
    11297                builtin_write_line(run);
     98        } else if (fun_sym == bi_exec) {
     99                builtin_exec(run);
    113100        } else {
    114101                assert(b_false);
     
    116103}
    117104
     105/** Declare a builtin function in @a csi. */
     106static stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, char *name)
     107{
     108        stree_ident_t *ident;
     109        stree_fun_t *fun;
     110        stree_csimbr_t *csimbr;
     111        stree_symbol_t *symbol;
     112
     113        ident = stree_ident_new();
     114        ident->sid = strtab_get_sid(name);
     115
     116        fun = stree_fun_new();
     117        fun->name = ident;
     118        fun->body = NULL;
     119        list_init(&fun->args);
     120
     121        csimbr = stree_csimbr_new(csimbr_fun);
     122        csimbr->u.fun = fun;
     123
     124        symbol = stree_symbol_new(sc_fun);
     125        symbol->u.fun = fun;
     126        symbol->outer_csi = csi;
     127        fun->symbol = symbol;
     128
     129        list_append(&csi->members, csimbr);
     130
     131        return symbol;
     132}
     133
     134/** Add one formal parameter to function. */
     135static void builtin_fun_add_arg(stree_symbol_t *fun_sym, char *name)
     136{
     137        stree_fun_arg_t *fun_arg;
     138        stree_fun_t *fun;
     139
     140        fun = symbol_to_fun(fun_sym);
     141        assert(fun != NULL);
     142
     143        fun_arg = stree_fun_arg_new();
     144        fun_arg->name = stree_ident_new();
     145        fun_arg->name->sid = strtab_get_sid(name);
     146        fun_arg->type = NULL; /* XXX */
     147
     148        list_append(&fun->args, fun_arg);
     149}
     150
     151/** Add variadic formal parameter to function. */
     152static void builtin_fun_add_vararg(stree_symbol_t *fun_sym, char *name)
     153{
     154        stree_fun_arg_t *fun_arg;
     155        stree_fun_t *fun;
     156
     157        fun = symbol_to_fun(fun_sym);
     158        assert(fun != NULL);
     159
     160        fun_arg = stree_fun_arg_new();
     161        fun_arg->name = stree_ident_new();
     162        fun_arg->name->sid = strtab_get_sid(name);
     163        fun_arg->type = NULL; /* XXX */
     164
     165        fun->varg = fun_arg;
     166}
     167
    118168static void builtin_write_line(run_t *run)
    119169{
     
    121171
    122172#ifdef DEBUG_RUN_TRACE
    123         printf("Called Builtin.writeLine()\n");
     173        printf("Called Builtin.WriteLine()\n");
    124174#endif
    125175        var = run_local_vars_lookup(run, strtab_get_sid("arg"));
     
    138188        }
    139189}
     190
     191/** Start an executable and wait for it to finish. */
     192static void builtin_exec(run_t *run)
     193{
     194        rdata_var_t *args;
     195        rdata_var_t *var;
     196        rdata_array_t *array;
     197        rdata_var_t *arg;
     198        int idx, dim;
     199        char **cmd;
     200
     201#ifdef DEBUG_RUN_TRACE
     202        printf("Called Builtin.Exec()\n");
     203#endif
     204        args = run_local_vars_lookup(run, strtab_get_sid("args"));
     205
     206        assert(args);
     207        assert(args->vc == vc_ref);
     208
     209        var = args->u.ref_v->vref;
     210        assert(var->vc == vc_array);
     211
     212        array = var->u.array_v;
     213        assert(array->rank == 1);
     214        dim = array->extent[0];
     215
     216        if (dim == 0) {
     217                printf("Error: Builtin.Exec() expects at least one argument.\n");
     218                exit(1);
     219        }
     220
     221        cmd = calloc(dim + 1, sizeof(char *));
     222        if (cmd == NULL) {
     223                printf("Memory allocation failed.\n");
     224                exit(1);
     225        }
     226
     227        for (idx = 0; idx < dim; ++idx) {
     228                arg = array->element[idx];
     229                if (arg->vc != vc_string) {
     230                        printf("Error: Argument to Builtin.Exec() must be "
     231                            "string (found %d).\n", arg->vc);
     232                        exit(1);
     233                }
     234
     235                cmd[idx] = arg->u.string_v->value;
     236        }
     237
     238        cmd[dim] = '\0';
     239
     240        if (os_exec(cmd) != EOK) {
     241                printf("Error: Exec failed.\n");
     242                exit(1);
     243        }
     244}
  • uspace/app/sbi/src/compat.h

    rfa36f29 r94d484a  
    4545#define list_remove sbi_list_remove
    4646
    47 /*
    48  * These functions can be simply mapped to HelenOS string API.
    49  */
    50 #define strcmp str_cmp
    51 #define strdup str_dup
    52 
    5347#endif
    5448
  • uspace/app/sbi/src/lex.c

    rfa36f29 r94d484a  
    3535#include <stdlib.h>
    3636#include <string.h>
    37 #include "compat.h"
    3837#include "mytypes.h"
    3938#include "input.h"
     39#include "os/os.h"
    4040#include "strtab.h"
    4141
     
    4444#define TAB_WIDTH 8
    4545
     46static bool_t lex_next_try(lex_t *lex);
     47
     48static void lex_skip_comment(lex_t *lex);
    4649static void lex_skip_ws(lex_t *lex);
    4750static bool_t is_wstart(char c);
     
    8790        { lc_nil,       "nil" },
    8891        { lc_override,  "override" },
     92        { lc_packed,    "packed" },
    8993        { lc_private,   "private" },
    9094        { lc_prop,      "prop" },
     
    222226void lex_next(lex_t *lex)
    223227{
     228        bool_t got_lem;
     229
     230        do {
     231                got_lem = lex_next_try(lex);
     232        } while (got_lem == b_false);
     233}
     234
     235/** Try reading next lexical element.
     236 *
     237 * @return @c b_true on success or @c b_false if it needs restarting.
     238 */
     239static bool_t lex_next_try(lex_t *lex)
     240{
    224241        char *bp;
    225242
     
    240257                /* End of input */
    241258                lex->current.lclass = lc_eof;
    242                 return;
     259                return b_true;
    243260        }
    244261
    245262        if (is_wstart(bp[0])) {
    246263                lex_word(lex);
    247                 return;
     264                return b_true;
    248265        }
    249266
    250267        if (is_digit(bp[0])) {
    251268                lex_number(lex);
    252                 return;
     269                return b_true;
    253270        }
    254271
    255272        if (bp[0] == '"') {
    256273                lex_string(lex);
    257                 return;
     274                return b_true;
     275        }
     276
     277        if (bp[0] == '-' && bp[1] == '-') {
     278                lex_skip_comment(lex);
     279                return b_false;
    258280        }
    259281
     
    305327
    306328        lex->ibp = bp;
    307         return;
     329        return b_true;
    308330
    309331invalid:
     
    311333        ++bp;
    312334        lex->ibp = bp;
     335
     336        return b_true;
    313337}
    314338
     
    340364        dp = keywords;
    341365        while (dp->name != NULL) {
    342                 if (strcmp(ident_buf, dp->name) == 0) {
     366                if (os_str_cmp(ident_buf, dp->name) == 0) {
    343367                        /* Match */
    344368                        lex->current.lclass = dp->lclass;
     
    402426
    403427        lex->current.lclass = lc_lit_string;
    404         lex->current.u.lit_string.value = strdup(strlit_buf);
    405 }
    406 
     428        lex->current.u.lit_string.value = os_str_dup(strlit_buf);
     429}
     430
     431/** Lex a single-line comment. */
     432static void lex_skip_comment(lex_t *lex)
     433{
     434        char *bp;
     435
     436        bp = lex->ibp + 2;
     437
     438        while (*bp != '\n' && *bp != '\0') {
     439                ++bp;
     440        }
     441
     442        lex->ibp = bp;
     443}
    407444
    408445/** Skip whitespace characters. */
  • uspace/app/sbi/src/lex_t.h

    rfa36f29 r94d484a  
    5858        lc_nil,
    5959        lc_override,
     60        lc_packed,
    6061        lc_private,
    6162        lc_prop,
  • uspace/app/sbi/src/p_expr.c

    rfa36f29 r94d484a  
    4848static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a);
    4949static stree_expr_t *parse_pf_call(parse_t *parse, stree_expr_t *a);
     50static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a);
    5051static stree_expr_t *parse_primitive(parse_t *parse);
    5152static stree_expr_t *parse_nameref(parse_t *parse);
     
    181182        lmatch(parse, lc_new);
    182183        texpr = parse_texpr(parse);
    183         lmatch(parse, lc_lparen);
    184         lmatch(parse, lc_rparen);
     184
     185        /* Parenthesis should be present except for arrays. */
     186        if (texpr->tc != tc_tindex) {
     187                lmatch(parse, lc_lparen);
     188                lmatch(parse, lc_rparen);
     189        }
    185190
    186191        new_op = stree_new_new();
     
    200205        a = parse_primitive(parse);
    201206
    202         while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen) {
     207        while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen ||
     208            lcur_lc(parse) == lc_lsbr) {
    203209
    204210                switch (lcur_lc(parse)) {
     
    209215                        tmp = parse_pf_call(parse, a);
    210216                        break;
     217                case lc_lsbr:
     218                        tmp = parse_pf_index(parse, a);
     219                        break;
    211220                default:
    212221                        assert(b_false);
     
    273282}
    274283
     284/** Parse index expression. */
     285static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a)
     286{
     287        stree_expr_t *expr;
     288        stree_index_t *index;
     289        stree_expr_t *arg;
     290
     291        lmatch(parse, lc_lsbr);
     292
     293        index = stree_index_new();
     294        index->base = a;
     295        list_init(&index->args);
     296
     297        /* Parse indices */
     298
     299        if (lcur_lc(parse) != lc_rsbr) {
     300                while (b_true) {
     301                        arg = parse_expr(parse);
     302                        list_append(&index->args, arg);
     303
     304                        if (lcur_lc(parse) == lc_rsbr)
     305                                break;
     306                        lmatch(parse, lc_comma);
     307                }
     308        }
     309
     310        lmatch(parse, lc_rsbr);
     311
     312        expr = stree_expr_new(ec_index);
     313        expr->u.index = index;
     314
     315        return expr;
     316}
     317
    275318/** Parse primitive expression. */
    276319static stree_expr_t *parse_primitive(parse_t *parse)
  • uspace/app/sbi/src/p_type.c

    rfa36f29 r94d484a  
    1 /*
     1/*                              YI
    22 * Copyright (c) 2010 Jiri Svoboda
    33 * All rights reserved.
     
    3535#include "mytypes.h"
    3636#include "parse.h"
     37#include "p_expr.h"
    3738#include "stree.h"
    3839
     
    4142static stree_texpr_t *parse_tapply(parse_t *parse);
    4243static stree_texpr_t *parse_tpostfix(parse_t *parse);
     44static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a);
     45static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a);
    4346static stree_texpr_t *parse_tprimitive(parse_t *parse);
    4447static stree_tliteral_t *parse_tliteral(parse_t *parse);
     
    7881{
    7982        stree_texpr_t *a;
     83        stree_texpr_t *tmp;
     84
     85        a = parse_tprimitive(parse);
     86
     87        while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lsbr) {
     88
     89                switch (lcur_lc(parse)) {
     90                case lc_period:
     91                        tmp = parse_pf_taccess(parse, a);
     92                        break;
     93                case lc_lsbr:
     94                        tmp = parse_pf_tindex(parse, a);
     95                        break;
     96                default:
     97                        lunexpected_error(parse);
     98                        exit(1);
     99                }
     100
     101                a = tmp;
     102        }
     103
     104        return a;
     105}
     106
     107/** Parse access type expression. */
     108static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a)
     109{
     110        stree_texpr_t *texpr;
    80111        stree_ident_t *ident;
    81         stree_texpr_t *tmp;
    82112        stree_taccess_t *taccess;
    83113
    84         a = parse_tprimitive(parse);
    85 
    86         while (lcur_lc(parse) == lc_period) {
    87                 lskip(parse);
    88                 ident = parse_ident(parse);
    89 
    90                 taccess = stree_taccess_new();
    91                 taccess->arg = a;
    92                 taccess->member_name = ident;
    93 
    94                 tmp = stree_texpr_new(tc_taccess);
    95                 tmp->u.taccess = taccess;
    96                 a = tmp;
    97         }
    98 
    99         return a;
     114        lmatch(parse, lc_period);
     115        ident = parse_ident(parse);
     116
     117        taccess = stree_taccess_new();
     118        taccess->arg = a;
     119        taccess->member_name = ident;
     120
     121        texpr = stree_texpr_new(tc_taccess);
     122        texpr->u.taccess = taccess;
     123
     124        return texpr;
     125}
     126
     127/** Parse index type expression. */
     128static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a)
     129{
     130        stree_texpr_t *texpr;
     131        stree_tindex_t *tindex;
     132        stree_expr_t *expr;
     133
     134        tindex = stree_tindex_new();
     135        tindex->base_type = a;
     136
     137        tindex->n_args = 0;
     138        list_init(&tindex->args);
     139
     140        lmatch(parse, lc_lsbr);
     141
     142        if (lcur_lc(parse) != lc_rsbr && lcur_lc(parse) != lc_comma) {
     143                while (b_true) {
     144                        expr = parse_expr(parse);
     145                        tindex->n_args += 1;
     146                        list_append(&tindex->args, expr);
     147
     148                        if (lcur_lc(parse) == lc_rsbr)
     149                                break;
     150
     151                        lmatch(parse, lc_comma);
     152                }
     153        } else {
     154                tindex->n_args = 1;
     155                while (lcur_lc(parse) == lc_comma) {
     156                        lskip(parse);
     157                        tindex->n_args += 1;
     158                }
     159        }
     160
     161        lmatch(parse, lc_rsbr);
     162
     163        texpr = stree_texpr_new(tc_tindex);
     164        texpr->u.tindex = tindex;
     165
     166        return texpr;
    100167}
    101168
  • uspace/app/sbi/src/parse.c

    rfa36f29 r94d484a  
    5656
    5757static stree_fun_arg_t *parse_fun_arg(parse_t *parse);
     58static stree_arg_attr_t *parse_arg_attr(parse_t *parse);
    5859
    5960/*
     
    7273static stree_exps_t *parse_exps(parse_t *parse);
    7374
     75static stree_except_t *parse_except(parse_t *parse);
     76
    7477void parse_init(parse_t *parse, stree_program_t *prog, struct lex *lex)
    7578{
     
    8790        stree_symbol_t *symbol;
    8891
    89 /*      do {
    90                 lex_next(parse->lex);
    91                 printf("Read token: "); lem_print(&parse->lex->current);
    92                 putchar('\n');
    93         } while (parse->lex->current.lclass != lc_eof);
    94 */
    9592        while (lcur_lc(parse) != lc_eof) {
    9693                switch (lcur_lc(parse)) {
     
    245242                while (b_true) {
    246243                        arg = parse_fun_arg(parse);
    247                         list_append(&fun->args, arg);
     244                        if (stree_arg_has_attr(arg, aac_packed)) {
     245                                fun->varg = arg;
     246                                break;
     247                        } else {
     248                                list_append(&fun->args, arg);
     249                        }
    248250
    249251                        if (lcur_lc(parse) == lc_rparen)
     
    307309{
    308310        stree_fun_arg_t *arg;
     311        stree_arg_attr_t *attr;
    309312
    310313        arg = stree_fun_arg_new();
     
    313316        arg->type = parse_texpr(parse);
    314317
     318        list_init(&arg->attr);
     319
     320        /* Parse attributes. */
     321        while (lcur_lc(parse) == lc_comma) {
     322                lskip(parse);
     323                attr = parse_arg_attr(parse);
     324                list_append(&arg->attr, attr);
     325        }
     326
    315327        return arg;
     328}
     329
     330/** Parse argument attribute. */
     331static stree_arg_attr_t *parse_arg_attr(parse_t *parse)
     332{
     333        stree_arg_attr_t *attr;
     334
     335        if (lcur_lc(parse) != lc_packed) {
     336                printf("Error: Unexpected attribute '");
     337                lem_print(lcur(parse));
     338                printf("'.\n");
     339                exit(1);
     340        }
     341
     342        lskip(parse);
     343
     344        attr = stree_arg_attr_new(aac_packed);
     345        return attr;
    316346}
    317347
     
    378408                stat->u.return_s = return_s;
    379409                break;
     410        case lc_do:
    380411        case lc_with:
    381412                wef_s = parse_wef(parse);
     
    485516static stree_raise_t *parse_raise(parse_t *parse)
    486517{
     518        stree_raise_t *raise_s;
     519
     520        raise_s = stree_raise_new();
    487521        lmatch(parse, lc_raise);
    488         (void) parse_expr(parse);
     522        raise_s->expr = parse_expr(parse);
    489523        lmatch(parse, lc_scolon);
    490524
    491         return stree_raise_new();
     525        return raise_s;
    492526}
    493527
     
    510544{
    511545        stree_wef_t *wef_s;
    512         stree_block_t *block;
     546        stree_except_t *except_c;
    513547
    514548        wef_s = stree_wef_new();
    515         list_init(&wef_s->except_blocks);
    516 
    517         lmatch(parse, lc_with);
    518         lmatch(parse, lc_ident);
    519         lmatch(parse, lc_colon);
    520         (void) parse_texpr(parse);
    521         lmatch(parse, lc_assign);
    522         (void) parse_expr(parse);
    523         lmatch(parse, lc_do);
    524         wef_s->with_block = parse_block(parse);
    525 
    526         while (lcur_lc(parse) == lc_except) {
    527                 lmatch(parse, lc_except);
     549        list_init(&wef_s->except_clauses);
     550
     551        if (lcur_lc(parse) == lc_with) {
     552                lmatch(parse, lc_with);
    528553                lmatch(parse, lc_ident);
    529554                lmatch(parse, lc_colon);
    530555                (void) parse_texpr(parse);
     556                lmatch(parse, lc_assign);
     557                (void) parse_expr(parse);
     558        }
     559
     560        lmatch(parse, lc_do);
     561        wef_s->with_block = parse_block(parse);
     562
     563        while (lcur_lc(parse) == lc_except) {
     564                except_c = parse_except(parse);
     565                list_append(&wef_s->except_clauses, except_c);
     566        }
     567
     568        if (lcur_lc(parse) == lc_finally) {
     569                lmatch(parse, lc_finally);
    531570                lmatch(parse, lc_do);
    532 
    533                 block = parse_block(parse);
    534                 list_append(&wef_s->except_blocks, block);
    535         }
    536 
    537         lmatch(parse, lc_finally);
    538         lmatch(parse, lc_do);
    539         wef_s->finally_block = parse_block(parse);
     571                wef_s->finally_block = parse_block(parse);
     572        } else {
     573                wef_s->finally_block = NULL;
     574        }
     575
    540576        lmatch(parse, lc_end);
    541577
     
    556592
    557593        return exps;
     594}
     595
     596/* Parse @c except clause. */
     597static stree_except_t *parse_except(parse_t *parse)
     598{
     599        stree_except_t *except_c;
     600
     601        except_c = stree_except_new();
     602
     603        lmatch(parse, lc_except);
     604        except_c->evar = parse_ident(parse);
     605        lmatch(parse, lc_colon);
     606        except_c->etype = parse_texpr(parse);
     607        lmatch(parse, lc_do);
     608
     609        except_c->block = parse_block(parse);
     610
     611        return except_c;
    558612}
    559613
  • uspace/app/sbi/src/rdata.c

    rfa36f29 r94d484a  
    3232#include <assert.h>
    3333#include "mytypes.h"
     34#include "stree.h"
    3435
    3536#include "rdata.h"
     
    3940static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest);
    4041static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest);
     42static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest);
    4143static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest);
     44
     45static int rdata_array_get_dim(rdata_array_t *array);
    4246
    4347static void rdata_address_print(rdata_address_t *address);
     
    126130}
    127131
     132rdata_array_t *rdata_array_new(int rank)
     133{
     134        rdata_array_t *array;
     135
     136        array = calloc(1, sizeof(rdata_array_t));
     137        if (array == NULL) {
     138                printf("Memory allocation failed.\n");
     139                exit(1);
     140        }
     141
     142        array->rank = rank;
     143        array->extent = calloc(rank, sizeof(int));
     144        if (array == NULL) {
     145                printf("Memory allocation failed.\n");
     146                exit(1);
     147        }
     148
     149        return array;
     150}
     151
    128152rdata_object_t *rdata_object_new(void)
    129153{
     
    163187
    164188        return string_v;
     189}
     190
     191rdata_titem_t *rdata_titem_new(titem_class_t tic)
     192{
     193        rdata_titem_t *titem;
     194
     195        titem = calloc(1, sizeof(rdata_titem_t));
     196        if (titem == NULL) {
     197                printf("Memory allocation failed.\n");
     198                exit(1);
     199        }
     200
     201        titem->tic = tic;
     202        return titem;
     203}
     204
     205rdata_tarray_t *rdata_tarray_new(void)
     206{
     207        rdata_tarray_t *tarray;
     208
     209        tarray = calloc(1, sizeof(rdata_tarray_t));
     210        if (tarray == NULL) {
     211                printf("Memory allocation failed.\n");
     212                exit(1);
     213        }
     214
     215        return tarray;
     216}
     217
     218rdata_tcsi_t *rdata_tcsi_new(void)
     219{
     220        rdata_tcsi_t *tcsi;
     221
     222        tcsi = calloc(1, sizeof(rdata_tcsi_t));
     223        if (tcsi == NULL) {
     224                printf("Memory allocation failed.\n");
     225                exit(1);
     226        }
     227
     228        return tcsi;
     229}
     230
     231rdata_tprimitive_t *rdata_tprimitive_new(void)
     232{
     233        rdata_tprimitive_t *tprimitive;
     234
     235        tprimitive = calloc(1, sizeof(rdata_tprimitive_t));
     236        if (tprimitive == NULL) {
     237                printf("Memory allocation failed.\n");
     238                exit(1);
     239        }
     240
     241        return tprimitive;
     242}
     243
     244void rdata_array_alloc_element(rdata_array_t *array)
     245{
     246        int dim, idx;
     247
     248        dim = rdata_array_get_dim(array);
     249
     250        array->element = calloc(dim, sizeof(rdata_var_t *));
     251        if (array->element == NULL) {
     252                printf("Memory allocation failed.\n");
     253                exit(1);
     254        }
     255
     256        for (idx = 0; idx < dim; ++idx) {
     257                array->element[idx] = calloc(1, sizeof(rdata_var_t));
     258                if (array->element[idx] == NULL) {
     259                        printf("Memory allocation failed.\n");
     260                        exit(1);
     261                }
     262        }
     263}
     264
     265/** Get array dimension.
     266 *
     267 * Dimension is the total number of elements in an array, in other words,
     268 * the product of all extents.
     269 */
     270static int rdata_array_get_dim(rdata_array_t *array)
     271{
     272        int didx, dim;
     273
     274        dim = 1;
     275        for (didx = 0; didx < array->rank; ++didx)
     276                dim = dim * array->extent[didx];
     277
     278        return dim;
    165279}
    166280
     
    185299                rdata_deleg_copy(src->u.deleg_v, &nvar->u.deleg_v);
    186300                break;
     301        case vc_array:
     302                rdata_array_copy(src->u.array_v, &nvar->u.array_v);
     303                break;
    187304        case vc_object:
    188305                rdata_object_copy(src->u.object_v, &nvar->u.object_v);
     
    215332        (void) src; (void) dest;
    216333        printf("Unimplemented: Copy delegate.\n");
     334        exit(1);
     335}
     336
     337static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
     338{
     339        (void) src; (void) dest;
     340        printf("Unimplemented: Copy array.\n");
    217341        exit(1);
    218342}
     
    339463void rdata_address_write(rdata_address_t *address, rdata_value_t *value)
    340464{
     465        rdata_var_write(address->vref, value);
     466}
     467
     468/** Write data to a variable.
     469 *
     470 * Store @a value to variable @a var.
     471 */
     472void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
     473{
    341474        rdata_var_t *nvar;
    342         rdata_var_t *orig_var;
    343475
    344476        /* Perform a shallow copy of @c value->var. */
    345477        rdata_var_copy(value->var, &nvar);
    346         orig_var = address->vref;
    347478
    348479        /* XXX do this in a prettier way. */
    349480
    350         orig_var->vc = nvar->vc;
     481        var->vc = nvar->vc;
    351482        switch (nvar->vc) {
    352         case vc_int: orig_var->u.int_v = nvar->u.int_v; break;
    353         case vc_ref: orig_var->u.ref_v = nvar->u.ref_v; break;
    354         case vc_deleg: orig_var->u.deleg_v = nvar->u.deleg_v; break;
    355         case vc_object: orig_var->u.object_v = nvar->u.object_v; break;
    356         default: assert(b_false);
     483        case vc_int: var->u.int_v = nvar->u.int_v; break;
     484        case vc_string: var->u.string_v = nvar->u.string_v; break;
     485        case vc_ref: var->u.ref_v = nvar->u.ref_v; break;
     486        case vc_deleg: var->u.deleg_v = nvar->u.deleg_v; break;
     487        case vc_array: var->u.array_v = nvar->u.array_v; break;
     488        case vc_object: var->u.object_v = nvar->u.object_v; break;
    357489        }
    358490
    359491        /* XXX We should free some stuff around here. */
     492}
     493
     494/** Determine if CSI @a a is derived from CSI described by type item @a tb. */
     495bool_t rdata_is_csi_derived_from_ti(stree_csi_t *a, rdata_titem_t *tb)
     496{
     497        bool_t res;
     498
     499        switch (tb->tic) {
     500        case tic_tcsi:
     501                res = stree_is_csi_derived_from_csi(a, tb->u.tcsi->csi);
     502                break;
     503        default:
     504                printf("Error: Base type is not a CSI.\n");
     505                exit(1);
     506        }
     507
     508        return res;
    360509}
    361510
  • uspace/app/sbi/src/rdata.h

    rfa36f29 r94d484a  
    3838rdata_ref_t *rdata_ref_new(void);
    3939rdata_deleg_t *rdata_deleg_new(void);
     40rdata_array_t *rdata_array_new(int rank);
    4041rdata_object_t *rdata_object_new(void);
    4142rdata_int_t *rdata_int_new(void);
    4243rdata_string_t *rdata_string_new(void);
    4344
     45rdata_titem_t *rdata_titem_new(titem_class_t tic);
     46rdata_tarray_t *rdata_tarray_new(void);
     47rdata_tcsi_t *rdata_tcsi_new(void);
     48rdata_tprimitive_t *rdata_tprimitive_new(void);
     49
     50void rdata_array_alloc_element(rdata_array_t *array);
    4451void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest);
    4552
     
    4956void rdata_address_read(rdata_address_t *address, rdata_item_t **ritem);
    5057void rdata_address_write(rdata_address_t *address, rdata_value_t *value);
     58void rdata_var_write(rdata_var_t *var, rdata_value_t *value);
     59
     60bool_t rdata_is_csi_derived_from_ti(stree_csi_t *a, rdata_titem_t *tb);
    5161
    5262void rdata_item_print(rdata_item_t *item);
  • uspace/app/sbi/src/rdata_t.h

    rfa36f29 r94d484a  
    6868} rdata_deleg_t;
    6969
     70/** Array variable */
     71typedef struct {
     72        /** Rank */
     73        int rank;
     74
     75        /** Extents (@c rank entries) */
     76        int *extent;
     77
     78        /**
     79         * Elements (extent[0] * extent[1] * ... extent[rank - 1] entries)
     80         * stored in lexicographical order. Each element is (rdata_var_t *).
     81         */
     82        struct rdata_var **element;
     83} rdata_array_t;
     84
    7085/** Object variable */
    7186typedef struct {
     
    89104        /** Delegate */
    90105        vc_deleg,
     106
     107        /** Array */
     108        vc_array,
    91109
    92110        /** Object */
     
    108126                rdata_ref_t *ref_v;
    109127                rdata_deleg_t *deleg_v;
     128                rdata_array_t *array_v;
    110129                rdata_object_t *object_v;
    111130        } u;
     
    113132
    114133/** Address item. */
    115 typedef struct {
     134typedef struct rdata_address {
    116135        /** Targeted variable */
    117136        rdata_var_t *vref;
     
    119138
    120139/** Value item. */
    121 typedef struct {
     140typedef struct rdata_value {
    122141        /**
    123142         * Read-only Variable holding a copy of the data. The same @c var
     
    150169} rdata_item_t;
    151170
     171/** Primitive type. */
     172typedef struct {
     173} rdata_tprimitive_t;
     174
     175/** Class, struct or interface type. */
     176typedef struct {
     177        struct stree_csi *csi;
     178} rdata_tcsi_t;
     179
     180/** Array type. */
     181typedef struct {
     182        /** Base type item */
     183        struct rdata_titem *base_ti;
     184
     185        /** Rank */
     186        int rank;
     187
     188        /** Extents */
     189        list_t extents; /* of stree_expr_t */
     190} rdata_tarray_t;
     191
     192/** Generic type. */
     193typedef struct {
     194} rdata_tgeneric_t;
     195
     196typedef enum {
     197        tic_tprimitive,
     198        tic_tcsi,
     199        tic_tarray,
     200        tic_tgeneric
     201} titem_class_t;
     202
     203/** Type item, the result of evaluating a type expression. */
     204typedef struct rdata_titem {
     205        titem_class_t tic;
     206
     207        union {
     208                rdata_tprimitive_t *tprimitive;
     209                rdata_tcsi_t *tcsi;
     210                rdata_tarray_t *tarray;
     211                rdata_tgeneric_t *tgeneric;
     212        } u;
     213} rdata_titem_t;
     214
    152215#endif
  • uspace/app/sbi/src/run.c

    rfa36f29 r94d484a  
    3939#include "rdata.h"
    4040#include "run_expr.h"
     41#include "run_texpr.h"
    4142#include "stree.h"
    4243#include "strtab.h"
     
    5152static void run_if(run_t *run, stree_if_t *if_s);
    5253static void run_while(run_t *run, stree_while_t *while_s);
     54static void run_raise(run_t *run, stree_raise_t *raise_s);
    5355static void run_return(run_t *run, stree_return_t *return_s);
     56static void run_wef(run_t *run, stree_wef_t *wef_s);
     57
     58static bool_t run_exc_match(run_t *run, stree_except_t *except_c);
    5459
    5560/** Initialize runner instance. */
     
    101106        run_fun_ar_set_args(run, fun_ar, &main_args);
    102107        run_fun(run, fun_ar, &res);
     108
     109        /* Check for unhandled exceptions. */
     110        if (run->thread_ar->bo_mode != bm_none) {
     111                assert(run->thread_ar->bo_mode == bm_exc);
     112                printf("Error: Unhandled exception.\n");
     113                exit(1);
     114        }
    103115}
    104116
     
    217229                run_while(run, stat->u.while_s);
    218230                break;
     231        case st_raise:
     232                run_raise(run, stat->u.raise_s);
     233                break;
    219234        case st_return:
    220235                run_return(run, stat->u.return_s);
    221236                break;
     237        case st_wef:
     238                run_wef(run, stat->u.wef_s);
     239                break;
    222240        case st_for:
    223         case st_raise:
    224         case st_wef:
    225241                printf("Ignoring unimplemented statement type %d.\n", stat->sc);
    226242                break;
     
    331347}
    332348
     349/** Run @c raise statement. */
     350static void run_raise(run_t *run, stree_raise_t *raise_s)
     351{
     352        rdata_item_t *rexpr;
     353        rdata_item_t *rexpr_vi;
     354
     355#ifdef DEBUG_RUN_TRACE
     356        printf("Executing raise statement.\n");
     357#endif
     358        run_expr(run, raise_s->expr, &rexpr);
     359        rdata_cvt_value_item(rexpr, &rexpr_vi);
     360
     361        /* Store expression result in thread AR. */
     362        run->thread_ar->exc_payload = rexpr_vi->u.value;
     363
     364        /* Start exception bailout. */
     365        run->thread_ar->bo_mode = bm_exc;
     366}
     367
    333368/** Run @c return statement. */
    334369static void run_return(run_t *run, stree_return_t *return_s)
     
    349384        if (run->thread_ar->bo_mode == bm_none)
    350385                run->thread_ar->bo_mode = bm_fun;
     386}
     387
     388/** Run @c with-except-finally statement. */
     389static void run_wef(run_t *run, stree_wef_t *wef_s)
     390{
     391        list_node_t *except_n;
     392        stree_except_t *except_c;
     393        rdata_value_t *exc_payload;
     394        run_bailout_mode_t bo_mode;
     395
     396#ifdef DEBUG_RUN_TRACE
     397        printf("Executing with-except-finally statement.\n");
     398#endif
     399        run_block(run, wef_s->with_block);
     400
     401        if (run->thread_ar->bo_mode == bm_exc) {
     402#ifdef DEBUG_RUN_TRACE
     403                printf("With statement detected exception.\n");
     404#endif
     405                /* Reset to normal execution. */
     406                run->thread_ar->bo_mode = bm_none;
     407
     408                /* Look for an except block. */
     409                except_n = list_first(&wef_s->except_clauses);
     410                while (except_n != NULL) {
     411                        except_c = list_node_data(except_n, stree_except_t *);
     412                        if (run_exc_match(run, except_c))
     413                                break;
     414
     415                        except_n = list_next(&wef_s->except_clauses, except_n);
     416                }
     417
     418                /* If one was found, execute it. */
     419                if (except_n != NULL)
     420                        run_block(run, except_c->block);
     421
     422                /* Execute finally block */
     423                if (wef_s->finally_block != NULL) {
     424                        /* Put exception on the side temporarily. */
     425                        bo_mode = run->thread_ar->bo_mode;
     426                        exc_payload = run->thread_ar->exc_payload;
     427
     428                        run->thread_ar->bo_mode = bm_none;
     429                        run->thread_ar->exc_payload = NULL;
     430
     431                        run_block(run, wef_s->finally_block);
     432
     433                        if (bo_mode == bm_exc) {
     434                                /*
     435                                 * Restore the original exception. If another
     436                                 * exception occured in the finally block (i.e.
     437                                 * double fault), it is forgotten.
     438                                 */
     439                                run->thread_ar->bo_mode = bm_exc;
     440                                run->thread_ar->exc_payload = exc_payload;
     441                        }
     442                }
     443        }
     444
     445#ifdef DEBUG_RUN_TRACE
     446        printf("With-except-finally statement terminated.\n");
     447#endif
     448}
     449
     450/** Determine whether currently active exception matches @c except clause.
     451 *
     452 * Checks if the currently active exception in the runner object @c run
     453 * matches except clause @c except_c. Generates an error if the exception
     454 * payload has invalid type (i.e. not an object).
     455 *
     456 * @param run           Runner object.
     457 * @param except_c      @c except clause.
     458 * @return              @c b_true if there is a match, @c b_false otherwise.
     459 */
     460static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
     461{
     462        rdata_value_t *payload;
     463        rdata_var_t *payload_v;
     464        rdata_object_t *payload_o;
     465        rdata_titem_t *etype;
     466
     467        payload = run->thread_ar->exc_payload;
     468        assert(payload != NULL);
     469
     470        if (payload->var->vc != vc_ref) {
     471                printf("Error: Exception payload must be an object "
     472                    "(found type %d).\n", payload->var->vc);
     473                exit(1);
     474        }
     475
     476        payload_v = payload->var->u.ref_v->vref;
     477        if (payload_v->vc != vc_object) {
     478                printf("Error: Exception payload must be an object "
     479                    "(found type %d).\n", payload_v->vc);
     480                exit(1);
     481        }
     482
     483        payload_o = payload_v->u.object_v;
     484
     485#ifdef DEBUG_RUN_TRACE
     486        printf("Active exception: '");
     487        symbol_print_fqn(run->program, payload_o->class_sym);
     488        printf("'.\n");
     489#endif
     490        assert(payload_o->class_sym != NULL);
     491        assert(payload_o->class_sym->sc == sc_csi);
     492
     493        /* Evaluate type expression in except clause. */
     494        run_texpr(run, except_c->etype, &etype);
     495
     496        return rdata_is_csi_derived_from_ti(payload_o->class_sym->u.csi,
     497            etype);
    351498}
    352499
     
    395542        node = list_last(&fun_ar->block_ar);
    396543        return list_node_data(node, run_block_ar_t *);
     544}
     545
     546/** Get current CSI. */
     547stree_csi_t *run_get_current_csi(run_t *run)
     548{
     549        run_fun_ar_t *fun_ar;
     550
     551        fun_ar = run_get_current_fun_ar(run);
     552        return fun_ar->fun_sym->outer_csi;
    397553}
    398554
     
    468624        run_block_ar_t *block_ar;
    469625        list_node_t *rarg_n, *farg_n;
     626        list_node_t *cn;
    470627        rdata_item_t *rarg;
    471628        stree_fun_arg_t *farg;
    472629        rdata_var_t *var;
     630        rdata_var_t *ref_var;
     631        rdata_ref_t *ref;
     632        rdata_array_t *array;
     633        int n_vargs, idx;
    473634
    474635        /* AR should have been created with run_fun_ar_create(). */
     
    511672        }
    512673
     674        if (fun->varg != NULL) {
     675                /* Function is variadic. Count number of variadic arguments. */
     676                cn = rarg_n;
     677                n_vargs = 0;
     678                while (cn != NULL) {
     679                        n_vargs += 1;
     680                        cn = list_next(args, cn);
     681                }
     682
     683                /* Prepare array to store variadic arguments. */
     684                array = rdata_array_new(1);
     685                array->extent[0] = n_vargs;
     686                rdata_array_alloc_element(array);
     687
     688                /* Read variadic arguments. */
     689
     690                idx = 0;
     691                while (rarg_n != NULL) {
     692                        rarg = list_node_data(rarg_n, rdata_item_t *);
     693                        assert(rarg->ic == ic_value);
     694
     695                        rdata_var_write(array->element[idx], rarg->u.value);
     696
     697                        rarg_n = list_next(args, rarg_n);
     698                        idx += 1;
     699                }
     700
     701                var = rdata_var_new(vc_array);
     702                var->u.array_v = array;
     703
     704                /* Create reference to the new array. */
     705                ref_var = rdata_var_new(vc_ref);
     706                ref = rdata_ref_new();
     707                ref_var->u.ref_v = ref;
     708                ref->vref = var;
     709
     710                /* Declare variable using name of formal argument. */
     711                intmap_set(&block_ar->vars, fun->varg->name->sid,
     712                    ref_var);
     713        }
     714
    513715        /* Check for excess real parameters. */
    514716        if (rarg_n != NULL) {
  • uspace/app/sbi/src/run.h

    rfa36f29 r94d484a  
    4141run_fun_ar_t *run_get_current_fun_ar(run_t *run);
    4242run_block_ar_t *run_get_current_block_ar(run_t *run);
     43stree_csi_t *run_get_current_csi(run_t *run);
    4344
    4445void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var);
  • uspace/app/sbi/src/run_expr.c

    rfa36f29 r94d484a  
    3636#include "list.h"
    3737#include "mytypes.h"
     38#include "os/os.h"
    3839#include "rdata.h"
    3940#include "run.h"
     41#include "run_texpr.h"
    4042#include "symbol.h"
    4143#include "strtab.h"
     
    6163static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    6264    rdata_value_t *v2, rdata_item_t **res);
     65static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     66    rdata_value_t *v2, rdata_item_t **res);
    6367static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    6468    rdata_value_t *v2, rdata_item_t **res);
     
    6670static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
    6771static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res);
     72static void run_new_array(run_t *run, stree_new_t *new_op,
     73    rdata_titem_t *titem, rdata_item_t **res);
     74static void run_new_object(run_t *run, stree_new_t *new_op,
     75    rdata_titem_t *titem, rdata_item_t **res);
    6876
    6977static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res);
     
    7886
    7987static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res);
     88static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res);
    8089static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res);
    8190
     
    111120        case ec_call:
    112121                run_call(run, expr->u.call, res);
     122                break;
     123        case ec_index:
     124                run_index(run, expr->u.index, res);
    113125                break;
    114126        case ec_assign:
     
    442454                run_binop_int(run, binop, v1, v2, res);
    443455                break;
     456        case vc_string:
     457                run_binop_string(run, binop, v1, v2, res);
     458                break;
    444459        case vc_ref:
    445460                run_binop_ref(run, binop, v1, v2, res);
     
    508523}
    509524
     525/** Evaluate binary operation on string arguments. */
     526static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     527    rdata_value_t *v2, rdata_item_t **res)
     528{
     529        rdata_item_t *item;
     530        rdata_value_t *value;
     531        rdata_var_t *var;
     532        rdata_string_t *string_v;
     533
     534        char *s1, *s2;
     535
     536        (void) run;
     537
     538        item = rdata_item_new(ic_value);
     539        value = rdata_value_new();
     540        var = rdata_var_new(vc_string);
     541        string_v = rdata_string_new();
     542
     543        item->u.value = value;
     544        value->var = var;
     545        var->u.string_v = string_v;
     546
     547        s1 = v1->var->u.string_v->value;
     548        s2 = v2->var->u.string_v->value;
     549
     550        switch (binop->bc) {
     551        case bo_plus:
     552                /* Concatenate strings. */
     553                string_v->value = os_str_acat(s1, s2);
     554                break;
     555        default:
     556                printf("Error: Invalid binary operation on string "
     557                    "arguments (%d).\n", binop->bc);
     558                assert(b_false);
     559        }
     560
     561        *res = item;
     562}
     563
    510564/** Evaluate binary operation on ref arguments. */
    511565static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     
    566620static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res)
    567621{
     622        rdata_titem_t *titem;
     623
     624#ifdef DEBUG_RUN_TRACE
     625        printf("Run 'new' operation.\n");
     626#endif
     627        /* Evaluate type expression */
     628        run_texpr(run, new_op->texpr, &titem);
     629
     630        switch (titem->tic) {
     631        case tic_tarray:
     632                run_new_array(run, new_op, titem, res);
     633                break;
     634        case tic_tcsi:
     635                run_new_object(run, new_op, titem, res);
     636                break;
     637        default:
     638                printf("Error: Invalid argument to operator 'new', "
     639                    "expected object.\n");
     640                exit(1);
     641        }
     642}
     643
     644/** Create new array. */
     645static void run_new_array(run_t *run, stree_new_t *new_op,
     646    rdata_titem_t *titem, rdata_item_t **res)
     647{
     648        rdata_tarray_t *tarray;
     649        rdata_array_t *array;
     650        rdata_var_t *array_var;
     651        rdata_var_t *elem_var;
     652
     653        rdata_item_t *rexpr, *rexpr_vi;
     654        rdata_var_t *rexpr_var;
     655
     656        stree_expr_t *expr;
     657
     658        list_node_t *node;
     659        int length;
     660        int i;
     661
     662#ifdef DEBUG_RUN_TRACE
     663        printf("Create new array.\n");
     664#endif
     665        (void) run;
     666        (void) new_op;
     667
     668        assert(titem->tic == tic_tarray);
     669        tarray = titem->u.tarray;
     670
     671        /* Create the array. */
     672        assert(titem->u.tarray->rank > 0);
     673        array = rdata_array_new(titem->u.tarray->rank);
     674
     675        /* Compute extents. */
     676        node = list_first(&tarray->extents);
     677        if (node == NULL) {
     678                printf("Error: Extents must be specified when constructing "
     679                    "an array with 'new'.\n");
     680                exit(1);
     681        }
     682
     683        i = 0; length = 1;
     684        while (node != NULL) {
     685                expr = list_node_data(node, stree_expr_t *);
     686
     687                /* Evaluate extent argument. */
     688                run_expr(run, expr, &rexpr);
     689                rdata_cvt_value_item(rexpr, &rexpr_vi);
     690                assert(rexpr_vi->ic == ic_value);
     691                rexpr_var = rexpr_vi->u.value->var;
     692
     693                if (rexpr_var->vc != vc_int) {
     694                        printf("Error: Array extent must be an integer.\n");
     695                        exit(1);
     696                }
     697
     698#ifdef DEBUG_RUN_TRACE
     699                printf("Array extent: %d.\n", rexpr_var->u.int_v->value);
     700#endif
     701                array->extent[i] = rexpr_var->u.int_v->value;
     702                length = length * array->extent[i];
     703
     704                node = list_next(&tarray->extents, node);
     705                i += 1;
     706        }
     707
     708        array->element = calloc(length, sizeof(rdata_var_t *));
     709        if (array->element == NULL) {
     710                printf("Memory allocation failed.\n");
     711                exit(1);
     712        }
     713
     714        /* Create member variables */
     715        for (i = 0; i < length; ++i) {
     716                /* XXX Depends on member variable type. */
     717                elem_var = rdata_var_new(vc_int);
     718                elem_var->u.int_v = rdata_int_new();
     719                elem_var->u.int_v->value = 0;
     720
     721                array->element[i] = elem_var;
     722        }
     723
     724        /* Create array variable. */
     725        array_var = rdata_var_new(vc_array);
     726        array_var->u.array_v = array;
     727
     728        /* Create reference to the new array. */
     729        rdata_reference(array_var, res);
     730}
     731
     732/** Create new object. */
     733static void run_new_object(run_t *run, stree_new_t *new_op,
     734    rdata_titem_t *titem, rdata_item_t **res)
     735{
    568736        rdata_object_t *obj;
    569737        rdata_var_t *obj_var;
     
    578746
    579747#ifdef DEBUG_RUN_TRACE
    580         printf("Run 'new' operation.\n");
    581 #endif
     748        printf("Create new object.\n");
     749#endif
     750        (void) run;
     751        (void) new_op;
     752
    582753        /* Lookup object CSI. */
    583         /* XXX Should start in the current CSI. */
    584         csi_sym = symbol_xlookup_in_csi(run->program, NULL, new_op->texpr);
    585         csi = symbol_to_csi(csi_sym);
    586         if (csi == NULL) {
    587                 printf("Error: Symbol '");
    588                 symbol_print_fqn(run->program, csi_sym);
    589                 printf("' is not a CSI. CSI required for 'new' operator.\n");
    590                 exit(1);
    591         }
     754        assert(titem->tic == tic_tcsi);
     755        csi = titem->u.tcsi->csi;
     756        csi_sym = csi_to_symbol(csi);
    592757
    593758        /* Create the object. */
     
    8751040}
    8761041
     1042/** Run index operation. */
     1043static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res)
     1044{
     1045        rdata_item_t *rbase;
     1046        rdata_item_t *base_i;
     1047        list_node_t *node;
     1048        stree_expr_t *arg;
     1049        rdata_item_t *rarg_i, *rarg_vi;
     1050        rdata_array_t *array;
     1051        var_class_t vc;
     1052
     1053        int i;
     1054        int elem_index;
     1055        int arg_val;
     1056
     1057        rdata_item_t *ritem;
     1058        rdata_address_t *address;
     1059
     1060#ifdef DEBUG_RUN_TRACE
     1061        printf("Run index operation.\n");
     1062#endif
     1063        run_expr(run, index->base, &rbase);
     1064
     1065        switch (rbase->ic) {
     1066        case ic_value:
     1067                vc = rbase->u.value->var->vc;
     1068                break;
     1069        case ic_address:
     1070                vc = rbase->u.address->vref->vc;
     1071                break;
     1072        default:
     1073                /* Silence warning. */
     1074                abort();
     1075        }
     1076
     1077        if (vc != vc_ref) {
     1078                printf("Error: Base of index operation is not a reference.\n");
     1079                exit(1);
     1080        }
     1081
     1082        rdata_dereference(rbase, &base_i);
     1083        assert(base_i->ic == ic_address);
     1084
     1085        if (base_i->u.value->var->vc != vc_array) {
     1086                printf("Error: Indexing something which is not an array.\n");
     1087                exit(1);
     1088        }
     1089
     1090        array = base_i->u.value->var->u.array_v;
     1091
     1092        /* Evaluate arguments (indices). */
     1093        node = list_first(&index->args);
     1094
     1095        /*
     1096         * Linear index of the desired element. Elements are stored in
     1097         * lexicographic order with the last index changing the fastest.
     1098         */
     1099        elem_index = 0;
     1100
     1101        i = 0;
     1102        while (node != NULL) {
     1103                if (i >= array->rank) {
     1104                        printf("Error: Too many indices for array of rank %d",
     1105                            array->rank);
     1106                        exit(1);
     1107                }
     1108
     1109                arg = list_node_data(node, stree_expr_t *);
     1110                run_expr(run, arg, &rarg_i);
     1111                rdata_cvt_value_item(rarg_i, &rarg_vi);
     1112                assert(rarg_vi->ic == ic_value);
     1113
     1114                if (rarg_vi->u.value->var->vc != vc_int) {
     1115                        printf("Error: Array index is not an integer.\n");
     1116                        exit(1);
     1117                }
     1118
     1119                arg_val = rarg_vi->u.value->var->u.int_v->value;
     1120
     1121                if (arg_val < 0 || arg_val >= array->extent[i]) {
     1122                        printf("Error: Array index (value: %d) is out of range.\n",
     1123                            arg_val);
     1124                        exit(1);
     1125                }
     1126
     1127                elem_index = elem_index * array->extent[i] + arg_val;
     1128
     1129                node = list_next(&index->args, node);
     1130                i += 1;
     1131        }
     1132
     1133        if (i < array->rank) {
     1134                printf("Error: Too few indices for array of rank %d",
     1135                    array->rank);
     1136                exit(1);
     1137        }
     1138
     1139        /* Construct variable address item. */
     1140        ritem = rdata_item_new(ic_address);
     1141        address = rdata_address_new();
     1142        ritem->u.address = address;
     1143
     1144        address->vref = array->element[elem_index];
     1145
     1146        *res = ritem;
     1147}
     1148
    8771149/** Execute assignment. */
    8781150static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res)
  • uspace/app/sbi/src/run_t.h

    rfa36f29 r94d484a  
    7474
    7575        /** Return from function */
    76         bm_fun
    77 } run_bailout_mode;
     76        bm_fun,
     77
     78        /** Exception */
     79        bm_exc
     80} run_bailout_mode_t;
    7881
    7982/** Thread activation record
     
    8689
    8790        /** Bailout mode */
    88         run_bailout_mode bo_mode;
     91        run_bailout_mode_t bo_mode;
     92
     93        /** Exception payload */
     94        struct rdata_value *exc_payload;
    8995} run_thread_ar_t;
    9096
  • uspace/app/sbi/src/stree.c

    rfa36f29 r94d484a  
    149149}
    150150
     151stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac)
     152{
     153        stree_arg_attr_t *arg_attr;
     154
     155        arg_attr = calloc(1, sizeof(stree_arg_attr_t));
     156        if (arg_attr == NULL) {
     157                printf("Memory allocation failed.\n");
     158                exit(1);
     159        }
     160
     161        arg_attr->aac = aac;
     162        return arg_attr;
     163}
     164
    151165stree_stat_t *stree_stat_new(stat_class_t sc)
    152166{
     
    267281}
    268282
     283stree_except_t *stree_except_new(void)
     284{
     285        stree_except_t *except_c;
     286
     287        except_c = calloc(1, sizeof(stree_except_t));
     288        if (except_c == NULL) {
     289                printf("Memory allocation failed.\n");
     290                exit(1);
     291        }
     292
     293        return except_c;
     294}
     295
    269296stree_block_t *stree_block_new(void)
    270297{
     
    361388}
    362389
     390stree_index_t *stree_index_new(void)
     391{
     392        stree_index_t *index;
     393
     394        index = calloc(1, sizeof(stree_index_t));
     395        if (index == NULL) {
     396                printf("Memory allocation failed.\n");
     397                exit(1);
     398        }
     399
     400        return index;
     401}
     402
    363403stree_nameref_t *stree_nameref_new(void)
    364404{
     
    428468}
    429469
     470stree_taccess_t *stree_taccess_new(void)
     471{
     472        stree_taccess_t *taccess;
     473
     474        taccess = calloc(1, sizeof(stree_taccess_t));
     475        if (taccess == NULL) {
     476                printf("Memory allocation failed.\n");
     477                exit(1);
     478        }
     479
     480        return taccess;
     481}
     482
    430483stree_tapply_t *stree_tapply_new(void)
    431484{
     
    441494}
    442495
    443 stree_taccess_t *stree_taccess_new(void)
    444 {
    445         stree_taccess_t *taccess;
    446 
    447         taccess = calloc(1, sizeof(stree_taccess_t));
    448         if (taccess == NULL) {
    449                 printf("Memory allocation failed.\n");
    450                 exit(1);
    451         }
    452 
    453         return taccess;
     496stree_tindex_t *stree_tindex_new(void)
     497{
     498        stree_tindex_t *tindex;
     499
     500        tindex = calloc(1, sizeof(stree_tindex_t));
     501        if (tindex == NULL) {
     502                printf("Memory allocation failed.\n");
     503                exit(1);
     504        }
     505
     506        return tindex;
    454507}
    455508
     
    506559        return program;
    507560}
     561
     562/** Determine if argument @a arg has attribute of class @a aac. */
     563bool_t stree_arg_has_attr(stree_fun_arg_t *arg, arg_attr_class_t aac)
     564{
     565        list_node_t *node;
     566        stree_arg_attr_t *attr;
     567
     568        node = list_first(&arg->attr);
     569        while (node != NULL) {
     570                attr = list_node_data(node, stree_arg_attr_t *);
     571                if (attr->aac == aac)
     572                        return b_true;
     573
     574                node = list_next(&arg->attr, node);
     575        }
     576
     577        return b_false;
     578}
     579
     580/** Determine wheter @a a is derived (transitively) from @a b.
     581 *
     582 * @param a     Derived CSI.
     583 * @param b     Base CSI.
     584 * @return      @c b_true if @a a is equal to or directly or indirectly
     585 *              derived from @a b.
     586 */
     587bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b)
     588{
     589        stree_csi_t *csi;
     590
     591        csi = a;
     592        while (csi != NULL) {
     593                if (csi == b)
     594                        return b_true;
     595
     596                csi = csi->base_csi;
     597        }
     598
     599        /* We went all the way to the root and did not find b. */
     600        return b_false;
     601}
  • uspace/app/sbi/src/stree.h

    rfa36f29 r94d484a  
    4141
    4242stree_fun_arg_t *stree_fun_arg_new(void);
     43stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac);
    4344
    4445stree_stat_t *stree_stat_new(stat_class_t sc);
     
    5152stree_wef_t *stree_wef_new(void);
    5253stree_exps_t *stree_exps_new(void);
     54
     55stree_except_t *stree_except_new(void);
    5356stree_block_t *stree_block_new(void);
    5457
     
    5962stree_access_t *stree_access_new(void);
    6063stree_call_t *stree_call_new(void);
     64stree_index_t *stree_index_new(void);
    6165stree_nameref_t *stree_nameref_new(void);
    6266
     
    6670
    6771stree_texpr_t *stree_texpr_new(texpr_class_t tc);
     72stree_taccess_t *stree_taccess_new(void);
    6873stree_tapply_t *stree_tapply_new(void);
    69 stree_taccess_t *stree_taccess_new(void);
     74stree_tindex_t *stree_tindex_new(void);
    7075stree_tliteral_t *stree_tliteral_new(void);
    7176stree_tnameref_t *stree_tnameref_new(void);
     
    7479stree_program_t *stree_program_new(void);
    7580
     81bool_t stree_arg_has_attr(stree_fun_arg_t *arg, arg_attr_class_t aac);
     82bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b);
     83
    7684#endif
  • uspace/app/sbi/src/stree_t.h

    rfa36f29 r94d484a  
    151151} stree_assign_t;
    152152
     153/** Indexing operation */
     154typedef struct {
     155        /** Base */
     156        struct stree_expr *base;
     157
     158        /** Arguments (indices) */
     159        list_t args; /* of stree_expr_t */
     160} stree_index_t;
     161
    153162/** Arithmetic expression class */
    154163typedef enum {
     
    161170        ec_access,
    162171        ec_call,
    163         ec_assign
     172        ec_assign,
     173        ec_index
    164174} expr_class_t;
    165175
     
    177187                stree_access_t *access;
    178188                stree_call_t *call;
     189                stree_index_t *index;
    179190                stree_assign_t *assign;
    180191        } u;
     
    217228} stree_tapply_t;
    218229
     230/** Type index operation */
     231typedef struct {
     232        /** Base type */
     233        struct stree_texpr *base_type;
     234
     235        /**
     236         * Number of arguments (rank). Needed when only rank is specified
     237         * and @c args are not used.
     238         */
     239        int n_args;
     240
     241        /** Arguments (extents) */
     242        list_t args; /* of stree_expr_t */
     243} stree_tindex_t;
     244
    219245/** Type expression class */
    220246typedef enum {
     
    222248        tc_tnameref,
    223249        tc_taccess,
    224         tc_tapply
     250        tc_tapply,
     251        tc_tindex
    225252} texpr_class_t;
    226253
     
    234261                stree_taccess_t *taccess;
    235262                stree_tapply_t *tapply;
     263                stree_tindex_t *tindex;
    236264        } u;
    237265} stree_texpr_t;
     
    252280        stree_texpr_t *type;
    253281} stree_vdecl_t;
     282
     283/** @c except clause */
     284typedef struct {
     285        stree_ident_t *evar;
     286        stree_texpr_t *etype;
     287        stree_block_t *block;
     288} stree_except_t;
    254289
    255290/** If statement */
     
    273308/** Raise statement */
    274309typedef struct {
     310        stree_expr_t *expr;
    275311} stree_raise_t;
    276312
     
    288324typedef struct {
    289325        stree_block_t *with_block;
    290         list_t except_blocks; /* of stree_block_t */
     326        list_t except_clauses; /* of stree_except_t */
    291327        stree_block_t *finally_block;
    292328} stree_wef_t;
     329
    293330
    294331/** Statement class */
     
    320357} stree_stat_t;
    321358
     359/** Argument attribute class */
     360typedef enum {
     361        /** Packed argument (for variadic functions) */
     362        aac_packed
     363} arg_attr_class_t;
     364
     365/** Argument atribute */
     366typedef struct {
     367        arg_attr_class_t aac;
     368} stree_arg_attr_t;
     369
    322370/** Formal function parameter */
    323371typedef struct {
     
    327375        /* Argument type */
    328376        stree_texpr_t *type;
     377
     378        /* Attributes */
     379        list_t attr; /* of stree_arg_attr_t */
    329380} stree_fun_arg_t;
    330381
     
    339390        /** Formal parameters */
    340391        list_t args; /* of stree_fun_arg_t */
     392
     393        /** Variadic argument or @c NULL if none. */
     394        stree_fun_arg_t *varg;
    341395
    342396        /** Return type */
     
    400454        stree_texpr_t *base_csi_ref;
    401455
     456        /** Base CSI. Only available when ancr_state == ws_visited. */
     457        struct stree_csi *base_csi;
     458
    402459        /** Node state for ancr walks. */
    403460        walk_state_t ancr_state;
  • uspace/app/sbi/src/strtab.c

    rfa36f29 r94d484a  
    3737#include <string.h>
    3838#include "mytypes.h"
    39 #include "compat.h"
     39#include "os/os.h"
    4040#include "list.h"
    4141
     
    5959        while (node != NULL) {
    6060                ++sid;
    61                 if (strcmp(str, list_node_data(node, char *)) == 0)
     61                if (os_str_cmp(str, list_node_data(node, char *)) == 0)
    6262                        return sid;
    6363
     
    6666
    6767        ++sid;
    68         list_append(&str_list, strdup(str));
     68        list_append(&str_list, os_str_dup(str));
    6969
    7070        return sid;
     
    8585        if (node == NULL) {
    8686                printf("Internal error: Invalid SID %d", sid);
    87                 exit(1);
     87                abort();
    8888        }
    8989
  • uspace/dist/sysel/count.sy

    rfa36f29 r94d484a  
     1--
     2-- Copyright (c) 2010 Jiri Svoboda
     3-- All rights reserved.
     4--
     5-- Redistribution and use in source and binary forms, with or without
     6-- modification, are permitted provided that the following conditions
     7-- are met:
     8--
     9-- o Redistributions of source code must retain the above copyright
     10--   notice, this list of conditions and the following disclaimer.
     11-- o Redistributions in binary form must reproduce the above copyright
     12--   notice, this list of conditions and the following disclaimer in the
     13--   documentation and/or other materials provided with the distribution.
     14-- o The name of the author may not be used to endorse or promote products
     15--   derived from this software without specific prior written permission.
     16--
     17-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27--
     28
    129class CountDemo is
    230        fun Count(a : int; b : int) is
  • uspace/dist/sysel/hello.sy

    rfa36f29 r94d484a  
     1--
     2-- Copyright (c) 2010 Jiri Svoboda
     3-- All rights reserved.
     4--
     5-- Redistribution and use in source and binary forms, with or without
     6-- modification, are permitted provided that the following conditions
     7-- are met:
     8--
     9-- o Redistributions of source code must retain the above copyright
     10--   notice, this list of conditions and the following disclaimer.
     11-- o Redistributions in binary form must reproduce the above copyright
     12--   notice, this list of conditions and the following disclaimer in the
     13--   documentation and/or other materials provided with the distribution.
     14-- o The name of the author may not be used to endorse or promote products
     15--   derived from this software without specific prior written permission.
     16--
     17-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27--
     28
    129class HelloWorld is
    230        fun Main() is
  • uspace/dist/sysel/inherit.sy

    rfa36f29 r94d484a  
     1--
     2-- Copyright (c) 2010 Jiri Svoboda
     3-- All rights reserved.
     4--
     5-- Redistribution and use in source and binary forms, with or without
     6-- modification, are permitted provided that the following conditions
     7-- are met:
     8--
     9-- o Redistributions of source code must retain the above copyright
     10--   notice, this list of conditions and the following disclaimer.
     11-- o Redistributions in binary form must reproduce the above copyright
     12--   notice, this list of conditions and the following disclaimer in the
     13--   documentation and/or other materials provided with the distribution.
     14-- o The name of the author may not be used to endorse or promote products
     15--   derived from this software without specific prior written permission.
     16--
     17-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27--
     28
    129class A is
    230        fun Foo() is
  • uspace/dist/sysel/list.sy

    rfa36f29 r94d484a  
    1 
    2 class ListNode is
    3         var value : int;
    4 
    5         var prev : ListNode;
    6         var next : ListNode;
    7         var head : ListNode;
    8 
    9         fun GetNext() : ListNode is
    10                 if next != head then
    11                         return next;
    12                 else
    13                         return nil;
    14                 end
    15         end
    16 
    17         fun GetPrev() : ListNode is
    18                 if prev != head then
    19                         return next;
    20                 else
    21                         return nil;
    22                 end
    23         end
    24 
    25         fun GetValue() : int is
    26                 return value;
    27         end
    28 end
     1--
     2-- Copyright (c) 2010 Jiri Svoboda
     3-- All rights reserved.
     4--
     5-- Redistribution and use in source and binary forms, with or without
     6-- modification, are permitted provided that the following conditions
     7-- are met:
     8--
     9-- o Redistributions of source code must retain the above copyright
     10--   notice, this list of conditions and the following disclaimer.
     11-- o Redistributions in binary form must reproduce the above copyright
     12--   notice, this list of conditions and the following disclaimer in the
     13--   documentation and/or other materials provided with the distribution.
     14-- o The name of the author may not be used to endorse or promote products
     15--   derived from this software without specific prior written permission.
     16--
     17-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27--
    2928
    3029class List is
     
    5958end
    6059
     60class ListNode is
     61        var value : int;
     62
     63        var prev : ListNode;
     64        var next : ListNode;
     65        var head : ListNode;
     66
     67        fun GetNext() : ListNode is
     68                if next != head then
     69                        return next;
     70                else
     71                        return nil;
     72                end
     73        end
     74
     75        fun GetPrev() : ListNode is
     76                if prev != head then
     77                        return next;
     78                else
     79                        return nil;
     80                end
     81        end
     82
     83        fun GetValue() : int is
     84                return value;
     85        end
     86end
     87
    6188class ListDemo is
    6289        fun Main() is
Note: See TracChangeset for help on using the changeset viewer.