Ignore:
File:
1 edited

Legend:

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

    r051bc69a r6c39a907  
    7878static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    7979    rdata_value_t *v2, rdata_item_t **res);
    80 static void run_binop_enum(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    81     rdata_value_t *v2, rdata_item_t **res);
    8280
    8381static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res);
    84 static void run_unop_bool(run_t *run, stree_unop_t *unop, rdata_value_t *val,
    85     rdata_item_t **res);
    8682static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
    8783    rdata_item_t **res);
     
    9288static void run_new_object(run_t *run, stree_new_t *new_op,
    9389    tdata_item_t *titem, rdata_item_t **res);
    94 
    95 static void run_object_ctor(run_t *run, rdata_var_t *obj, list_t *arg_vals);
    9690
    9791static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res);
     
    10498static void run_access_object(run_t *run, stree_access_t *access,
    10599    rdata_item_t *arg, rdata_item_t **res);
    106 static void run_access_symbol(run_t *run, stree_access_t *access,
    107     rdata_item_t *arg, rdata_item_t **res);
    108100
    109101static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res);
    110 static void run_call_args(run_t *run, list_t *args, list_t *arg_vals);
    111 
    112102static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res);
    113103static void run_index_array(run_t *run, stree_index_t *index,
     
    199189        rdata_var_t *var;
    200190        rdata_deleg_t *deleg_v;
    201         rdata_symbol_t *symbol_v;
    202191
    203192        run_proc_ar_t *proc_ar;
     
    257246        case sc_csi:
    258247#ifdef DEBUG_RUN_TRACE
    259                 printf("Referencing CSI.\n");
     248                printf("Referencing class.\n");
    260249#endif
    261250                item = rdata_item_new(ic_value);
     
    271260                deleg_v->sym = sym;
    272261                *res = item;
    273                 break;
    274         case sc_ctor:
    275                 /* It is not possible to reference a constructor explicitly. */
    276                 assert(b_false);
    277         case sc_enum:
    278 #ifdef DEBUG_RUN_TRACE
    279                 printf("Referencing enum.\n");
    280 #endif
    281                 item = rdata_item_new(ic_value);
    282                 value = rdata_value_new();
    283                 var = rdata_var_new(vc_symbol);
    284                 symbol_v = rdata_symbol_new();
    285 
    286                 item->u.value = value;
    287                 value->var = var;
    288                 var->u.symbol_v = symbol_v;
    289 
    290                 symbol_v->sym = sym;
    291                 *res = item;
    292                 break;
    293         case sc_deleg:
    294                 /* XXX TODO */
    295                 printf("Unimplemented: Delegate name reference.\n");
    296                 abort();
    297262                break;
    298263        case sc_fun:
     
    364329                *res = item;
    365330                break;
    366         case sc_prop:
    367                 /* XXX TODO */
    368                 printf("Unimplemented: Property name reference.\n");
    369                 abort();
     331        default:
     332                printf("Referencing symbol class %d unimplemented.\n", sym->sc);
     333                *res = NULL;
    370334                break;
    371335        }
     
    607571        }
    608572
     573        switch (binop->bc) {
     574        case bo_plus:
     575        case bo_minus:
     576        case bo_mult:
     577        case bo_equal:
     578        case bo_notequal:
     579        case bo_lt:
     580        case bo_gt:
     581        case bo_lt_equal:
     582        case bo_gt_equal:
     583                /* These are implemented so far. */
     584                break;
     585        default:
     586                printf("Unimplemented: Binary operation type %d.\n",
     587                    binop->bc);
     588                exit(1);
     589        }
     590
    609591#ifdef DEBUG_RUN_TRACE
    610592        printf("Check binop argument results.\n");
     
    639621                run_binop_ref(run, binop, v1, v2, res);
    640622                break;
    641         case vc_enum:
    642                 run_binop_enum(run, binop, v1, v2, res);
    643                 break;
    644623        case vc_deleg:
    645624        case vc_array:
    646625        case vc_object:
    647626        case vc_resource:
    648         case vc_symbol:
    649627                assert(b_false);
    650628        }
     
    707685                bool_v->value = (b1 == b_true) || (b2 == b_false);
    708686                break;
    709 
    710         case bo_and:
    711                 bool_v->value = (b1 == b_true) && (b2 == b_true);
    712                 break;
    713         case bo_or:
    714                 bool_v->value = (b1 == b_true) || (b2 == b_true);
    715                 break;
    716687        }
    717688
     
    782753                bool_v->value = !nf;
    783754                break;
    784 
    785         case bo_and:
    786         case bo_or:
     755        default:
    787756                assert(b_false);
    788757        }
     
    863832
    864833        switch (binop->bc) {
    865         case bo_plus:
    866         case bo_minus:
    867         case bo_mult:
    868                 assert(b_false);
    869 
    870834        case bo_equal:
    871835                bool_v->value = zf;
     
    886850                bool_v->value = !nf;
    887851                break;
    888         case bo_and:
    889         case bo_or:
     852        default:
    890853                assert(b_false);
    891854        }
     
    909872        rdata_var_t *var;
    910873        rdata_string_t *string_v;
    911         rdata_bool_t *bool_v;
    912         bool_t done;
    913         bool_t zf;
    914874
    915875        const char *s1, *s2;
     
    919879        item = rdata_item_new(ic_value);
    920880        value = rdata_value_new();
     881        var = rdata_var_new(vc_string);
     882        string_v = rdata_string_new();
    921883
    922884        item->u.value = value;
     885        value->var = var;
     886        var->u.string_v = string_v;
    923887
    924888        s1 = v1->var->u.string_v->value;
    925889        s2 = v2->var->u.string_v->value;
    926 
    927         done = b_true;
    928890
    929891        switch (binop->bc) {
    930892        case bo_plus:
    931893                /* Concatenate strings. */
    932                 string_v = rdata_string_new();
    933894                string_v->value = os_str_acat(s1, s2);
    934                 break;
    935         default:
    936                 done = b_false;
    937                 break;
    938         }
    939 
    940         if (done) {
    941                 var = rdata_var_new(vc_string);
    942                 var->u.string_v = string_v;
    943                 value->var = var;
    944                 *res = item;
    945                 return;
    946         }
    947 
    948         var = rdata_var_new(vc_bool);
    949         bool_v = rdata_bool_new();
    950         var->u.bool_v = bool_v;
    951         value->var = var;
    952 
    953         /* Relational operation. */
    954 
    955         zf = os_str_cmp(s1, s2) == 0;
    956 
    957         switch (binop->bc) {
    958         case bo_equal:
    959                 bool_v->value = zf;
    960                 break;
    961         case bo_notequal:
    962                 bool_v->value = !zf;
    963895                break;
    964896        default:
     
    1019951}
    1020952
    1021 /** Evaluate binary operation on enum arguments.
    1022  *
    1023  * @param run           Runner object
    1024  * @param binop         Binary operation
    1025  * @param v1            Value of first argument
    1026  * @param v2            Value of second argument
    1027  * @param res           Place to store result
    1028  */
    1029 static void run_binop_enum(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    1030     rdata_value_t *v2, rdata_item_t **res)
    1031 {
    1032         rdata_item_t *item;
    1033         rdata_value_t *value;
    1034         rdata_var_t *var;
    1035         rdata_bool_t *bool_v;
    1036 
    1037         rdata_var_t *ref1, *ref2;
    1038 
    1039         (void) run;
    1040 
    1041         item = rdata_item_new(ic_value);
    1042         value = rdata_value_new();
    1043         var = rdata_var_new(vc_bool);
    1044         bool_v = rdata_bool_new();
    1045 
    1046         item->u.value = value;
    1047         value->var = var;
    1048         var->u.bool_v = bool_v;
    1049 
    1050         ref1 = v1->var->u.ref_v->vref;
    1051         ref2 = v2->var->u.ref_v->vref;
    1052 
    1053         switch (binop->bc) {
    1054         case bo_equal:
    1055                 bool_v->value = (ref1 == ref2);
    1056                 break;
    1057         case bo_notequal:
    1058                 bool_v->value = (ref1 != ref2);
    1059                 break;
    1060         default:
    1061                 /* Should have been caught by static typing. */
    1062                 assert(b_false);
    1063         }
    1064 
    1065         *res = item;
    1066 }
    1067953
    1068954/** Evaluate unary operation.
     
    1095981
    1096982        switch (val->var->vc) {
    1097         case vc_bool:
    1098                 run_unop_bool(run, unop, val, res);
    1099                 break;
    1100983        case vc_int:
    1101984                run_unop_int(run, unop, val, res);
     
    1110993}
    1111994
    1112 /** Evaluate unary operation on bool argument.
    1113  *
    1114  * @param run           Runner object
    1115  * @param unop          Unary operation
    1116  * @param val           Value of argument
    1117  * @param res           Place to store result
    1118  */
    1119 static void run_unop_bool(run_t *run, stree_unop_t *unop, rdata_value_t *val,
    1120     rdata_item_t **res)
    1121 {
    1122         rdata_item_t *item;
    1123         rdata_value_t *value;
    1124         rdata_var_t *var;
    1125         rdata_bool_t *bool_v;
    1126 
    1127         (void) run;
    1128 
    1129         item = rdata_item_new(ic_value);
    1130         value = rdata_value_new();
    1131         var = rdata_var_new(vc_bool);
    1132         bool_v = rdata_bool_new();
    1133 
    1134         item->u.value = value;
    1135         value->var = var;
    1136         var->u.bool_v = bool_v;
    1137 
    1138         switch (unop->uc) {
    1139         case uo_plus:
    1140         case uo_minus:
    1141                 assert(b_false);
    1142 
    1143         case uo_not:
    1144                 bool_v->value = !val->var->u.bool_v->value;
    1145                 break;
    1146         }
    1147 
    1148         *res = item;
    1149 }
    1150 
    1151995/** Evaluate unary operation on int argument.
    1152996 *
     
    11831027                    &int_v->value);
    11841028                break;
    1185         case uo_not:
    1186                 assert(b_false);
    11871029        }
    11881030
    11891031        *res = item;
    11901032}
     1033
    11911034
    11921035/** Evaluate @c new operation.
     
    13431186{
    13441187        stree_csi_t *csi;
    1345         rdata_item_t *obj_i;
    1346         list_t arg_vals;
    13471188
    13481189#ifdef DEBUG_RUN_TRACE
    13491190        printf("Create new object.\n");
    13501191#endif
     1192        (void) new_op;
     1193
    13511194        /* Lookup object CSI. */
    13521195        assert(titem->tic == tic_tobject);
    13531196        csi = titem->u.tobject->csi;
    13541197
    1355         /* Evaluate constructor arguments. */
    1356         run_call_args(run, &new_op->ctor_args, &arg_vals);
    1357         if (run_is_bo(run)) {
    1358                 *res = NULL;
    1359                 return;
    1360         }
    1361 
    13621198        /* Create CSI instance. */
    13631199        run_new_csi_inst(run, csi, res);
    1364 
    1365         /* Run the constructor. */
    1366         run_dereference(run, *res, NULL, &obj_i);
    1367         assert(obj_i->ic == ic_address);
    1368         assert(obj_i->u.address->ac == ac_var);
    1369         run_object_ctor(run, obj_i->u.address->u.var_a->vref, &arg_vals);
    13701200}
    13711201
     
    14261256                run_access_object(run, access, arg, res);
    14271257                break;
    1428         case vc_symbol:
    1429                 run_access_symbol(run, access, arg, res);
    1430                 break;
    1431 
    1432         case vc_bool:
    1433         case vc_char:
    1434         case vc_enum:
    1435         case vc_int:
    1436         case vc_string:
    1437         case vc_array:
    1438         case vc_resource:
     1258        default:
    14391259                printf("Unimplemented: Using access operator ('.') "
    14401260                    "with unsupported data type (value/%d).\n", vc);
     
    14561276
    14571277        /* Implicitly dereference. */
    1458         run_dereference(run, arg, access->arg->cspan, &darg);
     1278        run_dereference(run, arg, &darg);
    14591279
    14601280        if (run->thread_ar->bo_mode != bm_none) {
     
    15761396                printf("Error: Accessing object member which is a delegate.\n");
    15771397                exit(1);
    1578         case sc_enum:
    1579                 printf("Error: Accessing object member which is an enum.\n");
    1580                 exit(1);
    1581         case sc_ctor:
    1582                 /* It is not possible to reference a constructor explicitly. */
    1583                 assert(b_false);
    15841398        case sc_fun:
    15851399                /* Construct anonymous delegate. */
     
    16281442}
    16291443
    1630 /** Evaluate symbol member acccess.
    1631  *
    1632  * @param run           Runner object
    1633  * @param access        Access operation
    1634  * @param arg           Evaluated base expression
    1635  * @param res           Place to store result
    1636  */
    1637 static void run_access_symbol(run_t *run, stree_access_t *access,
    1638     rdata_item_t *arg, rdata_item_t **res)
    1639 {
    1640         rdata_item_t *arg_vi;
    1641         rdata_value_t *arg_val;
    1642         rdata_symbol_t *symbol_v;
    1643         stree_embr_t *embr;
    1644 
    1645         rdata_item_t *ritem;
    1646         rdata_value_t *rvalue;
    1647         rdata_var_t *rvar;
    1648         rdata_enum_t *enum_v;
    1649 
    1650 #ifdef DEBUG_RUN_TRACE
    1651         printf("Run symbol access operation.\n");
    1652 #endif
    1653         run_cvt_value_item(run, arg, &arg_vi);
    1654         arg_val = arg_vi->u.value;
    1655         assert(arg_val->var->vc == vc_symbol);
    1656 
    1657         symbol_v = arg_val->var->u.symbol_v;
    1658 
    1659         /* XXX Port CSI symbol reference to using vc_symbol */
    1660         assert(symbol_v->sym->sc == sc_enum);
    1661 
    1662         embr = stree_enum_find_mbr(symbol_v->sym->u.enum_d,
    1663             access->member_name);
    1664 
    1665         /* Member existence should be ensured by static type checking. */
    1666         assert(embr != NULL);
    1667 
    1668 #ifdef DEBUG_RUN_TRACE
    1669         printf("Found enum member '%s'.\n",
    1670             strtab_get_str(access->member_name->sid));
    1671 #endif
    1672         ritem = rdata_item_new(ic_value);
    1673         rvalue = rdata_value_new();
    1674         rvar = rdata_var_new(vc_enum);
    1675         enum_v = rdata_enum_new();
    1676 
    1677         ritem->u.value = rvalue;
    1678         rvalue->var = rvar;
    1679         rvar->u.enum_v = enum_v;
    1680         enum_v->value = embr;
    1681 
    1682         *res = ritem;
    1683 }
    1684 
    16851444/** Call a function.
    16861445 *
     
    16961455        rdata_deleg_t *deleg_v;
    16971456        list_t arg_vals;
     1457        list_node_t *node;
     1458        stree_expr_t *arg;
     1459        rdata_item_t *rarg_i, *rarg_vi;
    16981460
    16991461        stree_fun_t *fun;
     
    17371499#endif
    17381500        /* Evaluate function arguments. */
    1739         run_call_args(run, &call->args, &arg_vals);
    1740         if (run_is_bo(run)) {
    1741                 *res = NULL;
    1742                 return;
     1501        list_init(&arg_vals);
     1502        node = list_first(&call->args);
     1503
     1504        while (node != NULL) {
     1505                arg = list_node_data(node, stree_expr_t *);
     1506                run_expr(run, arg, &rarg_i);
     1507                if (run_is_bo(run)) {
     1508                        *res = NULL;
     1509                        return;
     1510                }
     1511
     1512                run_cvt_value_item(run, rarg_i, &rarg_vi);
     1513
     1514                list_append(&arg_vals, rarg_vi);
     1515                node = list_next(&call->args, node);
    17431516        }
    17441517
     
    17551528        run_proc(run, proc_ar, res);
    17561529
    1757         if (!run_is_bo(run) && fun->sig->rtype != NULL && *res == NULL) {
    1758                 printf("Error: Function '");
    1759                 symbol_print_fqn(deleg_v->sym);
    1760                 printf("' did not return a value.\n");
    1761                 exit(1);
    1762         }
    1763 
    17641530#ifdef DEBUG_RUN_TRACE
    17651531        printf("Returned from function call.\n");
    17661532#endif
    1767 }
    1768 
    1769 /** Evaluate call arguments.
    1770  *
    1771  * Evaluate arguments to function or constructor.
    1772  *
    1773  * @param run           Runner object
    1774  * @param args          Real arguments (list of stree_expr_t)
    1775  * @param arg_vals      Address of uninitialized list to store argument values
    1776  *                      (list of rdata_item_t).
    1777  */
    1778 static void run_call_args(run_t *run, list_t *args, list_t *arg_vals)
    1779 {
    1780         list_node_t *arg_n;
    1781         stree_expr_t *arg;
    1782         rdata_item_t *rarg_i, *rarg_vi;
    1783 
    1784         /* Evaluate function arguments. */
    1785         list_init(arg_vals);
    1786         arg_n = list_first(args);
    1787 
    1788         while (arg_n != NULL) {
    1789                 arg = list_node_data(arg_n, stree_expr_t *);
    1790                 run_expr(run, arg, &rarg_i);
    1791                 if (run_is_bo(run))
    1792                         return;
    1793 
    1794                 run_cvt_value_item(run, rarg_i, &rarg_vi);
    1795 
    1796                 list_append(arg_vals, rarg_vi);
    1797                 arg_n = list_next(args, arg_n);
    1798         }
    17991533}
    18001534
     
    18301564        /* Implicitly dereference. */
    18311565        if (vc == vc_ref) {
    1832                 run_dereference(run, rbase, index->base->cspan, &base_i);
    1833                 if (run_is_bo(run)) {
    1834                         *res = NULL;
    1835                         return;
    1836                 }
     1566                run_dereference(run, rbase, &base_i);
    18371567        } else {
    18381568                base_i = rbase;
     
    19041634#endif
    19051635        (void) run;
     1636        (void) index;
    19061637
    19071638        assert(base->ic == ic_address);
     
    19451676                        /* Raise Error.OutOfBounds */
    19461677                        run_raise_exc(run,
    1947                             run->program->builtin->error_outofbounds,
    1948                             index->expr->cspan);
    1949                         /* XXX It should be cspan of the argument. */
     1678                            run->program->builtin->error_outofbounds);
    19501679                        *res = run_recovery_item(run);
    19511680                        return;
     
    20851814#endif
    20861815        (void) run;
     1816        (void) index;
    20871817
    20881818        run_cvt_value_item(run, base, &base_vi);
     
    21361866#endif
    21371867                /* Raise Error.OutOfBounds */
    2138                 run_raise_exc(run, run->program->builtin->error_outofbounds,
    2139                     index->expr->cspan);
     1868                run_raise_exc(run, run->program->builtin->error_outofbounds);
    21401869                *res = run_recovery_item(run);
    21411870                return;
     
    22411970        }
    22421971
    2243         run_dereference(run, rarg_vi, NULL, &rarg_di);
     1972        run_dereference(run, rarg_vi, &rarg_di);
    22441973
    22451974        /* Now we should have a variable address. */
     
    23192048        case vc_ref:
    23202049        case vc_deleg:
    2321         case vc_enum:
    23222050        case vc_array:
    23232051        case vc_object:
    23242052        case vc_resource:
    2325         case vc_symbol:
    23262053                assert(b_false);
    23272054        }
     
    24202147}
    24212148
    2422 /** Run constructor on an object.
    2423  *
    2424  * @param run           Runner object
    2425  * @param obj           Object to run constructor on
    2426  * @param arg_vals      Argument values (list of rdata_item_t)
    2427  */
    2428 static void run_object_ctor(run_t *run, rdata_var_t *obj, list_t *arg_vals)
    2429 {
    2430         stree_ident_t *ctor_ident;
    2431         stree_symbol_t *csi_sym;
    2432         stree_csi_t *csi;
    2433         stree_symbol_t *ctor_sym;
    2434         stree_ctor_t *ctor;
    2435         run_proc_ar_t *proc_ar;
    2436         rdata_item_t *res;
    2437 
    2438         csi_sym = obj->u.object_v->class_sym;
    2439         csi = symbol_to_csi(csi_sym);
    2440         assert(csi != NULL);
    2441 
    2442 #ifdef DEBUG_RUN_TRACE
    2443         printf("Run object constructor from CSI '");
    2444         symbol_print_fqn(csi_sym);
    2445         printf("'.\n");
    2446 #endif
    2447         ctor_ident = stree_ident_new();
    2448         ctor_ident->sid = strtab_get_sid(CTOR_IDENT);
    2449 
    2450         /* Find constructor. */
    2451         ctor_sym = symbol_search_csi_no_base(run->program, csi, ctor_ident);
    2452         if (ctor_sym == NULL) {
    2453 #ifdef DEBUG_RUN_TRACE
    2454                 printf("No constructor found.\n");
    2455 #endif
    2456                 return;
    2457         }
    2458 
    2459         ctor = symbol_to_ctor(ctor_sym);
    2460         assert(ctor != NULL);
    2461 
    2462         /* Create procedure activation record. */
    2463         run_proc_ar_create(run, obj, ctor->proc, &proc_ar);
    2464 
    2465         /* Fill in argument values. */
    2466         run_proc_ar_set_args(run, proc_ar, arg_vals);
    2467 
    2468         /* Run the procedure. */
    2469         run_proc(run, proc_ar, &res);
    2470 
    2471         /* Constructor does not return a value. */
    2472         assert(res == NULL);
    2473 
    2474 #ifdef DEBUG_RUN_TRACE
    2475         printf("Returned from constructor..\n");
    2476 #endif
    2477 }
    2478 
    24792149/** Return boolean value of an item.
    24802150 *
Note: See TracChangeset for help on using the changeset viewer.