bf: extract loop_end to its own function
This commit is contained in:
44
src/bf.c
44
src/bf.c
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user