X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fset_func.c;h=2b5968695c8ec7c2383f67d4b8498ae03c8ca32e;hp=c6ab80fd0ac091aead128c5ad432751bd62f3fbd;hb=c9384515a81cb64d345b299908b2852f51bb8e6e;hpb=b029005e56a8913fbb3d17ab497b4a37a00a211c diff --git a/src/types/set_func.c b/src/types/set_func.c index c6ab80f..2b59686 100644 --- a/src/types/set_func.c +++ b/src/types/set_func.c @@ -202,15 +202,15 @@ static inline bool psi_set_func_validate_to_recursive(struct psi_data *data, } bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, - struct psi_set_exp *set, struct psi_impl *impl, struct psi_decl *cb_decl) + struct psi_validate_scope *scope) { - if (!func->var->arg - && !psi_decl_var_validate(data, func->var, impl, impl->decl, NULL, set) - && !psi_decl_var_validate(data, func->var, NULL, cb_decl, NULL, NULL) - && !psi_impl_get_temp_let_arg(impl, func->var)) { + struct psi_set_exp *set = scope->current_set; + + if (!psi_decl_var_validate(data, func->var, scope) + && !psi_impl_get_temp_let_arg(scope->impl, func->var)) { data->error(data, func->var->token, PSI_WARNING, "Unknown variable '%s' in implementation %s", - func->var->name, impl->func->name); + func->var->name, scope->impl->func->name); return false; } @@ -223,7 +223,6 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, } if (func->inner && (!set->outer || set->outer->inner != func->inner)) { - size_t i = 0; struct psi_set_exp *inner; @@ -232,17 +231,26 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, struct psi_plist *sub_args; inner->outer = set; + scope->current_set = inner; + /* skip to "fail:" if field does not exists */ sub_var = psi_set_exp_get_decl_var(inner); sub_args = psi_decl_type_get_args(func->var->arg->type, NULL); - if (sub_var && sub_args && !psi_decl_arg_get_by_var(sub_var, sub_args, NULL)) { - /* remove expr for portability with different struct members */ - psi_plist_del(func->inner, --i, NULL); - psi_set_exp_free(&inner); - } else if (!psi_set_exp_validate(data, inner, impl, cb_decl)) { - /* remove exp for portability */ - psi_plist_del(func->inner, --i, NULL); + if (sub_var && sub_args) { + if (!psi_decl_arg_get_by_var(sub_var, sub_args, NULL)) { + goto fail; + } + } + + if (psi_set_exp_validate(data, inner, scope)) { + scope->current_set = set; + continue; } + fail: + scope->current_set = set; + /* remove expr for portability with different struct members */ + psi_plist_del(func->inner, --i, NULL); + psi_set_exp_free(&inner); } } @@ -266,19 +274,19 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func, func->handler = psi_set_to_object; break; case PSI_T_TO_STRING: - if (!psi_set_func_validate_to_string(data, func, set, impl)) { + if (!psi_set_func_validate_to_string(data, func, set, scope->impl)) { return false; } break; case PSI_T_TO_ARRAY: - if (!psi_set_func_validate_to_array(data, func, set, impl)) { + if (!psi_set_func_validate_to_array(data, func, set, scope->impl)) { return false; } break; default: data->error(data, func->token, PSI_WARNING, "Unknown cast '%s' in `set` statement of implementation '%s'", - func->name, impl->func->name); + func->name, scope->impl->func->name); return false; }