+ if (val->type == PSI_T_NULL) {
+ return true;
+ } else if (val->type == PSI_T_NUMBER) {
+ if (!psi_num_exp_validate(data, val->data.num, scope)) {
+ return false;
+ }
+ }
+
+ switch (type ? type->type : PSI_T_MIXED) {
+ case PSI_T_BOOL:
+ val->ival.zend.bval = val->type == PSI_T_TRUE ? 1 : 0;
+ return true;
+ break;
+
+ /* macros */
+ case PSI_T_NUMBER:
+ if (val->type == PSI_T_NUMBER) {
+ token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp);
+
+ switch (typ) {
+ case PSI_T_FLOAT:
+ val->ival.dval = val->ival.fval;
+ /* no break */
+ case PSI_T_DOUBLE:
+ val->type = PSI_T_FLOAT;
+ type->type = PSI_T_FLOAT;
+ zend_string_release(type->name);
+ type->name = zend_string_init_interned(ZEND_STRL("float"), 1);
+ break;
+ case PSI_T_UINT64:
+ if (val->ival.u64 > ZEND_LONG_MAX) {
+ data->error(data, val->token, PSI_WARNING,
+ "Integer too big for signed representation: '%" PRIu64 "'",
+ val->ival.u64);
+ }
+ default:
+ /* FIXME big integers */
+ val->type = PSI_T_INT;
+ type->type = PSI_T_INT;
+ zend_string_release(type->name);
+ type->name = zend_string_init_interned(ZEND_STRL("int"), 1);
+ break;
+ }
+ psi_num_exp_free(&val->data.num);
+ return true;
+ }
+ break;
+
+ case PSI_T_INT:
+ if (val->type == PSI_T_NUMBER) {
+ val->type = PSI_T_INT;
+ val->ival.zend.lval = psi_num_exp_get_long(val->data.num, NULL, scope->cpp);
+#if PSI_IMPL_DEF_VAL_DEBUG
+ PSI_DEBUG_PRINT(data, "PSI: NUMBER (long) %" PRIi64 " from ", val->ival.zend.lval);
+ PSI_DEBUG_DUMP(data, psi_num_exp_dump, val->data.num);
+ PSI_DEBUG_PRINT(data, "\n");
+#endif
+ psi_num_exp_free(&val->data.num);
+ }
+ if (val->type == PSI_T_INT) {
+ return true;
+ }
+ break;
+
+ case PSI_T_FLOAT:
+ case PSI_T_DOUBLE:
+ if (val->type == PSI_T_NUMBER) {
+ val->type = PSI_T_DOUBLE;
+ val->ival.dval = psi_num_exp_get_double(val->data.num, NULL, scope->cpp);
+#if PSI_IMPL_DEF_VAL_DEBUG
+ PSI_DEBUG_PRINT(data, "PSI: NUMBER (double) %" PRIdval " from ", val->ival.dval);
+ PSI_DEBUG_DUMP(data, psi_num_exp_dump, val->data.num);
+ PSI_DEBUG_PRINT(data, "\n");
+#endif
+ psi_num_exp_free(&val->data.num);
+ }
+ if (val->type == PSI_T_DOUBLE) {
+ return true;
+ }
+ break;
+
+ case PSI_T_STRING:
+ if (val->type == PSI_T_STRING) {
+ return true;
+ }
+ break;
+
+ case PSI_T_MIXED:
+ switch (val->type) {
+ case PSI_T_TRUE:
+ case PSI_T_FALSE:
+ case PSI_T_NULL:
+ case PSI_T_STRING: