aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-03-11 14:23:41 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-03-11 14:23:41 -0400
commite7035e6a861c1d5e8a4917e31b1e8b722b54d55b (patch)
tree270eb3d1d61de7ad795472fc374aee94583aa647 /compile.c
parent26476a0b41c480a5eb2c4ade835f48c70070d146 (diff)
Clean up doctest code a bit
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c68
1 files changed, 27 insertions, 41 deletions
diff --git a/compile.c b/compile.c
index 87ae0edd..5882aae1 100644
--- a/compile.c
+++ b/compile.c
@@ -875,6 +875,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (norm && norm != buf) free(norm);
}
+ CORD setup = CORD_EMPTY;
+ CORD test_code;
if (test->expr->tag == Declare) {
auto decl = Match(test->expr, Declare);
const char *varname = Match(decl->var, Var)->name;
@@ -887,15 +889,9 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
assert(promote(env, decl->value, &val_code, t, Type(ClosureType, t)));
t = Type(ClosureType, t);
}
- return CORD_asprintf(
- "%r;\n"
- "test((%r = %r), %r, %r, %ld, %ld);\n",
- compile_declaration(t, var),
- var, val_code,
- compile_type_info(env, get_type(env, decl->value)),
- compile_string_literal(output),
- (int64_t)(test->expr->start - test->expr->file->text),
- (int64_t)(test->expr->end - test->expr->file->text));
+ setup = CORD_all(compile_declaration(t, var), ";\n");
+ test_code = CORD_all("(", var, " = ", val_code, ")");
+ expr_t = t;
} else if (test->expr->tag == Assign) {
auto assign = Match(test->expr, Assign);
if (!assign->targets->next && assign->targets->ast->tag == Var && is_idempotent(assign->targets->ast)) {
@@ -908,22 +904,16 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
code_err(test->expr, "Stack references cannot be assigned to variables because the variable's scope may outlive the scope of the stack memory.");
env_t *val_scope = with_enum_scope(env, lhs_t);
CORD value = compile_to_type(val_scope, assign->values->ast, lhs_t);
- return CORD_asprintf(
- "test((%r), %r, %r, %ld, %ld);",
- compile_assignment(env, assign->targets->ast, value),
- compile_type_info(env, lhs_t),
- compile_string_literal(output),
- (int64_t)(test->expr->start - test->expr->file->text),
- (int64_t)(test->expr->end - test->expr->file->text));
+ test_code = CORD_all("(", compile_assignment(env, assign->targets->ast, value), ")");
+ expr_t = lhs_t;
} else {
// Multi-assign or assignment to potentially non-idempotent targets
if (output && assign->targets->next)
code_err(ast, "Sorry, but doctesting with '=' is not supported for multi-assignments");
- CORD code = "test(({ // Assignment\n";
+ test_code = "({ // Assignment\n";
int64_t i = 1;
- type_t *first_type = NULL;
for (ast_list_t *target = assign->targets, *value = assign->values; target && value; target = target->next, value = value->next) {
type_t *lhs_t = get_type(env, target->ast);
if (target->ast->tag == Index && lhs_t->tag == OptionalType
@@ -932,21 +922,16 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (has_stack_memory(lhs_t))
code_err(ast, "Stack references cannot be assigned to variables because the variable's scope may outlive the scope of the stack memory.");
if (target == assign->targets)
- first_type = lhs_t;
+ expr_t = lhs_t;
env_t *val_scope = with_enum_scope(env, lhs_t);
CORD val_code = compile_to_type(val_scope, value->ast, lhs_t);
- CORD_appendf(&code, "%r $%ld = %r;\n", compile_type(lhs_t), i++, val_code);
+ CORD_appendf(&test_code, "%r $%ld = %r;\n", compile_type(lhs_t), i++, val_code);
}
i = 1;
for (ast_list_t *target = assign->targets; target; target = target->next)
- code = CORD_all(code, compile_assignment(env, target->ast, CORD_asprintf("$%ld", i++)), ";\n");
+ test_code = CORD_all(test_code, compile_assignment(env, target->ast, CORD_asprintf("$%ld", i++)), ";\n");
- CORD_appendf(&code, "$1; }), %r, %r, %ld, %ld);",
- compile_type_info(env, first_type),
- compile_string_literal(output),
- (int64_t)(test->expr->start - test->expr->file->text),
- (int64_t)(test->expr->end - test->expr->file->text));
- return code;
+ test_code = CORD_all(test_code, "$1; })");
}
} else if (test->expr->tag == UpdateAssign) {
type_t *lhs_t = get_type(env, Match(test->expr, UpdateAssign)->lhs);
@@ -961,27 +946,28 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
ast_t *update_var = WrapAST(ast, UpdateAssign,
.lhs=WrapAST(update->lhs, InlineCCode, .code="(*expr)", .type=lhs_t),
.op=update->op, .rhs=update->rhs);
- return CORD_asprintf(
- "test(({%r = &(%r); %r; *expr;}), %r, %r, %ld, %ld);",
- compile_declaration(Type(PointerType, lhs_t), "expr"),
- compile_lvalue(env, update->lhs),
- compile_statement(env, update_var),
- compile_type_info(env, lhs_t),
- compile_string_literal(output),
- (int64_t)(test->expr->start - test->expr->file->text),
- (int64_t)(test->expr->end - test->expr->file->text));
+ test_code = CORD_all("({",
+ compile_declaration(Type(PointerType, lhs_t), "expr"), " = &(", compile_lvalue(env, update->lhs), "); ",
+ compile_statement(env, update_var), "; *expr; })");
+ expr_t = lhs_t;
} else if (expr_t->tag == VoidType || expr_t->tag == AbortType || expr_t->tag == ReturnType) {
+ test_code = CORD_all("({", compile_statement(env, test->expr), " NULL;})");
+ } else {
+ test_code = compile(env, test->expr);
+ }
+ if (test->output) {
return CORD_asprintf(
- "test(({%r NULL;}), NULL, NULL, %ld, %ld);",
- compile_statement(env, test->expr),
+ "%rtest(%r, %r, %r, %ld, %ld);",
+ setup, test_code,
+ compile_type_info(env, expr_t),
+ compile_string_literal(output),
(int64_t)(test->expr->start - test->expr->file->text),
(int64_t)(test->expr->end - test->expr->file->text));
} else {
return CORD_asprintf(
- "test(%r, %r, %r, %ld, %ld);",
- compile(env, test->expr),
+ "%rinspect(%r, %r, %ld, %ld);",
+ setup, test_code,
compile_type_info(env, expr_t),
- compile_string_literal(output),
(int64_t)(test->expr->start - test->expr->file->text),
(int64_t)(test->expr->end - test->expr->file->text));
}