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
00035 #include <assert.h>
00036 #include <stdlib.h>
00037 #include "cspan.h"
00038 #include "debug.h"
00039 #include "lex.h"
00040 #include "list.h"
00041 #include "mytypes.h"
00042 #include "p_expr.h"
00043 #include "p_type.h"
00044 #include "stree.h"
00045 #include "strtab.h"
00046 #include "symbol.h"
00047
00048 #include "parse.h"
00049
00050
00051
00052
00053 static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
00054 stree_csi_t *outer_csi);
00055 static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi);
00056
00057 static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi);
00058
00059 static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi);
00060 static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum);
00061
00062 static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi);
00063 static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi);
00064 static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi);
00065 static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi);
00066
00067 static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol);
00068 static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse);
00069
00070 static stree_proc_arg_t *parse_proc_arg(parse_t *parse);
00071 static stree_arg_attr_t *parse_arg_attr(parse_t *parse);
00072 static stree_fun_sig_t *parse_fun_sig(parse_t *parse);
00073
00074 static void parse_prop_get(parse_t *parse, stree_prop_t *prop);
00075 static void parse_prop_set(parse_t *parse, stree_prop_t *prop);
00076
00077
00078
00079
00080 static stree_block_t *parse_block(parse_t *parse);
00081
00082 static stree_vdecl_t *parse_vdecl(parse_t *parse);
00083 static stree_if_t *parse_if(parse_t *parse);
00084 static stree_switch_t *parse_switch(parse_t *parse);
00085 static stree_while_t *parse_while(parse_t *parse);
00086 static stree_for_t *parse_for(parse_t *parse);
00087 static stree_raise_t *parse_raise(parse_t *parse);
00088 static stree_break_t *parse_break(parse_t *parse);
00089 static stree_return_t *parse_return(parse_t *parse);
00090 static stree_wef_t *parse_wef(parse_t *parse);
00091 static stree_exps_t *parse_exps(parse_t *parse);
00092
00093 static stree_except_t *parse_except(parse_t *parse);
00094
00106 void parse_init(parse_t *parse, stree_program_t *prog, struct lex *lex)
00107 {
00108 parse->program = prog;
00109 parse->cur_mod = parse->program->module;
00110 parse->lex = lex;
00111
00112 parse->error = b_false;
00113 parse->error_bailout = b_false;
00114
00115 lex_next(parse->lex);
00116 }
00117
00133 void parse_module(parse_t *parse)
00134 {
00135 stree_csi_t *csi;
00136 stree_enum_t *enum_d;
00137 stree_modm_t *modm;
00138
00139 while (lcur_lc(parse) != lc_eof && !parse_is_error(parse)) {
00140 switch (lcur_lc(parse)) {
00141 case lc_class:
00142 case lc_struct:
00143 case lc_interface:
00144 csi = parse_csi(parse, lcur_lc(parse), NULL);
00145 modm = stree_modm_new(mc_csi);
00146 modm->u.csi = csi;
00147
00148 list_append(&parse->cur_mod->members, modm);
00149 break;
00150 case lc_enum:
00151 enum_d = parse_enum(parse, NULL);
00152 modm = stree_modm_new(mc_enum);
00153 modm->u.enum_d = enum_d;
00154
00155 list_append(&parse->cur_mod->members, modm);
00156 break;
00157 default:
00158 lunexpected_error(parse);
00159 lex_next(parse->lex);
00160 break;
00161 }
00162
00163 }
00164 }
00165
00173 static stree_csi_t *parse_csi(parse_t *parse, lclass_t dclass,
00174 stree_csi_t *outer_csi)
00175 {
00176 stree_csi_t *csi;
00177 csi_class_t cc;
00178 stree_csimbr_t *csimbr;
00179 stree_symbol_t *symbol;
00180 stree_ident_t *targ_name;
00181 stree_targ_t *targ;
00182 stree_texpr_t *pref;
00183
00184 switch (dclass) {
00185 case lc_class: cc = csi_class; break;
00186 case lc_struct: cc = csi_struct; break;
00187 case lc_interface: cc = csi_interface; break;
00188 default: assert(b_false);
00189 }
00190
00191 lskip(parse);
00192
00193 csi = stree_csi_new(cc);
00194 csi->name = parse_ident(parse);
00195
00196 list_init(&csi->targ);
00197
00198 while (lcur_lc(parse) == lc_slash) {
00199 lskip(parse);
00200 targ_name = parse_ident(parse);
00201
00202 targ = stree_targ_new();
00203 targ->name = targ_name;
00204
00205 list_append(&csi->targ, targ);
00206 }
00207
00208 symbol = stree_symbol_new(sc_csi);
00209 symbol->u.csi = csi;
00210 symbol->outer_csi = outer_csi;
00211 csi->symbol = symbol;
00212
00213 #ifdef DEBUG_PARSE_TRACE
00214 printf("parse_csi: csi=%p, csi->name = %p (%s)\n", csi, csi->name,
00215 strtab_get_str(csi->name->sid));
00216 #endif
00217 if (lcur_lc(parse) == lc_colon) {
00218
00219 lskip(parse);
00220
00221 while (b_true) {
00222 pref = parse_texpr(parse);
00223 if (parse_is_error(parse))
00224 break;
00225
00226 list_append(&csi->inherit, pref);
00227 if (lcur_lc(parse) != lc_plus)
00228 break;
00229
00230 lskip(parse);
00231 }
00232 }
00233
00234 lmatch(parse, lc_is);
00235 list_init(&csi->members);
00236
00237
00238 while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
00239 csimbr = parse_csimbr(parse, csi);
00240 if (csimbr == NULL)
00241 continue;
00242
00243 list_append(&csi->members, csimbr);
00244 }
00245
00246 lmatch(parse, lc_end);
00247
00248 if (outer_csi != NULL) {
00249 switch (outer_csi->cc) {
00250 case csi_class:
00251 case csi_struct:
00252 break;
00253 case csi_interface:
00254 cspan_print(csi->name->cspan);
00255 printf(" Error: CSI declared inside interface.\n");
00256 parse_note_error(parse);
00257
00258 return NULL;
00259 }
00260 }
00261
00262 return csi;
00263 }
00264
00272 static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi)
00273 {
00274 stree_csimbr_t *csimbr;
00275
00276 stree_csi_t *csi;
00277 stree_ctor_t *ctor;
00278 stree_deleg_t *deleg;
00279 stree_enum_t *enum_d;
00280 stree_fun_t *fun;
00281 stree_var_t *var;
00282 stree_prop_t *prop;
00283
00284 csimbr = NULL;
00285
00286 switch (lcur_lc(parse)) {
00287 case lc_class:
00288 case lc_struct:
00289 case lc_interface:
00290 csi = parse_csi(parse, lcur_lc(parse), outer_csi);
00291 if (csi != NULL) {
00292 csimbr = stree_csimbr_new(csimbr_csi);
00293 csimbr->u.csi = csi;
00294 }
00295 break;
00296 case lc_new:
00297 ctor = parse_ctor(parse, outer_csi);
00298 if (ctor != NULL) {
00299 csimbr = stree_csimbr_new(csimbr_ctor);
00300 csimbr->u.ctor = ctor;
00301 }
00302 break;
00303 case lc_deleg:
00304 deleg = parse_deleg(parse, outer_csi);
00305 if (deleg != NULL) {
00306 csimbr = stree_csimbr_new(csimbr_deleg);
00307 csimbr->u.deleg = deleg;
00308 }
00309 break;
00310 case lc_enum:
00311 enum_d = parse_enum(parse, outer_csi);
00312 if (enum_d != NULL) {
00313 csimbr = stree_csimbr_new(csimbr_enum);
00314 csimbr->u.enum_d = enum_d;
00315 }
00316 break;
00317 case lc_fun:
00318 fun = parse_fun(parse, outer_csi);
00319 csimbr = stree_csimbr_new(csimbr_fun);
00320 csimbr->u.fun = fun;
00321 break;
00322 case lc_var:
00323 var = parse_var(parse, outer_csi);
00324 if (var != NULL) {
00325 csimbr = stree_csimbr_new(csimbr_var);
00326 csimbr->u.var = var;
00327 }
00328 break;
00329 case lc_prop:
00330 prop = parse_prop(parse, outer_csi);
00331 csimbr = stree_csimbr_new(csimbr_prop);
00332 csimbr->u.prop = prop;
00333 break;
00334 default:
00335 lunexpected_error(parse);
00336 lex_next(parse->lex);
00337 break;
00338 }
00339
00340 return csimbr;
00341 }
00342
00349 static stree_ctor_t *parse_ctor(parse_t *parse, stree_csi_t *outer_csi)
00350 {
00351 stree_ctor_t *ctor;
00352 stree_symbol_t *symbol;
00353 cspan_t *cspan;
00354
00355 ctor = stree_ctor_new();
00356 symbol = stree_symbol_new(sc_ctor);
00357
00358 symbol->u.ctor = ctor;
00359 symbol->outer_csi = outer_csi;
00360 ctor->symbol = symbol;
00361
00362 lmatch(parse, lc_new);
00363 cspan = lprev_span(parse);
00364
00365
00366 ctor->name = stree_ident_new();
00367 ctor->name->sid = strtab_get_sid(CTOR_IDENT);
00368 ctor->name->cspan = lprev_span(parse);
00369
00370 #ifdef DEBUG_PARSE_TRACE
00371 printf("Parsing constructor of CSI '");
00372 symbol_print_fqn(csi_to_symbol(outer_csi));
00373 printf("'.\n");
00374 #endif
00375 ctor->sig = parse_fun_sig(parse);
00376 if (ctor->sig->rtype != NULL) {
00377 cspan_print(cspan);
00378 printf(" Error: Constructor of CSI '");
00379 symbol_print_fqn(csi_to_symbol(outer_csi));
00380 printf("' has a return type.\n");
00381 parse_note_error(parse);
00382 }
00383
00384
00385 parse_symbol_attrs(parse, symbol);
00386
00387 ctor->proc = stree_proc_new();
00388 ctor->proc->outer_symbol = symbol;
00389
00390 if (lcur_lc(parse) == lc_scolon) {
00391 lskip(parse);
00392
00393
00394 cspan_print(cspan);
00395 printf(" Error: Constructor of CSI '");
00396 symbol_print_fqn(csi_to_symbol(outer_csi));
00397 printf("' has no body.\n");
00398 parse_note_error(parse);
00399
00400 ctor->proc->body = NULL;
00401 } else {
00402 lmatch(parse, lc_is);
00403 ctor->proc->body = parse_block(parse);
00404 lmatch(parse, lc_end);
00405 }
00406
00407 switch (outer_csi->cc) {
00408 case csi_class:
00409 case csi_struct:
00410 break;
00411 case csi_interface:
00412 cspan_print(ctor->name->cspan);
00413 printf(" Error: Constructor declared inside interface.\n");
00414 parse_note_error(parse);
00415
00416 return NULL;
00417 }
00418
00419 return ctor;
00420 }
00421
00428 static stree_enum_t *parse_enum(parse_t *parse, stree_csi_t *outer_csi)
00429 {
00430 stree_enum_t *enum_d;
00431 stree_symbol_t *symbol;
00432 stree_embr_t *embr;
00433
00434 enum_d = stree_enum_new();
00435 symbol = stree_symbol_new(sc_enum);
00436
00437 symbol->u.enum_d = enum_d;
00438 symbol->outer_csi = outer_csi;
00439 enum_d->symbol = symbol;
00440
00441 lmatch(parse, lc_enum);
00442 enum_d->name = parse_ident(parse);
00443 list_init(&enum_d->members);
00444
00445 #ifdef DEBUG_PARSE_TRACE
00446 printf("Parse enum '%s'.\n", strtab_get_str(enum_d->name->sid));
00447 #endif
00448 lmatch(parse, lc_is);
00449
00450
00451 while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
00452 embr = parse_embr(parse, enum_d);
00453 if (embr == NULL)
00454 break;
00455
00456 list_append(&enum_d->members, embr);
00457 }
00458
00459 if (list_is_empty(&enum_d->members)) {
00460 cspan_print(enum_d->name->cspan);
00461 printf("Error: Enum type '%s' has no members.\n",
00462 strtab_get_str(enum_d->name->sid));
00463 parse_note_error(parse);
00464 }
00465
00466 lmatch(parse, lc_end);
00467
00468 if (outer_csi != NULL) {
00469 switch (outer_csi->cc) {
00470 case csi_class:
00471 case csi_struct:
00472 break;
00473 case csi_interface:
00474 cspan_print(enum_d->name->cspan);
00475 printf(" Error: Enum declared inside interface.\n");
00476 parse_note_error(parse);
00477
00478 return NULL;
00479 }
00480 }
00481
00482 return enum_d;
00483 }
00484
00492 static stree_embr_t *parse_embr(parse_t *parse, stree_enum_t *outer_enum)
00493 {
00494 stree_embr_t *embr;
00495
00496 embr = stree_embr_new();
00497 embr->outer_enum = outer_enum;
00498 embr->name = parse_ident(parse);
00499
00500 lmatch(parse, lc_scolon);
00501
00502 return embr;
00503 }
00504
00511 static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi)
00512 {
00513 stree_deleg_t *deleg;
00514 stree_symbol_t *symbol;
00515
00516 deleg = stree_deleg_new();
00517 symbol = stree_symbol_new(sc_deleg);
00518
00519 symbol->u.deleg = deleg;
00520 symbol->outer_csi = outer_csi;
00521 deleg->symbol = symbol;
00522
00523 lmatch(parse, lc_deleg);
00524 deleg->name = parse_ident(parse);
00525
00526 #ifdef DEBUG_PARSE_TRACE
00527 printf("Parsing delegate '%s'.\n", strtab_get_str(deleg->name->sid));
00528 #endif
00529
00530 deleg->sig = parse_fun_sig(parse);
00531
00532
00533 parse_symbol_attrs(parse, symbol);
00534
00535 lmatch(parse, lc_scolon);
00536
00537 switch (outer_csi->cc) {
00538 case csi_class:
00539 case csi_struct:
00540 break;
00541 case csi_interface:
00542 cspan_print(deleg->name->cspan);
00543 printf(" Error: Delegate declared inside interface.\n");
00544 parse_note_error(parse);
00545
00546 return NULL;
00547 }
00548
00549 return deleg;
00550 }
00551
00558 static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi)
00559 {
00560 stree_fun_t *fun;
00561 stree_symbol_t *symbol;
00562 bool_t body_expected;
00563
00564 fun = stree_fun_new();
00565 symbol = stree_symbol_new(sc_fun);
00566
00567 symbol->u.fun = fun;
00568 symbol->outer_csi = outer_csi;
00569 fun->symbol = symbol;
00570
00571 lmatch(parse, lc_fun);
00572 fun->name = parse_ident(parse);
00573
00574 #ifdef DEBUG_PARSE_TRACE
00575 printf("Parsing function '%s'.\n", strtab_get_str(fun->name->sid));
00576 #endif
00577 fun->sig = parse_fun_sig(parse);
00578
00579
00580 parse_symbol_attrs(parse, symbol);
00581
00582 body_expected = !stree_symbol_has_attr(symbol, sac_builtin) &&
00583 (outer_csi->cc != csi_interface);
00584
00585 fun->proc = stree_proc_new();
00586 fun->proc->outer_symbol = symbol;
00587
00588 if (lcur_lc(parse) == lc_scolon) {
00589 lskip(parse);
00590
00591
00592 if (body_expected) {
00593 cspan_print(fun->name->cspan);
00594 printf(" Error: Function '");
00595 symbol_print_fqn(symbol);
00596 printf("' should have a body.\n");
00597 parse_note_error(parse);
00598 }
00599
00600 fun->proc->body = NULL;
00601 } else {
00602 lmatch(parse, lc_is);
00603 fun->proc->body = parse_block(parse);
00604 lmatch(parse, lc_end);
00605
00606
00607 if (!body_expected) {
00608 cspan_print(fun->name->cspan);
00609 printf(" Error: Function declaration '");
00610 symbol_print_fqn(symbol);
00611 printf("' should not have a body.\n");
00612 parse_note_error(parse);
00613 }
00614 }
00615
00616 return fun;
00617 }
00618
00625 static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi)
00626 {
00627 stree_var_t *var;
00628 stree_symbol_t *symbol;
00629
00630 var = stree_var_new();
00631 symbol = stree_symbol_new(sc_var);
00632 symbol->u.var = var;
00633 symbol->outer_csi = outer_csi;
00634 var->symbol = symbol;
00635
00636 lmatch(parse, lc_var);
00637 var->name = parse_ident(parse);
00638 lmatch(parse, lc_colon);
00639 var->type = parse_texpr(parse);
00640
00641 parse_symbol_attrs(parse, symbol);
00642
00643 lmatch(parse, lc_scolon);
00644
00645 switch (outer_csi->cc) {
00646 case csi_class:
00647 case csi_struct:
00648 break;
00649 case csi_interface:
00650 cspan_print(var->name->cspan);
00651 printf(" Error: Variable declared inside interface.\n");
00652 parse_note_error(parse);
00653
00654 return NULL;
00655 }
00656
00657 return var;
00658 }
00659
00666 static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi)
00667 {
00668 stree_prop_t *prop;
00669 stree_symbol_t *symbol;
00670
00671 stree_ident_t *ident;
00672 stree_proc_arg_t *arg;
00673
00674 prop = stree_prop_new();
00675 list_init(&prop->args);
00676
00677 symbol = stree_symbol_new(sc_prop);
00678 symbol->u.prop = prop;
00679 symbol->outer_csi = outer_csi;
00680 prop->symbol = symbol;
00681
00682 lmatch(parse, lc_prop);
00683
00684 if (lcur_lc(parse) == lc_self) {
00685
00686
00687
00688 ident = stree_ident_new();
00689 ident->sid = strtab_get_sid(INDEXER_IDENT);
00690 prop->name = ident;
00691
00692 lskip(parse);
00693 lmatch(parse, lc_lsbr);
00694
00695
00696 while (!parse_is_error(parse)) {
00697 arg = parse_proc_arg(parse);
00698 if (stree_arg_has_attr(arg, aac_packed)) {
00699 prop->varg = arg;
00700 break;
00701 } else {
00702 list_append(&prop->args, arg);
00703 }
00704
00705 if (lcur_lc(parse) == lc_rsbr)
00706 break;
00707
00708 lmatch(parse, lc_scolon);
00709 }
00710
00711 lmatch(parse, lc_rsbr);
00712 } else {
00713
00714 prop->name = parse_ident(parse);
00715 }
00716
00717 lmatch(parse, lc_colon);
00718 prop->type = parse_texpr(parse);
00719
00720
00721 parse_symbol_attrs(parse, symbol);
00722
00723 lmatch(parse, lc_is);
00724
00725 while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
00726 switch (lcur_lc(parse)) {
00727 case lc_get:
00728 parse_prop_get(parse, prop);
00729 break;
00730 case lc_set:
00731 parse_prop_set(parse, prop);
00732 break;
00733 default:
00734 lunexpected_error(parse);
00735 }
00736 }
00737
00738 lmatch(parse, lc_end);
00739
00740 return prop;
00741 }
00742
00750 static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol)
00751 {
00752 stree_symbol_attr_t *attr;
00753
00754
00755 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
00756 lskip(parse);
00757 attr = parse_symbol_attr(parse);
00758 list_append(&symbol->attr, attr);
00759 }
00760 }
00761
00767 static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse)
00768 {
00769 stree_symbol_attr_t *attr;
00770 symbol_attr_class_t sac;
00771
00772
00773 sac = 0;
00774
00775 switch (lcur_lc(parse)) {
00776 case lc_builtin: sac = sac_builtin; break;
00777 case lc_static: sac = sac_static; break;
00778 default:
00779 cspan_print(lcur_span(parse));
00780 printf(" Error: Unexpected attribute '");
00781 lem_print(lcur(parse));
00782 printf("'.\n");
00783 parse_note_error(parse);
00784 break;
00785 }
00786
00787 lskip(parse);
00788
00789 attr = stree_symbol_attr_new(sac);
00790 return attr;
00791 }
00792
00798 static stree_proc_arg_t *parse_proc_arg(parse_t *parse)
00799 {
00800 stree_proc_arg_t *arg;
00801 stree_arg_attr_t *attr;
00802
00803 arg = stree_proc_arg_new();
00804 arg->name = parse_ident(parse);
00805 lmatch(parse, lc_colon);
00806 arg->type = parse_texpr(parse);
00807
00808 #ifdef DEBUG_PARSE_TRACE
00809 printf("Parse procedure argument.\n");
00810 #endif
00811 list_init(&arg->attr);
00812
00813
00814 while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
00815 lskip(parse);
00816 attr = parse_arg_attr(parse);
00817 list_append(&arg->attr, attr);
00818 }
00819
00820 return arg;
00821 }
00822
00828 static stree_arg_attr_t *parse_arg_attr(parse_t *parse)
00829 {
00830 stree_arg_attr_t *attr;
00831
00832 if (lcur_lc(parse) != lc_packed) {
00833 cspan_print(lcur_span(parse));
00834 printf(" Error: Unexpected attribute '");
00835 lem_print(lcur(parse));
00836 printf("'.\n");
00837 parse_note_error(parse);
00838 }
00839
00840 lskip(parse);
00841
00842 attr = stree_arg_attr_new(aac_packed);
00843 return attr;
00844 }
00845
00851 static stree_fun_sig_t *parse_fun_sig(parse_t *parse)
00852 {
00853 stree_fun_sig_t *sig;
00854 stree_proc_arg_t *arg;
00855
00856 sig = stree_fun_sig_new();
00857
00858 lmatch(parse, lc_lparen);
00859
00860 #ifdef DEBUG_PARSE_TRACE
00861 printf("Parsing function signature.\n");
00862 #endif
00863
00864 list_init(&sig->args);
00865
00866 if (lcur_lc(parse) != lc_rparen) {
00867
00868
00869 while (!parse_is_error(parse)) {
00870 arg = parse_proc_arg(parse);
00871
00872 if (stree_arg_has_attr(arg, aac_packed)) {
00873 sig->varg = arg;
00874 break;
00875 } else {
00876 list_append(&sig->args, arg);
00877 }
00878
00879 if (lcur_lc(parse) == lc_rparen)
00880 break;
00881
00882 lmatch(parse, lc_scolon);
00883 }
00884 }
00885
00886 lmatch(parse, lc_rparen);
00887
00888 if (lcur_lc(parse) == lc_colon) {
00889 lskip(parse);
00890 sig->rtype = parse_texpr(parse);
00891 } else {
00892 sig->rtype = NULL;
00893 }
00894
00895 return sig;
00896 }
00897
00903 static void parse_prop_get(parse_t *parse, stree_prop_t *prop)
00904 {
00905 cspan_t *cspan;
00906 stree_block_t *block;
00907 stree_proc_t *getter;
00908 bool_t body_expected;
00909
00910 body_expected = (prop->symbol->outer_csi->cc != csi_interface);
00911
00912 lskip(parse);
00913 cspan = lprev_span(parse);
00914
00915 if (prop->getter != NULL) {
00916 cspan_print(cspan);
00917 printf(" Error: Duplicate getter.\n");
00918 parse_note_error(parse);
00919 return;
00920 }
00921
00922 if (lcur_lc(parse) == lc_scolon) {
00923
00924 lskip(parse);
00925 block = NULL;
00926
00927 if (body_expected) {
00928 cspan_print(prop->name->cspan);
00929 printf(" Error: Property '");
00930 symbol_print_fqn(prop->symbol);
00931 printf("' getter should have "
00932 "a body.\n");
00933 parse_note_error(parse);
00934 }
00935 } else {
00936
00937 lmatch(parse, lc_is);
00938 block = parse_block(parse);
00939 lmatch(parse, lc_end);
00940
00941 if (!body_expected) {
00942 cspan_print(prop->name->cspan);
00943 printf(" Error: Property '");
00944 symbol_print_fqn(prop->symbol);
00945 printf("' getter declaration should "
00946 "not have a body.\n");
00947 parse_note_error(parse);
00948
00949
00950 block = NULL;
00951 }
00952 }
00953
00954
00955 getter = stree_proc_new();
00956 getter->body = block;
00957 getter->outer_symbol = prop->symbol;
00958
00959
00960 prop->getter = getter;
00961 }
00962
00963
00969 static void parse_prop_set(parse_t *parse, stree_prop_t *prop)
00970 {
00971 cspan_t *cspan;
00972 stree_block_t *block;
00973 stree_proc_t *setter;
00974 bool_t body_expected;
00975
00976 body_expected = (prop->symbol->outer_csi->cc != csi_interface);
00977
00978 lskip(parse);
00979 cspan = lprev_span(parse);
00980
00981 if (prop->setter != NULL) {
00982 cspan_print(cspan);
00983 printf(" Error: Duplicate setter.\n");
00984 parse_note_error(parse);
00985 return;
00986 }
00987
00988 prop->setter_arg = stree_proc_arg_new();
00989 prop->setter_arg->name = parse_ident(parse);
00990 prop->setter_arg->type = prop->type;
00991
00992 if (lcur_lc(parse) == lc_scolon) {
00993
00994 lskip(parse);
00995
00996 block = NULL;
00997
00998 if (body_expected) {
00999 cspan_print(prop->name->cspan);
01000 printf(" Error: Property '");
01001 symbol_print_fqn(prop->symbol);
01002 printf("' setter should have "
01003 "a body.\n");
01004 parse_note_error(parse);
01005 }
01006 } else {
01007
01008 lmatch(parse, lc_is);
01009 block = parse_block(parse);
01010 lmatch(parse, lc_end);
01011
01012 if (!body_expected) {
01013 cspan_print(prop->name->cspan);
01014 printf(" Error: Property '");
01015 symbol_print_fqn(prop->symbol);
01016 printf("' setter declaration should "
01017 "not have a body.\n");
01018 parse_note_error(parse);
01019 }
01020 }
01021
01022
01023
01024 setter = stree_proc_new();
01025 setter->body = block;
01026 setter->outer_symbol = prop->symbol;
01027
01028
01029 prop->setter = setter;
01030 }
01031
01037 static stree_block_t *parse_block(parse_t *parse)
01038 {
01039 stree_block_t *block;
01040 stree_stat_t *stat;
01041
01042 block = stree_block_new();
01043 list_init(&block->stats);
01044
01045
01046 if (parse_is_error(parse))
01047 return block;
01048
01049 while (terminates_block(lcur_lc(parse)) != b_true &&
01050 !parse_is_error(parse)) {
01051
01052 stat = parse_stat(parse);
01053 list_append(&block->stats, stat);
01054 }
01055
01056 return block;
01057 }
01058
01064 stree_stat_t *parse_stat(parse_t *parse)
01065 {
01066 stree_stat_t *stat;
01067
01068 stree_vdecl_t *vdecl_s;
01069 stree_if_t *if_s;
01070 stree_switch_t *switch_s;
01071 stree_while_t *while_s;
01072 stree_for_t *for_s;
01073 stree_raise_t *raise_s;
01074 stree_break_t *break_s;
01075 stree_return_t *return_s;
01076 stree_wef_t *wef_s;
01077 stree_exps_t *exp_s;
01078
01079 #ifdef DEBUG_PARSE_TRACE
01080 printf("Parse statement.\n");
01081 #endif
01082 switch (lcur_lc(parse)) {
01083 case lc_var:
01084 vdecl_s = parse_vdecl(parse);
01085 stat = stree_stat_new(st_vdecl);
01086 stat->u.vdecl_s = vdecl_s;
01087 break;
01088 case lc_if:
01089 if_s = parse_if(parse);
01090 stat = stree_stat_new(st_if);
01091 stat->u.if_s = if_s;
01092 break;
01093 case lc_switch:
01094 switch_s = parse_switch(parse);
01095 stat = stree_stat_new(st_switch);
01096 stat->u.switch_s = switch_s;
01097 break;
01098 case lc_while:
01099 while_s = parse_while(parse);
01100 stat = stree_stat_new(st_while);
01101 stat->u.while_s = while_s;
01102 break;
01103 case lc_for:
01104 for_s = parse_for(parse);
01105 stat = stree_stat_new(st_for);
01106 stat->u.for_s = for_s;
01107 break;
01108 case lc_raise:
01109 raise_s = parse_raise(parse);
01110 stat = stree_stat_new(st_raise);
01111 stat->u.raise_s = raise_s;
01112 break;
01113 case lc_break:
01114 break_s = parse_break(parse);
01115 stat = stree_stat_new(st_break);
01116 stat->u.break_s = break_s;
01117 break;
01118 case lc_return:
01119 return_s = parse_return(parse);
01120 stat = stree_stat_new(st_return);
01121 stat->u.return_s = return_s;
01122 break;
01123 case lc_do:
01124 case lc_with:
01125 wef_s = parse_wef(parse);
01126 stat = stree_stat_new(st_wef);
01127 stat->u.wef_s = wef_s;
01128 break;
01129 default:
01130 exp_s = parse_exps(parse);
01131 stat = stree_stat_new(st_exps);
01132 stat->u.exp_s = exp_s;
01133 break;
01134 }
01135
01136 #ifdef DEBUG_PARSE_TRACE
01137 printf("Parsed statement %p\n", stat);
01138 #endif
01139 return stat;
01140 }
01141
01147 static stree_vdecl_t *parse_vdecl(parse_t *parse)
01148 {
01149 stree_vdecl_t *vdecl;
01150
01151 vdecl = stree_vdecl_new();
01152
01153 lmatch(parse, lc_var);
01154 vdecl->name = parse_ident(parse);
01155 lmatch(parse, lc_colon);
01156 vdecl->type = parse_texpr(parse);
01157
01158 if (lcur_lc(parse) == lc_assign) {
01159 lskip(parse);
01160 (void) parse_expr(parse);
01161 }
01162
01163 lmatch(parse, lc_scolon);
01164
01165 #ifdef DEBUG_PARSE_TRACE
01166 printf("Parsed vdecl for '%s'\n", strtab_get_str(vdecl->name->sid));
01167 printf("vdecl = %p, vdecl->name = %p, sid=%d\n",
01168 vdecl, vdecl->name, vdecl->name->sid);
01169 #endif
01170 return vdecl;
01171 }
01172
01178 static stree_if_t *parse_if(parse_t *parse)
01179 {
01180 stree_if_t *if_s;
01181 stree_if_clause_t *if_c;
01182
01183 #ifdef DEBUG_PARSE_TRACE
01184 printf("Parse 'if' statement.\n");
01185 #endif
01186 if_s = stree_if_new();
01187 list_init(&if_s->if_clauses);
01188
01189
01190 lmatch(parse, lc_if);
01191
01192 if_c = stree_if_clause_new();
01193 if_c->cond = parse_expr(parse);
01194 lmatch(parse, lc_then);
01195 if_c->block = parse_block(parse);
01196
01197 list_append(&if_s->if_clauses, if_c);
01198
01199
01200 while (lcur_lc(parse) == lc_elif) {
01201 lskip(parse);
01202 if_c = stree_if_clause_new();
01203 if_c->cond = parse_expr(parse);
01204 lmatch(parse, lc_then);
01205 if_c->block = parse_block(parse);
01206
01207 list_append(&if_s->if_clauses, if_c);
01208 }
01209
01210
01211 if (lcur_lc(parse) == lc_else) {
01212 lskip(parse);
01213 if_s->else_block = parse_block(parse);
01214 } else {
01215 if_s->else_block = NULL;
01216 }
01217
01218 lmatch(parse, lc_end);
01219 return if_s;
01220 }
01221
01227 static stree_switch_t *parse_switch(parse_t *parse)
01228 {
01229 stree_switch_t *switch_s;
01230 stree_when_t *when_c;
01231 stree_expr_t *expr;
01232
01233 #ifdef DEBUG_PARSE_TRACE
01234 printf("Parse 'switch' statement.\n");
01235 #endif
01236 lmatch(parse, lc_switch);
01237
01238 switch_s = stree_switch_new();
01239 list_init(&switch_s->when_clauses);
01240
01241 switch_s->expr = parse_expr(parse);
01242 lmatch(parse, lc_is);
01243
01244
01245 while (lcur_lc(parse) == lc_when) {
01246 lskip(parse);
01247 when_c = stree_when_new();
01248 list_init(&when_c->exprs);
01249 while (b_true) {
01250 expr = parse_expr(parse);
01251 list_append(&when_c->exprs, expr);
01252 if (lcur_lc(parse) != lc_comma)
01253 break;
01254 lskip(parse);
01255 }
01256
01257 lmatch(parse, lc_do);
01258 when_c->block = parse_block(parse);
01259
01260 list_append(&switch_s->when_clauses, when_c);
01261 }
01262
01263
01264 if (lcur_lc(parse) == lc_else) {
01265 lskip(parse);
01266 lmatch(parse, lc_do);
01267 switch_s->else_block = parse_block(parse);
01268 } else {
01269 switch_s->else_block = NULL;
01270 }
01271
01272 lmatch(parse, lc_end);
01273 return switch_s;
01274 }
01275
01280 static stree_while_t *parse_while(parse_t *parse)
01281 {
01282 stree_while_t *while_s;
01283
01284 #ifdef DEBUG_PARSE_TRACE
01285 printf("Parse 'while' statement.\n");
01286 #endif
01287 while_s = stree_while_new();
01288
01289 lmatch(parse, lc_while);
01290 while_s->cond = parse_expr(parse);
01291 lmatch(parse, lc_do);
01292 while_s->body = parse_block(parse);
01293 lmatch(parse, lc_end);
01294
01295 return while_s;
01296 }
01297
01303 static stree_for_t *parse_for(parse_t *parse)
01304 {
01305 stree_for_t *for_s;
01306
01307 #ifdef DEBUG_PARSE_TRACE
01308 printf("Parse 'for' statement.\n");
01309 #endif
01310 for_s = stree_for_new();
01311
01312 lmatch(parse, lc_for);
01313 lmatch(parse, lc_ident);
01314 lmatch(parse, lc_colon);
01315 (void) parse_texpr(parse);
01316 lmatch(parse, lc_in);
01317 (void) parse_expr(parse);
01318 lmatch(parse, lc_do);
01319 for_s->body = parse_block(parse);
01320 lmatch(parse, lc_end);
01321
01322 return for_s;
01323 }
01324
01329 static stree_raise_t *parse_raise(parse_t *parse)
01330 {
01331 stree_raise_t *raise_s;
01332
01333 #ifdef DEBUG_PARSE_TRACE
01334 printf("Parse 'raise' statement.\n");
01335 #endif
01336 raise_s = stree_raise_new();
01337 lmatch(parse, lc_raise);
01338 raise_s->expr = parse_expr(parse);
01339 lmatch(parse, lc_scolon);
01340
01341 return raise_s;
01342 }
01343
01349 static stree_break_t *parse_break(parse_t *parse)
01350 {
01351 stree_break_t *break_s;
01352
01353 #ifdef DEBUG_PARSE_TRACE
01354 printf("Parse 'break' statement.\n");
01355 #endif
01356 break_s = stree_break_new();
01357
01358 lmatch(parse, lc_break);
01359 lmatch(parse, lc_scolon);
01360
01361 return break_s;
01362 }
01363
01369 static stree_return_t *parse_return(parse_t *parse)
01370 {
01371 stree_return_t *return_s;
01372
01373 #ifdef DEBUG_PARSE_TRACE
01374 printf("Parse 'return' statement.\n");
01375 #endif
01376 return_s = stree_return_new();
01377
01378 lmatch(parse, lc_return);
01379
01380 if (lcur_lc(parse) != lc_scolon)
01381 return_s->expr = parse_expr(parse);
01382
01383 lmatch(parse, lc_scolon);
01384
01385 return return_s;
01386 }
01387
01388
01389
01390
01391
01392
01393 static stree_wef_t *parse_wef(parse_t *parse)
01394 {
01395 stree_wef_t *wef_s;
01396 stree_except_t *except_c;
01397
01398 #ifdef DEBUG_PARSE_TRACE
01399 printf("Parse WEF statement.\n");
01400 #endif
01401 wef_s = stree_wef_new();
01402 list_init(&wef_s->except_clauses);
01403
01404 if (lcur_lc(parse) == lc_with) {
01405 lmatch(parse, lc_with);
01406 lmatch(parse, lc_ident);
01407 lmatch(parse, lc_colon);
01408 (void) parse_texpr(parse);
01409 lmatch(parse, lc_assign);
01410 (void) parse_expr(parse);
01411 }
01412
01413 lmatch(parse, lc_do);
01414 wef_s->with_block = parse_block(parse);
01415
01416 while (lcur_lc(parse) == lc_except && !parse_is_error(parse)) {
01417 except_c = parse_except(parse);
01418 list_append(&wef_s->except_clauses, except_c);
01419 }
01420
01421 if (lcur_lc(parse) == lc_finally) {
01422 lmatch(parse, lc_finally);
01423 lmatch(parse, lc_do);
01424 wef_s->finally_block = parse_block(parse);
01425 } else {
01426 wef_s->finally_block = NULL;
01427 }
01428
01429 lmatch(parse, lc_end);
01430
01431 return wef_s;
01432 }
01433
01434
01435
01436
01437
01438
01439 static stree_exps_t *parse_exps(parse_t *parse)
01440 {
01441 stree_expr_t *expr;
01442 stree_exps_t *exps;
01443
01444 #ifdef DEBUG_PARSE_TRACE
01445 printf("Parse expression statement.\n");
01446 #endif
01447 expr = parse_expr(parse);
01448 lmatch(parse, lc_scolon);
01449
01450 exps = stree_exps_new();
01451 exps->expr = expr;
01452
01453 return exps;
01454 }
01455
01456
01457
01458
01459
01460
01461 static stree_except_t *parse_except(parse_t *parse)
01462 {
01463 stree_except_t *except_c;
01464
01465 #ifdef DEBUG_PARSE_TRACE
01466 printf("Parse 'except' statement.\n");
01467 #endif
01468 except_c = stree_except_new();
01469
01470 lmatch(parse, lc_except);
01471 except_c->evar = parse_ident(parse);
01472 lmatch(parse, lc_colon);
01473 except_c->etype = parse_texpr(parse);
01474 lmatch(parse, lc_do);
01475
01476 except_c->block = parse_block(parse);
01477
01478 return except_c;
01479 }
01480
01486 stree_ident_t *parse_ident(parse_t *parse)
01487 {
01488 stree_ident_t *ident;
01489
01490 #ifdef DEBUG_PARSE_TRACE
01491 printf("Parse identifier.\n");
01492 #endif
01493 lcheck(parse, lc_ident);
01494 ident = stree_ident_new();
01495 ident->sid = lcur(parse)->u.ident.sid;
01496 ident->cspan = lcur_span(parse);
01497 lskip(parse);
01498
01499 return ident;
01500 }
01501
01506 void parse_raise_error(parse_t *parse)
01507 {
01508 parse->error = b_true;
01509 parse->error_bailout = b_true;
01510 }
01511
01516 void parse_note_error(parse_t *parse)
01517 {
01518 parse->error = b_true;
01519 }
01520
01525 bool_t parse_is_error(parse_t *parse)
01526 {
01527 return parse->error_bailout;
01528 }
01529
01536 void parse_recover_error(parse_t *parse)
01537 {
01538 assert(parse->error == b_true);
01539 assert(parse->error_bailout == b_true);
01540
01541 parse->error_bailout = b_false;
01542 }
01543
01550 lem_t *lcur(parse_t *parse)
01551 {
01552 #ifdef DEBUG_LPARSE_TRACE
01553 printf("lcur()\n");
01554 #endif
01555 return lex_get_current(parse->lex);
01556 }
01557
01563 lclass_t lcur_lc(parse_t *parse)
01564 {
01565 lem_t *lem;
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575 if (parse_is_error(parse))
01576 return lc_invalid;
01577
01578 lem = lcur(parse);
01579 return lem->lclass;
01580 }
01581
01588 cspan_t *lcur_span(parse_t *parse)
01589 {
01590 lem_t *lem;
01591
01592 if (parse_is_error(parse))
01593 return NULL;
01594
01595 lem = lcur(parse);
01596 return lem->cspan;
01597 }
01598
01606 cspan_t *lprev_span(parse_t *parse)
01607 {
01608 lem_t *lem;
01609
01610 if (parse_is_error(parse))
01611 return NULL;
01612
01613 lem = lex_peek_prev(parse->lex);
01614 if (lem == NULL)
01615 return NULL;
01616
01617 return lem->cspan;
01618 }
01619
01624 void lskip(parse_t *parse)
01625 {
01626 #ifdef DEBUG_LPARSE_TRACE
01627 printf("lskip()\n");
01628 #endif
01629 lex_next(parse->lex);
01630 }
01631
01640 void lcheck(parse_t *parse, lclass_t lc)
01641 {
01642 #ifdef DEBUG_LPARSE_TRACE
01643 printf("lcheck(");
01644 lclass_print(lc);
01645 printf(")\n");
01646 #endif
01647 if (lcur(parse)->lclass != lc) {
01648 lem_print_coords(lcur(parse));
01649 printf(" Error: expected '"); lclass_print(lc);
01650 printf("', got '"); lem_print(lcur(parse));
01651 printf("'.\n");
01652 parse_raise_error(parse);
01653 }
01654 }
01655
01664 void lmatch(parse_t *parse, lclass_t lc)
01665 {
01666 #ifdef DEBUG_LPARSE_TRACE
01667 printf("lmatch(");
01668 lclass_print(lc);
01669 printf(")\n");
01670 #endif
01671
01672
01673
01674
01675
01676
01677
01678
01679 if (parse_is_error(parse))
01680 return;
01681
01682 lcheck(parse, lc);
01683 lskip(parse);
01684 }
01685
01690 void lunexpected_error(parse_t *parse)
01691 {
01692 lem_print_coords(lcur(parse));
01693 printf(" Error: unexpected token '");
01694 lem_print(lcur(parse));
01695 printf("'.\n");
01696 parse_raise_error(parse);
01697 }
01698
01706 bool_t terminates_block(lclass_t lclass)
01707 {
01708 switch (lclass) {
01709 case lc_elif:
01710 case lc_else:
01711 case lc_end:
01712 case lc_except:
01713 case lc_finally:
01714 case lc_when:
01715 return b_true;
01716 default:
01717 return b_false;
01718 }
01719 }