aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-08-18 14:16:35 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-08-18 14:16:35 +0300
commit8e25ff1846acd82e522e32dddd7cc298018eca0c (patch)
tree1a38bccc1f8fbf6068d5e9dc70b536deb1815550
parent3121834c53912f8a6bfcd4931bae9998bbb4a78d (diff)
downloadmailfromd-8e25ff1846acd82e522e32dddd7cc298018eca0c.tar.gz
mailfromd-8e25ff1846acd82e522e32dddd7cc298018eca0c.tar.bz2
Fix definition of `next'.
* mfd/drivers.c (struct loop_stack): Replace `begjmp' with `nxtjmp'. (enter_loop): Reflect this. (code_type_next): Likewise. (code_type_loop): Rewrite jump fixup for `next' chain. * tests/next01.at, tests/next02.at: New testcases. * tests/Makefile.am: Add next01.at and next02.at * tests/testsuite.at: Likewise. * NEWS, doc/mailfromd.texi: Update
-rw-r--r--NEWS8
-rw-r--r--doc/mailfromd.texi2
-rw-r--r--mfd/drivers.c17
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/next01.at50
-rw-r--r--tests/next02.at51
-rw-r--r--tests/testsuite.at3
7 files changed, 124 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index a1b052a3..aae3abdd 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,14 @@ Please send Mailfromd bug reports to <bug-mailfromd@gnu.org.ua>
Version 5.1.91 (Git)
+* `next' statement
+
+The definition of `next' statement has been fixed to match `continue'
+in other programming languages. Namely, `next' passes control to
+STMT2 in the loop definition:
+
+ loop for STMT1, while EXPR1, STMT2
+
* Process titles.
The process titles visible in the output of the ps(1) command reflect
diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi
index 60af5b07..e18310c8 100644
--- a/doc/mailfromd.texi
+++ b/doc/mailfromd.texi
@@ -11018,7 +11018,7 @@ allows to break from nested loops.
@kwindex next
@cindex next statement
@item next [@var{label}]
- Initiates next iteration of the loop. Control passes to @samp{2} in
+ Initiates next iteration of the loop. Control passes to @samp{4} in
the formal definition above. If @var{label} is supplied, the
statement starts next iteration of the loop statement marked with that
label. This allows to request next iteration of an upper-level
diff --git a/mfd/drivers.c b/mfd/drivers.c
index ed8a288a..1b7203fa 100644
--- a/mfd/drivers.c
+++ b/mfd/drivers.c
@@ -1998,8 +1998,8 @@ code_type_switch(NODE *node, struct locus **old_locus)
/* Loop nesting stack */
struct loop_stack {
struct literal *ident;
- prog_counter_t *begjmp;
prog_counter_t *endjmp;
+ prog_counter_t *nxtjmp;
};
static mf_stack_t loop_stack;
@@ -2039,13 +2039,13 @@ within_loop(struct literal *lit)
}
void
-enter_loop(struct literal *lit, prog_counter_t *begptr, prog_counter_t *endptr)
+enter_loop(struct literal *lit, prog_counter_t *endptr, prog_counter_t *nxtptr)
{
struct loop_stack ent;
if (!loop_stack)
loop_stack = mf_stack_create(sizeof(struct loop_stack), 0);
- ent.begjmp = begptr;
ent.endjmp = endptr;
+ ent.nxtjmp = nxtptr;
ent.ident = lit;
mf_stack_push(loop_stack, &ent);
}
@@ -2083,7 +2083,7 @@ code_type_next(NODE *node, struct locus **old_locus)
}
code_op(opcode_jmp);
- *ent.begjmp = code_immediate((void*) *ent.begjmp);
+ *ent.nxtjmp = code_immediate((void*) *ent.nxtjmp);
}
@@ -2206,11 +2206,11 @@ code_type_loop(NODE *node, struct locus **old_locus)
jmp L_begin
L_end:
*/
- prog_counter_t begin, end, begjmp = 0, endjmp = 0;
+ prog_counter_t begin, end, stmt, endjmp = 0, nxtjmp = 0;
MARK_LOCUS();
- enter_loop(node->v.loop.ident, &begjmp, &endjmp);
+ enter_loop(node->v.loop.ident, &endjmp, &nxtjmp);
traverse_tree(node->v.loop.for_stmt);
begin = code_get_counter();
@@ -2227,14 +2227,15 @@ code_type_loop(NODE *node, struct locus **old_locus)
code_op(opcode_bz);
endjmp = code_immediate((void*)endjmp);
}
-
+
+ stmt = code_get_counter();
traverse_tree(node->v.loop.stmt);
code_op(opcode_jmp);
code_immediate((void*)(begin - code_get_counter() - 1));
end = code_get_counter();
- jump_fixup(begjmp, begin);
jump_fixup(endjmp, end);
+ jump_fixup(nxtjmp, stmt);
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 368a9643..af95477c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -84,6 +84,8 @@ TESTSUITE_AT = \
ismx.at\
macros.at\
ml.at\
+ next01.at\
+ next02.at\
numrcpt.at\
poll.at\
poll01.at\
diff --git a/tests/next01.at b/tests/next01.at
new file mode 100644
index 00000000..c44bb57c
--- /dev/null
+++ b/tests/next01.at
@@ -0,0 +1,50 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2009 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([next01])
+AT_KEYWORDS([next loop])
+
+# Description: The `next' keyword was implemented incorrectly in
+# versions up to 5.1.
+
+MF_RUN_TEXT([
+func main(...)
+ returns number
+do
+ loop for string names $1 " "
+ number i index(%names, " "),
+ while %i != -1,
+ set names substr(%names, %i + 1)
+ set i index(%names, " ")
+ do
+ string s substr(%names, 0, %i)
+ if %s == 'next'
+ next
+ fi
+ echo "WORD: %s"
+ done
+ return 0
+done
+],
+['begin next cont next end next'],
+[0],
+[],
+[WORD: begin
+WORD: cont
+WORD: end
+])
+
+AT_CLEANUP
diff --git a/tests/next02.at b/tests/next02.at
new file mode 100644
index 00000000..9690f732
--- /dev/null
+++ b/tests/next02.at
@@ -0,0 +1,51 @@
+# This file is part of Mailfromd testsuite. -*- Autotest -*-
+# Copyright (C) 2009 Sergey Poznyakoff
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+AT_SETUP([next02])
+AT_KEYWORDS([next loop])
+
+# Description: The `next' keyword was implemented incorrectly in
+# versions up to 5.1.
+
+MF_RUN_TEXT([
+func main(...)
+ returns number
+do
+ loop for string names $1 " "
+ number i index(%names, " "),
+ while %i != -1,
+ set names substr(%names, %i + 1)
+ set i index(%names, " ")
+ do
+ string s substr(%names, 0, %i)
+ if %s == 'next'
+ next
+ fi
+ echo "WORD: %s"
+ done while index(%names, '@') != 0
+ return 0
+done
+],
+['begin next cont next end @ finis'],
+[0],
+[],
+[WORD: begin
+WORD: cont
+WORD: end
+WORD: @
+])
+
+AT_CLEANUP
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2e647921..fafaacd2 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -141,6 +141,9 @@ m4_include([cond04.at])
m4_include([cond05.at])
m4_include([cond06.at])
+m4_include([next01.at])
+m4_include([next02.at])
+
m4_include([resolve.at])
m4_include([rescname.at])
m4_include([hostname.at])

Return to:

Send suggestions and report system problems to the System administrator.