X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fnumber.c;h=5e62c62535e8297baaf33c9e2df3e76a2aa658fd;hp=b0a669f978d25fd7780919af401679548f488da0;hb=ef40ce43c98a00823e06c14f5cf7a8241f637ab1;hpb=ba906e039ffe9e57842ce5135aa43efa00b8a4c6 diff --git a/src/types/number.c b/src/types/number.c index b0a669f..5e62c62 100644 --- a/src/types/number.c +++ b/src/types/number.c @@ -74,6 +74,8 @@ struct psi_number *psi_number_init(token_t t, void *num, unsigned flags) exp->data.ival.ldval = *(long double *) num; break; #endif + case PSI_T_NULL: + break; case PSI_T_QUOTED_CHAR: case PSI_T_NUMBER: case PSI_T_NSNAME: @@ -86,6 +88,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); } @@ -117,6 +122,7 @@ struct psi_number *psi_number_copy(struct psi_number *exp) #endif case PSI_T_ENUM: case PSI_T_CONST: + case PSI_T_NULL: break; case PSI_T_NUMBER: case PSI_T_NSNAME: @@ -130,6 +136,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); } @@ -160,6 +169,7 @@ void psi_number_free(struct psi_number **exp_ptr) #endif case PSI_T_ENUM: case PSI_T_CONST: + case PSI_T_NULL: break; case PSI_T_FUNCTION: psi_cpp_macro_call_free(&exp->data.call); @@ -173,6 +183,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,20 +220,29 @@ 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_NULL: + dprintf(fd, "NULL"); + break; case PSI_T_NUMBER: case PSI_T_NSNAME: case PSI_T_DEFINE: 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 +252,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 +278,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) @@ -425,6 +458,9 @@ bool psi_number_validate(struct psi_data *data, struct psi_number *exp, struct psi_decl_enum *enm; switch (exp->type) { + case PSI_T_NULL: + exp->type = PSI_T_UINT8; + /* no break */ case PSI_T_CONST: case PSI_T_INT8: case PSI_T_UINT8: @@ -455,11 +491,12 @@ bool psi_number_validate(struct psi_data *data, struct psi_number *exp, if (exp->data.dvar->arg) { return true; } - if (psi_decl_var_validate(data, exp->data.dvar, impl ? impl->decl : NULL, - current_let, current_set)) { + if (psi_decl_var_validate(data, exp->data.dvar, impl, + impl ? impl->decl : NULL, current_let, current_set)) { return true; } - if (cb_decl && psi_decl_var_validate(data, exp->data.dvar, cb_decl, NULL, NULL)) { + if (cb_decl && psi_decl_var_validate(data, exp->data.dvar, + NULL, cb_decl, NULL, NULL)) { return true; } data->error(data, exp->token, PSI_WARNING, @@ -467,6 +504,21 @@ 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); + psi_decl_type_free(&dtyp); + return true; + } else { + data->error(data, exp->token, PSI_WARNING, + "Cannot compute sizeof(%s) (%u)", + exp->data.dtyp->name, exp->data.dtyp->type); + } + break; + case PSI_T_NSNAME: while (psi_plist_get(data->consts, i++, &cnst)) { if (!strcmp(cnst->name, exp->data.numb)) { @@ -511,7 +563,7 @@ static inline token_t psi_number_eval_constant(struct psi_number *exp, if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIdval, res->dval); return PSI_T_DOUBLE; default: - if (frame) PSI_DEBUG_PRINT(frame->context, " ?(t=%d)", exp->data.cnst->type->type); + if (frame) PSI_DEBUG_PRINT(frame->context, " ?(t=%u)", exp->data.cnst->type->type); return 0; } } @@ -523,15 +575,27 @@ static inline token_t psi_number_eval_decl_var(struct psi_number *exp, impl_val *ref; struct psi_call_frame_symbol *sym; struct psi_decl_type *real; + struct psi_decl_var *var; size_t size; - real = psi_decl_type_get_real(exp->data.dvar->arg->type); - size = psi_decl_arg_get_size(exp->data.dvar->arg); - sym = psi_call_frame_fetch_symbol(frame, exp->data.dvar); - ref = deref_impl_val(sym->ptr, exp->data.dvar); + var = exp->data.dvar; + real = psi_decl_type_get_real(var->arg->type); + size = psi_decl_arg_get_size(var->arg); + sym = psi_call_frame_fetch_symbol(frame, var); + ref = deref_impl_val(sym->ptr, var); memcpy(res, ref, size); + if (var->arg->var->pointer_level > var->pointer_level) { + switch (SIZEOF_VOID_P) { + case 4: + return PSI_T_INT32; + case 8: + return PSI_T_INT64; + default: + assert(0); + } + } return real->type; } @@ -590,7 +654,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 +663,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);