X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Floop.c;h=b2685cfa201639c87eb86e86fc679902de174363;hb=b9e28aa5614a079548c616bcf97aa804024ad647;hp=e9bb674749bf9626f2dfcf0b2f3719b5e2f6a3ef;hpb=60d7d619ee7885ad065f178eb0cf1e5d432b1921;p=pspp-builds.git diff --git a/src/loop.c b/src/loop.c index e9bb6747..b2685cfa 100644 --- a/src/loop.c +++ b/src/loop.c @@ -18,7 +18,7 @@ 02111-1307, USA. */ #include -#include +#include "error.h" #include "alloc.h" #include "command.h" #include "do-ifP.h" @@ -32,7 +32,6 @@ #include "debug-print.h" -/* *INDENT-OFF* */ /* LOOP strategy: Each loop causes 3 different transformations to be output. The @@ -43,42 +42,40 @@ transformation to -1. This ensures that the pass number is set to -1 every time the loop is encountered, before the first iteration. - The second transformation increments the pass number. If there is - no indexing or test clause on either LOOP or END LOOP, then the - pass number is checked against MXLOOPS and control may pass out of - the loop; otherwise the indexing or test clause(s) on LOOP are - checked, and again control may pass out of the loop. + The second transformation increments the pass number. If + there is no indexing or test clause on either LOOP or END + LOOP, then the pass number is checked against MXLOOPS and + control may pass out of the loop. Otherwise the indexing or + test clause(s) on LOOP are checked, and again control may pass + out of the loop. - After the second transformation the body of the loop is executed. + After the second transformation the body of the loop is + executed. The last transformation checks the test clause if present and - either jumps back up to the second transformation or terminates the - loop. - - Flow of control: (The characters ^V<> represents arrows.) - - 1. LOOP (sets pass # to -1) - V - V - >>2. LOOP (increment pass number) - ^ (test optional indexing clause) - ^ (test optional IF clause) - ^ if we need another trip if we're done with the loop>>V - ^ V V - ^ V V - ^ *. execute loop body V - ^ . V - ^ . (any number of transformations) V - ^ . V - ^ V - ^ 3. END LOOP (test optional IF clause) V - ^<<<>V - V - V - *. transformations after loop body<<<<<<<<<<<<<<<<<<<<<<<<<<< + either jumps back up to the second transformation or + terminates the loop. + + Flow of control: + + 1. LOOP. Sets pass number to -1 and continues to next + transformation. + + 2. LOOP. Increments pass number. Tests optional indexing + clause and optional IF clause. If we're done with the + loop, we jump to the transformation just after LOOP + transformation 3. + Otherwise, we continue through the transformations in the + loop body. + + 3. END LOOP. We test the optional IF clause. If we need to + make another pass through the loop, we jump to LOOP + transformation 2. + + Otherwise, we continue with the transformation jump after + the loop. */ -/* *INDENT-ON* */ /* Types of limits on loop execution. */ enum @@ -140,13 +137,9 @@ static struct loop_3_trns *thr; static int internal_cmd_loop (void); static int internal_cmd_end_loop (void); -static int break_trns_proc (struct trns_header *, struct ccase *); -static int loop_1_trns_proc (struct trns_header *, struct ccase *); -static void loop_1_trns_free (struct trns_header *); -static int loop_2_trns_proc (struct trns_header *, struct ccase *); -static void loop_2_trns_free (struct trns_header *); -static int loop_3_trns_proc (struct trns_header *, struct ccase *); -static void loop_3_trns_free (struct trns_header *); +static trns_proc_func break_trns_proc; +static trns_proc_func loop_1_trns_proc, loop_2_trns_proc, loop_3_trns_proc; +static trns_free_func loop_1_trns_free, loop_2_trns_free, loop_3_trns_free; static void pop_ctl_stack (void); /* LOOP. */ @@ -173,8 +166,6 @@ internal_cmd_loop (void) /* Name of indexing variable if applicable. */ char name[9]; - lex_match_id ("LOOP"); - /* Create and initialize transformations to facilitate error-handling. */ two = xmalloc (sizeof *two); @@ -207,7 +198,7 @@ internal_cmd_loop (void) assert (token == '='); lex_get (); - one->init = expr_parse (PXP_NUMERIC); + one->init = expr_parse (EXPR_NUMERIC); if (!one->init) return 0; @@ -216,7 +207,7 @@ internal_cmd_loop (void) expr_free (one->init); return 0; } - one->term = expr_parse (PXP_NUMERIC); + one->term = expr_parse (EXPR_NUMERIC); if (!one->term) { expr_free (one->init); @@ -225,7 +216,7 @@ internal_cmd_loop (void) if (lex_match (T_BY)) { - one->incr = expr_parse (PXP_NUMERIC); + one->incr = expr_parse (EXPR_NUMERIC); if (!one->incr) return 0; } @@ -238,7 +229,7 @@ internal_cmd_loop (void) { two->flags |= LPC_COND; - two->cond = expr_parse (PXP_BOOLEAN); + two->cond = expr_parse (EXPR_BOOLEAN); if (!two->cond) return 0; } @@ -322,7 +313,7 @@ internal_cmd_end_loop (void) /* Parse the expression if any. */ if (lex_match_id ("IF")) { - thr->cond = expr_parse (PXP_BOOLEAN); + thr->cond = expr_parse (EXPR_BOOLEAN); if (!thr->cond) return 0; } @@ -349,7 +340,8 @@ internal_cmd_end_loop (void) /* Performs transformation 1. */ static int -loop_1_trns_proc (struct trns_header * trns, struct ccase * c) +loop_1_trns_proc (struct trns_header * trns, struct ccase * c, + int case_num) { struct loop_1_trns *one = (struct loop_1_trns *) trns; struct loop_2_trns *two = one->two; @@ -359,12 +351,12 @@ loop_1_trns_proc (struct trns_header * trns, struct ccase * c) { union value t1, t2, t3; - expr_evaluate (one->init, c, &t1); + expr_evaluate (one->init, c, case_num, &t1); if (one->incr) - expr_evaluate (one->incr, c, &t2); + expr_evaluate (one->incr, c, case_num, &t2); else t2.f = 1.0; - expr_evaluate (one->term, c, &t3); + expr_evaluate (one->term, c, case_num, &t3); /* Even if the loop is never entered, force the index variable to assume the initial value. */ @@ -415,7 +407,8 @@ loop_1_trns_free (struct trns_header * trns) /* Performs transformation 2. */ static int -loop_2_trns_proc (struct trns_header * trns, struct ccase * c) +loop_2_trns_proc (struct trns_header * trns, struct ccase * c, + int case_num UNUSED) { struct loop_2_trns *two = (struct loop_2_trns *) trns; @@ -423,7 +416,7 @@ loop_2_trns_proc (struct trns_header * trns, struct ccase * c) if (two->flags == 0) { two->pass++; - if (two->pass > set_mxloops) + if (two->pass > get_mxloops() ) return two->loop_term; } @@ -456,7 +449,7 @@ loop_2_trns_proc (struct trns_header * trns, struct ccase * c) /* Conditional clause limiter. */ if ((two->flags & LPC_COND) - && expr_evaluate (two->cond, c, NULL) != 1.0) + && expr_evaluate (two->cond, c, case_num, NULL) != 1.0) return two->loop_term; return -1; @@ -473,13 +466,14 @@ loop_2_trns_free (struct trns_header * trns) /* Performs transformation 3. */ static int -loop_3_trns_proc (struct trns_header * trns, struct ccase * c) +loop_3_trns_proc (struct trns_header * trns, struct ccase * c, + int case_num) { struct loop_3_trns *thr = (struct loop_3_trns *) trns; /* Note that it breaks out of the loop if the expression is true *or missing*. This is conformant. */ - if (thr->cond && expr_evaluate (two->cond, c, NULL) != 0.0) + if (thr->cond && expr_evaluate (two->cond, c, case_num, NULL) != 0.0) return -1; return thr->loop_start; @@ -506,8 +500,6 @@ cmd_break (void) /* New transformation. */ struct break_trns *t; - lex_match_id ("BREAK"); - for (loop = ctl_stack; loop; loop = loop->down) if (loop->type == CST_LOOP) break; @@ -532,7 +524,8 @@ cmd_break (void) } static int -break_trns_proc (struct trns_header * trns, struct ccase * c UNUSED) +break_trns_proc (struct trns_header * trns, struct ccase * c UNUSED, + int case_num UNUSED) { return ((struct break_trns *) trns)->loop_term; }