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 *******************************************************************************/
29 # include "php_config.h"
41 #include "Zend/zend_constants.h"
42 #include "Zend/zend_operators.h"
45 struct psi_number
*psi_number_init(token_t t
, void *num
, unsigned flags
)
47 struct psi_number
*exp
= pecalloc(1, sizeof(*exp
), 1);
50 switch (exp
->type
= t
) {
52 exp
->data
.ival
.i8
= *(int8_t *) num
;
56 exp
->data
.ival
.u8
= *(uint8_t *) num
;
59 exp
->data
.ival
.i16
= *(int16_t *) num
;
62 exp
->data
.ival
.u16
= *(uint16_t *) num
;
65 exp
->data
.ival
.i32
= *(int32_t *) num
;
68 exp
->data
.ival
.u32
= *(uint32_t *) num
;
71 exp
->data
.ival
.i64
= *(int64_t *) num
;
74 exp
->data
.ival
.u64
= *(uint64_t *) num
;
77 exp
->data
.ival
.fval
= *(float *) num
;
80 exp
->data
.ival
.dval
= *(double *) num
;
83 case PSI_T_LONG_DOUBLE
:
84 exp
->data
.ival
.ldval
= *(long double *) num
;
89 case PSI_T_QUOTED_CHAR
:
93 case PSI_T_CPP_HEADER
:
94 exp
->data
.numb
= zend_string_copy(num
);
100 exp
->data
.call
= num
;
103 exp
->data
.dtyp
= num
;
112 struct psi_number
*psi_number_copy(struct psi_number
*exp
)
114 struct psi_number
*num
= pecalloc(1, sizeof(*num
), 1);
119 num
->token
= psi_token_copy(num
->token
);
134 case PSI_T_LONG_DOUBLE
:
143 case PSI_T_QUOTED_CHAR
:
144 case PSI_T_CPP_HEADER
:
145 num
->data
.numb
= zend_string_copy(num
->data
.numb
);
148 num
->data
.dvar
= psi_decl_var_copy(num
->data
.dvar
);
151 num
->data
.call
= psi_cpp_macro_call_copy(num
->data
.call
);
154 num
->data
.dtyp
= psi_decl_type_copy(num
->data
.dtyp
);
162 void psi_number_free(struct psi_number
**exp_ptr
)
165 struct psi_number
*exp
= *exp_ptr
;
168 psi_token_free(&exp
->token
);
182 case PSI_T_LONG_DOUBLE
:
189 psi_cpp_macro_call_free(&exp
->data
.call
);
194 case PSI_T_QUOTED_CHAR
:
195 case PSI_T_CPP_HEADER
:
196 zend_string_release(exp
->data
.numb
);
199 psi_decl_var_free(&exp
->data
.dvar
);
202 psi_decl_type_free(&exp
->data
.dtyp
);
211 struct psi_plist
*psi_number_tokens(struct psi_number
*exp
,
212 struct psi_plist
*list
)
214 struct psi_token
*ntoken
;
218 list
= psi_plist_init((psi_plist_dtor
) psi_token_free
);
224 ntoken
= psi_token_copy(exp
->data
.dvar
->token
);
226 if (exp
->data
.dvar
->pointer_level
> 1 || !exp
->data
.dvar
->array_size
) {
227 struct psi_token
*temp
= ntoken
;
228 unsigned pl
= exp
->data
.dvar
->pointer_level
- !!exp
->data
.dvar
->array_size
;
231 ntoken
= psi_token_init(PSI_T_POINTER
, "*", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
232 list
= psi_plist_add(list
, &ntoken
);
237 list
= psi_plist_add(list
, &ntoken
);
239 if (exp
->data
.dvar
->array_size
) {
240 char buf
[0x20], *ptr
;
242 ntoken
= psi_token_init(PSI_T_LBRACKET
, "[", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
243 list
= psi_plist_add(list
, &ntoken
);
244 ptr
= zend_print_ulong_to_buf(&buf
[sizeof(buf
) - 1], exp
->data
.dvar
->array_size
);
246 ntoken
= psi_token_init(PSI_T_NUMBER
, ptr
, strlen(ptr
), ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
247 list
= psi_plist_add(list
, &ntoken
);
253 ntoken
= psi_token_copy(exp
->token
);
254 list
= psi_plist_add(list
, &ntoken
);
255 ntoken
= psi_token_init(PSI_T_LPAREN
, "(", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
256 list
= psi_plist_add(list
, &ntoken
);
257 ntoken
= psi_token_copy(exp
->data
.dtyp
->token
);
258 list
= psi_plist_add(list
, &ntoken
);
259 ntoken
= psi_token_init(PSI_T_RPAREN
, ")", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
260 list
= psi_plist_add(list
, &ntoken
);
264 ntoken
= psi_token_copy(exp
->token
);
265 list
= psi_plist_add(list
, &ntoken
);
266 ntoken
= psi_token_init(PSI_T_LPAREN
, "(", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
267 list
= psi_plist_add(list
, &ntoken
);
268 for (i
= 0; i
< psi_plist_count(exp
->data
.call
->args
); ++i
) {
269 struct psi_num_exp
*tmp_exp
;
272 ntoken
= psi_token_init(PSI_T_COMMA
, ",", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
273 list
= psi_plist_add(list
, &ntoken
);
275 if (psi_plist_get(exp
->data
.call
->args
, i
, &tmp_exp
)) {
276 struct psi_plist
*tmp
= psi_num_exp_tokens(tmp_exp
, NULL
);
277 list
= psi_plist_add_r(list
, psi_plist_count(tmp
), psi_plist_eles(tmp
));
278 psi_plist_top(list
, &ntoken
);
282 ntoken
= psi_token_init(PSI_T_RPAREN
, ")", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
283 list
= psi_plist_add(list
, &ntoken
);
287 ntoken
= psi_token_init(PSI_T_DEFINED
, "defined", sizeof("defined")-1, exp
->token
->col
, exp
->token
->line
, exp
->token
->file
);
288 list
= psi_plist_add(list
, &ntoken
);
292 ntoken
= psi_token_copy(exp
->token
);
293 list
= psi_plist_add(list
, &ntoken
);
300 void psi_number_dump(struct psi_dump
*dump
, struct psi_number
*exp
)
304 CASE_IMPLVAL_NUM_DUMP(dump
, exp
->data
.ival
, true);
306 PSI_DUMP(dump
, "NULL");
310 case PSI_T_QUOTED_CHAR
:
311 case PSI_T_CPP_HEADER
:
312 PSI_DUMP(dump
, "%s", exp
->data
.numb
->val
);
315 PSI_DUMP(dump
, "%s /* DEFINE */", exp
->data
.numb
->val
);
318 psi_cpp_macro_call_dump(dump
, exp
->data
.call
);
321 PSI_DUMP(dump
, "%s", exp
->data
.cnst
->name
->val
);
324 PSI_DUMP(dump
, "%s /* ENUM */ ", exp
->data
.enm
->name
->val
);
327 psi_decl_var_dump(dump
, exp
->data
.dvar
);
330 PSI_DUMP(dump
, "sizeof(");
331 psi_decl_type_dump(dump
, exp
->data
.dtyp
, 0);
338 PSI_DUMP(dump
, "\t/* number.type=%d */ ", exp
->type
);
342 static inline bool psi_number_validate_enum(struct psi_data
*data
,
343 struct psi_number
*exp
, struct psi_validate_scope
*scope
)
345 if (scope
&& scope
->current_enum
) {
347 struct psi_decl_enum_item
*itm
;
348 struct psi_decl_enum
*enm
;
350 enm
= scope
->current_enum
;
354 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
355 if (zend_string_equals(itm
->name
, exp
->data
.dvar
->name
)) {
356 psi_decl_var_free(&exp
->data
.dvar
);
357 exp
->type
= PSI_T_ENUM
;
359 return psi_number_validate(data
, exp
, scope
);
365 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
366 if (zend_string_equals(itm
->name
, exp
->data
.numb
)) {
367 zend_string_release(exp
->data
.numb
);
368 exp
->type
= PSI_T_ENUM
;
370 return psi_number_validate(data
, exp
, scope
);
382 static inline token_t
validate_char(char *numb
, impl_val
*res
, unsigned *lvl
)
385 token_t typ
= PSI_T_INT8
;
396 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
397 res
->i8
= strtol(&numb
[1], &endptr
, 8);
401 res
->i8
= strtol(&numb
[2], &endptr
, 16);
435 impl_val tmp_val
= {0};
436 token_t tmp_typ
= validate_char(endptr
, &tmp_val
, lvl
);
442 res
->i32
= res
->i8
<< (8 * *lvl
);
443 typ
= psi_calc_add(PSI_T_INT32
, res
, tmp_typ
, &tmp_val
, res
);
450 static inline bool psi_number_validate_char(struct psi_data
*data
, struct psi_number
*exp
)
454 token_t typ
= validate_char(exp
->data
.numb
->val
, &val
, &lvl
);
460 zend_string_release(exp
->data
.numb
);
462 exp
->data
.ival
= val
;
466 static inline bool psi_number_validate_number(struct psi_data
*data
, struct psi_number
*exp
)
471 switch (exp
->flags
& 0x0f) {
473 switch (exp
->flags
& 0x0f00) {
476 tmp
.i64
= strtol(exp
->data
.numb
->val
, NULL
, 0);
477 zend_string_release(exp
->data
.numb
);
478 exp
->type
= PSI_T_INT64
;
479 exp
->data
.ival
.i64
= tmp
.i64
;
482 tmp
.i64
= strtoll(exp
->data
.numb
->val
, NULL
, 0);
483 zend_string_release(exp
->data
.numb
);
484 exp
->type
= PSI_T_INT64
;
485 exp
->data
.ival
.i64
= tmp
.i64
;
489 tmp
.u64
= strtoul(exp
->data
.numb
->val
, NULL
, 0);
490 zend_string_release(exp
->data
.numb
);
491 exp
->type
= PSI_T_UINT64
;
492 exp
->data
.ival
.u64
= tmp
.u64
;
495 tmp
.u64
= strtoull(exp
->data
.numb
->val
, NULL
, 0);
496 zend_string_release(exp
->data
.numb
);
497 exp
->type
= PSI_T_UINT64
;
498 exp
->data
.ival
.u64
= tmp
.u64
;
504 switch (exp
->flags
& 0x0ff00) {
506 tmp
.fval
= strtof(exp
->data
.numb
->val
, NULL
);
507 zend_string_release(exp
->data
.numb
);
508 exp
->type
= PSI_T_FLOAT
;
509 exp
->data
.ival
.fval
= tmp
.fval
;
514 tmp
.ldval
= strtold(exp
->data
.numb
->val
, NULL
);
515 zend_string_release(exp
->data
.numb
);
516 exp
->type
= PSI_T_LONG_DOUBLE
;
517 exp
->data
.ival
.ldval
= tmp
.ldval
;
523 tmp
.dval
= strtod(exp
->data
.numb
->val
, NULL
);
524 zend_string_release(exp
->data
.numb
);
525 exp
->type
= PSI_T_DOUBLE
;
526 exp
->data
.ival
.dval
= tmp
.dval
;
535 int type
= is_numeric_string(exp
->data
.numb
->val
, exp
->data
.numb
->len
, (zend_long
*) &tmp
, (double *)&tmp
, 0);
542 zend_string_release(exp
->data
.numb
);
543 exp
->type
= PSI_T_INT64
;
544 exp
->data
.ival
.i64
= tmp
.zend
.lval
;
548 zend_string_release(exp
->data
.numb
);
549 exp
->type
= PSI_T_DOUBLE
;
550 exp
->data
.ival
.dval
= tmp
.dval
;
557 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
558 lval
= strtol(exp
->data
.numb
->val
, &stop
, 0);
561 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
567 if (errno
== ERANGE
) {
570 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
571 ulval
= strtoul(exp
->data
.numb
->val
, &stop
, 0);
574 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
578 zend_string_release(exp
->data
.numb
);
579 exp
->type
= PSI_T_UINT64
;
580 exp
->data
.ival
.u64
= ulval
;
586 zend_string_release(exp
->data
.numb
);
587 exp
->type
= PSI_T_INT64
;
588 exp
->data
.ival
.i64
= lval
;
592 data
->error(data
, exp
->token
, PSI_WARNING
, "Not a numeric string: '%s'", exp
->data
.numb
->val
);
595 data
->error(data
, exp
->token
, PSI_WARNING
, "Expected numeric entity (parser error?)");
599 bool psi_number_validate(struct psi_data
*data
, struct psi_number
*exp
,
600 struct psi_validate_scope
*scope
)
603 struct psi_const
*cnst
;
604 struct psi_decl_enum
*enm
;
608 exp
->type
= PSI_T_UINT8
;
626 case PSI_T_LONG_DOUBLE
:
633 //if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
634 // exp->type = PSI_T_DEFINE;
637 if (scope
&& scope
->current_enum
&& psi_number_validate_enum(data
, exp
, scope
)) {
640 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
641 struct psi_validate_scope enum_scope
= *scope
;
642 enum_scope
.current_enum
= enm
;
643 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
647 if (exp
->data
.dvar
->arg
) {
650 if (psi_decl_var_validate(data
, exp
->data
.dvar
, scope
)) {
653 data
->error(data
, exp
->token
, PSI_WARNING
,
654 "Unknown variable '%s' in numeric expression",
655 exp
->data
.dvar
->name
->val
);
659 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.call
->name
)) {
661 struct psi_cpp_macro_call
*call
= exp
->data
.call
;
663 for (i
= 0, argc
= psi_plist_count(call
->args
); i
< argc
; ++i
) {
664 struct psi_num_exp
*arg
;
666 if (!psi_plist_get(call
->args
, i
, &arg
)) {
669 if (!psi_num_exp_validate(data
, arg
, scope
)) {
675 if (psi_builtin_exists(exp
->data
.call
->name
)) {
676 exp
->data
.call
->builtin
= psi_builtin_get(exp
->data
.call
->name
);
682 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.numb
)) {
683 if (!scope
->macro
|| !zend_string_equals(scope
->macro
->token
->text
, exp
->data
.numb
)) {
686 /* #define foo foo */
688 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
689 struct psi_validate_scope enum_scope
= *scope
;
690 enum_scope
.current_enum
= enm
;
691 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
698 if (psi_decl_type_validate(data
, exp
->data
.dtyp
, NULL
, scope
)) {
699 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
701 exp
->type
= PSI_T_UINT64
;
702 exp
->data
.ival
.u64
= psi_decl_type_get_size(dtyp
, NULL
);
703 psi_decl_type_free(&dtyp
);
706 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
708 data
->error(data
, exp
->token
, PSI_WARNING
,
709 "Cannot compute sizeof(%s) (%u)", dtyp
->name
->val
, dtyp
->type
);
711 exp
->type
= PSI_T_UINT8
;
712 exp
->data
.ival
.u8
= 0;
713 psi_decl_type_free(&dtyp
);
721 if (exp
->data
.numb
->val
[0] == '\\') {
722 zc
= zend_get_constant_str(&exp
->data
.numb
->val
[1], exp
->data
.numb
->len
- 1);
724 zc
= zend_get_constant(exp
->data
.numb
);
728 switch (Z_TYPE_P(zc
)) {
730 zend_string_release(exp
->data
.numb
);
731 exp
->type
= PSI_T_INT64
;
732 exp
->data
.ival
.i64
= Z_LVAL_P(zc
);
736 zend_string_release(exp
->data
.numb
);
737 exp
->type
= PSI_T_DOUBLE
;
738 exp
->data
.ival
.dval
= Z_DVAL_P(zc
);
746 while (psi_plist_get(data
->consts
, i
++, &cnst
)) {
747 if (zend_string_equals(cnst
->name
, exp
->data
.numb
)) {
748 zend_string_release(exp
->data
.numb
);
749 exp
->type
= PSI_T_CONST
;
750 exp
->data
.cnst
= cnst
;
754 data
->error(data
, exp
->token
, PSI_WARNING
,
755 "Unknown constant '%s' in numeric expression",
756 exp
->data
.numb
->val
);
760 return psi_number_validate_number(data
, exp
);
762 case PSI_T_QUOTED_CHAR
:
763 return psi_number_validate_char(data
, exp
);
765 case PSI_T_CPP_HEADER
:
775 static inline token_t
psi_number_eval_constant(struct psi_number
*exp
,
776 impl_val
*res
, struct psi_call_frame
*frame
)
778 token_t typ
= exp
->data
.cnst
->type
? exp
->data
.cnst
->type
->type
: PSI_T_MIXED
;
782 res
->i64
= zend_get_constant(exp
->data
.cnst
->name
)->value
.lval
;
783 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
786 res
->dval
= zend_get_constant(exp
->data
.cnst
->name
)->value
.dval
;
787 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
790 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " ?(t=%u)", exp
->data
.cnst
->type
->type
);
796 static inline token_t
psi_number_eval_decl_var(struct psi_number
*exp
,
797 impl_val
*res
, struct psi_call_frame
*frame
)
800 struct psi_call_frame_symbol
*sym
;
801 struct psi_decl_type
*real
;
802 struct psi_decl_var
*var
;
805 var
= exp
->data
.dvar
;
806 real
= psi_decl_type_get_real(var
->arg
->type
);
807 size
= psi_decl_arg_get_size(var
->arg
);
808 sym
= psi_call_frame_fetch_symbol(frame
, var
);
809 ref
= deref_impl_val(sym
->ptr
, var
);
811 memcpy(res
, ref
, size
);
813 if (var
->arg
->var
->pointer_level
> var
->pointer_level
) {
814 switch (SIZEOF_VOID_P
) {
826 static inline token_t
psi_number_eval_define(struct psi_number
*exp
,
827 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
830 struct psi_cpp_macro_decl
*macro
;
832 macro
= zend_hash_find_ptr(&cpp
->defs
, exp
->data
.numb
);
833 if (macro
&& macro
->exp
&& macro
->exp
!= rec_guard
) {
834 return psi_num_exp_exec(macro
->exp
, res
, NULL
, cpp
);
842 static inline token_t
psi_number_eval_function(struct psi_number
*exp
,
843 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
846 PSI_DEBUG_PRINT(cpp
->parser
, "psi_number_eval(PSI_T_FUNCTION): %s\n", exp
->token
->text
->val
);
852 token_t
psi_number_eval(struct psi_number
*exp
, impl_val
*res
,
853 struct psi_call_frame
*frame
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
857 *res
= exp
->data
.ival
;
858 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi8
, res
->i8
);
862 *res
= exp
->data
.ival
;
863 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu8
, res
->u8
);
866 *res
= exp
->data
.ival
;
867 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi16
, res
->i16
);
870 *res
= exp
->data
.ival
;
871 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu16
, res
->u16
);
874 *res
= exp
->data
.ival
;
875 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi32
, res
->i32
);
878 *res
= exp
->data
.ival
;
879 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu32
, res
->u32
);
882 *res
= exp
->data
.ival
;
883 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
886 *res
= exp
->data
.ival
;
887 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu64
, res
->u64
);
891 *res
= exp
->data
.ival
;
892 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi128, res->i128);
895 *res
= exp
->data
.ival
;
896 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu128, res->u128);
897 return PSI_T_UINT128
;
900 *res
= exp
->data
.ival
;
901 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIfval
, res
->fval
);
905 *res
= exp
->data
.ival
;
906 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
910 case PSI_T_LONG_DOUBLE
:
911 *res
= exp
->data
.ival
;
912 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIldval
, res
->ldval
);
917 res
->i64
= exp
->data
.enm
->val
;
918 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
922 res
->i64
= atol(exp
->data
.numb
->val
);
926 return psi_number_eval_constant(exp
, res
, frame
);
929 return psi_number_eval_decl_var(exp
, res
, frame
);
932 return psi_number_eval_define(exp
, res
, cpp
, rec_guard
);
935 return psi_number_eval_function(exp
, res
, cpp
, rec_guard
);
937 case PSI_T_CPP_HEADER
: