/***** * * Michael Riff * RPN software version 1.0 Oktob 2013. * * Neudefinition der ursprueglichen mathematischen standard Funktionen. * Hier werden mehrere Funktionsgruppen definiert. Die erste Gruppe * sind die ursprueglichen Funktionnen/Operatoren die jezt mit RPN oder * Postfix Notation arbeiten und mit einen Operanden Stack arbeiten * (HP Taschenrecher). * Eine weitere Gruppe dient dazu diesen Stack zu bedienen (Operand abzulegen) * Eine Gruppe sind Operatoren fuer Boolean Tests die auch mit der RPN arbeiten. * Dazu kommen noch die Verzweigungsfunktionen fuer if else, while und for * Kontroll Strukuren. * Und die fonktionen fuer Variablen Wert manipulation und Parameter auslesen. * * Die Eingelesenen Berechnungen (Scripte) werden als Liste von Referenzen * auf die hier neu definierten Routinen abgespeichert. * Die Ausführung des Script Kodes ist eine Schleife die die Routinen durch ihre in der * Liste gespeicherten Referenzen aufruft. * * Version 1.1: 07 Jan 2014 * corrected nNot to test if argument stack contains at least 1 (not 2) argument. * * Version 1.3: 08 Feb 2014 * Routine Debug uses decimal separator from UX_StdLib.c if USE_ITL is defined. * Added check of status returned by FormatX2Str. * * Version 1.4: 15 Jun 2014 * CalcMaxStack added missing cases of routine that modifies the num of values on * the argument stack, and corrected counting for do while loops. * * Version 1.7: 06 June 2016 * Implemented handling of additional routines that can be called out of the text code. As example * we used the following: print() and print("constant string") that print out * the value of a variable or a string. * Added missing compiler switches. *****/ #include #include "Calculs.h" /* Makro Definierung */ #define PI 3.1415926535897932384650 #define EXP 2.718281828459045 /* Fehler Wert Definierung Im Falle eines Fehlers während der Ausführung wird einen NAN Wert zurückgegeben. */ //#define ValErr pow(2,64)-1 /* ou 0xFFFF FFFF FFFF FFFF */ double ValErr; #define NAN_MASK 0x7FF0000000000000 typedef union { double PtFlottant; unsigned int Brut[2]; } Type_Erreur; Type_Erreur *Conversion; /* Variablen Deklaration */ /* Mit jeder Tabelle wird die Anzahl der gespeicherten Werte. Der Letzte Wert steht dann am Index index - 1. */ /* Argumenten Stack Definierung (Typ HP) -------------------------------------*/ double *Pile; unsigned long nbArg; /* Argumenten Anzahl im Stack */ unsigned long maxArg; /* Speicher Bloc Groesse des Stacks */ /* Angabe der Tabelle der Funktions Referenzen um die Berechnungen Durchzufuehren. Fuer jeder Berechnung wird eine benoetigt. ---------------------------------------------------*/ //double (**Fonction)(void); Commande *Fonction; unsigned long nbFonctions; /* Anzahl der gespeicherten Funktionsreferenzen */ unsigned long maxFonctions; /* Groesse der Funktionsreferenzen Tabelle */ //#define Resa Fonction = (double(**)(void)) calloc(maxFonctions,sizeof(double(*)(void))); /* Definierung des Platzes der ein float in der Funktionsreferezentabelle einnimmt -----------------------------------------------------------------------*/ unsigned int tailleFlottant = sizeof(float) / sizeof(double(*)(void)); #ifdef DEBUG unsigned int tailleDouble = sizeof(double) / sizeof(double(*)(void)); unsigned int tailleuLong = sizeof(unsigned long) / sizeof(double(*)(void)); #endif #ifdef MIT_VAR /* Deklarierung der Tabelle der Variablen --------------------------------------*/ variables *Valeurs; unsigned short nbVar; /* Anzahl der gespeicherten Variablen */ #endif #ifdef ARG_DOUBLE /* Hilfsvariablen fuer die constanten argumente (als double) ---------------------------------------------------*/ double *constValues; long maxConst; unsigned int cntValues; unsigned int tailleEntier = sizeof(int) / sizeof(double(*)(void)); #endif /* Hilfsvariablen fuer die Ausfuehrung -----------------------------------*/ #ifdef Mac Boolean Erreur; #else // typedef enum {false,true} bool; bool Erreur; #endif unsigned long monindex; /* Index wo die Durchfuehrung steht */ #ifdef MIT_IF /* Variablen fuer die if Verzweigungen -----------------------------------*/ /* Stack um die Eingeschachtelten Strukturen zu Verwalten. */ typedef struct ElseEnd { unsigned long aktElse; unsigned long aktEnd; }; struct ElseEnd SpruengeIF[10]; int aktIf; /* Einschachtelungsstufe der Strukturen */ #endif #ifdef MIT_WHILE int whileEinsch; /* Anzahl der eingeschachtelten Strukturen */ #endif /* Parameter der Berechnungen (Namen beginnnen mit p_) Globale Variablen --------------------------*/ /* Aktuelle Werte der Eingabeparameter */ double aktDaten[MAX_PARAM]; /* Neudefinierung der Funktionnen damit Sie Ihr(e) Argument(e) in dem Argumentenstack nehmen und dort das Resultat ablegen. */ /* Standard Operatoren : ======================*/ /* Addition des deux derniers arguments de la pile --------------------------------------------*/ double nPlus(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -1)) + (*(Pile + nbArg -2)); /* Deux arguments consommes et un retourne. */ nbArg--; /* return (double)NULL; */ return 0; } /* Soustraction du dernier argument du précédent ---------------------------------------------*/ double nMoins(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) - (*(Pile + nbArg -1)); /* Deux arguments consommes et un retourne. */ nbArg--; /* return (double)NULL; */ return 0; } /* Multiplication des deux derniers arguments de la pile -------------------------------------------------*/ double nMult(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -1)) * (*(Pile + nbArg -2)); /* Deux arguments consommes et un retourne. */ nbArg--; /* return (double)NULL; */ return 0; } /* Division de l'avant dernier argument de la pile par le dernier --------------------------------------------------------*/ double nDiv(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) / (*(Pile + nbArg -1)); /* Deux arguments consommes et un retourne. */ nbArg--; /* return (double)NULL; */ return 0; } /* Librairien Funktionnen : =========================*/ /* Elevation de l'avant dernier argument de la pile à la puissance dernier argument de la pile ----------------------------------------------------------------------------------*/ double nExpo(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = pow( (*(Pile + nbArg -2)) , (*(Pile + nbArg -1)) ); /* Deux arguments consommés et un retourne. */ nbArg--; /* printf("^ donne %f\n",*(Pile + nbArg -1)); */ /* return (double)NULL; */ return 0; } /* Recine du dernier argument de la pile -----------------------------------*/ double nSqrt(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } (*(Pile + nbArg -1)) = pow((*(Pile + nbArg -1)),0.5); /* return (double)NULL; */ return 0; } /* Sinus du dernier argument de la pile -----------------------------------*/ double nSin(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = sin(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nCos(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = cos(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nTan(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = tan(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } /* Fonctions trigo inverses ---------------------------------------*/ double nAsin(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = asin(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nAcos(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = acos(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nAtan(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = atan(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } /* Logarithme du dernier argument de la pile ---------------------------------------*/ double nLog(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = log(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nExp(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = exp(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } /*Trigo hyperbol du dernier argument de la pile ---------------------------------------*/ double nCosh(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = cosh(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nSinh(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = sinh(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } double nTanh(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = tanh(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } /* Change le signe du dernier argument sur la pile --------------------------------------------*/ double chs(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = -(*(Pile + nbArg -1)); return 0; } /* Fuer die Argumenten Stack Manipulierung : ==========================================*/ /* Ajoute une valeur sur la pile (operande constante) Valeur stockee dans la pile des appels de fonction juste dans la ligne suivante. -----------------------------------------------------*/ double put(void) { #ifndef ARG_DOUBLE /* double *tierceVar; */ float tierceVar; /* *(Pile + nbArg) = ((double)(*(Fonction + monindex))); Ne compile pas */ /* tierceVar = (double*)(Fonction + monindex); *(Pile + nbArg) = *tierceVar; */ tierceVar = (Fonction + monindex+1)->dataf; *(Pile + nbArg) = (double)(tierceVar); #else int tierceIndex; tierceIndex = (Fonction + monindex+1)->idx; *(Pile + nbArg) = constValues[tierceIndex]; #endif nbArg++; /* La(es) ligne(s) suivante contenant la valeur du double ne doit(vent) pas etre executee(s). */ #ifndef ARG_DOUBLE /* monindex += tailleDouble; */ monindex += tailleFlottant; #else monindex += tailleEntier; #endif /* return (double)NULL; */ return 0; } /* Duplication du dernier argument de la pile ---------------------------------------*/ double dup(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg) = *(Pile + nbArg -1); nbArg++; /* return (double)NULL; */ return 0; } /* Supression du dernier argument de la pile ---------------------------------------*/ double drop(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } nbArg--; /* return (double)NULL; */ return 0; } /* Inversion des deux derniers arguments de la pile ---------------------------------------------*/ double swap(void) { double buffer; /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } buffer = *(Pile + nbArg -1); *(Pile + nbArg -1) = *(Pile + nbArg -2); *(Pile + nbArg -2) = buffer; /* return (double)NULL; */ return 0; } /* Bool Operatoren fuer die if : ==============================*/ /* Opérateur et --------------*/ double nAnd(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) && (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur ou --------------*/ double nOr(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) || (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur ou exclusif -----------------------*/ double nXor(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } if( (*(Pile + nbArg -2)) && (*(Pile + nbArg -1)) ) { *(Pile + nbArg -2) = false; } else { *(Pile + nbArg -2) = (*(Pile + nbArg -2)) || (*(Pile + nbArg -1)); } nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur négation --------------------*/ double nNot(void) { /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } *(Pile + nbArg -1) = !(*(Pile + nbArg -1)); /* return (double)NULL; */ return 0; } /* Opérateur inférieur à ---------------------*/ double nLth(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) < (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur supérieur à ---------------------*/ double nGth(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) > (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur inférieur ou égal à ----------------------------*/ double nLeth(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) <= (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur supérieur ou égal à ----------------------------*/ double nGeth(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) >= (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur non égal à --------------------*/ double nNeq(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) != (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } /* Opérateur égal à -----------------*/ double nEq(void) { /* Test si la pile contient au moins deux arguments. */ if (nbArg < 2) { /* Erreur! */ return ValErr; } *(Pile + nbArg -2) = (*(Pile + nbArg -2)) == (*(Pile + nbArg -1)); nbArg--; /* return (double)NULL; */ return 0; } #ifdef MIT_IF /* Verzweigungs Operator an Stelle eines ifs. Die respectiven Indexe des else Zweiges und Ende der Struktur sind in der Reihenfolge gerade nach der Referenz in der Funktionsreferenzen Tabelle gespeichert. ------------------------------------------------*/ double branchif(void) { /* Realise les sauts des structures if au niveau du if par incrementation de l'index des appels de fonction et memorise le saut de la brache else si necessaire. */ /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } /* Les valeurs des sauts sont stockes dans le Tableau des appels de fonction juste apres l'adresse de branchif. */ if (*(Pile + nbArg -1)) { if (NULL != (void*)((Fonction + monindex+2)->idx) ) { /* Cas if, simple incrementation mais memorisation du saut pour le saut du cas else qui est present. Dans branchelse aktIf sera decremente. */ SpruengeIF[aktIf].aktElse = (Fonction + monindex+1)->idx; SpruengeIF[aktIf].aktEnd = (Fonction + monindex+2)->idx; aktIf++; monindex += 2; #ifdef DEBUG printf("Dans branchif %ld %ld \n",SpruengeIF[aktIf-1].aktElse,SpruengeIF[aktIf-1].aktEnd); #endif } else { /* Cas if, simple incrementation et pas de memorisation de saut puisque le cas else n'est pas present */ monindex += 2; #ifdef DEBUG printf("Dans branchif : kein else Zweig\n"); #endif } } else { /* Cas else, saut a la premiere instruction du else (apres branchelse) et pas de memorisation de saut puisque l'execution continue sequentiellement */ monindex = (Fonction + monindex+1)->idx; #ifdef DEBUG printf("Dans branchif NULL NULL et %ld\n",monindex); #endif /* aktIf wird nicht geaendert weil die Ausfuehrung sequentiell weitergeht */ } nbArg--; /* return (double)NULL; */ return 0; } /* Operator an Stelle eines else -------------------------------*/ double branchelse(void) { /* Realise les sauts des structures if au niveau du else par incrementation de l'index des appels de fonction. */ #ifdef DEBUG printf("Dans branchelse %ld %ld : %ld",SpruengeIF[aktIf-1].aktElse,SpruengeIF[aktIf-1].aktEnd,monindex); #endif if (SpruengeIF[aktIf-1].aktEnd != 0 && monindex == SpruengeIF[aktIf-1].aktElse) { /* Saut du cas else */ // monindex = SpruengeIF[aktIf-1].aktEnd -1; //MODIF monindex = SpruengeIF[aktIf-1].aktEnd; /* Wir habe eine Struktur verlassen (Ausfuehrung geht sequentiell weiter, die Spung Indexe brauchen nicht mehr gespeichert werden */ aktIf--; } #ifdef DEBUG printf("\tSaut a %ld\n",monindex+1); #endif /* return (double)NULL; */ return 0; } #endif #ifdef MIT_VAR /* Wert Zuweisungs Operator zu eine Variable. Der letzte Wert auf den ArgumentenStack wird der Variable zugewiesen deren Index in der Variablentabelle gerade nach der Funktionreferenz gespeichert ist. -------------------------------------------------------------------*/ double stovar(void) { unsigned int buffer; /* Test si la pile contient au moins un argument. */ if (nbArg < 1) { /* Erreur! */ return ValErr; } buffer = (Fonction + monindex+1)->idx; #ifdef DEBUG printf("Dans stovar index %ld valeur %f\n",buffer,*(Pile + nbArg - 1)); #endif (Valeurs + buffer)->valeur = *(Pile + nbArg - 1); nbArg--; /* Sauter la valeur juste après (index de la variable qu'il ne faut pas éxécuter) */ monindex++; return 0; } /* Wert Auslese Operator einer Variable. Der Index der Variable in der Variablentabelle ist gerade nach der Funktionreferenz gespeichert. Der ausgelsene Wert wird auf dem Argumentenstack abgelegt. ----------------------------------------------------------*/ double getvar(void) { unsigned int buffer; /* La pile n'a pas besion de contenir d'argument. */ buffer = (Fonction + monindex+1)->idx; #ifdef DEBUG printf("Dans getvar index %ld valeur %f\n",buffer,(Valeurs + buffer)->valeur); #endif *(Pile + nbArg) = (Valeurs + buffer)->valeur; nbArg++; /* Sauter la valeur juste après (index de la variable qu'il ne faut pas éxécuter) */ monindex++; return 0; } #endif #ifdef MIT_WHILE /* Operator fuer While Schleife Dans la liste des pointeurs de fonctions, après le pointeur nwhile est stocké l'index du début de l'expression booléenne du while -------------------------------------------------------------*/ double nwhile(void) { /* Springt zum Ende der Schleife wenn der letzte Argument auf dem Operanden Stack nicht null ist. Zu beachten : monindex wird vor dem naechsten Aufruf nochmal inkrementiert. */ #ifdef DEBUG printf("In while\t"); #endif /* Test ob der Operanden Stack noch mindestens einen Wert beinhaltet */ if (nbArg < 1) { /* Erreur! */ return ValErr; } if (*(Pile + nbArg -1)) { /* In der Schleife Gehen ohne zu vergessen den Index des Ende Der Schleife zu ueberspringen, der gerade nach nwhile gespeichert ist. */ monindex++; #ifdef DEBUG printf("index %ld, fin %ld\n",monindex, (Fonction + monindex)->idx); #endif } else { /* Zum Ende der Schleife gehen Notiz: die End Funktion der Schleife wird nicht Aufgerufen denn monindex vor dem naechsten Aufruf nochmal inkrementiert wird */ // monindex = (unsigned long) (*(Fonction + monindex + 1).idx) - 1; //MODIF monindex = (Fonction + monindex + 1)->idx; #ifdef DEBUG printf("Augang\n"); #endif } nbArg--; return 0; } /* Operator am Ende des While Schleife. Springt immer zum Anfang zurueck Dans la liste des pointeurs de fonctions, après le pointeur endwhile est stocké l'index de fin de la boucle dans la liste. -----------------------------------------------------*/ //double endwhile(void) { provoque intruction trap dans debugger Mac, sinon crash double endloop(void) { /* Springt in allen Faellen zum Anfang der Schleife (Bool Satz des whiles). Zu beachten : monindex wird vor dem naechsten Aufruf nochmal inkrementiert. */ // monindex = (unsigned long) (*(Fonction + monindex + 1).idx) - 1; //MODIF monindex = (Fonction + monindex + 1)->idx; #ifdef DEBUG printf("End while geht auf %ld zurueck\n",monindex); #endif /* Da bei jedem Eingang in der Schleife inkrementiert wird */ whileEinsch--; return 0; } /* Operator fuer eine Repeat ... Until Schleife --------------------------------------*/ double dowhile(void) { /* Springt zum Anfang der Schleife wenn der letzte Operand auf dem Stack "war" ist. Zu beachten : monindex wird vor dem naechsten Aufruf nochmal inkrementiert. */ /* Test ob der Operanden Stack noch mindestens einen Wert beinhaltet */ if (nbArg < 1) { /* Erreur! */ return ValErr; } if (*(Pile + nbArg -1)) { /* Zum Anfang der Schleife gehen */ // monindex = (unsigned long) (*(Fonction + monindex + 1).idx) - 1; //MODIF monindex = (Fonction + monindex + 1)->idx; #ifdef DEBUG printf("Dowhile geht auf %ld zurueck\n",monindex); #endif } else { /* Sonst wird die Ausfuehrung sequentiell fortgesetzt ohne zu vergessen den nach dowhile gespeicherten Index zu ueberspringen */ monindex++; } #ifdef DEBUG printf("Dowhile verlassen %ld\n",monindex); #endif nbArg--; return 0; } #endif #ifdef MIT_FOR /* Fonctions pour optimiser l'incrémentation/décrémentation de l'index des boucles for que l'on implémentera à l'aide d'un while La variable considérée est identifiée par son index dans la table des variables stocké juste après le pointeur de cette fonction. ------------------------------------------------------------------*/ double incVar(void) { ( Valeurs + (Fonction + monindex + 1)->idx )->valeur++; /* Den danach gespeicherten Variablenindex ueberspringen */ monindex++; return 0; } double decVar(void){ ( Valeurs + (Fonction + monindex + 1)->idx )->valeur--; /* Den danach gespeicherten Variablenindex ueberspringen */ monindex++; return 0; } #endif /* Eingabeparameter spezifische Funktionnen : ================================*/ /* Zum auslesen der Parameterwerte (in aktDaten gespeichert) */ double readParam(void) { /* Gerade nach der Referenz zur dieser Funktion ist der Index des Parameters in aktDaten (0 bis MAX_PARAM) */ /* Optional tester si valeur inde correcte if ((Fonction + monindex+1)->idx < MAX_PARAM)*/ *(Pile + nbArg) = aktDaten[(Fonction + monindex+1)->idx]; //printf("Dans read p_%ld valeur %f.\n",(Fonction + monindex+1)->idx,*(Pile + nbArg)); nbArg++; /* Sauter la valeur juste après (index de la variable qu'il ne faut pas éxécuter) */ monindex++; return 0; } /* Special routines to perform other actions whithin the software As an example we define printing routines ================================*/ #ifdef ADD_FUNCT /* Temporäre Tabelle um die durch der print Funktion anzuzeigende Texte zu speichern */ char **Msges; #define SIZE_MSGES 5 int numMsges; int maxMsges; double printMsg() { char *msg = Msges[(Fonction + monindex+1)->idx]; printf("- %s\n",msg); monindex++; return 0; } double printVar() { printf("-%s:%g\n", Valeurs[(Fonction + monindex+1)->idx].nom, Valeurs[(Fonction + monindex+1)->idx].valeur); monindex++; return 0; } #endif /* Initialisierung : ==================*/ int InitCalc(void) { #ifdef ADD_FUNCT int idx; #endif nbArg = 0; nbFonctions = 0; #ifdef ARG_DOUBLE cntValues = 0; #endif /* Table pour les references sur les fonctions. */ // ToDo read out of input file maxFonctions = 1000; Resa; if(Fonction == NULL) { printf("Allocation1 echouee\n"); Pile = NULL; #ifdef MIT_VAR Valeurs = NULL; #endif return 1; } /* Table pour les arguments. */// ToDo read out of input file maxArg = 100; Pile = (double*)malloc(maxArg*sizeof(double)); if(Pile == NULL) { printf("Allocation2 echouee\n"); free(Fonction); Fonction = NULL; #ifdef MIT_VAR Valeurs = NULL; #endif return 1; } #ifdef MIT_VAR // ToDo read size out of input file nbVar = 0; Valeurs = (variables*)malloc(50*sizeof(variables)); if(Valeurs == NULL) { printf("Allocation3 echouee\n"); free(Fonction); Fonction = NULL; free(Pile); Pile = NULL; return 1; } /* Anlegen der Variable fuer Fehler Wert */ // ValErr = pow(2.0,64.0)-1; ValErr = pow(-1,0.5); // NAN Conversion = (Type_Erreur*)(&ValErr); Conversion->Brut[0] = 0x7FF00000; Conversion->Brut[1] = 0x00000001; Valeurs->valeur = ValErr; strcpy(Valeurs->nom,"Fehler"); nbVar = 1; #endif #ifdef ADD_FUNCT numMsges = 0; maxMsges = 0; Msges = (char**)malloc(SIZE_MSGES); if (Msges == NULL) { printf("Allocation 4 échouée\n"); free(Valeurs); Valeurs = NULL; free(Fonction); Fonction = NULL; free(Pile); Pile = NULL; return 1; } // Do not allocate the buffers here! // They will be allocated during the parsig operation. for (idx=0; idxcmd()); /* Test possible pour cas d'erreur */ /* In den Verzweigungsmethoden branchif u. branchelse ist dieser Vorgang berugsichtigt worden */ monindex++; } if (Erreur) { printf("Erreur d'execution\n"); } else { #ifdef DEBUG printf("Fin %ld\n",nbArg); #endif } /* Retourner le resultat de la pile */ return *(Pile + nbArg -1); } /* En cas d'erreur de syntaxe lors de la lecture des formules, cette procédure génère un code court qui simplement retourne un code indiquant une erreur lors de l'éxécution. =================================================*/ extern int indexPuffer; void ExecError(void) { #ifdef ARG_DOUBLE cntValues = 0; #endif #ifdef MIT_VAR nbVar = 1; #endif indexPuffer = 0; #ifdef MIT_VAR Fonction->cmd = getvar; (Fonction+1)->idx = 0; nbFonctions = 2; #else TBD #endif // Valeurs->valeur = ValErr; // strcpy(Valeurs->nom,"Fehler"); } /* Pour calculer la taille de la pile nécessaire au calcul : =================================================*/ int CalcMaxStack(unsigned long startInst, unsigned long endInst, int *aktSize) { unsigned long i; int Size, maxSize=0; Size = 0; for(i=startInst;i<=endInst;i++) { if ((Fonction + i)->cmd == put) { Size++; // Constant value put on the stack i++; #ifdef MIT_VAR } else if ((Fonction + i)->cmd == stovar) { Size--; // Value taken from stack and put into variable table i++; } else if ((Fonction + i)->cmd == getvar) { Size++; i++; #endif #ifdef MIT_FOR } else if ((Fonction + i)->cmd == incVar) { i++; } else if ((Fonction + i)->cmd == decVar) { i++; #endif #ifdef MIT_IF } else if ((Fonction + i)->cmd == branchif) { int ifSize, elseSize, tmpSize1, tmpSize2; Size--; // One Boolean argument taken from stack if ((void*)(Fonction + i+2)->idx != NULL) { // Wir haben einen else zweig ifSize = CalcMaxStack(i+3, (Fonction + i+1)->idx-1, &tmpSize1); // elseSize = CalcMaxStack((unsigned long)(*(Fonction + i+1)), (unsigned long)(*(Fonction + i+2))-1, &tmpSize2); //MODIF elseSize = CalcMaxStack((Fonction + i+1)->idx+1, (Fonction + i+2)->idx, &tmpSize2); if (tmpSize1 != tmpSize2) { printf("Error if & else branch have != sizes\n"); tmpSize1 = tmpSize1>tmpSize2?tmpSize1:tmpSize2; } ifSize = ifSize>elseSize?ifSize:elseSize; maxSize = maxSize>(Size+ifSize)?maxSize:(Size+ifSize); // i = (unsigned long)(*(Fonction + i+2)) -1; // Go to instruction after else branch (!!! i will be incremented 1) //MODIF i = (Fonction + i+2)->idx; // Go to instruction after else branch (!!! i will be incremented 1) } else { // Keinen else zweig vorhanden ifSize = CalcMaxStack(i+3, (Fonction + i+2)->idx, &tmpSize1); if (tmpSize1 != 0) printf("Error if only branch changes stack size\n"); maxSize = maxSize>(Size+ifSize)?maxSize:(Size+ifSize); i = (Fonction + i+1)->idx -1; // Go to instruction after else branch (!!! i will be incremented 1) } Size += tmpSize1; } else if ((Fonction + i)->cmd == branchelse) { printf("Error else found\n"); #endif #ifdef MIT_WHILE } else if ((Fonction + i)->cmd == nwhile) { int whileSize, tmpSize; Size--; // One Boolean argument taken from stack // whileSize = CalcMaxStack(i+2, (unsigned long)(*(Fonction + i+1)) -3); //MODIF whileSize = CalcMaxStack(i+2, (Fonction + i+1)->idx -2, &tmpSize); // i = (unsigned long)(*(Fonction + i+1)) -1; // Go to instruction after loop end (!!! i will be incremented 1); //MODIF i = (Fonction + i+1)->idx; // Go to instruction after loop end (!!! i will be incremented 1); if (0 != tmpSize) printf("Pb While loop adds arguments on stack\n"); Size += tmpSize; maxSize = maxSize>(Size+whileSize)?maxSize:(Size+whileSize); // } else if ((*(Fonction + i)) == endwhile) { } else if ((Fonction + i)->cmd == endloop) { printf("Error endloop found\n"); i++; } else if ((Fonction + i)->cmd == dowhile) { int doSize, tmpSize; Size--; // One Boolean argument taken from stack // Do not add doSize as the loop and test have been parsed. doSize = CalcMaxStack((Fonction + i+1)->idx+1, i-1, &tmpSize); i++; if (0 != tmpSize) printf("Pb Do While loop adds arguments on stack\n"); // maxSize = doSize>maxSize?doSize:maxSize; #endif } else if ((Fonction + i)->cmd == nPlus) { Size--; } else if ((Fonction + i)->cmd == nMoins) { Size--; } else if ((Fonction + i)->cmd == nMult) { Size--; } else if ((Fonction + i)->cmd == nDiv) { Size--; } else if ((Fonction + i)->cmd == nExpo) { Size--; // } else if ((*(Fonction + i)) == chs) { } else if ((Fonction + i)->cmd == nLeth) { Size--; } else if ((Fonction + i)->cmd == nLth) { Size--; } else if ((Fonction + i)->cmd == nGeth) { Size--; } else if ((Fonction + i)->cmd == nGth) { Size--; } else if ((Fonction + i)->cmd == nEq) { Size--; } else if ((Fonction + i)->cmd == nNeq) { Size--; } else if ((Fonction + i)->cmd == readParam) { Size++; i++; } else if ((Fonction + i)->cmd == dup) { Size++; } else if ((Fonction + i)->cmd == drop) { Size--; // } else if ((*(Fonction + i)) == swap) { } else if ((Fonction + i)->cmd == nAnd) { Size--; } else if ((Fonction + i)->cmd == nOr) { Size--; } else if ((Fonction + i)->cmd == nXor) { Size--; // } else if ((*(Fonction + i)) == nNot) { } else { // printf("%d\tAutre\n",i); } maxSize = maxSize>Size?maxSize:Size; } // In case we have a do while loop, the recursive call is doe with endInst // just before the dowhile command that "consumes" one argument. if ((Fonction + endInst+1)->cmd == dowhile) --Size; *aktSize = Size; return maxSize; } /* Pour vérifier consistance du code : sauts restent dans le code, index variables dans plage de valeurs =================================================*/ #include "Parser.h" Boolean checkConsist(Grph_struct *Graph) { int instIdx; int tmpIdx; for(instIdx=0; instIdx < Graph->execSize ;instIdx++) { #ifdef MIT_IF if (branchif == Graph->Rechnung[instIdx].cmd) { // The following 2 values are indexes of the strart of the else branch // and the end of it. if (Graph->Rechnung[++instIdx].idx >= Graph->execSize || Graph->Rechnung[instIdx].idx <= instIdx) return true; // If second index != 0, we have an else branch, and instruction before else branch is branchelse // The first index after the branchif instruction is the position of the branchelse instruction if (0 != Graph->Rechnung[++instIdx].idx && branchelse != Graph->Rechnung[Graph->Rechnung[instIdx-1].idx].cmd) return true; if (Graph->Rechnung[instIdx].idx >= Graph->execSize || (0 != Graph->Rechnung[++instIdx].idx && Graph->Rechnung[instIdx].idx <= instIdx)) return true; #endif #ifdef ARG_DOUBLE } else if (put == Graph->Rechnung[instIdx].cmd) { // The following value is the index in the constants array. if (Graph->Rechnung[++instIdx].idx >= Graph->numConsts) return true; #endif } else if (readParam == Graph->Rechnung[instIdx].cmd) { if (Graph->Rechnung[++instIdx].idx > Graph->parmAnzahl) return true; #ifdef MIT_VAR } else if (stovar == Graph->Rechnung[instIdx].cmd) { // Check if following variable index is in range if (Graph->Rechnung[++instIdx].idx >= Graph->numVar) return true; } else if (getvar == Graph->Rechnung[instIdx].cmd) { if (Graph->Rechnung[++instIdx].idx >= Graph->numVar) return true; #endif #ifdef MIT_WHILE } else if (nwhile == Graph->Rechnung[instIdx].cmd) { // The following value is the index of the end of the loop if (Graph->Rechnung[++instIdx].idx >= Graph->execSize || Graph->Rechnung[instIdx].idx <= instIdx) return true; if (endloop != Graph->Rechnung[Graph->Rechnung[instIdx].idx-1].cmd) return true; } else if (endloop == Graph->Rechnung[instIdx].cmd) { // The following value is the index of the beginning of the loop if(Graph->Rechnung[++instIdx].idx >= instIdx) return true; // Search for the corresponding while command for(tmpIdx=Graph->Rechnung[instIdx].idx; tmpIdx<(instIdx-1) && nwhile!=Graph->Rechnung[tmpIdx].cmd; ++tmpIdx); if (tmpIdx==(instIdx-1)) return true; if (Graph->Rechnung[tmpIdx+1].idx != instIdx) return true; } else if (dowhile == Graph->Rechnung[instIdx].cmd) { // The following value is the index of the beginning of the loop if (Graph->Rechnung[++instIdx].idx >= instIdx) return true; #endif #ifdef MIT_FOR } else if (incVar == Graph->Rechnung[instIdx].cmd) { // Check if following variable index is in range if (Graph->Rechnung[++instIdx].idx >= Graph->numVar) return true; } else if (decVar == Graph->Rechnung[instIdx].cmd) { // Check if following variable index is in range if (Graph->Rechnung[++instIdx].idx >= Graph->numVar) return true; #endif #ifdef ADD_FUNCT } else if (printMsg == Graph->Rechnung[instIdx].cmd) { // Check if following string index is in range if (Graph->Rechnung[++instIdx].idx >= Graph->numMsg) return true; } else if (printVar == Graph->Rechnung[instIdx].cmd) { // Check if following variable index is in range if (Graph->Rechnung[++instIdx].idx >= Graph->numVar) return true; #endif } } return false; } #ifdef MAC_UI Str63 TextLine; unsigned int colNum; #endif #ifdef MAC_UI extern int aktGraphik; /* Variables pour la conversion de nombres en texte ************************************************************/ #include Str63 numBuffer; #ifdef USE_FORMATX2STR /* Access to system resource to have settings for numbers */ Itl4Handle interRes; long offset; long length; NumberParts *partsTble; /* Format definition: Positive ; Negative : 0 */ Str255 formatDef = "\p#######.####;-#######.####;0.0"; NumFormatString formatRec; /* Or Better reuse already defined data un UX_StdLib.c as done in Display.c // Définies dans UX_StdLib.c extern NumberParts *partsTbl; extern NumFormatString formatRecD; */ long double dblValue; extended80 xValueSrc; #else const char dec2char[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; double dblValue; #endif #ifdef USE_ITL // Defined in UX_StdLib.c extern char decSeparat; #endif Str63 sValueDst; Boolean quitter; EventRecord event; Point Cellule; short type; ControlHandle Controle; int idx; /* Fonctions et variables pour l'affichage de la fenêtre dans lequel le code éxécutable va être affiché. ************************************************************/ #include #define LARG_ASCENS 15 #define BORD 6 #define MARGE 20 extern OSErr erreur; Rect LogBounds; WindowPtr WinLog; ControlHandle Ascens; FontInfo infoTxt; TEHandle TextCode; Str63 TextLine; int visLines; #endif /* Pour Debugger affichage du contenu de la liste d'instructions : =================================================*/ void Debug(void) { int i; #ifndef ARG_DOUBLE float tier; #else #ifndef MAC_UI double tier; #else #ifdef ADD_FUNCT int len; #endif #endif #endif #ifndef MAC_UI for(i=0;icmd == put) { printf("%d\tput\t",i); i++; #ifndef ARG_DOUBLE tier = (Fonction + i)->dataf; printf("\t%f\n",tier); #else tier = constValues[(Fonction + i)->idx]; printf("\t%g\n",tier); #endif } else if( (Fonction + i)->cmd == stovar) { printf("%d\tstovar\t",i); printf("\t%d\n",(Fonction + ++i)->idx); } else if( (Fonction + i)->cmd == getvar) { printf("%d\tgetvar\t",i); printf("\t%d\n",(Fonction + ++i)->idx); #ifdef MIT_FOR } else if( (Fonction + i)->cmd == incVar) { printf("%d\tincVar\t",i); i++; printf("\t%ld\n",(Fonction + i)->idx); } else if( (Fonction + i)->cmd == decVar) { printf("%d\tdecVar\t",i); i++; printf("\t%d\n",(Fonction + i)->idx); #endif } else if( (Fonction + i)->cmd == readParam) { printf("%d\tget\t",i); printf("\t%d\n",(Fonction + ++i)->idx); #ifdef MIT_IF } else if( (Fonction + i)->cmd == branchif) { printf("%d\tif\t",i); printf("\t%d\t",(Fonction + ++i)->idx); printf("\t%d\n",(Fonction + ++i)->idx); } else if( (Fonction + i)->cmd == branchelse) { printf("%d\telse\n",i); #endif #ifdef MIT_WHILE } else if( (Fonction + i)->cmd == nwhile) { printf("%d\twhile\t",i); printf("\t%d\n",(*(Fonction + ++i)).idx); // } else if( (*(Fonction + i)) == endwhile) { } else if( (Fonction + i)->cmd == endloop) { printf("%d\tend\t",i); printf("\t%d\n",(*(Fonction + ++i)).idx); } else if( (Fonction + i)->cmd == dowhile) { printf("%d\tdowhile\t",i); printf("\t%d\n",(*(Fonction + ++i)).idx); #endif } else if( (Fonction + i)->cmd == nPlus) { printf("%d\tplus\n",i); } else if( (Fonction + i)->cmd == nMoins) { printf("%d\tmoins\n",i); } else if( (Fonction + i)->cmd == nMult) { printf("%d\t*\n",i); } else if( (Fonction + i)->cmd == nDiv) { printf("%d\t/\n",i); } else if( (Fonction + i)->cmd == chs) { printf("%d\tchs\n",i); } else if( (Fonction + i)->cmd == nExpo) { printf("%d\tpow\n",i); } else if( (Fonction + i)->cmd == nSqrt) { printf("%d\tsqrt\n",i); } else if( (Fonction + i)->cmd == nLog) { printf("%d\tlog\n",i); } else if( (Fonction + i)->cmd == nExp) { printf("%d\texp\n",i); } else if( (Fonction + i)->cmd == nSin) { printf("%d\tsin\n",i); } else if( (Fonction + i)->cmd == nCos) { printf("%d\tcos\n",i); } else if( (Fonction + i)->cmd == nTan) { printf("%d\ttan\n",i); } else if( (Fonction + i)->cmd == nCosh) { printf("%d\tcosh\n",i); } else if( (Fonction + i)->cmd == nSinh) { printf("%d\tsinh\n",i); } else if( (Fonction + i)->cmd == nTanh) { printf("%d\ttanh\n",i); } else if( (Fonction + i)->cmd == nAsin) { printf("%d\tasinh\n",i); } else if( (Fonction + i)->cmd == nAcos) { printf("%d\tacos\n",i); } else if( (Fonction + i)->cmd == nAtan) { printf("%d\tatan\n",i); } else if( (Fonction + i)->cmd == nLeth) { printf("%d\t<=\n",i); } else if( (Fonction + i)->cmd == nLth) { printf("%d\t<\n",i); } else if( (Fonction + i)->cmd == nGeth) { printf("%d\t>=\n",i); } else if( (Fonction + i)->cmd == nGth) { printf("%d\t>\n",i); } else if( (Fonction + i)->cmd == nEq) { printf("%d\t==\n",i); } else if( (Fonction + i)->cmd == nNeq) { printf("%d\t!=\n",i); } else if( (Fonction + i)->cmd == nAnd) { printf("%d\t&&\n",i); } else if( (Fonction + i)->cmd == nOr) { printf("%d\t||\n",i); } else if( (Fonction + i)->cmd == nXor) { printf("%d\t^\n",i); } else if( (Fonction + i)->cmd == nNot) { printf("%d\t!\n",i); // À continuer ... } else if( (Fonction + i)->cmd == dup) { printf("%d\tdup\n",i); #ifdef ADD_FUNCT } else if( (Fonction + i)->cmd == printMsg) { printf("%d\tprintMsg %s\n", i, Msges[(Fonction + ++i)->idx]); } else if( (Fonction + i)->cmd == printVar) { printf("%d\tprintVar %s\n", i, Valeurs[(Fonction + ++i)->idx].nom); #endif } else { printf("%d\tAutre\n",i); } } #else #ifdef USE_FORMATX2STR IUGetItlTable(iuSystemScript, iuNumberPartsTable, (Handle*)(&interRes), &offset, &length); partsTble = (NumberPartsPtr)((SInt32) (*interRes) + offset); // BlockMove("#######.####;-#######.####;0.0", formatDef+1, 30); // *formatDef = 30; #ifdef USE_ITL if ('.' != decSeparat) { for(i=1; i<=formatDef[0]; i++) { if ('.' == formatDef[i]) { formatDef[i] = decSeparat; } } } #endif erreur = Str2Format(formatDef, partsTble, &formatRec); if (erreur) { ParamText("\pStr2Format Error","\pBad formatDef string","\p","\pStop"); i = StopAlert(128, NULL); return; } #endif GetFontInfo(&infoTxt); visLines = (int)floor(800.0 / (double)(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); // visLines = (short)floor(800.0 / ((*TextCode)->lineHeight + (*TextCode)->fontAscent)); SetRect(&LogBounds, 800, 50, 1080, 54+visLines*(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); // SetRect(&LogBounds, 100, 400, 1050, 400+visLines*((*TextCode)->lineHeight + (*TextCode)->fontAscent)); WinLog = NewWindow(NULL, &LogBounds, "\pLog", true, documentProc, (WindowPtr)-1, TRUE, 0L); SetPort(WinLog); SetRect(&LogBounds, 280-LARG_ASCENS, 4, 280, 4+visLines*(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); Ascens = NewControl(WinLog, &LogBounds, "\p", true, 0, 0, 0, scrollBarProc, 0L); SetRect(&LogBounds, 0, 0, 1080-LARG_ASCENS,visLines*(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); // En coordonnˆ©es locales InsetRect(&LogBounds, 4, 4); TextCode = TENew(&LogBounds, &(WinLog->portRect)); BlockMove("Code éxécutable de graphique: ", TextLine, 30); NumToString(aktGraphik, numBuffer); BlockMove(numBuffer+1, TextLine+30, numBuffer[0]); TextLine[30+numBuffer[0]] = '\r'; TESetText(TextLine, 31+numBuffer[0], TextCode); for(i=0;icmd == put) { BlockMove("\tput\t", TextLine+colNum, 5); colNum +=5; ++i; #ifdef USE_FORMATX2STR #ifndef ARG_DOUBLE dblValue = (long double)((Fonction + i)->dataf); #else dblValue = (long double)(constValues[(Fonction + i)->idx]); #endif ldtox80 ( &dblValue, &xValueSrc ); erreur = FormatX2Str(&xValueSrc, &formatRec, partsTble, sValueDst); if (erreur) { ParamText("\pPut","\pFormatStr2X",sValueDst,"\perror"); StopAlert(128, NULL); } #else #ifndef ARG_DOUBLE dblValue = (double)((Fonction + i)->dataf); #else dblValue = constValues[(Fonction + i)->idx]; #endif { int exp, coefd, lIdx, idxTmp; idxTmp = 1; if (0>dblValue) { sValueDst[idxTmp++] = '-'; dblValue = -dblValue; } exp = (int)floor(log10(dblValue)); // Convert integer part if ( 0<=exp ) { // dblValue >= 1.0 for (lIdx=exp; lIdx>=0; lIdx--) { coefd = floor(dblValue / pow(10,lIdx)); dblValue -= coefd*pow(10,lIdx); sValueDst[idxTmp++] = dec2char[coefd]; } // Safety check if (dblValue >= 1.0) { // Pb Debugger(); sValueDst[0] = idxTmp-1; } } else { // dlbBuf < 1.0 sValueDst[idxTmp++] = '0'; } #ifndef USE_ITL sValueDst[idxTmp++] = '.'; #else sValueDst[idxTmp++] = decSeparat; #endif // Convert fractionnary part lIdx = 1; while( pow(10,exp-10) < dblValue ) { coefd = floor(dblValue * pow(10, lIdx)); dblValue -= coefd/pow(10,lIdx); sValueDst[idxTmp++] = dec2char[coefd]; lIdx++; } sValueDst[0] = idxTmp-1; } #endif *(TextLine+colNum) = '\t'; colNum++; BlockMove(sValueDst+1, TextLine+colNum, sValueDst[0]); colNum += sValueDst[0]; } else if( (Fonction + i)->cmd == stovar) { BlockMove("\tstovar\t", TextLine+colNum, 8); colNum += 8; ++i; BlockMove(Valeurs[(Fonction + i)->idx].nom, TextLine+colNum, strlen(Valeurs[(Fonction + i)->idx].nom)); colNum += strlen(Valeurs[(Fonction + i)->idx].nom); } else if( (Fonction + i)->cmd == getvar) { BlockMove("\tgetvar\t", TextLine+colNum, 8); colNum += 8; ++i; BlockMove(Valeurs[(Fonction + i)->idx].nom, TextLine+colNum, strlen(Valeurs[(Fonction + i)->idx].nom)); colNum += strlen(Valeurs[(Fonction + i)->idx].nom); #ifdef MIT_FOR } else if( (Fonction + i)->cmd == incVar) { BlockMove("\tincvar\t", TextLine+colNum, 8); colNum += 8; ++i; BlockMove(Valeurs[(Fonction + i)->idx].nom, TextLine+colNum, strlen(Valeurs[(Fonction + i)->idx].nom)); colNum += strlen(Valeurs[(Fonction + i)->idx].nom); } else if( (Fonction + i)->cmd == decVar) { BlockMove("\tdecvar\t", TextLine+colNum, 8); colNum += 8; ++i; BlockMove(Valeurs[(Fonction + i)->idx].nom, TextLine+colNum, strlen(Valeurs[(Fonction + i)->idx].nom)); colNum += strlen(Valeurs[(Fonction + i)->idx].nom); #endif } else if( (Fonction + i)->cmd == readParam) { BlockMove("\tget param\t", TextLine+colNum, 11); colNum += 11; ++i; NumToString((Fonction + i)->idx, sValueDst); BlockMove(sValueDst+1, TextLine+colNum, sValueDst[0]); colNum += sValueDst[0]; #ifdef MIT_IF } else if( (Fonction + i)->cmd == branchif) { BlockMove("\tif\t", TextLine+colNum, 4); colNum += 4; ++i; NumToString((Fonction + i)->idx, numBuffer); BlockMove(numBuffer+1, TextLine+colNum, numBuffer[0]); colNum += numBuffer[0]; *(TextLine+colNum) = '\t'; colNum++; ++i; NumToString((Fonction + i)->idx, numBuffer); BlockMove(numBuffer+1, TextLine+colNum, numBuffer[0]); colNum += numBuffer[0]; } else if( (Fonction + i)->cmd == branchelse) { BlockMove("\telse", TextLine+colNum, 5); colNum += 5; #endif #ifdef MIT_WHILE } else if( (Fonction + i)->cmd == nwhile) { BlockMove("\twhile\t", TextLine+colNum, 7); colNum += 7; ++i; NumToString((*(Fonction + i)).idx, numBuffer); BlockMove(numBuffer+1, TextLine+colNum, numBuffer[0]); colNum += numBuffer[0]; // } else if( (*(Fonction + i)) == endwhile) { } else if( (Fonction + i)->cmd == endloop) { BlockMove("\tend\t", TextLine+colNum, 5); colNum += 5; ++i; NumToString((*(Fonction + i)).idx, numBuffer); BlockMove(numBuffer+1, TextLine+colNum, numBuffer[0]); colNum += numBuffer[0]; } else if( (Fonction + i)->cmd == dowhile) { BlockMove("\tdowhile\t", TextLine+colNum, 9); colNum += 9; i++; NumToString((*(Fonction + i)).idx, numBuffer); BlockMove(numBuffer+1, TextLine+colNum, numBuffer[0]); colNum += numBuffer[0]; #endif } else if( (Fonction + i)->cmd == nPlus) { BlockMove("\tplus\t", TextLine+colNum, 6); colNum += 6; } else if( (Fonction + i)->cmd == nMoins) { BlockMove("\tmoins\t", TextLine+colNum, 7); colNum += 7; } else if( (Fonction + i)->cmd == nMult) { BlockMove("\t*\t", TextLine+colNum, 3); colNum += 3; } else if( (Fonction + i)->cmd == nDiv) { BlockMove("\t/\t", TextLine+colNum, 3); colNum += 3; } else if( (Fonction + i)->cmd == chs) { BlockMove("\tchs\t", TextLine+colNum, 5); colNum += 5; } else if( (*(Fonction + i)->cmd) == nExpo) { BlockMove("\tpow", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nSqrt) { BlockMove("\tsqrt", TextLine+colNum, 5); colNum += 5; } else if( (*(Fonction + i)->cmd) == nLog) { BlockMove("\tlog", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nExp) { BlockMove("\texp", TextLine+colNum, 4); colNum += 4; } else if( (*(Fonction + i)->cmd) == nSin) { BlockMove("\tsin", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nCos) { BlockMove("\tcos", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nTan) { BlockMove("\ttan", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nCosh) { BlockMove("\tcosh", TextLine+colNum, 5); colNum += 5; } else if( (Fonction + i)->cmd == nSinh) { BlockMove("\tsinh", TextLine+colNum, 5); colNum += 5; } else if( (Fonction + i)->cmd == nTanh) { BlockMove("\ttanh", TextLine+colNum, 5); colNum += 5; } else if( (Fonction + i)->cmd == nAsin) { BlockMove("\tasin", TextLine+colNum, 5); colNum += 5; } else if( (Fonction + i)->cmd == nAcos) { BlockMove("\tacos", TextLine+colNum, 5); colNum += 5; } else if( (Fonction + i)->cmd == nAtan) { BlockMove("\tatan", TextLine+colNum, 5); colNum += 5; } else if( (Fonction + i)->cmd == nLeth) { BlockMove("\t<=\t", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nLth) { BlockMove("\t<\t", TextLine+colNum, 3); colNum += 3; } else if( (Fonction + i)->cmd == nGeth) { BlockMove("\t>=\t", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nGth) { BlockMove("\t>\t", TextLine+colNum, 3); colNum += 3; } else if( (Fonction + i)->cmd == nEq) { BlockMove("\t==\t", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nNeq) { BlockMove("\t!=", TextLine+colNum, 3); colNum += 3; } else if( (Fonction + i)->cmd == dup) { BlockMove("\tdup", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nAnd) { BlockMove("\tand", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nOr) { BlockMove("\tor", TextLine+colNum, 3); colNum += 3; } else if( (Fonction + i)->cmd == nXor) { BlockMove("\txor", TextLine+colNum, 4); colNum += 4; } else if( (Fonction + i)->cmd == nNot) { BlockMove("\t!", TextLine+colNum, 2); colNum += 2; #ifdef ADD_FUNCT } else if( (Fonction + i)->cmd == printMsg) { BlockMove("\tprint\t", TextLine+colNum, 7); colNum += 7; i++; len = strlen(Msges[(*(Fonction + i)).idx]); BlockMove(Msges[(*(Fonction + i)).idx], TextLine+colNum, len); colNum += len; } else if( (Fonction + i)->cmd == printVar) { BlockMove("\tprint\t", TextLine+colNum, 7); colNum += 7; i++; len = strlen(Valeurs[(*(Fonction + i)).idx].nom); BlockMove(Valeurs[(*(Fonction + i)).idx].nom, TextLine+colNum, len); colNum += len; #endif } else { BlockMove("\t-- Autre --", TextLine+colNum, 12); colNum += 12; } // *(TextLine+colNum) = '\n'; colNum++; *(TextLine+colNum) = '\r'; colNum++; TEInsert(TextLine, colNum, TextCode); } TECalText(TextCode); SetCtlMin(Ascens, 0); SetCtlMax(Ascens, (*TextCode)->nLines-visLines); /* Boucle des ˆ©vˆ®nements avec la fenˆtre des fichiers touchˆ©s ===============================================*/ quitter = false; do { WaitNextEvent(everyEvent, &event, 0xFFFFFFFF, 0L); switch(event.what) { case nullEvent: break; case keyDown: if ('q' == (event.message & charCodeMask)) quitter = true; break; case mouseDown: Cellule = event.where; GlobalToLocal(&Cellule); type = FindControl(Cellule, FrontWindow(), &Controle); if (0 != type) { idx = GetCtlValue(Controle); switch(type) { case kControlUpButtonPart: if (idx > 1) { idx = idx - 2; SetCtlValue(Controle, idx); TEScroll(0, 2 * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, 0); TEScroll(0, idx * (*TextCode)->lineHeight, TextCode); idx = 0; } break; case kControlDownButtonPart: if (idx < (*TextCode)->nLines-visLines) { idx = idx + 2; SetCtlValue(Controle, idx); TEScroll(0, -2 * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, (*TextCode)->nLines-visLines+1); TEScroll(0, -((*TextCode)->nLines-visLines-idx)* (*TextCode)->lineHeight, TextCode); idx = (*TextCode)->nLines-visLines; } break; case kControlPageUpPart: if (idx > visLines) { idx = idx - (visLines-1); SetCtlValue(Controle, idx); TEScroll(0, (visLines-1) * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, 0); TEScroll(0, idx * (*TextCode)->lineHeight, TextCode); idx = 0; } break; case kControlPageDownPart: if (idx < ((*TextCode)->nLines-2*visLines)) { idx = idx + (visLines-1); SetCtlValue(Controle, idx); TEScroll(0, -(visLines-1) * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, (*TextCode)->nLines-visLines); TEScroll(0, -((*TextCode)->nLines-visLines-idx)* (*TextCode)->lineHeight, TextCode); idx = (*TextCode)->nLines-visLines; } break; } Draw1Control(Ascens); } break; case updateEvt: BeginUpdate((WindowPtr)event.message); TEUpdate(&(FrontWindow()->portRect), TextCode); Draw1Control(Ascens); EndUpdate((WindowPtr)event.message); break; } } while (!quitter); // (*TextCode)->selStart = 0; // (*TextCode)->selEnd = (*TextLog)->teLength; TESetSelect(0, (*TextCode)->teLength,TextCode); TECopy(TextCode); erreur = ZeroScrap(); if (erreur) { NumToString(erreur, (unsigned char*)numBuffer); ParamText("\pInit presse papier:","\pNo", (unsigned char*)numBuffer, NULL); NoteAlert(128,NULL); } // Copier text vers presse-papier erreur = TEToScrap(); if (erreur) { NumToString(erreur, (unsigned char*)numBuffer); ParamText("\pCopie presse papier:","\pNo", (unsigned char*)numBuffer, NULL); NoteAlert(128,NULL); } TEDispose(TextCode); DisposeControl(Ascens); DisposeWindow(WinLog); #endif }