~lbnz/xr0

2062971d7ade4f1341f1c4d25a5cdde298d6133d — Claude Betz a month ago 7dd8392
fix: stepping with next working

issue: https://github.com/xr0-org/xr0/issues/45
M include/ast.h => include/ast.h +1 -1
@@ 458,7 458,7 @@ ast_stmt_as_expr(struct ast_stmt *);
enum execution_mode;

struct error *
ast_stmt_linearise(struct ast_stmt *, struct state *, enum execution_mode);
ast_stmt_linearise(struct ast_stmt *, struct state *);

bool
ast_stmt_linearisable(struct ast_stmt *);

M include/path.h => include/path.h +3 -0
@@ 25,4 25,7 @@ path_step(struct path *);
struct error *
path_next(struct path *);

char *
path_str(struct path *);

#endif

M include/state.h => include/state.h +3 -0
@@ 66,6 66,9 @@ state_atend(struct state *);
struct error *
state_step(struct state *);

struct error *
state_next(struct state *);

struct externals *
state_getext(struct state *);


M src/ast/function/function.c => src/ast/function/function.c +1 -0
@@ 225,6 225,7 @@ ast_function_debug(struct ast_function *f, struct externals *ext)
{
	struct path *path = path_create(f, ext);
	while (!path_atend(path)) {
		d_printf("%s\n", path_str(path));
		struct error *err = next(path);
		if (err) {
			return err;

M src/ast/stmt/verify.c => src/ast/stmt/verify.c +3 -4
@@ 29,8 29,7 @@ ast_stmt_linearise_proper(struct ast_stmt *, struct ast_block *, struct lexemema
		struct state *);

struct error *
ast_stmt_linearise(struct ast_stmt *stmt, struct state *state,
		enum execution_mode mode)
ast_stmt_linearise(struct ast_stmt *stmt, struct state *state)
{
	struct lexememarker *loc = ast_stmt_lexememarker(stmt);
	struct ast_block *b = ast_block_create(NULL, 0, NULL, 0);


@@ 41,7 40,7 @@ ast_stmt_linearise(struct ast_stmt *stmt, struct state *state,
		return err;
	}
	struct frame *inter_frame = frame_intermediate_create(
		dynamic_str("inter"), b, mode
		dynamic_str("inter"), b, state_execmode(state)
	);
	state_pushframe(state, inter_frame);
	return NULL;


@@ 707,7 706,7 @@ sel_buildsetup(struct ast_stmt *stmt, struct state *state, struct ast_block *set
			*nest = ast_stmt_sel_nest(stmt);
	struct decision dec = sel_decide(cond, state);
	if (dec.err) {
		v_printf("setup branch decision error: %s\n", error_str(dec.err));
		// v_printf("setup branch decision error: %s\n", error_str(dec.err));
		/* XXX: if error is `undecidable', must be decidable in some other branch */
		return NULL;
	}

M src/object/object.c => src/object/object.c +7 -2
@@ 710,8 710,13 @@ object_arr_remove(struct object_arr *arr, int index)
	for (int i = index; i < arr->n-1; i++) {
		arr->object[i] = arr->object[i+1];
	}
	arr->object = realloc(arr->object, sizeof(struct alloc *) * --arr->n);
	assert(arr->object || !arr->n);
	if (arr->n == 1) {
		--arr->n;
		free(arr->object[0]);
	} else {
		arr->object = realloc(arr->object, sizeof(struct object *) * --arr->n);
		assert(arr->object || !arr->n);
	}
}

int

M src/path/path.c => src/path/path.c +57 -42
@@ 289,19 289,7 @@ path_continue(struct path *, enum path_state og_state, int og_frame,
static struct error *
path_next_abstract(struct path *p)
{
	struct error *err;

	int og_frame = state_frameid(p->abstract);
	int og_index = state_programindex(p->abstract);
	if ((err = path_step(p))) {
		return err;
	}
	while (path_continue(p, PATH_STATE_ABSTRACT, og_frame, og_index)) {
		if ((err = path_step_abstract(p, false))) {
			return err;
		}
	}
	return NULL;
	return state_next(p->abstract);
}

static struct error *


@@ 389,19 377,7 @@ path_insamestmt(struct path *p, enum path_state og_state, int og_frame, int og_i
static struct error *
path_next_actual(struct path *p)
{
	struct error *err;

	int og_frame = state_frameid(p->actual);
	int og_index = state_programindex(p->actual);
	if ((err = path_step(p))) {
		return err;
	}
	while (path_continue(p, PATH_STATE_ACTUAL, og_frame, og_index)) {
		if ((err = path_step_actual(p, false))) {
			return err;
		}
	}
	return NULL;
	return state_next(p->actual);	
}

static struct error *


@@ 409,7 385,6 @@ path_init_abstract(struct path *p)
{
	struct error *err;

	d_printf("init abstract state\n");
	struct frame *f = frame_call_create(
		ast_function_name(p->f),
		ast_function_abstract(p->f),


@@ 431,7 406,6 @@ static struct error *
path_init_actual(struct path *p)
{
	struct error *err;
	d_printf("init actual state\n");
	/* if body empty just apply setup */
	struct frame *f = frame_call_create(
		ast_function_name(p->f),


@@ 459,12 433,7 @@ path_init_actual(struct path *p)

static struct error *
path_step_abstract(struct path *p, bool print)
{
	if (print) {
		d_printf("mode:%s\n", state_execmode_str(state_execmode(p->abstract)));
		d_printf("text:\n%s\n", state_programtext(p->abstract));
		d_printf("%s\n", state_str(p->abstract));
	}
{	
	if (state_atend(p->abstract) && state_frameid(p->abstract) == 0) {
		p->path_state = PATH_STATE_HALFWAY;
		return path_step(p);


@@ 484,12 453,7 @@ path_step_abstract(struct path *p, bool print)

static struct error *
path_step_actual(struct path *p, bool print)
{
	if (print) {
		d_printf("mode:%s\n", state_execmode_str(state_execmode(p->actual)));
		d_printf("text:\n%s\n", state_programtext(p->actual));
		d_printf("actual: %s\n", state_str(p->actual));
	}
{	
	if (state_atend(p->actual) && state_frameid(p->actual) == 0) {
		p->path_state = PATH_STATE_AUDIT;
		return path_step(p);


@@ 510,9 474,8 @@ path_step_actual(struct path *p, bool print)
static struct error *
path_audit(struct path *p)
{
	d_printf("audit\n");
	if (state_hasgarbage(p->actual)) {
		d_printf("actual: %s", state_str(p->actual));
		v_printf("actual: %s", state_str(p->actual));
		return error_printf(
			"%s: garbage on heap", ast_function_name(p->f)
		);


@@ 556,3 519,55 @@ branch_step(struct path *parent, struct path *branch)
	}
	return path_step(branch);
}

char *
path_abstract_str(struct path *);

char *
path_actual_str(struct path *);

char *
path_str(struct path *p)
{
	switch (p->path_state) {
	case PATH_STATE_UNINIT:
		return dynamic_str("init abstract state");
	case PATH_STATE_ABSTRACT:
		return path_abstract_str(p);
	case PATH_STATE_HALFWAY:
		return dynamic_str("init actual state");
	case PATH_STATE_ACTUAL:
		return path_actual_str(p);
	case PATH_STATE_AUDIT:
		return dynamic_str("audit");
	case PATH_STATE_SPLIT:
		return dynamic_str("split");
	case PATH_STATE_ATEND:
	default:
		assert(false);
	}
}

char *
path_abstract_str(struct path *p)
{
	struct strbuilder *b = strbuilder_create();
	strbuilder_printf(
		b, "mode: %s\n", state_execmode_str(state_execmode(p->abstract))
	);
	strbuilder_printf(b, "text:\n%s\n", state_programtext(p->abstract));
	strbuilder_printf(b, "%s\n", state_str(p->abstract));
	return strbuilder_build(b);
}

char *
path_actual_str(struct path *p)
{
	struct strbuilder *b = strbuilder_create();
	strbuilder_printf(
		b, "mode: %s\n", state_execmode_str(state_execmode(p->actual))
	);
	strbuilder_printf(b, "text:\n%s\n", state_programtext(p->actual));
	strbuilder_printf(b, "%s\n", state_str(p->actual));
	return strbuilder_build(b);
}

M src/state/program.c => src/state/program.c +41 -11
@@ 64,8 64,7 @@ program_destroy(struct program *p)
	free(p);
}

struct program *
program_copy(struct program *old)
struct program * program_copy(struct program *old)
{
	struct program *new = program_create(old->b);
	new->s = old->s;


@@ 155,10 154,10 @@ program_stmt_atend(struct program *p, struct state *s)
}

static struct error *
program_stmt_step(struct program *, enum execution_mode, struct state *);
program_stmt_step(struct program *, struct state *);

struct error *
program_exec(struct program *p, enum execution_mode mode, struct state *s)
program_step(struct program *p, struct state *s)
{
	switch (p->s) {
	case PROGRAM_COUNTER_DECLS:


@@ 166,7 165,7 @@ program_exec(struct program *p, enum execution_mode mode, struct state *s)
		program_nextdecl(p);
		return NULL;
	case PROGRAM_COUNTER_STMTS:
		return program_stmt_step(p, mode, s);
		return program_stmt_step(p, s);
	case PROGRAM_COUNTER_ATEND:
		state_popframe(s);
		return NULL;


@@ 176,12 175,12 @@ program_exec(struct program *p, enum execution_mode mode, struct state *s)
}

static struct error *
program_stmt_process(struct program *p, enum execution_mode mode, struct state *s);
program_stmt_process(struct program *p, struct state *s);

static struct error *
program_stmt_step(struct program *p, enum execution_mode mode, struct state *s)
program_stmt_step(struct program *p, struct state *s)
{
	struct error *err = program_stmt_process(p, mode, s);
	struct error *err = program_stmt_process(p, s);
	if (!err) {
		program_nextstmt(p, s);
		return NULL;


@@ 195,13 194,13 @@ program_stmt_step(struct program *p, enum execution_mode mode, struct state *s)
}

static struct error *
program_stmt_process(struct program *p, enum execution_mode mode, struct state *s)
program_stmt_process(struct program *p, struct state *s)
{
	struct ast_stmt *stmt = ast_block_stmts(p->b)[p->index];
	if (!state_islinear(s) && ast_stmt_linearisable(stmt)) {
		return ast_stmt_linearise(stmt, s, mode);
		return ast_stmt_linearise(stmt, s);
	}
	switch (mode) {
	switch (state_execmode(s)) {
	case EXEC_ABSTRACT:
		return ast_stmt_absprocess(stmt, s);
	case EXEC_ABSTRACT_NO_SETUP:


@@ 216,6 215,37 @@ program_stmt_process(struct program *p, enum execution_mode mode, struct state *
	}
}

static struct error *
program_stmt_next(struct program *, struct state *);

struct error *
program_next(struct program *p, struct state *s)
{
	switch (p->s) {
	case PROGRAM_COUNTER_STMTS:
		return program_stmt_next(p, s);
	case PROGRAM_COUNTER_ATEND:
		return program_step(p, s);
	default:
		assert(false);
	}
}

static struct error *
program_stmt_next(struct program *p, struct state *s)
{
	int og_frame = state_frameid(s);
	do {
		struct error *err = state_step(s);			
		if (err) {
			return err;
		}
	} while (state_frameid(s) != og_frame);


	return NULL;
}

char *
program_loc(struct program *p)
{

M src/state/program.h => src/state/program.h +4 -1
@@ 36,7 36,10 @@ program_prevcall(struct program *);
enum execution_mode;

struct error *
program_exec(struct program *, enum execution_mode, struct state *);
program_step(struct program *, struct state *);

struct error *
program_next(struct program *, struct state *);

char *
program_loc(struct program *);

M src/state/stack.c => src/state/stack.c +7 -1
@@ 316,7 316,13 @@ stack_atend(struct stack *s)
struct error *
stack_step(struct stack *s, struct state *state)
{
	return program_exec(s->p, s->mode, state);
	return program_step(s->p, state);
}

struct error *
stack_next(struct stack *s, struct state *state)
{
	return program_next(s->p, state);
}

void

M src/state/stack.h => src/state/stack.h +3 -0
@@ 56,6 56,9 @@ stack_atend(struct stack *);
struct error *
stack_step(struct stack *, struct state *);

struct error *
stack_next(struct stack *, struct state *);

void
stack_nextstmt(struct stack *s, struct state *state);


M src/state/state.c => src/state/state.c +6 -0
@@ 178,6 178,12 @@ state_step(struct state *s)
	return stack_step(s->stack, s);
}

struct error *
state_next(struct state *s)
{
	return stack_next(s->stack, s);
}

struct externals *
state_getext(struct state *s)
{