shithub: mc

Download patch

ref: 26fef326df126ced69c6eb4f531b487de37e23c7
parent: a14644877bbb7cbe45cbd006f2773a3e4b9008a7
author: Ori Bernstein <[email protected]>
date: Tue Jan 14 14:44:14 EST 2014

Add support for break/continue in loops.

    Yeah, I resisted until now. Oh well.

--- a/6/isel.c
+++ b/6/isel.c
@@ -719,6 +719,7 @@
         case Oslice: case Oidx: case Osize: case Numops:
         case Oucon: case Ouget: case Otup: case Oarr: case Ostruct:
         case Oslbase: case Osllen: case Ocast:
+        case Obreak: case Ocontinue:
             dump(n, stdout);
             die("Should not see %s in isel", opstr(exprop(n)));
             break;
--- a/6/simp.c
+++ b/6/simp.c
@@ -37,6 +37,12 @@
     /* pre/postinc handling */
     Node **incqueue;
     size_t nqueue;
+    
+    /* break/continue handling */
+    Node **loopstep;
+    size_t nloopstep;
+    Node **loopexit;
+    size_t nloopexit;
 
     /* location handling */
     Node **blobs;
@@ -469,19 +475,28 @@
     Node *lbody;
     Node *lend;
     Node *lcond;
+    Node *lstep;
 
     lbody = genlbl();
     lcond = genlbl();
+    lstep = genlbl();
     lend = genlbl();
 
+    lappend(&s->loopstep, &s->nloopstep, lstep);
+    lappend(&s->loopexit, &s->nloopexit, lend);
+
     simp(s, n->loopstmt.init);  /* init */
     jmp(s, lcond);              /* goto test */
     simp(s, lbody);             /* body lbl */
     simp(s, n->loopstmt.body);  /* body */
+    simp(s, lstep);             /* test lbl */
     simp(s, n->loopstmt.step);  /* step */
     simp(s, lcond);             /* test lbl */
     simpcond(s, n->loopstmt.cond, lbody, lend);    /* repeat? */
     simp(s, lend);              /* exit */
+
+    s->nloopstep--;
+    s->nloopexit--;
 }
 
 /* pat; seq; 
@@ -514,6 +529,9 @@
     lmatch = genlbl();
     lend = genlbl();
 
+    lappend(&s->loopstep, &s->nloopstep, lstep);
+    lappend(&s->loopexit, &s->nloopexit, lend);
+
     zero = mkintlit(n->line, 0);
     zero->expr.type = tyintptr;
 
@@ -539,6 +557,9 @@
     val = load(idxaddr(s, seq, idx));
     umatch(s, n->iterstmt.elt, val, val->expr.type, lbody, lstep);
     simp(s, lend);
+
+    s->nloopstep--;
+    s->nloopexit--;
 }
 
 static Ucon *finducon(Node *n)
@@ -1230,7 +1251,6 @@
     r = NULL;
     args = n->expr.args;
     switch (exprop(n)) {
-        case Obad:
         case Olor: case Oland:
             r = simplazy(s, n);
             break;
@@ -1402,6 +1422,17 @@
                 r = visit(s, n);
             }
             break;
+        case Obreak:
+            if (s->nloopexit == 0)
+                fatal(n->line, "trying to break when not in loop");
+            jmp(s, s->loopexit[s->nloopexit - 1]);
+            break;
+        case Ocontinue:
+            if (s->nloopstep == 0)
+                fatal(n->line, "trying to continue when not in loop");
+            jmp(s, s->loopstep[s->nloopstep - 1]);
+            break;
+            break;
         default:
             if (istyfloat(exprtype(n))) {
                 switch (exprop(n)) {
@@ -1413,6 +1444,10 @@
                 }
             }
             r = visit(s, n);
+            break;
+        case Obad:
+            die("Bad operator");
+            break;
     }
     return r;
 }
--- a/libstd/sys-linux.myr
+++ b/libstd/sys-linux.myr
@@ -2,6 +2,7 @@
 use "sleq.use"
 
 pkg std =
+	type pid	= int64
 	type scno	= int64	/* syscall */
 	type fdopt	= int64	/* fd options */
 	type fd		= int64	/* fd */
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -85,6 +85,8 @@
 %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 @@
 %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 @@
         ;
 
 stmt    : goto
+        | break
+        | continue
         | retexpr
         | label
         | ifstmt
@@ -706,6 +711,14 @@
         | whilestmt
         | matchstmt
         | /* empty */ {$$ = NULL;}
+        ;
+
+break   : Tbreak
+     	    {$$ = mkexpr($1->line, Obreak, NULL);}
+        ;
+
+continue   : Tcontinue
+     	    {$$ = mkexpr($1->line, Ocontinue, NULL);}
         ;
 
 forstmt : Tfor optexprln optexprln optexprln block
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1190,6 +1190,11 @@
                 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));
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -45,7 +45,9 @@
 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)
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -159,8 +159,10 @@
 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},
--- a/test/loop.myr
+++ b/test/loop.myr
@@ -5,8 +5,20 @@
 	var n
 
 	n = 0
+	for i = 0; i < 5; ++i
+		std.put("%i", i)
+	;;
+	for i = 0; i < 5; ++i
+		if i > 3
+			break
+		;;
+		std.put("%i", i)
+	;;
 	for i = 0; i < 10; ++i
-		n += i
+		if i < 6
+			continue
+		;;
+		std.put("%i", i)
 	;;
-	std.exit(n)
+	std.put("\n")
 }
--- a/test/tests
+++ b/test/tests
@@ -56,7 +56,7 @@
 B callbig	E	42
 B nestfn	E	42
 # B closure	E	55      ## BUGGERED
-B loop		E	45
+B loop		P	0123401236789
 B subrangefor	P       12
 B patiter	P	23512
 B condiftrue	E	7