summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/help.txt2
-rw-r--r--docs/stats.txt6
-rw-r--r--docs/version.txt2
-rw-r--r--examples/all-examples.txt26
-rw-r--r--examples/break_next.fy25
-rwxr-xr-xfypebin471287 -> 265440 bytes
-rw-r--r--src/build.h2
-rw-r--r--src/core/interpret.c36
8 files changed, 81 insertions, 18 deletions
diff --git a/docs/help.txt b/docs/help.txt
index 3921ea2..4ccd7a7 100644
--- a/docs/help.txt
+++ b/docs/help.txt
@@ -1,4 +1,4 @@
-Fype Superalpha Build 9669
+Fype Superalpha Build 9671
(c) Paul C. Buetow (2005 - 2008) <fype@dev.buetow.org>
-e Executes given code string (see synopses)
-h Prints this help
diff --git a/docs/stats.txt b/docs/stats.txt
index 81214dc..583ddf1 100644
--- a/docs/stats.txt
+++ b/docs/stats.txt
@@ -1,6 +1,6 @@
make[1]: Entering directory '/home/paul/git/fype'
===> Num of C source files : 46
-===> Num of C source lines : 8225
-===> Num of Fype source examples : 14
-===> Num of Fype source lines : 362
+===> Num of C source lines : 8237
+===> Num of Fype source examples : 15
+===> Num of Fype source lines : 387
make[1]: Leaving directory '/home/paul/git/fype'
diff --git a/docs/version.txt b/docs/version.txt
index 1a4849f..ea87c13 100644
--- a/docs/version.txt
+++ b/docs/version.txt
@@ -1 +1 @@
-Fype Superalpha Build 9669
+Fype Superalpha Build 9671
diff --git a/examples/all-examples.txt b/examples/all-examples.txt
index f71e8a2..5e0f13e 100644
--- a/examples/all-examples.txt
+++ b/examples/all-examples.txt
@@ -32,6 +32,32 @@ assert 1 == (say 1 :< 5 :> 5 or 2 and (5 xor 8));
assert (neg 1) == (say neg not 0);
+# break exits the while loop early when i reaches 5
+my i = 0;
+while i < 10 {
+ i = i + 1;
+ if i == 5 { break; }
+}
+say i; # expected: 5
+
+# next skips adding j when j == 3, so sum = 1+2+4+5 = 12
+my sum = 0;
+my j = 0;
+while j < 5 {
+ j = j + 1;
+ if j == 3 { next; }
+ sum = sum + j;
+}
+say sum; # expected: 12
+
+# break inside an until loop stops when k reaches 7
+my k = 0;
+until k == 10 {
+ k = k + 1;
+ if k == 7 { break; }
+}
+say k; # expected: 7
+
#*
* Simple examples how to write comments
*#
diff --git a/examples/break_next.fy b/examples/break_next.fy
new file mode 100644
index 0000000..bd060f8
--- /dev/null
+++ b/examples/break_next.fy
@@ -0,0 +1,25 @@
+# break exits the while loop early when i reaches 5
+my i = 0;
+while i < 10 {
+ i = i + 1;
+ if i == 5 { break; }
+}
+say i; # expected: 5
+
+# next skips adding j when j == 3, so sum = 1+2+4+5 = 12
+my sum = 0;
+my j = 0;
+while j < 5 {
+ j = j + 1;
+ if j == 3 { next; }
+ sum = sum + j;
+}
+say sum; # expected: 12
+
+# break inside an until loop stops when k reaches 7
+my k = 0;
+until k == 10 {
+ k = k + 1;
+ if k == 7 { break; }
+}
+say k; # expected: 7
diff --git a/fype b/fype
index 356c7b0..3f150ce 100755
--- a/fype
+++ b/fype
Binary files differ
diff --git a/src/build.h b/src/build.h
index 794ac65..c3808f5 100644
--- a/src/build.h
+++ b/src/build.h
@@ -36,7 +36,7 @@
#ifndef BUILD_H
#define BUILD_H
-#define BUILDNR 9670
+#define BUILDNR 9672
#define OS_LINUX
#endif
diff --git a/src/core/interpret.c b/src/core/interpret.c
index 5b5e80b..0667148 100644
--- a/src/core/interpret.c
+++ b/src/core/interpret.c
@@ -168,7 +168,9 @@ int
_program(Interpret *p_interpret) {
_CHECK TRACK
- while (_statement(p_interpret) == 1)
+ /* Stop executing statements as soon as break/next is active so the
+ * control flag propagates cleanly up to the enclosing loop. */
+ while (_statement(p_interpret) == 1 && p_interpret->ct == CONTROL_NONE)
garbage_collect();
return (1);
@@ -496,6 +498,18 @@ _control(Interpret *p_interpret) {
Token *p_token = p_interpret->p_token;
switch (p_interpret->tt) {
+ /* break; — set the break flag; the statement loop in _program() will
+ * stop and the flag propagates up to the enclosing while/until. */
+ case TT_BREAK:
+ p_interpret->ct = CONTROL_BREAK;
+ _NEXT
+ return (1);
+ /* next; — set the next flag to skip the rest of the loop body and
+ * let the loop re-evaluate its condition on the next iteration. */
+ case TT_NEXT:
+ p_interpret->ct = CONTROL_NEXT;
+ _NEXT
+ return (1);
case TT_IF:
case TT_IFNOT:
{
@@ -584,18 +598,16 @@ _control(Interpret *p_interpret) {
}
}
- /*
- switch (p_interpret->ct) {
- case CONTROL_BREAK:
- p_interpret->ct = CONTROL_NONE;
- b_flag = false;
- break;
- case CONTROL_NEXT:
- p_interpret->ct = CONTROL_NONE;
- break;
- NO_DEFAULT;
+ /* Act on any break/next flag set during loop body execution.
+ * break clears the flag and stops iteration; next clears it
+ * and lets the loop re-evaluate the condition naturally. */
+ if (p_interpret->ct == CONTROL_BREAK) {
+ p_interpret->ct = CONTROL_NONE;
+ b_flag = false;
+ } else if (p_interpret->ct == CONTROL_NEXT) {
+ p_interpret->ct = CONTROL_NONE;
+ /* b_flag stays true; condition re-evaluated next iteration */
}
- */
} else {
_INTERPRET_ERROR("Expected expression after control keyword",