Changeset 883fedc in mainline for uspace/app/sbi/src/stype.c


Ignore:
Timestamp:
2010-04-23T23:09:56Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
37c9fc8
Parents:
80badbe (diff), 6c39a907 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jsvoboda/helenos/sysel. New: generic classes, autoboxing, delegates.

File:
1 edited

Legend:

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

    r80badbe r883fedc  
    3030 * @file Implements a walk on the program that computes and checks static
    3131 * types. 'Types' the program.
     32 *
     33 * If a type error is encountered, stype_note_error() is called to set
     34 * the typing error flag.
    3235 */
    3336
     
    5356static void stype_prop(stype_t *stype, stree_prop_t *prop);
    5457
     58static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,
     59    stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig);
     60static void stype_fun_body(stype_t *stype, stree_fun_t *fun);
    5561static void stype_block(stype_t *stype, stree_block_t *block);
    5662
     
    6470static void stype_wef(stype_t *stype, stree_wef_t *wef_s);
    6571
    66 /** Type module */
     72static stree_expr_t *stype_convert_tprimitive(stype_t *stype,
     73    stree_expr_t *expr, tdata_item_t *dest);
     74static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype,
     75    stree_expr_t *expr, tdata_item_t *dest);
     76static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr,
     77    tdata_item_t *dest);
     78static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr,
     79    tdata_item_t *dest);
     80static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
     81    tdata_item_t *dest);
     82static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
     83    stree_expr_t *expr, tdata_item_t *dest);
     84static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
     85    tdata_item_t *dest);
     86static void stype_convert_failure(stype_t *stype, tdata_item_t *src,
     87    tdata_item_t *dest);
     88
     89static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
     90    tdata_fun_sig_t *sdig);
     91
     92/** Type module.
     93 *
     94 * If the module contains a type error, @a stype->error will be set
     95 * when this function returns.
     96 *
     97 * @param stype         Static typing object
     98 * @param module        Module to type
     99 */
    67100void stype_module(stype_t *stype, stree_module_t *module)
    68101{
     
    87120}
    88121
    89 /** Type CSI */
     122/** Type CSI.
     123 *
     124 * @param stype         Static typing object
     125 * @param csi           CSI to type
     126 */
    90127static void stype_csi(stype_t *stype, stree_csi_t *csi)
    91128{
     
    108145                switch (csimbr->cc) {
    109146                case csimbr_csi: stype_csi(stype, csimbr->u.csi); break;
     147                case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break;
    110148                case csimbr_fun: stype_fun(stype, csimbr->u.fun); break;
    111149                case csimbr_var: stype_var(stype, csimbr->u.var); break;
     
    119157}
    120158
    121 /** Type function */
     159/** Type delegate.
     160 *
     161 * @param stype         Static typing object.
     162 * @param deleg         Delegate to type.
     163 */
     164void stype_deleg(stype_t *stype, stree_deleg_t *deleg)
     165{
     166        stree_symbol_t *deleg_sym;
     167        tdata_item_t *deleg_ti;
     168        tdata_deleg_t *tdeleg;
     169        tdata_fun_sig_t *tsig;
     170
     171#ifdef DEBUG_TYPE_TRACE
     172        printf("Type delegate '");
     173        symbol_print_fqn(deleg_to_symbol(deleg));
     174        printf("'.\n");
     175#endif
     176        if (deleg->titem == NULL) {
     177                deleg_ti = tdata_item_new(tic_tdeleg);
     178                deleg->titem = deleg_ti;
     179                tdeleg = tdata_deleg_new();
     180                deleg_ti->u.tdeleg = tdeleg;
     181        } else {
     182                deleg_ti = deleg->titem;
     183                assert(deleg_ti->u.tdeleg != NULL);
     184                tdeleg = deleg_ti->u.tdeleg;
     185        }
     186
     187        if (tdeleg->tsig != NULL)
     188                return; /* Delegate has already been typed. */
     189
     190        deleg_sym = deleg_to_symbol(deleg);
     191
     192        /* Type function signature. Store result in deleg->titem. */
     193        stype_fun_sig(stype, deleg_sym->outer_csi, deleg->sig, &tsig);
     194
     195        tdeleg->deleg = deleg;
     196        tdeleg->tsig = tsig;
     197}
     198
     199/** Type function.
     200 *
     201 * We split typing of function header and body because at the point we
     202 * are typing the body of some function we may encounter function calls.
     203 * To type a function call we first need to type the header of the function
     204 * being called.
     205 *
     206 * @param stype         Static typing object.
     207 * @param fun           Function to type.
     208 */
    122209static void stype_fun(stype_t *stype, stree_fun_t *fun)
    123210{
    124         list_node_t *arg_n;
    125         stree_proc_arg_t *arg;
    126         stree_symbol_t *fun_sym;
    127         tdata_item_t *titem;
    128 
    129211#ifdef DEBUG_TYPE_TRACE
    130212        printf("Type function '");
     
    132214        printf("'.\n");
    133215#endif
     216        if (fun->titem == NULL)
     217                stype_fun_header(stype, fun);
     218
     219        stype_fun_body(stype, fun);
     220}
     221
     222/** Type function header.
     223 *
     224 * Types the header of @a fun (but not its body).
     225 *
     226 * @param stype         Static typing object
     227 * @param fun           Funtction
     228 */
     229void stype_fun_header(stype_t *stype, stree_fun_t *fun)
     230{
     231        stree_symbol_t *fun_sym;
     232        tdata_item_t *fun_ti;
     233        tdata_fun_t *tfun;
     234        tdata_fun_sig_t *tsig;
     235
     236#ifdef DEBUG_TYPE_TRACE
     237        printf("Type function '");
     238        symbol_print_fqn(fun_to_symbol(fun));
     239        printf("' header.\n");
     240#endif
     241        if (fun->titem != NULL)
     242                return; /* Function header has already been typed. */
     243
    134244        fun_sym = fun_to_symbol(fun);
     245
     246        /* Type function signature. */
     247        stype_fun_sig(stype, fun_sym->outer_csi, fun->sig, &tsig);
     248
     249        fun_ti = tdata_item_new(tic_tfun);
     250        tfun = tdata_fun_new();
     251        fun_ti->u.tfun = tfun;
     252        tfun->tsig = tsig;
     253
     254        fun->titem = fun_ti;
     255}
     256
     257/** Type function signature.
     258 *
     259 * Types the function signature @a sig.
     260 *
     261 * @param stype         Static typing object
     262 * @param outer_csi     CSI within which the signature is defined.
     263 * @param sig           Function signature
     264 */
     265static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,
     266    stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig)
     267{
     268        list_node_t *arg_n;
     269        stree_proc_arg_t *arg;
     270        tdata_item_t *titem;
     271        tdata_fun_sig_t *tsig;
     272
     273#ifdef DEBUG_TYPE_TRACE
     274        printf("Type function signature.\n");
     275#endif
     276        tsig = tdata_fun_sig_new();
     277
     278        list_init(&tsig->arg_ti);
    135279
    136280        /*
    137281         * Type formal arguments.
    138          * XXX Save the results.
    139282         */
    140         arg_n = list_first(&fun->args);
     283        arg_n = list_first(&sig->args);
    141284        while (arg_n != NULL) {
    142285                arg = list_node_data(arg_n, stree_proc_arg_t *);
     
    144287                /* XXX Because of overloaded builtin WriteLine. */
    145288                if (arg->type == NULL) {
    146                         arg_n = list_next(&fun->args, arg_n);
     289                        list_append(&tsig->arg_ti, NULL);
     290                        arg_n = list_next(&sig->args, arg_n);
    147291                        continue;
    148292                }
    149293
    150                 run_texpr(stype->program, fun_sym->outer_csi, arg->type,
    151                     &titem);
    152 
    153                 arg_n = list_next(&fun->args, arg_n);
     294                run_texpr(stype->program, outer_csi, arg->type, &titem);
     295                list_append(&tsig->arg_ti, titem);
     296
     297                arg_n = list_next(&sig->args, arg_n);
    154298        }
    155299
    156300        /* Variadic argument */
    157         if (fun->varg != NULL) {
     301        if (sig->varg != NULL) {
    158302                /* Check type and verify it is an array. */
    159                 run_texpr(stype->program, fun_sym->outer_csi, fun->varg->type,
    160                     &titem);
     303                run_texpr(stype->program, outer_csi, sig->varg->type, &titem);
     304                tsig->varg_ti = titem;
    161305
    162306                if (titem->tic != tic_tarray && titem->tic != tic_ignore) {
     
    166310        }
    167311
    168         /*
    169          * Type function body.
    170          */
     312        /* Return type */
     313        if (sig->rtype != NULL) {
     314                run_texpr(stype->program, outer_csi, sig->rtype, &titem);
     315                tsig->rtype = titem;
     316        }
     317
     318        *rtsig = tsig;
     319}
     320
     321/** Type function body.
     322 *
     323 * Types the body of function @a fun (if it has one).
     324 *
     325 * @param stype         Static typing object
     326 * @param fun           Funtction
     327 */
     328static void stype_fun_body(stype_t *stype, stree_fun_t *fun)
     329{
     330#ifdef DEBUG_TYPE_TRACE
     331        printf("Type function '");
     332        symbol_print_fqn(fun_to_symbol(fun));
     333        printf("' body.\n");
     334#endif
     335        assert(stype->proc_vr == NULL);
    171336
    172337        /* Builtin functions do not have a body. */
     
    184349}
    185350
    186 /** Type member variable */
     351/** Type member variable.
     352 *
     353 * @param stype         Static typing object
     354 * @param var           Member variable
     355 */
    187356static void stype_var(stype_t *stype, stree_var_t *var)
    188357{
     
    201370}
    202371
    203 /** Type property */
     372/** Type property.
     373 *
     374 * @param stype         Static typing object
     375 * @param prop          Property
     376 */
    204377static void stype_prop(stype_t *stype, stree_prop_t *prop)
    205378{
     
    226399}
    227400
    228 /** Type statement block */
     401/** Type statement block.
     402 *
     403 * @param stype         Static typing object
     404 * @param block         Statement block
     405 */
    229406static void stype_block(stype_t *stype, stree_block_t *block)
    230407{
     
    265442 * for nested statemens). This is used in interactive mode.
    266443 *
    267  * @param stype         Static typer object.
    268  * @param stat          Statement to type.
    269  * @param want_value    @c b_true to allow ignoring expression value.
     444 * @param stype         Static typing object
     445 * @param stat          Statement to type
     446 * @param want_value    @c b_true to allow ignoring expression value
    270447 */
    271448void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value)
     
    286463}
    287464
    288 /** Type local variable declaration */
     465/** Type local variable declaration statement.
     466 *
     467 * @param stype         Static typing object
     468 * @param vdecl_s       Variable delcaration statement
     469 */
    289470static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s)
    290471{
     
    317498}
    318499
    319 /** Type @c if statement */
     500/** Type @c if statement.
     501 *
     502 * @param stype         Static typing object
     503 * @param if_s          @c if statement
     504 */
    320505static void stype_if(stype_t *stype, stree_if_t *if_s)
    321506{
     
    340525}
    341526
    342 /** Type @c while statement */
     527/** Type @c while statement
     528 *
     529 * @param stype         Static typing object
     530 * @param while_s       @c while statement
     531 */
    343532static void stype_while(stype_t *stype, stree_while_t *while_s)
    344533{
     
    360549}
    361550
    362 /** Type @c for statement */
     551/** Type @c for statement.
     552 *
     553 * @param stype         Static typing object
     554 * @param for_s         @c for statement
     555 */
    363556static void stype_for(stype_t *stype, stree_for_t *for_s)
    364557{
     
    369562}
    370563
    371 /** Type @c raise statement */
     564/** Type @c raise statement.
     565 *
     566 * @param stype         Static typing object
     567 * @param raise_s       @c raise statement
     568 */
    372569static void stype_raise(stype_t *stype, stree_raise_t *raise_s)
    373570{
     
    402599
    403600                /* XXX Memoize to avoid recomputing. */
    404                 run_texpr(stype->program, outer_sym->outer_csi, fun->rtype,
    405                     &dtype);
     601                run_texpr(stype->program, outer_sym->outer_csi,
     602                    fun->sig->rtype, &dtype);
    406603                break;
    407604        case sc_prop:
     
    430627}
    431628
    432 /** Type expression statement */
     629/** Type expression statement.
     630 *
     631 * @param stype         Static typing object
     632 * @param exp_s         Expression statement
     633 */
    433634static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value)
    434635{
     
    442643}
    443644
    444 /** Type With-Except-Finally statement */
     645/** Type with-except-finally statement.
     646 *
     647 * @param stype         Static typing object
     648 * @param wef_s         With-except-finally statement
     649 */
    445650static void stype_wef(stype_t *stype, stree_wef_t *wef_s)
    446651{
     
    482687 * Note: No conversion that would require modifying @a expr is implemented
    483688 * yet.
     689 *
     690 * @param stype         Static typing object
     691 * @param expr          Expression
     692 * @param dest          Destination type
    484693 */
    485694stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
     
    488697        tdata_item_t *src;
    489698
    490         (void) stype;
    491699        src = expr->titem;
     700
     701#ifdef DEBUG_TYPE_TRACE
     702        printf("Convert '");
     703        tdata_item_print(src);
     704        printf("' to '");
     705        tdata_item_print(dest);
     706        printf("'.\n");
     707#endif
    492708
    493709        if (dest == NULL) {
     
    514730        }
    515731
    516         if (src->tic != dest->tic)
    517                 goto failure;
     732        if (src->tic == tic_tprimitive && dest->tic == tic_tobject) {
     733                return stype_convert_tprim_tobj(stype, expr, dest);
     734        }
     735
     736        if (src->tic == tic_tfun && dest->tic == tic_tdeleg) {
     737                return stype_convert_tfun_tdeleg(stype, expr, dest);
     738        }
     739
     740        if (src->tic != dest->tic) {
     741                stype_convert_failure(stype, src, dest);
     742                return expr;
     743        }
    518744
    519745        switch (src->tic) {
    520746        case tic_tprimitive:
    521                 /* Check if both have the same tprimitive class. */
    522                 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
    523                         goto failure;
     747                expr = stype_convert_tprimitive(stype, expr, dest);
    524748                break;
    525749        case tic_tobject:
    526                 /* Check if @c src is derived from @c dest. */
    527                 if (stree_is_csi_derived_from_csi(src->u.tobject->csi,
    528                     dest->u.tobject->csi) != b_true) {
    529                         goto failure;
    530                 }
     750                expr = stype_convert_tobject(stype, expr, dest);
    531751                break;
    532752        case tic_tarray:
    533                 /* Compare rank and base type. */
    534                 if (src->u.tarray->rank != dest->u.tarray->rank)
    535                         goto failure;
    536 
    537                 /* XXX Should we convert each element? */
    538                 if (tdata_item_equal(src->u.tarray->base_ti,
    539                     dest->u.tarray->base_ti) != b_true)
    540                         goto failure;
     753                expr = stype_convert_tarray(stype, expr, dest);
     754                break;
     755        case tic_tdeleg:
     756                expr = stype_convert_tdeleg(stype, expr, dest);
    541757                break;
    542758        case tic_tfun:
    543                 printf("Error: Unimplemented: Converting '");
    544                 tdata_item_print(src);
    545                 printf("' to '");
    546                 tdata_item_print(dest);
    547                 printf("'.\n");
    548                 stype_note_error(stype);
     759                assert(b_false);
     760        case tic_tvref:
     761                expr = stype_convert_tvref(stype, expr, dest);
    549762                break;
    550763        case tic_ignore:
     
    553766
    554767        return expr;
    555 
    556 failure:
     768}
     769
     770/** Convert expression of primitive type to primitive type.
     771 *
     772 * @param stype         Static typing object
     773 * @param expr          Expression
     774 * @param dest          Destination type
     775 */
     776static stree_expr_t *stype_convert_tprimitive(stype_t *stype,
     777    stree_expr_t *expr, tdata_item_t *dest)
     778{
     779        tdata_item_t *src;
     780
     781#ifdef DEBUG_TYPE_TRACE
     782        printf("Convert primitive type.\n");
     783#endif
     784        src = expr->titem;
     785        assert(src->tic == tic_tprimitive);
     786        assert(dest->tic == tic_tprimitive);
     787
     788        /* Check if both have the same tprimitive class. */
     789        if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
     790                stype_convert_failure(stype, src, dest);
     791
     792        return expr;
     793}
     794
     795/** Convert expression of primitive type to object type.
     796 *
     797 * This function implements autoboxing. It modified the code.
     798 *
     799 * @param stype         Static typing object
     800 * @param expr          Expression
     801 * @param dest          Destination type
     802 */
     803static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype,
     804    stree_expr_t *expr, tdata_item_t *dest)
     805{
     806        tdata_item_t *src;
     807        builtin_t *bi;
     808        stree_symbol_t *csi_sym;
     809        stree_symbol_t *bp_sym;
     810        stree_box_t *box;
     811        stree_expr_t *bexpr;
     812
     813#ifdef DEBUG_TYPE_TRACE
     814        printf("Convert primitive type to object.\n");
     815#endif
     816        src = expr->titem;
     817        assert(src->tic == tic_tprimitive);
     818        assert(dest->tic == tic_tobject);
     819
     820        bi = stype->program->builtin;
     821        csi_sym = csi_to_symbol(dest->u.tobject->csi);
     822
     823        switch (src->u.tprimitive->tpc) {
     824        case tpc_bool: bp_sym = bi->boxed_bool; break;
     825        case tpc_char: bp_sym = bi->boxed_char; break;
     826        case tpc_int: bp_sym = bi->boxed_int; break;
     827        case tpc_nil: assert(b_false);
     828        case tpc_string: bp_sym = bi->boxed_string; break;
     829        case tpc_resource:
     830                stype_convert_failure(stype, src, dest);
     831                return expr;
     832        }
     833
     834        /* Target type must be boxed @a src or Object */
     835        if (csi_sym != bp_sym && csi_sym != bi->gf_class)
     836                stype_convert_failure(stype, src, dest);
     837
     838        /* Patch the code to box the primitive value */
     839        box = stree_box_new();
     840        box->arg = expr;
     841        bexpr = stree_expr_new(ec_box);
     842        bexpr->u.box = box;
     843
     844        /* No action needed to optionally convert boxed type to Object */
     845
     846        return bexpr;
     847}
     848
     849/** Convert expression of object type to object type.
     850 *
     851 * @param stype         Static typing object
     852 * @param expr          Expression
     853 * @param dest          Destination type
     854 */
     855static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr,
     856    tdata_item_t *dest)
     857{
     858        tdata_item_t *src;
     859        tdata_item_t *cur;
     860        stree_csi_t *cur_csi;
     861        tdata_tvv_t *tvv;
     862        tdata_item_t *b_ti, *bs_ti;
     863
     864#ifdef DEBUG_TYPE_TRACE
     865        printf("Convert object type.\n");
     866#endif
     867        list_node_t *ca_n, *da_n;
     868        tdata_item_t *carg, *darg;
     869
     870        src = expr->titem;
     871        assert(src->tic == tic_tobject);
     872        assert(dest->tic == tic_tobject);
     873
     874        cur = src;
     875
     876        while (cur->u.tobject->csi != dest->u.tobject->csi) {
     877
     878                cur_csi = cur->u.tobject->csi;
     879                stype_titem_to_tvv(stype, cur, &tvv);
     880
     881                if (cur_csi->base_csi_ref != NULL) {
     882                        run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti);
     883                        if (b_ti->tic == tic_ignore) {
     884                                /* An error occured. */
     885                                stype_note_error(stype);
     886                                return expr;
     887                        }
     888
     889                        tdata_item_subst(b_ti, tvv, &bs_ti);
     890                        cur = bs_ti;
     891                        assert(cur->tic == tic_tobject);
     892
     893                } else if (cur_csi->base_csi != NULL) {
     894                        /* No explicit reference. Use grandfather class. */
     895                        cur = tdata_item_new(tic_tobject);
     896                        cur->u.tobject = tdata_object_new();
     897                        cur->u.tobject->csi = cur_csi->base_csi;
     898                        cur->u.tobject->static_ref = b_false;
     899
     900                        list_init(&cur->u.tobject->targs);
     901                } else {
     902                        /* No match */
     903                        stype_convert_failure(stype, src, dest);
     904                        return expr;
     905                }
     906        }
     907
     908        /* Verify that type arguments match */
     909        ca_n = list_first(&cur->u.tobject->targs);
     910        da_n = list_first(&dest->u.tobject->targs);
     911
     912        while (ca_n != NULL && da_n != NULL) {
     913                carg = list_node_data(ca_n, tdata_item_t *);
     914                darg = list_node_data(da_n, tdata_item_t *);
     915
     916                if (tdata_item_equal(carg, darg) != b_true) {
     917                        /* Diferent argument type */
     918                        stype_convert_failure(stype, src, dest);
     919                        printf("Different argument type '");
     920                        tdata_item_print(carg);
     921                        printf("' vs. '");
     922                        tdata_item_print(darg);
     923                        printf("'.\n");
     924                        return expr;
     925                }
     926
     927                ca_n = list_next(&cur->u.tobject->targs, ca_n);
     928                da_n = list_next(&dest->u.tobject->targs, da_n);
     929        }
     930
     931        if (ca_n != NULL || da_n != NULL) {
     932                /* Diferent number of arguments */
     933                stype_convert_failure(stype, src, dest);
     934                printf("Different number of arguments.\n");
     935                return expr;
     936        }
     937
     938        return expr;
     939}
     940
     941/** Convert expression of array type to array type.
     942 *
     943 * @param stype         Static typing object
     944 * @param expr          Expression
     945 * @param dest          Destination type
     946 */
     947static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr,
     948    tdata_item_t *dest)
     949{
     950        tdata_item_t *src;
     951
     952#ifdef DEBUG_TYPE_TRACE
     953        printf("Convert array type.\n");
     954#endif
     955        src = expr->titem;
     956        assert(src->tic == tic_tarray);
     957        assert(dest->tic == tic_tarray);
     958
     959        /* Compare rank and base type. */
     960        if (src->u.tarray->rank != dest->u.tarray->rank) {
     961                stype_convert_failure(stype, src, dest);
     962                return expr;
     963        }
     964
     965        /* XXX Should we convert each element? */
     966        if (tdata_item_equal(src->u.tarray->base_ti,
     967            dest->u.tarray->base_ti) != b_true) {
     968                stype_convert_failure(stype, src, dest);
     969        }
     970
     971        return expr;
     972}
     973
     974/** Convert expression of delegate type to delegate type.
     975 *
     976 * @param stype         Static typing object
     977 * @param expr          Expression
     978 * @param dest          Destination type
     979 */
     980static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
     981    tdata_item_t *dest)
     982{
     983        tdata_item_t *src;
     984        tdata_deleg_t *sdeleg, *ddeleg;
     985
     986#ifdef DEBUG_TYPE_TRACE
     987        printf("Convert delegate type.\n");
     988#endif
     989        src = expr->titem;
     990        assert(src->tic == tic_tdeleg);
     991        assert(dest->tic == tic_tdeleg);
     992
     993        sdeleg = src->u.tdeleg;
     994        ddeleg = dest->u.tdeleg;
     995
     996        /*
     997         * XXX We need to redesign handling of generic types to handle
     998         * delegates in generic CSIs properly.
     999         */
     1000
     1001        /* Destination should never be anonymous delegate. */
     1002        assert(ddeleg->deleg != NULL);
     1003
     1004        /* Both must be the same delegate. */
     1005        if (sdeleg->deleg != ddeleg->deleg) {
     1006                stype_convert_failure(stype, src, dest);
     1007                return expr;
     1008        }
     1009
     1010        return expr;
     1011}
     1012
     1013/** Convert expression of function type to delegate type.
     1014 *
     1015 * @param stype         Static typing object
     1016 * @param expr          Expression
     1017 * @param dest          Destination type
     1018 */
     1019static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
     1020    stree_expr_t *expr, tdata_item_t *dest)
     1021{
     1022        tdata_item_t *src;
     1023        tdata_fun_t *sfun;
     1024        tdata_deleg_t *ddeleg;
     1025        tdata_fun_sig_t *ssig, *dsig;
     1026
     1027#ifdef DEBUG_TYPE_TRACE
     1028        printf("Convert delegate type.\n");
     1029#endif
     1030        src = expr->titem;
     1031        assert(src->tic == tic_tfun);
     1032        assert(dest->tic == tic_tdeleg);
     1033
     1034        sfun = src->u.tfun;
     1035        ddeleg = dest->u.tdeleg;
     1036
     1037        ssig = sfun->tsig;
     1038        assert(ssig != NULL);
     1039        dsig = stype_deleg_get_sig(stype, ddeleg);
     1040        assert(dsig != NULL);
     1041
     1042        /* Signature type must match. */
     1043
     1044        if (!stype_fun_sig_equal(stype, ssig, dsig)) {
     1045                stype_convert_failure(stype, src, dest);
     1046                return expr;
     1047        }
     1048
     1049        /*
     1050         * XXX We should also compare attributes. Either the
     1051         * tdeleg should be extended or we should get them
     1052         * from stree_deleg.
     1053         */
     1054
     1055        return expr;
     1056}
     1057
     1058
     1059/** Convert expression of variable type to variable type.
     1060 *
     1061 * @param stype         Static typing object
     1062 * @param expr          Expression
     1063 * @param dest          Destination type
     1064 */
     1065static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
     1066    tdata_item_t *dest)
     1067{
     1068        tdata_item_t *src;
     1069
     1070#ifdef DEBUG_TYPE_TRACE
     1071        printf("Convert variable type.\n");
     1072#endif
     1073        src = expr->titem;
     1074
     1075        /* Currently only allow if both types are the same. */
     1076        if (src->u.tvref->targ != dest->u.tvref->targ) {
     1077                stype_convert_failure(stype, src, dest);
     1078                return expr;
     1079        }
     1080
     1081        return expr;
     1082}
     1083
     1084/** Display conversion error message and note error.
     1085 *
     1086 * @param stype         Static typing object
     1087 * @param src           Original type
     1088 * @param dest          Destination type
     1089 */
     1090static void stype_convert_failure(stype_t *stype, tdata_item_t *src,
     1091    tdata_item_t *dest)
     1092{
    5571093        printf("Error: Cannot convert ");
    5581094        tdata_item_print(src);
     
    5621098
    5631099        stype_note_error(stype);
    564         return expr;
    565 }
    566 
    567 /** Return a boolean type item */
     1100}
     1101
     1102/** Determine if two type signatures are equal.
     1103 *
     1104 * XXX This does not compare the attributes, which are missing from
     1105 * @c tdata_fun_sig_t.
     1106 *
     1107 * @param stype         Static typing object
     1108 * @param asig          First function signature type
     1109 * @param bsig          Second function signature type
     1110 */
     1111static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
     1112    tdata_fun_sig_t *bsig)
     1113{
     1114        list_node_t *aarg_n, *barg_n;
     1115        tdata_item_t *aarg_ti, *barg_ti;
     1116
     1117        (void) stype;
     1118
     1119        /* Compare types of arguments */
     1120        aarg_n = list_first(&asig->arg_ti);
     1121        barg_n = list_first(&bsig->arg_ti);
     1122
     1123        while (aarg_n != NULL && barg_n != NULL) {
     1124                aarg_ti = list_node_data(aarg_n, tdata_item_t *);
     1125                barg_ti = list_node_data(barg_n, tdata_item_t *);
     1126
     1127                if (!tdata_item_equal(aarg_ti, barg_ti))
     1128                        return b_false;
     1129
     1130                aarg_n = list_next(&asig->arg_ti, aarg_n);
     1131                barg_n = list_next(&bsig->arg_ti, barg_n);
     1132        }
     1133
     1134        if (aarg_n != NULL || barg_n != NULL)
     1135                return b_false;
     1136
     1137        /* Compare variadic argument */
     1138
     1139        if (asig->varg_ti != NULL || bsig->varg_ti != NULL) {
     1140                if (asig->varg_ti == NULL ||
     1141                    bsig->varg_ti == NULL) {
     1142                        return b_false;
     1143                }
     1144
     1145                if (!tdata_item_equal(asig->varg_ti, bsig->varg_ti)) {
     1146                        return b_false;
     1147                }
     1148        }
     1149
     1150        /* Compare return type */
     1151        if (!tdata_item_equal(asig->rtype, bsig->rtype))
     1152                return b_false;
     1153
     1154        return b_true;
     1155}
     1156
     1157/** Get function signature from delegate.
     1158 *
     1159 * Function signature can be missing if the delegate type is incomplete.
     1160 * This is used to break circular dependency when typing delegates.
     1161 * If this happens, we type the delegate, which gives us the signature.
     1162 */
     1163tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg)
     1164{
     1165        if (tdeleg->tsig == NULL)
     1166                stype_deleg(stype, tdeleg->deleg);
     1167
     1168        /* Now we should have a signature. */
     1169        assert(tdeleg->tsig != NULL);
     1170        return tdeleg->tsig;
     1171}
     1172
     1173/** Convert tic_tobject type item to TVV,
     1174 *
     1175 * We split generic type application into two steps. In the first step
     1176 * we match argument names of @a ti->csi to argument values in @a ti
     1177 * to produce a TVV (name to value map for type arguments). That is the
     1178 * purpose of this function.
     1179 *
     1180 * In the second step we substitute variables in another type item
     1181 * with their values using the TVV. This is performed by tdata_item_subst().
     1182 *
     1183 * @param stype         Static typing object.
     1184 * @param ti            Type item of class tic_tobject.
     1185 * @param rtvv          Place to store pointer to new TVV.
     1186 */
     1187void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv)
     1188{
     1189        tdata_tvv_t *tvv;
     1190        stree_csi_t *csi;
     1191
     1192        list_node_t *formal_n;
     1193        list_node_t *real_n;
     1194
     1195        stree_targ_t *formal_arg;
     1196        tdata_item_t *real_arg;
     1197
     1198        assert(ti->tic == tic_tobject);
     1199
     1200        tvv = tdata_tvv_new();
     1201        intmap_init(&tvv->tvv);
     1202
     1203        csi = ti->u.tobject->csi;
     1204        formal_n = list_first(&csi->targ);
     1205        real_n = list_first(&ti->u.tobject->targs);
     1206
     1207        while (formal_n != NULL && real_n != NULL) {
     1208                formal_arg = list_node_data(formal_n, stree_targ_t *);
     1209                real_arg = list_node_data(real_n, tdata_item_t *);
     1210
     1211                /* Store argument value into valuation. */
     1212                tdata_tvv_set_val(tvv, formal_arg->name->sid, real_arg);
     1213
     1214                formal_n = list_next(&csi->targ, formal_n);
     1215                real_n = list_next(&ti->u.tobject->targs, real_n);
     1216        }
     1217
     1218        if (formal_n != NULL || real_n != NULL) {
     1219                printf("Error: Incorrect number of type arguments.\n");
     1220                stype_note_error(stype);
     1221
     1222                /* Fill missing arguments with recovery type items. */
     1223                while (formal_n != NULL) {
     1224                        formal_arg = list_node_data(formal_n, stree_targ_t *);
     1225                        /* Store recovery value into valuation. */
     1226                        tdata_tvv_set_val(tvv, formal_arg->name->sid,
     1227                            stype_recovery_titem(stype));
     1228
     1229                        formal_n = list_next(&csi->targ, formal_n);
     1230                }
     1231        }
     1232
     1233        *rtvv = tvv;
     1234}
     1235
     1236/** Return a boolean type item.
     1237 *
     1238 * @param stype         Static typing object
     1239 * @return              New boolean type item.
     1240 */
    5681241tdata_item_t *stype_boolean_titem(stype_t *stype)
    5691242{
     
    5801253}
    5811254
    582 /** Find a local variable in the current function. */
     1255/** Find a local variable in the current function.
     1256 *
     1257 * @param stype         Static typing object
     1258 * @param name          Name of variable (SID).
     1259 * @return              Pointer to variable declaration or @c NULL if not
     1260 *                      found.
     1261 */
    5831262stree_vdecl_t *stype_local_vars_lookup(stype_t *stype, sid_t name)
    5841263{
     
    6051284}
    6061285
    607 /** Find argument of the current procedure. */
     1286/** Find argument of the current procedure.
     1287 *
     1288 * @param stype         Static typing object
     1289 * @param name          Name of argument (SID).
     1290 * @return              Pointer to argument declaration or @c NULL if not
     1291 *                      found.
     1292 */
    6081293stree_proc_arg_t *stype_proc_args_lookup(stype_t *stype, sid_t name)
    6091294{
     
    6331318                fun = symbol_to_fun(outer_sym);
    6341319                assert(fun != NULL);
    635                 args = &fun->args;
    636                 varg = fun->varg;
     1320                args = &fun->sig->args;
     1321                varg = fun->sig->varg;
    6371322                break;
    6381323        case sc_prop:
     
    6881373}
    6891374
    690 /** Note a static typing error that has been immediately recovered. */
     1375/** Note a static typing error that has been immediately recovered.
     1376 *
     1377 * @param stype         Static typing object
     1378 */
    6911379void stype_note_error(stype_t *stype)
    6921380{
     
    6941382}
    6951383
    696 /** Construct a special type item for recovery. */
     1384/** Construct a special type item for recovery.
     1385 *
     1386 * The recovery item is propagated towards the expression root and causes
     1387 * any further typing errors in the expression to be supressed.
     1388 *
     1389 * @param stype         Static typing object
     1390 */
    6971391tdata_item_t *stype_recovery_titem(stype_t *stype)
    6981392{
     
    7051399}
    7061400
    707 /** Get current block visit record. */
     1401/** Get current block visit record.
     1402 *
     1403 * @param stype         Static typing object
     1404 */
    7081405stype_block_vr_t *stype_get_current_block_vr(stype_t *stype)
    7091406{
     
    7141411}
    7151412
     1413/** Allocate new procedure visit record.
     1414 *
     1415 * @return      New procedure VR
     1416 */
    7161417stype_proc_vr_t *stype_proc_vr_new(void)
    7171418{
     
    7271428}
    7281429
     1430/** Allocate new block visit record.
     1431 *
     1432 * @return      New block VR
     1433 */
    7291434stype_block_vr_t *stype_block_vr_new(void)
    7301435{
Note: See TracChangeset for help on using the changeset viewer.