--- rpl/src/instructions_f4.c 2012/08/22 10:47:15 1.35 +++ rpl/src/instructions_f4.c 2012/09/29 17:53:02 1.36 @@ -424,4 +424,333 @@ instruction_fleche_diag(struct_processus return; } + +/* +================================================================================ + Fonction 'forall' +================================================================================ + Entrées : structure processus +-------------------------------------------------------------------------------- + Sorties : +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +void +instruction_forall(struct_processus *s_etat_processus) +{ + struct_objet *s_objet_1; + struct_objet *s_objet_2; + + struct_variable s_variable; + + unsigned char instruction_valide; + unsigned char *tampon; + unsigned char test_instruction; + + (*s_etat_processus).erreur_execution = d_ex; + + if ((*s_etat_processus).affichage_arguments == 'Y') + { + printf("\n FORALL "); + + if ((*s_etat_processus).langue == 'F') + { + printf("(boucle définie sur un objet)\n\n"); + } + else + { + printf("(define a object-based loop)\n\n"); + } + + if ((*s_etat_processus).langue == 'F') + { + printf(" Utilisation :\n\n"); + } + else + { + printf(" Usage:\n\n"); + } + + printf(" %s/%s FORALL (variable)\n", d_LST, d_TAB); + printf(" (expression)\n"); + printf(" NEXT\n"); + return; + } + else if ((*s_etat_processus).test_instruction == 'Y') + { + (*s_etat_processus).nombre_arguments = -1; + return; + } + + if ((*s_etat_processus).erreur_systeme != d_es) + { + return; + } + + if (test_cfsf(s_etat_processus, 31) == d_vrai) + { + if (empilement_pile_last(s_etat_processus, 1) == d_erreur) + { + return; + } + } + + if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), + &s_objet_1) == d_erreur) + { + (*s_etat_processus).erreur_execution = d_ex_manque_argument; + return; + } + + if (((*s_objet_1).type != LST) && ((*s_objet_1).type != TBL)) + { + liberation(s_etat_processus, s_objet_1); + + (*s_etat_processus).erreur_execution = d_ex_erreur_traitement_boucle; + return; + } + + tampon = (*s_etat_processus).instruction_courante; + test_instruction = (*s_etat_processus).test_instruction; + instruction_valide = (*s_etat_processus).instruction_valide; + (*s_etat_processus).test_instruction = 'Y'; + + empilement_pile_systeme(s_etat_processus); + + if ((*s_etat_processus).erreur_systeme != d_es) + { + return; + } + + if ((*s_etat_processus).mode_execution_programme == 'Y') + { + if (recherche_instruction_suivante(s_etat_processus) == d_erreur) + { + return; + } + + analyse(s_etat_processus, NULL); + + if ((*s_etat_processus).instruction_valide == 'Y') + { + liberation(s_etat_processus, s_objet_1); + free((*s_etat_processus).instruction_courante); + (*s_etat_processus).instruction_courante = tampon; + + depilement_pile_systeme(s_etat_processus); + + (*s_etat_processus).erreur_execution = d_ex_nom_reserve; + return; + } + + recherche_type(s_etat_processus); + + free((*s_etat_processus).instruction_courante); + (*s_etat_processus).instruction_courante = tampon; + + if ((*s_etat_processus).erreur_execution != d_ex) + { + depilement_pile_systeme(s_etat_processus); + liberation(s_etat_processus, s_objet_1); + return; + } + + if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), + &s_objet_2) == d_erreur) + { + liberation(s_etat_processus, s_objet_1); + + depilement_pile_systeme(s_etat_processus); + (*s_etat_processus).erreur_execution = d_ex_manque_argument; + return; + } + + (*(*s_etat_processus).l_base_pile_systeme) + .origine_routine_evaluation = 'N'; + } + else + { + if ((*s_etat_processus).expression_courante == NULL) + { + depilement_pile_systeme(s_etat_processus); + + (*s_etat_processus).erreur_execution = d_ex_manque_argument; + return; + } + + (*s_etat_processus).expression_courante = (*(*s_etat_processus) + .expression_courante).suivant; + + if ((s_objet_2 = copie_objet(s_etat_processus, + (*(*s_etat_processus).expression_courante) + .donnee, 'P')) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*(*s_etat_processus).l_base_pile_systeme) + .origine_routine_evaluation = 'Y'; + } + + if ((*s_objet_2).type != NOM) + { + liberation(s_etat_processus, s_objet_1); + depilement_pile_systeme(s_etat_processus); + + (*s_etat_processus).erreur_execution = d_ex_erreur_traitement_boucle; + return; + } + else if ((*((struct_nom *) (*s_objet_2).objet)).symbole == d_vrai) + { + liberation(s_etat_processus, s_objet_1); + depilement_pile_systeme(s_etat_processus); + + (*s_etat_processus).erreur_execution = d_ex_erreur_traitement_boucle; + return; + } + + (*s_etat_processus).niveau_courant++; + (*(*s_etat_processus).l_base_pile_systeme).type_cloture = 'A'; + + if ((s_variable.nom = malloc((strlen( + (*((struct_nom *) (*s_objet_2).objet)).nom) + 1) * + sizeof(unsigned char))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + strcpy(s_variable.nom, (*((struct_nom *) (*s_objet_2).objet)).nom); + s_variable.niveau = (*s_etat_processus).niveau_courant; + + if ((*s_objet_1).type == LST) + { + if ((*s_objet_1).objet == NULL) + { + // La liste est vide. On doit sauter au NEXT correspondant. + liberation(s_etat_processus, s_objet_1); + liberation(s_etat_processus, s_objet_2); + free(s_variable.nom); + + if (((*(*s_etat_processus).l_base_pile_systeme) + .limite_indice_boucle = allocation(s_etat_processus, NON)) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*s_etat_processus).test_instruction = test_instruction; + (*s_etat_processus).instruction_valide = instruction_valide; + + instruction_cycle(s_etat_processus); + return; + } + + if ((s_variable.objet = copie_objet(s_etat_processus, + (*((struct_liste_chainee *) (*s_objet_1).objet)).donnee, 'P')) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + // Mémorisation de la position courante dans la liste + + if (((*(*s_etat_processus).l_base_pile_systeme).indice_boucle = + allocation(s_etat_processus, NON)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*(*(*s_etat_processus).l_base_pile_systeme).indice_boucle).objet = + (struct_objet *) (*s_objet_1).objet; + } + else + { + if ((*((struct_tableau *) (*s_objet_1).objet)).nombre_elements == 0) + { + // La table est vide, il convient de sauter au NEXT correspondant. + liberation(s_etat_processus, s_objet_1); + liberation(s_etat_processus, s_objet_2); + free(s_variable.nom); + + if (((*(*s_etat_processus).l_base_pile_systeme) + .limite_indice_boucle = allocation(s_etat_processus, NON)) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*s_etat_processus).test_instruction = test_instruction; + (*s_etat_processus).instruction_valide = instruction_valide; + + instruction_cycle(s_etat_processus); + return; + } + + if ((s_variable.objet = copie_objet(s_etat_processus, + (*((struct_tableau *) (*s_objet_1).objet)).elements[0], 'P')) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + // Création d'un objet de type entier contenant la position + // de l'élément courant dans la table. + + if (((*(*s_etat_processus).l_base_pile_systeme).indice_boucle = + allocation(s_etat_processus, INT)) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + (*((integer8 *) (*(*(*s_etat_processus).l_base_pile_systeme) + .indice_boucle).objet)) = 0; + } + + if (creation_variable(s_etat_processus, &s_variable, 'V', 'P') == d_erreur) + { + return; + } + + liberation(s_etat_processus, s_objet_2); + + (*s_etat_processus).test_instruction = test_instruction; + (*s_etat_processus).instruction_valide = instruction_valide; + + (*(*s_etat_processus).l_base_pile_systeme).limite_indice_boucle = s_objet_1; + + if ((*s_etat_processus).mode_execution_programme == 'Y') + { + (*(*s_etat_processus).l_base_pile_systeme).adresse_retour = + (*s_etat_processus).position_courante; + } + else + { + (*(*s_etat_processus).l_base_pile_systeme).pointeur_objet_retour = + (*s_etat_processus).expression_courante; + } + + if (((*(*s_etat_processus).l_base_pile_systeme).nom_variable = + malloc((strlen(s_variable.nom) + 1) * + sizeof(unsigned char))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + strcpy((*(*s_etat_processus).l_base_pile_systeme).nom_variable, + s_variable.nom); + + return; +} + // vim: ts=4