Changeset 23de644 in mainline


Ignore:
Timestamp:
2010-04-04T22:31:01Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
074444f, ecb6ac32
Parents:
3aae4e8
Message:

Update SBI to rev. 174.

Location:
uspace
Files:
6 added
30 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/Makefile

    r3aae4e8 r23de644  
    3434
    3535SOURCES = \
     36        src/builtin/bi_error.c \
    3637        src/builtin/bi_fun.c \
    3738        src/builtin/bi_textfile.c \
    3839        src/os/helenos.c \
    3940        src/ancr.c \
     41        src/bigint.c \
    4042        src/builtin.c \
    4143        src/imode.c \
  • uspace/app/sbi/src/builtin.c

    r3aae4e8 r23de644  
    4141#include <assert.h>
    4242#include "ancr.h"
     43#include "builtin/bi_error.h"
    4344#include "builtin/bi_fun.h"
    4445#include "builtin/bi_textfile.h"
     
    8687         */
    8788
     89        bi_error_declare(bi);
    8890        bi_fun_declare(bi);
    8991        bi_textfile_declare(bi);
     
    9294        ancr_module_process(program, program->module);
    9395
     96        bi_error_bind(bi);
    9497        bi_fun_bind(bi);
    9598        bi_textfile_bind(bi);
  • uspace/app/sbi/src/builtin/bi_fun.c

    r3aae4e8 r23de644  
    3232#include <stdlib.h>
    3333#include <assert.h>
     34#include "../bigint.h"
    3435#include "../builtin.h"
    3536#include "../list.h"
     
    107108        switch (var->vc) {
    108109        case vc_int:
    109                 printf("%d\n", var->u.int_v->value);
     110                bigint_print(&var->u.int_v->value);
     111                putchar('\n');
    110112                break;
    111113        case vc_string:
  • uspace/app/sbi/src/builtin/bi_textfile.c

    r3aae4e8 r23de644  
    3232#include <stdlib.h>
    3333#include <assert.h>
     34#include "../bigint.h"
    3435#include "../builtin.h"
    3536#include "../debug.h"
     
    344345        /* Construct return value. */
    345346        eof_int = rdata_int_new();
    346         eof_int->value = eof_flag;
     347        bigint_init(&eof_int->value, eof_flag);
    347348
    348349        eof_var = rdata_var_new(vc_int);
  • uspace/app/sbi/src/builtin_t.h

    r3aae4e8 r23de644  
    4242        /** Grandfather object */
    4343        struct stree_symbol *gf_class;
     44
     45        /** Error class for nil reference access. */
     46        struct stree_csi *error_nilreference;
     47
     48        /** Error class for out-of-bounds array access. */
     49        struct stree_csi *error_outofbounds;
    4450} builtin_t;
    4551
  • uspace/app/sbi/src/debug.h

    r3aae4e8 r23de644  
    4545//#define DEBUG_RUN_TRACE
    4646
     47/** Uncomment this to get verbose debugging messages for bigint computation. */
     48//#define DEBUG_BIGINT_TRACE
     49
    4750#endif
  • uspace/app/sbi/src/imode.c

    r3aae4e8 r23de644  
    4040#include <stdio.h>
    4141#include <stdlib.h>
     42#include "os/os.h"
    4243#include "ancr.h"
    4344#include "assert.h"
     
    122123        list_append(&run.thread_ar->proc_ar, proc_ar);
    123124
     125        printf("SBI interactive mode. ");
     126        os_input_disp_help();
     127
    124128        quit_im = b_false;
    125129        while (quit_im != b_true) {
     
    152156                run_stat(&run, stat, &rexpr);
    153157
     158                /* Check for unhandled exceptions. */
     159                run_exc_check_unhandled(&run);
     160
    154161                if (rexpr != NULL) {
    155162                        /* Convert expression result to value item. */
  • uspace/app/sbi/src/lex.c

    r3aae4e8 r23de644  
    3434#include <stdio.h>
    3535#include <stdlib.h>
     36#include "bigint.h"
    3637#include "mytypes.h"
    3738#include "input.h"
     
    135136        { lc_assign,    "=" },
    136137        { lc_plus,      "+" },
     138        { lc_minus,     "-" },
     139        { lc_mult,      "*" },
    137140        { lc_increase,  "+=" },
    138141
     
    205208                break;
    206209        case lc_lit_int:
    207                 printf("(%d)", lem->u.lit_int.value);
     210                printf("(");
     211                bigint_print(&lem->u.lit_int.value);
     212                printf(")");
    208213                break;
    209214        case lc_lit_string:
     
    267272 *
    268273 * @param lex           Lexer object.
     274 * @return              Pointer to current lem. Owned by @a lex and only valid
     275 *                      until next call to lex_next().
    269276 */
    270277lem_t *lex_get_current(lex_t *lex)
     
    376383                lex->current.lclass = lc_plus; ++bp; break;
    377384
     385        case '-':
     386                lex->current.lclass = lc_minus; ++bp; break;
     387
     388        case '*':
     389                lex->current.lclass = lc_mult; ++bp; break;
     390
    378391        case '<':
    379392                if (bp[1] == '=') {
     
    458471{
    459472        char *bp;
    460         int value;
     473        bigint_t value;
     474        bigint_t dgval;
     475        bigint_t base;
     476        bigint_t tprod;
    461477
    462478        bp = lex->ibp;
    463         value = 0;
     479
     480        bigint_init(&value, 0);
     481        bigint_init(&base, 10);
    464482
    465483        while (is_digit(*bp)) {
    466                 value = value * 10 + digit_value(*bp);
     484                bigint_mul(&value, &base, &tprod);
     485                bigint_init(&dgval, digit_value(*bp));
     486
     487                bigint_destroy(&value);
     488                bigint_add(&tprod, &dgval, &value);
     489                bigint_destroy(&tprod);
     490                bigint_destroy(&dgval);
     491
    467492                ++bp;
    468493        }
    469494
     495        bigint_destroy(&base);
     496
    470497        lex->ibp = bp;
    471498
    472499        lex->current.lclass = lc_lit_int;
    473         lex->current.u.lit_int.value = value;
     500        bigint_shallow_copy(&value, &lex->current.u.lit_int.value);
    474501}
    475502
  • uspace/app/sbi/src/lex_t.h

    r3aae4e8 r23de644  
    2929#ifndef LEX_T_H_
    3030#define LEX_T_H_
     31
     32#include "bigint_t.h"
    3133
    3234/** Lexical element class */
     
    9597        lc_assign,
    9698        lc_plus,
     99        lc_minus,
     100        lc_mult,
    97101        lc_increase,
    98102
     
    112116typedef struct {
    113117        /* Integer value */
    114         int value;
     118        bigint_t value;
    115119} lem_lit_int_t;
    116120
  • uspace/app/sbi/src/main.c

    r3aae4e8 r23de644  
    9494        parse_module(&parse);
    9595
     96        /* Check for parse errors. */
    9697        if (parse.error)
    9798                return 1;
     
    105106        stype_module(&stype, program->module);
    106107
     108        /* Check for typing errors. */
    107109        if (stype.error)
    108110                return 1;
     
    111113        run_init(&run);
    112114        run_program(&run, program);
     115
     116        /* Check for run-time errors. */
     117        if (run.thread_ar->error)
     118                return 1;
    113119
    114120        return 0;
  • uspace/app/sbi/src/mytypes.h

    r3aae4e8 r23de644  
    4747#define EOK 0
    4848
     49#include "bigint_t.h"
    4950#include "builtin_t.h"
    5051#include "input_t.h"
  • uspace/app/sbi/src/os/helenos.c

    r3aae4e8 r23de644  
    101101}
    102102
     103/** Display survival help message. */
     104void os_input_disp_help(void)
     105{
     106        printf("Press Ctrl-Q to quit.\n");
     107}
     108
    103109/** Read one line of input from the user. */
    104110int os_input_line(char **ptr)
  • uspace/app/sbi/src/os/os.h

    r3aae4e8 r23de644  
    3434char *os_str_dup(const char *str);
    3535int os_str_get_char(const char *str, int index, int *out_char);
     36void os_input_disp_help(void);
    3637int os_input_line(char **ptr);
    3738int os_exec(char *const cmd[]);
  • uspace/app/sbi/src/os/posix.c

    r3aae4e8 r23de644  
    9595static char os_input_buffer[OS_INPUT_BUFFER_SIZE];
    9696
     97/** Display survival help message. */
     98void os_input_disp_help(void)
     99{
     100        printf("Send ^C (SIGINT) to quit.\n");
     101}
     102
    97103/** Read one line of input from the user. */
    98104int os_input_line(char **ptr)
  • uspace/app/sbi/src/p_expr.c

    r3aae4e8 r23de644  
    3131#include <assert.h>
    3232#include <stdlib.h>
     33#include "bigint.h"
    3334#include "debug.h"
    3435#include "lex.h"
     
    4445static stree_expr_t *parse_comparative(parse_t *parse);
    4546static stree_expr_t *parse_additive(parse_t *parse);
     47static stree_expr_t *parse_multip(parse_t *parse);
    4648static stree_expr_t *parse_prefix(parse_t *parse);
    4749static stree_expr_t *parse_prefix_new(parse_t *parse);
     
    5153static stree_expr_t *parse_pf_index(parse_t *parse, stree_expr_t *a);
    5254static stree_expr_t *parse_pf_as(parse_t *parse, stree_expr_t *a);
     55static stree_expr_t *parse_paren(parse_t *parse);
    5356static stree_expr_t *parse_primitive(parse_t *parse);
    5457static stree_expr_t *parse_nameref(parse_t *parse);
     
    166169        stree_expr_t *a, *b, *tmp;
    167170        stree_binop_t *binop;
    168 
    169         a = parse_prefix(parse);
    170         while (lcur_lc(parse) == lc_plus) {
     171        binop_class_t bc;
     172
     173        a = parse_multip(parse);
     174        while (lcur_lc(parse) == lc_plus || lcur_lc(parse) == lc_minus) {
    171175                if (parse_is_error(parse))
    172176                        break;
    173177
     178                switch (lcur_lc(parse)) {
     179                case lc_plus: bc = bo_plus; break;
     180                case lc_minus: bc = bo_minus; break;
     181                default: assert(b_false);
     182                }
     183
    174184                lskip(parse);
    175                 b = parse_prefix(parse);
    176 
    177                 binop = stree_binop_new(bo_plus);
     185                b = parse_multip(parse);
     186
     187                binop = stree_binop_new(bc);
    178188                binop->arg1 = a;
    179189                binop->arg2 = b;
     
    187197}
    188198
     199/** Parse multiplicative expression.
     200 *
     201 * @param parse         Parser object.
     202 */
     203static stree_expr_t *parse_multip(parse_t *parse)
     204{
     205        stree_expr_t *a, *b, *tmp;
     206        stree_binop_t *binop;
     207        binop_class_t bc;
     208
     209        a = parse_prefix(parse);
     210        while (lcur_lc(parse) == lc_mult) {
     211                if (parse_is_error(parse))
     212                        break;
     213
     214                switch (lcur_lc(parse)) {
     215                case lc_mult: bc = bo_mult; break;
     216                default: assert(b_false);
     217                }
     218
     219                lskip(parse);
     220                b = parse_prefix(parse);
     221
     222                binop = stree_binop_new(bc);
     223                binop->arg1 = a;
     224                binop->arg2 = b;
     225
     226                tmp = stree_expr_new(ec_binop);
     227                tmp->u.binop = binop;
     228                a = tmp;
     229        }
     230
     231        return a;
     232}
     233
    189234/** Parse prefix expression.
    190235 *
     
    194239{
    195240        stree_expr_t *a;
     241        stree_expr_t *tmp;
     242        stree_unop_t *unop;
     243        unop_class_t uc;
    196244
    197245        switch (lcur_lc(parse)) {
    198246        case lc_plus:
    199                 printf("Unimplemented: Unary plus.\n");
    200                 a = parse_recovery_expr(parse);
    201                 parse_note_error(parse);
     247        case lc_minus:
     248                if (parse_is_error(parse))
     249                        return parse_recovery_expr(parse);
     250
     251                switch (lcur_lc(parse)) {
     252                case lc_plus: uc = uo_plus; break;
     253                case lc_minus: uc = uo_minus; break;
     254                default: assert(b_false);
     255                }
     256
     257                lskip(parse);
     258                a = parse_postfix(parse);
     259
     260                unop = stree_unop_new(uc);
     261                unop->arg = a;
     262
     263                tmp = stree_expr_new(ec_unop);
     264                tmp->u.unop = unop;
     265                a = tmp;
    202266                break;
    203267        case lc_new:
     
    248312        stree_expr_t *tmp;
    249313
    250         a = parse_primitive(parse);
     314        a = parse_paren(parse);
    251315
    252316        while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lparen ||
     
    398462}
    399463
     464/** Parse possibly partenthesized expression.
     465 *
     466 * @param parse         Parser object.
     467 */
     468static stree_expr_t *parse_paren(parse_t *parse)
     469{
     470        stree_expr_t *expr;
     471
     472        if (lcur_lc(parse) == lc_lparen) {
     473                lskip(parse);
     474                expr = parse_expr(parse);
     475                lmatch(parse, lc_rparen);
     476        } else {
     477                expr = parse_primitive(parse);
     478        }
     479
     480        return expr;
     481}
     482
     483
    400484/** Parse primitive expression.
    401485 *
     
    459543
    460544        literal = stree_literal_new(ltc_int);
    461         literal->u.lit_int.value = lcur(parse)->u.lit_int.value;
     545        bigint_clone(&lcur(parse)->u.lit_int.value,
     546            &literal->u.lit_int.value);
    462547
    463548        lskip(parse);
  • uspace/app/sbi/src/parse.c

    r3aae4e8 r23de644  
    7979static stree_except_t *parse_except(parse_t *parse);
    8080
     81/** Initialize parser object.
     82 *
     83 * Set up parser @a parse to use lexer @a lex for input and to store
     84 * output (i.e. new declarations) to program @a prog. @a prog is not
     85 * necessarily empty, the declarations being parsed are simply added
     86 * to it.
     87 *
     88 * @param parse         Parser object.
     89 * @param prog          Destination program stree.
     90 * @param lex           Input lexer.
     91 */
    8192void parse_init(parse_t *parse, stree_program_t *prog, struct lex *lex)
    8293{
     
    91102}
    92103
    93 /** Parse module. */
     104/** Parse module.
     105 *
     106 * Parse a program module.
     107 *
     108 * The input is read using the lexer associated with @a parse. The resulting
     109 * declarations are added to existing declarations in the program associated
     110 * with @a parse.
     111 *
     112 * If any parse error occurs, parse->error will @c b_true when this function
     113 * returns. parse->error_bailout will be @c b_true if the error has not
     114 * been recovered yet. Similar holds for other parsing functions in this
     115 * module.
     116 *
     117 * @param parse         Parser object.
     118 */
    94119void parse_module(parse_t *parse)
    95120{
     
    117142}
    118143
    119 /** Parse class, struct or interface declaration. */
     144/** Parse class, struct or interface declaration.
     145 *
     146 * @param parse         Parser object.
     147 * @param dclass        What to parse: @c lc_class, @c lc_struct or @c lc_csi.
     148 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     149 * @return              New syntax tree node.
     150 */
    120151static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
    121152    stree_csi_t *outer_csi)
     
    169200}
    170201
    171 /** Parse class, struct or interface member. */
     202/** Parse class, struct or interface member.
     203 *
     204 * @param parse         Parser object.
     205 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     206 * @return              New syntax tree node.
     207 */
    172208static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi)
    173209{
     
    211247
    212248
    213 /** Parse member function. */
     249/** Parse member function.
     250 *
     251 * @param parse         Parser object.
     252 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     253 * @return              New syntax tree node.
     254 */
    214255static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi)
    215256{
     
    297338}
    298339
    299 /** Parse member variable. */
     340/** Parse member variable.
     341 *
     342 * @param parse         Parser object.
     343 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     344 * @return              New syntax tree node.
     345 */
    300346static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi)
    301347{
     
    318364}
    319365
    320 /** Parse member property. */
     366/** Parse member property.
     367 *
     368 * @param parse         Parser object.
     369 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     370 * @return              New syntax tree node.
     371 */
    321372static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi)
    322373{
     
    424475}
    425476
    426 /** Parse symbol attribute. */
     477/** Parse symbol attribute.
     478 *
     479 * @param parse         Parser object.
     480 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     481 * @return              New syntax tree node.
     482 */
    427483static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse)
    428484{
     
    442498}
    443499
    444 /** Parse formal function argument. */
     500/** Parse formal function argument.
     501 *
     502 * @param parse         Parser object.
     503 * @return              New syntax tree node.
     504 */
    445505static stree_proc_arg_t *parse_proc_arg(parse_t *parse)
    446506{
     
    468528}
    469529
    470 /** Parse argument attribute. */
     530/** Parse argument attribute.
     531 *
     532 * @param parse         Parser object.
     533 * @return              New syntax tree node.
     534 */
    471535static stree_arg_attr_t *parse_arg_attr(parse_t *parse)
    472536{
     
    486550}
    487551
    488 /** Parse statement block. */
     552/** Parse statement block.
     553 *
     554 * @param parse         Parser object.
     555 * @return              New syntax tree node.
     556 */
    489557static stree_block_t *parse_block(parse_t *parse)
    490558{
     
    509577}
    510578
    511 /** Parse statement. */
     579/** Parse statement.
     580 *
     581 * @param parse         Parser object.
     582 * @return              New syntax tree node.
     583 */
    512584stree_stat_t *parse_stat(parse_t *parse)
    513585{
     
    576648}
    577649
    578 /** Parse variable declaration statement. */
     650/** Parse variable declaration statement.
     651 *
     652 * @param parse         Parser object.
     653 * @return              New syntax tree node.
     654 */
    579655static stree_vdecl_t *parse_vdecl(parse_t *parse)
    580656{
     
    603679}
    604680
    605 /** Parse @c if statement, */
     681/** Parse @c if statement.
     682 *
     683 * @param parse         Parser object.
     684 * @return              New syntax tree node.
     685 */
    606686static stree_if_t *parse_if(parse_t *parse)
    607687{
     
    629709}
    630710
    631 /** Parse @c while statement. */
     711/** Parse @c while statement.
     712 *
     713 * @param parse         Parser object.
     714 */
    632715static stree_while_t *parse_while(parse_t *parse)
    633716{
     
    648731}
    649732
    650 /** Parse @c for statement. */
     733/** Parse @c for statement.
     734 *
     735 * @param parse         Parser object.
     736 * @return              New syntax tree node.
     737 */
    651738static stree_for_t *parse_for(parse_t *parse)
    652739{
     
    671758}
    672759
    673 /** Parse @c raise statement. */
     760/** Parse @c raise statement.
     761 *
     762 * @param parse         Parser object.
     763 */
    674764static stree_raise_t *parse_raise(parse_t *parse)
    675765{
     
    687777}
    688778
    689 /** Parse @c return statement. */
     779/** Parse @c return statement.
     780 *
     781 * @param parse         Parser object.
     782 * @return              New syntax tree node.
     783 */
    690784static stree_return_t *parse_return(parse_t *parse)
    691785{
     
    704798}
    705799
    706 /* Parse @c with-except-finally statement. */
     800/* Parse @c with-except-finally statement.
     801 *
     802 * @param parse         Parser object.
     803 * @return              New syntax tree node.
     804 */
    707805static stree_wef_t *parse_wef(parse_t *parse)
    708806{
     
    746844}
    747845
    748 /* Parse expression statement. */
     846/* Parse expression statement.
     847 *
     848 * @param parse         Parser object.
     849 * @return              New syntax tree node.
     850 */
    749851static stree_exps_t *parse_exps(parse_t *parse)
    750852{
     
    764866}
    765867
    766 /* Parse @c except clause. */
     868/* Parse @c except clause.
     869 *
     870 * @param parse         Parser object.
     871 * @return              New syntax tree node.
     872 */
    767873static stree_except_t *parse_except(parse_t *parse)
    768874{
     
    785891}
    786892
    787 /** Parse identifier. */
     893/** Parse identifier.
     894 *
     895 * @param parse         Parser object.
     896 * @return              New syntax tree node.
     897 */
    788898stree_ident_t *parse_ident(parse_t *parse)
    789899{
     
    801911}
    802912
    803 /** Signal a parse error, start bailing out from parser. */
     913/** Signal a parse error, start bailing out from parser.
     914 *
     915 * @param parse         Parser object.
     916 */
    804917void parse_raise_error(parse_t *parse)
    805918{
     
    808921}
    809922
    810 /** Note a parse error that has been immediately recovered. */
     923/** Note a parse error that has been immediately recovered.
     924 *
     925 * @param parse         Parser object.
     926 */
    811927void parse_note_error(parse_t *parse)
    812928{
     
    814930}
    815931
    816 /** Check if we are currently bailing out of parser due to a parse error. */
     932/** Check if we are currently bailing out of parser due to a parse error.
     933 *
     934 * @param parse         Parser object.
     935 */
    817936bool_t parse_is_error(parse_t *parse)
    818937{
     
    823942 *
    824943 * Still remember that there was an error, but stop bailing out.
     944 *
     945 * @param parse         Parser object.
    825946 */
    826947void parse_recover_error(parse_t *parse)
     
    832953}
    833954
    834 /** Return current lem. */
     955/** Return current lem.
     956 *
     957 * @param parse         Parser object.
     958 * @return              Pointer to current lem. Only valid until the lexing
     959 *                      position is advanced.
     960 */
    835961lem_t *lcur(parse_t *parse)
    836962{
     
    841967}
    842968
    843 /** Retturn current lem lclass. */
     969/** Return current lem lclass.
     970 *
     971 * @param parse         Parser object.
     972 * @return              Lclass of the current lem.
     973 */
    844974lclass_t lcur_lc(parse_t *parse)
    845975{
     
    861991}
    862992
    863 /** Skip to next lem. */
     993/** Skip to next lem.
     994 *
     995 * @param parse         Parser object.
     996 */
    864997void lskip(parse_t *parse)
    865998{
     
    8701003}
    8711004
    872 /** Verify that lclass of current lem is @a lc. */
     1005/** Verify that lclass of current lem is @a lc.
     1006 *
     1007 * If a lem of different lclass is found, a parse error is raised and
     1008 * a message is printed.
     1009 *
     1010 * @param parse         Parser object.
     1011 * @param lc            Expected lclass.
     1012 */
    8731013void lcheck(parse_t *parse, lclass_t lc)
    8741014{
     
    8871027}
    8881028
    889 /** Verify that lclass of current lem is @a lc and go to next lem. */
     1029/** Verify that lclass of current lem is @a lc and go to next lem.
     1030 *
     1031 * If a lem of different lclass is found, a parse error is raised and
     1032 * a message is printed.
     1033 *
     1034 * @param parse         Parser object.
     1035 * @param lc            Expected lclass.
     1036 */
    8901037void lmatch(parse_t *parse, lclass_t lc)
    8911038{
     
    9101057}
    9111058
    912 /** Display generic parsing error. */
     1059/** Raise and display generic parsing error.
     1060 *
     1061 * @param parse         Parser object.
     1062 */
    9131063void lunexpected_error(parse_t *parse)
    9141064{
     
    9201070}
    9211071
    922 /** Basically tells us whether @a lclass is in next(block). */
     1072/** Determine whether @a lclass is in follow(block).
     1073 *
     1074 * Tests whether @a lclass belongs to the follow(block) set, i.e. if it is
     1075 * lclass of a lem that can follow a block in the program.
     1076 *
     1077 * @param lclass        Lclass.
     1078 */
    9231079bool_t terminates_block(lclass_t lclass)
    9241080{
  • uspace/app/sbi/src/rdata.c

    r3aae4e8 r23de644  
    2727 */
    2828
    29 /** @file Run-time data representation. */
     29/** @file Run-time data representation.
     30 *
     31 * At run time SBI represents all data as a graph of interconnected @c var
     32 * nodes (variable nodes). Any piece of memory addressable by the program
     33 * (i.e. all variables) are stored in var nodes. However, var nodes are also
     34 * used internally to implement value items. (I.e. values in value items
     35 * have exactly the same structure as program variables).
     36 *
     37 * Unlike byte- or word-oriented memory on a real machine, var nodes provide
     38 * structured and typed storage. (This typing is dynamic, however and has
     39 * nothing to do with the static type system).
     40 *
     41 * There are several types of var nodes, one for each primitive type,
     42 * reference, delegate, array, and object. A reference var node contains
     43 * a pointer to another var node. Delegate var node points to some stree
     44 * declaration. Array and object var nodes refer to a collection of child
     45 * nodes (fields, elements).
     46 */
    3047
    3148#include <stdlib.h>
    3249#include <assert.h>
     50#include "bigint.h"
    3351#include "mytypes.h"
    3452#include "stree.h"
     
    5068static void rdata_var_print(rdata_var_t *var);
    5169
    52 
     70/** Allocate new data item.
     71 *
     72 * @param ic    Item class.
     73 * @return      New item.
     74 */
    5375rdata_item_t *rdata_item_new(item_class_t ic)
    5476{
     
    6587}
    6688
     89/** Allocate new address.
     90 *
     91 * @return      New address.
     92 */
    6793rdata_addr_var_t *rdata_addr_var_new(void)
    6894{
     
    78104}
    79105
     106/** Allocate new named property address.
     107 *
     108 * @return      New named property address.
     109 */
    80110rdata_aprop_named_t *rdata_aprop_named_new(void)
    81111{
     
    91121}
    92122
     123/** Allocate new indexed property address.
     124 *
     125 * @return      New indexed property address.
     126 */
    93127rdata_aprop_indexed_t *rdata_aprop_indexed_new(void)
    94128{
     
    104138}
    105139
     140/** Allocate new property address.
     141 *
     142 * @param apc   Property address class.
     143 * @return      New property address.
     144 */
    106145rdata_addr_prop_t *rdata_addr_prop_new(aprop_class_t apc)
    107146{
     
    118157}
    119158
     159/** Allocate new address.
     160 *
     161 * @param ac    Address class.
     162 * @return      New address.
     163 */
    120164rdata_address_t *rdata_address_new(address_class_t ac)
    121165{
     
    132176}
    133177
     178/** Allocate new value.
     179 *
     180 * @return      New value.
     181 */
    134182rdata_value_t *rdata_value_new(void)
    135183{
     
    145193}
    146194
     195/** Allocate new var node.
     196 *
     197 * @param vc    Var node class (varclass).
     198 * @return      New var node.
     199 */
    147200rdata_var_t *rdata_var_new(var_class_t vc)
    148201{
     
    159212}
    160213
     214/** Allocate new reference.
     215 *
     216 * @return      New reference.
     217 */
    161218rdata_ref_t *rdata_ref_new(void)
    162219{
     
    172229}
    173230
     231/** Allocate new delegate.
     232 *
     233 * @return      New delegate.
     234 */
    174235rdata_deleg_t *rdata_deleg_new(void)
    175236{
     
    185246}
    186247
     248/** Allocate new array.
     249 *
     250 * @return      New array.
     251 */
    187252rdata_array_t *rdata_array_new(int rank)
    188253{
     
    205270}
    206271
     272/** Allocate new object.
     273 *
     274 * @return      New object.
     275 */
    207276rdata_object_t *rdata_object_new(void)
    208277{
     
    218287}
    219288
     289/** Allocate new integer.
     290 *
     291 * @return      New integer.
     292 */
    220293rdata_int_t *rdata_int_new(void)
    221294{
     
    231304}
    232305
     306/** Allocate new string.
     307 *
     308 * @return      New string.
     309 */
    233310rdata_string_t *rdata_string_new(void)
    234311{
     
    244321}
    245322
     323/** Allocate new resource.
     324 *
     325 * @return      New resource.
     326 */
    246327rdata_resource_t *rdata_resource_new(void)
    247328{
     
    257338}
    258339
     340/** Allocate array elements.
     341 *
     342 * Allocates var nodes for elements of @a array.
     343 *
     344 * @param array         Array.
     345 */
    259346void rdata_array_alloc_element(rdata_array_t *array)
    260347{
     
    282369 * Dimension is the total number of elements in an array, in other words,
    283370 * the product of all extents.
     371 *
     372 * @param array         Array.
    284373 */
    285374static int rdata_array_get_dim(rdata_array_t *array)
     
    294383}
    295384
    296 /** Make copy of a variable. */
     385/** Make copy of a variable.
     386 *
     387 * Creates a new var node that is an exact copy of an existing var node.
     388 * This can be thought of as a shallow copy.
     389 *
     390 * @param src           Source var node.
     391 * @param dest          Place to store pointer to new var node.
     392 */
    297393void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest)
    298394{
     
    328424}
    329425
     426/** Copy integer.
     427 *
     428 * @param src           Source integer.
     429 * @param dest          Place to store pointer to new integer.
     430 */
    330431static void rdata_int_copy(rdata_int_t *src, rdata_int_t **dest)
    331432{
    332433        *dest = rdata_int_new();
    333         (*dest)->value = src->value;
    334 }
    335 
     434        bigint_clone(&src->value, &(*dest)->value);
     435}
     436
     437/** Copy string.
     438 *
     439 * @param src           Source string.
     440 * @param dest          Place to store pointer to new string.
     441 */
    336442static void rdata_string_copy(rdata_string_t *src, rdata_string_t **dest)
    337443{
     
    340446}
    341447
     448/** Copy reference.
     449 *
     450 * @param src           Source reference.
     451 * @param dest          Place to store pointer to new reference.
     452 */
    342453static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
    343454{
     
    346457}
    347458
     459/** Copy delegate.
     460 *
     461 * @param src           Source delegate.
     462 * @param dest          Place to store pointer to new delegate.
     463 */
    348464static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
    349465{
     
    353469}
    354470
     471/** Copy array.
     472 *
     473 * @param src           Source array.
     474 * @param dest          Place to store pointer to new array.
     475 */
    355476static void rdata_array_copy(rdata_array_t *src, rdata_array_t **dest)
    356477{
     
    360481}
    361482
     483/** Copy object.
     484 *
     485 * @param src           Source object.
     486 * @param dest          Place to store pointer to new object.
     487 */
    362488static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
    363489{
     
    367493}
    368494
     495/** Copy resource.
     496 *
     497 * @param src           Source resource.
     498 * @param dest          Place to store pointer to new resource.
     499 */
    369500static void rdata_resource_copy(rdata_resource_t *src, rdata_resource_t **dest)
    370501{
     
    375506/** Read data from a variable.
    376507 *
    377  * Return value stored in variable @a var.
     508 * This copies data from the variable to a value item. Ideally any read access
     509 * to a program variable should go through this function. (Keep in mind
     510 * that although values are composed of var nodes internally, but are not
     511 * variables per se. Therefore this function is not used to read from values)
     512 *
     513 * @param var           Variable to read from (var node where it is stored).
     514 * @param ritem         Place to store pointer to new value item read from
     515 *                      the variable.
    378516 */
    379517void rdata_var_read(rdata_var_t *var, rdata_item_t **ritem)
     
    393531/** Write data to a variable.
    394532 *
    395  * Store @a value to variable @a var.
     533 * This copies data to the variable from a value. Ideally any write access
     534 * to a program variable should go through this function. (Keep in mind
     535 * that even though values are composed of var nodes internally, but are not
     536 * variables per se. Therefore this function is not used to write to values)
     537 *
     538 * @param var           Variable to write to (var node where it is stored).
     539 * @param value         The value to write.
    396540 */
    397541void rdata_var_write(rdata_var_t *var, rdata_value_t *value)
     
    418562}
    419563
     564/** Print data item in human-readable form.
     565 *
     566 * @param item          Item to print.
     567 */
    420568void rdata_item_print(rdata_item_t *item)
    421569{
     
    437585}
    438586
     587/** Print address in human-readable form.
     588 *
     589 * Actually this displays contents of the var node that is being addressed.
     590 *
     591 * XXX Maybe we should really rather print the address and not the data
     592 * it is pointing to?
     593 *
     594 * @param item          Address to print.
     595 */
    439596static void rdata_address_print(rdata_address_t *address)
    440597{
     
    449606}
    450607
     608/** Print value in human-readable form.
     609 *
     610 * @param value         Value to print.
     611 */
    451612void rdata_value_print(rdata_value_t *value)
    452613{
     
    454615}
    455616
     617/** Print contents of var node in human-readable form.
     618 *
     619 * @param item          Var node to print.
     620 */
    456621static void rdata_var_print(rdata_var_t *var)
    457622{
    458623        switch (var->vc) {
    459624        case vc_int:
    460                 printf("int(%d)", var->u.int_v->value);
     625                printf("int(");
     626                bigint_print(&var->u.int_v->value);
     627                printf(")");
    461628                break;
    462629        case vc_string:
  • uspace/app/sbi/src/rdata_t.h

    r3aae4e8 r23de644  
    3535#include "intmap_t.h"
    3636
    37 /** Integer variable */
    38 typedef struct {
    39         /*
    40          * Note: Sysel int type should be able to store arbitrarily large
    41          * numbers. But for now we can live with limited width.
    42          */
    43         int value;
     37/** Integer variable.
     38 *
     39 * Sysel int type should be able to store arbitrarily (or at least
     40 * very) large numbers.
     41 */
     42typedef struct {
     43        bigint_t value;
    4444} rdata_int_t;
    4545
  • uspace/app/sbi/src/run.c

    r3aae4e8 r23de644  
    3232#include <stdlib.h>
    3333#include <assert.h>
     34#include "bigint.h"
    3435#include "builtin.h"
    3536#include "debug.h"
     
    5758
    5859static bool_t run_exc_match(run_t *run, stree_except_t *except_c);
     60static stree_csi_t *run_exc_payload_get_csi(run_t *run);
     61
    5962static rdata_var_t *run_aprop_get_tpos(run_t *run, rdata_address_t *aprop);
    6063
     
    113116        run_proc(run, proc_ar, &res);
    114117
    115         /* Check for unhandled exceptions. */
    116         if (run->thread_ar->bo_mode != bm_none) {
    117                 assert(run->thread_ar->bo_mode == bm_exc);
    118                 printf("Error: Unhandled exception.\n");
    119                 exit(1);
    120         }
     118        run_exc_check_unhandled(run);
    121119}
    122120
     
    302300
    303301        var->u.int_v = int_v;
    304         int_v->value = 0;
     302        bigint_init(&int_v->value, 0);
    305303
    306304        block_ar = run_get_current_block_ar(run);
     
    329327#endif
    330328        run_expr(run, if_s->cond, &rcond);
     329        if (run_is_bo(run))
     330                return;
    331331
    332332        if (run_item_boolean_value(run, rcond) == b_true) {
     
    357357#endif
    358358        run_expr(run, while_s->cond, &rcond);
     359        if (run_is_bo(run))
     360                return;
    359361
    360362        while (run_item_boolean_value(run, rcond) == b_true) {
    361363                run_block(run, while_s->body);
    362364                run_expr(run, while_s->cond, &rcond);
     365                if (run_is_bo(run))
     366                        return;
    363367
    364368                if (run->thread_ar->bo_mode != bm_none)
     
    381385#endif
    382386        run_expr(run, raise_s->expr, &rexpr);
     387        if (run_is_bo(run))
     388                return;
     389
    383390        run_cvt_value_item(run, rexpr, &rexpr_vi);
    384391
     
    401408#endif
    402409        run_expr(run, return_s->expr, &rexpr);
     410        if (run_is_bo(run))
     411                return;
     412
    403413        run_cvt_value_item(run, rexpr, &rexpr_vi);
    404414
     
    477487 *
    478488 * Checks if the currently active exception in the runner object @c run
    479  * matches except clause @c except_c. Generates an error if the exception
    480  * payload has invalid type (i.e. not an object).
     489 * matches except clause @c except_c.
    481490 *
    482491 * @param run           Runner object.
     
    486495static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
    487496{
     497        stree_csi_t *exc_csi;
     498        tdata_item_t *etype;
     499
     500        /* Get CSI of active exception. */
     501        exc_csi = run_exc_payload_get_csi(run);
     502
     503        /* Evaluate type expression in except clause. */
     504        run_texpr(run->program, run_get_current_csi(run), except_c->etype,
     505            &etype);
     506
     507        /* Determine if active exc. is derived from type in exc. clause. */
     508        return tdata_is_csi_derived_from_ti(exc_csi, etype);
     509}
     510
     511/** Return CSI of the active exception.
     512 *
     513 * @param run           Runner object.
     514 * @return              CSI of the active exception.
     515 */
     516static stree_csi_t *run_exc_payload_get_csi(run_t *run)
     517{
    488518        rdata_value_t *payload;
    489519        rdata_var_t *payload_v;
    490520        rdata_object_t *payload_o;
    491         tdata_item_t *etype;
    492521
    493522        payload = run->thread_ar->exc_payload;
     
    495524
    496525        if (payload->var->vc != vc_ref) {
     526                /* XXX Prevent this via static type checking. */
    497527                printf("Error: Exception payload must be an object "
    498528                    "(found type %d).\n", payload->var->vc);
     
    502532        payload_v = payload->var->u.ref_v->vref;
    503533        if (payload_v->vc != vc_object) {
     534                /* XXX Prevent this via static type checking. */
    504535                printf("Error: Exception payload must be an object "
    505536                    "(found type %d).\n", payload_v->vc);
     
    517548        assert(payload_o->class_sym->sc == sc_csi);
    518549
    519         /* Evaluate type expression in except clause. */
    520         run_texpr(run->program, run_get_current_csi(run), except_c->etype,
    521             &etype);
    522 
    523         return tdata_is_csi_derived_from_ti(payload_o->class_sym->u.csi,
    524             etype);
     550        return payload_o->class_sym->u.csi;
     551}
     552
     553
     554/** Check for unhandled exception.
     555 *
     556 * Checks whether there is an active exception. If so, it prints an
     557 * error message and raises a run-time error.
     558 *
     559 * @param run           Runner object.
     560 */
     561void run_exc_check_unhandled(run_t *run)
     562{
     563        stree_csi_t *exc_csi;
     564
     565        if (run->thread_ar->bo_mode != bm_none) {
     566                assert(run->thread_ar->bo_mode == bm_exc);
     567
     568                exc_csi = run_exc_payload_get_csi(run);
     569
     570                printf("Error: Unhandled exception '");
     571                symbol_print_fqn(csi_to_symbol(exc_csi));
     572                printf("'.\n");
     573
     574                run_raise_error(run);
     575        }
    525576}
    526577
     
    620671
    621672                (*var)->u.int_v = int_v;
    622                 int_v->value = item->u.value->var->u.int_v->value;
     673                bigint_clone(&item->u.value->var->u.int_v->value,
     674                    &int_v->value);
    623675                break;
    624676        case vc_string:
     
    11711223
    11721224        if (addr_var->vref == NULL) {
     1225#ifdef DEBUG_RUN_TRACE
    11731226                printf("Error: Accessing null reference.\n");
    1174                 run_raise_error(run);
     1227#endif
     1228                /* Raise Error.NilReference */
     1229                run_raise_exc(run, run->program->builtin->error_nilreference);
    11751230                *ritem = run_recovery_item(run);
    11761231                return;
     
    11811236#endif
    11821237        *ritem = item;
     1238}
     1239
     1240/** Raise an exception of the given class.
     1241 *
     1242 * Used when the interpreter generates an exception due to a run-time
     1243 * error (not for the @c raise statement).
     1244 *
     1245 * @param run           Runner object.
     1246 * @param csi           Exception class.
     1247 */
     1248void run_raise_exc(run_t *run, stree_csi_t *csi)
     1249{
     1250        rdata_item_t *exc_vi;
     1251
     1252        /* Create exception object. */
     1253        run_new_csi_inst(run, csi, &exc_vi);
     1254        assert(exc_vi->ic == ic_value);
     1255
     1256        /* Store exception object in thread AR. */
     1257        run->thread_ar->exc_payload = exc_vi->u.value;
     1258
     1259        /* Start exception bailout. */
     1260        run->thread_ar->bo_mode = bm_exc;
     1261}
     1262
     1263/** Determine if we are bailing out. */
     1264bool_t run_is_bo(run_t *run)
     1265{
     1266        return run->thread_ar->bo_mode != bm_none;
    11831267}
    11841268
  • uspace/app/sbi/src/run.h

    r3aae4e8 r23de644  
    3939void run_print_fun_bt(run_t *run);
    4040
     41void run_exc_check_unhandled(run_t *run);
    4142void run_raise_error(run_t *run);
    4243rdata_item_t *run_recovery_item(run_t *run);
     
    6465void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem);
    6566
     67void run_raise_exc(run_t *run, stree_csi_t *csi);
     68bool_t run_is_bo(run_t *run);
     69
    6670run_thread_ar_t *run_thread_ar_new(void);
    6771run_proc_ar_t *run_proc_ar_new(void);
  • uspace/app/sbi/src/run_expr.c

    r3aae4e8 r23de644  
    3232#include <stdlib.h>
    3333#include <assert.h>
     34#include "bigint.h"
    3435#include "debug.h"
    3536#include "intmap.h"
     
    7172
    7273static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
     74static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
     75    rdata_item_t **res);
     76
    7377static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res);
    7478static void run_new_array(run_t *run, stree_new_t *new_op,
     
    349353        value->var = var;
    350354        var->u.int_v = int_v;
    351         int_v->value = lit_int->value;
     355        bigint_clone(&lit_int->value, &int_v->value);
    352356
    353357        *res = item;
     
    436440#endif
    437441        run_expr(run, binop->arg1, &rarg1_i);
     442        if (run_is_bo(run)) {
     443                *res = NULL;
     444                return;
     445        }
     446
    438447        run_expr(run, binop->arg2, &rarg2_i);
     448        if (run_is_bo(run)) {
     449                *res = NULL;
     450                return;
     451        }
    439452
    440453        switch (binop->bc) {
    441454        case bo_plus:
     455        case bo_minus:
     456        case bo_mult:
    442457        case bo_equal:
    443458        case bo_notequal:
     
    496511        rdata_int_t *int_v;
    497512
    498         int i1, i2;
     513        bigint_t *i1, *i2;
     514        bigint_t diff;
     515        bool_t done;
     516        bool_t zf, nf;
    499517
    500518        (void) run;
     
    509527        var->u.int_v = int_v;
    510528
    511         i1 = v1->var->u.int_v->value;
    512         i2 = v2->var->u.int_v->value;
     529        i1 = &v1->var->u.int_v->value;
     530        i2 = &v2->var->u.int_v->value;
     531
     532        done = b_true;
    513533
    514534        switch (binop->bc) {
    515535        case bo_plus:
    516                 int_v->value = i1 + i2;
    517                 break;
     536                bigint_add(i1, i2, &int_v->value);
     537                break;
     538        case bo_minus:
     539                bigint_sub(i1, i2, &int_v->value);
     540                break;
     541        case bo_mult:
     542                bigint_mul(i1, i2, &int_v->value);
     543                break;
     544        default:
     545                done = b_false;
     546                break;
     547        }
     548
     549        if (done) {
     550                *res = item;
     551                return;
     552        }
     553
     554        /* Relational operation. */
     555
     556        bigint_sub(i1, i2, &diff);
     557        zf = bigint_is_zero(&diff);
     558        nf = bigint_is_negative(&diff);
    518559
    519560        /* XXX We should have a real boolean type. */
     561        switch (binop->bc) {
    520562        case bo_equal:
    521                 int_v->value = (i1 == i2) ? 1 : 0;
     563                bigint_init(&int_v->value, zf ? 1 : 0);
    522564                break;
    523565        case bo_notequal:
    524                 int_v->value = (i1 != i2) ? 1 : 0;
     566                bigint_init(&int_v->value, !zf ? 1 : 0);
    525567                break;
    526568        case bo_lt:
    527                 int_v->value = (i1 < i2) ? 1 : 0;
     569                bigint_init(&int_v->value, (!zf && nf) ? 1 : 0);
    528570                break;
    529571        case bo_gt:
    530                 int_v->value = (i1 > i2) ? 1 : 0;
     572                bigint_init(&int_v->value, (!zf && !nf) ? 1 : 0);
    531573                break;
    532574        case bo_lt_equal:
    533                 int_v->value = (i1 <= i2) ? 1 : 0;
     575                bigint_init(&int_v->value, (zf || nf) ? 1 : 0);
    534576                break;
    535577        case bo_gt_equal:
    536                 int_v->value = (i1 >= i2) ? 1 : 0;
     578                bigint_init(&int_v->value, !nf ? 1 : 0);
    537579                break;
    538580        default:
     
    610652        /* XXX We should have a real boolean type. */
    611653        case bo_equal:
    612                 int_v->value = (ref1 == ref2) ? 1 : 0;
     654                bigint_init(&int_v->value, (ref1 == ref2) ? 1 : 0);
    613655                break;
    614656        case bo_notequal:
    615                 int_v->value = (ref1 != ref2) ? 1 : 0;
     657                bigint_init(&int_v->value, (ref1 != ref2) ? 1 : 0);
    616658                break;
    617659        default:
     
    628670static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res)
    629671{
    630         rdata_item_t *rarg;
     672        rdata_item_t *rarg_i;
     673        rdata_item_t *rarg_vi;
     674        rdata_value_t *val;
    631675
    632676#ifdef DEBUG_RUN_TRACE
    633677        printf("Run unary operation.\n");
    634678#endif
    635         run_expr(run, unop->arg, &rarg);
    636         *res = NULL;
    637 }
     679        run_expr(run, unop->arg, &rarg_i);
     680        if (run_is_bo(run)) {
     681                *res = NULL;
     682                return;
     683        }
     684
     685#ifdef DEBUG_RUN_TRACE
     686        printf("Check unop argument result.\n");
     687#endif
     688        run_cvt_value_item(run, rarg_i, &rarg_vi);
     689
     690        val = rarg_vi->u.value;
     691
     692        switch (val->var->vc) {
     693        case vc_int:
     694                run_unop_int(run, unop, val, res);
     695                break;
     696        default:
     697                printf("Unimplemented: Unrary operation argument of "
     698                    "type %d.\n", val->var->vc);
     699                run_raise_error(run);
     700                *res = NULL;
     701                break;
     702        }
     703}
     704
     705/** Evaluate unary operation on int argument. */
     706static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
     707    rdata_item_t **res)
     708{
     709        rdata_item_t *item;
     710        rdata_value_t *value;
     711        rdata_var_t *var;
     712        rdata_int_t *int_v;
     713
     714        (void) run;
     715
     716        item = rdata_item_new(ic_value);
     717        value = rdata_value_new();
     718        var = rdata_var_new(vc_int);
     719        int_v = rdata_int_new();
     720
     721        item->u.value = value;
     722        value->var = var;
     723        var->u.int_v = int_v;
     724
     725        switch (unop->uc) {
     726        case uo_plus:
     727                bigint_clone(&val->var->u.int_v->value, &int_v->value);
     728                break;
     729        case uo_minus:
     730                bigint_reverse_sign(&val->var->u.int_v->value,
     731                    &int_v->value);
     732                break;
     733        }
     734
     735        *res = item;
     736}
     737
    638738
    639739/** Evaluate @c new operation. */
     
    680780        int length;
    681781        int i;
     782        int rc;
     783        int iextent;
    682784
    683785#ifdef DEBUG_RUN_TRACE
     
    708810                /* Evaluate extent argument. */
    709811                run_expr(run, expr, &rexpr);
     812                if (run_is_bo(run)) {
     813                        *res = NULL;
     814                        return;
     815                }
     816
    710817                run_cvt_value_item(run, rexpr, &rexpr_vi);
    711818                assert(rexpr_vi->ic == ic_value);
     
    718825
    719826#ifdef DEBUG_RUN_TRACE
    720                 printf("Array extent: %d.\n", rexpr_var->u.int_v->value);
    721 #endif
    722                 array->extent[i] = rexpr_var->u.int_v->value;
     827                printf("Array extent: ");
     828                bigint_print(&rexpr_var->u.int_v->value);
     829                printf(".\n");
     830#endif
     831                rc = bigint_get_value_int(&rexpr_var->u.int_v->value,
     832                    &iextent);
     833                if (rc != EOK) {
     834                        printf("Memory allocation failed (big int used).\n");
     835                        exit(1);
     836                }
     837
     838                array->extent[i] = iextent;
    723839                length = length * array->extent[i];
    724840
     
    738854                elem_var = rdata_var_new(vc_int);
    739855                elem_var->u.int_v = rdata_int_new();
    740                 elem_var->u.int_v->value = 0;
     856                bigint_init(&elem_var->u.int_v->value, 0);
    741857
    742858                array->element[i] = elem_var;
     
    755871    tdata_item_t *titem, rdata_item_t **res)
    756872{
    757         rdata_object_t *obj;
    758         rdata_var_t *obj_var;
    759 
    760         stree_symbol_t *csi_sym;
    761873        stree_csi_t *csi;
    762         stree_csimbr_t *csimbr;
    763 
    764         rdata_var_t *mbr_var;
    765 
    766         list_node_t *node;
    767874
    768875#ifdef DEBUG_RUN_TRACE
    769876        printf("Create new object.\n");
    770877#endif
    771         (void) run;
    772878        (void) new_op;
    773879
     
    775881        assert(titem->tic == tic_tobject);
    776882        csi = titem->u.tobject->csi;
    777         csi_sym = csi_to_symbol(csi);
    778 
    779         /* Create the object. */
    780         obj = rdata_object_new();
    781         obj->class_sym = csi_sym;
    782         intmap_init(&obj->fields);
    783 
    784         obj_var = rdata_var_new(vc_object);
    785         obj_var->u.object_v = obj;
    786 
    787         /* Create object fields. */
    788         node = list_first(&csi->members);
    789         while (node != NULL) {
    790                 csimbr = list_node_data(node, stree_csimbr_t *);
    791                 if (csimbr->cc == csimbr_var) {
    792                         /* XXX Depends on member variable type. */
    793                         mbr_var = rdata_var_new(vc_int);
    794                         mbr_var->u.int_v = rdata_int_new();
    795                         mbr_var->u.int_v->value = 0;
    796 
    797                         intmap_set(&obj->fields, csimbr->u.var->name->sid,
    798                             mbr_var);
    799                 }
    800 
    801                 node = list_next(&csi->members, node);
    802         }
    803 
    804         /* Create reference to the new object. */
    805         run_reference(run, obj_var, res);
     883
     884        /* Create CSI instance. */
     885        run_new_csi_inst(run, csi, res);
    806886}
    807887
     
    815895#endif
    816896        run_expr(run, access->arg, &rarg);
     897        if (run_is_bo(run)) {
     898                *res = NULL;
     899                return;
     900        }
     901
    817902        if (rarg == NULL) {
    818903                printf("Error: Sub-expression has no value.\n");
     
    10281113#endif
    10291114        run_expr(run, call->fun, &rfun);
     1115        if (run_is_bo(run)) {
     1116                *res = NULL;
     1117                return;
     1118        }
    10301119
    10311120        if (run->thread_ar->bo_mode != bm_none) {
     
    10581147                arg = list_node_data(node, stree_expr_t *);
    10591148                run_expr(run, arg, &rarg_i);
     1149                if (run_is_bo(run)) {
     1150                        *res = NULL;
     1151                        return;
     1152                }
     1153
    10601154                run_cvt_value_item(run, rarg_i, &rarg_vi);
    10611155
     
    10961190#endif
    10971191        run_expr(run, index->base, &rbase);
     1192        if (run_is_bo(run)) {
     1193                *res = NULL;
     1194                return;
     1195        }
    10981196
    10991197        vc = run_item_get_vc(run, rbase);
     
    11151213                arg = list_node_data(node, stree_expr_t *);
    11161214                run_expr(run, arg, &rarg_i);
     1215                if (run_is_bo(run)) {
     1216                        *res = NULL;
     1217                        return;
     1218                }
     1219
    11171220                run_cvt_value_item(run, rarg_i, &rarg_vi);
    11181221
     
    11491252        int elem_index;
    11501253        int arg_val;
     1254        int rc;
    11511255
    11521256        rdata_item_t *ritem;
     
    11891293                }
    11901294
    1191                 arg_val = arg->u.value->var->u.int_v->value;
    1192 
    1193                 if (arg_val < 0 || arg_val >= array->extent[i]) {
     1295                rc = bigint_get_value_int(
     1296                    &arg->u.value->var->u.int_v->value,
     1297                    &arg_val);
     1298
     1299                if (rc != EOK || arg_val < 0 || arg_val >= array->extent[i]) {
     1300#ifdef DEBUG_RUN_TRACE
    11941301                        printf("Error: Array index (value: %d) is out of range.\n",
    11951302                            arg_val);
    1196                         run_raise_error(run);
     1303#endif
     1304                        /* Raise Error.OutOfBounds */
     1305                        run_raise_exc(run,
     1306                            run->program->builtin->error_outofbounds);
    11971307                        *res = run_recovery_item(run);
    11981308                        return;
     
    13071417        int elem_index;
    13081418        int arg_val;
    1309         int rc;
     1419        int rc1, rc2;
    13101420
    13111421        rdata_value_t *value;
     
    13221432        run_cvt_value_item(run, base, &base_vi);
    13231433        assert(base_vi->u.value->var->vc == vc_string);
    1324         string = base->u.value->var->u.string_v;
     1434        string = base_vi->u.value->var->u.string_v;
    13251435
    13261436        /*
     
    13461456                }
    13471457
    1348                 arg_val = arg->u.value->var->u.int_v->value;
     1458                rc1 = bigint_get_value_int(
     1459                    &arg->u.value->var->u.int_v->value,
     1460                    &arg_val);
     1461
    13491462                elem_index = arg_val;
    13501463
     
    13581471        }
    13591472
    1360         rc = os_str_get_char(string->value, elem_index, &cval);
    1361         if (rc != EOK) {
     1473        if (rc1 == EOK)
     1474                rc2 = os_str_get_char(string->value, elem_index, &cval);
     1475
     1476        if (rc1 != EOK || rc2 != EOK) {
    13621477                printf("Error: String index (value: %d) is out of range.\n",
    13631478                    arg_val);
     
    13721487        cvar = rdata_var_new(vc_int);
    13731488        cvar->u.int_v = rdata_int_new();
    1374         cvar->u.int_v->value = cval;
     1489        bigint_init(&cvar->u.int_v->value, cval);
    13751490        value->var = cvar;
    13761491
     
    13891504#endif
    13901505        run_expr(run, assign->dest, &rdest_i);
     1506        if (run_is_bo(run)) {
     1507                *res = NULL;
     1508                return;
     1509        }
     1510
    13911511        run_expr(run, assign->src, &rsrc_i);
     1512        if (run_is_bo(run)) {
     1513                *res = NULL;
     1514                return;
     1515        }
    13921516
    13931517        run_cvt_value_item(run, rsrc_i, &rsrc_vi);
     
    14231547#endif
    14241548        run_expr(run, as_op->arg, &rarg_i);
     1549        if (run_is_bo(run)) {
     1550                *res = NULL;
     1551                return;
     1552        }
    14251553
    14261554        /*
     
    14671595
    14681596        *res = rarg_vi;
     1597}
     1598
     1599/** Create new CSI instance. */
     1600void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
     1601{
     1602        rdata_object_t *obj;
     1603        rdata_var_t *obj_var;
     1604
     1605        stree_symbol_t *csi_sym;
     1606        stree_csimbr_t *csimbr;
     1607
     1608        rdata_var_t *mbr_var;
     1609
     1610        list_node_t *node;
     1611
     1612        csi_sym = csi_to_symbol(csi);
     1613
     1614#ifdef DEBUG_RUN_TRACE
     1615        printf("Create new instance of CSI '");
     1616        symbol_print_fqn(csi_sym);
     1617        printf("'.\n");
     1618#endif
     1619
     1620        /* Create the object. */
     1621        obj = rdata_object_new();
     1622        obj->class_sym = csi_sym;
     1623        intmap_init(&obj->fields);
     1624
     1625        obj_var = rdata_var_new(vc_object);
     1626        obj_var->u.object_v = obj;
     1627
     1628        /* Create object fields. */
     1629        node = list_first(&csi->members);
     1630        while (node != NULL) {
     1631                csimbr = list_node_data(node, stree_csimbr_t *);
     1632                if (csimbr->cc == csimbr_var) {
     1633                        /* XXX Depends on member variable type. */
     1634                        mbr_var = rdata_var_new(vc_int);
     1635                        mbr_var->u.int_v = rdata_int_new();
     1636                        bigint_init(&mbr_var->u.int_v->value, 0);
     1637
     1638                        intmap_set(&obj->fields, csimbr->u.var->name->sid,
     1639                            mbr_var);
     1640                }
     1641
     1642                node = list_next(&csi->members, node);
     1643        }
     1644
     1645        /* Create reference to the new object. */
     1646        run_reference(run, obj_var, res);
    14691647}
    14701648
     
    14921670        }
    14931671
    1494         return (var->u.int_v->value != 0);
    1495 }
     1672        return !bigint_is_zero(&var->u.int_v->value);
     1673}
  • uspace/app/sbi/src/run_expr.h

    r3aae4e8 r23de644  
    3434void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res);
    3535
     36void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res);
    3637bool_t run_item_boolean_value(run_t *run, rdata_item_t *item);
    3738
  • uspace/app/sbi/src/stree.c

    r3aae4e8 r23de644  
    376376}
    377377
     378stree_unop_t *stree_unop_new(unop_class_t uc)
     379{
     380        stree_unop_t *unop;
     381
     382        unop = calloc(1, sizeof(stree_unop_t));
     383        if (unop == NULL) {
     384                printf("Memory allocation failed.\n");
     385                exit(1);
     386        }
     387
     388        unop->uc = uc;
     389        return unop;
     390}
     391
    378392stree_new_t *stree_new_new(void)
    379393{
  • uspace/app/sbi/src/stree.h

    r3aae4e8 r23de644  
    6262stree_assign_t *stree_assign_new(assign_class_t ac);
    6363stree_binop_t *stree_binop_new(binop_class_t bc);
     64stree_unop_t *stree_unop_new(unop_class_t uc);
    6465stree_new_t *stree_new_new(void);
    6566stree_access_t *stree_access_new(void);
  • uspace/app/sbi/src/stree_t.h

    r3aae4e8 r23de644  
    3030#define STREE_T_H_
    3131
     32#include "bigint_t.h"
    3233#include "list_t.h"
    3334#include "builtin_t.h"
     
    5455
    5556typedef struct {
    56         int value;
     57        bigint_t value;
    5758} stree_lit_int_t;
    5859
     
    8990        bo_lt_equal,
    9091        bo_gt_equal,
    91         bo_plus
     92        bo_plus,
     93        bo_minus,
     94        bo_mult
    9295} binop_class_t;
    9396
    9497/** Unary operation class */
    9598typedef enum {
    96         uo_plus
     99        uo_plus,
     100        uo_minus,
    97101} unop_class_t;
    98102
     
    109113typedef struct {
    110114        /** Operation class */
    111         unop_class_t oc;
     115        unop_class_t uc;
    112116
    113117        /** Argument */
  • uspace/app/sbi/src/stype.c

    r3aae4e8 r23de644  
    162162                    &titem);
    163163
    164                 if (titem->tic != tic_tarray) {
     164                if (titem->tic != tic_tarray && titem->tic != tic_ignore) {
    165165                        printf("Error: Packed argument is not an array.\n");
    166166                        stype_note_error(stype);
     
    487487        }
    488488
    489         if (dest == NULL || src == NULL)
     489        if (dest->tic == tic_ignore || src->tic == tic_ignore)
    490490                return expr;
    491491
     
    680680{
    681681        tdata_item_t *titem;
    682         tdata_primitive_t *tprimitive;
    683682
    684683        (void) stype;
    685684
    686         titem = tdata_item_new(tic_tprimitive);
    687         tprimitive = tdata_primitive_new(tpc_int);
    688 
    689         titem->u.tprimitive = tprimitive;
    690 
     685        titem = tdata_item_new(tic_ignore);
    691686        return titem;
    692687}
  • uspace/app/sbi/src/stype_expr.c

    r3aae4e8 r23de644  
    6060static void stype_unop(stype_t *stype, stree_unop_t *unop,
    6161    tdata_item_t **rtitem);
     62static void stype_unop_tprimitive(stype_t *stype, stree_unop_t *unop,
     63    tdata_item_t *ta, tdata_item_t **rtitem);
    6264static void stype_new(stype_t *stype, stree_new_t *new,
    6365    tdata_item_t **rtitem);
     
    276278{
    277279        bool_t equal;
    278         tdata_item_t *titem;
     280        tdata_item_t *titem1, *titem2;
    279281
    280282#ifdef DEBUG_TYPE_TRACE
     
    284286        stype_expr(stype, binop->arg2);
    285287
    286         /* XXX This should be checked properly. */
    287         assert(binop->arg1->titem != NULL);
    288         assert(binop->arg2->titem != NULL);
    289 
    290         if (binop->arg1->titem == NULL) {
    291                 printf("Error First binary operand has no value.\n");
    292                 stype_note_error(stype);
    293                 if (binop->arg2->titem != NULL)
    294                         *rtitem = binop->arg2->titem;
    295                 else
    296                         *rtitem = stype_recovery_titem(stype);
    297                 return;
    298         }
    299 
    300         if (binop->arg2->titem == NULL) {
    301                 printf("Error: Second binary operand has no value.\n");
    302                 stype_note_error(stype);
    303                 *rtitem = binop->arg1->titem;
    304                 return;
    305         }
    306 
    307         equal = tdata_item_equal(binop->arg1->titem, binop->arg2->titem);
     288        titem1 = binop->arg1->titem;
     289        titem2 = binop->arg2->titem;
     290
     291        if (titem1 == NULL || titem2 == NULL) {
     292                printf("Error: Binary operand has no value.\n");
     293                stype_note_error(stype);
     294                *rtitem = stype_recovery_titem(stype);
     295                return;
     296        }
     297
     298        if (titem1->tic == tic_ignore || titem2->tic == tic_ignore) {
     299                *rtitem = stype_recovery_titem(stype);
     300                return;
     301        }
     302
     303        equal = tdata_item_equal(titem1, titem2);
    308304        if (equal != b_true) {
    309305                printf("Error: Binary operation arguments "
    310306                    "have different types ('");
    311                 tdata_item_print(binop->arg1->titem);
     307                tdata_item_print(titem1);
    312308                printf("' and '");
    313                 tdata_item_print(binop->arg2->titem);
     309                tdata_item_print(titem2);
    314310                printf("').\n");
    315311                stype_note_error(stype);
    316                 *rtitem = binop->arg1->titem;
    317                 return;
    318         }
    319 
    320         titem = binop->arg1->titem;
    321 
    322         switch (titem->tic) {
     312                *rtitem = stype_recovery_titem(stype);
     313                return;
     314        }
     315
     316        switch (titem1->tic) {
    323317        case tic_tprimitive:
    324                 stype_binop_tprimitive(stype, binop, binop->arg1->titem,
    325                     binop->arg2->titem, rtitem);
     318                stype_binop_tprimitive(stype, binop, titem1, titem2, rtitem);
    326319                break;
    327320        case tic_tobject:
    328                 stype_binop_tobject(stype, binop, binop->arg1->titem,
    329                     binop->arg2->titem, rtitem);
     321                stype_binop_tobject(stype, binop, titem1, titem2, rtitem);
    330322                break;
    331323        default:
    332324                printf("Error: Binary operation on value which is not of a "
    333325                    "supported type (found '");
    334                 tdata_item_print(titem);
     326                tdata_item_print(titem1);
    335327                printf("').\n");
    336328                stype_note_error(stype);
    337                 *rtitem = titem;
     329                *rtitem = stype_recovery_titem(stype);
    338330                break;
    339331        }
     
    417409    tdata_item_t **rtitem)
    418410{
     411        tdata_item_t *titem;
     412
    419413#ifdef DEBUG_TYPE_TRACE
    420414        printf("Evaluate type of unary operation.\n");
     
    422416        stype_expr(stype, unop->arg);
    423417
    424         *rtitem = NULL;
     418        titem = unop->arg->titem;
     419
     420        if (titem->tic == tic_ignore) {
     421                *rtitem = stype_recovery_titem(stype);
     422                return;
     423        }
     424
     425        switch (titem->tic) {
     426        case tic_tprimitive:
     427                stype_unop_tprimitive(stype, unop, titem, rtitem);
     428                break;
     429        default:
     430                printf("Error: Unary operation on value which is not of a "
     431                    "supported type (found '");
     432                tdata_item_print(titem);
     433                printf("').\n");
     434                stype_note_error(stype);
     435                *rtitem = stype_recovery_titem(stype);
     436                break;
     437        }
     438}
     439
     440/** Type a binary operation arguments of primitive type. */
     441static void stype_unop_tprimitive(stype_t *stype, stree_unop_t *unop,
     442    tdata_item_t *ta, tdata_item_t **rtitem)
     443{
     444        tprimitive_class_t rtpc;
     445        tdata_item_t *res_ti;
     446
     447        (void) stype;
     448        (void) unop;
     449
     450        assert(ta->tic == tic_tprimitive);
     451
     452        switch (ta->u.tprimitive->tpc) {
     453        case tpc_int:
     454                rtpc = tpc_int;
     455                break;
     456        default:
     457                printf("Error: Unary operator applied on unsupported "
     458                    "primitive type %d.\n", ta->u.tprimitive->tpc);
     459                stype_note_error(stype);
     460                *rtitem = stype_recovery_titem(stype);
     461                return;
     462        }
     463
     464        res_ti = tdata_item_new(tic_tprimitive);
     465        res_ti->u.tprimitive = tdata_primitive_new(rtpc);
     466
     467        *rtitem = res_ti;
    425468}
    426469
     
    474517                printf("Error: Using '.' operator on a function.\n");
    475518                stype_note_error(stype);
     519                *rtitem = stype_recovery_titem(stype);
     520                break;
     521        case tic_ignore:
    476522                *rtitem = stype_recovery_titem(stype);
    477523                break;
     
    613659        stype_expr(stype, call->fun);
    614660
     661        /* Check type item class */
     662
    615663        fun_ti = call->fun->titem;
    616         assert(fun_ti->tic == tic_tfun);
     664        switch (fun_ti->tic) {
     665        case tic_tfun:
     666                /* The expected case */
     667                break;
     668        case tic_ignore:
     669                *rtitem = stype_recovery_titem(stype);
     670                return;
     671        default:
     672                printf("Error: Calling something which is not a function ");
     673                printf("(found '");
     674                tdata_item_print(fun_ti);
     675                printf("').\n");
     676                stype_note_error(stype);
     677                *rtitem = stype_recovery_titem(stype);
     678                return;
     679        }
     680
    617681        fun = fun_ti->u.tfun->fun;
    618682        fun_sym = fun_to_symbol(fun);
     
    734798                printf("Error: Indexing a function.\n");
    735799                stype_note_error(stype);
     800                *rtitem = stype_recovery_titem(stype);
     801                break;
     802        case tic_ignore:
    736803                *rtitem = stype_recovery_titem(stype);
    737804                break;
  • uspace/app/sbi/src/tdata.c

    r3aae4e8 r23de644  
    148148                tdata_tfun_print(titem->u.tfun);
    149149                break;
     150        case tic_ignore:
     151                printf("ignore");
     152                break;
    150153        }
    151154}
  • uspace/app/sbi/src/tdata_t.h

    r3aae4e8 r23de644  
    8484
    8585typedef enum {
     86        /** Primitive type item */
    8687        tic_tprimitive,
     88        /** Object type item */
    8789        tic_tobject,
     90        /** Array type item */
    8891        tic_tarray,
     92        /** Generic type item */
    8993        tic_tgeneric,
    90         tic_tfun
     94        /** Function type item */
     95        tic_tfun,
     96        /** Special error-recovery type item */
     97        tic_ignore
    9198} titem_class_t;
    9299
  • uspace/dist/src/sysel/demos/varargs.sy

    r3aae4e8 r23de644  
    3333        -- with the attribute 'packed'.
    3434        --
    35         -- Note that we need to pass 'n' just because the array type
    36         -- does not implement the Length property yet.
    37         --
    38         fun Print(n : int; args : string[], packed) is
     35        fun Print(args : string[], packed) is
    3936                var i : int;
     37                var error : int;
    4038
     39                error = 0;
    4140                i = 0;
    42                 while i < n do
    43                         Builtin.WriteLine(args[i]);
     41                while error == 0 do
     42                        -- This is definitely the wrong way to determine
     43                        -- array bounds, but until a better one is
     44                        -- implemented...
     45                        do
     46                                Builtin.WriteLine(args[i]);
     47                        except e : Error.OutOfBounds do
     48                                error = 1;
     49                        end
     50
    4451                        i = i + 1;
    4552                end
     
    4754
    4855        fun Main() is
    49                 Print(5, "One", "Two", "Three", "Four", "Five");
     56                Print("One", "Two", "Three", "Four", "Five");
    5057        end
    5158end
Note: See TracChangeset for help on using the changeset viewer.