+ free(c);
+ }
+}
+
+static inline const char *psi_num_exp_op_tok(token_t op)
+{
+ switch (op) {
+ case PSI_T_NOT:
+ return "!";
+ case PSI_T_TILDE:
+ return "~";
+ case PSI_T_LPAREN:
+ return "(";
+ case PSI_T_CAST:
+ return "(cast)";
+
+ case PSI_T_PIPE:
+ return "|";
+ case PSI_T_CARET:
+ return "^";
+ case PSI_T_AMPERSAND:
+ return "&";
+
+ case PSI_T_LSHIFT:
+ return "<<";
+ case PSI_T_RSHIFT:
+ return ">>";
+
+ case PSI_T_PLUS:
+ return "+";
+ case PSI_T_MINUS:
+ return "-";
+
+ case PSI_T_ASTERISK:
+ return "*";
+ case PSI_T_SLASH:
+ return "/";
+ case PSI_T_MODULO:
+ return "%";
+
+ case PSI_T_OR:
+ return "||";
+ case PSI_T_AND:
+ return "&&";
+
+ case PSI_T_CMP_EQ:
+ return "==";
+ case PSI_T_CMP_NE:
+ return "!=";
+ case PSI_T_CMP_LE:
+ return "<=";
+ case PSI_T_CMP_GE:
+ return ">=";
+ case PSI_T_RCHEVR:
+ return ">";
+ case PSI_T_LCHEVR:
+ return "<";
+
+ case PSI_T_IIF:
+ return "?";
+
+ default:
+ assert(0);
+ }
+ return 0;
+}
+
+struct psi_plist *psi_num_exp_tokens(struct psi_num_exp *exp,
+ struct psi_plist *list)
+{
+ struct psi_token *ntoken;
+ if (!list) {
+ list = psi_plist_init((psi_plist_dtor) psi_token_free);
+ }
+
+ switch (exp->op) {
+ case PSI_T_NUMBER:
+ list = psi_number_tokens(exp->data.n, list);
+ break;
+
+ case PSI_T_CAST:
+ ntoken = exp->data.c.typ->token;
+ ntoken = psi_token_init(PSI_T_LPAREN, "(", 1, ntoken->col-1, ntoken->line, ntoken->file);
+ list = psi_plist_add(list, &ntoken);
+ ntoken = psi_token_copy(exp->data.c.typ->token);
+ list = psi_plist_add(list, &ntoken);
+ ntoken = psi_token_init(PSI_T_RPAREN, ")", 1, ntoken->col+ntoken->text->len, ntoken->line, ntoken->file);
+ list = psi_plist_add(list, &ntoken);
+ break;
+
+ case PSI_T_NOT:
+ case PSI_T_TILDE:
+ unary:
+ ntoken = psi_token_copy(exp->token);
+ list = psi_plist_add(list, &ntoken);
+ list = psi_num_exp_tokens(exp->data.u, list);
+ break;
+
+ case PSI_T_LPAREN:
+ ntoken = psi_token_copy(exp->token);
+ list = psi_plist_add(list, &ntoken);
+ list = psi_num_exp_tokens(exp->data.u, list);
+ psi_plist_top(list, &ntoken);
+ ntoken = psi_token_init(PSI_T_RPAREN, ")", 1, ntoken->col+ntoken->text->len, ntoken->line, ntoken->file);
+ list = psi_plist_add(list, &ntoken);
+ break;
+
+ case PSI_T_PLUS:
+ case PSI_T_MINUS:
+ if (!exp->data.b.rhs) {
+ goto unary;