run_texpr.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 <assert.h>
00032 #include <stdlib.h>
00033 #include "cspan.h"
00034 #include "debug.h"
00035 #include "list.h"
00036 #include "mytypes.h"
00037 #include "stree.h"
00038 #include "strtab.h"
00039 #include "symbol.h"
00040 #include "tdata.h"
00041 
00042 #include "run_texpr.h"
00043 
00044 static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
00045     stree_taccess_t *taccess, tdata_item_t **res);
00046 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
00047     stree_tindex_t *tindex, tdata_item_t **res);
00048 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
00049     stree_tliteral_t *tliteral, tdata_item_t **res);
00050 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
00051     stree_tnameref_t *tnameref, tdata_item_t **res);
00052 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
00053     stree_tapply_t *tapply, tdata_item_t **res);
00054 
00065 void run_texpr(stree_program_t *prog, stree_csi_t *ctx, stree_texpr_t *texpr,
00066     tdata_item_t **res)
00067 {
00068         switch (texpr->tc) {
00069         case tc_taccess:
00070                 run_taccess(prog, ctx, texpr->u.taccess, res);
00071                 break;
00072         case tc_tindex:
00073                 run_tindex(prog, ctx, texpr->u.tindex, res);
00074                 break;
00075         case tc_tliteral:
00076                 run_tliteral(prog, ctx, texpr->u.tliteral, res);
00077                 break;
00078         case tc_tnameref:
00079                 run_tnameref(prog, ctx, texpr->u.tnameref, res);
00080                 break;
00081         case tc_tapply:
00082                 run_tapply(prog, ctx, texpr->u.tapply, res);
00083                 break;
00084         }
00085 }
00086 
00096 static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
00097     stree_taccess_t *taccess, tdata_item_t **res)
00098 {
00099         stree_symbol_t *sym;
00100         tdata_item_t *targ_i;
00101         tdata_item_t *titem;
00102         tdata_object_t *tobject;
00103         tdata_deleg_t *tdeleg;
00104         stree_csi_t *base_csi;
00105         stree_deleg_t *deleg;
00106         stree_enum_t *enum_d;
00107         tdata_enum_t *tenum;
00108 
00109 #ifdef DEBUG_RUN_TRACE
00110         printf("Evaluating type access operation.\n");
00111 #endif
00112         /* Evaluate base type. */
00113         run_texpr(prog, ctx, taccess->arg, &targ_i);
00114 
00115         if (targ_i->tic == tic_ignore) {
00116                 *res = tdata_item_new(tic_ignore);
00117                 return;
00118         }
00119 
00120         if (targ_i->tic != tic_tobject) {
00121                 cspan_print(taccess->texpr->cspan);
00122                 printf(" Error: Using '.' with type which is not an "
00123                     "object.\n");
00124                 *res = tdata_item_new(tic_ignore);
00125                 return;
00126         }
00127 
00128         /* Get base CSI. */
00129         base_csi = targ_i->u.tobject->csi;
00130 
00131         sym = symbol_lookup_in_csi(prog, base_csi, taccess->member_name);
00132         if (sym == NULL) {
00133                 cspan_print(taccess->member_name->cspan);
00134                 printf(" Error: CSI '");
00135                 symbol_print_fqn(csi_to_symbol(base_csi));
00136                 printf("' has no member named '%s'.\n",
00137                     strtab_get_str(taccess->member_name->sid));
00138                 *res = tdata_item_new(tic_ignore);
00139                 return;
00140         }
00141 
00142         /* Make compiler happy. */
00143         titem = NULL;
00144 
00145         switch (sym->sc) {
00146         case sc_csi:
00147                 /* Construct type item. */
00148                 titem = tdata_item_new(tic_tobject);
00149                 tobject = tdata_object_new();
00150                 titem->u.tobject = tobject;
00151 
00152                 tobject->static_ref = sn_nonstatic;
00153                 tobject->csi = sym->u.csi;
00154                 list_init(&tobject->targs);
00155                 break;
00156         case sc_ctor:
00157                 /* It is not possible to reference a constructor explicitly. */
00158                 assert(b_false);
00159         case sc_deleg:
00160                 /* Fetch stored delegate type. */
00161                 deleg = symbol_to_deleg(sym);
00162                 assert(deleg != NULL);
00163                 if (deleg->titem == NULL) {
00164                         /*
00165                          * Prepare a partial delegate which will be completed
00166                          * later.
00167                          */
00168                         titem = tdata_item_new(tic_tdeleg);
00169                         tdeleg = tdata_deleg_new();
00170                         titem->u.tdeleg = tdeleg;
00171                         tdeleg->deleg = deleg;
00172                         tdeleg->tsig = NULL;
00173 
00174                         deleg->titem = titem;
00175                 } else {
00176                         titem = deleg->titem;
00177                 }
00178                 break;
00179         case sc_enum:
00180                 /* Fetch stored enum type. */
00181                 enum_d = symbol_to_enum(sym);
00182                 assert(enum_d != NULL);
00183                 if (enum_d->titem == NULL) {
00184                         /*
00185                          * Prepare a partial enum whic will be completed
00186                          * later.
00187                          */
00188                         titem = tdata_item_new(tic_tenum);
00189                         tenum = tdata_enum_new();
00190                         titem->u.tenum = tenum;
00191                         tenum->enum_d = enum_d;
00192                 } else {
00193                         titem = enum_d->titem;
00194                 }
00195                 break;
00196         case sc_fun:
00197         case sc_var:
00198         case sc_prop:
00199                 cspan_print(taccess->member_name->cspan);
00200                 printf(" Error: Symbol '");
00201                 symbol_print_fqn(sym);
00202                 printf("' is not a type.\n");
00203                 titem = tdata_item_new(tic_ignore);
00204                 break;
00205         }
00206 
00207         *res = titem;
00208 }
00209 
00221 static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
00222     stree_tindex_t *tindex, tdata_item_t **res)
00223 {
00224         tdata_item_t *base_ti;
00225         tdata_item_t *titem;
00226         tdata_array_t *tarray;
00227         stree_expr_t *arg_expr;
00228         list_node_t *arg_node;
00229 
00230 #ifdef DEBUG_RUN_TRACE
00231         printf("Evaluating type index operation.\n");
00232 #endif
00233         /* Evaluate base type. */
00234         run_texpr(prog, ctx, tindex->base_type, &base_ti);
00235 
00236         if (base_ti->tic == tic_ignore) {
00237                 *res = tdata_item_new(tic_ignore);
00238                 return;
00239         }
00240 
00241         /* Construct type item. */
00242         titem = tdata_item_new(tic_tarray);
00243         tarray = tdata_array_new();
00244         titem->u.tarray = tarray;
00245 
00246         tarray->base_ti = base_ti;
00247         tarray->rank = tindex->n_args;
00248 
00249         /* Copy extents. */
00250         list_init(&tarray->extents);
00251         arg_node = list_first(&tindex->args);
00252 
00253         while (arg_node != NULL) {
00254                 arg_expr = list_node_data(arg_node, stree_expr_t *);
00255                 list_append(&tarray->extents, arg_expr);
00256                 arg_node = list_next(&tindex->args, arg_node);
00257         }
00258 
00259         *res = titem;
00260 }
00261 
00269 static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
00270     stree_tliteral_t *tliteral, tdata_item_t **res)
00271 {
00272         tdata_item_t *titem;
00273         tdata_primitive_t *tprimitive;
00274         tprimitive_class_t tpc;
00275 
00276 #ifdef DEBUG_RUN_TRACE
00277         printf("Evaluating type literal.\n");
00278 #endif
00279         (void) prog;
00280         (void) ctx;
00281         (void) tliteral;
00282 
00283         /* Make compiler happy. */
00284         tpc = 0;
00285 
00286         switch (tliteral->tlc) {
00287         case tlc_bool: tpc = tpc_bool; break;
00288         case tlc_char: tpc = tpc_char; break;
00289         case tlc_int: tpc = tpc_int; break;
00290         case tlc_string: tpc = tpc_string; break;
00291         case tlc_resource: tpc = tpc_resource; break;
00292         }
00293 
00294         /* Construct type item. */
00295         titem = tdata_item_new(tic_tprimitive);
00296         tprimitive = tdata_primitive_new(tpc);
00297         titem->u.tprimitive = tprimitive;
00298 
00299         *res = titem;
00300 }
00301 
00302 static void run_tnameref(stree_program_t *prog, stree_csi_t *ctx,
00303     stree_tnameref_t *tnameref, tdata_item_t **res)
00304 {
00305         stree_symbol_t *sym;
00306         tdata_item_t *titem;
00307         tdata_object_t *tobject;
00308         stree_targ_t *targ;
00309         tdata_vref_t *tvref;
00310         stree_deleg_t *deleg;
00311         tdata_deleg_t *tdeleg;
00312         stree_enum_t *enum_d;
00313         tdata_enum_t *tenum;
00314 
00315 #ifdef DEBUG_RUN_TRACE
00316         printf("Evaluating type name reference.\n");
00317         printf("'%s'\n", strtab_get_str(tnameref->name->sid));
00318 #endif
00319         /* In interactive mode we are not in a class */
00320         if (ctx != NULL) {
00321                 /* Look for type argument */
00322                 targ = stree_csi_find_targ(ctx, tnameref->name);
00323 
00324                 if (targ != NULL) {
00325                         /* Found type argument */
00326 #ifdef DEBUG_RUN_TRACE
00327                         printf("Found type argument '%s'.\n",
00328                             strtab_get_str(tnameref->name->sid));
00329 #endif
00330                         titem = tdata_item_new(tic_tvref);
00331                         tvref = tdata_vref_new();
00332                         titem->u.tvref = tvref;
00333                         tvref->targ = targ;
00334 
00335                         *res = titem;
00336                         return;
00337                 }
00338         }
00339 
00340         /* Look for symbol */
00341         sym = symbol_lookup_in_csi(prog, ctx, tnameref->name);
00342         if (sym == NULL) {
00343                 cspan_print(tnameref->texpr->cspan);
00344                 printf(" Error: Symbol '%s' not found.\n",
00345                     strtab_get_str(tnameref->name->sid));
00346                 *res = tdata_item_new(tic_ignore);
00347                 return;
00348         }
00349 
00350         /* Make compiler happy. */
00351         titem = NULL;
00352 
00353         switch (sym->sc) {
00354         case sc_csi:
00355                 /* Construct type item. */
00356                 titem = tdata_item_new(tic_tobject);
00357                 tobject = tdata_object_new();
00358                 titem->u.tobject = tobject;
00359 
00360                 tobject->static_ref = sn_nonstatic;
00361                 tobject->csi = sym->u.csi;
00362                 list_init(&tobject->targs);
00363                 break;
00364         case sc_ctor:
00365                 /* It is not possible to reference a constructor explicitly. */
00366                 assert(b_false);
00367         case sc_deleg:
00368                 /* Fetch stored delegate type. */
00369                 deleg = symbol_to_deleg(sym);
00370                 assert(deleg != NULL);
00371                 if (deleg->titem == NULL) {
00372                         /*
00373                          * Prepare a partial delegate which will be completed
00374                          * later.
00375                          */
00376                         titem = tdata_item_new(tic_tdeleg);
00377                         tdeleg = tdata_deleg_new();
00378                         titem->u.tdeleg = tdeleg;
00379                         tdeleg->deleg = deleg;
00380                         tdeleg->tsig = NULL;
00381 
00382                         deleg->titem = titem;
00383                 } else {
00384                         titem = deleg->titem;
00385                 }
00386                 break;
00387         case sc_enum:
00388                 /* Fetch stored enum type. */
00389                 enum_d = symbol_to_enum(sym);
00390                 assert(enum_d != NULL);
00391                 if (enum_d->titem == NULL) {
00392                         /*
00393                          * Prepare a partial enum whic will be completed
00394                          * later.
00395                          */
00396                         titem = tdata_item_new(tic_tenum);
00397                         tenum = tdata_enum_new();
00398                         titem->u.tenum = tenum;
00399                         tenum->enum_d = enum_d;
00400                 } else {
00401                         titem = enum_d->titem;
00402                 }
00403                 break;
00404         case sc_fun:
00405         case sc_var:
00406         case sc_prop:
00407                 cspan_print(tnameref->texpr->cspan);
00408                 printf(" Error: Symbol '");
00409                 symbol_print_fqn(sym);
00410                 printf("' is not a type.\n");
00411                 titem = tdata_item_new(tic_ignore);
00412                 break;
00413         }
00414 
00415         *res = titem;
00416 }
00417 
00428 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
00429     stree_tapply_t *tapply, tdata_item_t **res)
00430 {
00431         tdata_item_t *base_ti;
00432         tdata_item_t *arg_ti;
00433         tdata_item_t *titem;
00434         tdata_object_t *tobject;
00435 
00436         list_node_t *arg_n;
00437         stree_texpr_t *arg;
00438 
00439         list_node_t *farg_n;
00440 
00441 #ifdef DEBUG_RUN_TRACE
00442         printf("Evaluating type apply operation.\n");
00443 #endif
00444         /* Construct type item. */
00445         titem = tdata_item_new(tic_tobject);
00446         tobject = tdata_object_new();
00447         titem->u.tobject = tobject;
00448 
00449         /* Evaluate base (generic) type. */
00450         run_texpr(prog, ctx, tapply->gtype, &base_ti);
00451 
00452         if (base_ti->tic != tic_tobject) {
00453                 cspan_print(tapply->gtype->cspan);
00454                 printf(" Error: Base type of generic application is not "
00455                     "a CSI.\n");
00456                 *res = tdata_item_new(tic_ignore);
00457                 return;
00458         }
00459 
00460         tobject->static_ref = sn_nonstatic;
00461         tobject->csi = base_ti->u.tobject->csi;
00462         list_init(&tobject->targs);
00463 
00464         /* Evaluate type arguments. */
00465         farg_n = list_first(&tobject->csi->targ);
00466         arg_n = list_first(&tapply->targs);
00467         while (farg_n != NULL && arg_n != NULL) {
00468                 arg = list_node_data(arg_n, stree_texpr_t *);
00469 
00470                 run_texpr(prog, ctx, arg, &arg_ti);
00471 
00472                 if (arg_ti->tic == tic_ignore) {
00473                         *res = tdata_item_new(tic_ignore);
00474                         return;
00475                 }
00476 
00477                 list_append(&tobject->targs, arg_ti);
00478 
00479                 farg_n = list_next(&tobject->csi->targ, farg_n);
00480                 arg_n = list_next(&tapply->targs, arg_n);
00481         }
00482 
00483         if (farg_n != NULL || arg_n != NULL) {
00484                 cspan_print(tapply->texpr->cspan);
00485                 printf(" Error: Incorrect number of type arguments.\n");
00486                 *res = tdata_item_new(tic_ignore);
00487                 return;
00488         }
00489 
00490         *res = titem;
00491 }

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