#include "token.h"
#include "types/impl_val.h"
-#define PRIfval ".6g"
-#define PRIdval ".16g"
-#define PRIldval ".29Lg"
+#include <float.h>
+
+#define PRIfmt_digits(digits) #digits
+#define PRIfmt(digits, fmt) "." PRIfmt_digits(digits) fmt
+#define PRIfval PRIfmt(FLT_DECIMAL_DIG, "g")
+#define PRIdval PRIfmt(DBL_DECIMAL_DIG, "g")
+#if HAVE_LONG_DOUBLE
+# define PRIldval PRIfmt(LDBL_DECIMAL_DIG, "Lg")
+#endif
typedef token_t (*psi_calc)(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res);
struct psi_decl_enum *enm;
while (psi_plist_get(D->enums, i++, &enm)) {
- if (!psi_decl_type_is_anon(enm->name, "enum")) {
+ if (true || !psi_decl_type_is_anon(enm->name, "enum")) {
psi_decl_enum_dump(dump, enm, 0);
PSI_DUMP(dump, "\n");
}
#include "parser.h"
-struct psi_parser *psi_parser_init(struct psi_parser *P, psi_error_cb error, unsigned flags)
+struct psi_parser *psi_parser_init(struct psi_parser *P, psi_error_cb error,
+ unsigned flags)
{
if (!P) {
P = pemalloc(sizeof(*P), 1);
return P;
}
-struct psi_parser_input *psi_parser_open_file(struct psi_parser *P, const char *filename, bool report_errors)
+struct psi_parser_input *psi_parser_open_file(struct psi_parser *P,
+ const char *filename, bool report_errors)
{
struct stat sb;
FILE *fp;
return fb;
}
-struct psi_parser_input *psi_parser_open_string(struct psi_parser *P, const char *string, size_t length)
+struct psi_parser_input *psi_parser_open_string(struct psi_parser *P,
+ const char *string, size_t length)
{
struct psi_parser_input *sb;
return sb;
}
-struct psi_plist *psi_parser_preprocess(struct psi_parser *P, struct psi_plist **tokens)
+struct psi_plist *psi_parser_preprocess(struct psi_parser *P,
+ struct psi_plist **tokens)
{
if (psi_cpp_process(P->preproc, tokens)) {
return *tokens;
return NULL;
}
-bool psi_parser_process(struct psi_parser *P, struct psi_plist *tokens, size_t *processed)
+bool psi_parser_process(struct psi_parser *P, struct psi_plist *tokens,
+ size_t *processed)
{
if (psi_plist_count(tokens)) {
return 0 == psi_parser_proc_parse(P, tokens, processed);
smart_str_append_printf(&str, "const psi\\%s = ", name->val);
if (scope->macro->exp) {
- struct psi_dump dump = {{.hn = &str}, .fun = (psi_dump_cb) smart_str_append_printf};
+ struct psi_dump dump = {{.hn = &str},
+ .fun = (psi_dump_cb) smart_str_append_printf};
psi_num_exp_dump(&dump, scope->macro->exp);
} else while (psi_plist_get(scope->macro->tokens, i++, &tok)) {
if (!cnst) {
continue;
}
-
+//fprintf(stderr, "PARSE: %s", ZSTR_VAL(cnst));
I = psi_parser_open_string(P, ZSTR_VAL(cnst), ZSTR_LEN(cnst));
zend_string_release(cnst);
void psi_decl_enum_dump(struct psi_dump *dump, struct psi_decl_enum *e, unsigned level)
{
- PSI_DUMP(dump, "enum %s {\n", e->name->val);
+ bool is_anon = psi_decl_type_is_anon(e->name, "enum");
+ PSI_DUMP(dump, "enum %s%s%s {\n",
+ is_anon ? "/* ":"", e->name->val, is_anon ? " */":"");
if (e->items) {
size_t i = 0;
struct psi_decl_enum_item *item;
}
}
-/*
-token_t psi_impl_def_val_get_zend(struct psi_impl_def_val *val, impl_val *res)
-{
- switch (val->type) {
- case PSI_T_NULL:
- return PSI_T_NULL;
- case PSI_T_TRUE:
- case PSI_T_FALSE:
- res->zend.bval = val->ival.zend.bval;
- return PSI_T_BOOL;
- case PSI_T_STRING:
- res->zend.str = val->ival.zend.str
- ? zend_string_copy(val->ival.zend.str)
- : zend_empty_string;
- return PSI_T_STRING;
- case PSI_T_NUMBER:
- switch (val->ityp) {
- case PSI_T_FLOAT:
- res->dval = val->ival.fval;
- return PSI_T_DOUBLE;
- case PSI_T_DOUBLE:
- res->dval = val->ival.dval;
- return PSI_T_DOUBLE;
-#if HAVE_LONG_DOUBLE
- case PSI_T_LONG_DOUBLE:
- res->dval = val->ival.ldval;
- return PSI_T_DOUBLE;
-#endif
- default:
- psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, res);
- return PSI_T_INT;
- }
- break;
- default:
- assert(0);
- return 0;
- }
-}
-*/
static inline bool psi_impl_def_val_validate_impl_type(struct psi_data *data,
struct psi_impl_def_val *val, struct psi_impl_type *type,
case PSI_T_FALSE:
return true;
case PSI_T_STRING:
- if (val->ival.zend.str
- && *val->ival.zend.str->val
- && *val->ival.zend.str->val != '0') {
- zend_string_release(val->ival.zend.str);
- val->ival.zend.bval = 1;
- } else {
- if (val->ival.zend.str) {
- zend_string_release(val->ival.zend.str);
- }
- val->ival.zend.bval = 0;
+ if (val->ival.zend.str) {
+ zend_string *tmp = val->ival.zend.str;
+
+ val->ival.zend.bval = (*tmp->val && *tmp->val != '0');
+ zend_string_release(tmp);
}
val->ityp = PSI_T_UINT8;
+ val->type = PSI_T_BOOL;
return true;
default:
assert(0);
return true;
}
psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, &val->ival);
- val->type = val->ityp = PSI_T_INT64;
+ val->type = PSI_T_INT;
+ val->ityp = PSI_T_INT64;
return true;
case PSI_T_FLOAT:
case PSI_T_DOUBLE:
return true;
} else {
smart_str str = {0};
+ struct psi_dump dump = {{.hn = &str},
+ .fun = (psi_dump_cb) smart_str_append_printf};
switch (val->ityp) {
- CASE_IMPLVAL_NUM_PRINTF(smart_str_append_printf, &str, val->ival, false);
+ CASE_IMPLVAL_NUM_DUMP(&dump, val->ival, false);
default:
assert(0);
}
}
return false;
-/*
- switch (type ? type->type : PSI_T_MIXED) {
- case PSI_T_BOOL:
- val->ival.zend.bval = val->type == PSI_T_TRUE ? 1 : 0;
- return true;
- break;
-
- // macros
- case PSI_T_NUMBER:
- if (val->type == PSI_T_NUMBER) {
- token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp);
-
- switch (typ) {
- case PSI_T_FLOAT:
- val->ival.dval = val->ival.fval;
- // no break
- case PSI_T_DOUBLE:
- val->type = PSI_T_FLOAT;
- type->type = PSI_T_FLOAT;
- zend_string_release(type->name);
- type->name = zend_string_init_interned(ZEND_STRL("float"), 1);
- break;
- case PSI_T_UINT64:
- if (val->ival.u64 > ZEND_LONG_MAX) {
- data->error(data, val->token, PSI_WARNING,
- "Integer too big for signed representation: '%" PRIu64 "'",
- val->ival.u64);
- }
- default:
- // FIXME big integers
- val->type = PSI_T_INT;
- type->type = PSI_T_INT;
- zend_string_release(type->name);
- type->name = zend_string_init_interned(ZEND_STRL("int"), 1);
- break;
- }
- psi_num_exp_free(&val->data.num);
- return true;
- }
- break;
-
- case PSI_T_INT:
- if (val->type == PSI_T_NUMBER) {
- val->type = PSI_T_INT;
- val->ival.zend.lval = psi_num_exp_get_long(val->data.num, NULL, scope->cpp);
-#if PSI_IMPL_DEF_VAL_DEBUG
- PSI_DEBUG_PRINT(data, "PSI: NUMBER (long) %" PRIi64 " from ", val->ival.zend.lval);
- PSI_DEBUG_DUMP(data, psi_num_exp_dump, val->data.num);
- PSI_DEBUG_PRINT(data, "\n");
-#endif
- psi_num_exp_free(&val->data.num);
- }
- if (val->type == PSI_T_INT) {
- return true;
- }
- break;
-
- case PSI_T_FLOAT:
- case PSI_T_DOUBLE:
- if (val->type == PSI_T_NUMBER) {
- val->type = PSI_T_DOUBLE;
- val->ival.dval = psi_num_exp_get_double(val->data.num, NULL, scope->cpp);
-#if PSI_IMPL_DEF_VAL_DEBUG
- PSI_DEBUG_PRINT(data, "PSI: NUMBER (double) %" PRIdval " from ", val->ival.dval);
- PSI_DEBUG_DUMP(data, psi_num_exp_dump, val->data.num);
- PSI_DEBUG_PRINT(data, "\n");
-#endif
- psi_num_exp_free(&val->data.num);
- }
- if (val->type == PSI_T_DOUBLE) {
- return true;
- }
- break;
-
- case PSI_T_STRING:
- if (val->type == PSI_T_STRING) {
- return true; data->error(data, val->token, PSI_WARNING,
- "Invalid default value type '%s', "
- "expected one of bool, int, float, string.",
- type ? type->name->val : "mixed");
-
- }
- break;
-
- case PSI_T_MIXED:
-
- }
- // no break
- default:
- }
-*/
}
void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val) {
default:
assert(0);
}
- PSI_DUMP(dump, "\t/* t=%d */ ", val->type);
+#if 0
+ PSI_DUMP(dump, "\t/* impl_def_val.type=%d */ ", val->type);
+#endif
}
# define isnanl isnan
#endif
#if HAVE_LONG_DOUBLE
-# define CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix) \
+# define CASE_IMPLVAL_LD_DUMP(dump, ival, with_suffix) \
case PSI_T_LONG_DOUBLE: \
if (isinfl(ival.ldval)) { \
- fun(to, "\\INF"); \
+ PSI_DUMP(dump, "\\INF"); \
} else if (isnanl(ival.ldval)) { \
- fun(to, "\\NAN"); \
+ PSI_DUMP(dump, "\\NAN"); \
} else { \
- fun(to, "%" PRIldval "%s", ival.ldval, (with_suffix) ? "L" : ""); \
+ /* bug in long double formatting of xbuf_fmt_conv? */ \
+ char buf[0x100] = {0}; \
+ snprintf(buf, sizeof(buf) - 1, "%" PRIldval, ival.ldval); \
+ PSI_DUMP(dump, "%s%s", buf, (with_suffix) ? "L" : ""); \
} \
- break;
+ break
#else
-# define CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix)
+# define CASE_IMPLVAL_LD_DUMP(dump, ival, with_suffix)
#endif
-#define CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix) \
- CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix); \
+#define CASE_IMPLVAL_FLOAT_DUMP(dump, ival, with_suffix) \
+ CASE_IMPLVAL_LD_DUMP(dump, ival, with_suffix); \
case PSI_T_FLOAT: \
if (isinf(ival.dval)) { \
- fun(to, "\\INF"); \
+ PSI_DUMP(dump, "\\INF"); \
} else if (isnan(ival.dval)) { \
- fun(to, "\\NAN"); \
+ PSI_DUMP(dump, "\\NAN"); \
} else { \
- fun(to, "%" PRIfval "%s", ival.dval, (with_suffix) ? "F" : ""); \
+ PSI_DUMP(dump, "%" PRIfval "%s", ival.fval, (with_suffix) ? "F" : ""); \
} \
break; \
case PSI_T_DOUBLE: \
if (isinf(ival.dval)) { \
- fun(to, "\\INF"); \
+ PSI_DUMP(dump, "\\INF"); \
} else if (isnan(ival.dval)) { \
- fun(to, "\\NAN"); \
+ PSI_DUMP(dump, "\\NAN"); \
} else { \
- fun(to, "%" PRIdval, ival.dval); \
+ PSI_DUMP(dump, "%" PRIdval, ival.dval); \
} \
break
-#define CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix) \
+#define CASE_IMPLVAL_INT_DUMP(dump, ival, with_suffix) \
case PSI_T_INT8: \
- fun(to, "%" PRId8, ival.i8); \
+ PSI_DUMP(dump, "%" PRId8, ival.i8); \
break; \
case PSI_T_UINT8: \
- fun(to, "%" PRIu8, ival.u8); \
+ PSI_DUMP(dump, "%" PRIu8, ival.u8); \
break; \
case PSI_T_INT16: \
- fun(to, "%" PRId16, ival.i16); \
+ PSI_DUMP(dump, "%" PRId16, ival.i16); \
break; \
case PSI_T_UINT16: \
- fun(to, "%" PRIu16, ival.u16); \
+ PSI_DUMP(dump, "%" PRIu16, ival.u16); \
break; \
case PSI_T_INT32: \
- fun(to, "%" PRId32, ival.i32); \
+ PSI_DUMP(dump, "%" PRId32, ival.i32); \
break; \
case PSI_T_UINT32: \
- fun(to, "%" PRIu32 "%s", ival.u32, (with_suffix) ? "U" : ""); \
+ PSI_DUMP(dump, "%" PRIu32 "%s", ival.u32, (with_suffix) ? "U" : ""); \
break; \
case PSI_T_INT64: \
- fun(to, "%" PRId64 "%s", ival.i64, (with_suffix) ? "L" : ""); \
+ PSI_DUMP(dump, "%" PRId64 "%s", ival.i64, (with_suffix) ? "L" : ""); \
break; \
case PSI_T_UINT64: \
- fun(to, "%" PRIu64 "%s", ival.u64, (with_suffix) ? "UL" : ""); \
+ PSI_DUMP(dump, "%" PRIu64 "%s", ival.u64, (with_suffix) ? "UL" : ""); \
break
-#define CASE_IMPLVAL_NUM_PRINTF(fun, to, ival, with_suffix) \
- CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix); \
- CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix)
+#define CASE_IMPLVAL_NUM_DUMP(dump, ival, with_suffix) \
+ CASE_IMPLVAL_INT_DUMP(dump, ival, with_suffix); \
+ CASE_IMPLVAL_FLOAT_DUMP(dump, ival, with_suffix)
#endif
PSI_DUMP(dump, "(");
psi_decl_type_dump(dump, exp->data.c.typ, 0);
PSI_DUMP(dump, ")");
+ psi_num_exp_dump(dump, exp->data.c.num);
break;
case PSI_T_NOT:
{
switch (exp->type) {
case PSI_T_DEFINED:
- CASE_IMPLVAL_NUM_PRINTF(dump->fun, dump->ctx, exp->data.ival, 1);
+ CASE_IMPLVAL_NUM_DUMP(dump, exp->data.ival, true);
case PSI_T_NULL:
PSI_DUMP(dump, "NULL");
break;
case PSI_T_NUMBER:
case PSI_T_NSNAME:
- case PSI_T_DEFINE:
case PSI_T_QUOTED_CHAR:
case PSI_T_CPP_HEADER:
PSI_DUMP(dump, "%s", exp->data.numb->val);
break;
+ case PSI_T_DEFINE:
+ PSI_DUMP(dump, "%s /* DEFINE */", exp->data.numb->val);
+ break;
case PSI_T_FUNCTION:
psi_cpp_macro_call_dump(dump, exp->data.call);
break;
PSI_DUMP(dump, "%s", exp->data.cnst->name->val);
break;
case PSI_T_ENUM:
- PSI_DUMP(dump, "%s", exp->data.enm->name->val);
+ PSI_DUMP(dump, "%s /* ENUM */ ", exp->data.enm->name->val);
break;
case PSI_T_NAME:
psi_decl_var_dump(dump, exp->data.dvar);
default:
assert(0);
}
+#if 0
+ PSI_DUMP(dump, "\t/* number.type=%d */ ", exp->type);
+#endif
}
static inline bool psi_number_validate_enum(struct psi_data *data,
return true;
case PSI_T_NAME:
- if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
- exp->type = PSI_T_DEFINE;
- goto define;
- }
+ //if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
+ // exp->type = PSI_T_DEFINE;
+ // goto define;
+ //}
if (scope && scope->current_enum && psi_number_validate_enum(data, exp, scope)) {
return true;
}
var_dump(file_exists($fn));
var_dump(psi_validate($fn, 0, $e), $e);
-@unlink(__DIR__."/dump001.psi");
+#@unlink(__DIR__."/dump001.psi");
?>
===DONE===
===DONE===
--CLEAN--
<?php
-@unlink(__DIR__."/dump001.psi");
+#@unlink(__DIR__."/dump001.psi");
?>