aboutsummaryrefslogtreecommitdiff
path: root/stmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'stmt.c')
-rw-r--r--stmt.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/stmt.c b/stmt.c
index ff163bf..358f232 100644
--- a/stmt.c
+++ b/stmt.c
@@ -81,6 +81,7 @@ stmt(struct func *f, struct scope *s)
stmt(f, s);
}
s = delscope(s);
+ funcdefer(f);
next();
break;
@@ -95,6 +96,15 @@ stmt(struct func *f, struct scope *s)
expect(TSEMICOLON, "after expression statement");
break;
+ case TDEFER:
+ next();
+ funcstartdefer(f);
+ s = mkscope(s);
+ stmt(f, s);
+ s = delscope(s);
+ funcenddefer(f);
+ break;
+
/* 6.8.4 Selection statement */
case TIF:
next();
@@ -276,6 +286,7 @@ stmt(struct func *f, struct scope *s)
case TGOTO:
next();
name = expect(TIDENT, "after 'goto'");
+ //funcdefer(f);
funcjmp(f, funcgoto(f, name)->label);
expect(TSEMICOLON, "after 'goto' statement");
break;
@@ -283,6 +294,7 @@ stmt(struct func *f, struct scope *s)
next();
if (!s->continuelabel)
error(&tok.loc, "'continue' statement must be in loop");
+ funcdefer(f);
funcjmp(f, s->continuelabel);
expect(TSEMICOLON, "after 'continue' statement");
break;
@@ -290,6 +302,7 @@ stmt(struct func *f, struct scope *s)
next();
if (!s->breaklabel)
error(&tok.loc, "'break' statement must be in loop or switch");
+ funcdefer(f);
funcjmp(f, s->breaklabel);
expect(TSEMICOLON, "after 'break' statement");
break;
@@ -303,6 +316,7 @@ stmt(struct func *f, struct scope *s)
} else {
v = NULL;
}
+ funcdefer(f);
funcret(f, v);
expect(TSEMICOLON, "after 'return' statement");
break;