+struct psi_num_exp *psi_num_exp_init_binary(token_t op,
+ struct psi_num_exp *lhs, struct psi_num_exp *rhs);
+struct psi_num_exp *psi_num_exp_init_unary(token_t op,
+ struct psi_num_exp *u);
+struct psi_num_exp *psi_num_exp_init_num(struct psi_number *n);
+void psi_num_exp_free(struct psi_num_exp **c_ptr);
+
+struct psi_num_exp *psi_num_exp_copy(struct psi_num_exp *exp);
+void psi_num_exp_dump(int fd, struct psi_num_exp *exp);
+bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp,
+ struct psi_impl *impl, struct psi_decl *cb_decl,
+ struct psi_let_exp *current_let, struct psi_set_exp *current_set,
+ struct psi_decl_enum *current_enum);
+
+token_t psi_num_exp_exec(struct psi_num_exp *exp, impl_val *res, struct psi_call_frame *frame);
+
+#include <assert.h>
+
+static inline zend_long psi_long_num_exp(struct psi_num_exp *exp, struct psi_call_frame *frame) {
+ impl_val val = {0};
+
+ switch (psi_num_exp_exec(exp, &val, frame)) {
+ case PSI_T_UINT8: return val.u8;
+ case PSI_T_UINT16: return val.u16;
+ case PSI_T_UINT32: return val.u32;
+ case PSI_T_UINT64: return val.u64; /* FIXME */
+ case PSI_T_INT8: return val.i8;
+ case PSI_T_INT16: return val.i16;
+ case PSI_T_INT32: return val.i32;
+ case PSI_T_INT64: return val.i64;
+ case PSI_T_FLOAT: return val.fval;
+ case PSI_T_DOUBLE: return val.dval;
+ default:
+ assert(0);
+ }
+ return 0;
+}