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_DUMP(dump
, exp
->data
.ival
, true);
301 PSI_DUMP(dump
, "NULL");
305 case PSI_T_QUOTED_CHAR
:
306 case PSI_T_CPP_HEADER
:
307 PSI_DUMP(dump
, "%s", exp
->data
.numb
->val
);
310 PSI_DUMP(dump
, "%s /* DEFINE */", exp
->data
.numb
->val
);
313 psi_cpp_macro_call_dump(dump
, exp
->data
.call
);
316 PSI_DUMP(dump
, "%s", exp
->data
.cnst
->name
->val
);
319 PSI_DUMP(dump
, "%s /* ENUM */ ", exp
->data
.enm
->name
->val
);
322 psi_decl_var_dump(dump
, exp
->data
.dvar
);
325 PSI_DUMP(dump
, "sizeof(");
326 psi_decl_type_dump(dump
, exp
->data
.dtyp
, 0);
333 PSI_DUMP(dump
, "\t/* number.type=%d */ ", exp
->type
);
337 static inline bool psi_number_validate_enum(struct psi_data
*data
,
338 struct psi_number
*exp
, struct psi_validate_scope
*scope
)
340 if (scope
&& scope
->current_enum
) {
342 struct psi_decl_enum_item
*itm
;
343 struct psi_decl_enum
*enm
;
345 enm
= scope
->current_enum
;
349 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
350 if (zend_string_equals(itm
->name
, exp
->data
.dvar
->name
)) {
351 psi_decl_var_free(&exp
->data
.dvar
);
352 exp
->type
= PSI_T_ENUM
;
354 return psi_number_validate(data
, exp
, scope
);
360 while (psi_plist_get(enm
->items
, i
++, &itm
)) {
361 if (zend_string_equals(itm
->name
, exp
->data
.numb
)) {
362 zend_string_release(exp
->data
.numb
);
363 exp
->type
= PSI_T_ENUM
;
365 return psi_number_validate(data
, exp
, scope
);
377 static inline token_t
validate_char(char *numb
, impl_val
*res
, unsigned *lvl
)
380 token_t typ
= PSI_T_INT8
;
391 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
392 res
->i8
= strtol(&numb
[1], &endptr
, 8);
396 res
->i8
= strtol(&numb
[2], &endptr
, 16);
430 impl_val tmp_val
= {0};
431 token_t tmp_typ
= validate_char(endptr
, &tmp_val
, lvl
);
437 res
->i32
= res
->i8
<< (8 * *lvl
);
438 typ
= psi_calc_add(PSI_T_INT32
, res
, tmp_typ
, &tmp_val
, res
);
445 static inline bool psi_number_validate_char(struct psi_data
*data
, struct psi_number
*exp
)
449 token_t typ
= validate_char(exp
->data
.numb
->val
, &val
, &lvl
);
455 zend_string_release(exp
->data
.numb
);
457 exp
->data
.ival
= val
;
461 static inline bool psi_number_validate_number(struct psi_data
*data
, struct psi_number
*exp
)
466 switch (exp
->flags
& 0x0f) {
468 switch (exp
->flags
& 0x0f00) {
471 tmp
.i64
= strtol(exp
->data
.numb
->val
, NULL
, 0);
472 zend_string_release(exp
->data
.numb
);
473 exp
->type
= PSI_T_INT64
;
474 exp
->data
.ival
.i64
= tmp
.i64
;
477 tmp
.i64
= strtoll(exp
->data
.numb
->val
, NULL
, 0);
478 zend_string_release(exp
->data
.numb
);
479 exp
->type
= PSI_T_INT64
;
480 exp
->data
.ival
.i64
= tmp
.i64
;
484 tmp
.u64
= strtoul(exp
->data
.numb
->val
, NULL
, 0);
485 zend_string_release(exp
->data
.numb
);
486 exp
->type
= PSI_T_UINT64
;
487 exp
->data
.ival
.u64
= tmp
.u64
;
490 tmp
.u64
= strtoull(exp
->data
.numb
->val
, NULL
, 0);
491 zend_string_release(exp
->data
.numb
);
492 exp
->type
= PSI_T_UINT64
;
493 exp
->data
.ival
.u64
= tmp
.u64
;
499 switch (exp
->flags
& 0x0ff00) {
501 tmp
.fval
= strtof(exp
->data
.numb
->val
, NULL
);
502 zend_string_release(exp
->data
.numb
);
503 exp
->type
= PSI_T_FLOAT
;
504 exp
->data
.ival
.fval
= tmp
.fval
;
509 tmp
.ldval
= strtold(exp
->data
.numb
->val
, NULL
);
510 zend_string_release(exp
->data
.numb
);
511 exp
->type
= PSI_T_LONG_DOUBLE
;
512 exp
->data
.ival
.ldval
= tmp
.ldval
;
518 tmp
.dval
= strtod(exp
->data
.numb
->val
, NULL
);
519 zend_string_release(exp
->data
.numb
);
520 exp
->type
= PSI_T_DOUBLE
;
521 exp
->data
.ival
.dval
= tmp
.dval
;
530 int type
= is_numeric_string(exp
->data
.numb
->val
, exp
->data
.numb
->len
, (zend_long
*) &tmp
, (double *)&tmp
, 0);
537 zend_string_release(exp
->data
.numb
);
538 exp
->type
= PSI_T_INT64
;
539 exp
->data
.ival
.i64
= tmp
.zend
.lval
;
543 zend_string_release(exp
->data
.numb
);
544 exp
->type
= PSI_T_DOUBLE
;
545 exp
->data
.ival
.dval
= tmp
.dval
;
552 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
553 lval
= strtol(exp
->data
.numb
->val
, &stop
, 0);
556 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
562 if (errno
== ERANGE
) {
565 stop
= exp
->data
.numb
->val
+ exp
->data
.numb
->len
;
566 ulval
= strtoul(exp
->data
.numb
->val
, &stop
, 0);
569 assert(stop
== exp
->data
.numb
->val
+ exp
->data
.numb
->len
);
573 zend_string_release(exp
->data
.numb
);
574 exp
->type
= PSI_T_UINT64
;
575 exp
->data
.ival
.u64
= ulval
;
581 zend_string_release(exp
->data
.numb
);
582 exp
->type
= PSI_T_INT64
;
583 exp
->data
.ival
.i64
= lval
;
587 data
->error(data
, exp
->token
, PSI_WARNING
, "Not a numeric string: '%s'", exp
->data
.numb
->val
);
590 data
->error(data
, exp
->token
, PSI_WARNING
, "Expected numeric entity (parser error?)");
594 bool psi_number_validate(struct psi_data
*data
, struct psi_number
*exp
,
595 struct psi_validate_scope
*scope
)
598 struct psi_const
*cnst
;
599 struct psi_decl_enum
*enm
;
603 exp
->type
= PSI_T_UINT8
;
621 case PSI_T_LONG_DOUBLE
:
628 //if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
629 // exp->type = PSI_T_DEFINE;
632 if (scope
&& scope
->current_enum
&& psi_number_validate_enum(data
, exp
, scope
)) {
635 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
636 struct psi_validate_scope enum_scope
= *scope
;
637 enum_scope
.current_enum
= enm
;
638 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
642 if (exp
->data
.dvar
->arg
) {
645 if (psi_decl_var_validate(data
, exp
->data
.dvar
, scope
)) {
648 data
->error(data
, exp
->token
, PSI_WARNING
,
649 "Unknown variable '%s' in numeric expression",
650 exp
->data
.dvar
->name
->val
);
654 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.call
->name
)) {
656 struct psi_cpp_macro_call
*call
= exp
->data
.call
;
658 for (i
= 0, argc
= psi_plist_count(call
->args
); i
< argc
; ++i
) {
659 struct psi_num_exp
*arg
;
661 if (!psi_plist_get(call
->args
, i
, &arg
)) {
664 if (!psi_num_exp_validate(data
, arg
, scope
)) {
670 if (psi_builtin_exists(exp
->data
.call
->name
)) {
671 exp
->data
.call
->builtin
= psi_builtin_get(exp
->data
.call
->name
);
677 if (scope
&& scope
->cpp
&& zend_hash_exists(&scope
->cpp
->defs
, exp
->data
.numb
)) {
679 if (!scope
->macro
|| !zend_string_equals(scope
->macro
->token
->text
, exp
->data
.numb
)) {
682 /* #define foo foo */
684 while (psi_plist_get(data
->enums
, i
++, &enm
)) {
685 struct psi_validate_scope enum_scope
= *scope
;
686 enum_scope
.current_enum
= enm
;
687 if (psi_number_validate_enum(data
, exp
, &enum_scope
)) {
694 if (psi_decl_type_validate(data
, exp
->data
.dtyp
, NULL
, scope
)) {
695 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
697 exp
->type
= PSI_T_UINT64
;
698 exp
->data
.ival
.u64
= psi_decl_type_get_size(dtyp
, NULL
);
699 psi_decl_type_free(&dtyp
);
702 struct psi_decl_type
*dtyp
= exp
->data
.dtyp
;
704 data
->error(data
, exp
->token
, PSI_WARNING
,
705 "Cannot compute sizeof(%s) (%u)", dtyp
->name
->val
, dtyp
->type
);
707 exp
->type
= PSI_T_UINT8
;
708 exp
->data
.ival
.u8
= 0;
709 psi_decl_type_free(&dtyp
);
717 if (exp
->data
.numb
->val
[0] == '\\') {
718 zc
= zend_get_constant_str(&exp
->data
.numb
->val
[1], exp
->data
.numb
->len
- 1);
720 zc
= zend_get_constant(exp
->data
.numb
);
724 switch (Z_TYPE_P(zc
)) {
726 zend_string_release(exp
->data
.numb
);
727 exp
->type
= PSI_T_INT64
;
728 exp
->data
.ival
.i64
= Z_LVAL_P(zc
);
732 zend_string_release(exp
->data
.numb
);
733 exp
->type
= PSI_T_DOUBLE
;
734 exp
->data
.ival
.dval
= Z_DVAL_P(zc
);
742 while (psi_plist_get(data
->consts
, i
++, &cnst
)) {
743 if (zend_string_equals(cnst
->name
, exp
->data
.numb
)) {
744 zend_string_release(exp
->data
.numb
);
745 exp
->type
= PSI_T_CONST
;
746 exp
->data
.cnst
= cnst
;
750 data
->error(data
, exp
->token
, PSI_WARNING
,
751 "Unknown constant '%s' in numeric expression",
752 exp
->data
.numb
->val
);
756 return psi_number_validate_number(data
, exp
);
758 case PSI_T_QUOTED_CHAR
:
759 return psi_number_validate_char(data
, exp
);
761 case PSI_T_CPP_HEADER
:
771 static inline token_t
psi_number_eval_constant(struct psi_number
*exp
,
772 impl_val
*res
, struct psi_call_frame
*frame
)
774 token_t typ
= exp
->data
.cnst
->type
? exp
->data
.cnst
->type
->type
: PSI_T_MIXED
;
778 res
->i64
= zend_get_constant(exp
->data
.cnst
->name
)->value
.lval
;
779 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
782 res
->dval
= zend_get_constant(exp
->data
.cnst
->name
)->value
.dval
;
783 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
786 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " ?(t=%u)", exp
->data
.cnst
->type
->type
);
792 static inline token_t
psi_number_eval_decl_var(struct psi_number
*exp
,
793 impl_val
*res
, struct psi_call_frame
*frame
)
796 struct psi_call_frame_symbol
*sym
;
797 struct psi_decl_type
*real
;
798 struct psi_decl_var
*var
;
801 var
= exp
->data
.dvar
;
802 real
= psi_decl_type_get_real(var
->arg
->type
);
803 size
= psi_decl_arg_get_size(var
->arg
);
804 sym
= psi_call_frame_fetch_symbol(frame
, var
);
805 ref
= deref_impl_val(sym
->ptr
, var
);
807 memcpy(res
, ref
, size
);
809 if (var
->arg
->var
->pointer_level
> var
->pointer_level
) {
810 switch (SIZEOF_VOID_P
) {
822 static inline token_t
psi_number_eval_define(struct psi_number
*exp
,
823 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
826 struct psi_cpp_macro_decl
*macro
;
828 macro
= zend_hash_find_ptr(&cpp
->defs
, exp
->data
.numb
);
829 if (macro
&& macro
->exp
&& macro
->exp
!= rec_guard
) {
830 return psi_num_exp_exec(macro
->exp
, res
, NULL
, cpp
);
838 static inline token_t
psi_number_eval_function(struct psi_number
*exp
,
839 impl_val
*res
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
842 PSI_DEBUG_PRINT(cpp
->parser
, "psi_number_eval(PSI_T_FUNCTION): %s\n", exp
->token
->text
->val
);
848 token_t
psi_number_eval(struct psi_number
*exp
, impl_val
*res
,
849 struct psi_call_frame
*frame
, struct psi_cpp
*cpp
, struct psi_num_exp
*rec_guard
)
853 *res
= exp
->data
.ival
;
854 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi8
, res
->i8
);
858 *res
= exp
->data
.ival
;
859 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu8
, res
->u8
);
862 *res
= exp
->data
.ival
;
863 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi16
, res
->i16
);
866 *res
= exp
->data
.ival
;
867 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu16
, res
->u16
);
870 *res
= exp
->data
.ival
;
871 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi32
, res
->i32
);
874 *res
= exp
->data
.ival
;
875 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu32
, res
->u32
);
878 *res
= exp
->data
.ival
;
879 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
882 *res
= exp
->data
.ival
;
883 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIu64
, res
->u64
);
887 *res
= exp
->data
.ival
;
888 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi128, res->i128);
891 *res
= exp
->data
.ival
;
892 //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu128, res->u128);
893 return PSI_T_UINT128
;
896 *res
= exp
->data
.ival
;
897 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIfval
, res
->fval
);
901 *res
= exp
->data
.ival
;
902 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIdval
, res
->dval
);
906 case PSI_T_LONG_DOUBLE
:
907 *res
= exp
->data
.ival
;
908 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIldval
, res
->ldval
);
913 res
->i64
= exp
->data
.enm
->val
;
914 if (frame
) PSI_DEBUG_PRINT(frame
->context
, " %" PRIi64
, res
->i64
);
918 res
->i64
= atol(exp
->data
.numb
->val
);
922 return psi_number_eval_constant(exp
, res
, frame
);
925 return psi_number_eval_decl_var(exp
, res
, frame
);
928 return psi_number_eval_define(exp
, res
, cpp
, rec_guard
);
931 return psi_number_eval_function(exp
, res
, cpp
, rec_guard
);
933 case PSI_T_CPP_HEADER
: