Annotation of rpl/src/simplification.c, revision 1.71

1.1       bertrand    1: /*
                      2: ================================================================================
1.68      bertrand    3:   RPL/2 (R) version 4.1.32
1.66      bertrand    4:   Copyright (C) 1989-2019 Dr. BERTRAND Joël
1.1       bertrand    5: 
                      6:   This file is part of RPL/2.
                      7: 
                      8:   RPL/2 is free software; you can redistribute it and/or modify it
                      9:   under the terms of the CeCILL V2 License as published by the french
                     10:   CEA, CNRS and INRIA.
                     11:  
                     12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
                     13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
                     14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
                     15:   for more details.
                     16:  
                     17:   You should have received a copy of the CeCILL License
                     18:   along with RPL/2. If not, write to info@cecill.info.
                     19: ================================================================================
                     20: */
                     21: 
                     22: 
1.11      bertrand   23: #include "rpl-conv.h"
1.1       bertrand   24: 
                     25: 
                     26: /*
                     27: ================================================================================
1.69      bertrand   28:   Fonction d'affichage d'un arbre q-aire
                     29: ================================================================================
                     30:   Entrées : pointeur sur une structure struct_processus
                     31: --------------------------------------------------------------------------------
                     32:   Sorties :
                     33: --------------------------------------------------------------------------------
                     34:   Effets de bord : néant
                     35: ================================================================================
                     36: */
                     37: 
                     38: static void
                     39: affichage_arbre(struct_processus *s_etat_processus, struct_arbre *s_arbre,
                     40:        int niveau)
                     41: {
                     42:    int                         i;
                     43: 
                     44:    integer8                    branche;
                     45: 
                     46:    struct_liste_chainee        *l_element_courant;
                     47: 
                     48:    unsigned char               *chaine;
                     49: 
                     50:    if (niveau == 0)
                     51:    {
1.70      bertrand   52:        printf("--- Arbre $%016X\n", s_arbre);
1.69      bertrand   53:    }
                     54: 
                     55:    // Affichage de la feuille (fonction ou donnée générale s'il n'y 
                     56:    // a pas de branche)
                     57: 
                     58:    l_element_courant = (*s_arbre).feuille;
                     59: 
                     60:    while(l_element_courant != NULL)
                     61:    {
                     62:        if ((chaine = formateur(s_etat_processus, 0,
                     63:                (*l_element_courant).donnee)) == NULL)
                     64:        {
                     65:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                     66:            return;
                     67:        }
                     68: 
                     69:        for(i = 0; i < niveau; i++)
                     70:        {
                     71:            printf("  ");
                     72:        }
                     73: 
                     74:        printf("%s\n", chaine);
                     75:        free(chaine);
                     76: 
                     77:        l_element_courant = (*l_element_courant).suivant;
                     78:    }
                     79: 
                     80:    // Affichage des branches (arguments de la fonction dans la feuille)
                     81: 
                     82:    for(branche = 0; branche < (*s_arbre).nombre_branches; branche++)
                     83:    {
                     84:        affichage_arbre(s_etat_processus, (*s_arbre).branches[branche],
                     85:                niveau + 1);
                     86:    }
                     87: 
                     88:    if (niveau == 0)
                     89:    {
1.70      bertrand   90:        printf("--- Fin de l'arbre\n");
1.69      bertrand   91:    }
                     92: 
                     93:    return;
                     94: }
                     95: 
                     96: 
                     97: /*
                     98: ================================================================================
1.50      bertrand   99:   Fonction de transcription d'un arbre en liste chaînée
1.1       bertrand  100: ================================================================================
                    101:   Entrées : pointeur sur une structure struct_processus
                    102: --------------------------------------------------------------------------------
                    103:   Sorties :
                    104: --------------------------------------------------------------------------------
                    105:   Effets de bord : néant
                    106: ================================================================================
                    107: */
                    108: 
