File:
[local] /
rpl /
src /
sequenceur.c
Revision
1.59:
download - view:
text,
annotated -
select for diffs -
revision graph
Thu Oct 4 15:21:26 2012 UTC (12 years, 7 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Première série de patches pour intégrer la gestion des variables statiques
à l'arbre des variables. Attention, cela compile, mais il reste des choses Ã
faire. Prière de ne pas utilser en l'état de variables statiques.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.11
4: Copyright (C) 1989-2012 Dr. BERTRAND Joël
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:
23: #include "rpl-conv.h"
24:
25:
26: /*
27: ================================================================================
28: Boucle principale de l'interprète RPL/2
29: ================================================================================
30: Entrées : structure sur l'état du processus
31: --------------------------------------------------------------------------------
32: Sorties : Néant
33: --------------------------------------------------------------------------------
34: Effets de bord : néant
35: ================================================================================
36: */
37:
38: logical1
39: sequenceur(struct_processus *s_etat_processus)
40: {
41: struct_liste_chainee *l_element_courant;
42:
43: struct_objet *s_objet;
44: struct_objet *s_objet_evaluation;
45: struct_objet *s_sous_objet;
46:
47: logical1 drapeau_appel_definition;
48: logical1 drapeau_fin;
49: logical1 drapeau_then;
50: logical1 erreur;
51: logical1 presence_compteur;
52:
53: static logical1 completion_valide = d_faux;
54:
55: struct sigaction action;
56: struct sigaction action_defaut;
57: struct sigaction action_defaut2;
58:
59: unsigned char *instruction_majuscule;
60: unsigned char *ligne;
61: unsigned char *message;
62: unsigned char *registre;
63: unsigned char *tampon;
64: unsigned char tampon_retour;
65: unsigned char *t_ligne;
66:
67: unsigned long niveau;
68: unsigned long position_courante;
69:
70: Keymap ancien_keymap;
71: Keymap nouveau_keymap;
72:
73: (*s_etat_processus).retour_routine_evaluation = 'N';
74:
75: if ((*s_etat_processus).debug == d_vrai)
76: if (((*s_etat_processus).type_debug &
77: d_debug_appels_fonctions) != 0)
78: {
79: if ((*s_etat_processus).niveau_recursivite != 0)
80: {
81: if ((*s_etat_processus).langue == 'F')
82: {
83: printf("[%d] Exécution récursive de niveau %lu\n",
84: (int) getpid(), (*s_etat_processus).niveau_recursivite);
85: }
86: else
87: {
88: printf("[%d] %lu level recursive execution\n",
89: (int) getpid(), (*s_etat_processus).niveau_recursivite);
90: }
91: }
92: else
93: {
94: if ((*s_etat_processus).langue == 'F')
95: {
96: printf("[%d] Exécution\n", (int) getpid());
97: }
98: else
99: {
100: printf("[%d] Execution\n", (int) getpid());
101: }
102: }
103:
104: fflush(stdout);
105: }
106:
107: /*
108: --------------------------------------------------------------------------------
109: Boucle de l'interprète RPL/2
110: On boucle tant qu'on n'a pas une bonne raison de sortir...
111: --------------------------------------------------------------------------------
112: */
113:
114: do
115: {
116: drapeau_appel_definition = d_faux;
117:
118: /*
119: --------------------------------------------------------------------------------
120: Recherche de l'instruction suivante dans les définitions chaînées
121: --------------------------------------------------------------------------------
122: */
123:
124: if ((erreur = recherche_instruction_suivante(s_etat_processus))
125: == d_erreur)
126: {
127: return(d_erreur);
128: }
129:
130: if (((*s_etat_processus).debug_programme == d_vrai) &&
131: ((*s_etat_processus).niveau_recursivite == 0))
132: {
133: /*
134: * Traitement de la commande HALT (debug)
135: */
136:
137: action.sa_handler = SIG_IGN;
138: action.sa_flags = SA_NODEFER | SA_ONSTACK;
139:
140: (*s_etat_processus).execution_pas_suivant = d_faux;
141: (*s_etat_processus).traitement_instruction_halt = d_vrai;
142:
143: if (completion_valide == d_faux)
144: {
145: initialisation_completion();
146: completion_valide = d_vrai;
147: }
148:
149: while((*s_etat_processus).execution_pas_suivant == d_faux)
150: {
151: if ((*s_etat_processus).hauteur_pile_operationnelle != 0)
152: {
153: fprintf(stdout, "\n");
154: }
155:
156: affichage_pile(s_etat_processus, (*s_etat_processus)
157: .l_base_pile, 1);
158:
159: if ((*s_etat_processus).mode_interactif == 'N')
160: {
161: printf("[%d] Instruction : %s\n", (int) getpid(),
162: (*s_etat_processus).instruction_courante);
163: fflush(stdout);
164: }
165:
166: if (sigaction(SIGINT, &action, &action_defaut) != 0)
167: {
168: (*s_etat_processus).erreur_systeme = d_es_signal;
169: return(d_erreur);
170: }
171:
172: if (sigaction(SIGTSTP, &action, &action_defaut2) != 0)
173: {
174: (*s_etat_processus).erreur_systeme = d_es_signal;
175: return(d_erreur);
176: }
177:
178: (*s_etat_processus).var_volatile_requete_arret = 0;
179: (*s_etat_processus).var_volatile_requete_arret2 = 0;
180:
181: flockfile(stdin);
182: flockfile(stdout);
183:
184: ancien_keymap = rl_get_keymap();
185: nouveau_keymap = rl_copy_keymap(ancien_keymap);
186: rl_set_keymap(nouveau_keymap);
187:
188: rl_bind_key(NEWLINE, readline_analyse_syntaxique);
189: rl_bind_key(RETURN, readline_analyse_syntaxique);
190: rl_bind_key(CTRL('g'), readline_effacement);
191: rl_done = 0;
192:
193: ligne = readline("RPL/2> ");
194:
195: rl_set_keymap(ancien_keymap);
196: rl_free(nouveau_keymap);
197:
198: funlockfile(stdin);
199: funlockfile(stdout);
200:
201: if ((*s_etat_processus).var_volatile_requete_arret != 0)
202: {
203: (*s_etat_processus).requete_arret = 'Y';
204: break;
205: }
206:
207: if (ligne != NULL)
208: {
209: if ((t_ligne = transliteration(s_etat_processus, ligne,
210: (*s_etat_processus).localisation, d_locale))
211: == NULL)
212: {
213: free((*s_etat_processus).instruction_courante);
214: return(d_erreur);
215: }
216:
217: free(ligne);
218: ligne = t_ligne;
219:
220: if ((ligne = compactage(ligne)) == NULL)
221: {
222: (*s_etat_processus).erreur_systeme =
223: d_es_allocation_memoire;
224: return(d_erreur);
225: }
226: }
227:
228: if (sigaction(SIGINT, &action_defaut, NULL) != 0)
229: {
230: (*s_etat_processus).erreur_systeme = d_es_signal;
231: return(d_erreur);
232: }
233:
234: if (sigaction(SIGTSTP, &action_defaut2, NULL) != 0)
235: {
236: (*s_etat_processus).erreur_systeme = d_es_signal;
237: return(d_erreur);
238: }
239:
240: if (ligne == NULL)
241: {
242: if ((ligne = (unsigned char *) malloc(6 *
243: sizeof(unsigned char))) == NULL)
244: {
245: (*s_etat_processus).erreur_systeme =
246: d_es_allocation_memoire;
247: return(d_erreur);
248: }
249:
250: sprintf(ligne, "abort");
251: fprintf(stdout, "%s\n", ligne);
252: }
253: else if (((*ligne) == d_code_fin_chaine) &&
254: ((*s_etat_processus).l_base_pile != NULL))
255: {
256: free(ligne);
257:
258: if ((ligne = (unsigned char *) malloc(4 *
259: sizeof(unsigned char))) == NULL)
260: {
261: (*s_etat_processus).erreur_systeme =
262: d_es_allocation_memoire;
263: return(d_erreur);
264: }
265:
266: sprintf(ligne, "dup");
267: }
268:
269: add_history(ligne);
270: stifle_history(ds_longueur_historique);
271:
272: position_courante = (*s_etat_processus).position_courante;
273: tampon = (*s_etat_processus).definitions_chainees;
274: registre = (*s_etat_processus).instruction_courante;
275: (*s_etat_processus).definitions_chainees = ligne;
276:
277: if (analyse_syntaxique(s_etat_processus) == d_absence_erreur)
278: {
279: (*s_etat_processus).instruction_courante = registre;
280: (*s_etat_processus).position_courante = position_courante;
281: (*s_etat_processus).definitions_chainees = tampon;
282:
283: if ((tampon = (unsigned char *) malloc((strlen(ligne) + 7) *
284: sizeof(unsigned char))) == NULL)
285: {
286: (*s_etat_processus).erreur_systeme =
287: d_es_allocation_memoire;
288: return(d_erreur);
289: }
290:
291: sprintf(tampon, "<< %s >>", ligne);
292:
293: free(ligne);
294: ligne = tampon;
295:
296: tampon = (*s_etat_processus).instruction_courante;
297: (*s_etat_processus).instruction_courante = ligne;
298:
299: recherche_type(s_etat_processus);
300:
301: (*s_etat_processus).instruction_courante = tampon;
302:
303: if ((((*s_etat_processus).erreur_execution != d_ex) ||
304: ((*s_etat_processus).erreur_systeme != d_es)) &&
305: ((*s_etat_processus).invalidation_message_erreur
306: == d_faux))
307: {
308: if ((*s_etat_processus).erreur_execution != d_ex)
309: {
310: (*s_etat_processus).erreur_scrutation = d_vrai;
311: }
312:
313: if (test_cfsf(s_etat_processus, 51) == d_faux)
314: {
315: printf("%s", ds_beep);
316: }
317:
318: if ((message = messages(s_etat_processus)) == NULL)
319: {
320: free((*s_etat_processus).instruction_courante);
321: return(d_erreur);
322: }
323:
324: printf("%s [%d]\n", message, (int) getpid());
325:
326: free(message);
327:
328: (*s_etat_processus).erreur_execution = d_ex;
329:
330: if ((*s_etat_processus).erreur_systeme != d_es)
331: {
332: return(d_erreur);
333: }
334: }
335: else
336: {
337: tampon_retour = (*(*s_etat_processus)
338: .l_base_pile_systeme).retour_definition;
339: (*(*s_etat_processus).l_base_pile_systeme)
340: .retour_definition = 'Y';
341:
342: if (depilement(s_etat_processus, &((*s_etat_processus)
343: .l_base_pile), &s_objet) == d_erreur)
344: {
345: if (test_cfsf(s_etat_processus, 51) == d_faux)
346: {
347: printf("%s", ds_beep);
348: }
349:
350: if ((*s_etat_processus).langue == 'F')
351: {
352: printf("+++Erreur : Défaut d'argument\n");
353: }
354: else
355: {
356: printf("+++Error : Too few arguments\n");
357: }
358:
359: (*(*s_etat_processus).l_base_pile_systeme)
360: .retour_definition = tampon_retour;
361:
362: fflush(stdout);
363: }
364: else if (evaluation(s_etat_processus, s_objet, 'I') ==
365: d_erreur)
366: {
367: (*(*s_etat_processus).l_base_pile_systeme)
368: .retour_definition = tampon_retour;
369:
370: if ((*s_etat_processus).erreur_systeme != d_es)
371: {
372: if (test_cfsf(s_etat_processus, 51) == d_faux)
373: {
374: printf("%s", ds_beep);
375: }
376:
377: if ((message = messages(s_etat_processus))
378: == NULL)
379: {
380: free((*s_etat_processus)
381: .instruction_courante);
382: return(d_erreur);
383: }
384:
385: printf("%s [%d]\n", message, (int) getpid());
386:
387: free(message);
388: free((*s_etat_processus).instruction_courante);
389: return(d_erreur);
390: }
391: else if ((*s_etat_processus)
392: .invalidation_message_erreur == d_faux)
393: {
394: (*s_etat_processus).erreur_execution =
395: (*s_etat_processus)
396: .derniere_erreur_evaluation;
397:
398: if (test_cfsf(s_etat_processus, 51) == d_faux)
399: {
400: printf("%s", ds_beep);
401: }
402:
403: if ((message = messages(s_etat_processus))
404: == NULL)
405: {
406: free((*s_etat_processus)
407: .instruction_courante);
408: return(d_erreur);
409: }
410:
411: printf("%s [%d]\n", message, (int) getpid());
412: free(message);
413:
414: if (test_cfsf(s_etat_processus, 31) == d_vrai)
415: {
416: l_element_courant = (*s_etat_processus)
417: .l_base_pile_last;
418:
419: while(l_element_courant != NULL)
420: {
421: if ((s_sous_objet = copie_objet(
422: s_etat_processus,
423: (*l_element_courant).donnee,
424: 'P')) == NULL)
425: {
426: (*s_etat_processus).erreur_systeme =
427: d_es_allocation_memoire;
428: return(d_erreur);
429: }
430:
431: if (empilement(s_etat_processus,
432: &((*s_etat_processus)
433: .l_base_pile),
434: s_sous_objet) == d_erreur)
435: {
436: return(d_erreur);
437: }
438:
439: l_element_courant = (*l_element_courant)
440: .suivant;
441: }
442: }
443:
444: (*s_etat_processus).erreur_execution = d_ex;
445: (*s_etat_processus).exception = d_ep;
446: }
447:
448: liberation(s_etat_processus, s_objet);
449: }
450: else
451: {
452: liberation(s_etat_processus, s_objet);
453: }
454:
455: (*(*s_etat_processus).l_base_pile_systeme)
456: .retour_definition = tampon_retour;
457: }
458: }
459: else if ((*s_etat_processus).invalidation_message_erreur
460: == d_faux)
461: {
462: (*s_etat_processus).instruction_courante = registre;
463: (*s_etat_processus).position_courante = position_courante;
464: (*s_etat_processus).definitions_chainees = tampon;
465:
466: if (test_cfsf(s_etat_processus, 51) == d_faux)
467: {
468: printf("%s", ds_beep);
469: }
470:
471: if ((message = messages(s_etat_processus)) == NULL)
472: {
473: free((*s_etat_processus).instruction_courante);
474: free(ligne);
475: return(d_erreur);
476: }
477:
478: free(message);
479:
480: if ((*s_etat_processus).langue == 'F')
481: {
482: printf("+++Erreur : Erreur de syntaxe\n");
483: }
484: else
485: {
486: printf("+++Error : Syntax error\n");
487: }
488:
489: fflush(stdout);
490: }
491:
492: free(ligne);
493: }
494:
495: (*s_etat_processus).traitement_instruction_halt = d_faux;
496: }
497:
498: if ((*s_etat_processus).debug == d_vrai)
499: if (((*s_etat_processus).type_debug &
500: d_debug_fonctions_intrinseques) != 0)
501: {
502: if ((*s_etat_processus).langue == 'F')
503: {
504: printf("[%d] Instruction %s\n",
505: (int) getpid(),
506: (*s_etat_processus).instruction_courante);
507: }
508: else
509: {
510: printf("[%d] %s instruction\n",
511: (int) getpid(),
512: (*s_etat_processus).instruction_courante);
513: }
514:
515: fflush(stdout);
516: }
517:
518: /*
519: --------------------------------------------------------------------------------
520: Dans le cas où une instruction est retournée, celle-ci est évaluée. Dans le
521: cas contraire, l'interprète renvoie un message d'erreur et s'interrompt.
522: --------------------------------------------------------------------------------
523: */
524:
525: if (erreur == d_absence_erreur)
526: {
527:
528: /*
529: --------------------------------------------------------------------------------
530: Scrutation des mots clef du langage RPL/2 et exécution le cas échéant
531: de l'action associée.
532: --------------------------------------------------------------------------------
533: */
534:
535: analyse(s_etat_processus, NULL);
536:
537: if ((*s_etat_processus).traitement_cycle_exit != 'N')
538: {
539: switch((*s_etat_processus).traitement_cycle_exit)
540: {
541: case 'C' :
542: {
543: instruction_cycle(s_etat_processus);
544: break;
545: }
546:
547: case 'E' :
548: {
549: instruction_exit(s_etat_processus);
550: break;
551: }
552: }
553: }
554:
555: if ((*s_etat_processus).instruction_valide == 'N')
556: {
557:
558: /*
559: --------------------------------------------------------------------------------
560: L'instruction ne correspond pas à l'un des mots clef du langage RPL/2.
561: --------------------------------------------------------------------------------
562: */
563:
564: if ((recherche_variable(s_etat_processus,
565: (*s_etat_processus).instruction_courante) ==
566: d_vrai) && ((*s_etat_processus)
567: .autorisation_evaluation_nom == 'Y'))
568: {
569: if ((*(*s_etat_processus).pointeur_variable_courante)
570: .objet == NULL)
571: {
572:
573: /*
574: --------------------------------------------------------------------------------
575: L'instruction est une variable partagée
576: --------------------------------------------------------------------------------
577: */
578:
579: if ((*s_etat_processus).debug == d_vrai)
580: if (((*s_etat_processus).type_debug &
581: d_debug_variables) != 0)
582: {
583: if ((*s_etat_processus).langue == 'F')
584: {
585: printf("[%d] Empilement de la variable "
586: "partagée %s de type %d\n",
587: (int) getpid(), (*s_etat_processus)
588: .instruction_courante,
589: (*(*(*s_etat_processus)
590: .pointeur_variable_courante).objet)
591: .type);
592: }
593: else
594: {
595: printf("[%d] Pushing %s as %d type shared "
596: "variable \n", (int) getpid(),
597: (*s_etat_processus)
598: .instruction_courante,
599: (*(*(*s_etat_processus)
600: .pointeur_variable_courante).objet)
601: .type);
602: }
603:
604: fflush(stdout);
605: }
606:
607: if (pthread_mutex_lock(&((*(*s_etat_processus)
608: .s_liste_variables_partagees).mutex)) != 0)
609: {
610: (*s_etat_processus).erreur_systeme =
611: d_es_processus;
612: return(d_erreur);
613: }
614:
615: if (recherche_variable_partagee(s_etat_processus,
616: (*(*s_etat_processus)
617: .pointeur_variable_courante).nom,
618: (*(*s_etat_processus)
619: .pointeur_variable_courante).variable_partagee,
620: 'P') == d_vrai)
621: {
622: // La variable existe.
623:
624: if ((s_objet = copie_objet(s_etat_processus,
625: (*(*s_etat_processus)
626: .s_liste_variables_partagees)
627: .table[(*(*s_etat_processus)
628: .s_liste_variables_partagees)
629: .position_variable].objet, 'P'))
630: == NULL)
631: {
632: (*s_etat_processus).erreur_systeme =
633: d_es_allocation_memoire;
634: return(d_erreur);
635: }
636:
637: if (pthread_mutex_unlock(&((*(*s_etat_processus)
638: .s_liste_variables_partagees).mutex))
639: != 0)
640: {
641: (*s_etat_processus).erreur_systeme =
642: d_es_processus;
643: return(d_erreur);
644: }
645:
646: if (empilement(s_etat_processus,
647: &((*s_etat_processus).l_base_pile),
648: s_objet) == d_erreur)
649: {
650: (*s_etat_processus).erreur_systeme =
651: d_es_allocation_memoire;
652: return(d_erreur);
653: }
654: }
655: else
656: {
657: // La variable n'existe plus.
658:
659: (*s_etat_processus).erreur_systeme = d_es;
660:
661: if (pthread_mutex_unlock(&((*(*s_etat_processus)
662: .s_liste_variables_partagees).mutex))
663: != 0)
664: {
665: (*s_etat_processus).erreur_systeme =
666: d_es_processus;
667: return(d_erreur);
668: }
669:
670: recherche_type(s_etat_processus);
671: }
672: }
673:
674: /*
675: --------------------------------------------------------------------------------
676: L'instruction est une variable automatique (évaluation lors de l'empilement).
677: --------------------------------------------------------------------------------
678: */
679:
680: else if ((*(*(*s_etat_processus).pointeur_variable_courante)
681: .objet).type == ADR)
682: {
683:
684: /*
685: --------------------------------------------------------------------------------
686: L'instruction est une variable de type 'adresse' pointant sur une
687: définition. Un branchement est effectué à cette adresse.
688: --------------------------------------------------------------------------------
689: */
690:
691: if ((*s_etat_processus).debug == d_vrai)
692: if (((*s_etat_processus).type_debug &
693: d_debug_appels_fonctions) != 0)
694: {
695: if ((*s_etat_processus).langue == 'F')
696: {
697: printf("[%d] Branchement à la"
698: " définition %s\n", (int) getpid(),
699: (*s_etat_processus)
700: .instruction_courante);
701: }
702: else
703: {
704: printf("[%d] Execution : "
705: "Branching at %s definition\n",
706: (int) getpid(), (*s_etat_processus)
707: .instruction_courante);
708: }
709:
710: fflush(stdout);
711: }
712:
713: (*s_etat_processus).autorisation_empilement_programme =
714: 'N';
715:
716: empilement_pile_systeme(s_etat_processus);
717:
718: if ((*s_etat_processus).erreur_systeme != d_es)
719: {
720: erreur = d_erreur;
721: }
722: else
723: {
724: if ((*s_etat_processus).profilage == d_vrai)
725: {
726: profilage(s_etat_processus,
727: (*s_etat_processus)
728: .instruction_courante);
729:
730: if ((*s_etat_processus).erreur_systeme != d_es)
731: {
732: return(d_erreur);
733: }
734: }
735:
736: (*(*s_etat_processus).l_base_pile_systeme)
737: .adresse_retour = (*s_etat_processus)
738: .position_courante;
739:
740: (*(*s_etat_processus).l_base_pile_systeme)
741: .retour_definition = 'Y';
742:
743: (*(*s_etat_processus).l_base_pile_systeme)
744: .niveau_courant = (*s_etat_processus)
745: .niveau_courant;
746:
747: (*s_etat_processus).position_courante =
748: (*((unsigned long *)
749: ((*(*(*s_etat_processus)
750: .pointeur_variable_courante)
751: .objet).objet)));
752:
753: drapeau_appel_definition = d_vrai;
754: }
755: }
756: else
757: {
758: if ((*s_etat_processus).debug == d_vrai)
759: if (((*s_etat_processus).type_debug &
760: d_debug_variables) != 0)
761: {
762: if ((*s_etat_processus).langue == 'F')
763: {
764: printf("[%d] Empilement de la variable "
765: "%s de type %d\n",
766: (int) getpid(),
767: (*s_etat_processus)
768: .instruction_courante,
769: (*(*(*s_etat_processus)
770: .pointeur_variable_courante).objet)
771: .type);
772: }
773: else
774: {
775: printf("[%d] Pushing %s as %d type variable "
776: "\n", (int) getpid(),
777: (*s_etat_processus)
778: .instruction_courante,
779: (*(*(*s_etat_processus)
780: .pointeur_variable_courante).objet)
781: .type);
782: }
783:
784: fflush(stdout);
785: }
786:
787: if ((s_objet = copie_objet(s_etat_processus,
788: (*(*s_etat_processus)
789: .pointeur_variable_courante).objet, 'P'))
790: == NULL)
791: {
792: (*s_etat_processus).erreur_systeme =
793: d_es_allocation_memoire;
794: return(d_erreur);
795: }
796:
797: if (empilement(s_etat_processus,
798: &((*s_etat_processus).l_base_pile),
799: s_objet) == d_erreur)
800: {
801: (*s_etat_processus).erreur_systeme =
802: d_es_allocation_memoire;
803: return(d_erreur);
804: }
805: }
806: }
807: else
808: {
809:
810: /*
811: --------------------------------------------------------------------------------
812: L'instruction est une donnée à empiler.
813: --------------------------------------------------------------------------------
814: */
815:
816: (*s_etat_processus).erreur_systeme = d_es;
817: recherche_type(s_etat_processus);
818:
819: if ((*s_etat_processus).autorisation_nom_implicite == 'N')
820: {
821: if ((*s_etat_processus).l_base_pile == NULL)
822: {
823: if ((*s_etat_processus).erreur_execution !=
824: d_ex_nom_implicite)
825: {
826: (*s_etat_processus).erreur_execution =
827: d_ex_manque_argument;
828: }
829: }
830: else if ((*(*(*s_etat_processus).l_base_pile).donnee)
831: .type == NOM)
832: {
833: if ((*((struct_nom *) (*(*(*s_etat_processus)
834: .l_base_pile).donnee).objet)).symbole
835: == d_faux)
836: {
837: (*s_etat_processus).erreur_execution =
838: d_ex_nom_implicite;
839:
840: // Si le niveau de récursivité est non nul, on
841: // arrive ici depuis la fonction
842: // recherche_type(). On retourne à cette
843: // dernière en indiquant une erreur.
844:
845: if ((*s_etat_processus).niveau_recursivite != 0)
846: {
847: free((*s_etat_processus)
848: .instruction_courante);
849: return(d_erreur);
850: }
851: }
852: }
853: }
854:
855: // Le séquenceur est appelé depuis la routine d'évaluation
856:
857: if ((*s_etat_processus).evaluation_forcee == 'Y')
858: {
859: if (depilement(s_etat_processus,
860: &((*s_etat_processus).l_base_pile),
861: &s_objet_evaluation) == d_erreur)
862: {
863: free((*s_etat_processus).instruction_courante);
864: (*s_etat_processus).erreur_execution =
865: d_ex_manque_argument;
866: return(d_erreur);
867: }
868:
869: if (evaluation(s_etat_processus, s_objet_evaluation,
870: 'N') == d_erreur)
871: {
872: free((*s_etat_processus).instruction_courante);
873: liberation(s_etat_processus, s_objet_evaluation);
874: return(d_erreur);
875: }
876:
877: liberation(s_etat_processus, s_objet_evaluation);
878: }
879:
880: // Le séquenceur est appelé depuis la routine de
881: // recherche de type
882:
883: else if ((*s_etat_processus).recherche_type == 'Y')
884: {
885: if ((*s_etat_processus).erreur_execution != d_ex)
886: {
887: free((*s_etat_processus).instruction_courante);
888: return(d_erreur);
889: }
890: }
891: }
892: }
893: else if (((*s_etat_processus).test_instruction == 'Y') &&
894: ((*s_etat_processus).instruction_valide == 'Y'))
895: {
896:
897: /*
898: --------------------------------------------------------------------------------
899: Permet de traiter les fonctions dans les objets de type liste
900: --------------------------------------------------------------------------------
901: */
902:
903: if ((instruction_majuscule = conversion_majuscule(
904: (*s_etat_processus).instruction_courante)) == NULL)
905: {
906: (*s_etat_processus).erreur_systeme =
907: d_es_allocation_memoire;
908: return(d_erreur);
909: }
910:
911: if ((strcmp((*s_etat_processus).instruction_courante, "<<")
912: != 0) && (strcmp((*s_etat_processus)
913: .instruction_courante, ">>") != 0))
914: {
915: if ((s_objet = allocation(s_etat_processus, FCT)) == NULL)
916: {
917: (*s_etat_processus).erreur_systeme =
918: d_es_allocation_memoire;
919: return(d_erreur);
920: }
921:
922: (*((struct_fonction *) (*s_objet).objet))
923: .nombre_arguments = 0;
924:
925: if ((*s_etat_processus).instruction_intrinseque == 'Y')
926: {
927: if (((*((struct_fonction *) (*s_objet).objet))
928: .nom_fonction = conversion_majuscule(
929: (*s_etat_processus).instruction_courante))
930: == NULL)
931: {
932: (*s_etat_processus).erreur_systeme =
933: d_es_allocation_memoire;
934: return(d_erreur);
935: }
936: }
937: else
938: {
939: if (((*((struct_fonction *) (*s_objet).objet))
940: .nom_fonction = (unsigned char *) malloc(
941: (strlen((*s_etat_processus)
942: .instruction_courante)
943: + 1) * sizeof(unsigned char))) == NULL)
944: {
945: (*s_etat_processus).erreur_systeme =
946: d_es_allocation_memoire;
947: return(d_erreur);
948: }
949:
950: strcpy((*((struct_fonction *) (*s_objet).objet))
951: .nom_fonction, (*s_etat_processus)
952: .instruction_courante);
953: }
954:
955: (*((struct_fonction *) (*s_objet).objet)).fonction =
956: analyse_instruction(s_etat_processus,
957: (*s_etat_processus).instruction_courante);
958:
959: if (empilement(s_etat_processus,
960: &((*s_etat_processus).l_base_pile), s_objet) ==
961: d_erreur)
962: {
963: (*s_etat_processus).erreur_systeme =
964: d_es_allocation_memoire;
965: return(d_erreur);
966: }
967: }
968: else
969: {
970: (*s_etat_processus).test_instruction = 'N';
971: analyse(s_etat_processus, NULL);
972: (*s_etat_processus).test_instruction = 'Y';
973: }
974:
975: free(instruction_majuscule);
976: }
977:
978: erreur |= (((*s_etat_processus).erreur_execution != d_ex)
979: ? d_erreur : d_absence_erreur);
980: }
981: else
982: {
983: printf("\n");
984:
985: if ((*s_etat_processus).langue == 'F')
986: {
987: printf("+++Erreur : Argument %s invalide\n",
988: (*s_etat_processus).instruction_courante);
989: }
990: else
991: {
992: printf("+++Error : Invalid %s argument\n",
993: (*s_etat_processus).instruction_courante);
994: }
995:
996: fflush(stdout);
997:
998: free((*s_etat_processus).instruction_courante);
999: return(d_erreur);
1000: }
1001:
1002: /*
1003: --------------------------------------------------------------------------------
1004: Traitement des arrêts simples
1005: --------------------------------------------------------------------------------
1006: */
1007:
1008: if ((*s_etat_processus).var_volatile_requete_arret2 != 0)
1009: {
1010: if ((*s_etat_processus).debug_programme == d_vrai)
1011: {
1012: (*s_etat_processus).var_volatile_requete_arret2 = 0;
1013: }
1014: else
1015: {
1016: if ((*s_etat_processus).var_volatile_requete_arret2 == -1)
1017: {
1018: if (strncmp(getenv("LANG"), "fr", 2) == 0)
1019: {
1020: printf("[%d] Arrêt\n", (int) getpid());
1021: }
1022: else
1023: {
1024: printf("[%d] Break\n", (int) getpid());
1025: }
1026:
1027: (*s_etat_processus).var_volatile_requete_arret2 = 1;
1028:
1029: fflush(stdout);
1030: }
1031:
1032: if ((*s_etat_processus).niveau_recursivite == 0)
1033: {
1034: (*s_etat_processus).debug_programme = d_vrai;
1035: (*s_etat_processus).var_volatile_requete_arret2 = 0;
1036: }
1037: }
1038: }
1039:
1040: /*
1041: * On ne sort pas du debugger en cas d'une erreur sur un programme
1042: * en cours de débogage.
1043: */
1044:
1045: if ((((*s_etat_processus).erreur_execution != d_ex) ||
1046: ((*s_etat_processus).exception != d_ep)) &&
1047: ((*s_etat_processus).debug_programme == d_vrai))
1048: {
1049: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1050: {
1051: l_element_courant = (*s_etat_processus).l_base_pile_last;
1052:
1053: while(l_element_courant != NULL)
1054: {
1055: if ((s_objet = copie_objet(s_etat_processus,
1056: (*l_element_courant).donnee, 'P')) == NULL)
1057: {
1058: (*s_etat_processus).erreur_systeme =
1059: d_es_allocation_memoire;
1060: return(d_erreur);
1061: }
1062:
1063: if (empilement(s_etat_processus, &((*s_etat_processus)
1064: .l_base_pile), s_objet) == d_erreur)
1065: {
1066: return(d_erreur);
1067: }
1068:
1069: l_element_courant = (*l_element_courant).suivant;
1070: }
1071: }
1072:
1073: if (test_cfsf(s_etat_processus, 51) == d_faux)
1074: {
1075: printf("%s", ds_beep);
1076: }
1077:
1078: if ((message = messages(s_etat_processus)) == NULL)
1079: {
1080: free((*s_etat_processus).instruction_courante);
1081: return(d_erreur);
1082: }
1083:
1084: printf("%s [%d]\n", message, (int) getpid());
1085:
1086: free(message);
1087:
1088: (*s_etat_processus).erreur_execution = d_ex;
1089: (*s_etat_processus).exception = d_ep;
1090: erreur = d_absence_erreur;
1091:
1092: (*s_etat_processus).position_courante -=
1093: strlen((*s_etat_processus).instruction_courante);
1094: }
1095:
1096: /*
1097: --------------------------------------------------------------------------------
1098: Test de fin d'exécution du programme RPL/2
1099: --------------------------------------------------------------------------------
1100: */
1101:
1102: if (((*s_etat_processus).niveau_courant == 0) &&
1103: (drapeau_appel_definition != d_vrai))
1104: {
1105: drapeau_fin = d_vrai;
1106: }
1107: else if ((*s_etat_processus).requete_arret == 'Y')
1108: {
1109: drapeau_fin = d_vrai;
1110: }
1111: else if (((*s_etat_processus).var_volatile_requete_arret != 0)
1112: && ((*s_etat_processus).debug_programme == d_faux))
1113: {
1114: drapeau_fin = d_vrai;
1115:
1116: if ((*s_etat_processus).erreur_systeme == d_es)
1117: {
1118: erreur = d_absence_erreur;
1119: }
1120: }
1121: else if ((*s_etat_processus).arret_si_exception == d_vrai)
1122: {
1123: drapeau_fin = d_faux;
1124:
1125: if ((*s_etat_processus).exception != d_ep)
1126: {
1127: erreur = d_erreur;
1128: }
1129: else if ((*s_etat_processus).erreur_systeme != d_es)
1130: {
1131: erreur = d_erreur;
1132: }
1133: }
1134: else if ((*s_etat_processus).arret_si_exception == d_faux)
1135: {
1136: if ((message = messages(s_etat_processus)) == NULL)
1137: {
1138: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
1139: return(d_erreur);
1140: }
1141:
1142: free(message);
1143:
1144: drapeau_fin = d_faux;
1145:
1146: /*
1147: --------------------------------------------------------------------------------
1148: Traitement des exceptions
1149: --------------------------------------------------------------------------------
1150: */
1151:
1152: if ((*s_etat_processus).erreur_systeme != d_es)
1153: {
1154: erreur = d_erreur;
1155: }
1156: else if (((*s_etat_processus).exception != d_ep) ||
1157: ((*s_etat_processus).erreur_execution != d_ex))
1158: {
1159: tampon = (*s_etat_processus).instruction_courante;
1160:
1161: while((*(*s_etat_processus).l_base_pile_systeme).clause != 'R')
1162: {
1163: erreur = recherche_instruction_suivante(s_etat_processus);
1164:
1165: if (erreur == d_erreur)
1166: {
1167: free((*s_etat_processus).instruction_courante);
1168: return(d_erreur);
1169: }
1170:
1171: if (recherche_variable(s_etat_processus,
1172: (*s_etat_processus).instruction_courante) == d_vrai)
1173: {
1174: if ((*(*s_etat_processus).pointeur_variable_courante)
1175: .objet == NULL)
1176: {
1177: // Variable partagée
1178: }
1179: else if ((*(*(*s_etat_processus)
1180: .pointeur_variable_courante).objet).type == ADR)
1181: {
1182: empilement_pile_systeme(s_etat_processus);
1183:
1184: if ((*s_etat_processus).erreur_systeme != d_es)
1185: {
1186: free((*s_etat_processus).instruction_courante);
1187: return(d_erreur);
1188: }
1189:
1190: (*(*s_etat_processus).l_base_pile_systeme)
1191: .adresse_retour = (*s_etat_processus)
1192: .position_courante;
1193:
1194: (*(*s_etat_processus).l_base_pile_systeme)
1195: .retour_definition = 'Y';
1196:
1197: (*(*s_etat_processus).l_base_pile_systeme)
1198: .niveau_courant = (*s_etat_processus)
1199: .niveau_courant;
1200:
1201: (*s_etat_processus).position_courante =
1202: (*((unsigned long *)
1203: ((*(*(*s_etat_processus)
1204: .pointeur_variable_courante)
1205: .objet).objet)));
1206:
1207: (*s_etat_processus)
1208: .autorisation_empilement_programme = 'N';
1209: }
1210: }
1211: else
1212: {
1213: (*s_etat_processus).erreur_systeme = d_es;
1214: instruction_majuscule = conversion_majuscule(
1215: (*s_etat_processus).instruction_courante);
1216:
1217: if (instruction_majuscule == NULL)
1218: {
1219: free((*s_etat_processus).instruction_courante);
1220: return(d_erreur);
1221: }
1222:
1223: /*
1224: * Traitement de la pile système par les
1225: * différentes instructions.
1226: */
1227:
1228: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1229: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1230: (strcmp(instruction_majuscule, "DO") == 0) ||
1231: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1232: (strcmp(instruction_majuscule, "FOR") == 0) ||
1233: (strcmp(instruction_majuscule, "FORALL") == 0)
1234: ||
1235: (strcmp(instruction_majuscule, "START") == 0) ||
1236: (strcmp(instruction_majuscule, "SELECT") == 0)
1237: ||
1238: (strcmp(instruction_majuscule, "CRITICAL") == 0)
1239: || (strcmp(instruction_majuscule, "CASE") == 0)
1240: || (strcmp(instruction_majuscule, "<<") == 0))
1241: {
1242: if (strcmp(instruction_majuscule, "<<") == 0)
1243: {
1244: analyse(s_etat_processus, NULL);
1245: }
1246: else if ((strcmp(instruction_majuscule, "FOR") == 0)
1247: || (strcmp(instruction_majuscule, "FORALL")
1248: == 0) || (strcmp(instruction_majuscule,
1249: "START") == 0))
1250: {
1251: empilement_pile_systeme(s_etat_processus);
1252:
1253: if ((*s_etat_processus).erreur_systeme != d_es)
1254: {
1255: return(d_erreur);
1256: }
1257:
1258: (*(*s_etat_processus).l_base_pile_systeme)
1259: .type_cloture = 'L';
1260: }
1261: else
1262: {
1263: empilement_pile_systeme(s_etat_processus);
1264:
1265: if ((*s_etat_processus).erreur_systeme != d_es)
1266: {
1267: return(d_erreur);
1268: }
1269: }
1270: }
1271: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1272: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1273: (strcmp(instruction_majuscule, "STEP") == 0) ||
1274: (strcmp(instruction_majuscule, ">>") == 0))
1275: {
1276: if (strcmp(instruction_majuscule, ">>") == 0)
1277: {
1278: analyse(s_etat_processus, NULL);
1279:
1280: if ((*(*s_etat_processus).l_base_pile_systeme)
1281: .origine_routine_evaluation == 'Y')
1282: {
1283: free(instruction_majuscule);
1284: free((*s_etat_processus)
1285: .instruction_courante);
1286:
1287: (*s_etat_processus).instruction_courante =
1288: tampon;
1289:
1290: return(d_absence_erreur);
1291: }
1292: }
1293: else if (((strcmp(instruction_majuscule, "NEXT")
1294: == 0) || (strcmp(instruction_majuscule,
1295: "STEP") == 0)) && ((*(*s_etat_processus)
1296: .l_base_pile_systeme).type_cloture != 'L'))
1297: {
1298: /*
1299: * Libération des compteurs de boucle.
1300: */
1301:
1302: presence_compteur = (((*(*s_etat_processus)
1303: .l_base_pile_systeme).type_cloture
1304: == 'F') || ((*(*s_etat_processus)
1305: .l_base_pile_systeme).type_cloture
1306: == 'A')) ? d_vrai : d_faux;
1307:
1308: if (((*(*s_etat_processus).l_base_pile_systeme)
1309: .type_cloture != 'S') &&
1310: (presence_compteur == d_faux))
1311: {
1312: return(d_erreur);
1313: }
1314:
1315: if (presence_compteur == d_vrai)
1316: {
1317: if (recherche_variable(s_etat_processus,
1318: (*(*s_etat_processus)
1319: .l_base_pile_systeme).nom_variable)
1320: == d_faux)
1321: {
1322: return(d_erreur);
1323: }
1324:
1325: if ((*(*s_etat_processus)
1326: .pointeur_variable_courante).objet
1327: == NULL)
1328: {
1329: return(d_erreur);
1330: }
1331:
1332: (*s_etat_processus).niveau_courant--;
1333:
1334: if (retrait_variables_par_niveau(
1335: s_etat_processus) == d_erreur)
1336: {
1337: return(d_erreur);
1338: }
1339: }
1340:
1341: depilement_pile_systeme(s_etat_processus);
1342:
1343: if ((*s_etat_processus).erreur_systeme != d_es)
1344: {
1345: return(d_erreur);
1346: }
1347: }
1348: else
1349: {
1350: // Traitement spécifique pour la fin
1351: // d'une section critique
1352:
1353: if ((*s_etat_processus).l_base_pile_systeme
1354: == NULL)
1355: {
1356: (*s_etat_processus).erreur_systeme =
1357: d_es_processus;
1358: return(d_erreur);
1359: }
1360:
1361: if ((*(*s_etat_processus).l_base_pile_systeme)
1362: .type_cloture == 'Q')
1363: {
1364: if (pthread_mutex_unlock(
1365: &mutex_sections_critiques) != 0)
1366: {
1367: (*s_etat_processus).erreur_systeme =
1368: d_es_processus;
1369: return(d_erreur);
1370: }
1371:
1372: (*s_etat_processus).sections_critiques--;
1373: }
1374:
1375: depilement_pile_systeme(s_etat_processus);
1376:
1377: if ((*s_etat_processus).erreur_systeme != d_es)
1378: {
1379: return(d_erreur);
1380: }
1381: }
1382: }
1383:
1384: free(instruction_majuscule);
1385: }
1386:
1387: free((*s_etat_processus).instruction_courante);
1388: }
1389:
1390: drapeau_then = d_faux;
1391: niveau = 0;
1392:
1393: do
1394: {
1395: erreur = recherche_instruction_suivante(s_etat_processus);
1396:
1397: if (erreur == d_erreur)
1398: {
1399: return(d_erreur);
1400: }
1401:
1402: instruction_majuscule = conversion_majuscule(
1403: (*s_etat_processus).instruction_courante);
1404:
1405: if (instruction_majuscule == NULL)
1406: {
1407: return(d_erreur);
1408: }
1409:
1410: if ((strcmp(instruction_majuscule, "IF") == 0) ||
1411: (strcmp(instruction_majuscule, "IFERR") == 0) ||
1412: (strcmp(instruction_majuscule, "DO") == 0) ||
1413: (strcmp(instruction_majuscule, "WHILE") == 0) ||
1414: (strcmp(instruction_majuscule, "FOR") == 0) ||
1415: (strcmp(instruction_majuscule, "FORALL") == 0) ||
1416: (strcmp(instruction_majuscule, "START") == 0) ||
1417: (strcmp(instruction_majuscule, "SELECT") == 0)
1418: || (strcmp(instruction_majuscule, "CRITICAL") == 0)
1419: || (strcmp(instruction_majuscule, "CASE") == 0)
1420: || (strcmp(instruction_majuscule, "<<") == 0))
1421: {
1422: niveau++;
1423: }
1424: else if ((strcmp(instruction_majuscule, "END") == 0) ||
1425: (strcmp(instruction_majuscule, "NEXT") == 0) ||
1426: (strcmp(instruction_majuscule, "STEP") == 0) ||
1427: (strcmp(instruction_majuscule, ">>") == 0))
1428: {
1429: niveau--;
1430: }
1431:
1432: drapeau_then = ((strcmp(instruction_majuscule, "THEN") == 0)
1433: && (niveau == 0)) ? d_vrai : d_faux;
1434:
1435: free(instruction_majuscule);
1436: free((*s_etat_processus).instruction_courante);
1437: } while(drapeau_then == d_faux);
1438:
1439: (*s_etat_processus).position_courante -= 5;
1440: (*s_etat_processus).instruction_courante = tampon;
1441: (*(*s_etat_processus).l_base_pile_systeme).clause = 'X';
1442:
1443: erreur = d_absence_erreur;
1444: (*s_etat_processus).exception = d_ep;
1445: (*s_etat_processus).erreur_execution = d_ex;
1446: }
1447: }
1448: else
1449: {
1450: drapeau_fin = d_faux;
1451: }
1452:
1453: if (erreur == d_absence_erreur)
1454: {
1455: free((*s_etat_processus).instruction_courante);
1456: }
1457: } while((erreur == d_absence_erreur) &&
1458: ((*s_etat_processus).position_courante <
1459: (*s_etat_processus).longueur_definitions_chainees) &&
1460: (drapeau_fin == d_faux) &&
1461: ((*s_etat_processus).retour_routine_evaluation == 'N'));
1462:
1463: /*
1464: --------------------------------------------------------------------------------
1465: Messages d'erreur à afficher le cas échéant
1466: --------------------------------------------------------------------------------
1467: */
1468:
1469: if ((erreur != d_absence_erreur) && ((*s_etat_processus)
1470: .invalidation_message_erreur == d_faux))
1471: {
1472: if (test_cfsf(s_etat_processus, 31) == d_vrai)
1473: {
1474: l_element_courant = (*s_etat_processus).l_base_pile_last;
1475:
1476: while(l_element_courant != NULL)
1477: {
1478: if ((s_objet = copie_objet(s_etat_processus,
1479: (*l_element_courant).donnee, 'P')) == NULL)
1480: {
1481: (*s_etat_processus).erreur_systeme =
1482: d_es_allocation_memoire;
1483: return(d_erreur);
1484: }
1485:
1486: if (empilement(s_etat_processus, &((*s_etat_processus)
1487: .l_base_pile), s_objet) == d_erreur)
1488: {
1489: return(d_erreur);
1490: }
1491:
1492: l_element_courant = (*l_element_courant).suivant;
1493: }
1494: }
1495:
1496: if (test_cfsf(s_etat_processus, 51) == d_faux)
1497: {
1498: printf("%s", ds_beep);
1499: }
1500:
1501: if ((message = messages(s_etat_processus)) == NULL)
1502: {
1503: return(d_erreur);
1504: }
1505:
1506: printf("%s [%d]\n", message, (int) getpid());
1507:
1508: free(message);
1509: free((*s_etat_processus).instruction_courante);
1510:
1511: if ((*s_etat_processus).var_volatile_processus_pere == 0)
1512: {
1513: envoi_signal_processus((*s_etat_processus).pid_processus_pere,
1514: rpl_sigalrm);
1515: }
1516: else
1517: {
1518: (*s_etat_processus).var_volatile_alarme = -1;
1519: }
1520:
1521: return(d_erreur);
1522: }
1523:
1524: return(d_absence_erreur);
1525: }
1526:
1527: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>