diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index 5a5cab4ff..0d7f19c66 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -591,7 +591,7 @@ expr_t *incop_expr (int op, expr_t *e, int postop); expr_t *array_expr (expr_t *array, expr_t *index); expr_t *pointer_expr (expr_t *pointer); expr_t *address_expr (expr_t *e1, expr_t *e2, struct type_s *t); -expr_t *build_if_statement (expr_t *test, expr_t *s1, expr_t *s2); +expr_t *build_if_statement (expr_t *test, expr_t *s1, expr_t *els, expr_t *s2); expr_t *build_while_statement (expr_t *test, expr_t *statement, expr_t *break_label, expr_t *continue_label); expr_t *build_do_while_statement (expr_t *statement, expr_t *test, diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 6f398a963..2c0efdf41 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2250,7 +2250,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t) } expr_t * -build_if_statement (expr_t *test, expr_t *s1, expr_t *s2) +build_if_statement (expr_t *test, expr_t *s1, expr_t *els, expr_t *s2) { int line = pr.source_line; string_t file = pr.source_file; @@ -2272,6 +2272,11 @@ build_if_statement (expr_t *test, expr_t *s1, expr_t *s2) } append_expr (if_expr, s1); + if (els) { + pr.source_line = els->line; + pr.source_file = els->file; + } + if (s2) { expr_t *nl = new_label_expr (); append_expr (if_expr, goto_expr (nl)); diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 6a3cd41fe..4f1bdc732 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -183,7 +183,7 @@ int yylex (void); %type opt_expr fexpr expr element_list element %type optional_state_expr think opt_step texpr %type statement statements compound_statement -%type label break_label continue_label +%type else label break_label continue_label %type unary_expr cast_expr opt_arg_list arg_list %type switch_block %type identifier @@ -1087,11 +1087,11 @@ statement } | IF '(' texpr ')' statement %prec IFX { - $$ = build_if_statement ($3, $5, 0); + $$ = build_if_statement ($3, $5, 0, 0); } - | IF '(' texpr ')' statement ELSE statement + | IF '(' texpr ')' statement else statement { - $$ = build_if_statement ($3, $5, $7); + $$ = build_if_statement ($3, $5, $6, $7); } | FOR break_label continue_label '(' opt_expr ';' opt_expr ';' opt_expr ')' statement @@ -1120,6 +1120,14 @@ statement } ; +else + : ELSE + { + // this is only to get the the file and line number info + $$ = new_nil_expr (); + } + ; + label : /* empty */ { diff --git a/tools/qfcc/source/qp-parse.y b/tools/qfcc/source/qp-parse.y index c5f97ea9c..31652c9e2 100644 --- a/tools/qfcc/source/qp-parse.y +++ b/tools/qfcc/source/qp-parse.y @@ -133,7 +133,7 @@ int yylex (void); %type program_head identifier_list subprogram_head %type param_scope %type arguments parameter_list -%type compound_statement optional_statements statement_list +%type compound_statement else optional_statements statement_list %type statement procedure_statement %type expression_list expression unary_expr primary variable name %type sign @@ -352,13 +352,13 @@ statement } | procedure_statement | compound_statement - | IF expression THEN statement ELSE statement + | IF expression THEN statement else statement { - $$ = build_if_statement ($2, $4, $6); + $$ = build_if_statement ($2, $4, $5, $6); } | IF expression THEN statement %prec IFX { - $$ = build_if_statement ($2, $4, 0); + $$ = build_if_statement ($2, $4, 0, 0); } | WHILE expression DO statement { @@ -372,6 +372,13 @@ statement } ; +else + : ELSE + { + $$ = new_nil_expr (); + } + ; + variable : name | name '[' expression ']' { $$ = array_expr ($1, $3); }