bf: extract loop_end to its own function

This commit is contained in:
2026-03-17 21:28:40 +00:00
parent c6433b4429
commit 071fe2ff98

View File

@@ -27,10 +27,9 @@ struct MachineContext
u64 total_iters; u64 total_iters;
}; };
// This function implements the jump-forward operator of BrainFuck `[`, given // Jump-forward operator of BrainFuck `[`. We maintain a `loop_stack` which
// the current state of the machine. We maintain a `loop_stack` which allows us // allows us to trivially implement the jump-back operator `]` - essentially
// to trivially implement the jump-back operator `]` - essentially heavy forward // heavy forward investment.
// investment.
void loop_begin(struct ProgramConcat *prg, struct MachineContext *ctx, void loop_begin(struct ProgramConcat *prg, struct MachineContext *ctx,
vec_t *loop_stack) 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) void program_execute(struct ProgramConcat *prg)
{ {
vec_t loop_stack = {0}; vec_t loop_stack = {0};
@@ -120,28 +137,11 @@ void program_execute(struct ProgramConcat *prg)
++ctx.ip; ++ctx.ip;
break; break;
case '[': case '[':
{
loop_begin(prg, &ctx, &loop_stack); loop_begin(prg, &ctx, &loop_stack);
break; break;
}
case ']': case ']':
{ loop_end(prg, &ctx, &loop_stack);
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));
}
break; break;
}
default: default:
++ctx.ip; ++ctx.ip;
break; break;