Changeset 94d484a in mainline for uspace/app/sbi/src/run_expr.c


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

Update SBI to rev. 90.

File:
1 edited

Legend:

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

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