1.50      bertrand  109: static struct_liste_chainee *
                    110: transcription_arbre(struct_processus *s_etat_processus, struct_arbre *s_arbre)
1.1       bertrand  111: {
1.50      bertrand  112:    integer8                i;
1.1       bertrand  113: 
                    114:    struct_liste_chainee    *l_element_courant;
1.50      bertrand  115:    struct_liste_chainee    *l_liste;
                    116:    struct_liste_chainee    *l_nouvelle_pile_locale;
                    117:    struct_liste_chainee    *l_pile_locale;
1.1       bertrand  118: 
1.50      bertrand  119:    l_pile_locale = NULL;
1.1       bertrand  120: 
1.50      bertrand  121:    for(i = 0; i < (*s_arbre).nombre_branches; i++)
1.1       bertrand  122:    {
1.50      bertrand  123:        if ((l_nouvelle_pile_locale = allocation_maillon(s_etat_processus))
                    124:                == NULL)
                    125:        {
                    126:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    127:            return(NULL);
                    128:        }
1.1       bertrand  129: 
1.50      bertrand  130:        (*l_nouvelle_pile_locale).suivant = l_pile_locale;
                    131:        l_pile_locale = l_nouvelle_pile_locale;
1.1       bertrand  132: 
1.50      bertrand  133:        if (((*l_pile_locale).donnee = (void *) transcription_arbre(
                    134:                s_etat_processus, (*s_arbre).branches[i])) == NULL)
1.1       bertrand  135:        {
1.50      bertrand  136:            return(NULL);
1.1       bertrand  137:        }
1.50      bertrand  138:    }
                    139: 
1.52      bertrand  140:    // Ajout des fonctions
1.70      bertrand  141:    // Arbre q-aire => si q branches, q-1 fonctions
1.1       bertrand  142: 
1.52      bertrand  143:    l_liste = (*s_arbre).feuille;
1.50      bertrand  144: 
1.70      bertrand  145:    for(i = 0; i < (*s_arbre).nombre_branches - 2; i++)
                    146:    {
                    147:        if ((l_element_courant = allocation_maillon(s_etat_processus))
                    148:                == NULL)
                    149:        {
                    150:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    151:            return(NULL);
                    152:        }
                    153: 
                    154:        (*l_element_courant).suivant = l_liste;
                    155: 
                    156:        if (((*l_element_courant).donnee = copie_objet(s_etat_processus,
                    157:                (*l_liste).donnee, 'P')) == NULL)
                    158:        {
                    159:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    160:            return(NULL);
                    161:        }
                    162: 
                    163:        l_liste = l_element_courant;
                    164:    }
                    165: 
1.50      bertrand  166:    free((*s_arbre).branches);
                    167:    free(s_arbre);
                    168: 
                    169:    // Chaînage des arguments
                    170: 
                    171:    while(l_pile_locale != NULL)
                    172:    {
                    173:        l_element_courant = (void *) (*l_pile_locale).donnee;
                    174: 
                    175:        if (l_element_courant == NULL)
1.1       bertrand  176:        {
1.50      bertrand  177:            (*s_etat_processus).erreur_systeme = d_es_pile_vide;
1.1       bertrand  178:            return(NULL);
                    179:        }
                    180: 
1.50      bertrand  181:        while((*l_element_courant).suivant != NULL)
1.1       bertrand  182:        {
                    183:            l_element_courant = (*l_element_courant).suivant;
                    184:        }
                    185: 
1.50      bertrand  186:        (*l_element_courant).suivant = l_liste;
                    187:        l_liste = (void *) (*l_pile_locale).donnee;
1.1       bertrand  188: 
1.50      bertrand  189:        l_nouvelle_pile_locale = (*l_pile_locale).suivant;
                    190:        liberation_maillon(s_etat_processus, l_pile_locale);
                    191:        l_pile_locale = l_nouvelle_pile_locale;
1.1       bertrand  192:    }
                    193: 
1.50      bertrand  194:    return(l_liste);
1.1       bertrand  195: }
                    196: 
                    197: 
                    198: /*
                    199: ================================================================================
1.51      bertrand  200:   Fonction de simplification d'un arbre
                    201: ================================================================================
                    202:   Entrées : pointeur sur une structure struct_processus
                    203: --------------------------------------------------------------------------------
                    204:   Sorties :
                    205: --------------------------------------------------------------------------------
                    206:   Effets de bord : néant
                    207: ================================================================================
                    208: */
                    209: 
