Changeset fa36f29 in mainline


Ignore:
Timestamp:
2010-02-27T17:59:14Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
94d484a
Parents:
09ababb7
Message:

Update SBI to rev. 75.

Location:
uspace
Files:
2 added
23 edited

Legend:

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

    r09ababb7 rfa36f29  
    7272        stree_modm_t *modm;
    7373
     74        (void) module;
    7475        node = list_first(&prog->module->members);
    7576
  • uspace/app/sbi/src/input.c

    r09ababb7 rfa36f29  
    6464
    6565        input->buffer = malloc(INPUT_BUFFER_SIZE);
    66         if (input->buffer == NULL)
    67                 return ENOMEM;
     66        if (input->buffer == NULL) {
     67                printf("Memory allocation failed.\n");
     68                exit(1);
     69        }
    6870
    6971        input->line_no = 0;
  • uspace/app/sbi/src/lex.c

    r09ababb7 rfa36f29  
    7878        { lc_for,       "for" },
    7979        { lc_fun,       "fun" },
    80         { lc_new,       "new" },
    8180        { lc_get,       "get" },
    8281        { lc_if,        "if" },
     
    8584        { lc_interface, "interface" },
    8685        { lc_is,        "is" },
     86        { lc_new,       "new" },
     87        { lc_nil,       "nil" },
    8788        { lc_override,  "override" },
    8889        { lc_private,   "private" },
     
    9293        { lc_raise,     "raise" },
    9394        { lc_return,    "return" },
     95        { lc_self,      "self" },
    9496        { lc_set,       "set" },
    9597        { lc_static,    "static" },
  • uspace/app/sbi/src/lex_t.h

    r09ababb7 rfa36f29  
    5656        lc_interface,
    5757        lc_is,
     58        lc_nil,
    5859        lc_override,
    5960        lc_private,
     
    6364        lc_raise,
    6465        lc_return,
     66        lc_self,
    6567        lc_set,
    6668        lc_static,
  • uspace/app/sbi/src/main.c

    r09ababb7 rfa36f29  
    5959        rc = input_new(&input, argv[1]);
    6060        if (rc != EOK) {
    61                 printf("Failed initializing input.\n");
     61                printf("Failed opening source file '%s'.\n", argv[1]);
    6262                exit(1);
    6363        }
  • uspace/app/sbi/src/p_expr.c

    r09ababb7 rfa36f29  
    3434#include "list.h"
    3535#include "mytypes.h"
     36#include "p_type.h"
    3637#include "parse.h"
    3738#include "stree.h"
     
    4243static stree_expr_t *parse_comparative(parse_t *parse);
    4344static stree_expr_t *parse_additive(parse_t *parse);
     45static stree_expr_t *parse_prefix(parse_t *parse);
     46static stree_expr_t *parse_prefix_new(parse_t *parse);
    4447static stree_expr_t *parse_postfix(parse_t *parse);
    4548static stree_expr_t *parse_pf_access(parse_t *parse, stree_expr_t *a);
     
    4851static stree_expr_t *parse_nameref(parse_t *parse);
    4952static stree_expr_t *parse_lit_int(parse_t *parse);
     53static stree_expr_t *parse_lit_ref(parse_t *parse);
    5054static stree_expr_t *parse_lit_string(parse_t *parse);
     55static stree_expr_t *parse_self_ref(parse_t *parse);
    5156
    5257/** Parse expression. */
     
    130135        stree_binop_t *binop;
    131136
    132         a = parse_postfix(parse);
     137        a = parse_prefix(parse);
    133138        while (lcur_lc(parse) == lc_plus) {
    134139                lskip(parse);
    135                 b = parse_postfix(parse);
     140                b = parse_prefix(parse);
    136141
    137142                binop = stree_binop_new(bo_plus);
     
    145150
    146151        return a;
     152}
     153
     154/** Parse prefix expression. */
     155static stree_expr_t *parse_prefix(parse_t *parse)
     156{
     157        stree_expr_t *a;
     158
     159        switch (lcur_lc(parse)) {
     160        case lc_plus:
     161                printf("Unimplemented: Unary plus.\n");
     162                exit(1);
     163        case lc_new:
     164                a = parse_prefix_new(parse);
     165                break;
     166        default:
     167                a = parse_postfix(parse);
     168                break;
     169        }
     170
     171        return a;
     172}
     173
     174/** Parse @c new operator. */
     175static stree_expr_t *parse_prefix_new(parse_t *parse)
     176{
     177        stree_texpr_t *texpr;
     178        stree_new_t *new_op;
     179        stree_expr_t *expr;
     180
     181        lmatch(parse, lc_new);
     182        texpr = parse_texpr(parse);
     183        lmatch(parse, lc_lparen);
     184        lmatch(parse, lc_rparen);
     185
     186        new_op = stree_new_new();
     187        new_op->texpr = texpr;
     188        expr = stree_expr_new(ec_new);
     189        expr->u.new_op = new_op;
     190
     191        return expr;
    147192}
    148193
     
    240285                expr = parse_lit_int(parse);
    241286                break;
     287        case lc_nil:
     288                expr = parse_lit_ref(parse);
     289                break;
    242290        case lc_lit_string:
    243291                expr = parse_lit_string(parse);
     292                break;
     293        case lc_self:
     294                expr = parse_self_ref(parse);
    244295                break;
    245296        default:
     
    284335}
    285336
     337/** Parse reference literal (@c nil). */
     338static stree_expr_t *parse_lit_ref(parse_t *parse)
     339{
     340        stree_literal_t *literal;
     341        stree_expr_t *expr;
     342
     343        lmatch(parse, lc_nil);
     344
     345        literal = stree_literal_new(ltc_ref);
     346
     347        expr = stree_expr_new(ec_literal);
     348        expr->u.literal = literal;
     349
     350        return expr;
     351}
     352
    286353/** Parse string literal. */
    287354static stree_expr_t *parse_lit_string(parse_t *parse)
     
    302369        return expr;
    303370}
     371
     372/** Parse @c self keyword. */
     373static stree_expr_t *parse_self_ref(parse_t *parse)
     374{
     375        stree_self_ref_t *self_ref;
     376        stree_expr_t *expr;
     377
     378        lmatch(parse, lc_self);
     379
     380        self_ref = stree_self_ref_new();
     381
     382        expr = stree_expr_new(ec_self_ref);
     383        expr->u.self_ref = self_ref;
     384
     385        return expr;
     386}
  • uspace/app/sbi/src/p_type.c

    r09ababb7 rfa36f29  
    4242static stree_texpr_t *parse_tpostfix(parse_t *parse);
    4343static stree_texpr_t *parse_tprimitive(parse_t *parse);
     44static stree_tliteral_t *parse_tliteral(parse_t *parse);
    4445static stree_tnameref_t *parse_tnameref(parse_t *parse);
    4546
     
    104105        stree_texpr_t *texpr;
    105106
    106         lcheck(parse, lc_ident);
    107         texpr = stree_texpr_new(tc_tnameref);
    108         texpr->u.tnameref = parse_tnameref(parse);
     107        switch (lcur_lc(parse)) {
     108        case lc_ident:
     109                texpr = stree_texpr_new(tc_tnameref);
     110                texpr->u.tnameref = parse_tnameref(parse);
     111                break;
     112        case lc_int:
     113        case lc_string:
     114                texpr = stree_texpr_new(tc_tliteral);
     115                texpr->u.tliteral = parse_tliteral(parse);
     116                break;
     117        default:
     118                lunexpected_error(parse);
     119                exit(1);
     120        }
    109121
    110122        return texpr;
     123}
     124
     125/** Parse type literal. */
     126static stree_tliteral_t *parse_tliteral(parse_t *parse)
     127{
     128        stree_tliteral_t *tliteral;
     129
     130        tliteral = stree_tliteral_new();
     131
     132        switch (lcur_lc(parse)) {
     133        case lc_int:
     134                tliteral->tlc = tlc_int;
     135                break;
     136        case lc_string:
     137                tliteral->tlc = tlc_string;
     138                break;
     139        default:
     140                assert(b_false);
     141        }
     142
     143        lskip(parse);
     144
     145        return tliteral;
    111146}
    112147
  • uspace/app/sbi/src/parse.c

    r09ababb7 rfa36f29  
    6868static stree_for_t *parse_for(parse_t *parse);
    6969static stree_raise_t *parse_raise(parse_t *parse);
     70static stree_return_t *parse_return(parse_t *parse);
    7071static stree_wef_t *parse_wef(parse_t *parse);
    7172static stree_exps_t *parse_exps(parse_t *parse);
     
    342343        stree_for_t *for_s;
    343344        stree_raise_t *raise_s;
     345        stree_return_t *return_s;
    344346        stree_wef_t *wef_s;
    345347        stree_exps_t *exp_s;
     
    370372                stat = stree_stat_new(st_raise);
    371373                stat->u.raise_s = raise_s;
     374                break;
     375        case lc_return:
     376                return_s = parse_return(parse);
     377                stat = stree_stat_new(st_return);
     378                stat->u.return_s = return_s;
    372379                break;
    373380        case lc_with:
     
    485492}
    486493
     494/** Parse @c return statement. */
     495static stree_return_t *parse_return(parse_t *parse)
     496{
     497        stree_return_t *return_s;
     498
     499        return_s = stree_return_new();
     500
     501        lmatch(parse, lc_return);
     502        return_s->expr = parse_expr(parse);
     503        lmatch(parse, lc_scolon);
     504
     505        return return_s;
     506}
     507
    487508/* Parse @c with-except-finally statement. */
    488509static stree_wef_t *parse_wef(parse_t *parse)
  • uspace/app/sbi/src/rdata.c

    r09ababb7 rfa36f29  
    100100}
    101101
     102rdata_ref_t *rdata_ref_new(void)
     103{
     104        rdata_ref_t *ref;
     105
     106        ref = calloc(1, sizeof(rdata_ref_t));
     107        if (ref == NULL) {
     108                printf("Memory allocation failed.\n");
     109                exit(1);
     110        }
     111
     112        return ref;
     113}
     114
    102115rdata_deleg_t *rdata_deleg_new(void)
    103116{
     
    111124
    112125        return deleg;
     126}
     127
     128rdata_object_t *rdata_object_new(void)
     129{
     130        rdata_object_t *object;
     131
     132        object = calloc(1, sizeof(rdata_object_t));
     133        if (object == NULL) {
     134                printf("Memory allocation failed.\n");
     135                exit(1);
     136        }
     137
     138        return object;
    113139}
    114140
     
    181207static void rdata_ref_copy(rdata_ref_t *src, rdata_ref_t **dest)
    182208{
    183         printf("Unimplemented: Copy reference.\n");
    184         exit(1);
     209        *dest = rdata_ref_new();
     210        (*dest)->vref = src->vref;
    185211}
    186212
    187213static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
    188214{
     215        (void) src; (void) dest;
    189216        printf("Unimplemented: Copy delegate.\n");
    190217        exit(1);
     
    193220static void rdata_object_copy(rdata_object_t *src, rdata_object_t **dest)
    194221{
     222        (void) src; (void) dest;
    195223        printf("Unimplemented: Copy object.\n");
    196224        exit(1);
     225}
     226
     227/** Convert item to value item.
     228 *
     229 * If @a item is a value, we just return a copy. If @a item is an address,
     230 * we read from the address.
     231 */
     232void rdata_cvt_value_item(rdata_item_t *item, rdata_item_t **ritem)
     233{
     234        rdata_value_t *value;
     235
     236        /*
     237         * This can happen when trying to use output of a function which
     238         * does not return a value.
     239         */
     240        if (item == NULL) {
     241                printf("Error: Sub-expression has no value.\n");
     242                exit(1);
     243        }
     244
     245        /* Address item. Perform read operation. */
     246        if (item->ic == ic_address) {
     247                rdata_address_read(item->u.address, ritem);
     248                return;
     249        }
     250
     251        /* It already is a value, we can share the @c var. */
     252        value = rdata_value_new();
     253        value->var = item->u.value->var;
     254        *ritem = rdata_item_new(ic_value);
     255        (*ritem)->u.value = value;
     256}
     257
     258/** Return reference to a variable.
     259 *
     260 * Constructs a reference (value item) pointing to @a var.
     261 */
     262void rdata_reference(rdata_var_t *var, rdata_item_t **res)
     263{
     264        rdata_ref_t *ref;
     265        rdata_var_t *ref_var;
     266        rdata_value_t *ref_value;
     267        rdata_item_t *ref_item;
     268
     269        /* Create reference to the variable. */
     270        ref = rdata_ref_new();
     271        ref_var = rdata_var_new(vc_ref);
     272        ref->vref = var;
     273        ref_var->u.ref_v = ref;
     274
     275        /* Construct value of the reference to return. */
     276        ref_item = rdata_item_new(ic_value);
     277        ref_value = rdata_value_new();
     278        ref_item->u.value = ref_value;
     279        ref_value->var = ref_var;
     280
     281        *res = ref_item;
     282}
     283
     284/** Return address of reference target.
     285 *
     286 * Takes a reference (address or value) and returns the address (item) of
     287 * the target of the reference.
     288 */
     289void rdata_dereference(rdata_item_t *ref, rdata_item_t **ritem)
     290{
     291        rdata_item_t *ref_val;
     292        rdata_item_t *item;
     293        rdata_address_t *address;
     294
     295#ifdef DEBUG_RUN_TRACE
     296        printf("run_dereference()\n");
     297#endif
     298        rdata_cvt_value_item(ref, &ref_val);
     299        assert(ref_val->u.value->var->vc == vc_ref);
     300
     301        item = rdata_item_new(ic_address);
     302        address = rdata_address_new();
     303        item->u.address = address;
     304        address->vref = ref_val->u.value->var->u.ref_v->vref;
     305
     306        if (address->vref == NULL) {
     307                printf("Error: Accessing null reference.\n");
     308                exit(1);
     309        }
     310
     311#ifdef DEBUG_RUN_TRACE
     312        printf("vref set to %p\n", address->vref);
     313#endif
     314        *ritem = item;
     315}
     316
     317/** Read data from an address.
     318 *
     319 * Return value stored in a variable at the specified address.
     320 */
     321void rdata_address_read(rdata_address_t *address, rdata_item_t **ritem)
     322{
     323        rdata_value_t *value;
     324        rdata_var_t *rvar;
     325
     326        /* Perform a shallow copy of @c var. */
     327        rdata_var_copy(address->vref, &rvar);
     328
     329        value = rdata_value_new();
     330        value->var = rvar;
     331        *ritem = rdata_item_new(ic_value);
     332        (*ritem)->u.value = value;
     333}
     334
     335/** Write data to an address.
     336 *
     337 * Store @a value to the variable at @a address.
     338 */
     339void rdata_address_write(rdata_address_t *address, rdata_value_t *value)
     340{
     341        rdata_var_t *nvar;
     342        rdata_var_t *orig_var;
     343
     344        /* Perform a shallow copy of @c value->var. */
     345        rdata_var_copy(value->var, &nvar);
     346        orig_var = address->vref;
     347
     348        /* XXX do this in a prettier way. */
     349
     350        orig_var->vc = nvar->vc;
     351        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);
     357        }
     358
     359        /* XXX We should free some stuff around here. */
    197360}
    198361
     
    232395                printf("int(%d)", var->u.int_v->value);
    233396                break;
     397        case vc_string:
     398                printf("string(\"%s\")", var->u.string_v->value);
     399                break;
    234400        case vc_ref:
    235401                printf("ref");
     
    242408                break;
    243409        default:
     410                printf("print(%d)\n", var->vc);
    244411                assert(b_false);
    245412        }
  • uspace/app/sbi/src/rdata.h

    r09ababb7 rfa36f29  
    3636rdata_value_t *rdata_value_new(void);
    3737rdata_var_t *rdata_var_new(var_class_t vc);
     38rdata_ref_t *rdata_ref_new(void);
    3839rdata_deleg_t *rdata_deleg_new(void);
     40rdata_object_t *rdata_object_new(void);
    3941rdata_int_t *rdata_int_new(void);
    4042rdata_string_t *rdata_string_new(void);
    4143
    4244void rdata_var_copy(rdata_var_t *src, rdata_var_t **dest);
     45
     46void rdata_cvt_value_item(rdata_item_t *item, rdata_item_t **ritem);
     47void rdata_reference(rdata_var_t *var, rdata_item_t **res);
     48void rdata_dereference(rdata_item_t *ref, rdata_item_t **ritem);
     49void rdata_address_read(rdata_address_t *address, rdata_item_t **ritem);
     50void rdata_address_write(rdata_address_t *address, rdata_value_t *value);
     51
    4352void rdata_item_print(rdata_item_t *item);
    4453
  • uspace/app/sbi/src/rdata_t.h

    r09ababb7 rfa36f29  
    7474
    7575        /** Map field name SID to field data */
    76         intmap_t *fields; /* of (rdata_var_t *) */
     76        intmap_t fields; /* of (rdata_var_t *) */
    7777} rdata_object_t;
    7878
     
    141141 * assignment operator.
    142142 */
    143 typedef struct {
     143typedef struct rdata_item {
    144144        item_class_t ic;
    145145
  • uspace/app/sbi/src/run.c

    r09ababb7 rfa36f29  
    5151static void run_if(run_t *run, stree_if_t *if_s);
    5252static void run_while(run_t *run, stree_while_t *while_s);
    53 
    54 static void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var);
     53static void run_return(run_t *run, stree_return_t *return_s);
    5554
    5655/** Initialize runner instance. */
    5756void run_init(run_t *run)
    5857{
     58        (void) run;
    5959}
    6060
     
    6262void run_program(run_t *run, stree_program_t *prog)
    6363{
    64         stree_symbol_t *main_class_sym;
    6564        stree_symbol_t *main_fun_sym;
    66         stree_csi_t *main_class;
    6765        stree_fun_t *main_fun;
    6866        stree_ident_t *fake_ident;
    6967        list_t main_args;
     68        run_fun_ar_t *fun_ar;
     69        rdata_item_t *res;
    7070
    7171        /* Note down link to program code. */
     
    7575        run->thread_ar = run_thread_ar_new();
    7676        list_init(&run->thread_ar->fun_ar);
     77        run->thread_ar->bo_mode = bm_none;
    7778
    7879        /*
    79          * Resolve class @c HelloWorld
     80         * Find entry point @c Main().
    8081         */
    8182        fake_ident = stree_ident_new();
    82 
    83         fake_ident->sid = strtab_get_sid("HelloWorld");
    84         main_class_sym = symbol_lookup_in_csi(prog, NULL, fake_ident);
    85         main_class = symbol_to_csi(main_class_sym);
    86         if (main_class == NULL) {
    87                 printf("Error: HelloWorld is not a CSI.\n");
    88                 exit(1);
    89         }
    90 
    91 #ifdef DEBUG_RUN_TRACE
    92         printf("Found class '"); symbol_print_fqn(prog, main_class_sym);
    93         printf("'.\n");
    94 #endif
    95 
    96         /*
    97          * Resolve function @c main within the class.
    98          */
    99         fake_ident->sid = strtab_get_sid("main");
    100         main_fun_sym = symbol_lookup_in_csi(prog, main_class, fake_ident);
     83        fake_ident->sid = strtab_get_sid("Main");
     84        main_fun_sym = symbol_find_epoint(prog, fake_ident);
     85        if (main_fun_sym == NULL) {
     86                printf("Error: Entry point 'Main' not found.\n");
     87                exit(1);
     88        }
     89
    10190        main_fun = symbol_to_fun(main_fun_sym);
    102         if (main_fun == NULL) {
    103                 printf("Error: HelloWorld.main is not a function.\n");
    104                 exit(1);
    105         }
     91        assert(main_fun != NULL);
    10692
    10793#ifdef DEBUG_RUN_TRACE
     
    11096#endif
    11197
     98        /* Run function @c main. */
    11299        list_init(&main_args);
    113         run_fun(run, main_fun, &main_args);
     100        run_fun_ar_create(run, NULL, main_fun, &fun_ar);
     101        run_fun_ar_set_args(run, fun_ar, &main_args);
     102        run_fun(run, fun_ar, &res);
    114103}
    115104
    116105/** Run member function */
    117 void run_fun(run_t *run, stree_fun_t *fun, list_t *args)
     106void run_fun(run_t *run, run_fun_ar_t *fun_ar, rdata_item_t **res)
    118107{
    119108        stree_symbol_t *fun_sym;
    120         run_fun_ar_t *fun_ar;
    121         run_block_ar_t *block_ar;
    122         list_node_t *rarg_n, *farg_n;
     109        stree_fun_t *fun;
    123110        list_node_t *node;
    124         rdata_item_t *rarg;
    125         stree_fun_arg_t *farg;
    126         rdata_var_t *var;
    127 
    128         fun_sym = fun_to_symbol(fun);
     111
     112        fun_sym = fun_ar->fun_sym;
     113        fun = symbol_to_fun(fun_sym);
     114        assert(fun != NULL);
    129115
    130116#ifdef DEBUG_RUN_TRACE
     
    133119        printf("'.\n");
    134120#endif
    135 
    136         /* Create function activation record. */
    137         fun_ar = run_fun_ar_new();
    138         fun_ar->fun_sym = fun_sym;
    139         list_init(&fun_ar->block_ar);
    140 
    141121        /* Add function AR to the stack. */
    142122        list_append(&run->thread_ar->fun_ar, fun_ar);
    143 
    144         /* Create special block activation record to hold function arguments. */
    145         block_ar = run_block_ar_new();
    146         intmap_init(&block_ar->vars);
    147         list_append(&fun_ar->block_ar, block_ar);
    148 
    149         /* Declare local variables to hold argument values. */
    150         rarg_n = list_first(args);
    151         farg_n = list_first(&fun->args);
    152 
    153         while (farg_n != NULL) {
    154                 if (rarg_n == NULL) {
    155                         printf("Error: Too few arguments to function '");
    156                         symbol_print_fqn(run->program, fun_sym);
    157                         printf("'.\n");
    158                         exit(1);
    159                 }
    160 
    161                 rarg = list_node_data(rarg_n, rdata_item_t *);
    162                 farg = list_node_data(farg_n, stree_fun_arg_t *);
    163 
    164                 assert(rarg->ic == ic_value);
    165 
    166                 /* Construct a variable from the argument value. */
    167                 run_value_item_to_var(rarg, &var);
    168 
    169                 /* Declare variable using name of formal argument. */
    170                 intmap_set(&block_ar->vars, farg->name->sid, var);
    171 
    172                 rarg_n = list_next(args, rarg_n);
    173                 farg_n = list_next(&fun->args, farg_n);
    174         }
    175 
    176         /* Check for excess real parameters. */
    177         if (rarg_n != NULL) {
    178                 printf("Error: Too many arguments to function '");
    179                 symbol_print_fqn(run->program, fun_sym);
    180                 printf("'.\n");
    181                 exit(1);
    182         }
    183123
    184124        /* Run main function block. */
     
    189129        }
    190130
     131        /* Handle bailout. */
     132        switch (run->thread_ar->bo_mode) {
     133        case bm_stat:
     134                printf("Error: Misplaced 'break' statement.\n");
     135                exit(1);
     136        case bm_fun:
     137                run->thread_ar->bo_mode = bm_none;
     138                break;
     139        default:
     140                break;
     141        }
     142
    191143#ifdef DEBUG_RUN_TRACE
    192144        printf("Done executing function '");
     
    196148        run_print_fun_bt(run);
    197149#endif
    198 
    199150        /* Remove function activation record from the stack. */
    200151        node = list_last(&run->thread_ar->fun_ar);
    201152        assert(list_node_data(node, run_fun_ar_t *) == fun_ar);
    202153        list_remove(&run->thread_ar->fun_ar, node);
     154
     155        *res = fun_ar->retval;
    203156}
    204157
     
    227180                stat = list_node_data(node, stree_stat_t *);
    228181                run_stat(run, stat);
     182
     183                if (run->thread_ar->bo_mode != bm_none)
     184                        break;
     185
    229186                node = list_next(&block->stats, node);
    230187        }
     
    260217                run_while(run, stat->u.while_s);
    261218                break;
     219        case st_return:
     220                run_return(run, stat->u.return_s);
     221                break;
    262222        case st_for:
    263223        case st_raise:
     
    361321                run_block(run, while_s->body);
    362322                run_expr(run, while_s->cond, &rcond);
     323
     324                if (run->thread_ar->bo_mode != bm_none)
     325                        break;
    363326        }
    364327
     
    366329        printf("While statement terminated.\n");
    367330#endif
     331}
     332
     333/** Run @c return statement. */
     334static void run_return(run_t *run, stree_return_t *return_s)
     335{
     336        rdata_item_t *rexpr;
     337        run_fun_ar_t *fun_ar;
     338
     339#ifdef DEBUG_RUN_TRACE
     340        printf("Executing return statement.\n");
     341#endif
     342        run_expr(run, return_s->expr, &rexpr);
     343
     344        /* Store expression result in function AR. */
     345        fun_ar = run_get_current_fun_ar(run);
     346        fun_ar->retval = rexpr;
     347
     348        /* Force control to ascend and leave the function. */
     349        if (run->thread_ar->bo_mode == bm_none)
     350                run->thread_ar->bo_mode = bm_fun;
    368351}
    369352
     
    421404 * (2) Initialize the variable with the provided value.
    422405 */
    423 static void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var)
     406void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var)
    424407{
    425408        rdata_int_t *int_v;
    426409        rdata_string_t *string_v;
     410        rdata_ref_t *ref_v;
    427411        rdata_var_t *in_var;
    428412
     
    445429                string_v->value = item->u.value->var->u.string_v->value;
    446430                break;
     431        case vc_ref:
     432                *var = rdata_var_new(vc_ref);
     433                ref_v = rdata_ref_new();
     434
     435                (*var)->u.ref_v = ref_v;
     436                ref_v->vref = item->u.value->var->u.ref_v->vref;
     437                break;
    447438        default:
    448439                printf("Error: Unimplemented argument type.\n");
    449440                exit(1);
    450441
     442        }
     443}
     444
     445/** Construct a function AR. */
     446void run_fun_ar_create(run_t *run, rdata_var_t *obj, stree_fun_t *fun,
     447    run_fun_ar_t **rfun_ar)
     448{
     449        run_fun_ar_t *fun_ar;
     450
     451        (void) run;
     452
     453        /* Create function activation record. */
     454        fun_ar = run_fun_ar_new();
     455        fun_ar->obj = obj;
     456        fun_ar->fun_sym = fun_to_symbol(fun);
     457        list_init(&fun_ar->block_ar);
     458
     459        fun_ar->retval = NULL;
     460
     461        *rfun_ar = fun_ar;
     462}
     463
     464/** Fill arguments in a function AR. */
     465void run_fun_ar_set_args(run_t *run, run_fun_ar_t *fun_ar, list_t *args)
     466{
     467        stree_fun_t *fun;
     468        run_block_ar_t *block_ar;
     469        list_node_t *rarg_n, *farg_n;
     470        rdata_item_t *rarg;
     471        stree_fun_arg_t *farg;
     472        rdata_var_t *var;
     473
     474        /* AR should have been created with run_fun_ar_create(). */
     475        assert(fun_ar->fun_sym != NULL);
     476        assert(list_is_empty(&fun_ar->block_ar));
     477
     478        fun = symbol_to_fun(fun_ar->fun_sym);
     479        assert(fun != NULL);
     480
     481        /* Create special block activation record to hold function arguments. */
     482        block_ar = run_block_ar_new();
     483        intmap_init(&block_ar->vars);
     484        list_append(&fun_ar->block_ar, block_ar);
     485
     486        /* Declare local variables to hold argument values. */
     487        rarg_n = list_first(args);
     488        farg_n = list_first(&fun->args);
     489
     490        while (farg_n != NULL) {
     491                if (rarg_n == NULL) {
     492                        printf("Error: Too few arguments to function '");
     493                        symbol_print_fqn(run->program, fun_ar->fun_sym);
     494                        printf("'.\n");
     495                        exit(1);
     496                }
     497
     498                rarg = list_node_data(rarg_n, rdata_item_t *);
     499                farg = list_node_data(farg_n, stree_fun_arg_t *);
     500
     501                assert(rarg->ic == ic_value);
     502
     503                /* Construct a variable from the argument value. */
     504                run_value_item_to_var(rarg, &var);
     505
     506                /* Declare variable using name of formal argument. */
     507                intmap_set(&block_ar->vars, farg->name->sid, var);
     508
     509                rarg_n = list_next(args, rarg_n);
     510                farg_n = list_next(&fun->args, farg_n);
     511        }
     512
     513        /* Check for excess real parameters. */
     514        if (rarg_n != NULL) {
     515                printf("Error: Too many arguments to function '");
     516                symbol_print_fqn(run->program, fun_ar->fun_sym);
     517                printf("'.\n");
     518                exit(1);
    451519        }
    452520}
  • uspace/app/sbi/src/run.h

    r09ababb7 rfa36f29  
    3434void run_init(run_t *run);
    3535void run_program(run_t *run, stree_program_t *prog);
    36 void run_fun(run_t *run, stree_fun_t *fun, list_t *args);
     36void run_fun(run_t *run, run_fun_ar_t *fun_ar, rdata_item_t **res);
    3737
    3838void run_print_fun_bt(run_t *run);
     
    4242run_block_ar_t *run_get_current_block_ar(run_t *run);
    4343
     44void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var);
     45void run_fun_ar_set_args(run_t *run, run_fun_ar_t *fun_ar, list_t *args);
     46void run_fun_ar_create(run_t *run, rdata_var_t *obj, stree_fun_t *fun,
     47    run_fun_ar_t **rfun_ar);
     48
    4449run_thread_ar_t *run_thread_ar_new(void);
    4550run_fun_ar_t *run_fun_ar_new(void);
  • uspace/app/sbi/src/run_expr.c

    r09ababb7 rfa36f29  
    3333#include <assert.h>
    3434#include "debug.h"
     35#include "intmap.h"
    3536#include "list.h"
    3637#include "mytypes.h"
     
    4445static void run_nameref(run_t *run, stree_nameref_t *nameref,
    4546    rdata_item_t **res);
     47
    4648static void run_literal(run_t *run, stree_literal_t *literal,
    4749    rdata_item_t **res);
    4850static void run_lit_int(run_t *run, stree_lit_int_t *lit_int,
    4951    rdata_item_t **res);
     52static void run_lit_ref(run_t *run, stree_lit_ref_t *lit_ref,
     53    rdata_item_t **res);
    5054static void run_lit_string(run_t *run, stree_lit_string_t *lit_string,
    5155    rdata_item_t **res);
     56
     57static void run_self_ref(run_t *run, stree_self_ref_t *self_ref,
     58    rdata_item_t **res);
     59
    5260static void run_binop(run_t *run, stree_binop_t *binop, rdata_item_t **res);
     61static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     62    rdata_value_t *v2, rdata_item_t **res);
     63static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     64    rdata_value_t *v2, rdata_item_t **res);
     65
    5366static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
     67static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res);
     68
    5469static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res);
     70static void run_access_item(run_t *run, stree_access_t *access,
     71    rdata_item_t *arg, rdata_item_t **res);
     72static void run_access_ref(run_t *run, stree_access_t *access,
     73    rdata_item_t *arg, rdata_item_t **res);
     74static void run_access_deleg(run_t *run, stree_access_t *access,
     75    rdata_item_t *arg, rdata_item_t **res);
     76static void run_access_object(run_t *run, stree_access_t *access,
     77    rdata_item_t *arg, rdata_item_t **res);
     78
    5579static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res);
    5680static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res);
    57 
    58 static void run_address_read(run_t *run, rdata_address_t *address,
    59     rdata_item_t **ritem);
    60 static void run_address_write(run_t *run, rdata_address_t *address,
    61     rdata_value_t *value);
    6281
    6382/** Evaluate expression. */
     
    7594                run_literal(run, expr->u.literal, res);
    7695                break;
     96        case ec_self_ref:
     97                run_self_ref(run, expr->u.self_ref, res);
     98                break;
    7799        case ec_binop:
    78100                run_binop(run, expr->u.binop, res);
     
    80102        case ec_unop:
    81103                run_unop(run, expr->u.unop, res);
     104                break;
     105        case ec_new:
     106                run_new(run, expr->u.new_op, res);
    82107                break;
    83108        case ec_access:
     
    106131        rdata_item_t *item;
    107132        rdata_address_t *address;
    108         rdata_value_t *val;
     133        rdata_value_t *value;
    109134        rdata_var_t *var;
    110135        rdata_deleg_t *deleg_v;
     136
     137        run_fun_ar_t *fun_ar;
     138        stree_symbol_t *csi_sym;
     139        stree_csi_t *csi;
     140        rdata_object_t *obj;
     141        rdata_var_t *member_var;
    111142
    112143#ifdef DEBUG_RUN_TRACE
     
    137168         */
    138169
    139         /* XXX Start lookup in currently active CSI. */
    140         sym = symbol_lookup_in_csi(run->program, NULL, nameref->name);
     170        /* Determine currently active object or CSI. */
     171        fun_ar = run_get_current_fun_ar(run);
     172        if (fun_ar->obj != NULL) {
     173                assert(fun_ar->obj->vc == vc_object);
     174                obj = fun_ar->obj->u.object_v;
     175                csi_sym = obj->class_sym;
     176                csi = symbol_to_csi(csi_sym);
     177                assert(csi != NULL);
     178        } else {
     179                csi = fun_ar->fun_sym->outer_csi;
     180                obj = NULL;
     181        }
     182
     183        sym = symbol_lookup_in_csi(run->program, csi, nameref->name);
    141184
    142185        switch (sym->sc) {
     
    146189#endif
    147190                item = rdata_item_new(ic_value);
    148                 val = rdata_value_new();
     191                value = rdata_value_new();
    149192                var = rdata_var_new(vc_deleg);
    150193                deleg_v = rdata_deleg_new();
    151194
    152                 item->u.value = val;
    153                 val->var = var;
     195                item->u.value = value;
     196                value->var = var;
    154197                var->u.deleg_v = deleg_v;
    155198
     
    158201                *res = item;
    159202                break;
     203        case sc_fun:
     204                /* There should be no global functions. */
     205                assert(csi != NULL);
     206
     207                if (sym->outer_csi != csi) {
     208                        /* Function is not in the current object. */
     209                        printf("Error: Cannot access non-static member "
     210                            "function '");
     211                        symbol_print_fqn(run->program, sym);
     212                        printf("' from nested CSI '");
     213                        symbol_print_fqn(run->program, csi_sym);
     214                        printf("'.\n");
     215                        exit(1);
     216                }
     217
     218                /* Construct delegate. */
     219                item = rdata_item_new(ic_value);
     220                value = rdata_value_new();
     221                item->u.value = value;
     222
     223                var = rdata_var_new(vc_deleg);
     224                deleg_v = rdata_deleg_new();
     225                value->var = var;
     226                var->u.deleg_v = deleg_v;
     227
     228                deleg_v->obj = fun_ar->obj;
     229                deleg_v->sym = sym;
     230
     231                *res = item;
     232                break;
     233        case sc_var:
     234#ifdef DEBUG_RUN_TRACE
     235                printf("Referencing member variable.\n");
     236#endif
     237                /* There should be no global variables. */
     238                assert(csi != NULL);
     239
     240                /* XXX Assume variable is not static for now. */
     241                assert(obj != NULL);
     242
     243                if (sym->outer_csi != csi) {
     244                        /* Variable is not in the current object. */
     245                        printf("Error: Cannot access non-static member "
     246                            "variable '");
     247                        symbol_print_fqn(run->program, sym);
     248                        printf("' from nested CSI '");
     249                        symbol_print_fqn(run->program, csi_sym);
     250                        printf("'.\n");
     251                        exit(1);
     252                }
     253
     254                /* Find member variable in object. */
     255                member_var = intmap_get(&obj->fields, nameref->name->sid);
     256                assert(member_var != NULL);
     257
     258                /* Return address of the variable. */
     259                item = rdata_item_new(ic_address);
     260                address = rdata_address_new();
     261
     262                item->u.address = address;
     263                address->vref = member_var;
     264
     265                *res = item;
     266                break;
    160267        default:
    161268                printf("Referencing symbol class %d unimplemented.\n", sym->sc);
     
    176283        case ltc_int:
    177284                run_lit_int(run, &literal->u.lit_int, res);
     285                break;
     286        case ltc_ref:
     287                run_lit_ref(run, &literal->u.lit_ref, res);
    178288                break;
    179289        case ltc_string:
     
    197307        printf("Run integer literal.\n");
    198308#endif
     309        (void) run;
    199310
    200311        item = rdata_item_new(ic_value);
     
    211322}
    212323
     324/** Evaluate reference literal (@c nil). */
     325static void run_lit_ref(run_t *run, stree_lit_ref_t *lit_ref,
     326    rdata_item_t **res)
     327{
     328        rdata_item_t *item;
     329        rdata_value_t *value;
     330        rdata_var_t *var;
     331        rdata_ref_t *ref_v;
     332
     333#ifdef DEBUG_RUN_TRACE
     334        printf("Run reference literal (nil).\n");
     335#endif
     336        (void) run;
     337        (void) lit_ref;
     338
     339        item = rdata_item_new(ic_value);
     340        value = rdata_value_new();
     341        var = rdata_var_new(vc_ref);
     342        ref_v = rdata_ref_new();
     343
     344        item->u.value = value;
     345        value->var = var;
     346        var->u.ref_v = ref_v;
     347        ref_v->vref = NULL;
     348
     349        *res = item;
     350}
     351
    213352/** Evaluate string literal. */
    214353static void run_lit_string(run_t *run, stree_lit_string_t *lit_string,
     
    223362        printf("Run integer literal.\n");
    224363#endif
     364        (void) run;
     365
    225366        item = rdata_item_new(ic_value);
    226367        value = rdata_value_new();
     
    236377}
    237378
     379/** Evaluate @c self reference. */
     380static void run_self_ref(run_t *run, stree_self_ref_t *self_ref,
     381    rdata_item_t **res)
     382{
     383        run_fun_ar_t *fun_ar;
     384
     385#ifdef DEBUG_RUN_TRACE
     386        printf("Run self reference.\n");
     387#endif
     388        (void) self_ref;
     389        fun_ar = run_get_current_fun_ar(run);
     390
     391        /* Return reference to the currently active object. */
     392        rdata_reference(fun_ar->obj, res);
     393}
    238394
    239395/** Evaluate binary operation. */
     
    243399        rdata_item_t *rarg1_vi, *rarg2_vi;
    244400        rdata_value_t *v1, *v2;
    245         int i1, i2;
    246 
    247         rdata_item_t *item;
    248         rdata_value_t *value;
    249         rdata_var_t *var;
    250         rdata_int_t *int_v;
    251401
    252402#ifdef DEBUG_RUN_TRACE
     
    276426#endif
    277427
    278         run_cvt_value_item(run, rarg1_i, &rarg1_vi);
    279         run_cvt_value_item(run, rarg2_i, &rarg2_vi);
     428        rdata_cvt_value_item(rarg1_i, &rarg1_vi);
     429        rdata_cvt_value_item(rarg2_i, &rarg2_vi);
    280430
    281431        v1 = rarg1_vi->u.value;
    282432        v2 = rarg2_vi->u.value;
    283433
    284         if (v1->var->vc != vc_int || v2->var->vc != vc_int) {
    285                 printf("Unimplemented: Binary operation arguments are not "
    286                     "integer values.\n");
    287                 exit(1);
    288         }
     434        if (v1->var->vc != v2->var->vc) {
     435                printf("Unimplemented: Binary operation arguments have "
     436                    "different type.\n");
     437                exit(1);
     438        }
     439
     440        switch (v1->var->vc) {
     441        case vc_int:
     442                run_binop_int(run, binop, v1, v2, res);
     443                break;
     444        case vc_ref:
     445                run_binop_ref(run, binop, v1, v2, res);
     446                break;
     447        default:
     448                printf("Unimplemented: Binary operation arguments of "
     449                    "type %d.\n", v1->var->vc);
     450                exit(1);
     451        }
     452}
     453
     454/** Evaluate binary operation on int arguments. */
     455static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     456    rdata_value_t *v2, rdata_item_t **res)
     457{
     458        rdata_item_t *item;
     459        rdata_value_t *value;
     460        rdata_var_t *var;
     461        rdata_int_t *int_v;
     462
     463        int i1, i2;
     464
     465        (void) run;
    289466
    290467        item = rdata_item_new(ic_value);
     
    331508}
    332509
     510/** Evaluate binary operation on ref arguments. */
     511static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
     512    rdata_value_t *v2, rdata_item_t **res)
     513{
     514        rdata_item_t *item;
     515        rdata_value_t *value;
     516        rdata_var_t *var;
     517        rdata_int_t *int_v;
     518
     519        rdata_var_t *ref1, *ref2;
     520
     521        (void) run;
     522
     523        item = rdata_item_new(ic_value);
     524        value = rdata_value_new();
     525        var = rdata_var_new(vc_int);
     526        int_v = rdata_int_new();
     527
     528        item->u.value = value;
     529        value->var = var;
     530        var->u.int_v = int_v;
     531
     532        ref1 = v1->var->u.ref_v->vref;
     533        ref2 = v2->var->u.ref_v->vref;
     534
     535        switch (binop->bc) {
     536        /* XXX We should have a real boolean type. */
     537        case bo_equal:
     538                int_v->value = (ref1 == ref2) ? 1 : 0;
     539                break;
     540        case bo_notequal:
     541                int_v->value = (ref1 != ref2) ? 1 : 0;
     542                break;
     543        default:
     544                printf("Error: Invalid binary operation on reference "
     545                    "arguments (%d).\n", binop->bc);
     546                assert(b_false);
     547        }
     548
     549        *res = item;
     550}
     551
     552
    333553/** Evaluate unary operation. */
    334554static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res)
     
    343563}
    344564
     565/** Evaluate @c new operation. */
     566static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res)
     567{
     568        rdata_object_t *obj;
     569        rdata_var_t *obj_var;
     570
     571        stree_symbol_t *csi_sym;
     572        stree_csi_t *csi;
     573        stree_csimbr_t *csimbr;
     574
     575        rdata_var_t *mbr_var;
     576
     577        list_node_t *node;
     578
     579#ifdef DEBUG_RUN_TRACE
     580        printf("Run 'new' operation.\n");
     581#endif
     582        /* 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        }
     592
     593        /* Create the object. */
     594        obj = rdata_object_new();
     595        obj->class_sym = csi_sym;
     596        intmap_init(&obj->fields);
     597
     598        obj_var = rdata_var_new(vc_object);
     599        obj_var->u.object_v = obj;
     600
     601        /* Create object fields. */
     602        node = list_first(&csi->members);
     603        while (node != NULL) {
     604                csimbr = list_node_data(node, stree_csimbr_t *);
     605                if (csimbr->cc == csimbr_var) {
     606                        /* XXX Depends on member variable type. */
     607                        mbr_var = rdata_var_new(vc_int);
     608                        mbr_var->u.int_v = rdata_int_new();
     609                        mbr_var->u.int_v->value = 0;
     610
     611                        intmap_set(&obj->fields, csimbr->u.var->name->sid,
     612                            mbr_var);
     613                }
     614
     615                node = list_next(&csi->members, node);
     616        }
     617
     618        /* Create reference to the new object. */
     619        rdata_reference(obj_var, res);
     620}
     621
    345622/** Evaluate member acccess. */
    346623static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res)
    347624{
    348625        rdata_item_t *rarg;
     626
     627#ifdef DEBUG_RUN_TRACE
     628        printf("Run access operation.\n");
     629#endif
     630        run_expr(run, access->arg, &rarg);
     631        if (rarg == NULL) {
     632                printf("Error: Sub-expression has no value.\n");
     633                exit(1);
     634        }
     635
     636        run_access_item(run, access, rarg, res);
     637}
     638
     639/** Evaluate member acccess (with base already evaluated). */
     640static void run_access_item(run_t *run, stree_access_t *access,
     641    rdata_item_t *arg, rdata_item_t **res)
     642{
     643        var_class_t vc;
     644
     645#ifdef DEBUG_RUN_TRACE
     646        printf("Run access operation on pre-evaluated base.\n");
     647#endif
     648        switch (arg->ic) {
     649        case ic_value:
     650                vc = arg->u.value->var->vc;
     651                break;
     652        case ic_address:
     653                vc = arg->u.address->vref->vc;
     654                break;
     655        default:
     656                /* Silence warning. */
     657                abort();
     658        }
     659
     660        switch (vc) {
     661        case vc_ref:
     662                run_access_ref(run, access, arg, res);
     663                break;
     664        case vc_deleg:
     665                run_access_deleg(run, access, arg, res);
     666                break;
     667        case vc_object:
     668                run_access_object(run, access, arg, res);
     669                break;
     670        default:
     671                printf("Unimplemented: Using access operator ('.') "
     672                    "with unsupported data type (value/%d).\n", vc);
     673                exit(1);
     674        }
     675}
     676
     677/** Evaluate reference acccess. */
     678static void run_access_ref(run_t *run, stree_access_t *access,
     679    rdata_item_t *arg, rdata_item_t **res)
     680{
     681        rdata_item_t *darg;
     682
     683        /* Implicitly dereference. */
     684        rdata_dereference(arg, &darg);
     685
     686        /* Try again. */
     687        run_access_item(run, access, darg, res);
     688}
     689
     690/** Evaluate delegate-member acccess. */
     691static void run_access_deleg(run_t *run, stree_access_t *access,
     692    rdata_item_t *arg, rdata_item_t **res)
     693{
     694        rdata_item_t *arg_vi;
     695        rdata_value_t *arg_val;
    349696        rdata_deleg_t *deleg_v;
    350697        stree_symbol_t *member;
    351698
    352699#ifdef DEBUG_RUN_TRACE
    353         printf("Run access operation.\n");
    354 #endif
    355         run_expr(run, access->arg, &rarg);
    356 
    357         if (rarg->ic == ic_value && rarg->u.value->var->vc == vc_deleg) {
    358 #ifdef DEBUG_RUN_TRACE
    359                 printf("Accessing delegate.\n");
    360 #endif
    361                 deleg_v = rarg->u.value->var->u.deleg_v;
    362                 if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) {
    363                         printf("Error: Using '.' with symbol of wrong "
    364                             "type (%d).\n", deleg_v->sym->sc);
    365                         exit(1);
    366                 }
    367 
    368                 member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
    369                     access->member_name);
    370 
    371                 if (member == NULL) {
    372                         printf("Error: No such member.\n");
    373                         exit(1);
    374                 }
    375 
    376 #ifdef DEBUG_RUN_TRACE
    377                 printf("Found member '%s'.\n",
     700        printf("Run delegate access operation.\n");
     701#endif
     702        rdata_cvt_value_item(arg, &arg_vi);
     703        arg_val = arg_vi->u.value;
     704        assert(arg_val->var->vc == vc_deleg);
     705
     706        deleg_v = arg_val->var->u.deleg_v;
     707        if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) {
     708                printf("Error: Using '.' with delegate to different object "
     709                    "than a CSI (%d).\n", deleg_v->sym->sc);
     710                exit(1);
     711        }
     712
     713        member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
     714            access->member_name);
     715
     716        if (member == NULL) {
     717                printf("Error: CSI '");
     718                symbol_print_fqn(run->program, deleg_v->sym);
     719                printf("' has no member named '%s'.\n",
    378720                    strtab_get_str(access->member_name->sid));
    379 #endif
    380 
    381                 /* Reuse existing item, value, var, deleg. */
     721                exit(1);
     722        }
     723
     724#ifdef DEBUG_RUN_TRACE
     725        printf("Found member '%s'.\n",
     726            strtab_get_str(access->member_name->sid));
     727#endif
     728
     729        /*
     730         * Reuse existing item, value, var, deleg.
     731         * XXX This is maybe not a good idea because it complicates memory
     732         * management as there is not a single owner
     733         */
     734        deleg_v->sym = member;
     735        *res = arg;
     736}
     737
     738/** Evaluate object member acccess. */
     739static void run_access_object(run_t *run, stree_access_t *access,
     740    rdata_item_t *arg, rdata_item_t **res)
     741{
     742        stree_symbol_t *member;
     743        rdata_object_t *object;
     744        rdata_item_t *ritem;
     745        rdata_address_t *address;
     746
     747        rdata_value_t *value;
     748        rdata_deleg_t *deleg_v;
     749        rdata_var_t *var;
     750
     751#ifdef DEBUG_RUN_TRACE
     752        printf("Run object access operation.\n");
     753#endif
     754        assert(arg->ic == ic_address);
     755        assert(arg->u.value->var->vc == vc_object);
     756
     757        object = arg->u.value->var->u.object_v;
     758
     759        member = symbol_search_csi(run->program, object->class_sym->u.csi,
     760            access->member_name);
     761
     762        if (member == NULL) {
     763                printf("Error: Object of class '");
     764                symbol_print_fqn(run->program, object->class_sym);
     765                printf("' has no member named '%s'.\n",
     766                    strtab_get_str(access->member_name->sid));
     767                exit(1);
     768        }
     769
     770#ifdef DEBUG_RUN_TRACE
     771        printf("Found member '%s'.\n",
     772            strtab_get_str(access->member_name->sid));
     773#endif
     774
     775        switch (member->sc) {
     776        case sc_csi:
     777                printf("Error: Accessing object member which is nested CSI.\n");
     778                exit(1);
     779        case sc_fun:
     780                /* Construct delegate. */
     781                ritem = rdata_item_new(ic_value);
     782                value = rdata_value_new();
     783                ritem->u.value = value;
     784
     785                var = rdata_var_new(vc_deleg);
     786                value->var = var;
     787                deleg_v = rdata_deleg_new();
     788                var->u.deleg_v = deleg_v;
     789
     790                deleg_v->obj = arg->u.value->var;
    382791                deleg_v->sym = member;
    383 
    384                 *res = rarg;
    385                 return;
    386         }
    387 
    388         *res = NULL;
     792                break;
     793        case sc_var:
     794                /* Construct variable address item. */
     795                ritem = rdata_item_new(ic_address);
     796                address = rdata_address_new();
     797                ritem->u.address = address;
     798
     799                address->vref = intmap_get(&object->fields,
     800                    access->member_name->sid);
     801                assert(address->vref != NULL);
     802                break;
     803        case sc_prop:
     804                printf("Unimplemented: Accessing object property.\n");
     805                exit(1);
     806        }
     807
     808        *res = ritem;
    389809}
    390810
     
    399819        rdata_item_t *rarg_i, *rarg_vi;
    400820
     821        stree_fun_t *fun;
     822        run_fun_ar_t *fun_ar;
     823
    401824#ifdef DEBUG_RUN_TRACE
    402825        printf("Run call operation.\n");
     
    422845        printf("'\n");
    423846#endif
    424 
    425847        /* Evaluate function arguments. */
    426848        list_init(&arg_vals);
     
    430852                arg = list_node_data(node, stree_expr_t *);
    431853                run_expr(run, arg, &rarg_i);
    432                 run_cvt_value_item(run, rarg_i, &rarg_vi);
     854                rdata_cvt_value_item(rarg_i, &rarg_vi);
    433855
    434856                list_append(&arg_vals, rarg_vi);
     
    436858        }
    437859
    438         run_fun(run, deleg_v->sym->u.fun, &arg_vals);
     860        fun = symbol_to_fun(deleg_v->sym);
     861        assert(fun != NULL);
     862
     863        /* Create function activation record. */
     864        run_fun_ar_create(run, deleg_v->obj, fun, &fun_ar);
     865
     866        /* Fill in argument values. */
     867        run_fun_ar_set_args(run, fun_ar, &arg_vals);
     868
     869        /* Run the function. */
     870        run_fun(run, fun_ar, res);
    439871
    440872#ifdef DEBUG_RUN_TRACE
    441873        printf("Returned from function call.\n");
    442874#endif
    443         *res = NULL;
    444875}
    445876
     
    457888        run_expr(run, assign->src, &rsrc_i);
    458889
    459         run_cvt_value_item(run, rsrc_i, &rsrc_vi);
     890        rdata_cvt_value_item(rsrc_i, &rsrc_vi);
    460891        src_val = rsrc_vi->u.value;
    461892
     
    466897        }
    467898
    468         run_address_write(run, rdest_i->u.address, rsrc_vi->u.value);
     899        rdata_address_write(rdest_i->u.address, rsrc_vi->u.value);
    469900
    470901        *res = NULL;
     
    483914        rdata_var_t *var;
    484915
    485         run_cvt_value_item(run, item, &vitem);
     916        (void) run;
     917        rdata_cvt_value_item(item, &vitem);
    486918
    487919        assert(vitem->ic == ic_value);
     
    495927        return (var->u.int_v->value != 0);
    496928}
    497 
    498 /** Convert item to value item.
    499  *
    500  * If @a item is a value, we just return a copy. If @a item is an address,
    501  * we read from the address.
    502  */
    503 void run_cvt_value_item(run_t *run, rdata_item_t *item,
    504     rdata_item_t **ritem)
    505 {
    506         rdata_value_t *value;
    507 
    508         /* Address item. Perform read operation. */
    509         if (item->ic == ic_address) {
    510                 run_address_read(run, item->u.address, ritem);
    511                 return;
    512         }
    513 
    514         /* It already is a value, we can share the @c var. */
    515         value = rdata_value_new();
    516         value->var = item->u.value->var;
    517         *ritem = rdata_item_new(ic_value);
    518         (*ritem)->u.value = value;
    519 }
    520 
    521 /** Read data from an address.
    522  *
    523  * Return value stored in a variable at the specified address.
    524  */
    525 static void run_address_read(run_t *run, rdata_address_t *address,
    526     rdata_item_t **ritem)
    527 {
    528         rdata_value_t *value;
    529         rdata_var_t *rvar;
    530         (void) run;
    531 
    532         /* Perform a shallow copy of @c var. */
    533         rdata_var_copy(address->vref, &rvar);
    534 
    535         value = rdata_value_new();
    536         value->var = rvar;
    537         *ritem = rdata_item_new(ic_value);
    538         (*ritem)->u.value = value;
    539 }
    540 
    541 /** Write data to an address.
    542  *
    543  * Store @a value to the variable at @a address.
    544  */
    545 static void run_address_write(run_t *run, rdata_address_t *address,
    546     rdata_value_t *value)
    547 {
    548         rdata_var_t *nvar;
    549         rdata_var_t *orig_var;
    550 
    551         /* Perform a shallow copy of @c value->var. */
    552         rdata_var_copy(value->var, &nvar);
    553         orig_var = address->vref;
    554 
    555         /* XXX do this in a prettier way. */
    556 
    557         orig_var->vc = nvar->vc;
    558         switch (nvar->vc) {
    559         case vc_int: orig_var->u.int_v = nvar->u.int_v; break;
    560         case vc_ref: orig_var->u.ref_v = nvar->u.ref_v; break;
    561         case vc_deleg: orig_var->u.deleg_v = nvar->u.deleg_v; break;
    562         case vc_object: orig_var->u.object_v = nvar->u.object_v; break;
    563         default: assert(b_false);
    564         }
    565 
    566         /* XXX We should free some stuff around here. */
    567 }
  • uspace/app/sbi/src/run_expr.h

    r09ababb7 rfa36f29  
    3434void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res);
    3535
    36 void run_cvt_value_item(run_t *run, rdata_item_t *item,
    37     rdata_item_t **ritem);
    3836bool_t run_item_boolean_value(run_t *run, rdata_item_t *item);
    3937
  • uspace/app/sbi/src/run_t.h

    r09ababb7 rfa36f29  
    4343} run_block_ar_t;
    4444
     45
    4546/** Function activation record
    4647 *
     
    4849 */
    4950typedef struct run_fun_ar {
     51        /** Object on which the member function is being invoked or @c NULL. */
     52        struct rdata_var *obj;
     53
    5054        /** Definition of function being invoked */
    5155        struct stree_symbol *fun_sym;
     
    5357        /** Block activation records */
    5458        list_t block_ar; /* of run_block_ar_t */
     59
     60        /** Function return value or @c NULL if not set. */
     61        struct rdata_item *retval;
    5562} run_fun_ar_t;
     63
     64/** Bailout mode
     65 *
     66 * Determines whether control is bailing out of a statement, function, etc.
     67 */
     68typedef enum {
     69        /** Normal execution */
     70        bm_none,
     71
     72        /** Break from statement */
     73        bm_stat,
     74
     75        /** Return from function */
     76        bm_fun
     77} run_bailout_mode;
    5678
    5779/** Thread activation record
     
    6082 */
    6183typedef struct run_thread_ar {
    62         /** Function activation records. */
     84        /** Function activation records */
    6385        list_t fun_ar; /* of run_fun_ar_t */
     86
     87        /** Bailout mode */
     88        run_bailout_mode bo_mode;
    6489} run_thread_ar_t;
    6590
  • uspace/app/sbi/src/stree.c

    r09ababb7 rfa36f29  
    228228}
    229229
     230stree_return_t *stree_return_new(void)
     231{
     232        stree_return_t *return_s;
     233
     234        return_s = calloc(1, sizeof(stree_return_t));
     235        if (return_s == NULL) {
     236                printf("Memory allocation failed.\n");
     237                exit(1);
     238        }
     239
     240        return return_s;
     241}
     242
    230243stree_wef_t *stree_wef_new(void)
    231244{
     
    309322}
    310323
     324stree_new_t *stree_new_new(void)
     325{
     326        stree_new_t *new_op;
     327
     328        new_op = calloc(1, sizeof(stree_new_t));
     329        if (new_op == NULL) {
     330                printf("Memory allocation failed.\n");
     331                exit(1);
     332        }
     333
     334        return new_op;
     335}
     336
    311337stree_access_t *stree_access_new(void)
    312338{
     
    375401}
    376402
     403stree_self_ref_t *stree_self_ref_new(void)
     404{
     405        stree_self_ref_t *self_ref;
     406
     407        self_ref = calloc(1, sizeof(stree_self_ref_t));
     408        if (self_ref == NULL) {
     409                printf("Memory allocation failed.\n");
     410                exit(1);
     411        }
     412
     413        return self_ref;
     414}
     415
    377416stree_texpr_t *stree_texpr_new(texpr_class_t tc)
    378417{
     
    415454}
    416455
     456stree_tliteral_t *stree_tliteral_new(void)
     457{
     458        stree_tliteral_t *tliteral;
     459
     460        tliteral = calloc(1, sizeof(stree_tliteral_t));
     461        if (tliteral == NULL) {
     462                printf("Memory allocation failed.\n");
     463                exit(1);
     464        }
     465
     466        return tliteral;
     467}
     468
    417469stree_tnameref_t *stree_tnameref_new(void)
    418470{
  • uspace/app/sbi/src/stree.h

    r09ababb7 rfa36f29  
    4848stree_for_t *stree_for_new(void);
    4949stree_raise_t *stree_raise_new(void);
     50stree_return_t *stree_return_new(void);
    5051stree_wef_t *stree_wef_new(void);
    5152stree_exps_t *stree_exps_new(void);
     
    5556stree_assign_t *stree_assign_new(assign_class_t ac);
    5657stree_binop_t *stree_binop_new(binop_class_t bc);
     58stree_new_t *stree_new_new(void);
    5759stree_access_t *stree_access_new(void);
    5860stree_call_t *stree_call_new(void);
     
    6163stree_ident_t *stree_ident_new(void);
    6264stree_literal_t *stree_literal_new(literal_class_t ltc);
     65stree_self_ref_t *stree_self_ref_new(void);
    6366
    6467stree_texpr_t *stree_texpr_new(texpr_class_t tc);
    6568stree_tapply_t *stree_tapply_new(void);
    6669stree_taccess_t *stree_taccess_new(void);
     70stree_tliteral_t *stree_tliteral_new(void);
    6771stree_tnameref_t *stree_tnameref_new(void);
    6872
  • uspace/app/sbi/src/stree_t.h

    r09ababb7 rfa36f29  
    4848} stree_nameref_t;
    4949
     50/** Reference to currently active object. */
     51typedef struct {
     52} stree_self_ref_t;
     53
    5054typedef struct {
    5155        int value;
    5256} stree_lit_int_t;
    5357
     58/** Reference literal (there is only one: @c nil). */
     59typedef struct {
     60} stree_lit_ref_t;
     61
    5462typedef struct {
    5563        char *value;
     
    5866typedef enum {
    5967        ltc_int,
     68        ltc_ref,
    6069        ltc_string
    6170} literal_class_t;
     
    6675        union {
    6776                stree_lit_int_t lit_int;
     77                stree_lit_ref_t lit_ref;
    6878                stree_lit_string_t lit_string;
    6979        } u;
     
    107117} stree_unop_t;
    108118
     119/** New operation */
     120typedef struct {
     121        /** Type of object to construct. */
     122        struct stree_texpr *texpr;
     123} stree_new_t;
     124
    109125/** Member access operation */
    110126typedef struct {
     
    139155        ec_nameref,
    140156        ec_literal,
     157        ec_self_ref,
    141158        ec_binop,
    142159        ec_unop,
     160        ec_new,
    143161        ec_access,
    144162        ec_call,
     
    153171                stree_nameref_t *nameref;
    154172                stree_literal_t *literal;
     173                stree_self_ref_t *self_ref;
    155174                stree_binop_t *binop;
    156175                stree_unop_t *unop;
     176                stree_new_t *new_op;
    157177                stree_access_t *access;
    158178                stree_call_t *call;
     
    166186
    167187struct stree_texpr;
     188
     189/** Type literal class */
     190typedef enum {
     191        tlc_int,
     192        tlc_string
     193} tliteral_class_t;
     194
     195/** Type literal */
     196typedef struct {
     197        tliteral_class_t tlc;
     198} stree_tliteral_t;
    168199
    169200/** Type name reference */
     
    188219/** Type expression class */
    189220typedef enum {
     221        tc_tliteral,
    190222        tc_tnameref,
    191223        tc_taccess,
     
    198230
    199231        union {
     232                stree_tliteral_t *tliteral;
    200233                stree_tnameref_t *tnameref;
    201234                stree_taccess_t *taccess;
     
    241274typedef struct {
    242275} stree_raise_t;
     276
     277/** Return statement */
     278typedef struct {
     279        stree_expr_t *expr;
     280} stree_return_t;
    243281
    244282/** Expression statement */
     
    261299        st_for,
    262300        st_raise,
     301        st_return,
    263302        st_exps,
    264303        st_wef
     
    275314                stree_for_t *for_s;
    276315                stree_raise_t *raise_s;
     316                stree_return_t *return_s;
    277317                stree_exps_t *exp_s;
    278318                stree_wef_t *wef_s;
  • uspace/app/sbi/src/symbol.c

    r09ababb7 rfa36f29  
    4040static stree_symbol_t *symbol_search_global(stree_program_t *prog,
    4141    stree_ident_t *name);
     42static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
     43    stree_ident_t *name, stree_csi_t *csi);
    4244static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
    4345
     
    9294
    9395        if (symbol == NULL) {
    94                 printf("Error: Symbol '%s' not found\n", strtab_get_str(name->sid));
     96                printf("Error: Symbol '%s' not found.\n", strtab_get_str(name->sid));
    9597                exit(1);
    9698        }
     
    111113        stree_symbol_t *symbol;
    112114        stree_ident_t *mbr_name;
     115        stree_symbol_t *base_csi_sym;
     116        stree_csi_t *base_csi;
     117
     118        (void) prog;
     119
     120        /* Look in new members in this class. */
    113121
    114122        node = list_first(&scope->members);
     
    146154        }
    147155
     156        /* Try inherited members. */
     157        if (scope->base_csi_ref != NULL) {
     158                base_csi_sym = symbol_xlookup_in_csi(prog,
     159                    csi_to_symbol(scope)->outer_csi, scope->base_csi_ref);
     160                base_csi = symbol_to_csi(base_csi_sym);
     161                assert(base_csi != NULL);
     162
     163                return symbol_search_csi(prog, base_csi, name);
     164        }
     165
     166        /* No match */
    148167        return NULL;
    149168}
     
    176195}
    177196
     197/** Find entry point. */
     198stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name)
     199{
     200        list_node_t *node;
     201        stree_modm_t *modm;
     202        stree_symbol_t *entry, *etmp;
     203
     204        entry = NULL;
     205
     206        node = list_first(&prog->module->members);
     207        while (node != NULL) {
     208                modm = list_node_data(node, stree_modm_t *);
     209                if (modm->mc == mc_csi) {
     210                        etmp = symbol_find_epoint_rec(prog, name, modm->u.csi);
     211                        if (etmp != NULL) {
     212                                if (entry != NULL) {
     213                                        printf("Error: Duplicate entry point.\n");
     214                                        exit(1);
     215                                }
     216                                entry = etmp;
     217                        }
     218                }
     219                node = list_next(&prog->module->members, node);
     220        }
     221
     222        return entry;
     223}
     224
     225static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
     226    stree_ident_t *name, stree_csi_t *csi)
     227{
     228        list_node_t *node;
     229        stree_csimbr_t *csimbr;
     230        stree_symbol_t *entry, *etmp;
     231
     232        entry = NULL;
     233
     234        node = list_first(&csi->members);
     235        while (node != NULL) {
     236                csimbr = list_node_data(node, stree_csimbr_t *);
     237
     238                switch (csimbr->cc) {
     239                case csimbr_csi:
     240                        etmp = symbol_find_epoint_rec(prog, name, csimbr->u.csi);
     241                        if (etmp != NULL) {
     242                                if (entry != NULL) {
     243                                        printf("Error: Duplicate entry point.\n");
     244                                        exit(1);
     245                                }
     246                                entry = etmp;
     247                        }
     248                        break;
     249                case csimbr_fun:
     250                        if (csimbr->u.fun->name->sid == name->sid) {
     251                                if (entry != NULL) {
     252                                        printf("Error: Duplicate entry point.\n");
     253                                        exit(1);
     254                                }
     255                                entry = fun_to_symbol(csimbr->u.fun);
     256                        }
     257                default:
     258                        break;
     259                }
     260
     261                node = list_next(&csi->members, node);
     262        }
     263
     264        return entry;
     265}
     266
    178267stree_csi_t *symbol_to_csi(stree_symbol_t *symbol)
    179268{
  • uspace/app/sbi/src/symbol.h

    r09ababb7 rfa36f29  
    3838stree_symbol_t *symbol_search_csi(stree_program_t *prog, stree_csi_t *scope,
    3939    stree_ident_t *name);
    40 
     40stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name);
    4141
    4242stree_csi_t *symbol_to_csi(stree_symbol_t *symbol);
  • uspace/dist/sysel/count.sy

    r09ababb7 rfa36f29  
    1 class Counter is
    2         fun count(a : Int; b : Int) is
    3                 var i : Int;
     1class CountDemo is
     2        fun Count(a : int; b : int) is
     3                var i : int;
    44
    55                i = a;
     
    1010
    1111        end
    12 end
    1312
    14 class HelloWorld is
    15         fun main() is
    16                 Counter.count(0, 10);
     13        fun Main() is
     14                Count(0, 10);
    1715        end
    1816end
  • uspace/dist/sysel/hello.sy

    r09ababb7 rfa36f29  
    11class HelloWorld is
    2         fun main() is
     2        fun Main() is
    33                Builtin.WriteLine("Hello world!");
    44        end
Note: See TracChangeset for help on using the changeset viewer.