+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->size, 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->size, 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;
+ }
+ /* no break */
+ case PSI_T_PIPE:
+ case PSI_T_CARET:
+ case PSI_T_AMPERSAND:
+ case PSI_T_LSHIFT:
+ case PSI_T_RSHIFT:
+ case PSI_T_ASTERISK:
+ case PSI_T_SLASH:
+
+ case PSI_T_OR:
+ case PSI_T_AND:
+
+ case PSI_T_CMP_EQ:
+ case PSI_T_CMP_NE:
+ case PSI_T_CMP_LE:
+ case PSI_T_CMP_GE:
+ case PSI_T_RCHEVR:
+ case PSI_T_LCHEVR:
+
+ 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->size, 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;
+}
+