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>
7 7
8Version 5.1.91 (Git) 8Version 5.1.91 (Git)
9 9
10* `next' statement
11
12The definition of `next' statement has been fixed to match `continue'
13in other programming languages. Namely, `next' passes control to
14STMT2 in the loop definition:
15
16 loop for STMT1, while EXPR1, STMT2
17
10* Process titles. 18* Process titles.
11 19
12The process titles visible in the output of the ps(1) command reflect 20The 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.
11018@kwindex next 11018@kwindex next
11019@cindex next statement 11019@cindex next statement
11020@item next [@var{label}] 11020@item next [@var{label}]
11021 Initiates next iteration of the loop. Control passes to @samp{2} in 11021 Initiates next iteration of the loop. Control passes to @samp{4} in
11022the formal definition above. If @var{label} is supplied, the 11022the formal definition above. If @var{label} is supplied, the
11023statement starts next iteration of the loop statement marked with that 11023statement starts next iteration of the loop statement marked with that
11024label. This allows to request next iteration of an upper-level 11024label. 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)
1998/* Loop nesting stack */ 1998/* Loop nesting stack */
1999struct loop_stack { 1999struct loop_stack {
2000 struct literal *ident; 2000 struct literal *ident;
2001 prog_counter_t *begjmp;
2002 prog_counter_t *endjmp; 2001 prog_counter_t *endjmp;
2002 prog_counter_t *nxtjmp;
2003}; 2003};
2004 2004
2005static mf_stack_t loop_stack; 2005static mf_stack_t loop_stack;
@@ -2039,13 +2039,13 @@ within_loop(struct literal *lit)
2039} 2039}
2040 2040
2041void 2041void
2042enter_loop(struct literal *lit, prog_counter_t *begptr, prog_counter_t *endptr) 2042enter_loop(struct literal *lit, prog_counter_t *endptr, prog_counter_t *nxtptr)
2043{ 2043{
2044 struct loop_stack ent; 2044 struct loop_stack ent;
2045 if (!loop_stack) 2045 if (!loop_stack)
2046 loop_stack = mf_stack_create(sizeof(struct loop_stack), 0); 2046 loop_stack = mf_stack_create(sizeof(struct loop_stack), 0);
2047 ent.begjmp = begptr;
2048 ent.endjmp = endptr; 2047 ent.endjmp = endptr;
2048 ent.nxtjmp = nxtptr;
2049 ent.ident = lit; 2049 ent.ident = lit;
2050 mf_stack_push(loop_stack, &ent); 2050 mf_stack_push(loop_stack, &ent);
2051} 2051}
@@ -2083,7 +2083,7 @@ code_type_next(NODE *node, struct locus **old_locus)
2083 } 2083 }
2084 2084
2085 code_op(opcode_jmp); 2085 code_op(opcode_jmp);
2086 *ent.begjmp = code_immediate((void*) *ent.begjmp); 2086 *ent.nxtjmp = code_immediate((void*) *ent.nxtjmp);
2087} 2087}
2088 2088
2089 2089
@@ -2206,11 +2206,11 @@ code_type_loop(NODE *node, struct locus **old_locus)
2206 jmp L_begin 2206 jmp L_begin
2207 L_end: 2207 L_end:
2208 */ 2208 */
2209 prog_counter_t begin, end, begjmp = 0, endjmp = 0; 2209 prog_counter_t begin, end, stmt, endjmp = 0, nxtjmp = 0;
2210 2210
2211 MARK_LOCUS(); 2211 MARK_LOCUS();
2212 2212
2213 enter_loop(node->v.loop.ident, &begjmp, &endjmp); 2213 enter_loop(node->v.loop.ident, &endjmp, &nxtjmp);
2214 2214
2215 traverse_tree(node->v.loop.for_stmt); 2215 traverse_tree(node->v.loop.for_stmt);
2216 begin = code_get_counter(); 2216 begin = code_get_counter();
@@ -2227,14 +2227,15 @@ code_type_loop(NODE *node, struct locus **old_locus)
2227 code_op(opcode_bz); 2227 code_op(opcode_bz);
2228 endjmp = code_immediate((void*)endjmp); 2228 endjmp = code_immediate((void*)endjmp);
2229 } 2229 }
2230 2230
2231 stmt = code_get_counter();
2231 traverse_tree(node->v.loop.stmt); 2232 traverse_tree(node->v.loop.stmt);
2232 code_op(opcode_jmp); 2233 code_op(opcode_jmp);
2233 code_immediate((void*)(begin - code_get_counter() - 1)); 2234 code_immediate((void*)(begin - code_get_counter() - 1));
2234 end = code_get_counter(); 2235 end = code_get_counter();
2235 2236
2236 jump_fixup(begjmp, begin);
2237 jump_fixup(endjmp, end); 2237 jump_fixup(endjmp, end);
2238 jump_fixup(nxtjmp, stmt);
2238} 2239}
2239 2240
2240 2241
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 = \
84 ismx.at\ 84 ismx.at\
85 macros.at\ 85 macros.at\
86 ml.at\ 86 ml.at\
87 next01.at\
88 next02.at\
87 numrcpt.at\ 89 numrcpt.at\
88 poll.at\ 90 poll.at\
89 poll01.at\ 91 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 @@
1# This file is part of Mailfromd testsuite. -*- Autotest -*-
2# Copyright (C) 2009 Sergey Poznyakoff
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 3, or (at your option)
7# any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17AT_SETUP([next01])
18AT_KEYWORDS([next loop])
19
20# Description: The `next' keyword was implemented incorrectly in
21# versions up to 5.1.
22
23MF_RUN_TEXT([
24func main(...)
25 returns number
26do
27 loop for string names $1 " "
28 number i index(%names, " "),
29 while %i != -1,
30 set names substr(%names, %i + 1)
31 set i index(%names, " ")
32 do
33 string s substr(%names, 0, %i)
34 if %s == 'next'
35 next
36 fi
37 echo "WORD: %s"
38 done
39 return 0
40done
41],
42['begin next cont next end next'],
43[0],
44[],
45[WORD: begin
46WORD: cont
47WORD: end
48])
49
50AT_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 @@
1# This file is part of Mailfromd testsuite. -*- Autotest -*-
2# Copyright (C) 2009 Sergey Poznyakoff
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 3, or (at your option)
7# any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17AT_SETUP([next02])
18AT_KEYWORDS([next loop])
19
20# Description: The `next' keyword was implemented incorrectly in
21# versions up to 5.1.
22
23MF_RUN_TEXT([
24func main(...)
25 returns number
26do
27 loop for string names $1 " "
28 number i index(%names, " "),
29 while %i != -1,
30 set names substr(%names, %i + 1)
31 set i index(%names, " ")
32 do
33 string s substr(%names, 0, %i)
34 if %s == 'next'
35 next
36 fi
37 echo "WORD: %s"