diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-08-18 14:16:35 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-08-18 14:16:35 +0300 |
commit | 8e25ff1846acd82e522e32dddd7cc298018eca0c (patch) | |
tree | 1a38bccc1f8fbf6068d5e9dc70b536deb1815550 | |
parent | 3121834c53912f8a6bfcd4931bae9998bbb4a78d (diff) | |
download | mailfromd-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-- | NEWS | 8 | ||||
-rw-r--r-- | doc/mailfromd.texi | 2 | ||||
-rw-r--r-- | mfd/drivers.c | 17 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/next01.at | 50 | ||||
-rw-r--r-- | tests/next02.at | 51 | ||||
-rw-r--r-- | tests/testsuite.at | 3 |
7 files changed, 124 insertions, 9 deletions
@@ -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]) |