00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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 }