1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
26 #include "php_psi_stdinc.h"
36 #include "Zend/zend_constants.h"
37 #include "Zend/zend_operators.h"
40 struct psi_number
*psi_number_init(token_t t
, void *num
, unsigned flags
)
42 struct psi_number
*exp
= pecalloc(1, sizeof(*exp
), 1);
45 switch (exp
->type
= t
) {
47 exp
->data
.ival
.i8
= *(int8_t *) num
;
51 exp
->data
.ival
.u8
= *(uint8_t *) num
;
54 exp
->data
.ival
.i16
= *(int16_t *) num
;
57 exp
->data
.ival
.u16
= *(uint16_t *) num
;
60 exp
->data
.ival
.i32
= *(int32_t *) num
;
63 exp
->data
.ival
.u32
= *(uint32_t *) num
;
66 exp
->data
.ival
.i64
= *(int64_t *) num
;
69 exp
->data
.ival
.u64
= *(uint64_t *) num
;
72 exp
->data
.ival
.fval
= *(float *) num
;
75 exp
->data
.ival
.dval
= *(double *) num
;
78 case PSI_T_LONG_DOUBLE
:
79 exp
->data
.ival
.ldval
= *(long double *) num
;
84 case PSI_T_QUOTED_CHAR
:
88 case PSI_T_CPP_HEADER
:
89 exp
->data
.numb
= zend_string_copy(num
);
107 struct psi_number
*psi_number_copy(struct psi_number
*exp
)
109 struct psi_number
*num
= pecalloc(1, sizeof(*num
), 1);
114 num
->token
= psi_token_copy(num
->token
);
129 case PSI_T_LONG_DOUBLE
:
138 case PSI_T_QUOTED_CHAR
:
139 case PSI_T_CPP_HEADER
:
140 num
->data
.numb
= zend_string_copy(num
->data
.numb
);
143 num
->data
.dvar
= psi_decl_var_copy(num
->data
.dvar
);
146 num
->data
.call
= psi_cpp_macro_call_copy(num
->data
.call
);
149 num
->data
.dtyp
= psi_decl_type_copy(num
->data
.dtyp
);
157 void psi_number_free(struct psi_number
**exp_ptr
)
160 struct psi_number
*exp
= *exp_ptr
;
163 psi_token_free(&exp
->token
);
177 case PSI_T_LONG_DOUBLE
:
184 psi_cpp_macro_call_free(&exp
->data
.call
);
189 case PSI_T_QUOTED_CHAR
:
190 case PSI_T_CPP_HEADER
:
191 zend_string_release(exp
->data
.numb
);
194 psi_decl_var_free(&exp
->data
.dvar
);
197 psi_decl_type_free(&exp
->data
.dtyp
);
206 struct psi_plist
*psi_number_tokens(struct psi_number
*exp
,
207 struct psi_plist
*list
)
209 struct psi_token
*ntoken
;
213 list
= psi_plist_init((psi_plist_dtor
) psi_token_free
);
219 ntoken
= psi_token_copy(exp
->data
.dvar
->token
);
221 if (exp
->data
.dvar
->pointer_level
> 1 || !exp
->data
.dvar
->array_size
) {
222 struct psi_token
*temp
= ntoken
;
223 unsigned pl
= exp
->data
.dvar
->pointer_level
- !!exp
->data
.dvar
->array_size
;
226 ntoken
= psi_token_init(PSI_T_POINTER
, "*", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
227 list
= psi_plist_add(list
, &ntoken
);
232 list
= psi_plist_add(list
, &ntoken
);
234 if (exp
->data
.dvar
->array_size
) {
235 char buf
[0x20], *ptr
;
237 ntoken
= psi_token_init(PSI_T_LBRACKET
, "[", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
238 list
= psi_plist_add(list
, &ntoken
);
239 ptr
= zend_print_ulong_to_buf(&buf
[sizeof(buf
) - 1], exp
->data
.dvar
->array_size
);
241 ntoken
= psi_token_init(PSI_T_NUMBER
, ptr
, strlen(ptr
), ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
242 list
= psi_plist_add(list
, &ntoken
);
248 ntoken
= psi_token_copy(exp
->token
);
249 list
= psi_plist_add(list
, &ntoken
);
250 ntoken
= psi_token_init(PSI_T_LPAREN
, "(", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
251 list
= psi_plist_add(list
, &ntoken
);
252 ntoken
= psi_token_copy(exp
->data
.dtyp
->token
);
253 list
= psi_plist_add(list
, &ntoken
);
254 ntoken
= psi_token_init(PSI_T_RPAREN
, ")", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
255 list
= psi_plist_add(list
, &ntoken
);
259 ntoken
= psi_token_copy(exp
->token
);
260 list
= psi_plist_add(list
, &ntoken
);
261 ntoken
= psi_token_init(PSI_T_LPAREN
, "(", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
262 list
= psi_plist_add(list
, &ntoken
);
263 for (i
= 0; i
< psi_plist_count(exp
->data
.call
->args
); ++i
) {
264 struct psi_num_exp
*tmp_exp
;
267 ntoken
= psi_token_init(PSI_T_COMMA
, ",", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
268 list
= psi_plist_add(list
, &ntoken
);
270 if (psi_plist_get(exp
->data
.call
->args
, i
, &tmp_exp
)) {
271 struct psi_plist
*tmp
= psi_num_exp_tokens(tmp_exp
, NULL
);
272 list
= psi_plist_add_r(list
, psi_plist_count(tmp
), psi_plist_eles(tmp
));
273 psi_plist_top(list
, &ntoken
);
277 ntoken
= psi_token_init(PSI_T_RPAREN
, ")", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
278 list
= psi_plist_add(list
, &ntoken
);
282 ntoken
= psi_token_init(PSI_T_DEFINED
, "defined", sizeof("defined")-1, exp
->token
->col
, exp
->token
->line
, exp
->token
->file
);
283 list
= psi_plist_add(list
, &ntoken
);
287 ntoken
= psi_token_copy(exp
->token
);
288 list
= psi_plist_add(list
, &ntoken
);
295 void psi_number_dump(struct psi_dump
*dump
, struct psi_number
*exp
)
299 CASE_IMPLVAL_NUM_PRINTF(dump
->fun
, dump
->ctx
, exp
->data
.ival
, 1);
301 PSI_DUMP(dump
, "NULL");
306 case PSI_T_QUOTED_CHAR
:
307 case PSI_T_CPP_HEADER
:
308 PSI_DUMP(dump
, "%s", exp
->data
.numb
->val
);
311 psi_cpp_macro_call_dump(dump
, exp
->data
.call
);
314 PSI_DUMP(dump
, "%s", exp
->data
.cnst
->name
->val
);
317 PSI_DUMP(dump
, "%s", exp
->data
.enm
->name
->val
);
320 psi_decl_var_dump(dump
, exp
->data
.dvar
);
323 PSI_DUMP(dump
, "sizeof(");
324 psi_decl_type_dump(dump
, exp
->data
.dtyp
, 0);
332 static inline bool psi_number_validate_enum(struct psi_data
*data
,
333 struct psi_number
*exp
, struct psi_validate_scope
*scope
)
335 if (scope
&& scope
->current_enum
) {
337 struct psi_decl_enum_item
*itm
;
338 struct psi_decl_enum
*enm
;
340 enm
= scope
->current_enum
;
344 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
345 if (zend_string_equals(itm
->name
, exp
->data
.dvar
->name
)) {
346 psi_decl_var_free(&exp
->data
.dvar
);
347 exp
->type
= PSI_T_ENUM
;
349 return psi_number_validate(data
, exp
, scope
);
355 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
356 if (zend_string_equals(itm
->name
, exp
->data
.numb
)) {
357 zend_string_release(exp
->data
.numb
);
358 exp
->type
= PSI_T_ENUM
;
360 return psi_number_validate(data
, exp
, scope
);
372 static inline token_t
validate_char(char *numb
, impl_val
*res
, unsigned *lvl
)
375 token_t typ
= PSI_T_INT8
;
386 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
387 res
->i8
= strtol(&numb
[1], &endptr
, 8);
391 res
->i8
= strtol(&numb
[2], &endptr
, 16);
425 impl_val tmp_val
= {0};
426 token_t tmp_typ
= validate_char(endptr
, &tmp_val
, lvl
);
432 res
->i32
= res
->i8
<< (8 * *lvl
);
433 typ
= psi_calc_add(PSI_T_INT32
, res
, tmp_typ
, &tmp_val
, res
);
440 static inline bool psi_number_validate_char(struct psi_data
*data
, struct psi_number
*exp
)
444 token_t typ
= validate_char(exp
->data
.numb
->val
, &val
, &lvl
);
450 zend_string_release(exp
->data
.numb
);
452 exp
->data
.ival
= val
;
456 static inline bool psi_number_validate_number(struct psi_data
*data
, struct psi_number
*exp
)
461 switch (exp
->flags
& 0x0f) {
463 switch (exp
->flags
& 0x0f00) {
466 tmp
.i64
= strtol(exp
->data
.numb
->val
, NULL
, 0);
467 zend_string_release(exp
->data
.numb
);
468 exp
->type
= PSI_T_INT64
;
469 exp
->data
.ival
.i64
= tmp
.i64
;
472 tmp
.i64
= strtoll(exp
->data
.numb
->val
, NULL
, 0);
473 zend_string_release(exp
->data
.numb
);
474 exp
->type
= PSI_T_INT64
;
475 exp
->data
.ival
.i64
= tmp
.i64
;
479 tmp
.u64
= strtoul(exp
->data
.numb
->val
, NULL
, 0);
480 zend_string_release(exp
->data
.numb
);
481 exp
->type
= PSI_T_UINT64
;
482 exp
->data
.ival
.u64
= tmp
.u64
;
485 tmp
.u64
= strtoull(exp
->data
.numb
->val
, NULL
, 0);
486 zend_string_release(exp
->data
.numb
);
487 exp
->type
= PSI_T_UINT64
;
488 exp
->data
.ival
.u64
= tmp
.u64
;
494 switch (exp
->flags
& 0x0ff00) {
496 tmp
.fval
= strtof(exp
->data
.numb
->val
, NULL
);
497 zend_string_release(exp
->data
.numb
);
498 exp
->type
= PSI_T_FLOAT
;
499 exp
->data
.ival
.fval
= tmp
.fval
;
504 tmp
.ldval
= strtold(exp
->data
.numb
->val
, NULL
);
505 zend_string_release(exp
->data
.numb
);
506 exp
->type
= PSI_T_LONG_DOUBLE
;
507 exp
->data
.ival
.ldval
= tmp
.ldval
;
513 tmp
.dval
= strtod(exp
->data
.numb
->val
, NULL
);
514 zend_string_release(exp
->data
.numb
);
515 exp
->type
= PSI_T_DOUBLE
;
516 exp
->data
.ival
.dval
= tmp
.dval
;
525 int type
= is_numeric_string(exp
->data
.numb
->val
, exp
->data
.numb
->len
, (zend_long
*) &tmp
, (double *)&tmp
, 0);
532 zend_string_release(exp
->data
.numb
);
533 exp
->type
= PSI_T_INT64
;
534 exp
->data
.ival
.i64
= tmp
.zend
.lval
;
538 zend_string_release(exp
->data
.numb
);
539 exp
->type
= PSI_T_DOUBLE
;
540 exp
->data
.ival
.dval
= tmp
.dval
;
547 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
548 lval
= strtol(exp
->data
.numb
->val
, &stop
, 0);
551 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
557 if (errno
== ERANGE
) {
560 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
561 ulval
= strtoul(exp
->data
.numb
->val
, &stop
, 0);
564 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
568 zend_string_release(exp
->data
.numb
);
569 exp
->type
= PSI_T_UINT64
;
570 exp
->data
.ival
.u64
= ulval
;
576 zend_string_release(exp
->data
.numb
);
577 exp
->type
= PSI_T_INT64
;
578 exp
->data
.ival
.i64
= lval
;
582 data
->error(data
, exp
->token
, PSI_WARNING
, "Not a numeric string: '%s'", exp
->data
.numb
->val
);
585 data
->error(data
, exp
->token
, PSI_WARNING
, "Expected numeric entity (parser error?)");
589 bool psi_number_validate(struct psi_data
*data
, struct psi_number
*exp
,
590 struct psi_validate_scope
*scope
)
593 struct psi_const
*cnst
;
594 struct psi_decl_enum
*enm
;
598 exp
->type
= PSI_T_UINT8
;
616 case PSI_T_LONG_DOUBLE
:
623 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.dvar
->name
)) {
624 exp
->type
= PSI_T_DEFINE
;
627 if (scope
&& scope
->current_enum
&& psi_number_validate_enum(data
, exp
, scope
)) {
630 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
631 struct psi_validate_scope enum_scope
= *scope
;
632 enum_scope
.current_enum
= enm
;
633 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
637 if (exp
->data
.dvar
->arg
) {
640 if (psi_decl_var_validate(data
, exp
->data
.dvar
, scope
)) {
643 data
->error(data
, exp
->token
, PSI_WARNING
,
644 "Unknown variable '%s' in numeric expression",
645 exp
->data
.dvar
->name
->val
);
649 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.call
->name
)) {
651 struct psi_cpp_macro_call
*call
= exp
->data
.call
;
653 for (i
= 0, argc
= psi_plist_count(call
->args
); i
< argc
; ++i
) {
654 struct psi_num_exp
*arg
;
656 if (!psi_plist_get(call
->args
, i
, &arg
)) {
659 if (!psi_num_exp_validate(data
, arg
, scope
)) {
665 if (psi_builtin_exists(exp
->data
.call
->name
)) {
666 exp
->data
.call
->builtin
= psi_builtin_get(exp
->data
.call
->name
);
672 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.numb
)) {
674 if (!scope
->macro
|| !zend_string_equals(scope
->macro
->token
->text
, exp
->data
.numb
)) {
677 /* #define foo foo */
679 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
680 struct psi_validate_scope enum_scope
= *scope
;
681 enum_scope
.current_enum
= enm
;
682 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
689 if (psi_decl_type_validate(data
, exp
->data
.dtyp
, NULL
, scope
)) {
690 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
692 exp
->type
= PSI_T_UINT64
;
693 exp
->data
.ival
.u64
= psi_decl_type_get_size(dtyp
, NULL
);
694 psi_decl_type_free(&dtyp
);
697 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
699 data
->error(data
, exp
->token
, PSI_WARNING
,
700 "Cannot compute sizeof(%s) (%u)", dtyp
->name
->val
, dtyp
->type
);
702 exp
->type
= PSI_T_UINT8
;
703 exp
->data
.ival
.u8
= 0;
704 psi_decl_type_free(&dtyp
);
712 if (exp
->data
.numb
->val
[0] == '\\') {
713 zc
= zend_get_constant_str(&exp
->data
.numb
->val
[1], exp
->data
.numb
->len
- 1);
715 zc
= zend_get_constant(exp
->data
.numb
);
719 switch (Z_TYPE_P(zc
)) {
721 zend_string_release(exp
->data
.numb
);
722 exp
->type
= PSI_T_INT64
;
723 exp
->data
.ival
.i64
= Z_LVAL_P(zc
);
727 zend_string_release(exp
->data
.numb
);
728 exp
->type
= PSI_T_DOUBLE
;
729 exp
->data
.ival
.dval
= Z_DVAL_P(zc
);
737 while (psi_plist_get(data
->consts
, i
++, &cnst
)) {
738 if (zend_string_equals(cnst
->name
, exp
->data
.numb
)) {
739 zend_string_release(exp
->data
.numb
);
740 exp
->type
= PSI_T_CONST
;
741 exp
->data
.cnst
= cnst
;
745 data
->error(data
, exp
->token
, PSI_WARNING
,
746 "Unknown constant '%s' in numeric expression",
747 exp
->data
.numb
->val
);
751 return psi_number_validate_number(data
, exp
);
753 case PSI_T_QUOTED_CHAR
:
754 return psi_number_validate_char(data
, exp
);
756 case PSI_T_CPP_HEADER
:
766 static inline token_t
psi_number_eval_constant(struct psi_number
*exp
,
767 impl_val
*res
, struct psi_call_frame
*frame
)
769 token_t typ
= exp
->data
.cnst
->type
? exp
->data
.cnst
->type
->type
: PSI_T_MIXED
;
773 res
->i64
= zend_get_constant(exp
->data
.cnst
->name
)->value
.lval
;
774 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
777 res
->dval
= zend_get_constant(exp
->data
.cnst
->name
)->value
.dval
;
778 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
781 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " ?(t=%u)", exp
->data
.cnst
->type
->type
);
787 static inline token_t
psi_number_eval_decl_var(struct psi_number
*exp
,
788 impl_val
*res
, struct psi_call_frame
*frame
)
791 struct psi_call_frame_symbol
*sym
;
792 struct psi_decl_type
*real
;
793 struct psi_decl_var
*var
;
796 var
= exp
->data
.dvar
;
797 real
= psi_decl_type_get_real(var
->arg
->type
);
798 size
= psi_decl_arg_get_size(var
->arg
);
799 sym
= psi_call_frame_fetch_symbol(frame
, var
);
800 ref
= deref_impl_val(sym
->ptr
, var
);
802 memcpy(res
, ref
, size
);
804 if (var
->arg
->var
->pointer_level
> var
->pointer_level
) {
805 switch (SIZEOF_VOID_P
) {
817 static inline token_t
psi_number_eval_define(struct psi_number
*exp
,
818 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
821 struct psi_cpp_macro_decl
*macro
;
823 macro
= zend_hash_find_ptr(&cpp
->defs
, exp
->data
.numb
);
824 if (macro
&& macro
->exp
&& macro
->exp
!= rec_guard
) {
825 return psi_num_exp_exec(macro
->exp
, res
, NULL
, cpp
);
833 static inline token_t
psi_number_eval_function(struct psi_number
*exp
,
834 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
837 PSI_DEBUG_PRINT(cpp
->parser
, "psi_number_eval(PSI_T_FUNCTION): %s\n", exp
->token
->text
->val
);
843 token_t
psi_number_eval(struct psi_number
*exp
, impl_val
*res
,
844 struct psi_call_frame
*frame
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
848 *res
= exp
->data
.ival
;
849 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi8
, res
->i8
);
853 *res
= exp
->data
.ival
;
854 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu8
, res
->u8
);
857 *res
= exp
->data
.ival
;
858 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi16
, res
->i16
);
861 *res
= exp
->data
.ival
;
862 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu16
, res
->u16
);
865 *res
= exp
->data
.ival
;
866 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi32
, res
->i32
);
869 *res
= exp
->data
.ival
;
870 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu32
, res
->u32
);
873 *res
= exp
->data
.ival
;
874 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
877 *res
= exp
->data
.ival
;
878 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu64
, res
->u64
);
882 *res
= exp
->data
.ival
;
883 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi128, res->i128);
886 *res
= exp
->data
.ival
;
887 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu128, res->u128);
888 return PSI_T_UINT128
;
891 *res
= exp
->data
.ival
;
892 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIfval
, res
->fval
);
896 *res
= exp
->data
.ival
;
897 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
901 case PSI_T_LONG_DOUBLE
:
902 *res
= exp
->data
.ival
;
903 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIldval
, res
->ldval
);
908 res
->i64
= exp
->data
.enm
->val
;
909 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
913 res
->i64
= atol(exp
->data
.numb
->val
);
917 return psi_number_eval_constant(exp
, res
, frame
);
920 return psi_number_eval_decl_var(exp
, res
, frame
);
923 return psi_number_eval_define(exp
, res
, cpp
, rec_guard
);
926 return psi_number_eval_function(exp
, res
, cpp
, rec_guard
);
928 case PSI_T_CPP_HEADER
: