mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[qfcc] Implement goto
It's just too useful when used correctly.
This commit is contained in:
parent
4a8854d9ed
commit
813319efc2
3 changed files with 19 additions and 7 deletions
|
@ -353,6 +353,7 @@ static keyword_t obj_keywords[] = {
|
|||
// make the language features available to traditional code.
|
||||
static keyword_t at_keywords[] = {
|
||||
{"for", FOR },
|
||||
{"goto", GOTO },
|
||||
{"break", BREAK },
|
||||
{"continue", CONTINUE},
|
||||
{"switch", SWITCH },
|
||||
|
|
|
@ -145,8 +145,8 @@ int yylex (void);
|
|||
%token <expr> VALUE STRING
|
||||
|
||||
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS
|
||||
%token NIL IFBE IFB IFAE IFA SWITCH CASE DEFAULT ENUM TYPEDEF
|
||||
%token ARGS EXTERN STATIC SYSTEM NOSAVE OVERLOAD NOT
|
||||
%token NIL IFBE IFB IFAE IFA GOTO SWITCH CASE DEFAULT ENUM
|
||||
%token ARGS TYPEDEF EXTERN STATIC SYSTEM NOSAVE OVERLOAD NOT
|
||||
%token <op> STRUCT
|
||||
%token <type> TYPE
|
||||
%token <symbol> OBJECT TYPE_NAME
|
||||
|
@ -1310,6 +1310,11 @@ statement
|
|||
switch_block = $5;
|
||||
break_label = $2;
|
||||
}
|
||||
| GOTO NAME
|
||||
{
|
||||
expr_t *label = named_label_expr ($2);
|
||||
$$ = goto_expr (label);
|
||||
}
|
||||
| IF not '(' texpr ')' statement %prec IFX
|
||||
{
|
||||
$$ = build_if_statement ($2, $4, $6, 0, 0);
|
||||
|
|
|
@ -1551,7 +1551,7 @@ remove_label_from_dest (ex_label_t *label)
|
|||
sblock_t *sblock;
|
||||
ex_label_t **l;
|
||||
|
||||
if (!label)
|
||||
if (!label || !label->dest)
|
||||
return;
|
||||
|
||||
debug (0, "dropping deceased label %s", label->name);
|
||||
|
@ -1588,14 +1588,20 @@ thread_jumps (sblock_t *blocks)
|
|||
if (!sblock->statements)
|
||||
continue;
|
||||
s = (statement_t *) sblock->tail;
|
||||
if (statement_is_goto (s))
|
||||
if (statement_is_goto (s)) {
|
||||
label = &s->opa->o.label;
|
||||
else if (statement_is_cond (s))
|
||||
if (!(*label)->dest && s->opa->expr) {
|
||||
error (s->opa->expr, "undefined label `%s'", (*label)->name);
|
||||
s->opa->expr = 0;
|
||||
}
|
||||
} else if (statement_is_cond (s)) {
|
||||
label = &s->opb->o.label;
|
||||
else
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
for (l = *label;
|
||||
l->dest->statements && statement_is_goto (l->dest->statements);
|
||||
l->dest && l->dest->statements
|
||||
&& statement_is_goto (l->dest->statements);
|
||||
l = l->dest->statements->opa->o.label) {
|
||||
}
|
||||
if (l != *label) {
|
||||
|
|
Loading…
Reference in a new issue