~lbnz/xr0

68e96dcc645996f5a8027ac50c2f6a1d6825743a — Claude Betz 2 months ago 1a3fffd v0.14.0
feat: else

issue: https://github.com/xr0-org/xr0/issues/38
M include/ast.h => include/ast.h +3 -0
@@ 87,6 87,9 @@ ast_expr_unary_op(struct ast_expr *);
bool
ast_expr_unary_isdereference(struct ast_expr *);

bool
ast_expr_isnot(struct ast_expr *);

struct ast_expr *
ast_expr_unary_operand(struct ast_expr *);


M src/ast/expr/expr.c => src/ast/expr/expr.c +6 -0
@@ 416,6 416,12 @@ ast_expr_unary_isdereference(struct ast_expr *expr)
	return ast_expr_unary_op(expr) == UNARY_OP_DEREFERENCE;
}

bool
ast_expr_isnot(struct ast_expr *expr)
{
	return ast_expr_kind(expr) == EXPR_UNARY &&
		ast_expr_unary_op(expr) == UNARY_OP_BANG;
}

static void
ast_expr_unary_str_build(struct ast_expr *expr, struct strbuilder *b)

M src/ast/gram.y => src/ast/gram.y +2 -10
@@ 745,17 745,9 @@ selection_statement
	: IF '(' expression ')' statement
		{ $$ = ast_stmt_create_sel(lexloc(), false, $3, $5, NULL); }
	| IF '(' expression ')' statement ELSE statement
		{
			struct ast_expr *neg_cond = ast_expr_unary_create(
				ast_expr_copy($3), UNARY_OP_BANG
			);
			struct ast_stmt *_else = ast_stmt_create_sel(
				lexloc(), false, neg_cond, $7, NULL
			); 
			$$ = ast_stmt_create_sel(lexloc(), false, $3, $5, _else);
		}
		{ $$ = ast_stmt_create_sel(lexloc(), false, $3, $5, $7); }
	| SWITCH '(' expression ')' statement
		{ $$ = ast_stmt_create_nop(lexloc()); }
		{ assert(false); }
	;

for_some

M src/ast/stmt/verify.c => src/ast/stmt/verify.c +21 -9
@@ 216,14 216,18 @@ stmt_compound_exec(struct ast_stmt *stmt, struct state *state)
static struct error *
stmt_sel_exec(struct ast_stmt *stmt, struct state *state)
{
	struct decision dec = sel_decide(ast_stmt_sel_cond(stmt), state);
	struct ast_expr *cond = ast_stmt_sel_cond(stmt);
	struct ast_stmt *body = ast_stmt_sel_body(stmt),
			*nest = ast_stmt_sel_nest(stmt);
	struct decision dec = sel_decide(cond, state);
	if (dec.err) {
		return dec.err;
	}
	if (dec.decision) {
		return ast_stmt_exec(ast_stmt_sel_body(stmt), state);
		return ast_stmt_exec(body, state);
	} else if (nest) {
		return ast_stmt_exec(nest, state);
	}
	assert(!ast_stmt_sel_nest(stmt));
	return NULL;
}



@@ 388,14 392,18 @@ expr_absexec(struct ast_expr *expr, struct state *state)
static struct error *
sel_absexec(struct ast_stmt *stmt, struct state *state, bool should_setup)
{
	struct decision dec = sel_decide(ast_stmt_sel_cond(stmt), state);
	struct ast_expr *cond = ast_stmt_sel_cond(stmt);
	struct ast_stmt *body = ast_stmt_sel_body(stmt),
			*nest = ast_stmt_sel_nest(stmt);
	struct decision dec = sel_decide(cond, state);
	if (dec.err) {
		return dec.err;
	}
	if (dec.decision) {
		return ast_stmt_absexec(ast_stmt_sel_body(stmt), state, should_setup);
		return ast_stmt_absexec(body, state, should_setup);
	} else if (nest) {
		return ast_stmt_absexec(nest, state, should_setup);
	}
	assert(!ast_stmt_sel_nest(stmt));
	return NULL;
}



@@ 547,14 555,18 @@ labelled_setupabsexec(struct ast_stmt *stmt, struct state *state)
static struct error *
sel_setupabsexec(struct ast_stmt *stmt, struct state *state)
{
	struct decision dec = sel_decide(ast_stmt_sel_cond(stmt), state);
	struct ast_expr *cond = ast_stmt_sel_cond(stmt);
	struct ast_stmt *body = ast_stmt_sel_body(stmt),
			*nest = ast_stmt_sel_nest(stmt);
	struct decision dec = sel_decide(cond, state);
	if (dec.err) {
		return dec.err;
	}
	if (dec.decision) {
		return stmt_setupabsexec(ast_stmt_sel_body(stmt), state);
		return stmt_setupabsexec(body, state);
	} else if (nest) {
		return stmt_setupabsexec(nest, state);
	}
	assert(!ast_stmt_sel_nest(stmt));
	return NULL;
}


M src/props/props.c => src/props/props.c +4 -0
@@ 77,6 77,10 @@ props_install(struct props *p, struct ast_expr *e)
bool
props_get(struct props *p, struct ast_expr *e)
{
	/* XXX: hack for shallow not conditions, fix in TODO */
	if (ast_expr_isnot(e)) {
		return !props_contradicts(p, e);
	}
	for (int i = 0; i < p->n; i++) {
		/* TODO: logical comparison */
		if (ast_expr_equal(e, p->prop[i])) {

A tests/1-branches/0101-body-trivial-else.x => tests/1-branches/0101-body-trivial-else.x +11 -0
@@ 0,0 1,11 @@
#include <stdlib.h>

void *
test(int x) ~ [ return .malloc(1); ]
{
	if (x) {
		return malloc(1);
	} else {
		return malloc(1);
	}
}

A tests/1-branches/0102-body-trivial-else-if.x => tests/1-branches/0102-body-trivial-else-if.x +13 -0
@@ 0,0 1,13 @@
#include <stdlib.h>

void *
test(int x) ~ [ return .malloc(1); ]
{
	if (x) {
		return malloc(1);
	} else if (x) {
		return malloc(1);
	} else {
		return malloc(1);
	}
}

A tests/1-branches/0201-conditional-allocation-else.x => tests/1-branches/0201-conditional-allocation-else.x +12 -0
@@ 0,0 1,12 @@
#include <stdlib.h>

void *
test(int x) ~ [
	if (x) {
		return .malloc(1);
	} else {
		return .malloc(1);
	}
]{
	return malloc(1);
}

A tests/1-branches/0301-conditional-allocation-two.x => tests/1-branches/0301-conditional-allocation-two.x +17 -0
@@ 0,0 1,17 @@
#include <stdlib.h>

void *
test(int x, int y) ~ [
	if (x) {
		return .malloc(1);
	} else if (y) {
		return NULL;
	} else {
		return .malloc(1);
	}
]{
	if (!y) {
		return malloc(1);
	}
	return NULL;
}