summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2014-01-14 19:44:14 -0500
committerOri Bernstein <ori@eigenstate.org>2014-01-14 19:44:14 -0500
commit26fef326df126ced69c6eb4f531b487de37e23c7 (patch)
tree3f35a354bca4e70627111821ac7d61e82eef63ed /parse
parenta14644877bbb7cbe45cbd006f2773a3e4b9008a7 (diff)
downloadmc-26fef326df126ced69c6eb4f531b487de37e23c7.tar.gz
Add support for break/continue in loops.
Yeah, I resisted until now. Oh well.
Diffstat (limited to 'parse')
-rw-r--r--parse/gram.y15
-rw-r--r--parse/infer.c5
-rw-r--r--parse/ops.def4
-rw-r--r--parse/tok.c2
4 files changed, 24 insertions, 2 deletions
diff --git a/parse/gram.y b/parse/gram.y
index 1005275..d7ec7f2 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -85,6 +85,8 @@ static void constrainwith(Type *t, char *str);
%token<tok> Tmatch /* match */
%token<tok> Tdefault /* default */
%token<tok> Tgoto /* goto */
+%token<tok> Tbreak /* break */
+%token<tok> Tcontinue /* continue */
%token<tok> Tintlit
%token<tok> Tstrlit
@@ -134,7 +136,8 @@ static void constrainwith(Type *t, char *str);
%type <tydef> tydef typeid
%type <node> traitdef
-%type <node> exprln retexpr goto expr atomicexpr littok literal asnexpr lorexpr landexpr borexpr
+%type <node> exprln retexpr goto continue break expr atomicexpr
+%type <node> littok literal asnexpr lorexpr landexpr borexpr
%type <node> bandexpr cmpexpr unionexpr addexpr mulexpr shiftexpr prefixexpr postfixexpr
%type <node> funclit seqlit tuplit name block stmt label use
%type <node> declbody declcore structent arrayelt structelt tuphead
@@ -699,6 +702,8 @@ endlns : /* none */
;
stmt : goto
+ | break
+ | continue
| retexpr
| label
| ifstmt
@@ -708,6 +713,14 @@ stmt : goto
| /* empty */ {$$ = NULL;}
;
+break : Tbreak
+ {$$ = mkexpr($1->line, Obreak, NULL);}
+ ;
+
+continue : Tcontinue
+ {$$ = mkexpr($1->line, Ocontinue, NULL);}
+ ;
+
forstmt : Tfor optexprln optexprln optexprln block
{$$ = mkloopstmt($1->line, $2, $3, $4, $5);}
| Tfor expr Tin exprln block
diff --git a/parse/infer.c b/parse/infer.c
index 07f7524..0f00587 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1190,6 +1190,11 @@ static void inferexpr(Inferstate *st, Node *n, Type *ret, int *sawret)
t = unify(st, n, mktype(-1, Tyvoid), ret);
settype(st, n, t);
break;
+ case Obreak:
+ case Ocontinue:
+ /* nullary: nothing to infer. */
+ settype(st, n, mktype(-1, Tyvoid));
+ break;
case Ojmp: /* goto void* -> void */
infersub(st, n, ret, sawret, &isconst);
settype(st, n, mktype(-1, Tyvoid));
diff --git a/parse/ops.def b/parse/ops.def
index d7799ce..298ccb2 100644
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -45,7 +45,9 @@ O(Osize, 1)
O(Ocall, 0)
O(Ocast, 1)
O(Oret, 1)
-O(Ojmp, 1)
+O(Ojmp, 0)
+O(Obreak, 0)
+O(Ocontinue, 0)
O(Ovar, 1)
O(Olit, 1)
O(Olbl, 1)
diff --git a/parse/tok.c b/parse/tok.c
index 72edc8e..b1a0f05 100644
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -159,8 +159,10 @@ static void eatspace(void)
static int kwd(char *s)
{
static const struct {char* kw; int tt;} kwmap[] = {
+ {"break", Tbreak},
{"castto", Tcast},
{"const", Tconst},
+ {"continue", Tcontinue},
{"default", Tdefault},
{"elif", Telif},
{"else", Telse},