X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fnum_exp.c;fp=src%2Ftypes%2Fnum_exp.c;h=0577acf88160d4beabd9e31a5758c2708ed61ad5;hp=9718cede62ba0fb56e1426f148036818e79061b3;hb=42f44eb5bf4ecd36e26e051fada79d861d0f92d2;hpb=1b6db76e3005344b33ab45b00e7e61386a33932a diff --git a/src/types/num_exp.c b/src/types/num_exp.c index 9718ced..0577acf 100644 --- a/src/types/num_exp.c +++ b/src/types/num_exp.c @@ -60,11 +60,24 @@ struct psi_num_exp *psi_num_exp_init_num(struct psi_number *n) { struct psi_num_exp *exp = calloc(1, sizeof(*exp)); + exp->op = PSI_T_NUMBER; exp->data.n = n; return exp; } +struct psi_num_exp *psi_num_exp_init_cast(struct psi_decl_type *typ, + struct psi_num_exp *num) +{ + struct psi_num_exp *exp = calloc(1, sizeof(*exp)); + + exp->op = PSI_T_CAST; + exp->data.c.typ = typ; + exp->data.c.num = num; + + return exp; +} + struct psi_num_exp *psi_num_exp_copy(struct psi_num_exp *exp) { struct psi_num_exp *cpy; @@ -77,10 +90,15 @@ struct psi_num_exp *psi_num_exp_copy(struct psi_num_exp *exp) *cpy = *exp; switch (exp->op) { - case 0: + case PSI_T_NUMBER: cpy->data.n = psi_number_copy(exp->data.n); break; + case PSI_T_CAST: + cpy->data.c.typ = psi_decl_type_copy(exp->data.c.typ); + cpy->data.c.num = psi_num_exp_copy(exp->data.c.num); + break; + case PSI_T_NOT: case PSI_T_TILDE: case PSI_T_LPAREN: @@ -130,9 +148,15 @@ void psi_num_exp_free(struct psi_num_exp **c_ptr) *c_ptr = NULL; switch (c->op) { - case 0: + case PSI_T_NUMBER: psi_number_free(&c->data.n); break; + + case PSI_T_CAST: + psi_decl_type_free(&c->data.c.typ); + psi_num_exp_free(&c->data.c.num); + break; + case PSI_T_NOT: case PSI_T_TILDE: case PSI_T_LPAREN: @@ -184,6 +208,8 @@ static inline const char *psi_num_exp_op_tok(token_t op) return "~"; case PSI_T_LPAREN: return "("; + case PSI_T_CAST: + return "(cast)"; case PSI_T_PIPE: return "|"; @@ -236,7 +262,7 @@ static inline const char *psi_num_exp_op_tok(token_t op) void psi_num_exp_dump(int fd, struct psi_num_exp *exp) { switch (exp->op) { - case 0: + case PSI_T_NUMBER: psi_number_dump(fd, exp->data.n); break; @@ -287,7 +313,7 @@ bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp, struct psi_impl *impl, struct psi_decl *cb_decl, struct psi_let_exp *current_let, struct psi_set_exp *current_set, struct psi_decl_enum *current_enum) { - if (exp->op) { + if (exp->op && exp->op != PSI_T_NUMBER) { switch (exp->op) { case PSI_T_NOT: exp->calc = psi_calc_bool_not; @@ -321,6 +347,7 @@ bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp, exp->calc = psi_calc_cmp_gt; break; + case PSI_T_CAST: case PSI_T_LPAREN: break; @@ -362,9 +389,14 @@ bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp, } switch (exp->op) { - case 0: + case PSI_T_NUMBER: return psi_number_validate(data, exp->data.n, impl, cb_decl, current_let, current_set, current_enum); + case PSI_T_CAST: + return psi_num_exp_validate(data, exp->data.c.num, impl, cb_decl, current_let, current_set, current_enum) + && psi_decl_type_validate(data, exp->data.c.typ, NULL); + break; + case PSI_T_NOT: case PSI_T_TILDE: case PSI_T_LPAREN: @@ -447,11 +479,12 @@ static void psi_num_exp_reduce(struct psi_num_exp *exp, struct psi_plist **outpu union { impl_val value; psi_calc calc; + struct psi_decl_type *cast; } data; } entry; switch (exp->op) { - case 0: + case PSI_T_NUMBER: entry.type = psi_number_eval(exp->data.n, &entry.data.value, frame, defs); output = psi_plist_add(output, &entry); break; @@ -469,6 +502,22 @@ static void psi_num_exp_reduce(struct psi_num_exp *exp, struct psi_plist **outpu } break; + case PSI_T_CAST: + while (psi_plist_top(input, &entry)) { + /* bail out if exp->op >= entry.type */ + if (psi_calc_oper(exp->op, entry.type) != 1) { + break; + } + psi_plist_pop(input, NULL); + if (frame) PSI_DEBUG_PRINT(frame->context, " %s", psi_num_exp_op_tok(entry.type)); + output = psi_plist_add(output, &entry); + } + entry.type = exp->op; + entry.data.cast = exp->data.c.typ; + input = psi_plist_add(input, &entry); + psi_num_exp_reduce(exp->data.c.num, &output, &input, frame, defs); + break; + case PSI_T_NOT: case PSI_T_TILDE: while (psi_plist_top(input, &entry)) { @@ -517,6 +566,7 @@ token_t psi_num_exp_exec(struct psi_num_exp *exp, impl_val *res, union { impl_val value; psi_calc calc; + struct psi_decl_type *cast; } data; } entry, lhs, rhs; @@ -537,6 +587,17 @@ token_t psi_num_exp_exec(struct psi_num_exp *exp, impl_val *res, input = psi_plist_add(input, &entry); break; + case PSI_T_CAST: + psi_plist_pop(input, &rhs); + if (frame) PSI_DEBUG_PRINT(frame->context, " %s", psi_num_exp_op_tok(entry.type)); + psi_impl_val_dump(rhs.type, &rhs.data.value, frame); + + entry.type = psi_decl_type_get_real(entry.data.cast)->type; + psi_calc_cast(rhs.type, &rhs.data.value, entry.type, &entry.data.value); + input = psi_plist_add(input, &entry); + psi_num_exp_verify_result(entry.type, &entry.data.value, frame); + break; + case PSI_T_NOT: case PSI_T_TILDE: psi_plist_pop(input, &rhs);