tdata.c

00001 /*
00002  * Copyright (c) 2010 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00031 #include <stdlib.h>
00032 #include <assert.h>
00033 #include "intmap.h"
00034 #include "list.h"
00035 #include "mytypes.h"
00036 #include "stree.h"
00037 #include "strtab.h"
00038 #include "symbol.h"
00039 
00040 #include "tdata.h"
00041 
00042 static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,
00043     tdata_tvv_t *tvv, tdata_item_t **res);
00044 static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,
00045     tdata_item_t **res);
00046 static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,
00047     tdata_item_t **res);
00048 static void tdata_item_subst_tdeleg(tdata_deleg_t *torig,
00049     tdata_tvv_t *tvv, tdata_item_t **res);
00050 static void tdata_item_subst_tebase(tdata_ebase_t *tebase,
00051     tdata_tvv_t *tvv, tdata_item_t **res);
00052 static void tdata_item_subst_tenum(tdata_enum_t *tenum,
00053     tdata_tvv_t *tvv, tdata_item_t **res);
00054 static void tdata_item_subst_tfun(tdata_fun_t *torig,
00055     tdata_tvv_t *tvv, tdata_item_t **res);
00056 static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,
00057     tdata_item_t **res);
00058 
00059 static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,
00060     tdata_fun_sig_t **res);
00061 
00062 static void tdata_tprimitive_print(tdata_primitive_t *tprimitive);
00063 static void tdata_tobject_print(tdata_object_t *tobject);
00064 static void tdata_tarray_print(tdata_array_t *tarray);
00065 static void tdata_tdeleg_print(tdata_deleg_t *tdeleg);
00066 static void tdata_tebase_print(tdata_ebase_t *tebase);
00067 static void tdata_tenum_print(tdata_enum_t *tenum);
00068 static void tdata_tfun_print(tdata_fun_t *tfun);
00069 static void tdata_tvref_print(tdata_vref_t *tvref);
00070 
00078 bool_t tdata_is_csi_derived_from_ti(stree_csi_t *a, tdata_item_t *tb)
00079 {
00080         bool_t res;
00081 
00082         switch (tb->tic) {
00083         case tic_tobject:
00084                 res = stree_is_csi_derived_from_csi(a, tb->u.tobject->csi);
00085                 break;
00086         default:
00087                 printf("Error: Base type is not a CSI.\n");
00088                 exit(1);
00089         }
00090 
00091         return res;
00092 }
00093 
00107 bool_t tdata_is_ti_derived_from_ti(tdata_item_t *ta, tdata_item_t *tb)
00108 {
00109         bool_t res;
00110 
00111         switch (ta->tic) {
00112         case tic_tobject:
00113                 res = tdata_is_csi_derived_from_ti(ta->u.tobject->csi, tb);
00114                 break;
00115         default:
00116                 printf("Error: Derived type is not a CSI.\n");
00117                 exit(1);
00118         }
00119 
00120         return res;
00121 }
00122 
00132 bool_t tdata_item_equal(tdata_item_t *a, tdata_item_t *b)
00133 {
00134         /*
00135          * Special case: Nil vs. object
00136          *
00137          * XXX Type of @c Nil should probably be @c object to avoid this
00138          * madness.
00139          */
00140         if (a->tic == tic_tprimitive && a->u.tprimitive->tpc == tpc_nil) {
00141                 if (b->tic == tic_tobject)
00142                         return b_true;
00143         } else if (b->tic == tic_tprimitive && b->u.tprimitive->tpc == tpc_nil) {
00144                 if (a->tic == tic_tobject)
00145                         return b_true;
00146         }
00147 
00148         if (a->tic != b->tic)
00149                 return b_false;
00150 
00151         switch (a->tic) {
00152         case tic_tprimitive:
00153                 /* Check if both have the same tprimitive class. */
00154                 return (a->u.tprimitive->tpc == b->u.tprimitive->tpc);
00155         case tic_tobject:
00156                 /* Check if both use the same CSI definition. */
00157                 return (a->u.tobject->csi == b->u.tobject->csi);
00158         case tic_tarray:
00159                 /* Compare rank and base type. */
00160                 if (a->u.tarray->rank != b->u.tarray->rank)
00161                         return b_false;
00162 
00163                 return tdata_item_equal(a->u.tarray->base_ti,
00164                     b->u.tarray->base_ti);
00165         case tic_tenum:
00166                 /* Check if both use the same enum definition. */
00167                 return (a->u.tenum->enum_d == b->u.tenum->enum_d);
00168         case tic_tvref:
00169                 /* Check if both refer to the same type argument. */
00170                 return (a->u.tvref->targ == b->u.tvref->targ);
00171         default:
00172                 printf("Warning: Unimplemented: Compare types '");
00173                 tdata_item_print(a);
00174                 printf("' and '");
00175                 tdata_item_print(b);
00176                 printf("'.\n");
00177                 return b_true;
00178         }
00179 }
00180 
00192 void tdata_item_subst(tdata_item_t *ti, tdata_tvv_t *tvv, tdata_item_t **res)
00193 {
00194         switch (ti->tic) {
00195         case tic_tprimitive:
00196                 tdata_item_subst_tprimitive(ti->u.tprimitive, tvv, res);
00197                 break;
00198         case tic_tobject:
00199                 tdata_item_subst_tobject(ti->u.tobject, tvv, res);
00200                 break;
00201         case tic_tarray:
00202                 tdata_item_subst_tarray(ti->u.tarray, tvv, res);
00203                 break;
00204         case tic_tdeleg:
00205                 tdata_item_subst_tdeleg(ti->u.tdeleg, tvv, res);
00206                 break;
00207         case tic_tebase:
00208                 tdata_item_subst_tebase(ti->u.tebase, tvv, res);
00209                 break;
00210         case tic_tenum:
00211                 tdata_item_subst_tenum(ti->u.tenum, tvv, res);
00212                 break;
00213         case tic_tfun:
00214                 tdata_item_subst_tfun(ti->u.tfun, tvv, res);
00215                 break;
00216         case tic_tvref:
00217                 tdata_item_subst_tvref(ti->u.tvref, tvv, res);
00218                 break;
00219         case tic_ignore:
00220                 *res = tdata_item_new(tic_ignore);
00221         }
00222 }
00223 
00230 static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,
00231     tdata_tvv_t *tvv, tdata_item_t **res)
00232 {
00233         tdata_primitive_t *tnew;
00234 
00235         (void) tvv;
00236 
00237         /* Plain copy */
00238         tnew = tdata_primitive_new(torig->tpc);
00239         *res = tdata_item_new(tic_tprimitive);
00240         (*res)->u.tprimitive = tnew;
00241 }
00242 
00249 static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,
00250     tdata_item_t **res)
00251 {
00252         tdata_object_t *tnew;
00253         list_node_t *targ_n;
00254         tdata_item_t *targ;
00255         tdata_item_t *new_targ;
00256 
00257         /* Copy static ref flag and base CSI. */
00258         tnew = tdata_object_new();
00259         tnew->static_ref = torig->static_ref;
00260         tnew->csi = torig->csi;
00261         list_init(&tnew->targs);
00262 
00263         /* Substitute arguments */
00264         targ_n = list_first(&torig->targs);
00265         while (targ_n != NULL) {
00266                 targ = list_node_data(targ_n, tdata_item_t *);
00267                 tdata_item_subst(targ, tvv, &new_targ);
00268                 list_append(&tnew->targs, new_targ);
00269 
00270                 targ_n = list_next(&torig->targs, targ_n);
00271         }
00272 
00273         *res = tdata_item_new(tic_tobject);
00274         (*res)->u.tobject = tnew;
00275 }
00276 
00283 static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,
00284     tdata_item_t **res)
00285 {
00286         tdata_array_t *tnew;
00287         list_node_t *ext_n;
00288         stree_expr_t *extent;
00289 
00290         tnew = tdata_array_new();
00291 
00292         /* Substitute base type */
00293         tdata_item_subst(torig->base_ti, tvv, &tnew->base_ti);
00294 
00295         /* Copy rank and extents */
00296         tnew->rank = torig->rank;
00297         list_init(&tnew->extents);
00298 
00299         ext_n = list_first(&torig->extents);
00300         while (ext_n != NULL) {
00301                 extent = list_node_data(ext_n, stree_expr_t *);
00302                 list_append(&tnew->extents, extent);
00303 
00304                 ext_n = list_next(&tnew->extents, ext_n);
00305         }
00306 
00307         *res = tdata_item_new(tic_tarray);
00308         (*res)->u.tarray = tnew;
00309 }
00310 
00317 static void tdata_item_subst_tdeleg(tdata_deleg_t *torig, tdata_tvv_t *tvv,
00318     tdata_item_t **res)
00319 {
00320         tdata_deleg_t *tnew;
00321 
00322         tnew = tdata_deleg_new();
00323         tnew->deleg = torig->deleg;
00324         tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig);
00325 
00326         *res = tdata_item_new(tic_tdeleg);
00327         (*res)->u.tdeleg = tnew;
00328 }
00329 
00336 static void tdata_item_subst_tebase(tdata_ebase_t *tebase,
00337     tdata_tvv_t *tvv, tdata_item_t **res)
00338 {
00339         tdata_ebase_t *tnew;
00340 
00341         (void) tvv;
00342 
00343         /* Plain copy */
00344         tnew = tdata_ebase_new();
00345         tnew->enum_d = tebase->enum_d;
00346 
00347         *res = tdata_item_new(tic_tebase);
00348         (*res)->u.tebase = tnew;
00349 }
00350 
00357 static void tdata_item_subst_tenum(tdata_enum_t *tenum,
00358     tdata_tvv_t *tvv, tdata_item_t **res)
00359 {
00360         tdata_enum_t *tnew;
00361 
00362         (void) tvv;
00363 
00364         /* Plain copy */
00365         tnew = tdata_enum_new();
00366         tnew->enum_d = tenum->enum_d;
00367 
00368         *res = tdata_item_new(tic_tenum);
00369         (*res)->u.tenum = tnew;
00370 }
00371 
00378 static void tdata_item_subst_tfun(tdata_fun_t *torig, tdata_tvv_t *tvv,
00379     tdata_item_t **res)
00380 {
00381         tdata_fun_t *tnew;
00382 
00383         tnew = tdata_fun_new();
00384         tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig);
00385 
00386         *res = tdata_item_new(tic_tfun);
00387         (*res)->u.tfun = tnew;
00388 }
00389 
00396 static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,
00397     tdata_item_t **res)
00398 {
00399         tdata_item_t *ti_new;
00400 
00401         ti_new = tdata_tvv_get_val(tvv, tvref->targ->name->sid);
00402         assert(ti_new != NULL);
00403 
00404         /* XXX Might be better to clone here. */
00405         *res = ti_new;
00406 }
00407 
00414 static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,
00415     tdata_fun_sig_t **res)
00416 {
00417         tdata_fun_sig_t *tnew;
00418         list_node_t *arg_n;
00419         tdata_item_t *arg_ti;
00420         tdata_item_t *narg_ti;
00421 
00422         tnew = tdata_fun_sig_new();
00423 
00424         /* Substitute type of each argument */
00425         list_init(&tnew->arg_ti);
00426         arg_n = list_first(&torig->arg_ti);
00427         while (arg_n != NULL) {
00428                 arg_ti = list_node_data(arg_n, tdata_item_t *);
00429 
00430                 /* XXX Because of overloaded Builtin.WriteLine */
00431                 if (arg_ti == NULL)
00432                         narg_ti = NULL;
00433                 else
00434                         tdata_item_subst(arg_ti, tvv, &narg_ti);
00435 
00436                 list_append(&tnew->arg_ti, narg_ti);
00437 
00438                 arg_n = list_next(&torig->arg_ti, arg_n);
00439         }
00440 
00441         /* Substitute type of variadic argument */
00442         if (torig->varg_ti != NULL)
00443                 tdata_item_subst(torig->varg_ti, tvv, &tnew->varg_ti);
00444 
00445         /* Substitute return type */
00446         if (torig->rtype != NULL)
00447                 tdata_item_subst(torig->rtype, tvv, &tnew->rtype);
00448 
00449         *res = tnew;
00450 }
00451 
00452 
00457 void tdata_item_print(tdata_item_t *titem)
00458 {
00459         if (titem == NULL) {
00460                 printf("none");
00461                 return;
00462         }
00463 
00464         switch (titem->tic) {
00465         case tic_tprimitive:
00466                 tdata_tprimitive_print(titem->u.tprimitive);
00467                 break;
00468         case tic_tobject:
00469                 tdata_tobject_print(titem->u.tobject);
00470                 break;
00471         case tic_tarray:
00472                 tdata_tarray_print(titem->u.tarray);
00473                 break;
00474         case tic_tdeleg:
00475                 tdata_tdeleg_print(titem->u.tdeleg);
00476                 break;
00477         case tic_tebase:
00478                 tdata_tebase_print(titem->u.tebase);
00479                 break;
00480         case tic_tenum:
00481                 tdata_tenum_print(titem->u.tenum);
00482                 break;
00483         case tic_tfun:
00484                 tdata_tfun_print(titem->u.tfun);
00485                 break;
00486         case tic_tvref:
00487                 tdata_tvref_print(titem->u.tvref);
00488                 break;
00489         case tic_ignore:
00490                 printf("ignore");
00491                 break;
00492         }
00493 }
00494 
00499 static void tdata_tprimitive_print(tdata_primitive_t *tprimitive)
00500 {
00501         switch (tprimitive->tpc) {
00502         case tpc_bool: printf("bool"); break;
00503         case tpc_char: printf("char"); break;
00504         case tpc_int: printf("int"); break;
00505         case tpc_nil: printf("nil"); break;
00506         case tpc_string: printf("string"); break;
00507         case tpc_resource: printf("resource"); break;
00508         }
00509 }
00510 
00515 static void tdata_tobject_print(tdata_object_t *tobject)
00516 {
00517         stree_symbol_t *csi_sym;
00518         list_node_t *arg_n;
00519         tdata_item_t *arg;
00520 
00521         csi_sym = csi_to_symbol(tobject->csi);
00522         assert(csi_sym != NULL);
00523         symbol_print_fqn(csi_sym);
00524 
00525         arg_n = list_first(&tobject->targs);
00526         while (arg_n != NULL) {
00527                 arg = list_node_data(arg_n, tdata_item_t *);
00528                 putchar('/');
00529                 tdata_item_print(arg);
00530                 arg_n = list_next(&tobject->targs, arg_n);
00531         }
00532 }
00533 
00538 static void tdata_tarray_print(tdata_array_t *tarray)
00539 {
00540         int i;
00541 
00542         tdata_item_print(tarray->base_ti);
00543 
00544         printf("[");
00545         for (i = 0; i < tarray->rank - 1; ++i)
00546                 printf(",");
00547         printf("]");
00548 }
00549 
00554 static void tdata_tdeleg_print(tdata_deleg_t *tdeleg)
00555 {
00556         stree_symbol_t *deleg_sym;
00557 
00558         deleg_sym = deleg_to_symbol(tdeleg->deleg);
00559         symbol_print_fqn(deleg_sym);
00560 }
00561 
00566 static void tdata_tebase_print(tdata_ebase_t *tebase)
00567 {
00568         stree_symbol_t *enum_sym;
00569 
00570         enum_sym = enum_to_symbol(tebase->enum_d);
00571 
00572         printf("typeref(");
00573         symbol_print_fqn(enum_sym);
00574         printf(")");
00575 }
00576 
00581 static void tdata_tenum_print(tdata_enum_t *tenum)
00582 {
00583         stree_symbol_t *enum_sym;
00584 
00585         enum_sym = enum_to_symbol(tenum->enum_d);
00586         symbol_print_fqn(enum_sym);
00587 }
00588 
00593 static void tdata_tfun_print(tdata_fun_t *tfun)
00594 {
00595         list_node_t *arg_n;
00596         tdata_item_t *arg_ti;
00597         bool_t first;
00598 
00599         printf("fun(");
00600 
00601         arg_n = list_first(&tfun->tsig->arg_ti);
00602         first = b_true;
00603         while (arg_n != NULL) {
00604                 if (first == b_false)
00605                         printf("; ");
00606                 else
00607                         first = b_false;
00608 
00609                 arg_ti = list_node_data(arg_n, tdata_item_t *);
00610                 tdata_item_print(arg_ti);
00611 
00612                 arg_n = list_next(&tfun->tsig->arg_ti, arg_n);
00613         }
00614 
00615         printf(") : ");
00616         tdata_item_print(tfun->tsig->rtype);
00617 }
00618 
00623 static void tdata_tvref_print(tdata_vref_t *tvref)
00624 {
00625         printf("%s", strtab_get_str(tvref->targ->name->sid));
00626 }
00627 
00633 tdata_item_t *tdata_item_new(titem_class_t tic)
00634 {
00635         tdata_item_t *titem;
00636 
00637         titem = calloc(1, sizeof(tdata_item_t));
00638         if (titem == NULL) {
00639                 printf("Memory allocation failed.\n");
00640                 exit(1);
00641         }
00642 
00643         titem->tic = tic;
00644         return titem;
00645 }
00646 
00651 tdata_array_t *tdata_array_new(void)
00652 {
00653         tdata_array_t *tarray;
00654 
00655         tarray = calloc(1, sizeof(tdata_array_t));
00656         if (tarray == NULL) {
00657                 printf("Memory allocation failed.\n");
00658                 exit(1);
00659         }
00660 
00661         return tarray;
00662 }
00663 
00668 tdata_object_t *tdata_object_new(void)
00669 {
00670         tdata_object_t *tobject;
00671 
00672         tobject = calloc(1, sizeof(tdata_object_t));
00673         if (tobject == NULL) {
00674                 printf("Memory allocation failed.\n");
00675                 exit(1);
00676         }
00677 
00678         return tobject;
00679 }
00680 
00685 tdata_primitive_t *tdata_primitive_new(tprimitive_class_t tpc)
00686 {
00687         tdata_primitive_t *tprimitive;
00688 
00689         tprimitive = calloc(1, sizeof(tdata_primitive_t));
00690         if (tprimitive == NULL) {
00691                 printf("Memory allocation failed.\n");
00692                 exit(1);
00693         }
00694 
00695         tprimitive->tpc = tpc;
00696         return tprimitive;
00697 }
00698 
00703 tdata_deleg_t *tdata_deleg_new(void)
00704 {
00705         tdata_deleg_t *tdeleg;
00706 
00707         tdeleg = calloc(1, sizeof(tdata_deleg_t));
00708         if (tdeleg == NULL) {
00709                 printf("Memory allocation failed.\n");
00710                 exit(1);
00711         }
00712 
00713         return tdeleg;
00714 }
00715 
00720 tdata_ebase_t *tdata_ebase_new(void)
00721 {
00722         tdata_ebase_t *tebase;
00723 
00724         tebase = calloc(1, sizeof(tdata_ebase_t));
00725         if (tebase == NULL) {
00726                 printf("Memory allocation failed.\n");
00727                 exit(1);
00728         }
00729 
00730         return tebase;
00731 }
00732 
00737 tdata_enum_t *tdata_enum_new(void)
00738 {
00739         tdata_enum_t *tenum;
00740 
00741         tenum = calloc(1, sizeof(tdata_enum_t));
00742         if (tenum == NULL) {
00743                 printf("Memory allocation failed.\n");
00744                 exit(1);
00745         }
00746 
00747         return tenum;
00748 }
00749 
00754 tdata_fun_t *tdata_fun_new(void)
00755 {
00756         tdata_fun_t *tfun;
00757 
00758         tfun = calloc(1, sizeof(tdata_fun_t));
00759         if (tfun == NULL) {
00760                 printf("Memory allocation failed.\n");
00761                 exit(1);
00762         }
00763 
00764         return tfun;
00765 }
00766 
00771 tdata_vref_t *tdata_vref_new(void)
00772 {
00773         tdata_vref_t *tvref;
00774 
00775         tvref = calloc(1, sizeof(tdata_vref_t));
00776         if (tvref == NULL) {
00777                 printf("Memory allocation failed.\n");
00778                 exit(1);
00779         }
00780 
00781         return tvref;
00782 }
00783 
00788 tdata_fun_sig_t *tdata_fun_sig_new(void)
00789 {
00790         tdata_fun_sig_t *tfun_sig;
00791 
00792         tfun_sig = calloc(1, sizeof(tdata_fun_sig_t));
00793         if (tfun_sig == NULL) {
00794                 printf("Memory allocation failed.\n");
00795                 exit(1);
00796         }
00797 
00798         return tfun_sig;
00799 }
00800 
00805 tdata_tvv_t *tdata_tvv_new(void)
00806 {
00807         tdata_tvv_t *tvv;
00808 
00809         tvv = calloc(1, sizeof(tdata_tvv_t));
00810         if (tvv == NULL) {
00811                 printf("Memory allocation failed.\n");
00812                 exit(1);
00813         }
00814 
00815         return tvv;
00816 }
00817 
00828 tdata_item_t *tdata_tvv_get_val(tdata_tvv_t *tvv, sid_t name)
00829 {
00830         return (tdata_item_t *)intmap_get(&tvv->tvv, name);
00831 }
00832 
00842 void tdata_tvv_set_val(tdata_tvv_t *tvv, sid_t name, tdata_item_t *tvalue)
00843 {
00844         intmap_set(&tvv->tvv, name, tvalue);
00845 }

Generated on Thu Jun 2 07:45:43 2011 for HelenOS/USB by  doxygen 1.4.7