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"
40 #include "Zend/zend_constants.h"
41 #include "Zend/zend_operators.h"
44 struct psi_number
*psi_number_init(token_t t
, void *num
, unsigned flags
)
46 struct psi_number
*exp
= pecalloc(1, sizeof(*exp
), 1);
49 switch (exp
->type
= t
) {
51 exp
->data
.ival
.i8
= *(int8_t *) num
;
55 exp
->data
.ival
.u8
= *(uint8_t *) num
;
58 exp
->data
.ival
.i16
= *(int16_t *) num
;
61 exp
->data
.ival
.u16
= *(uint16_t *) num
;
64 exp
->data
.ival
.i32
= *(int32_t *) num
;
67 exp
->data
.ival
.u32
= *(uint32_t *) num
;
70 exp
->data
.ival
.i64
= *(int64_t *) num
;
73 exp
->data
.ival
.u64
= *(uint64_t *) num
;
76 exp
->data
.ival
.fval
= *(float *) num
;
79 exp
->data
.ival
.dval
= *(double *) num
;
82 case PSI_T_LONG_DOUBLE
:
83 exp
->data
.ival
.ldval
= *(long double *) num
;
88 case PSI_T_QUOTED_CHAR
:
92 case PSI_T_CPP_HEADER
:
93 exp
->data
.numb
= zend_string_copy(num
);
102 exp
->data
.dtyp
= num
;
111 struct psi_number
*psi_number_copy(struct psi_number
*exp
)
113 struct psi_number
*num
= pecalloc(1, sizeof(*num
), 1);
118 num
->token
= psi_token_copy(num
->token
);
133 case PSI_T_LONG_DOUBLE
:
142 case PSI_T_QUOTED_CHAR
:
143 case PSI_T_CPP_HEADER
:
144 num
->data
.numb
= zend_string_copy(num
->data
.numb
);
147 num
->data
.dvar
= psi_decl_var_copy(num
->data
.dvar
);
150 num
->data
.call
= psi_cpp_macro_call_copy(num
->data
.call
);
153 num
->data
.dtyp
= psi_decl_type_copy(num
->data
.dtyp
);
161 void psi_number_free(struct psi_number
**exp_ptr
)
164 struct psi_number
*exp
= *exp_ptr
;
167 psi_token_free(&exp
->token
);
181 case PSI_T_LONG_DOUBLE
:
188 psi_cpp_macro_call_free(&exp
->data
.call
);
193 case PSI_T_QUOTED_CHAR
:
194 case PSI_T_CPP_HEADER
:
195 zend_string_release(exp
->data
.numb
);
198 psi_decl_var_free(&exp
->data
.dvar
);
201 psi_decl_type_free(&exp
->data
.dtyp
);
210 struct psi_plist
*psi_number_tokens(struct psi_number
*exp
,
211 struct psi_plist
*list
)
213 struct psi_token
*ntoken
;
217 list
= psi_plist_init((psi_plist_dtor
) psi_token_free
);
223 ntoken
= psi_token_copy(exp
->data
.dvar
->token
);
225 if (exp
->data
.dvar
->pointer_level
> 1 || !exp
->data
.dvar
->array_size
) {
226 struct psi_token
*temp
= ntoken
;
227 unsigned pl
= exp
->data
.dvar
->pointer_level
- !!exp
->data
.dvar
->array_size
;
230 ntoken
= psi_token_init(PSI_T_POINTER
, "*", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
231 list
= psi_plist_add(list
, &ntoken
);
236 list
= psi_plist_add(list
, &ntoken
);
238 if (exp
->data
.dvar
->array_size
) {
239 char buf
[0x20], *ptr
;
241 ntoken
= psi_token_init(PSI_T_LBRACKET
, "[", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
242 list
= psi_plist_add(list
, &ntoken
);
243 ptr
= zend_print_ulong_to_buf(&buf
[sizeof(buf
) - 1], exp
->data
.dvar
->array_size
);
245 ntoken
= psi_token_init(PSI_T_NUMBER
, ptr
, strlen(ptr
), ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
246 list
= psi_plist_add(list
, &ntoken
);
252 ntoken
= psi_token_copy(exp
->token
);
253 list
= psi_plist_add(list
, &ntoken
);
254 ntoken
= psi_token_init(PSI_T_LPAREN
, "(", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
255 list
= psi_plist_add(list
, &ntoken
);
256 ntoken
= psi_token_copy(exp
->data
.dtyp
->token
);
257 list
= psi_plist_add(list
, &ntoken
);
258 ntoken
= psi_token_init(PSI_T_RPAREN
, ")", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
259 list
= psi_plist_add(list
, &ntoken
);
263 ntoken
= psi_token_copy(exp
->token
);
264 list
= psi_plist_add(list
, &ntoken
);
265 ntoken
= psi_token_init(PSI_T_LPAREN
, "(", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
266 list
= psi_plist_add(list
, &ntoken
);
267 for (i
= 0; i
< psi_plist_count(exp
->data
.call
->args
); ++i
) {
268 struct psi_num_exp
*tmp_exp
;
271 ntoken
= psi_token_init(PSI_T_COMMA
, ",", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
272 list
= psi_plist_add(list
, &ntoken
);
274 if (psi_plist_get(exp
->data
.call
->args
, i
, &tmp_exp
)) {
275 struct psi_plist
*tmp
= psi_num_exp_tokens(tmp_exp
, NULL
);
276 list
= psi_plist_add_r(list
, psi_plist_count(tmp
), psi_plist_eles(tmp
));
277 psi_plist_top(list
, &ntoken
);
281 ntoken
= psi_token_init(PSI_T_RPAREN
, ")", 1, ntoken
->col
+ntoken
->text
->len
, ntoken
->line
, ntoken
->file
);
282 list
= psi_plist_add(list
, &ntoken
);
286 ntoken
= psi_token_init(PSI_T_DEFINED
, "defined", sizeof("defined")-1, exp
->token
->col
, exp
->token
->line
, exp
->token
->file
);
287 list
= psi_plist_add(list
, &ntoken
);
291 ntoken
= psi_token_copy(exp
->token
);
292 list
= psi_plist_add(list
, &ntoken
);
299 void psi_number_dump(struct psi_dump
*dump
, struct psi_number
*exp
)
303 CASE_IMPLVAL_NUM_DUMP(dump
, exp
->data
.ival
, true);
305 PSI_DUMP(dump
, "NULL");
309 case PSI_T_QUOTED_CHAR
:
310 case PSI_T_CPP_HEADER
:
311 PSI_DUMP(dump
, "%s", exp
->data
.numb
->val
);
314 PSI_DUMP(dump
, "%s /* DEFINE */", exp
->data
.numb
->val
);
317 psi_cpp_macro_call_dump(dump
, exp
->data
.call
);
320 PSI_DUMP(dump
, "%s", exp
->data
.cnst
->name
->val
);
323 PSI_DUMP(dump
, "%s /* ENUM */ ", exp
->data
.enm
->name
->val
);
326 psi_decl_var_dump(dump
, exp
->data
.dvar
);
329 PSI_DUMP(dump
, "sizeof(");
330 psi_decl_type_dump(dump
, exp
->data
.dtyp
, 0);
337 PSI_DUMP(dump
, "\t/* number.type=%d */ ", exp
->type
);
341 static inline bool psi_number_validate_enum(struct psi_data
*data
,
342 struct psi_number
*exp
, struct psi_validate_scope
*scope
)
344 if (scope
&& scope
->current_enum
) {
346 struct psi_decl_enum_item
*itm
;
347 struct psi_decl_enum
*enm
;
349 enm
= scope
->current_enum
;
353 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
354 if (zend_string_equals(itm
->name
, exp
->data
.dvar
->name
)) {
355 psi_decl_var_free(&exp
->data
.dvar
);
356 exp
->type
= PSI_T_ENUM
;
358 return psi_number_validate(data
, exp
, scope
);
364 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
365 if (zend_string_equals(itm
->name
, exp
->data
.numb
)) {
366 zend_string_release(exp
->data
.numb
);
367 exp
->type
= PSI_T_ENUM
;
369 return psi_number_validate(data
, exp
, scope
);
381 static inline token_t
validate_char(char *numb
, impl_val
*res
, unsigned *lvl
)
384 token_t typ
= PSI_T_INT8
;
395 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
396 res
->i8
= strtol(&numb
[1], &endptr
, 8);
400 res
->i8
= strtol(&numb
[2], &endptr
, 16);
434 impl_val tmp_val
= {0};
435 token_t tmp_typ
= validate_char(endptr
, &tmp_val
, lvl
);
441 res
->i32
= res
->i8
<< (8 * *lvl
);
442 typ
= psi_calc_add(PSI_T_INT32
, res
, tmp_typ
, &tmp_val
, res
);
449 static inline bool psi_number_validate_char(struct psi_data
*data
, struct psi_number
*exp
)
453 token_t typ
= validate_char(exp
->data
.numb
->val
, &val
, &lvl
);
459 zend_string_release(exp
->data
.numb
);
461 exp
->data
.ival
= val
;
465 static inline bool psi_number_validate_number(struct psi_data
*data
, struct psi_number
*exp
)
470 switch (exp
->flags
& 0x0f) {
472 switch (exp
->flags
& 0x0f00) {
475 tmp
.i64
= strtol(exp
->data
.numb
->val
, NULL
, 0);
476 zend_string_release(exp
->data
.numb
);
477 exp
->type
= PSI_T_INT64
;
478 exp
->data
.ival
.i64
= tmp
.i64
;
481 tmp
.i64
= strtoll(exp
->data
.numb
->val
, NULL
, 0);
482 zend_string_release(exp
->data
.numb
);
483 exp
->type
= PSI_T_INT64
;
484 exp
->data
.ival
.i64
= tmp
.i64
;
488 tmp
.u64
= strtoul(exp
->data
.numb
->val
, NULL
, 0);
489 zend_string_release(exp
->data
.numb
);
490 exp
->type
= PSI_T_UINT64
;
491 exp
->data
.ival
.u64
= tmp
.u64
;
494 tmp
.u64
= strtoull(exp
->data
.numb
->val
, NULL
, 0);
495 zend_string_release(exp
->data
.numb
);
496 exp
->type
= PSI_T_UINT64
;
497 exp
->data
.ival
.u64
= tmp
.u64
;
503 switch (exp
->flags
& 0x0ff00) {
505 tmp
.fval
= strtof(exp
->data
.numb
->val
, NULL
);
506 zend_string_release(exp
->data
.numb
);
507 exp
->type
= PSI_T_FLOAT
;
508 exp
->data
.ival
.fval
= tmp
.fval
;
513 tmp
.ldval
= strtold(exp
->data
.numb
->val
, NULL
);
514 zend_string_release(exp
->data
.numb
);
515 exp
->type
= PSI_T_LONG_DOUBLE
;
516 exp
->data
.ival
.ldval
= tmp
.ldval
;
522 tmp
.dval
= strtod(exp
->data
.numb
->val
, NULL
);
523 zend_string_release(exp
->data
.numb
);
524 exp
->type
= PSI_T_DOUBLE
;
525 exp
->data
.ival
.dval
= tmp
.dval
;
534 int type
= is_numeric_string(exp
->data
.numb
->val
, exp
->data
.numb
->len
, (zend_long
*) &tmp
, (double *)&tmp
, 0);
541 zend_string_release(exp
->data
.numb
);
542 exp
->type
= PSI_T_INT64
;
543 exp
->data
.ival
.i64
= tmp
.zend
.lval
;
547 zend_string_release(exp
->data
.numb
);
548 exp
->type
= PSI_T_DOUBLE
;
549 exp
->data
.ival
.dval
= tmp
.dval
;
556 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
557 lval
= strtol(exp
->data
.numb
->val
, &stop
, 0);
560 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
566 if (errno
== ERANGE
) {
569 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
570 ulval
= strtoul(exp
->data
.numb
->val
, &stop
, 0);
573 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
577 zend_string_release(exp
->data
.numb
);
578 exp
->type
= PSI_T_UINT64
;
579 exp
->data
.ival
.u64
= ulval
;
585 zend_string_release(exp
->data
.numb
);
586 exp
->type
= PSI_T_INT64
;
587 exp
->data
.ival
.i64
= lval
;
591 data
->error(data
, exp
->token
, PSI_WARNING
, "Not a numeric string: '%s'", exp
->data
.numb
->val
);
594 data
->error(data
, exp
->token
, PSI_WARNING
, "Expected numeric entity (parser error?)");
598 bool psi_number_validate(struct psi_data
*data
, struct psi_number
*exp
,
599 struct psi_validate_scope
*scope
)
602 struct psi_const
*cnst
;
603 struct psi_decl_enum
*enm
;
607 exp
->type
= PSI_T_UINT8
;
625 case PSI_T_LONG_DOUBLE
:
632 //if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
633 // exp->type = PSI_T_DEFINE;
636 if (scope
&& scope
->current_enum
&& psi_number_validate_enum(data
, exp
, scope
)) {
639 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
640 struct psi_validate_scope enum_scope
= *scope
;
641 enum_scope
.current_enum
= enm
;
642 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
646 if (exp
->data
.dvar
->arg
) {
649 if (psi_decl_var_validate(data
, exp
->data
.dvar
, scope
)) {
652 data
->error(data
, exp
->token
, PSI_WARNING
,
653 "Unknown variable '%s' in numeric expression",
654 exp
->data
.dvar
->name
->val
);
658 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.call
->name
)) {
660 struct psi_cpp_macro_call
*call
= exp
->data
.call
;
662 for (i
= 0, argc
= psi_plist_count(call
->args
); i
< argc
; ++i
) {
663 struct psi_num_exp
*arg
;
665 if (!psi_plist_get(call
->args
, i
, &arg
)) {
668 if (!psi_num_exp_validate(data
, arg
, scope
)) {
674 if (psi_builtin_exists(exp
->data
.call
->name
)) {
675 exp
->data
.call
->builtin
= psi_builtin_get(exp
->data
.call
->name
);
681 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.numb
)) {
682 if (!scope
->macro
|| !zend_string_equals(scope
->macro
->token
->text
, exp
->data
.numb
)) {
685 /* #define foo foo */
687 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
688 struct psi_validate_scope enum_scope
= *scope
;
689 enum_scope
.current_enum
= enm
;
690 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
697 if (psi_decl_type_validate(data
, exp
->data
.dtyp
, NULL
, scope
)) {
698 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
700 exp
->type
= PSI_T_UINT64
;
701 exp
->data
.ival
.u64
= psi_decl_type_get_size(dtyp
, NULL
);
702 psi_decl_type_free(&dtyp
);
705 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
707 data
->error(data
, exp
->token
, PSI_WARNING
,
708 "Cannot compute sizeof(%s) (%u)", dtyp
->name
->val
, dtyp
->type
);
710 exp
->type
= PSI_T_UINT8
;
711 exp
->data
.ival
.u8
= 0;
712 psi_decl_type_free(&dtyp
);
720 if (exp
->data
.numb
->val
[0] == '\\') {
721 zc
= zend_get_constant_str(&exp
->data
.numb
->val
[1], exp
->data
.numb
->len
- 1);
723 zc
= zend_get_constant(exp
->data
.numb
);
727 switch (Z_TYPE_P(zc
)) {
729 zend_string_release(exp
->data
.numb
);
730 exp
->type
= PSI_T_INT64
;
731 exp
->data
.ival
.i64
= Z_LVAL_P(zc
);
735 zend_string_release(exp
->data
.numb
);
736 exp
->type
= PSI_T_DOUBLE
;
737 exp
->data
.ival
.dval
= Z_DVAL_P(zc
);
745 while (psi_plist_get(data
->consts
, i
++, &cnst
)) {
746 if (zend_string_equals(cnst
->name
, exp
->data
.numb
)) {
747 zend_string_release(exp
->data
.numb
);
748 exp
->type
= PSI_T_CONST
;
749 exp
->data
.cnst
= cnst
;
753 data
->error(data
, exp
->token
, PSI_WARNING
,
754 "Unknown constant '%s' in numeric expression",
755 exp
->data
.numb
->val
);
759 return psi_number_validate_number(data
, exp
);
761 case PSI_T_QUOTED_CHAR
:
762 return psi_number_validate_char(data
, exp
);
764 case PSI_T_CPP_HEADER
:
774 static inline token_t
psi_number_eval_constant(struct psi_number
*exp
,
775 impl_val
*res
, struct psi_call_frame
*frame
)
777 token_t typ
= exp
->data
.cnst
->type
? exp
->data
.cnst
->type
->type
: PSI_T_MIXED
;
781 res
->i64
= zend_get_constant(exp
->data
.cnst
->name
)->value
.lval
;
782 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
785 res
->dval
= zend_get_constant(exp
->data
.cnst
->name
)->value
.dval
;
786 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
789 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " ?(t=%u)", exp
->data
.cnst
->type
->type
);
795 static inline token_t
psi_number_eval_decl_var(struct psi_number
*exp
,
796 impl_val
*res
, struct psi_call_frame
*frame
)
799 struct psi_call_frame_symbol
*sym
;
800 struct psi_decl_type
*real
;
801 struct psi_decl_var
*var
;
804 var
= exp
->data
.dvar
;
805 real
= psi_decl_type_get_real(var
->arg
->type
);
806 size
= psi_decl_arg_get_size(var
->arg
);
807 sym
= psi_call_frame_fetch_symbol(frame
, var
);
808 ref
= deref_impl_val(sym
->ptr
, var
);
810 memcpy(res
, ref
, size
);
812 if (var
->arg
->var
->pointer_level
> var
->pointer_level
) {
813 switch (SIZEOF_VOID_P
) {
825 static inline token_t
psi_number_eval_define(struct psi_number
*exp
,
826 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
829 struct psi_cpp_macro_decl
*macro
;
831 macro
= zend_hash_find_ptr(&cpp
->defs
, exp
->data
.numb
);
832 if (macro
&& macro
->exp
&& macro
->exp
!= rec_guard
) {
833 return psi_num_exp_exec(macro
->exp
, res
, NULL
, cpp
);
841 static inline token_t
psi_number_eval_function(struct psi_number
*exp
,
842 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
845 PSI_DEBUG_PRINT(cpp
->parser
, "psi_number_eval(PSI_T_FUNCTION): %s\n", exp
->token
->text
->val
);
851 token_t
psi_number_eval(struct psi_number
*exp
, impl_val
*res
,
852 struct psi_call_frame
*frame
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
856 *res
= exp
->data
.ival
;
857 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi8
, res
->i8
);
861 *res
= exp
->data
.ival
;
862 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu8
, res
->u8
);
865 *res
= exp
->data
.ival
;
866 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi16
, res
->i16
);
869 *res
= exp
->data
.ival
;
870 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu16
, res
->u16
);
873 *res
= exp
->data
.ival
;
874 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi32
, res
->i32
);
877 *res
= exp
->data
.ival
;
878 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu32
, res
->u32
);
881 *res
= exp
->data
.ival
;
882 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
885 *res
= exp
->data
.ival
;
886 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu64
, res
->u64
);
890 *res
= exp
->data
.ival
;
891 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi128, res->i128);
894 *res
= exp
->data
.ival
;
895 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu128, res->u128);
896 return PSI_T_UINT128
;
899 *res
= exp
->data
.ival
;
900 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIfval
, res
->fval
);
904 *res
= exp
->data
.ival
;
905 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
909 case PSI_T_LONG_DOUBLE
:
910 *res
= exp
->data
.ival
;
911 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIldval
, res
->ldval
);
916 res
->i64
= exp
->data
.enm
->val
;
917 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
921 res
->i64
= atol(exp
->data
.numb
->val
);
925 return psi_number_eval_constant(exp
, res
, frame
);
928 return psi_number_eval_decl_var(exp
, res
, frame
);
931 return psi_number_eval_define(exp
, res
, cpp
, rec_guard
);
934 return psi_number_eval_function(exp
, res
, cpp
, rec_guard
);
936 case PSI_T_CPP_HEADER
: