~lbnz/xr0

2fc4cd1583768341bd9a1da632df41c8e6dcbaa1 — Amisi Kiarie 3 months ago 387ad7c
if, for, labels, etc.
4 files changed, 114 insertions(+), 8 deletions(-)

M src/ast/block.c
M src/ast/stmt/stmt.c
M src/ast/variable.c
M tests/99-program/200-init/init.c
M src/ast/block.c => src/ast/block.c +2 -2
@@ 167,12 167,12 @@ ast_block_initprint(struct ast_block *b, char *indent, struct externals *ext)
	struct strbuilder *sb = strbuilder_create();
	for (int i = 0; i < b->ndecl; i++) {
		char *s = ast_variable_initprint(b->decl[i], ext);
		strbuilder_printf(sb, "%s%s", indent, s);
		strbuilder_printf(sb, "%s%s\n", indent, s);
		free(s);
	}
	for (int i = 0; i < b->nstmt; i++) {
		char *s = ast_stmt_initprint(b->stmt[i], indent, ext);
		strbuilder_printf(sb, "%s", s);
		strbuilder_printf(sb, "%s%s\n", indent, s);
		free(s);
	}
	return strbuilder_build(sb);

M src/ast/stmt/stmt.c => src/ast/stmt/stmt.c +108 -4
@@ 584,7 584,19 @@ ast_stmt_str(struct ast_stmt *stmt)
}

static char *
stmt_regular_initprint(struct ast_stmt *, char *indent, struct externals *ext);
regular_initprint(struct ast_stmt *, char *indent, struct externals *ext);

static char *
labelled_initprint(struct ast_stmt *, char *indent, struct externals *ext);

static char *
compound_initprint(struct ast_stmt *, char *indent, struct externals *ext);

static char *
sel_initprint(struct ast_stmt *, char *indent, struct externals *ext);

static char *
iter_initprint(struct ast_stmt *, char *indent, struct externals *ext);

char *
ast_stmt_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)


@@ 593,26 605,118 @@ ast_stmt_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
	case STMT_NOP:
	case STMT_EXPR:
	case STMT_JUMP:
		return stmt_regular_initprint(stmt, indent, ext);
		return regular_initprint(stmt, indent, ext);
	case STMT_LABELLED:
		return labelled_initprint(stmt, indent, ext);
	case STMT_COMPOUND:
		return compound_initprint(stmt, indent, ext);
	case STMT_SELECTION:
		return sel_initprint(stmt, indent, ext);
	case STMT_ITERATION:
		return iter_initprint(stmt, indent, ext);
	default:
		assert(false);
	}
}

static char *
stmt_regular_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
regular_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
{
	/* indent ignored because statement is "regular" and it is the
	 * responsibility of the surrounding block to include it */
	struct strbuilder *b = strbuilder_create();
	char *s = ast_stmt_str(stmt);
	strbuilder_printf(b, "%s%s;\n", indent, s);
	strbuilder_printf(b, "%s\n", s);
	free(s);
	return strbuilder_build(b);
}

static char *
labelled_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
{
	struct strbuilder *b = strbuilder_create();
	char *s = ast_stmt_initprint(stmt->u.labelled.stmt, indent, ext);
	strbuilder_printf(b, "%s: %s;\n", stmt->u.labelled.label, s);
	free(s);
	return strbuilder_build(b);
}

static char *
append(char *s, char *t);

static char *
compound_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
{
	struct strbuilder *b = strbuilder_create();
	strbuilder_printf(b, "{\n");
	char *new_indent = append(indent, "\t");
	char *block = ast_block_initprint(stmt->u.compound, new_indent, ext);
	strbuilder_printf(b, "%s", block);
	free(block);
	free(new_indent);
	strbuilder_printf(b, "%s}", indent);
	return strbuilder_build(b);
}

static char *
append(char *s, char *t)
{
	struct strbuilder *b = strbuilder_create();
	strbuilder_printf(b, "%s%s", s, t);
	return strbuilder_build(b);
}

static char *
sel_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
{
	assert(!stmt->u.selection.isswitch);
	struct strbuilder *b = strbuilder_create();

	char *cond = ast_expr_str(stmt->u.selection.cond),
	     *body = ast_stmt_initprint(stmt->u.selection.body, indent, ext);

	strbuilder_printf(
		b,
		"if (%s) %s",
		cond, body
	);

	struct ast_stmt *nest_stmt = stmt->u.selection.nest;
	if (nest_stmt) {
		char *nest = ast_stmt_initprint(nest_stmt, indent, ext);
		strbuilder_printf(
			b,
			" else %s",
			nest
		);
		free(nest);
	}

	return strbuilder_build(b);
}

static char *
iter_initprint(struct ast_stmt *stmt, char *indent, struct externals *ext)
{
	struct strbuilder *b = strbuilder_create();

	char *init = ast_stmt_str(stmt->u.iteration.init),
	     *cond = ast_stmt_str(stmt->u.iteration.cond),
	     *body = ast_stmt_initprint(stmt->u.iteration.body, indent, ext),
	     *iter = ast_expr_str(stmt->u.iteration.iter);

	strbuilder_printf(
		b,
		"for (%s %s %s) %s",
		init, cond, iter, body
	);

	free(init); free(cond); free(body); free(iter);

	return strbuilder_build(b);
}


bool
ast_stmt_equal(struct ast_stmt *s1, struct ast_stmt *s2)
{

M src/ast/variable.c => src/ast/variable.c +1 -1
@@ 126,7 126,7 @@ ast_variable_initprint(struct ast_variable *v, struct externals *ext)
	struct strbuilder *b = strbuilder_create();
	char *t = ast_type_str(v->type);
	char *init = ast_type_zeroinit(v->type, ext);
	strbuilder_printf(b, "%s %s = %s;\n", t, v->name, init);
	strbuilder_printf(b, "%s %s = %s;", t, v->name, init);
	free(init);
	free(t);
	return strbuilder_build(b);

M tests/99-program/200-init/init.c => tests/99-program/200-init/init.c +3 -1
@@ 27,9 27,11 @@ foo()

	int i;

	if (1) {
	abc: if (1) {
		struct point p3;
		struct man james;
	} else {
		struct list l2;
	}

	for (i = 0; i < 20; i++) {