simulation: add mutation (disabled) and fix bf interpreter
So I was using safe subtraction to fix the heads at 0, but BF itself wraps heads around the tape if they overflow/underflow. This completely changes the presentation of the simulation.
This commit is contained in:
@@ -26,11 +26,12 @@ typedef float f32;
|
|||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define SAFE_SUB(A, B) ((A) < (B) ? 0 : (A) - (B))
|
#define SAFE_SUB(A, B) ((A) < (B) ? 0 : (A) - (B))
|
||||||
|
|
||||||
// GUI stuff
|
// GUI stuff
|
||||||
#define WIDTH 800
|
#define WIDTH 800
|
||||||
#define HEIGHT 600
|
#define HEIGHT 800
|
||||||
|
|
||||||
// Simulation constants
|
// Simulation constants
|
||||||
#define SIZEOF_PROGRAM_POW_2 8
|
#define SIZEOF_PROGRAM_POW_2 8
|
||||||
@@ -38,6 +39,9 @@ typedef double f64;
|
|||||||
#define NUM_PROGRAMS_POW_2 8
|
#define NUM_PROGRAMS_POW_2 8
|
||||||
#define NUM_PROGRAMS (1 << NUM_PROGRAMS_POW_2)
|
#define NUM_PROGRAMS (1 << NUM_PROGRAMS_POW_2)
|
||||||
|
|
||||||
|
#define MUTATION_CHANCE 0
|
||||||
|
#define MUTATION_OFFSET 2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copyright (C) 2026 Aryadev Chavali
|
/* Copyright (C) 2026 Aryadev Chavali
|
||||||
|
|||||||
16
src/bf.c
16
src/bf.c
@@ -12,7 +12,6 @@
|
|||||||
void program_concat(struct ProgramConcat *ret, bf_token *a, bf_token *b)
|
void program_concat(struct ProgramConcat *ret, bf_token *a, bf_token *b)
|
||||||
{
|
{
|
||||||
assert(a && b);
|
assert(a && b);
|
||||||
memset(ret, 0, sizeof(*ret));
|
|
||||||
ret->a = a;
|
ret->a = a;
|
||||||
ret->b = b;
|
ret->b = b;
|
||||||
memcpy(ret->tape, a, SIZEOF_PROGRAM);
|
memcpy(ret->tape, a, SIZEOF_PROGRAM);
|
||||||
@@ -92,9 +91,10 @@ void loop_end(struct ProgramConcat *prg, struct MachineContext *ctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static vec_t loop_stack = {0};
|
||||||
void program_execute(struct ProgramConcat *prg)
|
void program_execute(struct ProgramConcat *prg)
|
||||||
{
|
{
|
||||||
vec_t loop_stack = {0};
|
loop_stack.size = 0;
|
||||||
vec_ensure_capacity(&loop_stack, sizeof(prg->tape) * sizeof(u64));
|
vec_ensure_capacity(&loop_stack, sizeof(prg->tape) * sizeof(u64));
|
||||||
|
|
||||||
for (struct MachineContext ctx = {0};
|
for (struct MachineContext ctx = {0};
|
||||||
@@ -107,7 +107,10 @@ void program_execute(struct ProgramConcat *prg)
|
|||||||
case '<':
|
case '<':
|
||||||
// NOTE: We're doing a safe subtraction here, but maybe we should
|
// NOTE: We're doing a safe subtraction here, but maybe we should
|
||||||
// terminate execution if subtraction will overflow?
|
// terminate execution if subtraction will overflow?
|
||||||
ctx.head0 = SAFE_SUB(ctx.head0, 1);
|
// ctx.head0 = SAFE_SUB(ctx.head0, 1);
|
||||||
|
|
||||||
|
ctx.head0 -= 1;
|
||||||
|
ctx.head0 %= sizeof(prg->tape);
|
||||||
++ctx.ip;
|
++ctx.ip;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
@@ -117,7 +120,10 @@ void program_execute(struct ProgramConcat *prg)
|
|||||||
case '{':
|
case '{':
|
||||||
// NOTE: We're doing a safe subtraction here, but maybe we should
|
// NOTE: We're doing a safe subtraction here, but maybe we should
|
||||||
// terminate execution if subtraction will overflow?
|
// terminate execution if subtraction will overflow?
|
||||||
ctx.head1 = SAFE_SUB(ctx.head1, 1);
|
// ctx.head1 = SAFE_SUB(ctx.head1, 1);
|
||||||
|
|
||||||
|
ctx.head1 -= 1;
|
||||||
|
ctx.head1 %= sizeof(prg->tape);
|
||||||
++ctx.ip;
|
++ctx.ip;
|
||||||
break;
|
break;
|
||||||
case '}':
|
case '}':
|
||||||
@@ -151,8 +157,6 @@ void program_execute(struct ProgramConcat *prg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec_free(&loop_stack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void program_split(struct ProgramConcat *prg)
|
void program_split(struct ProgramConcat *prg)
|
||||||
|
|||||||
@@ -25,20 +25,31 @@ static const Color possible_colors[] = {
|
|||||||
|
|
||||||
void simulation_iterate(simulation_t *sim)
|
void simulation_iterate(simulation_t *sim)
|
||||||
{
|
{
|
||||||
sim->a = 0;
|
// Mutate cells if an option
|
||||||
sim->b = 0;
|
#if MUTATION_CHANCE
|
||||||
while (sim->a == sim->b)
|
for (u64 i = 0; i < SIMULATION_SIZE; ++i)
|
||||||
{
|
{
|
||||||
sim->a = rand() % NUM_PROGRAMS;
|
if ((rand() % MUTATION_CHANCE) == 0)
|
||||||
sim->b = rand() % NUM_PROGRAMS;
|
{
|
||||||
|
sim->memory[i] += (rand() % MUTATION_OFFSET) - (MUTATION_OFFSET / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u64 a = 0, b = 0;
|
||||||
|
while (a == b)
|
||||||
|
{
|
||||||
|
a = rand() % NUM_PROGRAMS;
|
||||||
|
b = rand() % NUM_PROGRAMS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the catalytic reaction
|
// Perform the reaction
|
||||||
struct ProgramConcat a_b_concat = {0};
|
struct ProgramConcat *a_b_concat = calloc(1, sizeof(*a_b_concat));
|
||||||
program_concat(&a_b_concat, sim->memory + (sim->a * SIZEOF_PROGRAM),
|
program_concat(a_b_concat, sim->memory + (a * SIZEOF_PROGRAM),
|
||||||
sim->memory + (sim->b * SIZEOF_PROGRAM));
|
sim->memory + (b * SIZEOF_PROGRAM));
|
||||||
program_execute(&a_b_concat);
|
program_execute(a_b_concat);
|
||||||
program_split(&a_b_concat);
|
program_split(a_b_concat);
|
||||||
|
free(a_b_concat);
|
||||||
}
|
}
|
||||||
|
|
||||||
bf_token get_op(const bf_token cell)
|
bf_token get_op(const bf_token cell)
|
||||||
@@ -56,42 +67,38 @@ Color simulation_cell_color(const bf_token cell)
|
|||||||
|
|
||||||
void simulation_draw(simulation_t *sim)
|
void simulation_draw(simulation_t *sim)
|
||||||
{
|
{
|
||||||
auto const PROGRAM_ROW = (1 << (SIZEOF_PROGRAM_POW_2 / 2));
|
const u64 PROGRAM_ROW = (1 << (SIZEOF_PROGRAM_POW_2 / 2));
|
||||||
auto const SIMULATION_ROW = (1 << (NUM_PROGRAMS_POW_2 / 2));
|
const u64 SIMULATION_ROW = (1 << (NUM_PROGRAMS_POW_2 / 2));
|
||||||
auto const CELL_WIDTH = WIDTH / ((f64)(PROGRAM_ROW * SIMULATION_ROW));
|
const u64 ROW_NUM_CELLS = (PROGRAM_ROW * SIMULATION_ROW);
|
||||||
auto const CELL_HEIGHT = HEIGHT / ((f64)(PROGRAM_ROW * SIMULATION_ROW));
|
const f64 CELL_WIDTH = WIDTH / (f64)ROW_NUM_CELLS;
|
||||||
|
const f64 CELL_HEIGHT = HEIGHT / (f64)ROW_NUM_CELLS;
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_PROGRAMS; ++i)
|
for (size_t i = 0; i < NUM_PROGRAMS; ++i)
|
||||||
{
|
{
|
||||||
auto s_x = (i / SIMULATION_ROW) * PROGRAM_ROW;
|
|
||||||
auto s_y = (i % SIMULATION_ROW) * PROGRAM_ROW;
|
|
||||||
// printf("%lu => (%lu, %lu)\n", i, s_x, s_y);
|
|
||||||
|
|
||||||
const bf_token *base = sim->memory + (i * SIZEOF_PROGRAM);
|
const bf_token *base = sim->memory + (i * SIZEOF_PROGRAM);
|
||||||
|
u64 s_x = (i / SIMULATION_ROW) * PROGRAM_ROW;
|
||||||
|
u64 s_y = (i % SIMULATION_ROW) * PROGRAM_ROW;
|
||||||
|
|
||||||
for (u64 j = 0; j < SIZEOF_PROGRAM; ++j)
|
for (u64 j = 0; j < SIZEOF_PROGRAM; ++j)
|
||||||
{
|
{
|
||||||
auto p_x = j / PROGRAM_ROW;
|
u64 p_x = j / PROGRAM_ROW;
|
||||||
auto p_y = j % PROGRAM_ROW;
|
u64 p_y = j % PROGRAM_ROW;
|
||||||
p_x += s_x;
|
p_x += s_x;
|
||||||
p_y += s_y;
|
p_y += s_y;
|
||||||
|
|
||||||
// printf("\t%lu => (%lu, %lu)\n", j, p_x, p_y);
|
Color color = simulation_cell_color(base[j]);
|
||||||
|
|
||||||
auto color = simulation_cell_color(base[j]);
|
|
||||||
|
|
||||||
|
// DrawRectangle(p_x * CELL_WIDTH, p_y * CELL_HEIGHT, CELL_WIDTH,
|
||||||
|
// CELL_HEIGHT, color);
|
||||||
DrawRectangleV((Vector2){CELL_WIDTH * p_x, CELL_HEIGHT * p_y},
|
DrawRectangleV((Vector2){CELL_WIDTH * p_x, CELL_HEIGHT * p_y},
|
||||||
(Vector2){CELL_WIDTH, CELL_HEIGHT}, color);
|
(Vector2){CELL_WIDTH, CELL_HEIGHT}, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sim->a == i || sim->b == i)
|
|
||||||
{
|
|
||||||
DrawRectangleLinesEx((Rectangle){.x = s_x * CELL_WIDTH,
|
DrawRectangleLinesEx((Rectangle){.x = s_x * CELL_WIDTH,
|
||||||
.y = s_y * CELL_HEIGHT,
|
.y = s_y * CELL_HEIGHT,
|
||||||
.width = PROGRAM_ROW * CELL_WIDTH,
|
.width = CELL_WIDTH * SIMULATION_ROW,
|
||||||
.height = PROGRAM_ROW * CELL_HEIGHT},
|
.height = CELL_HEIGHT * SIMULATION_ROW},
|
||||||
1, BLUE);
|
1, WHITE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u64 a, b;
|
|
||||||
bf_token memory[SIMULATION_SIZE];
|
bf_token memory[SIMULATION_SIZE];
|
||||||
} simulation_t;
|
} simulation_t;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user