1.70      bertrand  210: static int
                    211: ordonnancement_branches(const void *a1, const void *a2)
1.51      bertrand  212: {
1.70      bertrand  213:    struct_arbre    **_a1;
                    214:    struct_arbre    **_a2;
                    215: 
                    216:    _a1 = (struct_arbre **) a1;
                    217:    _a2 = (struct_arbre **) a2;
                    218: 
                    219:    if (((**_a1).feuille != NULL) && ((**_a2).feuille != NULL))
                    220:    {
1.71    ! bertrand  221:        // Si les types sont identiques, on ne change rien.
        !           222: 
1.70      bertrand  223:        if ((*(*(**_a1).feuille).donnee).type ==
                    224:                (*(*(**_a2).feuille).donnee).type)
                    225:        {
                    226:            return(0);
                    227:        }
                    228: 
1.71    ! bertrand  229:        // On rejette les nombres à la fin.
        !           230: 
        !           231:        if ((((*(*(**_a1).feuille).donnee).type == INT) ||
1.70      bertrand  232:                ((*(*(**_a1).feuille).donnee).type == REL) ||
1.71    ! bertrand  233:                ((*(*(**_a1).feuille).donnee).type == CPL)) &&
        !           234:                ((((*(*(**_a2).feuille).donnee).type != INT) &&
        !           235:                ((*(*(**_a2).feuille).donnee).type != REL) &&
        !           236:                ((*(*(**_a2).feuille).donnee).type != CPL))))
1.70      bertrand  237:        {
                    238:            return(1);
                    239:        }
                    240:        else
                    241:        {
                    242:            return(-1);
                    243:        }
                    244:    }
                    245: 
                    246:    return(0);
1.51      bertrand  247: }
                    248: 
                    249: 
                    250: static void
                    251: simplification_arbre(struct_processus *s_etat_processus,
1.52      bertrand  252:        struct_arbre *s_arbre)
1.51      bertrand  253: {
1.52      bertrand  254:    integer8                i;
1.70      bertrand  255:    integer8                j;
                    256:    integer8                nouveaux_elements;
                    257: 
1.71    ! bertrand  258:    struct_arbre            *s_branche;
        !           259: 
1.70      bertrand  260:    struct_objet            *s_objet;
1.52      bertrand  261: 
                    262:    if ((*(*(*s_arbre).feuille).donnee).type != FCT)
                    263:    {
                    264:        // L'objet formant le noeud n'est pas une fonction. Il n'y a aucune
                    265:        // simplification possible.
                    266: 
                    267:        return;
                    268:    }
                    269: 
1.71    ! bertrand  270:    // Transformation des soustractions que l'on remplace par
        !           271:    // une addition de l'opposé. Si l'on a une soustraction,
        !           272:    // on greffe donc une instruction NEG dans l'arbre.
        !           273:    // Note : à cet instant, l'instruction '-' ne peut avoir que deux
        !           274:    // opérandes.
        !           275: 
        !           276:    if (strcmp((*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
        !           277:            .nom_fonction, "-") == 0)
        !           278:    {
        !           279:        if ((*s_arbre).nombre_branches != 2)
        !           280:        {
        !           281:            (*s_etat_processus).erreur_execution = d_ex_simplification;
        !           282:            return;
        !           283:        }
        !           284: 
        !           285:        liberation(s_etat_processus, (*((*s_arbre).feuille)).donnee);
        !           286: 
        !           287:        if (((*((*s_arbre).feuille)).donnee = allocation(s_etat_processus,
        !           288:                FCT)) == NULL)
        !           289:        {
        !           290:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           291:            return;
        !           292:        }
        !           293: 
        !           294:        if (((*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
        !           295:                .nom_fonction = malloc(2 * sizeof(unsigned char))) == NULL)
        !           296:        {
        !           297:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           298:            return;
        !           299:        }
        !           300: 
        !           301:        strcpy((*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
        !           302:                .nom_fonction, "+");
        !           303:        (*((struct_fonction *) (*(*((*s_arbre).feuille)).donnee).objet))
        !           304:                .nombre_arguments = 1;
        !           305: 
        !           306:        if ((s_branche = malloc(sizeof(struct_arbre))) == NULL)
        !           307:        {
        !           308:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           309:            return;
        !           310:        }
        !           311: 
        !           312:        if (((*s_branche).branches = malloc(sizeof(struct_arbre *))) == NULL)
        !           313:        {
        !           314:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           315:            return;
        !           316:        }
        !           317: 
        !           318:        if (((*s_branche).feuille = allocation_maillon(s_etat_processus))
        !           319:                == NULL)
        !           320:        {
        !           321:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           322:            return;
        !           323:        }
        !           324: 
        !           325:        (*(*s_branche).feuille).suivant = NULL;
        !           326: 
        !           327:        if (((*(*s_branche).feuille).donnee = allocation(s_etat_processus, FCT))
        !           328:                == NULL)
        !           329:        {
        !           330:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           331:            return;
        !           332:        }
        !           333: 
        !           334:        if (((*((struct_fonction *) (*(*(*s_branche).feuille).donnee).objet))
        !           335:                .nom_fonction = malloc(4 * sizeof(unsigned char))) == NULL)
        !           336:        {
        !           337:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
        !           338:            return;
        !           339:        }
        !           340: 
        !           341:        strcpy((*((struct_fonction *) (*(*(*s_branche).feuille).donnee).objet))
        !           342:                .nom_fonction, "NEG");
        !           343:        (*((struct_fonction *) (*(*(*s_branche).feuille).donnee).objet))
        !           344:                .nombre_arguments = 1;
        !           345:        (*s_branche).branches[0] = (*s_arbre).branches[1];
        !           346:        (*s_branche).nombre_branches = 1;
        !           347:        (*s_arbre).branches[1] = s_branche;
        !           348:    }
        !           349: 
1.70      bertrand  350:    // La feuille est une fonction, on peut envisager la simplification
                    351:    // de l'arbre. Pour cela, on descend d'un niveau pour greffer
                    352:    // de nouvelles branches.
                    353: 
                    354:    if (strcmp((*((struct_fonction *) (*(*(*s_arbre).feuille).donnee).objet))
                    355:            .nom_fonction, "+") == 0)
1.52      bertrand  356:    {
                    357:        for(i = 0; i < (*s_arbre).nombre_branches; i++)
                    358:        {
1.70      bertrand  359:            s_objet = (*((*((*s_arbre).branches[i])).feuille)).donnee;
                    360: 
                    361:            if ((*s_objet).type == FCT)
                    362:            {
                    363:                if (strcmp((*((struct_fonction *) (*s_objet).objet))
                    364:                        .nom_fonction, "-") == 0)
                    365:                {
1.71    ! bertrand  366:                    simplification_arbre(s_etat_processus,
        !           367:                            (*s_arbre).branches[i]);
        !           368:                    s_objet = (*((*((*s_arbre).branches[i])).feuille)).donnee;
1.70      bertrand  369:                }
                    370: 
                    371:                if (strcmp((*((struct_fonction *) (*s_objet).objet))
                    372:                        .nom_fonction, "+") == 0)
                    373:                {
                    374:                    simplification_arbre(s_etat_processus,
                    375:                            (*s_arbre).branches[i]);
                    376: 
                    377:                    /*
                    378:                     On greffe.
                    379: +
                    380:   +
                    381:     2
                    382:     SIN
                    383:       3
                    384:   10
                    385: 
                    386:                     doit donner :
                    387: +
                    388:   2
                    389:   SIN
                    390:     3
                    391:   10
                    392:                    */
                    393: 
                    394:                    nouveaux_elements = (*(*s_arbre).branches[i])
                    395:                            .nombre_branches;
                    396: 
                    397:                    if (((*s_arbre).branches = realloc((*s_arbre).branches,
                    398:                            ((unsigned) ((*s_arbre).nombre_branches
                    399:                            + nouveaux_elements))
                    400:                            * sizeof(struct_arbre *))) == NULL)
                    401:                    {
                    402:                        (*s_etat_processus).erreur_systeme =
                    403:                                d_es_allocation_memoire;
                    404:                        return;
                    405:                    }
                    406: 
                    407:                    for(j = 0; j < nouveaux_elements; j++)
                    408:                    {
                    409:                        (*s_arbre).branches[(*s_arbre).nombre_branches++] =
                    410:                                (*(*s_arbre).branches[i]).branches[j];
                    411:                    }
                    412: 
                    413:                    free((*s_arbre).branches[i]);
                    414: 
                    415:                    // Retrait de la branche
                    416:                
                    417:                    for(j = i + 1; j < (*s_arbre).nombre_branches; j++)
                    418:                    {
                    419:                        (*s_arbre).branches[j - 1] = (*s_arbre).branches[j];
                    420:                    }
                    421: 
                    422:                    (*s_arbre).nombre_branches--;
                    423: 
                    424:                    // Réorganisation des valeurs numériques en queue.
                    425: 
                    426:                    qsort((*s_arbre).branches, (size_t) (*s_arbre)
                    427:                            .nombre_branches, sizeof(struct_arbre *),
                    428:                            ordonnancement_branches);
                    429:                }
                    430:            }
1.52      bertrand  431:        }
1.70      bertrand  432: 
                    433:        if (((*s_arbre).branches = realloc((*s_arbre).branches,
                    434:                ((unsigned) (*s_arbre).nombre_branches)
                    435:                * sizeof(struct_arbre *))) == NULL)
1.52      bertrand  436:        {
1.70      bertrand  437:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    438:            return;
1.52      bertrand  439:        }
                    440:    }
                    441: 
1.51      bertrand  442:    return;
                    443: }
                    444: 
                    445: 
                    446: /*
                    447: ================================================================================
1.50      bertrand  448:   Fonction 'simplification' (ne libère pas les paramètres)
1.1       bertrand  449: ================================================================================
1.50      bertrand  450:   Entrées : pointeur sur une structure struct_processus
1.1       bertrand  451: --------------------------------------------------------------------------------
                    452:   Sorties :
                    453: --------------------------------------------------------------------------------
                    454:   Effets de bord : néant
                    455: ================================================================================
                    456: */
                    457: 
1.50      bertrand  458: struct_objet *
                    459: simplification(struct_processus *s_etat_processus, struct_objet *s_objet)
1.1       bertrand  460: {
1.50      bertrand  461:    struct_objet                *s_objet_simplifie;
                    462: 
                    463:    integer8                    i;
                    464:    integer8                    nombre_arguments;
                    465: 
                    466:    struct_arbre                *s_arbre;
                    467: 
                    468:    struct_liste_chainee        *l_element_courant;
                    469: 
                    470:    // Attention : l_liste_locale et l_ancienne_liste_locale ne contiennent pas
                    471:    // un pointeur sur une struct_objet, mais sur une struct_arbre.
1.1       bertrand  472: 
1.50      bertrand  473:    struct_liste_chainee        *l_liste_locale;
                    474:    struct_liste_chainee        *l_ancienne_liste_locale;
1.1       bertrand  475: 
1.50      bertrand  476:    if ((*s_objet).type == ALG)
1.1       bertrand  477:    {
1.50      bertrand  478:        /*
                    479:         * Transcription de l'expression algébrique en arbre q-aire
                    480:         */
1.1       bertrand  481: 
1.50      bertrand  482:        l_liste_locale = NULL;
                    483:        l_element_courant = (*s_objet).objet;
1.1       bertrand  484: 
1.50      bertrand  485:        while(l_element_courant != NULL)
1.1       bertrand  486:        {
1.50      bertrand  487:            switch((*(*l_element_courant).donnee).type)
                    488:            {
                    489:                // Toutes les fonctions (intrinsèques, extrinsèques et
                    490:                // utilisateurs).
                    491: 
                    492:                case FCT:
                    493:                {
                    494:                    // Il s'agit d'un objet de type ALG. Nous pouvons donc
                    495:                    // sauter les délimiteurs d'expression.
                    496: 
                    497:                    if ((l_element_courant != (*s_objet).objet) &&
                    498:                            ((*l_element_courant).suivant != NULL))
                    499:                    {
                    500:                        nombre_arguments = (*((struct_fonction *)
                    501:                                (*(*l_element_courant).donnee).objet))
                    502:                                .nombre_arguments;
                    503: 
                    504:                        // Si le nombre d'arguments vaut 0, la fonction
                    505:                        // apparaît en notation algébrique comme une fonction
                    506:                        // infixe.
                    507: 
                    508:                        if (nombre_arguments == 0)
                    509:                        {
                    510:                            nombre_arguments = 2;
                    511:                        }
                    512: 
                    513:                        if ((s_arbre = malloc(sizeof(struct_arbre))) == NULL)
                    514:                        {
                    515:                            (*s_etat_processus).erreur_systeme =
                    516:                                    d_es_allocation_memoire;
                    517:                            return(NULL);
                    518:                        }
                    519: 
                    520:                        (*s_arbre).nombre_branches = nombre_arguments;
1.52      bertrand  521: 
                    522:                        if (((*s_arbre).feuille = allocation_maillon(
                    523:                                s_etat_processus)) == NULL)
                    524:                        {
                    525:                            (*s_etat_processus).erreur_systeme =
                    526:                                    d_es_allocation_memoire;
                    527:                            return(NULL);
                    528:                        }
                    529: 
                    530:                        (*(*s_arbre).feuille).donnee = copie_objet(
                    531:                                s_etat_processus, (*l_element_courant).donnee,
                    532:                                'P');
                    533:                        (*(*s_arbre).feuille).suivant = NULL;
1.50      bertrand  534: 
                    535:                        if (((*s_arbre).branches = malloc(((size_t) (*s_arbre)
                    536:                                .nombre_branches) * sizeof(struct_arbre *)))
                    537:                                == NULL)
                    538:                        {
                    539:                            (*s_etat_processus).erreur_systeme =
                    540:                                    d_es_allocation_memoire;
                    541:                            return(NULL);
                    542:                        }
                    543: 
1.51      bertrand  544:                        for(i = nombre_arguments - 1; i >= 0; i--)
1.50      bertrand  545:                        {
                    546:                            if (l_liste_locale == NULL)
                    547:                            {
                    548:                                (*s_etat_processus).erreur_execution =
                    549:                                        d_ex_manque_argument;
                    550:                                return(NULL);
                    551:                            }
                    552: 
1.51      bertrand  553:                            (*s_arbre).branches[i] = (struct_arbre *)
1.50      bertrand  554:                                    (*l_liste_locale).donnee;
                    555: 
                    556:                            l_ancienne_liste_locale = l_liste_locale;
                    557:                            l_liste_locale = (*l_liste_locale).suivant;
                    558: 
                    559:                            liberation_maillon(s_etat_processus,
                    560:                                    l_ancienne_liste_locale);
                    561:                        }
                    562: 
                    563:                        // Introduction de l'arbre dans la pile locale
                    564: 
                    565:                        l_ancienne_liste_locale = l_liste_locale;
                    566: 
                    567:                        if ((l_liste_locale = allocation_maillon(
                    568:                                s_etat_processus)) == NULL)
                    569:                        {
                    570:                            (*s_etat_processus).erreur_systeme =
                    571:                                    d_es_allocation_memoire;
                    572:                            return(NULL);
                    573:                        }
                    574: 
                    575:                        (*l_liste_locale).suivant = l_ancienne_liste_locale;
                    576:                        (*l_liste_locale).donnee = (void *) s_arbre;
                    577:                    }
1.1       bertrand  578: 
1.50      bertrand  579:                    break;
                    580:                }
1.1       bertrand  581: 
1.50      bertrand  582:                default:
1.1       bertrand  583:                {
1.50      bertrand  584:                    l_ancienne_liste_locale = l_liste_locale;
                    585: 
                    586:                    if ((l_liste_locale = allocation_maillon(s_etat_processus))
                    587:                            == NULL)
                    588:                    {
                    589:                        (*s_etat_processus).erreur_systeme =
                    590:                                d_es_allocation_memoire;
                    591:                        return(NULL);
                    592:                    }
                    593: 
                    594:                    (*l_liste_locale).suivant = l_ancienne_liste_locale;
                    595: 
                    596:                    if ((s_arbre = malloc(sizeof(struct_arbre))) == NULL)
                    597:                    {
                    598:                        (*s_etat_processus).erreur_systeme =
                    599:                                d_es_allocation_memoire;
                    600:                        return(NULL);
                    601:                    }
                    602: 
1.52      bertrand  603:                    if (((*s_arbre).feuille = allocation_maillon(
                    604:                            s_etat_processus)) == NULL)
                    605:                    {
                    606:                        (*s_etat_processus).erreur_systeme =
                    607:                                d_es_allocation_memoire;
                    608:                        return(NULL);
                    609:                    }
                    610: 
                    611:                    (*(*s_arbre).feuille).donnee = copie_objet(
                    612:                            s_etat_processus, (*l_element_courant).donnee, 'P');
                    613:                    (*(*s_arbre).feuille).suivant = NULL;
1.50      bertrand  614:                    (*s_arbre).nombre_branches = 0;
                    615:                    (*s_arbre).branches = NULL;
                    616: 
                    617:                    (*l_liste_locale).donnee = (void *) s_arbre;
                    618:                    break;
1.1       bertrand  619:                }
                    620:            }
1.50      bertrand  621: 
                    622:            l_element_courant = (*l_element_courant).suivant;
1.1       bertrand  623:        }
                    624: 
1.50      bertrand  625:        // Toute l'expression a été balayée. On ne doit plus avoir qu'un
                    626:        // seul niveau dans la pile locale, ce niveau contenant l'arbre
                    627:        // à réduire.
                    628: 
                    629:        if (l_liste_locale == NULL)
                    630:        {
                    631:            (*s_etat_processus).erreur_execution = d_ex_erreur_evaluation;
                    632:            return(NULL);
                    633:        }
                    634:        else if ((*l_liste_locale).suivant != NULL)
                    635:        {
                    636:            (*s_etat_processus).erreur_execution = d_ex_erreur_evaluation;
                    637:            return(NULL);
                    638:        }
                    639: 
                    640:        s_arbre = (void *) (*l_liste_locale).donnee;
                    641: 
                    642:        liberation_maillon(s_etat_processus, l_liste_locale);
                    643:        l_liste_locale = NULL;
                    644: 
                    645:        /*
                    646:         * Simplification de l'arbre
                    647:         */
                    648: 
1.69      bertrand  649:        affichage_arbre(s_etat_processus, s_arbre, 0);
1.52      bertrand  650:        simplification_arbre(s_etat_processus, s_arbre);
1.70      bertrand  651:        affichage_arbre(s_etat_processus, s_arbre, 0);
1.51      bertrand  652: 
                    653:        if ((*s_etat_processus).erreur_systeme != d_es)
                    654:        {
                    655:            return(NULL);
                    656:        }
1.50      bertrand  657: 
                    658:        /*
                    659:         * Transcription de l'arbre q-aire simplifié en expression algébrique.
                    660:         * Seule une fonction récursive permet de faire cette conversion
                    661:         * simplement.
                    662:         */
                    663: 
                    664:        l_liste_locale = transcription_arbre(s_etat_processus, s_arbre);
1.1       bertrand  665: 
1.50      bertrand  666:        if ((s_objet_simplifie = allocation(s_etat_processus, ALG))
                    667:                == NULL)
                    668:        {
                    669:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    670:            return(NULL);
                    671:        }
1.1       bertrand  672: 
1.50      bertrand  673:        // Ajout des délimiteurs '<<' et '>>' à la liste d'instructions
1.1       bertrand  674: 
1.50      bertrand  675:        if (((*s_objet_simplifie).objet = allocation_maillon(s_etat_processus))
                    676:                == NULL)
1.1       bertrand  677:        {
1.50      bertrand  678:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    679:            return(NULL);
                    680:        }
1.1       bertrand  681: 
1.50      bertrand  682:        l_element_courant = (*s_objet_simplifie).objet;
1.1       bertrand  683: 
1.50      bertrand  684:        if (((*l_element_courant).donnee = allocation(s_etat_processus,
                    685:                FCT)) == NULL)
                    686:        {
                    687:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    688:            return(NULL);
1.1       bertrand  689:        }
                    690: 
1.50      bertrand  691:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    692:                .nombre_arguments = 0;
                    693:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    694:                .fonction = instruction_vers_niveau_superieur;
1.1       bertrand  695: 
1.50      bertrand  696:        if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    697:                .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL)
                    698:        {
                    699:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    700:            return(NULL);
                    701:        }
1.1       bertrand  702: 
1.50      bertrand  703:        strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    704:                .nom_fonction, "<<");
1.1       bertrand  705: 
1.50      bertrand  706:        (*l_element_courant).suivant = l_liste_locale;
1.1       bertrand  707: 
1.50      bertrand  708:        while((*l_element_courant).suivant != NULL)
1.1       bertrand  709:        {
1.50      bertrand  710:            l_element_courant = (*l_element_courant).suivant;
1.1       bertrand  711:        }
                    712: 
1.50      bertrand  713:        if (((*l_element_courant).suivant =
                    714:                allocation_maillon(s_etat_processus)) == NULL)
                    715:        {
                    716:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    717:            return(NULL);
                    718:        }
1.1       bertrand  719: 
1.50      bertrand  720:        l_element_courant = (*l_element_courant).suivant;
                    721:        (*l_element_courant).suivant = NULL;
1.1       bertrand  722: 
1.50      bertrand  723:        if (((*l_element_courant).donnee = allocation(s_etat_processus,
                    724:                FCT)) == NULL)
                    725:        {
                    726:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    727:            return(NULL);
                    728:        }
1.1       bertrand  729: 
1.50      bertrand  730:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    731:                .nombre_arguments = 0;
                    732:        (*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    733:                .fonction = instruction_vers_niveau_inferieur;
1.1       bertrand  734: 
1.50      bertrand  735:        if (((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    736:                .nom_fonction = malloc(3 * sizeof(unsigned char))) == NULL)
1.1       bertrand  737:        {
1.50      bertrand  738:            (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
                    739:            return(NULL);
1.1       bertrand  740:        }
1.50      bertrand  741: 
                    742:        strcpy((*((struct_fonction *) (*(*l_element_courant).donnee).objet))
                    743:                .nom_fonction, ">>");
                    744:    }
                    745:    else
                    746:    {
                    747:        s_objet_simplifie = copie_objet(s_etat_processus, s_objet, 'P');
1.1       bertrand  748:    }
                    749: 
1.50      bertrand  750:    return(s_objet_simplifie);
1.1       bertrand  751: }
                    752: 
                    753: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>