diff --git a/src/bf.c b/src/bf.c index 5189c3a..deeef3e 100644 --- a/src/bf.c +++ b/src/bf.c @@ -27,10 +27,9 @@ struct MachineContext u64 total_iters; }; -// This function implements the jump-forward operator of BrainFuck `[`, given -// the current state of the machine. We maintain a `loop_stack` which allows us -// to trivially implement the jump-back operator `]` - essentially heavy forward -// investment. +// Jump-forward operator of BrainFuck `[`. We maintain a `loop_stack` which +// allows us to trivially implement the jump-back operator `]` - essentially +// heavy forward investment. void loop_begin(struct ProgramConcat *prg, struct MachineContext *ctx, vec_t *loop_stack) { @@ -75,6 +74,24 @@ void loop_begin(struct ProgramConcat *prg, struct MachineContext *ctx, } } +void loop_end(struct ProgramConcat *prg, struct MachineContext *ctx, + vec_t *loop_stack) +{ + if (!prg->tape[ctx->head0]) + { + ++ctx->ip; + } + else if (loop_stack->size < sizeof(u64)) + { + // NOTE: as per paper, terminate. + ctx->ip = sizeof(prg->tape); + } + else + { + ctx->ip = *(u64 *)vec_pop(loop_stack, sizeof(ctx->ip)); + } +} + void program_execute(struct ProgramConcat *prg) { vec_t loop_stack = {0}; @@ -120,28 +137,11 @@ void program_execute(struct ProgramConcat *prg) ++ctx.ip; break; case '[': - { loop_begin(prg, &ctx, &loop_stack); break; - } case ']': - { - if (!prg->tape[ctx.head0]) - { - ++ctx.ip; - continue; - } - else if (loop_stack.size < sizeof(u64)) - { - // NOTE: as per paper, terminate. - ctx.ip = sizeof(prg->tape); - } - else - { - ctx.ip = *(u64 *)vec_pop(&loop_stack, sizeof(ctx.ip)); - } + loop_end(prg, &ctx, &loop_stack); break; - } default: ++ctx.ip; break;