+ list = psi_num_exp_tokens(exp->data.b.lhs, list);
+ ntoken = psi_token_copy(exp->token);
+ list = psi_plist_add(list, &ntoken);
+ list = psi_num_exp_tokens(exp->data.b.rhs, list);
+ break;
+
+ case PSI_T_IIF:
+ list = psi_num_exp_tokens(exp->data.t.cond, list);
+ ntoken = psi_token_copy(exp->token);
+ list = psi_plist_add(list, &ntoken);
+ list = psi_num_exp_tokens(exp->data.t.truthy, list);
+ psi_plist_top(list, &ntoken);
+ ntoken = psi_token_init(PSI_T_COLON, ":", 1, ntoken->col+ntoken->text->len, ntoken->line, ntoken->file);
+ list = psi_plist_add(list, &ntoken);
+ list = psi_plist_add(list, &ntoken);
+ list = psi_num_exp_tokens(exp->data.t.falsy, list);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ return list;
+}
+
+void psi_num_exp_dump(int fd, struct psi_num_exp *exp)
+{
+ switch (exp->op) {
+ case PSI_T_NUMBER:
+ psi_number_dump(fd, exp->data.n);
+ break;
+
+ case PSI_T_CAST:
+ dprintf(fd, "(");
+ psi_decl_type_dump(1, exp->data.c.typ, 0);
+ dprintf(fd, ")");
+ break;
+
+ case PSI_T_NOT:
+ case PSI_T_TILDE:
+ unary:
+ dprintf(fd, "%s", psi_num_exp_op_tok(exp->op));
+ psi_num_exp_dump(fd, exp->data.u);
+ break;
+
+ case PSI_T_LPAREN:
+ dprintf(fd, "(");
+ psi_num_exp_dump(fd, exp->data.u);
+ dprintf(fd, ")");
+ break;
+
+ case PSI_T_PLUS:
+ case PSI_T_MINUS:
+ if (!exp->data.b.rhs) {
+ goto unary;
+ }
+ /* no break */