Ignore:
File:
1 edited

Legend:

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

    r074444f r38aaacc2  
    3131#include <stdlib.h>
    3232#include <assert.h>
     33#include "intmap.h"
    3334#include "list.h"
    3435#include "mytypes.h"
    3536#include "stree.h"
     37#include "strtab.h"
    3638#include "symbol.h"
    3739
    3840#include "tdata.h"
     41
     42static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,
     43    tdata_tvv_t *tvv, tdata_item_t **res);
     44static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,
     45    tdata_item_t **res);
     46static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,
     47    tdata_item_t **res);
     48static void tdata_item_subst_tdeleg(tdata_deleg_t *torig,
     49    tdata_tvv_t *tvv, tdata_item_t **res);
     50static void tdata_item_subst_tfun(tdata_fun_t *torig,
     51    tdata_tvv_t *tvv, tdata_item_t **res);
     52static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,
     53    tdata_item_t **res);
     54
     55static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,
     56    tdata_fun_sig_t **res);
    3957
    4058static void tdata_tprimitive_print(tdata_primitive_t *tprimitive);
    4159static void tdata_tobject_print(tdata_object_t *tobject);
    4260static void tdata_tarray_print(tdata_array_t *tarray);
     61static void tdata_tdeleg_print(tdata_deleg_t *tdeleg);
    4362static void tdata_tfun_print(tdata_fun_t *tfun);
    44 
    45 /** Determine if CSI @a a is derived from CSI described by type item @a tb. */
     63static void tdata_tvref_print(tdata_vref_t *tvref);
     64
     65/** Determine if CSI @a a is derived from CSI described by type item @a tb.
     66 *
     67 * XXX This won't work with generics.
     68 *
     69 * @param a     Potential derived CSI.
     70 * @param tb    Type of potentail base CSI.
     71 */
    4672bool_t tdata_is_csi_derived_from_ti(stree_csi_t *a, tdata_item_t *tb)
    4773{
     
    6389 * Determine if CSI described by type item @a a is derived from CSI described
    6490 * by type item @a tb.
     91 *
     92 * XXX This is somewhat complementary to stype_convert(). It is used for
     93 * the explicit @c as conversion. It should only work for objects and only
     94 * allow conversion from base to derived types. We might want to scrap this
     95 * for a version specific to @c as. The current code does not work with
     96 * generics.
     97 *
     98 * @param a     Potential derived CSI.
     99 * @param tb    Type of potentail base CSI.
    65100 */
    66101bool_t tdata_is_ti_derived_from_ti(tdata_item_t *ta, tdata_item_t *tb)
     
    80115}
    81116
    82 /** Determine if two type items are equal (i.e. describe the same type). */
     117/** Determine if two type items are equal (i.e. describe the same type).
     118 *
     119 * Needed to check compatibility of type arguments in which a parametrized
     120 * type is not monotonous.
     121 *
     122 * @param a     Type item
     123 * @param b     Type item
     124 * @return      @c b_true if equal, @c b_false if not.
     125 */
    83126bool_t tdata_item_equal(tdata_item_t *a, tdata_item_t *b)
    84127{
     
    114157                return tdata_item_equal(a->u.tarray->base_ti,
    115158                    b->u.tarray->base_ti);
     159        case tic_tvref:
     160                /* Check if both refer to the same type argument. */
     161                return (a->u.tvref->targ == b->u.tvref->targ);
    116162        default:
    117163                printf("Warning: Unimplemented: Compare types '");
     
    124170}
    125171
    126 /** Print type item. */
     172/** Substitute type variables in a type item.
     173 *
     174 * This is the second part of generic type application. In the first part
     175 * obtained a TVV using stype_titem_to_tvv() and in this second part we
     176 * actually substitute type variables in a type item for their values.
     177 * @a tvv must contain all variables referenced in @a ti.
     178 *
     179 * @param ti    Type item to substitute into.
     180 * @param tvv   Type variable valuation (values of type variables).
     181 * @param res   Place to store pointer to new type item.
     182 */
     183void tdata_item_subst(tdata_item_t *ti, tdata_tvv_t *tvv, tdata_item_t **res)
     184{
     185        switch (ti->tic) {
     186        case tic_tprimitive:
     187                tdata_item_subst_tprimitive(ti->u.tprimitive, tvv, res);
     188                break;
     189        case tic_tobject:
     190                tdata_item_subst_tobject(ti->u.tobject, tvv, res);
     191                break;
     192        case tic_tarray:
     193                tdata_item_subst_tarray(ti->u.tarray, tvv, res);
     194                break;
     195        case tic_tdeleg:
     196                tdata_item_subst_tdeleg(ti->u.tdeleg, tvv, res);
     197                break;
     198        case tic_tfun:
     199                tdata_item_subst_tfun(ti->u.tfun, tvv, res);
     200                break;
     201        case tic_tvref:
     202                tdata_item_subst_tvref(ti->u.tvref, tvv, res);
     203                break;
     204        case tic_ignore:
     205                *res = tdata_item_new(tic_ignore);
     206        }
     207}
     208
     209/** Substitute type variables in a primitive type item.
     210 *
     211 * @param torig Type item to substitute into.
     212 * @param tvv   Type variable valuation (values of type variables).
     213 * @param res   Place to store pointer to new type item.
     214 */
     215static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,
     216    tdata_tvv_t *tvv, tdata_item_t **res)
     217{
     218        tdata_primitive_t *tnew;
     219
     220        (void) tvv;
     221
     222        /* Plain copy */
     223        tnew = tdata_primitive_new(torig->tpc);
     224        *res = tdata_item_new(tic_tprimitive);
     225        (*res)->u.tprimitive = tnew;
     226}
     227
     228/** Substitute type variables in an object type item.
     229 *
     230 * @param torig Type item to substitute into.
     231 * @param tvv   Type variable valuation (values of type variables).
     232 * @param res   Place to store pointer to new type item.
     233 */
     234static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,
     235    tdata_item_t **res)
     236{
     237        tdata_object_t *tnew;
     238        list_node_t *targ_n;
     239        tdata_item_t *targ;
     240        tdata_item_t *new_targ;
     241
     242        /* Copy static ref flag and base CSI. */
     243        tnew = tdata_object_new();
     244        tnew->static_ref = torig->static_ref;
     245        tnew->csi = torig->csi;
     246        list_init(&tnew->targs);
     247
     248        /* Substitute arguments */
     249        targ_n = list_first(&torig->targs);
     250        while (targ_n != NULL) {
     251                targ = list_node_data(targ_n, tdata_item_t *);
     252                tdata_item_subst(targ, tvv, &new_targ);
     253                list_append(&tnew->targs, new_targ);
     254
     255                targ_n = list_next(&torig->targs, targ_n);
     256        }
     257
     258        *res = tdata_item_new(tic_tobject);
     259        (*res)->u.tobject = tnew;
     260}
     261
     262/** Substitute type variables in an array type item.
     263 *
     264 * @param torig Type item to substitute into.
     265 * @param tvv   Type variable valuation (values of type variables).
     266 * @param res   Place to store pointer to new type item.
     267 */
     268static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,
     269    tdata_item_t **res)
     270{
     271        tdata_array_t *tnew;
     272        list_node_t *ext_n;
     273        stree_expr_t *extent;
     274
     275        tnew = tdata_array_new();
     276
     277        /* Substitute base type */
     278        tdata_item_subst(torig->base_ti, tvv, &tnew->base_ti);
     279
     280        /* Copy rank and extents */
     281        tnew->rank = torig->rank;
     282        list_init(&tnew->extents);
     283
     284        ext_n = list_first(&torig->extents);
     285        while (ext_n != NULL) {
     286                extent = list_node_data(ext_n, stree_expr_t *);
     287                list_append(&tnew->extents, extent);
     288
     289                ext_n = list_next(&tnew->extents, ext_n);
     290        }
     291
     292        *res = tdata_item_new(tic_tarray);
     293        (*res)->u.tarray = tnew;
     294}
     295
     296/** Substitute type variables in a delegate type item.
     297 *
     298 * @param torig Type item to substitute into.
     299 * @param tvv   Type variable valuation (values of type variables).
     300 * @param res   Place to store pointer to new type item.
     301 */
     302static void tdata_item_subst_tdeleg(tdata_deleg_t *torig, tdata_tvv_t *tvv,
     303    tdata_item_t **res)
     304{
     305        tdata_deleg_t *tnew;
     306
     307        tnew = tdata_deleg_new();
     308        tnew->deleg = torig->deleg;
     309        tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig);
     310
     311        *res = tdata_item_new(tic_tdeleg);
     312        (*res)->u.tdeleg = tnew;
     313}
     314
     315/** Substitute type variables in a functional type item.
     316 *
     317 * @param torig Type item to substitute into.
     318 * @param tvv   Type variable valuation (values of type variables).
     319 * @param res   Place to store pointer to new type item.
     320 */
     321static void tdata_item_subst_tfun(tdata_fun_t *torig, tdata_tvv_t *tvv,
     322    tdata_item_t **res)
     323{
     324        tdata_fun_t *tnew;
     325
     326        tnew = tdata_fun_new();
     327        tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig);
     328
     329        *res = tdata_item_new(tic_tfun);
     330        (*res)->u.tfun = tnew;
     331}
     332
     333/** Substitute type variables in a type-variable reference item.
     334 *
     335 * @param torig Type item to substitute into.
     336 * @param tvv   Type variable valuation (values of type variables).
     337 * @param res   Place to store pointer to new type item.
     338 */
     339static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,
     340    tdata_item_t **res)
     341{
     342        tdata_item_t *ti_new;
     343
     344        ti_new = tdata_tvv_get_val(tvv, tvref->targ->name->sid);
     345        assert(ti_new != NULL);
     346
     347        /* XXX Might be better to clone here. */
     348        *res = ti_new;
     349}
     350
     351/** Substitute type variables in a function signature type fragment.
     352 *
     353 * @param torig Type item to substitute into.
     354 * @param tvv   Type variable valuation (values of type variables).
     355 * @param res   Place to store pointer to new type item.
     356 */
     357static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,
     358    tdata_fun_sig_t **res)
     359{
     360        tdata_fun_sig_t *tnew;
     361        list_node_t *arg_n;
     362        tdata_item_t *arg_ti;
     363        tdata_item_t *narg_ti;
     364
     365        tnew = tdata_fun_sig_new();
     366
     367        /* Substitute type of each argument */
     368        list_init(&tnew->arg_ti);
     369        arg_n = list_first(&torig->arg_ti);
     370        while (arg_n != NULL) {
     371                arg_ti = list_node_data(arg_n, tdata_item_t *);
     372
     373                /* XXX Because of overloaded Builtin.WriteLine */
     374                if (arg_ti == NULL)
     375                        narg_ti = NULL;
     376                else
     377                        tdata_item_subst(arg_ti, tvv, &narg_ti);
     378
     379                list_append(&tnew->arg_ti, narg_ti);
     380
     381                arg_n = list_next(&torig->arg_ti, arg_n);
     382        }
     383
     384        /* Substitute type of variadic argument */
     385        if (torig->varg_ti != NULL)
     386                tdata_item_subst(torig->varg_ti, tvv, &tnew->varg_ti);
     387
     388        /* Substitute return type */
     389        if (torig->rtype != NULL)
     390                tdata_item_subst(torig->rtype, tvv, &tnew->rtype);
     391
     392        *res = tnew;
     393}
     394
     395
     396/** Print type item.
     397 *
     398 * @param titem Type item
     399 */
    127400void tdata_item_print(tdata_item_t *titem)
    128401{
     
    142415                tdata_tarray_print(titem->u.tarray);
    143416                break;
     417        case tic_tdeleg:
     418                tdata_tdeleg_print(titem->u.tdeleg);
     419                break;
    144420        case tic_tfun:
    145421                tdata_tfun_print(titem->u.tfun);
    146422                break;
     423        case tic_tvref:
     424                tdata_tvref_print(titem->u.tvref);
     425                break;
    147426        case tic_ignore:
    148427                printf("ignore");
     
    151430}
    152431
     432/** Print primitive type item.
     433 *
     434 * @param tprimitive    Primitive type item
     435 */
    153436static void tdata_tprimitive_print(tdata_primitive_t *tprimitive)
    154437{
     
    163446}
    164447
     448/** Print object type item.
     449 *
     450 * @param tobject       Object type item
     451 */
    165452static void tdata_tobject_print(tdata_object_t *tobject)
    166453{
     
    182469}
    183470
     471/** Print array type item.
     472 *
     473 * @param tarray        Array type item
     474 */
    184475static void tdata_tarray_print(tdata_array_t *tarray)
    185476{
     
    194485}
    195486
     487/** Print delegate type item.
     488 *
     489 * @param tdeleg        Delegate type item
     490 */
     491static void tdata_tdeleg_print(tdata_deleg_t *tdeleg)
     492{
     493        stree_symbol_t *deleg_sym;
     494
     495        deleg_sym = deleg_to_symbol(tdeleg->deleg);
     496        symbol_print_fqn(deleg_sym);
     497}
     498
     499/** Print function type item.
     500 *
     501 * @param tfun          Function type item
     502 */
    196503static void tdata_tfun_print(tdata_fun_t *tfun)
    197504{
    198         (void) tfun;
    199         printf("unimplemented(fun)");
    200 }
    201 
     505        list_node_t *arg_n;
     506        tdata_item_t *arg_ti;
     507        bool_t first;
     508
     509        printf("fun(");
     510
     511        arg_n = list_first(&tfun->tsig->arg_ti);
     512        first = b_true;
     513        while (arg_n != NULL) {
     514                if (first == b_false)
     515                        printf("; ");
     516                else
     517                        first = b_false;
     518
     519                arg_ti = list_node_data(arg_n, tdata_item_t *);
     520                tdata_item_print(arg_ti);
     521
     522                arg_n = list_next(&tfun->tsig->arg_ti, arg_n);
     523        }
     524
     525        printf(") : ");
     526        tdata_item_print(tfun->tsig->rtype);
     527}
     528
     529/** Print type variable reference type item.
     530 *
     531 * @param tvref         Type variable reference type item
     532 */
     533static void tdata_tvref_print(tdata_vref_t *tvref)
     534{
     535        printf("%s", strtab_get_str(tvref->targ->name->sid));
     536}
     537
     538/** Allocate new type item.
     539 *
     540 * @param tic   Type item class
     541 * @return      New type item
     542 */
    202543tdata_item_t *tdata_item_new(titem_class_t tic)
    203544{
     
    214555}
    215556
     557/** Allocate new array type item.
     558 *
     559 * @return      New array type item
     560 */
    216561tdata_array_t *tdata_array_new(void)
    217562{
     
    227572}
    228573
     574/** Allocate new object type item.
     575 *
     576 * @return      New object type item
     577 */
    229578tdata_object_t *tdata_object_new(void)
    230579{
     
    240589}
    241590
     591/** Allocate new primitive type item.
     592 *
     593 * @return      New primitive type item
     594 */
    242595tdata_primitive_t *tdata_primitive_new(tprimitive_class_t tpc)
    243596{
     
    254607}
    255608
     609/** Allocate new delegate type item.
     610 *
     611 * @return      New function type item
     612 */
     613tdata_deleg_t *tdata_deleg_new(void)
     614{
     615        tdata_deleg_t *tdeleg;
     616
     617        tdeleg = calloc(1, sizeof(tdata_deleg_t));
     618        if (tdeleg == NULL) {
     619                printf("Memory allocation failed.\n");
     620                exit(1);
     621        }
     622
     623        return tdeleg;
     624}
     625
     626/** Allocate new functional type item.
     627 *
     628 * @return      New function type item
     629 */
    256630tdata_fun_t *tdata_fun_new(void)
    257631{
     
    266640        return tfun;
    267641}
     642
     643/** Allocate new type variable reference type item.
     644 *
     645 * @return      New type variable reference type item
     646 */
     647tdata_vref_t *tdata_vref_new(void)
     648{
     649        tdata_vref_t *tvref;
     650
     651        tvref = calloc(1, sizeof(tdata_vref_t));
     652        if (tvref == NULL) {
     653                printf("Memory allocation failed.\n");
     654                exit(1);
     655        }
     656
     657        return tvref;
     658}
     659
     660/** Allocate new function signature type fragment.
     661 *
     662 * @return      New function signature type fragment
     663 */
     664tdata_fun_sig_t *tdata_fun_sig_new(void)
     665{
     666        tdata_fun_sig_t *tfun_sig;
     667
     668        tfun_sig = calloc(1, sizeof(tdata_fun_sig_t));
     669        if (tfun_sig == NULL) {
     670                printf("Memory allocation failed.\n");
     671                exit(1);
     672        }
     673
     674        return tfun_sig;
     675}
     676
     677/** Create a new type variable valuation.
     678 *
     679 * @retrun      New type variable valuation
     680 */
     681tdata_tvv_t *tdata_tvv_new(void)
     682{
     683        tdata_tvv_t *tvv;
     684
     685        tvv = calloc(1, sizeof(tdata_tvv_t));
     686        if (tvv == NULL) {
     687                printf("Memory allocation failed.\n");
     688                exit(1);
     689        }
     690
     691        return tvv;
     692}
     693
     694/** Get type variable value.
     695 *
     696 * Looks up value of the variable with name SID @a name in type
     697 * variable valuation @a tvv.
     698 *
     699 * @param tvv           Type variable valuation
     700 * @param name          Name of the variable (SID)
     701 * @return              Value of the type variable (type item) or @c NULL
     702 *                      if not defined in @a tvv
     703 */
     704tdata_item_t *tdata_tvv_get_val(tdata_tvv_t *tvv, sid_t name)
     705{
     706        return (tdata_item_t *)intmap_get(&tvv->tvv, name);
     707}
     708
     709/** Set tyoe variable value.
     710 *
     711 * Sets the value of variable with name SID @a name in type variable
     712 * valuation @a tvv to the value @a tvalue.
     713 *
     714 * @param tvv           Type variable valuation
     715 * @param name          Name of the variable (SID)
     716 * @param tvalue        Value to set (type item) or @c NULL to unset
     717 */
     718void tdata_tvv_set_val(tdata_tvv_t *tvv, sid_t name, tdata_item_t *tvalue)
     719{
     720        intmap_set(&tvv->tvv, name, tvalue);
     721}
Note: See TracChangeset for help on using the changeset viewer.