fix loop end checking
This commit is contained in:
+20
-12
@@ -133,7 +133,7 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
|
||||
|
||||
uint32_t strl;
|
||||
uint32_t val;
|
||||
uint32_t limit, index, index0;
|
||||
uint32_t limit, index;
|
||||
|
||||
LOG("0x%08x: Instr %s, 0x%08x", fh->execptr, instr_name(instr->kind), instr->data);
|
||||
|
||||
@@ -271,20 +271,28 @@ enum fh_error w_user_word(struct fh_thread_s *fh, const struct fh_word_s *w0)
|
||||
TRY(rs_peek(fh, &limit));
|
||||
|
||||
LOG("+LOOP, i=%d, step %d, limit %d", fh->loop_i, val, limit);
|
||||
|
||||
index0 = fh->loop_i;
|
||||
fh->loop_i += val;
|
||||
|
||||
LOG("after add: %d", fh->loop_i);
|
||||
|
||||
// FIXME this is probably wrong
|
||||
// FIXME yes it actually is wrong
|
||||
if (((int32_t)index0 < (int32_t)limit) == ((int32_t)fh->loop_i < (int32_t)limit) && fh->loop_i != limit) { // boundary not crossed, continue
|
||||
fh->execptr = instr->data; // go to beginning
|
||||
} else {
|
||||
|
||||
const int32_t vi = (int32_t)val;
|
||||
const int32_t bdr = (int32_t)limit - (int32_t)1;
|
||||
const int32_t i0 = (int32_t)fh->loop_i;
|
||||
fh->loop_i += val; // this can overflow
|
||||
const int32_t i1 = (int32_t)fh->loop_i;
|
||||
|
||||
// TODO this can probably be optimized
|
||||
if (
|
||||
(vi > 0 && i0 <= bdr && i1 > bdr)
|
||||
|| (vi > 0 && i0 > 0 && i1 < 0 && (bdr >= i0 || bdr <= i1))
|
||||
|| (vi < 0 && i0 > bdr && i1 <= bdr)
|
||||
|| (vi < 0 && i0 < 0 && i1 > 0 && (bdr <= i0 || bdr >= i1))
|
||||
) {
|
||||
//LOGE("end of loop");
|
||||
// end of loop
|
||||
TRY(rs_pop(fh, &limit));
|
||||
TRY(fh_loop_unnest(fh));
|
||||
} else {
|
||||
//LOGE("continue loop");
|
||||
// continue the loop
|
||||
fh->execptr = instr->data;
|
||||
}
|
||||
goto instr;
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
: x 2147483647 -2147483648 DO I . -1 +LOOP ;
|
||||
x
|
||||
|
||||
Reference in New Issue
Block a user