/* ================================================================================ RPL/2 (R) version 4.0.20 Copyright (C) 1989-2011 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Procédure de vérification syntaxique du source et de précompilation ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : - renvoi : erreur -------------------------------------------------------------------------------- Effets de bord : ================================================================================ */ logical1 compilation(struct_processus *s_etat_processus) { struct_objet *s_objet; struct_variable *s_variable; unsigned char apostrophe_ouverte; unsigned char apostrophe_ouverte_registre; unsigned char caractere_courant; unsigned char caractere_precedent; unsigned char caractere_suivant; unsigned char *definition; unsigned char fermeture_definition; unsigned char guillemet_ouvert; unsigned char ouverture_definition; unsigned char position_debut_nom_definition_valide; unsigned long *adresse; unsigned long i; unsigned long niveau_definition; unsigned long niveau_definition_registre; unsigned long position_courante; unsigned long position_debut_nom_definition; unsigned long position_fin_nom_definition; unsigned long validation; unsigned long validation_registre; (*s_etat_processus).erreur_compilation = d_ec; (*s_etat_processus).erreur_systeme = d_es; (*s_etat_processus).erreur_execution = d_ex; (*s_etat_processus).exception = d_ep; (*s_etat_processus).arret_si_exception = d_vrai; (*s_etat_processus).position_courante = 0; /* -------------------------------------------------------------------------------- Recheche des définitions -------------------------------------------------------------------------------- */ niveau_definition = 0; niveau_definition_registre = 0; position_courante = 0; position_debut_nom_definition = 0; validation = 0; apostrophe_ouverte = d_faux; apostrophe_ouverte_registre = d_faux; guillemet_ouvert = d_faux; position_debut_nom_definition_valide = d_faux; if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_analyse) != 0) { printf("\n"); printf("[%d] Compilation\n", (int) getpid()); fflush(stdout); } while((*s_etat_processus).definitions_chainees[position_courante] != d_code_fin_chaine) { caractere_courant = (*s_etat_processus) .definitions_chainees[position_courante]; fermeture_definition = d_faux; ouverture_definition = d_faux; if (position_courante >= 1) { if (position_courante >= 2) { if (((*s_etat_processus).definitions_chainees [position_courante - 2] == '\\') && ((*s_etat_processus).definitions_chainees [position_courante - 1] == '\\')) { caractere_precedent = '*'; } else { caractere_precedent = (*s_etat_processus) .definitions_chainees[position_courante - 1]; } } else { caractere_precedent = (*s_etat_processus) .definitions_chainees[position_courante - 1]; } } else { caractere_precedent = ' '; } caractere_suivant = (*s_etat_processus) .definitions_chainees[position_courante + 1]; if (caractere_suivant == d_code_fin_chaine) { caractere_suivant = ' '; } if ((caractere_courant == '[') || (caractere_courant == '{')) { validation++; } else if ((caractere_courant == ']') || (caractere_courant == '}')) { validation--; } else if (caractere_courant == '\'') { if (apostrophe_ouverte == d_faux) { validation++; apostrophe_ouverte = d_vrai; } else { validation--; apostrophe_ouverte = d_faux; } } else if (caractere_courant == '"') { if (caractere_precedent != '\\') { swap((void *) &validation, (void *) &validation_registre, sizeof(validation)); swap((void *) &apostrophe_ouverte, (void *) &apostrophe_ouverte_registre, sizeof(apostrophe_ouverte)); swap((void *) &niveau_definition, (void *) &niveau_definition_registre, sizeof(niveau_definition)); guillemet_ouvert = (guillemet_ouvert == d_faux) ? d_vrai : d_faux; } } else if ((caractere_courant == '<') && (caractere_precedent == ' ') && (caractere_suivant == '<')) { if ((*s_etat_processus) .definitions_chainees[position_courante + 2] == ' ') { niveau_definition++; ouverture_definition = d_vrai; } } else if ((caractere_courant == '>') && (caractere_precedent == ' ') && (caractere_suivant == '>')) { if (((*s_etat_processus) .definitions_chainees[position_courante + 2] == ' ') || ((*s_etat_processus).definitions_chainees [position_courante + 2] == d_code_fin_chaine)) { if (niveau_definition == 0) { (*s_etat_processus).erreur_compilation = d_ec_niveau_definition_negatif; return(d_erreur); } else { niveau_definition--; fermeture_definition = d_vrai; position_courante++; } } } if ((niveau_definition == 0) && (guillemet_ouvert == d_faux) && (caractere_courant != ' ') && (fermeture_definition == d_faux)) { if (position_debut_nom_definition_valide == d_faux) { position_debut_nom_definition_valide = d_vrai; position_debut_nom_definition = position_courante; } } if (((niveau_definition == 1) && (ouverture_definition == d_vrai)) && (position_debut_nom_definition_valide == d_vrai)) { position_fin_nom_definition = position_courante - 1; position_debut_nom_definition_valide = d_faux; while((*s_etat_processus).definitions_chainees [position_fin_nom_definition] == ' ') { position_fin_nom_definition--; } i = position_debut_nom_definition; while(i <= position_fin_nom_definition) { if ((*s_etat_processus).definitions_chainees[i] == ' ') { (*s_etat_processus).erreur_compilation = d_ec_nom_definition_invalide; return(d_erreur); } else { i++; } } s_objet = allocation(s_etat_processus, ADR); s_variable = (struct_variable *) malloc(sizeof(struct_variable)); adresse = (*s_objet).objet; definition = (unsigned char *) malloc( (position_fin_nom_definition - position_debut_nom_definition + 2) * sizeof(unsigned char)); if ((s_objet == NULL) || (s_variable == NULL) || (adresse == NULL) || definition == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } else { (*adresse) = position_fin_nom_definition + 1; (*s_variable).nom = definition; (*s_variable).niveau = (*s_etat_processus).niveau_courant; (*s_variable).objet = s_objet; i = position_debut_nom_definition; while(i <= position_fin_nom_definition) { *(definition++) = (*s_etat_processus) .definitions_chainees[i++]; } *definition = d_code_fin_chaine; if (recherche_variable(s_etat_processus, (*s_variable).nom) == d_vrai) { if ((*s_etat_processus).langue == 'F') { printf("+++Attention : Plusieurs définitions de" " même nom\n"); } else { printf("+++Warning : Same name for several" " definitions\n"); } fflush(stdout); return(d_erreur); } (*s_etat_processus).erreur_systeme = d_es; creation_variable(s_etat_processus, s_variable, 'V', 'P'); if ((*s_etat_processus).erreur_systeme != d_es) { free(s_variable); return(d_erreur); } if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_analyse) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Compilation : Définition %s ($ %016lX) " "\n", (int) getpid(), (*s_variable).nom, (*adresse)); } else { printf("[%d] Compilation : %s definition ($ %016lX) " "\n", (int) getpid(), (*s_variable).nom, (*adresse)); } fflush(stdout); } } free(s_variable); } position_courante++; } return(analyse_syntaxique(s_etat_processus)); } /* ================================================================================ Procédure de d'analyse syntaxique du source ================================================================================ Entrées : -------------------------------------------------------------------------------- Sorties : - renvoi : erreur -------------------------------------------------------------------------------- Effets de bord : ================================================================================ */ logical1 analyse_syntaxique(struct_processus *s_etat_processus) { enum t_condition { AN_IF = 1, AN_IFERR, AN_THEN, AN_ELSE, AN_ELSEIF, AN_END, AN_DO, AN_UNTIL, AN_WHILE, AN_REPEAT, AN_SELECT, AN_CASE, AN_DEFAULT, AN_UP, AN_DOWN, AN_FOR, AN_START, AN_NEXT, AN_STEP }; unsigned char *instruction; unsigned char registre; typedef struct pile { enum t_condition condition; struct pile *suivant; } struct_pile_analyse; struct_pile_analyse *l_base_pile; struct_pile_analyse *l_nouvelle_base_pile; inline struct_pile_analyse * empilement_analyse(struct_pile_analyse *ancienne_base, enum t_condition condition) { struct_pile_analyse *nouvelle_base; if ((nouvelle_base = malloc(sizeof(struct_pile_analyse))) == NULL) { return(NULL); } (*nouvelle_base).suivant = ancienne_base; (*nouvelle_base).condition = condition; return(nouvelle_base); } inline struct_pile_analyse * depilement_analyse(struct_pile_analyse *ancienne_base) { struct_pile_analyse *nouvelle_base; if (ancienne_base == NULL) { return(NULL); } nouvelle_base = (*ancienne_base).suivant; free(ancienne_base); return(nouvelle_base); } inline logical1 test_analyse(struct_pile_analyse *l_base_pile, enum t_condition condition) { if (l_base_pile == NULL) { return(d_faux); } return(((*l_base_pile).condition == condition) ? d_vrai : d_faux); } inline void liberation_analyse(struct_pile_analyse *l_base_pile) { struct_pile_analyse *l_nouvelle_base_pile; while(l_base_pile != NULL) { l_nouvelle_base_pile = (*l_base_pile).suivant; free(l_base_pile); l_base_pile = l_nouvelle_base_pile; } return; } l_base_pile = NULL; l_nouvelle_base_pile = NULL; if ((*s_etat_processus).debug == d_vrai) if (((*s_etat_processus).type_debug & d_debug_analyse) != 0) { if ((*s_etat_processus).langue == 'F') { printf("[%d] Analyse\n", (int) getpid()); } else { printf("[%d] Analysis\n", (int) getpid()); } fflush(stdout); } (*s_etat_processus).position_courante = 0; registre = (*s_etat_processus).autorisation_empilement_programme; (*s_etat_processus).autorisation_empilement_programme = 'N'; /* -------------------------------------------------------------------------------- Analyse structurelle -------------------------------------------------------------------------------- */ while((*s_etat_processus).definitions_chainees [(*s_etat_processus).position_courante] != d_code_fin_chaine) { if (recherche_instruction_suivante(s_etat_processus) != d_absence_erreur) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; return(d_erreur); } if ((instruction = conversion_majuscule( (*s_etat_processus).instruction_courante)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } if (strcmp(instruction, "IF") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_IF)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; (*l_base_pile).condition = AN_IF; } else if (strcmp(instruction, "IFERR") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_IFERR)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "THEN") == 0) { if ((test_analyse(l_base_pile, AN_IF) == d_faux) && (test_analyse(l_base_pile, AN_ELSEIF) == d_faux) && (test_analyse(l_base_pile, AN_CASE) == d_faux) && (test_analyse(l_base_pile, AN_IFERR) == d_faux)) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_then; return(d_erreur); } (*l_base_pile).condition = AN_THEN; } else if (strcmp(instruction, "ELSE") == 0) { if (test_analyse(l_base_pile, AN_THEN) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_else; return(d_erreur); } (*l_base_pile).condition = AN_ELSE; } else if (strcmp(instruction, "ELSEIF") == 0) { if (test_analyse(l_base_pile, AN_THEN) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_elseif; return(d_erreur); } (*l_base_pile).condition = AN_ELSEIF; } else if (strcmp(instruction, "END") == 0) { if ((test_analyse(l_base_pile, AN_UNTIL) == d_faux) && (test_analyse(l_base_pile, AN_REPEAT) == d_faux) && (test_analyse(l_base_pile, AN_DEFAULT) == d_faux) && (test_analyse(l_base_pile, AN_SELECT) == d_faux) && (test_analyse(l_base_pile, AN_THEN) == d_faux) && (test_analyse(l_base_pile, AN_ELSE) == d_faux)) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_end; return(d_erreur); } l_base_pile = depilement_analyse(l_base_pile); } else if (strcmp(instruction, "DO") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_DO)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "UNTIL") == 0) { if (test_analyse(l_base_pile, AN_DO) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_until; return(d_erreur); } (*l_base_pile).condition = AN_UNTIL; } else if (strcmp(instruction, "WHILE") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_WHILE)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "REPEAT") == 0) { if (test_analyse(l_base_pile, AN_WHILE) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_while; return(d_erreur); } (*l_base_pile).condition = AN_REPEAT; } else if (strcmp(instruction, "SELECT") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_SELECT)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "CASE") == 0) { if (test_analyse(l_base_pile, AN_SELECT) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_case; return(d_erreur); } if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_CASE)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "DEFAULT") == 0) { if (test_analyse(l_base_pile, AN_SELECT) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_instruction_select; return(d_erreur); } (*l_base_pile).condition = AN_DEFAULT; } else if (strcmp(instruction, "<<") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_UP)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, ">>") == 0) { if (test_analyse(l_base_pile, AN_UP) == d_faux) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_source_incoherent; return(d_erreur); } l_base_pile = depilement_analyse(l_base_pile); } else if (strcmp(instruction, "FOR") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_FOR)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "START") == 0) { if ((l_nouvelle_base_pile = empilement_analyse(l_base_pile, AN_START)) == NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_erreur); } l_base_pile = l_nouvelle_base_pile; } else if (strcmp(instruction, "NEXT") == 0) { if ((test_analyse(l_base_pile, AN_FOR) == d_faux) && (test_analyse(l_base_pile, AN_START) == d_faux)) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_boucle_definie; return(d_erreur); } l_base_pile = depilement_analyse(l_base_pile); } else if (strcmp(instruction, "STEP") == 0) { if ((test_analyse(l_base_pile, AN_FOR) == d_faux) && (test_analyse(l_base_pile, AN_START) == d_faux)) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_erreur_boucle_definie; return(d_erreur); } l_base_pile = depilement_analyse(l_base_pile); } // Invalidation de l'instruction courante dans le fichier rpl-core free((*s_etat_processus).instruction_courante); (*s_etat_processus).instruction_courante = NULL; free(instruction); } (*s_etat_processus).autorisation_empilement_programme = registre; if (l_base_pile != NULL) { liberation_analyse(l_base_pile); (*s_etat_processus).autorisation_empilement_programme = registre; (*s_etat_processus).erreur_compilation = d_ec_source_incoherent; return(d_erreur); } return(d_absence_erreur); } /* ================================================================================ Routine d'échange de deux variables ================================================================================ Entrées : - pointeurs génériques sur les deux variables, - longueur en octet des objets à permuter. -------------------------------------------------------------------------------- Sorties : idem. -------------------------------------------------------------------------------- Effets de bord : néant. ================================================================================ */ void swap(void *variable_1, void *variable_2, unsigned long taille) { register unsigned char *t_var_1; register unsigned char *t_var_2; register unsigned char variable_temporaire; register unsigned long i; t_var_1 = (unsigned char *) variable_1; t_var_2 = (unsigned char *) variable_2; for(i = 0; i < taille; i++) { variable_temporaire = (*t_var_1); (*(t_var_1++)) = (*t_var_2); (*(t_var_2++)) = variable_temporaire; } return; } /* ================================================================================ Routine recherchant l'instruction suivante dans le programme compilé ================================================================================ Entrée : -------------------------------------------------------------------------------- Sortie : -------------------------------------------------------------------------------- Effets de bord : néant. ================================================================================ */ logical1 recherche_instruction_suivante(struct_processus *s_etat_processus) { logical1 drapeau_fin_objet; logical1 erreur; logical1 erreur_analyse; logical1 erreur_format; unsigned char base_binaire; unsigned char *pointeur_caractere_courant; unsigned char *pointeur_caractere_destination; unsigned char *pointeur_debut_instruction; unsigned char *pointeur_fin_instruction; signed long niveau; signed long niveau_annexe; erreur_analyse = d_ex; erreur_format = d_ex; erreur = d_absence_erreur; drapeau_fin_objet = d_faux; niveau = 0; pointeur_caractere_courant = (*s_etat_processus).definitions_chainees + (*s_etat_processus).position_courante; while(((*pointeur_caractere_courant) == d_code_espace) && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { pointeur_caractere_courant++; } if ((*pointeur_caractere_courant) == d_code_fin_chaine) { (*s_etat_processus).instruction_courante = (unsigned char *) malloc(sizeof(unsigned char)); if ((*s_etat_processus).instruction_courante == NULL) { erreur = d_erreur; (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; } else { erreur = d_absence_erreur; (*(*s_etat_processus).instruction_courante) = d_code_fin_chaine; (*s_etat_processus).position_courante = pointeur_caractere_courant - (*s_etat_processus).definitions_chainees; } return(erreur); } pointeur_debut_instruction = pointeur_caractere_courant; while(((*pointeur_caractere_courant) != d_code_espace) && ((*pointeur_caractere_courant) != d_code_fin_chaine) && (drapeau_fin_objet == d_faux) && (erreur_analyse == d_ex) && (erreur_format == d_ex)) { switch(*pointeur_caractere_courant++) { case ']' : case '}' : case ')' : { erreur_format = d_ex_syntaxe; break; } case '"' : { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } while((*pointeur_caractere_courant != '"') && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { if (*pointeur_caractere_courant == '\\') { pointeur_caractere_courant++; switch(*pointeur_caractere_courant) { case '\\' : case '"' : { pointeur_caractere_courant++; break; } } } else { pointeur_caractere_courant++; } } if ((*pointeur_caractere_courant) != '"') { erreur_analyse = d_ex_syntaxe; } if (erreur_analyse == d_ex) { pointeur_caractere_courant++; } drapeau_fin_objet = d_vrai; break; } case '\'' : { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } while(((*pointeur_caractere_courant) != '\'') && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { if ((*pointeur_caractere_courant) == '(') { niveau++; } else if ((*pointeur_caractere_courant) == ')') { niveau--; } pointeur_caractere_courant++; } if ((*pointeur_caractere_courant) != '\'') { erreur_analyse = d_ex_syntaxe; } else if (niveau != 0) { erreur_analyse = d_ex_syntaxe; } if (erreur_analyse == d_ex) { pointeur_caractere_courant++; } drapeau_fin_objet = d_vrai; break; } case '(' : { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } while(((*pointeur_caractere_courant) != ')') && ((*pointeur_caractere_courant) != d_code_fin_chaine) && (erreur_analyse == d_ex)) { switch(*pointeur_caractere_courant) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : case 'e' : case 'E' : case ',' : case '.' : case ' ' : case '-' : case '+' : case ')' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } pointeur_caractere_courant++; } if ((*pointeur_caractere_courant) != ')') { erreur_analyse = d_ex_syntaxe; } if (erreur_analyse == d_ex) { pointeur_caractere_courant++; } drapeau_fin_objet = d_vrai; break; } case '#' : { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } while(((*pointeur_caractere_courant) != 'b') && ((*pointeur_caractere_courant) != 'o') && ((*pointeur_caractere_courant) != 'd') && ((*pointeur_caractere_courant) != 'h') && ((*pointeur_caractere_courant) != d_code_fin_chaine) && (erreur_analyse == d_ex)) { switch(*pointeur_caractere_courant) { case ' ' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : case 'b' : case 'o' : case 'd' : case 'h' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } pointeur_caractere_courant++; } base_binaire = (*pointeur_caractere_courant); pointeur_caractere_courant++; if (((*pointeur_caractere_courant) != d_code_fin_chaine) && ((*pointeur_caractere_courant) != ' ')) { erreur_analyse = d_ex_syntaxe; } else { pointeur_caractere_courant = pointeur_debut_instruction + 1; switch(base_binaire) { case 'b' : case 'o' : case 'd' : case 'h' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } } while(((*pointeur_caractere_courant) != base_binaire) && ((*pointeur_caractere_courant) != d_code_fin_chaine) && (erreur_analyse == d_ex)) { if (base_binaire == 'b') { switch(*pointeur_caractere_courant) { case ' ' : case '0' : case '1' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } } else if (base_binaire == 'o') { switch(*pointeur_caractere_courant) { case ' ' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } } else if (base_binaire == 'd') { switch(*pointeur_caractere_courant) { case ' ' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } } else if (base_binaire != 'h') { erreur_analyse = d_ex_syntaxe; } pointeur_caractere_courant++; } if (erreur_analyse == d_ex) { pointeur_caractere_courant++; } drapeau_fin_objet = d_vrai; break; } case '{' : { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } niveau = 1; niveau_annexe = 0; while((niveau != 0) && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { switch(*pointeur_caractere_courant) { case '{' : { if (niveau_annexe == 0) { niveau++; } else { erreur_analyse = d_ex_syntaxe; } break; } case '}' : { if (niveau_annexe == 0) { niveau--; } else { erreur_analyse = d_ex_syntaxe; } break; } case '[' : { niveau_annexe++; if (niveau_annexe > 2) { erreur_analyse = d_ex_syntaxe; } break; } case ']' : { niveau_annexe--; if (niveau_annexe < 0) { erreur_analyse = d_ex_syntaxe; } break; } case '"' : { if (niveau_annexe == 0) { pointeur_caractere_courant++; while((*pointeur_caractere_courant != '"') && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { if (*pointeur_caractere_courant == '\\') { pointeur_caractere_courant++; switch(*pointeur_caractere_courant) { case '\\' : case '"' : { pointeur_caractere_courant++; break; } } } else { pointeur_caractere_courant++; } } } else { erreur_analyse = d_ex_syntaxe; } break; } } pointeur_caractere_courant++; } if ((niveau != 0) || (niveau_annexe != 0)) { erreur_analyse = d_ex_syntaxe; } drapeau_fin_objet = d_vrai; break; } case '[' : { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } niveau = 1; while((niveau > 0) && ((*pointeur_caractere_courant) != d_code_fin_chaine) && (erreur_analyse == d_ex)) { switch(*pointeur_caractere_courant) { case '[' : { niveau++; break; } case ']' : { niveau--; break; } case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : case '+' : case '-' : case 'e' : case 'E' : case '.' : case ',' : case '(' : case ')' : case ' ' : { break; } default : { erreur_analyse = d_ex_syntaxe; break; } } if (niveau < 0) { erreur_analyse = d_ex_syntaxe; } else if (niveau > 2) { erreur_format = d_ex_syntaxe; } pointeur_caractere_courant++; } if (niveau != 0) { erreur_analyse = d_ex_syntaxe; } drapeau_fin_objet = d_vrai; break; } case '<' : { if (((*s_etat_processus).autorisation_empilement_programme == 'Y') && ((*pointeur_caractere_courant) == '<')) { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } niveau = 1; while((niveau != 0) && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { if (((*pointeur_caractere_courant) == '<') && ((*(pointeur_caractere_courant + 1)) == '<')) { niveau++; pointeur_caractere_courant++; } else if (((*pointeur_caractere_courant) == '>') && ((*(pointeur_caractere_courant + 1)) == '>')) { niveau--; pointeur_caractere_courant++; } else if ((*pointeur_caractere_courant) == '"') { pointeur_caractere_courant++; while((*pointeur_caractere_courant != '"') && ((*pointeur_caractere_courant) != d_code_fin_chaine)) { if (*pointeur_caractere_courant == '\\') { pointeur_caractere_courant++; switch(*pointeur_caractere_courant) { case '\\' : case '"' : { pointeur_caractere_courant++; break; } } } else { pointeur_caractere_courant++; } } } pointeur_caractere_courant++; } if (niveau != 0) { erreur_analyse = d_ex_syntaxe; } drapeau_fin_objet = d_vrai; } else if ((*pointeur_caractere_courant) == '[') { if (pointeur_debut_instruction != (pointeur_caractere_courant - 1)) { erreur_format = d_ex_syntaxe; } pointeur_caractere_courant++; drapeau_fin_objet = d_faux; while(((*pointeur_caractere_courant) != d_code_fin_chaine) && (erreur_format == d_absence_erreur)) { while((*pointeur_caractere_courant) == d_code_espace) { pointeur_caractere_courant++; } if ((*pointeur_caractere_courant) == ']') { if ((*(++pointeur_caractere_courant)) == '>') { drapeau_fin_objet = d_vrai; } else { erreur_analyse = d_ex_syntaxe; } pointeur_caractere_courant++; break; } if ((erreur_format == d_absence_erreur) && (drapeau_fin_objet == d_faux)) { (*s_etat_processus).position_courante = pointeur_caractere_courant - (*s_etat_processus).definitions_chainees; if ((erreur = recherche_instruction_suivante( s_etat_processus)) != d_absence_erreur) { if ((*s_etat_processus).instruction_courante != NULL) { free((*s_etat_processus) .instruction_courante); } return(d_erreur); } pointeur_caractere_courant = (*s_etat_processus) .definitions_chainees + (*s_etat_processus) .position_courante; free((*s_etat_processus).instruction_courante); } } if (drapeau_fin_objet == d_faux) { erreur_analyse = d_ex_syntaxe; drapeau_fin_objet = d_vrai; } } break; } } } pointeur_fin_instruction = pointeur_caractere_courant; (*s_etat_processus).instruction_courante = (unsigned char *) malloc(((pointeur_fin_instruction - pointeur_debut_instruction) + 1) * sizeof(unsigned char)); if ((*s_etat_processus).instruction_courante == NULL) { erreur = d_erreur; (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; } else if (pointeur_fin_instruction != pointeur_debut_instruction) { pointeur_caractere_courant = pointeur_debut_instruction; pointeur_caractere_destination = (*s_etat_processus).instruction_courante; do { *pointeur_caractere_destination++ = *pointeur_caractere_courant++; } while(pointeur_caractere_courant < pointeur_fin_instruction); (*pointeur_caractere_destination) = d_code_fin_chaine; erreur = ((erreur_analyse == d_ex) && (erreur_format == d_ex)) ? d_absence_erreur : d_erreur; (*s_etat_processus).erreur_execution = erreur_analyse; } else { (*(*s_etat_processus).instruction_courante) = d_code_fin_chaine; } (*s_etat_processus).position_courante = pointeur_fin_instruction - (*s_etat_processus).definitions_chainees; return(erreur); } /* ================================================================================ Routine mettant la chaine d'entrée en majuscule ================================================================================ Entrée : pointeur sur une chaine en minuscules. -------------------------------------------------------------------------------- Sortie : pointeur sur la chaine en majuscules. Si le pointeur retourné est nul, il s'est produit une erreur. L'allocation est faite dans la routine. -------------------------------------------------------------------------------- Effets de bord : néant. ================================================================================ */ unsigned char * conversion_majuscule(unsigned char *chaine) { register unsigned char *caractere_courant; register unsigned char *caractere_courant_converti; register unsigned char *chaine_convertie; unsigned long longueur_chaine_plus_terminaison; longueur_chaine_plus_terminaison = 0; caractere_courant = chaine; while((*caractere_courant) != d_code_fin_chaine) { caractere_courant++; longueur_chaine_plus_terminaison++; } caractere_courant = chaine; caractere_courant_converti = chaine_convertie = (unsigned char *) malloc( (longueur_chaine_plus_terminaison + 1) * sizeof(unsigned char)); if (chaine_convertie != NULL) { while((*caractere_courant) != d_code_fin_chaine) { if (isalpha((*caractere_courant))) { (*caractere_courant_converti) = (unsigned char) toupper((*caractere_courant)); } else { (*caractere_courant_converti) = (*caractere_courant); } caractere_courant++; caractere_courant_converti++; } (*caractere_courant_converti) = d_code_fin_chaine; } return(chaine_convertie); } void conversion_majuscule_limitee(unsigned char *chaine_entree, unsigned char *chaine_sortie, unsigned long longueur) { unsigned long i; for(i = 0; i < longueur; i++) { if (isalpha((*chaine_entree))) { (*chaine_sortie) = (unsigned char) toupper((*chaine_entree)); } else { (*chaine_sortie) = (*chaine_entree); } if ((*chaine_entree) == d_code_fin_chaine) { break; } chaine_entree++; chaine_sortie++; } return; } /* ================================================================================ Initialisation de l'état du calculateur Configuration par défaut d'un calculateur HP-28S ================================================================================ Entrée : pointeur sur la structure struct_processus -------------------------------------------------------------------------------- Sortie : néant -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void initialisation_drapeaux(struct_processus *s_etat_processus) { unsigned long i; for(i = 0; i < 31; cf(s_etat_processus, i++)); if ((*s_etat_processus).lancement_interactif == d_vrai) { sf(s_etat_processus, 31); /* LAST autorisé */ } else { cf(s_etat_processus, 31); /* LAST invalidé */ } cf(s_etat_processus, 32); /* Impression automatique */ cf(s_etat_processus, 33); /* CR automatique (disp) */ cf(s_etat_processus, 34); /* Valeur principale (intervalle de déf.) */ sf(s_etat_processus, 35); /* Evaluation symbolique des constantes */ sf(s_etat_processus, 36); /* Evaluation symbolique des fonctions */ sf(s_etat_processus, 37); /* Taille de mot pour les entiers binaires */ sf(s_etat_processus, 38); /* Taille de mot pour les entiers binaires */ sf(s_etat_processus, 39); /* Taille de mot pour les entiers binaires */ sf(s_etat_processus, 40); /* Taille de mot pour les entiers binaires */ sf(s_etat_processus, 41); /* Taille de mot pour les entiers binaires */ sf(s_etat_processus, 42); /* Taille de mot pour les entiers binaires */ /* 37 : bit de poids faible 42 : bit de poids fort Les six drapeaux peuvent être nuls. Dans ce cas, la longueur des mots binaires reste de un bit. */ cf(s_etat_processus, 43); /* Base de numération binaire */ cf(s_etat_processus, 44); /* Base de numération binaire */ /* 43 44 = 00 => décimal 43 44 = 01 => binaire 43 44 = 10 => octal 43 44 = 11 => hexadécimal */ sf(s_etat_processus, 45); /* Affichage multiligne du niveau 1 */ cf(s_etat_processus, 46); /* Réservé */ cf(s_etat_processus, 47); /* Réservé */ /* 46 et 47 réservés sur le calculateur HP28S 46 47 = 00 => système rectangulaire 46 47 = 01 => système cylindrique 46 47 = 10 => système sphérique */ cf(s_etat_processus, 48); /* Séparateur décimal */ cf(s_etat_processus, 49); /* Format des nombres réels */ cf(s_etat_processus, 50); /* Format des nombres réels */ /* 49 50 = 00 => standard 49 50 = 01 => scientifique 49 50 = 10 => virgule fixe 49 50 = 11 => ingénieur */ cf(s_etat_processus, 51); /* Tonalité */ cf(s_etat_processus, 52); /* REDRAW automatique */ cf(s_etat_processus, 53); /* Nombre de chiffres décimaux */ cf(s_etat_processus, 54); /* Nombre de chiffres décimaux */ cf(s_etat_processus, 55); /* Nombre de chiffres décimaux */ cf(s_etat_processus, 56); /* Nombre de chiffres décimaux */ /* 53 : bit de poids faible 56 : bit de poids fort */ cf(s_etat_processus, 57); /* Underflow traité normalement */ cf(s_etat_processus, 58); /* Overflow traité normalement */ sf(s_etat_processus, 59); /* Infinite result traité normalement */ sf(s_etat_processus, 60); /* Angles */ /* 60 = 0 => degrés 60 = 1 => radians */ cf(s_etat_processus, 61); /* Underflow- traité en exception */ cf(s_etat_processus, 62); /* Underflow+ traité en exception */ cf(s_etat_processus, 63); /* Overflow traité en exception */ cf(s_etat_processus, 64); /* Infinite result traité en exception */ } // vim: ts=4