X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fnumber.c;h=b45e00ea2fe4126890ba97ac89b07823d4c2f26f;hp=b0a669f978d25fd7780919af401679548f488da0;hb=35ae2559447092572209f8b237460ceb551293ff;hpb=ba906e039ffe9e57842ce5135aa43efa00b8a4c6 diff --git a/src/types/number.c b/src/types/number.c index b0a669f..b45e00e 100644 --- a/src/types/number.c +++ b/src/types/number.c @@ -86,6 +86,9 @@ struct psi_number *psi_number_init(token_t t, void *num, unsigned flags) case PSI_T_FUNCTION: exp->data.call = num; break; + case PSI_T_SIZEOF: + exp->data.dtyp = num; + break; default: assert(0); } @@ -130,6 +133,9 @@ struct psi_number *psi_number_copy(struct psi_number *exp) case PSI_T_FUNCTION: num->data.call = psi_cpp_macro_call_copy(num->data.call); break; + case PSI_T_SIZEOF: + num->data.dtyp = psi_decl_type_copy(num->data.dtyp); + break; default: assert(0); } @@ -173,6 +179,9 @@ void psi_number_free(struct psi_number **exp_ptr) case PSI_T_NAME: psi_decl_var_free(&exp->data.dvar); break; + case PSI_T_SIZEOF: + psi_decl_type_free(&exp->data.dtyp); + break; default: assert(0); } @@ -207,12 +216,15 @@ void psi_number_dump(int fd, struct psi_number *exp) case PSI_T_UINT64: dprintf(fd, "%" PRIu64, exp->data.ival.u64); break; + case PSI_T_FLOAT: + dprintf(fd, "%" PRIfval, exp->data.ival.dval); + break; case PSI_T_DOUBLE: - dprintf(fd, "%F", exp->data.ival.dval); + dprintf(fd, "%" PRIdval, exp->data.ival.dval); break; #if HAVE_LONG_DOUBLE case PSI_T_LONG_DOUBLE: - dprintf(fd, "%lF", exp->data.ival.ldval); + dprintf(fd, "%" PRIldval, exp->data.ival.ldval); break; #endif case PSI_T_NUMBER: @@ -221,6 +233,9 @@ void psi_number_dump(int fd, struct psi_number *exp) case PSI_T_QUOTED_CHAR: dprintf(fd, "%s", exp->data.numb); break; + case PSI_T_FUNCTION: + psi_cpp_macro_call_dump(fd, exp->data.call); + break; case PSI_T_CONST: dprintf(fd, "%s", exp->data.cnst->name); break; @@ -230,6 +245,9 @@ void psi_number_dump(int fd, struct psi_number *exp) case PSI_T_NAME: psi_decl_var_dump(fd, exp->data.dvar); break; + case PSI_T_SIZEOF: + psi_decl_type_dump(fd, exp->data.dtyp, 0); + break; default: assert(0); } @@ -253,80 +271,88 @@ static inline bool psi_number_validate_enum(struct psi_data *data, struct psi_nu return false; } -static inline bool psi_number_validate_char(struct psi_data *data, struct psi_number *exp) +static inline token_t validate_char(char *numb, impl_val *res, unsigned *lvl) { - impl_val tmp = {0}; - /* FIXME L */ - tmp.i8 = exp->data.numb[1 + (*exp->data.numb == 'L')]; - switch(tmp.i8) { + char *endptr; + token_t typ = PSI_T_INT8; + + res->i8 = numb[0]; + endptr = &numb[1]; + + switch(res->i8) { case '\\': - tmp.i8 = exp->data.numb[2 + (*exp->data.numb == 'L')]; - switch(tmp.i8) { + res->i8 = numb[1]; + endptr = &numb[2]; + + switch(res->i8) { + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': + res->i8 = strtol(&numb[1], &endptr, 8); + break; + case 'x': - tmp.i8 = strtol(&exp->data.numb[3 + (*exp->data.numb == 'L')], NULL, 16); - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = tmp.i8; - return true; - case '\'': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\''; - return true; + res->i8 = strtol(&numb[2], &endptr, 16); + break; + case 'a': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\a'; - return true; + res->i8 = '\a'; + break; case 'b': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\b'; - return true; + res->i8 = '\b'; + break; case 'f': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\f'; - return true; + res->i8 = '\f'; + break; case 'n': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\n'; - return true; + res->i8 = '\n'; + break; case 'r': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\r'; - return true; + res->i8 = '\r'; + break; case 't': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\t'; - return true; + res->i8 = '\t'; + break; case 'v': - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = '\v'; - return true; - case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - tmp.i8 = strtol(&exp->data.numb[2 + (*exp->data.numb == 'L')], NULL, 8); - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = tmp.i8; - return true; + res->i8 = '\v'; + break; default: - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = tmp.i8; - return true; + break; } break; default: - free(exp->data.numb); - exp->type = PSI_T_INT8; - exp->data.ival.i8 = tmp.i8; - return true; + break; + } + + /* more to grok? */ + if (*endptr) { + impl_val tmp_val = {0}; + token_t tmp_typ = validate_char(endptr, &tmp_val, lvl); + + if (!tmp_typ) { + return 0; + } + + res->i32 = res->i8 << (8 * *lvl); + typ = psi_calc_add(PSI_T_INT32, res, tmp_typ, &tmp_val, res); } + + ++(*lvl); + + return typ; +} +static inline bool psi_number_validate_char(struct psi_data *data, struct psi_number *exp) +{ + impl_val val = {0}; + unsigned lvl = 1; + token_t typ = validate_char(exp->data.numb, &val, &lvl); + + if (!typ) { + return false; + } + + free(exp->data.numb); + exp->type = typ; + exp->data.ival = val; + return true; } static inline bool psi_number_validate_number(struct psi_data *data, struct psi_number *exp) @@ -467,6 +493,16 @@ bool psi_number_validate(struct psi_data *data, struct psi_number *exp, exp->data.dvar->name); return false; + case PSI_T_SIZEOF: + if (psi_decl_type_validate(data, exp->data.dtyp, 0, NULL)) { + struct psi_decl_type *dtyp = exp->data.dtyp; + + exp->type = PSI_T_UINT64; + exp->data.ival.u64 = psi_decl_type_get_size(dtyp, NULL); + return true; + } + break; + case PSI_T_NSNAME: while (psi_plist_get(data->consts, i++, &cnst)) { if (!strcmp(cnst->name, exp->data.numb)) { @@ -590,7 +626,7 @@ token_t psi_number_eval(struct psi_number *exp, impl_val *res, struct psi_call_f #if HAVE_LONG_DOUBLE case PSI_T_LONG_DOUBLE: *res = exp->data.ival; - if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIdval, res->dval); + if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIldval, res->ldval); return exp->type; #endif @@ -599,6 +635,10 @@ token_t psi_number_eval(struct psi_number *exp, impl_val *res, struct psi_call_f if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi64, res->i64); return PSI_T_INT64; + case PSI_T_NUMBER: + res->i64 = atol(exp->data.numb); + return PSI_T_INT64; + case PSI_T_CONST: return psi_number_eval_constant(exp, res, frame);