+static inline int validate_let_val(struct psi_data *data, let_val *val, decl_var *let_var, impl *impl) {
+
+ switch (val->kind) {
+ case PSI_LET_NULL:
+ break;
+ case PSI_LET_TMP:
+ if (!let_var) {
+ data->error(data, NULL, PSI_WARNING,
+ "Ivalid let statement value of implementation '%s'",
+ impl->func->name);
+ return 0;
+ }
+ /* e.g. let bar = &strval($bar); // decl_arg(char **bar) */
+ /* e.g. let foo = *bar; */
+ let_var->pointer_level = val->data.var->pointer_level;
+ let_var->arg = init_decl_arg(
+ init_decl_type(
+ real_decl_type(val->data.var->arg->type)->type,
+ real_decl_type(val->data.var->arg->type)->name),
+ init_decl_var(
+ let_var->name,
+ let_var->pointer_level,
+ let_var->array_size));
+ break;
+ case PSI_LET_NUMEXP:
+ if (!validate_num_exp(data, val->data.num, impl->decl->args, impl->decl->func, NULL)) {
+ return 0;
+ }
+ break;
+ case PSI_LET_CALLOC:
+ if (!validate_num_exp(data, val->data.alloc->nmemb, impl->decl->args, impl->decl->func, NULL)) {
+ return 0;
+ }
+ if (!validate_num_exp(data, val->data.alloc->size, impl->decl->args, impl->decl->func, NULL)) {
+ return 0;
+ }
+ break;
+ case PSI_LET_CALLBACK:
+ if (!let_var) {
+ data->error(data, NULL, PSI_WARNING,
+ "Ivalid let statement value of implementation '%s'",
+ impl->func->name);
+ return 0;
+ }
+ if (val->data.callback->func->inner) {
+ size_t i;
+
+ for (i = 0; i < val->data.callback->func->inner->count; ++i) {
+ let_val *inner = val->data.callback->func->inner->vals[i];
+ switch (inner->kind) {
+ case PSI_LET_FUNC:
+ inner->data.func->outer = val;
+ break;
+ case PSI_LET_CALLBACK:
+ inner->data.callback->func->outer = val;
+ break;
+ }
+ }
+ }
+ if (!validate_let_callback(data, let_var, val->data.callback, impl)) {
+ return 0;
+ }
+ break;
+ case PSI_LET_FUNC:
+ if (val->data.func->inner) {
+ size_t i;
+
+ for (i = 0; i < val->data.func->inner->count; ++i) {
+ let_val *inner = val->data.func->inner->vals[i];
+ switch (inner->kind) {
+ case PSI_LET_FUNC:
+ inner->data.func->outer = val;
+ break;
+ case PSI_LET_CALLBACK:
+ inner->data.callback->func->outer = val;
+ break;
+ }
+ }
+ }
+
+ if (!validate_let_func(data, val->data.func, let_var, impl)) {
+ return 0;
+ }
+ break;
+ }
+
+ return 1;
+}
+
+static inline int validate_impl_let_stmts(struct psi_data *data, impl *impl) {