p_type.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 "lex.h"
00036 #include "list.h"
00037 #include "mytypes.h"
00038 #include "parse.h"
00039 #include "p_expr.h"
00040 #include "stree.h"
00041 
00042 #include "p_type.h"
00043 
00044 static stree_texpr_t *parse_tapply(parse_t *parse);
00045 static stree_texpr_t *parse_tpostfix(parse_t *parse);
00046 static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a);
00047 static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a);
00048 static stree_texpr_t *parse_tparen(parse_t *parse);
00049 static stree_texpr_t *parse_tprimitive(parse_t *parse);
00050 static stree_texpr_t *parse_tliteral(parse_t *parse);
00051 static stree_texpr_t *parse_tnameref(parse_t *parse);
00052 
00053 static stree_texpr_t *parse_recovery_texpr(parse_t *parse);
00054 
00065 stree_texpr_t *parse_texpr(parse_t *parse)
00066 {
00067 #ifdef DEBUG_PARSE_TRACE
00068         printf("Parse type expression.\n");
00069 #endif
00070         if (parse_is_error(parse))
00071                 return parse_recovery_texpr(parse);
00072 
00073         return parse_tapply(parse);
00074 }
00075 
00080 static stree_texpr_t *parse_tapply(parse_t *parse)
00081 {
00082         stree_texpr_t *gtype;
00083         stree_texpr_t *aexpr;
00084         stree_texpr_t *targ;
00085         stree_tapply_t *tapply;
00086 
00087         gtype = parse_tpostfix(parse);
00088         if (lcur_lc(parse) != lc_slash)
00089                 return gtype;
00090 
00091         tapply = stree_tapply_new();
00092         tapply->gtype = gtype;
00093         list_init(&tapply->targs);
00094 
00095         targ = NULL;
00096 
00097         while (lcur_lc(parse) == lc_slash) {
00098 
00099                 if (parse_is_error(parse))
00100                         break;
00101 
00102                 lskip(parse);
00103                 targ = parse_tpostfix(parse);
00104 
00105                 list_append(&tapply->targs, targ);
00106         }
00107 
00108         aexpr = stree_texpr_new(tc_tapply);
00109         aexpr->u.tapply = tapply;
00110         tapply->texpr = aexpr;
00111 
00112         if (targ != NULL)
00113                 aexpr->cspan = cspan_merge(gtype->cspan, targ->cspan);
00114         else
00115                 aexpr->cspan = gtype->cspan;
00116 
00117         return aexpr;
00118 }
00119 
00124 static stree_texpr_t *parse_tpostfix(parse_t *parse)
00125 {
00126         stree_texpr_t *a;
00127         stree_texpr_t *tmp;
00128 
00129         a = parse_tparen(parse);
00130 
00131         while (lcur_lc(parse) == lc_period || lcur_lc(parse) == lc_lsbr) {
00132 
00133                 if (parse_is_error(parse))
00134                         break;
00135 
00136                 switch (lcur_lc(parse)) {
00137                 case lc_period:
00138                         tmp = parse_pf_taccess(parse, a);
00139                         break;
00140                 case lc_lsbr:
00141                         tmp = parse_pf_tindex(parse, a);
00142                         break;
00143                 default:
00144                         lunexpected_error(parse);
00145                         tmp = parse_recovery_texpr(parse);
00146                         break;
00147                 }
00148 
00149                 a = tmp;
00150         }
00151 
00152         return a;
00153 }
00154 
00160 static stree_texpr_t *parse_pf_taccess(parse_t *parse, stree_texpr_t *a)
00161 {
00162         stree_texpr_t *texpr;
00163         stree_ident_t *ident;
00164         stree_taccess_t *taccess;
00165 
00166         lmatch(parse, lc_period);
00167         ident = parse_ident(parse);
00168 
00169         taccess = stree_taccess_new();
00170         taccess->arg = a;
00171         taccess->member_name = ident;
00172 
00173         texpr = stree_texpr_new(tc_taccess);
00174         texpr->u.taccess = taccess;
00175         taccess->texpr = texpr;
00176         texpr->cspan = cspan_merge(a->cspan, ident->cspan);
00177 
00178         return texpr;
00179 }
00180 
00186 static stree_texpr_t *parse_pf_tindex(parse_t *parse, stree_texpr_t *a)
00187 {
00188         stree_texpr_t *texpr;
00189         stree_tindex_t *tindex;
00190         stree_expr_t *expr;
00191         cspan_t *cs1;
00192 
00193         tindex = stree_tindex_new();
00194         tindex->base_type = a;
00195 
00196         tindex->n_args = 0;
00197         list_init(&tindex->args);
00198 
00199         lmatch(parse, lc_lsbr);
00200 
00201         if (lcur_lc(parse) != lc_rsbr && lcur_lc(parse) != lc_comma) {
00202                 while (b_true) {
00203                         if (parse_is_error(parse))
00204                                 break;
00205                         expr = parse_expr(parse);
00206                         tindex->n_args += 1;
00207                         list_append(&tindex->args, expr);
00208 
00209                         if (lcur_lc(parse) == lc_rsbr)
00210                                 break;
00211 
00212                         lmatch(parse, lc_comma);
00213                 }
00214         } else {
00215                 tindex->n_args = 1;
00216                 while (lcur_lc(parse) == lc_comma) {
00217                         if (parse_is_error(parse))
00218                                 break;
00219                         lskip(parse);
00220                         tindex->n_args += 1;
00221                 }
00222         }
00223 
00224         lmatch(parse, lc_rsbr);
00225         cs1 = lprev_span(parse);
00226 
00227         texpr = stree_texpr_new(tc_tindex);
00228         texpr->u.tindex = tindex;
00229         tindex->texpr = texpr;
00230         texpr->cspan = cspan_merge(a->cspan, cs1);
00231 
00232         return texpr;
00233 }
00234 
00239 static stree_texpr_t *parse_tparen(parse_t *parse)
00240 {
00241         stree_texpr_t *texpr;
00242         cspan_t *cs0, *cs1;
00243 
00244         if (lcur_lc(parse) == lc_lparen) {
00245                 cs0 = lcur_span(parse);
00246                 lskip(parse);
00247                 texpr = parse_texpr(parse);
00248                 lmatch(parse, lc_rparen);
00249                 cs1 = lprev_span(parse);
00250                 texpr->cspan = cspan_merge(cs0, cs1);
00251         } else {
00252                 texpr = parse_tprimitive(parse);
00253         }
00254 
00255         return texpr;
00256 }
00257 
00258 
00263 static stree_texpr_t *parse_tprimitive(parse_t *parse)
00264 {
00265         stree_texpr_t *texpr;
00266 
00267         switch (lcur_lc(parse)) {
00268         case lc_ident:
00269                 texpr = parse_tnameref(parse);
00270                 break;
00271         case lc_bool:
00272         case lc_char:
00273         case lc_int:
00274         case lc_string:
00275         case lc_resource:
00276                 texpr = parse_tliteral(parse);
00277                 break;
00278         default:
00279                 lunexpected_error(parse);
00280                 texpr = parse_recovery_texpr(parse);
00281                 break;
00282         }
00283 
00284         return texpr;
00285 }
00286 
00291 static stree_texpr_t *parse_tliteral(parse_t *parse)
00292 {
00293         stree_tliteral_t *tliteral;
00294         tliteral_class_t tlc;
00295         stree_texpr_t *texpr;
00296 
00297         switch (lcur_lc(parse)) {
00298         case lc_bool:
00299                 tlc = tlc_bool;
00300                 break;
00301         case lc_char:
00302                 tlc = tlc_char;
00303                 break;
00304         case lc_int:
00305                 tlc = tlc_int;
00306                 break;
00307         case lc_string:
00308                 tlc = tlc_string;
00309                 break;
00310         case lc_resource:
00311                 tlc = tlc_resource;
00312                 break;
00313         default:
00314                 assert(b_false);
00315         }
00316 
00317         lskip(parse);
00318 
00319         tliteral = stree_tliteral_new(tlc);
00320         texpr = stree_texpr_new(tc_tliteral);
00321         texpr->u.tliteral = tliteral;
00322         tliteral->texpr = texpr;
00323         texpr->cspan = lprev_span(parse);
00324 
00325         return texpr;
00326 }
00327 
00332 static stree_texpr_t *parse_tnameref(parse_t *parse)
00333 {
00334         stree_tnameref_t *tnameref;
00335         stree_texpr_t *texpr;
00336 
00337         tnameref = stree_tnameref_new();
00338         tnameref->name = parse_ident(parse);
00339 
00340         texpr = stree_texpr_new(tc_tnameref);
00341         texpr->u.tnameref = tnameref;
00342         tnameref->texpr = texpr;
00343         texpr->cspan = tnameref->name->cspan;
00344 
00345         return texpr;
00346 }
00347 
00352 static stree_texpr_t *parse_recovery_texpr(parse_t *parse)
00353 {
00354         stree_tliteral_t *tliteral;
00355         stree_texpr_t *texpr;
00356 
00357         (void) parse;
00358 
00359         tliteral = stree_tliteral_new(tlc_int);
00360 
00361         texpr = stree_texpr_new(tc_tliteral);
00362         texpr->u.tliteral = tliteral;
00363         tliteral->texpr = texpr;
00364 
00365         return texpr;
00366 }

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