void psi_to_int(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_double(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val);
+void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val);
void psi_to_array(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_object(zval *return_value, set_value *set, impl_val *ret_val);
to_int(ai_socktype),
to_int(ai_protocol),
to_int(ai_addrlen),
- to_array(ai_addr,
- to_int(sa_family),
- to_string(sa_data, ai_addrlen)
- ),
- to_string(ai_canonname)
- // FIXME ai_next
+ to_string(ai_addr, ai_addrlen),
+ to_string(ai_canonname),
+ to_array(ai_next, ...)
);
}
\ No newline at end of file
case PSI_T_VOID:
set->func->handler = psi_to_void;
break;
+ case PSI_T_ELLIPSIS:
+ if (set->outer.set && set->outer.set->func->type == PSI_T_TO_ARRAY) {
+ set->func->handler = psi_to_recursive;
+ break;
+ }
+ /* no break */
default:
return 0;
}
decl_var *set_var = set->vars->vars[0];
if (!validate_set_value_handler(set)) {
- data->error(set->func->token, PSI_WARNING, "Invalid cast '%s'", set->func->name);
+ data->error(set->func->token, PSI_WARNING, "Invalid cast '%s' in `set` statement", set->func->name);
return 0;
}
for (i = 0; i < set->vars->count; ++i) {
decl_var *svar = set->vars->vars[i];
if (!svar->arg && !locate_decl_var_arg(svar, ref_list, NULL)) {
- data->error(svar->token, PSI_WARNING, "Unknown variable '%s'", svar->name);
+ data->error(svar->token, PSI_WARNING, "Unknown variable '%s' in `set` statement", svar->name);
return 0;
}
}
decl_var *sub_var = set->inner[i]->vars->vars[0];
decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var);
- set->inner[i]->outer.set = set;
if (sub_ref) {
if (!validate_set_value_ex(data, set->inner[i], sub_ref, ref_type->strct->args)) {
return 0;
decl_var *sub_var = set->inner[0]->vars->vars[0];
decl_arg *sub_ref = locate_decl_var_arg(sub_var, ref_list, ref);
- set->inner[0]->outer.set = set;
if (sub_ref) {
if (strcmp(sub_var->name, set_var->name)) {
data->error(sub_var->token, E_WARNING, "Inner `set` statement casts on pointers must reference the same variable");
exp = exp->operand;
}
}
+
static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) {
- size_t i;
+ size_t i, j;
if (level > 1) {
/* only if not directly after `set ...` */
dump_level(fd, level);
}
- dprintf(fd, "%s(", set->func->name);
+
+ if (set->func->type == PSI_T_ELLIPSIS) {
+ dprintf(fd, "%s(", set->outer.set->func->name);
+ } else {
+ dprintf(fd, "%s(", set->func->name);
+ }
for (i = 0; i < set->vars->count; ++i) {
decl_var *svar = set->vars->vars[i];
}
dump_decl_var(fd, svar);
}
+
+ if (set->func->type == PSI_T_ELLIPSIS) {
+ dprintf(fd, ", ...");
+ }
if (set->num) {
dprintf(fd, ", ");
dump_num_exp(fd, set->num);
token_t t = real_decl_type(var->arg->type)->type;
switch (t) {
+ case PSI_T_FLOAT:
+ RETVAL_DOUBLE((double) deref_impl_val(ret_val, var)->fval);
+ break;
+ case PSI_T_DOUBLE:
+ RETVAL_DOUBLE(deref_impl_val(ret_val, var)->dval);
+ break;
+ default:
case PSI_T_VOID:
case PSI_T_INT8:
case PSI_T_UINT8:
}
}
return;
- case PSI_T_FLOAT:
- RETVAL_DOUBLE((double) deref_impl_val(ret_val, var)->fval);
- break;
- case PSI_T_DOUBLE:
- RETVAL_DOUBLE(deref_impl_val(ret_val, var)->dval);
- break;
- default:
psi_to_int(return_value, set, ret_val);
break;
}
return mem;
}
+void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val)
+{
+ set->outer.set->func->handler(return_value, set->outer.set, r_val->ptr);
+}
+
void psi_to_array(zval *return_value, set_value *set, impl_val *r_val)
{
size_t i;
static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
val->inner[val->count-1] = inner;
+ inner->outer.set = val;
return val;
}
static inline void free_set_value(set_value *val) {
- free_set_func(val->func);
- free_decl_vars(val->vars);
+ if (val->func) {
+ free_set_func(val->func);
+ }
+ if (val->vars) {
+ free_decl_vars(val->vars);
+ }
if (val->inner) {
size_t i;
for (i = 0; i < val->count; ++i) {
val = init_set_value(func, init_decl_vars(var));
val->num = num_;
}
+set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA ELLIPSIS(T) RPAREN. {
+ free_set_func(func_);
+ val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var));
+ val->func->token = T;
+}
set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA set_vals(vals) RPAREN. {
val = vals;
val->func = func_;