/* cc: Calculette de demo */ #include #include #include #include "mo_tools.h" #include "MoiraLang.h" #include "CalculRules.h" MoiraLang* CalculLoad (); static logical db = TRUE; static logical erreur = FALSE; /*---------------------------------------- Valeurs initiales */ #define MAX_VAR 80 int nbr_var = 0; pstring var_nom [MAX_VAR]; double var_val [MAX_VAR]; /*---------------------------------------- Fonctions numeriques */ #define FF_SIN 0 #define FF_COS 1 #define MAX_FONC 2 pstring fonc_nom [MAX_FONC] = {"sin", "cos"}; /*---------------------------------------- Fonctions */ double calcul_reel (arbre racine); double autre_calcul (arbre racine); /* ======================================================= print_error */ /* == Ecrit un message d'erreur */ void print_error(pstring message, pstring nom) { erreur = TRUE; printf (" *** Erreur : %s %s \n", message, nom); } /* ======================================================= appel_fonction */ /* == Calcule le resultat d'un appel de fonction */ double appel_fonction (pstring nom, arbre racine) { arbre noeud; int nrof; double result, arg; char mess[80]; nrof = al_trouver_chaine (fonc_nom, MAX_FONC, nom); result = 0; noeud = racine; switch (nrof) { case FF_SIN : arg = calcul_reel (noeud); result = sin(arg); break; case FF_COS : arg = calcul_reel (noeud); result = cos(arg); break; default: print_error ("Fonction inconnue :", nom); result=0; } /* End Switch */ return(result); } /* ======================================================= calcul_var */ /* == Rend la valeur initiale d'une variable */ double calcul_var (arbre racine) { arbre noeud; int nro, code; pstring nom; double result; result = 0; nom = aa_ident(racine); if ((nro=al_trouver_chaine (var_nom, nbr_var, nom)) >=0) result = var_val[nro]; else { result = 0; print_error("Variable %s referencee et non initialisee :", nom); } return (result); } /* ======================================================= autre_calcul */ /* == Calcule une expression reelle */ double autre_calcul (arbre racine) { arbre nd1, nd2; double result, r1, r2; int ii, code; if (racine == NIL) return(0.0); code = aa_code (racine); nd1 = aa_fils (racine); nd2 = aa_frere(nd1); result = 1; switch (code) { case KN_Puissance : r1 = calcul_reel (nd1); r2 = calcul_reel (nd2); result = pow(r1, r2); break; case KN_AppelFonction : result = appel_fonction(aa_ident(nd1), nd2); break; /* Feuilles */ case KN_IDENT : result = calcul_var (racine); break; default:; print_error(" Code operation inconnu :", aa_nom_de_code(code)); result = 0; } /* End Switch */ return (result); } /* ======================================================= calcul_reel */ /* == Calcule une expression reelle */ double calcul_reel (arbre racine) { int code = aa_code (racine); arbre nd1 = aa_fils (racine); arbre nd2 = aa_frere(nd1); double result = 1; switch (code) { /* Noeuds d'arite 2 */ case KN_Addition : result = calcul_reel (nd1) + calcul_reel (nd2); break; case KN_Soustraction : result = calcul_reel (nd1) - calcul_reel (nd2); break; case KN_Multiplication : result = calcul_reel (nd1) * calcul_reel (nd2); break; case KN_Division : result = calcul_reel (nd1) / calcul_reel (nd2); break; /* Noeuds d'arite 1 */ case KN_Parentheses : result = calcul_reel (nd1); break; case KN_MoinsUnaire : result = -calcul_reel (nd1); break; /* Feuilles */ case KN_REEL : result = aa_reel(racine); break; case KN_ENTIER : result = aa_entier(racine); break; /* Pour les autres codes ... */ default:; result = autre_calcul (racine); } /* End Switch */ return (result); } /* ======================================================= affecter */ void affecter (arbre racine) { arbre gauche, droite; pstring nom; double result; int nro; /* Initialisations */ erreur = FALSE; gauche = aa_fils (racine); droite = aa_frere(gauche); if (gauche==NIL) { print_error ("Exression vide", ""); return; } nom = aa_ident (gauche); result = calcul_reel (droite); if (erreur) return; printf (" %s = %g\n", nom, result); nro = al_trouver_chaine (var_nom, nbr_var, nom); if (nro>=0) var_val[nro]= result ; else { var_nom[nbr_var] = al_creer_chaine (nom); var_val[nbr_var] = result; nbr_var++; } } /* ======================================================= calcul_ligne */ /* == Point d'entree : Analyse syntaxique et traduction */ void calcul_ligne () { #define SIZE 132 typedef char texpr[SIZE]; MoiraLang* ml = CalculLoad(); // -- Pour charger les "bonnes tables" ml -> SetDebug (1); // -- Pour visualiser l'arbre printf (" +++ Entrez une expression a calculer ...\n"); while (TRUE) { printf (" => "); texpr expression; al_get_line (expression, SIZE, stdin); if (strlen (expression)>0) { arbre racine = ml -> Analyze (expression); if (racine == NIL) al_stop ("Syntaxe incorrecte"); affecter (aa_fils(racine)); /* Travail applicatif */ aa_liberer_arbre (racine); } } } /* ============================================ main */ main() { calcul_ligne (); /* -- Lecture et calcul d'une expression */ }