Support explicit discards better by allowing multiple declared "_" vars
This commit is contained in:
parent
fe3d45c37a
commit
ec88848f6b
@ -455,6 +455,9 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
|
||||
if (test->expr->tag == Declare) {
|
||||
auto decl = Match(test->expr, Declare);
|
||||
const char *varname = Match(decl->var, Var)->name;
|
||||
if (streq(varname, "_"))
|
||||
return compile_statement(env, WrapAST(ast, DocTest, .expr=decl->value, .output=test->output, .skip_source=test->skip_source));
|
||||
CORD var = CORD_all("$", Match(decl->var, Var)->name);
|
||||
type_t *t = get_type(env, decl->value);
|
||||
CORD val_code = compile_maybe_incref(env, decl->value);
|
||||
@ -560,6 +563,8 @@ CORD compile_statement(env_t *env, ast_t *ast)
|
||||
auto decl = Match(ast, Declare);
|
||||
if (decl->value->tag == Use) {
|
||||
return compile_statement(env, decl->value);
|
||||
} else if (streq(Match(decl->var, Var)->name, "_")) { // Explicit discard
|
||||
return CORD_all("(void)", compile(env, decl->value), ";");
|
||||
} else {
|
||||
type_t *t = get_type(env, decl->value);
|
||||
if (t->tag == AbortType || t->tag == VoidType || t->tag == ReturnType)
|
||||
|
10
typecheck.c
10
typecheck.c
@ -260,6 +260,8 @@ void bind_statement(env_t *env, ast_t *statement)
|
||||
case Declare: {
|
||||
auto decl = Match(statement, Declare);
|
||||
const char *name = Match(decl->var, Var)->name;
|
||||
if (streq(name, "_")) // Explicit discard
|
||||
return;
|
||||
if (get_binding(env, name))
|
||||
code_err(decl->var, "A %T called '%s' has already been defined", get_binding(env, name)->type, name);
|
||||
if (decl->value->tag == Use) {
|
||||
@ -1164,10 +1166,12 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
falsey_scope = fresh_scope(env);
|
||||
bind_statement(falsey_scope, if_->condition);
|
||||
|
||||
truthy_scope = fresh_scope(env);
|
||||
const char *varname = Match(Match(if_->condition, Declare)->var, Var)->name;
|
||||
set_binding(truthy_scope, varname,
|
||||
new(binding_t, .type=Match(condition_type, OptionalType)->type));
|
||||
if (!streq(varname, "_")) {
|
||||
truthy_scope = fresh_scope(env);
|
||||
set_binding(truthy_scope, varname,
|
||||
new(binding_t, .type=Match(condition_type, OptionalType)->type));
|
||||
}
|
||||
} else if (if_->condition->tag == Var) {
|
||||
type_t *condition_type = get_type(env, if_->condition);
|
||||
if (condition_type->tag == OptionalType) {
|
||||
|
Loading…
Reference in New Issue
Block a user