--- rpl/src/interface_cas.cpp 2011/07/25 07:44:59 1.11 +++ rpl/src/interface_cas.cpp 2011/08/03 09:26:47 1.12 @@ -50,19 +50,24 @@ static unsigned char * conversion_rpl_vers_cas(struct_processus *s_etat_processus, struct_objet **s_objet) { + logical1 drapeau; + struct_liste_chainee *l_element_courant; + struct_liste_chainee *l_element_precedent; struct_objet *s_objet_temporaire; t_8_bits registre[8]; unsigned char *resultat; + unsigned char *index; for(int i = 0; i < 8; i++) { registre[i] = s_etat_processus->drapeaux_etat[i]; } + sf(s_etat_processus, 35); cf(s_etat_processus, 48); cf(s_etat_processus, 49); cf(s_etat_processus, 50); @@ -76,20 +81,81 @@ conversion_rpl_vers_cas(struct_processus // les noms de fonction. Les fonctions ne peuvent apparaître que dans le // cas d'un objet de type ALG. - if ((*s_objet)->type == ALG) + if ((*s_objet)->type == NOM) { - if ((*s_objet)->nombre_occurrences > 1) + if (strcmp((const char *) reinterpret_cast( + reinterpret_cast((*s_objet)->objet)->nom), + "infinity") == 0) { - if ((s_objet_temporaire = copie_objet(s_etat_processus, - (*s_objet), 'O')) == NULL) + if (evaluation(s_etat_processus, *s_objet, 'N') == d_erreur) + { + return(NULL); + } + + liberation(s_etat_processus, *s_objet); + + if (depilement(s_etat_processus, &(s_etat_processus + ->l_base_pile), s_objet) == d_erreur) + { + return(NULL); + } + } + } + else if ((*s_objet)->type == ALG) + { + if ((s_objet_temporaire = copie_objet(s_etat_processus, + (*s_objet), 'O')) == NULL) + { + s_etat_processus->erreur_systeme = d_es_allocation_memoire; + return(NULL); + } + + liberation(s_etat_processus, (*s_objet)); + (*s_objet) = s_objet_temporaire; + + // Si l'expression contient la fonction infinity, on commence par + // forcer une évaluation numérique. + + l_element_courant = reinterpret_cast( + (*s_objet)->objet); + drapeau = d_faux; + + while(l_element_courant != NULL) + { + if (l_element_courant->donnee->type == NOM) + { + if (strcmp((const char *) reinterpret_cast( + reinterpret_cast( + l_element_courant->donnee->objet)->nom), + "infinity") == 0) + { + drapeau = d_vrai; + break; + } + } + + l_element_courant = l_element_courant->suivant; + } + + if (drapeau == d_vrai) + { + if (evaluation(s_etat_processus, *s_objet, 'N') == d_erreur) { - s_etat_processus->erreur_systeme = d_es_allocation_memoire; return(NULL); } - liberation(s_etat_processus, (*s_objet)); - (*s_objet) = s_objet_temporaire; + liberation(s_etat_processus, *s_objet); + + if (depilement(s_etat_processus, &(s_etat_processus + ->l_base_pile), s_objet) == d_erreur) + { + return(NULL); + } } + } + + if ((*s_objet)->type == ALG) + { l_element_courant = reinterpret_cast( (*s_objet)->objet); @@ -118,13 +184,43 @@ conversion_rpl_vers_cas(struct_processus } } + l_element_precedent = l_element_courant; l_element_courant = l_element_courant->suivant; } } resultat = formateur(s_etat_processus, 0, (*s_objet)); - resultat[0] = ' '; - resultat[strlen((const char *) resultat) - 1] = ' '; + + // Il faut remplacer les occurrences de 'relax' par ' +'. + + index = resultat; + while((index = reinterpret_cast( + strstr(reinterpret_cast(index), + (const char *) "relax"))) != NULL) + { + strncpy(reinterpret_cast(index), " +", 5); + } + + // Si le résultat vaut infinity, on rajoute le signe +. + + if (strcmp(reinterpret_cast(resultat), "infinity") == 0) + { + if ((resultat = reinterpret_cast( + realloc(resultat, (strlen(reinterpret_cast( + resultat)) + 2) * sizeof(unsigned char)))) == NULL) + { + s_etat_processus->erreur_systeme = d_es_allocation_memoire; + return(NULL); + } + + strcpy(reinterpret_cast(resultat), "+infinity"); + } + + if (resultat[0] == '\'') + { + resultat[0] = ' '; + resultat[strlen((const char *) resultat) - 1] = ' '; + } for(int i = 0; i < 8; i++) { @@ -158,9 +254,12 @@ conversion_cas_vers_rpl(struct_processus // qui n'est pas reconnu comme un mot-clef du RPL/2. S'il // s'agit d'un mot-clef de GIAC, on le convertit. - if (strcmp((const char *) + if ((strcmp((const char *) + reinterpret_cast(l_element_courant + ->donnee->objet)->nom_fonction, "quote") == 0) || + (strcmp((const char *) reinterpret_cast(l_element_courant - ->donnee->objet)->nom_fonction, "quote") == 0) + ->donnee->objet)->nom_fonction, "nop") == 0)) { liberation(s_etat_processus, l_element_courant->donnee); @@ -218,11 +317,18 @@ interface_cas(struct_processus *s_etat_p # ifdef RPLCAS struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; + struct_objet *s_objet_temporaire; + + struct_liste_chainee *l_element_courant; unsigned char *argument_1; unsigned char *argument_2; + unsigned char *argument_3; + unsigned char *argument_4; unsigned char *registre; + unsigned int position; + switch(commande) { case RPLCAS_INTEGRATION: @@ -230,7 +336,7 @@ interface_cas(struct_processus *s_etat_p if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile), &s_objet_argument_1) == d_erreur) { - (*s_etat_processus).erreur_execution = d_ex_manque_argument; + s_etat_processus->erreur_execution = d_ex_manque_argument; return; } @@ -238,7 +344,7 @@ interface_cas(struct_processus *s_etat_p &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); - (*s_etat_processus).erreur_execution = d_ex_manque_argument; + s_etat_processus->erreur_execution = d_ex_manque_argument; return; } @@ -305,6 +411,179 @@ interface_cas(struct_processus *s_etat_p case RPLCAS_LIMITE: { + if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile), + &s_objet_argument_1) == d_erreur) + { + s_etat_processus->erreur_execution = d_ex_manque_argument; + return; + } + + if (depilement(s_etat_processus, &(s_etat_processus->l_base_pile), + &s_objet_argument_2) == d_erreur) + { + liberation(s_etat_processus, s_objet_argument_1); + s_etat_processus->erreur_execution = d_ex_manque_argument; + return; + } + + // Fonction + + if ((argument_2 = conversion_rpl_vers_cas(s_etat_processus, + &s_objet_argument_2)) == NULL) + { + s_etat_processus->erreur_systeme = d_es_allocation_memoire; + return; + } + + // On parcourt la liste. Cette liste est tout d'abord copiée + // car on est susceptible de modifier le second élément. + + if ((s_objet_temporaire = copie_objet(s_etat_processus, + s_objet_argument_1, 'O')) == NULL) + { + s_etat_processus->erreur_systeme = d_es_allocation_memoire; + return; + } + + liberation(s_etat_processus, s_objet_argument_1); + s_objet_argument_1 = s_objet_temporaire; + + l_element_courant = reinterpret_cast + (s_objet_argument_1->objet); + position = 1; + argument_4 = NULL; + + while(l_element_courant != NULL) + { + switch(position) + { + case 1: + { + // Variable + + if ((argument_1 = reinterpret_cast + (malloc((strlen((const char *) + ((struct_variable *) (l_element_courant + ->donnee->objet))->nom) + + 1) * sizeof(unsigned char)))) == NULL) + { + s_etat_processus->erreur_systeme = + d_es_allocation_memoire; + return; + } + + strcpy(reinterpret_cast(argument_1), + (const char *) ((struct_variable *) + (l_element_courant->donnee->objet))->nom); + break; + } + + case 2: + { + // Valeur + if ((argument_3 = conversion_rpl_vers_cas( + s_etat_processus, + &(l_element_courant->donnee))) == NULL) + { + s_etat_processus->erreur_systeme = + d_es_allocation_memoire; + return; + } + + break; + } + + case 3: + { + // Direction + + if ((argument_4 = reinterpret_cast + (malloc((strlen((const char *) + ((struct_fonction *) (l_element_courant + ->donnee->objet))->nom_fonction) + + 1) * sizeof(unsigned char)))) == NULL) + { + s_etat_processus->erreur_systeme = + d_es_allocation_memoire; + return; + } + + strcpy(reinterpret_cast(argument_4), + (const char *) ((struct_fonction *) + (l_element_courant->donnee->objet)) + ->nom_fonction); + break; + } + } + + l_element_courant = (*l_element_courant).suivant; + position++; + } + + liberation(s_etat_processus, s_objet_argument_1); + liberation(s_etat_processus, s_objet_argument_2); + + try + { + giac::context contexte; + + int direction; + + if (argument_4 == NULL) + { + direction = 0; + } + else + { + direction = (strcmp((const char *) argument_4, "+") == 0) + ? 1 : -1; + } + + gen expression( + string(reinterpret_cast(argument_2)), + &contexte); + identificateur variable( + string(reinterpret_cast(argument_1))); + gen valeur(string(reinterpret_cast + (argument_3)), &contexte); + + gen resultat = limit(expression, variable, valeur, direction, + &contexte); + string chaine = "'" + resultat.print() + "'"; + + registre = s_etat_processus->instruction_courante; + s_etat_processus->instruction_courante = + reinterpret_cast(const_cast + (chaine.c_str())); + + recherche_type(s_etat_processus); + + if (s_etat_processus->l_base_pile != NULL) + { + conversion_cas_vers_rpl(s_etat_processus, + s_etat_processus->l_base_pile->donnee); + } + + s_etat_processus->instruction_courante = registre; + } + catch(bad_alloc exception) + { + s_etat_processus->erreur_systeme = d_es_allocation_memoire; + } + catch(...) + { + s_etat_processus->erreur_execution = d_ex_erreur_interne_rplcas; + } + + free(argument_1); + free(argument_2); + free(argument_3); + + if (argument_4 != NULL) + { + free(argument_4); + } + break; } }