/***** * * Michael Riff * Object software version 1.0 Okto 2013. * * Diese Datei beinhaltet die Definition der Klassen die in einer Art Baumstruktur * zur Abspeicherung der Eingelesenen Berechnnugen dienen. * Die Operatoren & Funktionen mit höhere Priorität befinden sich zu den Enden der Verzweigungen. * Die Klassen sind alle von einem gemeinsame Vaterklasse abgeleitet. Jede Kalsse die durch * Instanzierung einen Operator/Funktion implementieren soll hat eine oder mehrere Referenzen * zu ein Objekt der Vaterkalsse die die Implementierung der Argumente referenzieren. * * Version 1.2 : 08 Feb 2014 * Use decimal separator from UX_StdLib.c when USE_ITL is defined in InitCalc and ConstOperand::Print. * * Version 1.4: 2 Sept 2014 * Converted print routines of arithmetic expression to reverse polish notation. * * Version 1.6: 06 June 2016 * Added size checks when copying strings into buffer. * 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. * * Version 1.7: 23 July 2016 * Print method of FunctOperat class: corrected spacing. * *****/ #include "OperandClasses.h" #include /* To generate a NAN value the is used in case of parsing error */ typedef union { double PtFlottant; unsigned int Brut[2]; } Type_Erreur; Type_Erreur *Conversion; double ValErr; #ifdef MAC_UI #include /* typedef enum { false = 0, true = 1, FALSE = 0, TRUE = 1 } bool; */ #include "UX_StdDefs.h" #ifdef USE_FORMATX2STR #include /* 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; long double dblValue; extended80 xValueSrc; #else const char dec2char[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; double dblValue; #endif Str63 sValueDst; #ifdef USE_ITL /* Decimal separator read from itl0 or itl4 resource in UX_StdLib.c */ extern char decSeparat; #endif int InitCalc(void) { #ifdef USE_FORMATX2STR short erreur; #ifdef USE_ITL int idx; #endif IUGetItlTable(iuSystemScript, iuNumberPartsTable, (Handle*)(&interRes), &offset, &length); partsTble = (NumberPartsPtr)((SInt32) (*interRes) + offset); BlockMove("######.####;-######.####;0.0", formatDef+1, 28); *formatDef = 28; #ifdef USE_ITL if ('.' != decSeparat) { for(idx=1; idx<=formatDef[0]; idx++) { if ('.' == formatDef[idx]) { formatDef[idx] = decSeparat; } } } #endif erreur = Str2Format(formatDef, partsTble, &formatRec); #endif Conversion = (Type_Erreur*)(&ValErr); Conversion->Brut[0] = 0x7FF00000; Conversion->Brut[1] = 0x00000001; #ifdef USE_FORMATX2STR return erreur; #else return 0; #endif } #else int InitCalc(void) { Conversion = (Type_Erreur*)(&ValErr); Conversion->Brut[0] = 0x7FF00000; Conversion->Brut[1] = 0x00000001; return 0; } #endif /* Top level general class to describe an operand of a function or operator for arithmetic computations. *//* //virtual class GeneralOperand { class GeneralOperand { public : GeneralOperand() ; ~GeneralOperand(); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ // Class to be declared abstract GeneralOperand::GeneralOperand() { } GeneralOperand::~GeneralOperand() { } double GeneralOperand::Calculate() { return 0; } #ifndef MAC_UI void GeneralOperand::Print() { printf("Call of abstract class GeneralOperand\n"); } #else void GeneralOperand::Print(TEHandle txtBuf) { Str63 TextLine; // Event private attribute BlockMove("Call of abstract class GeneralOperand\n", TextLine, 38); *(TextLine+38) = '\r'; TextLine[0] = 39; TEInsert(TextLine, 39, txtBuf); } #endif /* class ErrorOperand : public GeneralOperand { private: public : ErrorOperand(); ~ErrorOperand(); virtual double Calculate(); #ifndef MAC_UI virtual void Print(); #else virtual void Print(TEHandle txtBuf); #endif }; */ ErrorOperand:: ErrorOperand() { } ErrorOperand::~ ErrorOperand() { } double ErrorOperand::Calculate() { return ValErr; } #ifndef MAC_UI void ErrorOperand::Print() { printf("Error operation\n"); } #else void ErrorOperand::Print(TEHandle txtBuf) { TEInsert("Error operation\n", 16, txtBuf); } #endif /* For constant arguments *//* class ConstOperand : public GeneralOperand { private: // Constant value of argument // const double itsValue; double itsValue; public : ConstOperand(float value); ~ConstOperand(); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ ConstOperand::ConstOperand(double value) { this->itsValue = value; } ConstOperand::~ConstOperand() { } double ConstOperand::Calculate() { return itsValue; } #ifndef MAC_UI void ConstOperand::Print() { printf(" %f ", itsValue); } #else extern "C" { void ldtox80 ( long double *, extended80 * ); } void ConstOperand::Print(TEHandle txtBuf) { Str63 sValueDst; // Event private attribute Str63 TextLine; int colNum; #ifdef USE_FORMATX2STR short erreur; #endif *(TextLine) = ' '; colNum = 1; #ifdef USE_FORMATX2STR long double dblValue; dblValue = (long double)(itsValue); ldtox80 ( &dblValue, &xValueSrc ); erreur = FormatX2Str(&xValueSrc, &formatRec, partsTble, sValueDst); #else double dblValue; dblValue = itsValue; { 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 BlockMove(sValueDst+1, TextLine+colNum, sValueDst[0]); colNum += sValueDst[0]; // *(TextLine+colNum) = ' '; colNum++; TEInsert(TextLine, colNum, txtBuf); } #endif /* For constant arguments *//* class ParamOperand : public GeneralOperand { private: // Index of variable in value table int Position; public : VarOperand(int itsPosition); ~VarOperand(); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ //#define MAX_PARAM 10 /* Values for the input parameters (named p_xx) */ double aktDaten[MAX_PARAM]; ParamOperand::ParamOperand(int itsPosition) { Position = itsPosition; } ParamOperand::~ParamOperand() { } double ParamOperand::Calculate() { return aktDaten[Position]; } #ifndef MAC_UI void ParamOperand::Print() { printf(" P_%d", Position); } #else void ParamOperand::Print(TEHandle txtBuf) { Str63 sValueDst; // Event private attribute Str63 TextLine; int colNum; // *(TextLine) = ' '; colNum = 1; colNum = 0; NumToString(Position, sValueDst); BlockMove(" P_", TextLine+ colNum, 3); colNum = 3; BlockMove(sValueDst+1, TextLine+colNum, sValueDst[0]); colNum += sValueDst[0]; // *(TextLine+colNum) = '\n'; colNum++; // *(TextLine+colNum) = '\r'; colNum++; TEInsert(TextLine, colNum, txtBuf); } #endif /* For unary operators as +x or -x *//* typedef enum {uPlus, uMoins} UnarOperType; class UnaryOperat : public GeneralOperand { private : // Pointer to argument GeneralOperand *Argument; // Pointer to operator (only library methematical functions) // float operator Operation(float); Pb : ou faire avec un typedef UnarOperType Operation; public : // UnaryOperat(float operator Signe(float), GeneralOperand *itsArgument); UnaryOperat(UnarOperType Signe, GeneralOperand *itsArgument); ~UnaryOperat(); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ //UnaryOperat::UnaryOperat(float operator Signe(float), GeneralOperand *itsArgument) { UnaryOperat::UnaryOperat(UnarOperType Signe, GeneralOperand *itsArgument) { Operation = Signe; this->Argument = itsArgument; } UnaryOperat::~UnaryOperat() { delete Argument; } double UnaryOperat::Calculate() { // return Operation Argument->Calculate(); switch (Operation) { case uPlus : return Argument->Calculate(); case uMoins : return -Argument->Calculate(); default : return 0; } } #ifndef MAC_UI void UnaryOperat::Print() { switch (Operation) { case uPlus : printf(" +"); Argument->Print(); break; case uMoins : printf(" -"); Argument->Print(); break; default : printf(" +-0 ");; } } #else void UnaryOperat::Print(TEHandle txtBuf) { Str63 TextLine; // Event private attribute int colNum; // *(TextLine) = '\t'; colNum = 1; colNum = 0; switch (Operation) { case uPlus : BlockMove(" +", TextLine+colNum, 2); colNum = 2; TEInsert(TextLine, colNum, txtBuf); Argument->Print(txtBuf); break; case uMoins : BlockMove(" -", TextLine+colNum, 2); colNum = 2; TEInsert(TextLine, colNum, txtBuf); Argument->Print(txtBuf); break; default : BlockMove(" +-0 ", TextLine+colNum, 4); colNum = 4; TEInsert(TextLine, colNum, txtBuf); } } #endif /* For functions calls. Some similarity with binary operators *//* extern "C" { typedef double (*refFuncType)(double); } class FunctOperat : public GeneralOperand { private: // Pointer to argument GeneralOperand *Argument; // Pointer to function (only library methematical functions) // double (*refFunc)(double); Pb pointeur sur une fonction de la lib math écrite en C refFuncType refFunc; public : // FunctOperat((float (*refFunc)(float)) function, GeneralOperand *itsArgument) { // FunctOperat(double (*function)(double), GeneralOperand *itsArgument); FunctOperat(refFuncType function, GeneralOperand *itsArgument); ~FunctOperat(); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ //FunctOperat::FunctOperat((float (*refFunc)(float)) function, GeneralOperand *itsArgument) { //FunctOperat::FunctOperat(double (*function)(double), GeneralOperand *itsArgument) { FunctOperat::FunctOperat(refFuncType function, GeneralOperand *itsArgument) { this->Argument = itsArgument; refFunc = function; } FunctOperat::~FunctOperat() { delete Argument; } double FunctOperat::Calculate() { return (double)refFunc(Argument->Calculate()); } #ifndef MAC_UI void FunctOperat::Print() { Argument->Print(); if (refFunc == sqrt) { printf(" sqrt"); } else if (refFunc == exp) { printf(" exp"); } else if (refFunc == log) { printf(" ln"); } else if (refFunc == sin) { printf(" sin"); } else if (refFunc == cos) { printf(" cos"); } else if (refFunc == tan) { printf(" tan"); } else if (refFunc == sinh) { printf(" sinh"); } else if (refFunc == cosh) { printf(" cosh"); } else if (refFunc == tanh) { printf(" tanh"); } else if (refFunc == asin) { printf(" asin"); } else if (refFunc == acos) { printf(" acos"); } else if (refFunc == atan) { printf(" atan"); } else { printf("Error unimplemented function\n"); } printf("\n"); } #else void FunctOperat::Print(TEHandle txtBuf) { Str63 TextLine; // Event private attribute int colNum; Argument->Print(txtBuf); /* The (double(*)(double)) conversion should not be necessary as the name of a function should be implicitly converted to a reference to the start of the code of that function. But CW 6.0 issues error message: type mismatch had (double) (*double) and (double)(double) So we put and explicit conversion here. With symntec C++ 8.5 it is not necessary. Symantec compiler defines __SC__, SYMANTEC_C, SYMANTEC_CPLUS, __ZTC__, SC_PLUS_SYMANTEC */ #ifdef __SC__ #define convert(func) func #endif #ifdef __MWERKS__ #define convert(func) (double(*)(double))(func) // Used for CodeWarrior #endif #if !defined(__SC__) && !defined(__MWERKS__) #error "Other compiler used. Adaptation may be needed here!" #endif *(TextLine) = ' '; colNum = 1; if (refFunc == convert(sqrt)) { BlockMove("sqrt ", TextLine+1, 5); colNum = 6; } else if (refFunc == convert(exp)) { BlockMove("exp ", TextLine+1, 4); colNum = 5; } else if (refFunc == convert(log)) { BlockMove("ln ", TextLine+1, 3); colNum = 4; } else if (refFunc == convert(sin)) { BlockMove("sin ", TextLine+1, 4); colNum = 5; } else if (refFunc == convert(cos)) { BlockMove("cos ", TextLine+1, 4); colNum = 5; } else if (refFunc == convert(tan)) { BlockMove("tan ", TextLine+1, 4); colNum = 5; } else if (refFunc == convert(sinh)) { BlockMove("sinh ", TextLine+1, 5); colNum = 6; } else if (refFunc == convert(cosh)) { BlockMove("cosh ", TextLine+1, 5); colNum = 6; } else if (refFunc == convert(tanh)) { BlockMove("tanh ", TextLine+1, 5); colNum = 6; } else if (refFunc == convert(asin)) { BlockMove("asin ", TextLine+1, 5); colNum = 6; } else if (refFunc == convert(acos)) { BlockMove("acos ", TextLine+1, 5); colNum = 6; } else if (refFunc == convert(atan)) { BlockMove("atan ", TextLine+1, 5); colNum = 6; } else { BlockMove("Error unimplemented function\n", TextLine+1, 29); colNum = 30; } TEInsert(TextLine, colNum, txtBuf); } #endif /* For binary operators as + - * or / *//* typedef enum { bPlus, bMoins, bMult, bDiv } BinOperType; class BinaryOperat : public GeneralOperand { private : // Pointer to arguments GeneralOperand *LeftArgument; GeneralOperand *RightArgument; // Pointer to operator (only library methematical + - * / =) // (double) operator Operation(double,double); Pb ou faire avec typedef BinOperType Operation; public : // BinaryOperat((float) operator Action(float,float), GeneralOperand *itsLeftArgument); BinaryOperat(BinOperType Action, GeneralOperand *itsLeftArgument); ~BinaryOperat(); virtual double Calculate(); void SetRight(GeneralOperand *itsRightArgument); GeneralOperand *getRightArgument(void); #ifdef DEBUG virtual void Print(); #endif }; */ //BinaryOperat::BinaryOperat((float) operator Action(float,float), GeneralOperand *itsLeftArgument) BinaryOperat::BinaryOperat(BinOperType Action, GeneralOperand *itsLeftArgument) { Operation = Action; LeftArgument = itsLeftArgument; } BinaryOperat::~BinaryOperat() { delete LeftArgument; delete RightArgument; } double BinaryOperat::Calculate() { // return LeftArgument->Calculate() operat RightArgument->Calculate(); switch (Operation) { case bPlus: return LeftArgument->Calculate() + RightArgument->Calculate(); case bMoins: return LeftArgument->Calculate() - RightArgument->Calculate(); case bMult: return LeftArgument->Calculate() * RightArgument->Calculate(); case bDiv: return LeftArgument->Calculate() / RightArgument->Calculate(); case bPow: return pow(LeftArgument->Calculate(), RightArgument->Calculate()); default: return 0; } } void BinaryOperat::SetRight(GeneralOperand *itsRightArgument) { RightArgument = itsRightArgument; } GeneralOperand * BinaryOperat::getRightArgument(void) { return RightArgument; } #ifndef MAC_UI void BinaryOperat::Print() { switch (Operation) { case bPlus: LeftArgument->Print(); RightArgument->Print(); printf(" + "); break; case bMoins: LeftArgument->Print(); RightArgument->Print(); printf(" - "); break; case bMult: LeftArgument->Print(); RightArgument->Print(); printf(" * "); break; case bDiv: LeftArgument->Print(); RightArgument->Print(); printf(" / "); break; case bPow: LeftArgument->Print(); RightArgument->Print(); printf(" ^ "); break; default: printf(" _0_ \n"); } } #else void BinaryOperat::Print(TEHandle txtBuf) { switch (Operation) { case bPlus: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" + ", 3, txtBuf); break; case bMoins: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" - ", 3, txtBuf); break; case bMult: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" * ", 3, txtBuf); break; case bDiv: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" / ", 3, txtBuf); break; case bPow: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" ^ ", 3, txtBuf); break; default: TEInsert(" _0_ \r", 6, txtBuf); } } #endif /* To handle variables We use the variables in two ways: 1) first a value has to be assigned 2) second its value can be read */ // Table to store the values of variables /* typedef struct { char VarName[10]; float ActValue; } VarTableType; */ VarTableType *VarTable; int NumVars = 0; /* This class is used to assign a value to the variable */ /* class VarAssign : public GeneralOperand { private: // Index of variable in value table int Position; // Reference to arithmetic expression determining its value GeneralOperand *itsExpression; public : VarAssign(int itsPosition); ~VarAssign(); void SetArithmetic(GeneralOperand *itsArithmetic); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ VarAssign::VarAssign(int itsPosition) { Position = itsPosition; } VarAssign::~VarAssign() { delete itsExpression; } void VarAssign::SetArithmetic(GeneralOperand *itsArithmetic) { itsExpression = itsArithmetic; } double VarAssign::Calculate() { double result; result = itsExpression->Calculate(); // Store value in variable VarTable[Position].ActValue = result; // Also return its value return result; } #ifndef MAC_UI void VarAssign::Print() { itsExpression->Print(); printf(" "); printf("%s sto ",VarTable[Position].VarName); } #else void VarAssign::Print(TEHandle txtBuf) { Str63 TextLine; // Event private attribute int colNum; itsExpression->Print(txtBuf); TEInsert("\r", 1, txtBuf); colNum = 0; while (VarTable[Position].VarName[colNum]!=0) colNum++; BlockMove(VarTable[Position].VarName, TextLine, colNum); BlockMove(" sto ", TextLine+colNum, 5); TEInsert(TextLine, colNum+5, txtBuf); } #endif /* This class is used to read a value of the variable */ /* class VarOperand : public GeneralOperand { private: // Index of variable in value table int Position; public : VarOperand(int itsPosition); ~VarOperand(); virtual double Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ VarOperand::VarOperand(int itsPosition) { Position = itsPosition; } VarOperand::~VarOperand() { } double VarOperand::Calculate() { return VarTable[Position].ActValue; } #ifndef MAC_UI void VarOperand::Print() { printf(" %s ", VarTable[Position].VarName); } #else void VarOperand::Print(TEHandle txtBuf) { Str63 TextLine; // Event private attribute int colNum; colNum = 0; while (VarTable[Position].VarName[colNum]!=0) colNum++; TextLine[0] = ' '; BlockMove(VarTable[Position].VarName, TextLine+1, colNum); TextLine[colNum+1] = ' '; TEInsert(TextLine, colNum+2, txtBuf); } #endif /* Top level general class to describe an operand of a function or operator for boolean computations. *//* //virtual class GeneralBoolOperand { class GeneralBoolOperand { public : GeneralBoolOperand(); ~GeneralBoolOperand(); virtual bool Calculate(); // bool causes :virtual storage class is illegal in this context #ifdef DEBUG virtual void Print(); #endif }; */ // Class to be declared abstract GeneralBoolOperand::GeneralBoolOperand() { } GeneralBoolOperand::~GeneralBoolOperand() { } #ifndef MAC_UI bool GeneralBoolOperand::Calculate() { return false; } #else Boolean GeneralBoolOperand::Calculate() { return false; } #endif #ifndef MAC_UI void GeneralBoolOperand::Print() { printf("Call of abstract class GeneralBoolOperand\n"); } #else void GeneralBoolOperand::Print(TEHandle txtBuf) { TEInsert("Call of abstract class GeneralBoolOperand\n", 42, txtBuf); } #endif /* class ErrorBoolOperand : public GeneralBoolOperand { private: public : ErrorBoolOperand(); ~ErrorBoolOperand(); virtual bool Calculate(); #ifndef MAC_UI virtual void Print(); #else virtual void Print(TEHandle txtBuf); #endif }; */ ErrorBoolOperand::ErrorBoolOperand() { } ErrorBoolOperand::~ErrorBoolOperand() { } #ifndef MAC_UI bool ErrorBoolOperand::Calculate() { #else Boolean ErrorBoolOperand::Calculate() { #endif return ValErr; } #ifndef MAC_UI void ErrorBoolOperand::Print() { printf("Error bool operation\n"); } #else void ErrorBoolOperand::Print(TEHandle txtBuf) { TEInsert("Error bool operation\n", 21, txtBuf); } #endif /* For unary bool operator not *//* class UnaryBoolOperat : public GeneralBoolOperand { private: // Reference to its associated expression GeneralBoolOperand *Argument; public : UnaryBoolOperat(GeneralBoolOperand *itsArgument); ~UnaryBoolOperat(); virtual bool UnaryBoolOperat::Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ UnaryBoolOperat::UnaryBoolOperat(GeneralBoolOperand *itsArgument) { Argument = itsArgument; } UnaryBoolOperat::~UnaryBoolOperat() { delete Argument; } #ifndef MAC_UI bool UnaryBoolOperat::Calculate() { return (bool)(1-Argument->Calculate()); } #else Boolean UnaryBoolOperat::Calculate() { return (Boolean)(1-Argument->Calculate()); } #endif #ifndef MAC_UI void UnaryBoolOperat::Print() { Argument->Print(); printf(" not"); } #else void UnaryBoolOperat::Print(TEHandle txtBuf) { Argument->Print(txtBuf); TEInsert(" not", 4, txtBuf); } #endif /* For binary bool operators and or xor *//* typedef enum { or, xor, and } BinBoolOperType; class BinaryBoolOperat : public GeneralBoolOperand { private: // References to the arguments GeneralBoolOperand *LeftArgument; GeneralBoolOperand *RightArgument; // Pointer to operator (only library methematical and or xor) // (bool) operator Operation(bool,bool); Pb ou faire avec un typedef BinBoolOperType Operation; public : // BinaryBoolOperat((bool) operator itsComb(bool,bool), GeneralBoolOperand *itsLeftArgument); BinaryBoolOperat(BinBoolOperType itsComb, GeneralBoolOperand *itsLeftArgument); ~BinaryBoolOperat(); virtual bool Calculate(); virtual void SetRight(GeneralBoolOperand *itsRightArgument); virtual GeneralBoolOperand* GetRightArgument(void); #ifdef DEBUG virtual void Print(); #endif }; */ //BinaryBoolOperat::BinaryBoolOperat((bool) operator itsComb(bool,bool), GeneralBoolOperand *itsLeftArgument) { BinaryBoolOperat::BinaryBoolOperat(BinBoolOperType itsComb, GeneralBoolOperand *itsLeftArgument) { Operation = itsComb; LeftArgument = itsLeftArgument; } BinaryBoolOperat::~BinaryBoolOperat() { delete LeftArgument; delete RightArgument; } #ifndef MAC_UI bool BinaryBoolOperat::Calculate() { // return LeftArgument->Calculate() Operation RightArgument->Calculate(); switch (Operation) { case _or: return (bool)(LeftArgument->Calculate() || RightArgument->Calculate()); case _xor: return (bool)(LeftArgument->Calculate() ^ RightArgument->Calculate()); case _and: return (bool)(LeftArgument->Calculate() && RightArgument->Calculate()); default: return false; #else Boolean BinaryBoolOperat::Calculate() { // return LeftArgument->Calculate() Operation RightArgument->Calculate(); switch (Operation) { case _or: return (Boolean)(LeftArgument->Calculate() || RightArgument->Calculate()); case _xor: return (Boolean)(LeftArgument->Calculate() ^ RightArgument->Calculate()); case _and: return (Boolean)(LeftArgument->Calculate() && RightArgument->Calculate()); default: return false; #endif } } void BinaryBoolOperat::SetRight(GeneralBoolOperand *itsRightArgument) { RightArgument = itsRightArgument; } GeneralBoolOperand* BinaryBoolOperat::GetRightArgument(void) { return RightArgument; } #ifndef MAC_UI void BinaryBoolOperat::Print() { switch (Operation) { case _or: LeftArgument->Print(); RightArgument->Print(); printf(" or\n"); break; case _xor: LeftArgument->Print(); RightArgument->Print(); printf(" xor\n"); break; case _and: LeftArgument->Print(); RightArgument->Print(); printf(" and\n"); break; default: printf(" unknown bool \n"); } #else void BinaryBoolOperat::Print(TEHandle txtBuf) { switch (Operation) { case _or: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" or\r", 4, txtBuf); break; case _xor: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" xor\r", 5, txtBuf); break; case _and: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" and\r", 5, txtBuf); break; default: TEInsert(" unknown bool\r", 14, txtBuf); } #endif } /* For comparison operators as == != < > <= >= *//* typedef enum { eq, neq, gt, lt, get, let } BinCompOperType; class BinaryCompOperator : public GeneralBoolOperand { private : // References to arguments GeneralOperand *LeftArgument; GeneralOperand *RightArgument; // Pointer to operator (only library methematical < > >= >= != ==) // (bool) operator Operation(float,float); BinCompOperType Operation; public : // BinaryCompOperator((bool) operator itsCmp(float,float), GeneralOperand *LeftArgument); BinaryCompOperator(BinCompOperType itsCmp, GeneralOperand *LeftArgument); ~BinaryCompOperator(); virtual bool Calculate(); void SetRight(GeneralOperand *itsRightArgument); #ifdef DEBUG virtual void Print(); #endif }; */ //BinaryCompOperator::BinaryCompOperator((bool) operator itsCmp(float,float), GeneralOperand *itsLeftArgument) { BinaryCompOperator::BinaryCompOperator(BinCompOperType itsComp, GeneralOperand *itsLeftArgument) { Operation = itsComp; LeftArgument = itsLeftArgument; } BinaryCompOperator::~BinaryCompOperator() { delete LeftArgument; delete RightArgument; } #ifndef MAC_UI bool BinaryCompOperator::Calculate() { // return LeftArgument->Calculate() Operation RightArgument->Calculate(); switch(Operation) { case eq: return (bool)(LeftArgument->Calculate() == RightArgument->Calculate()); case neq: return (bool)(LeftArgument->Calculate() != RightArgument->Calculate()); case gt: return (bool)(LeftArgument->Calculate() > RightArgument->Calculate()); case lt: return (bool)(LeftArgument->Calculate() < RightArgument->Calculate()); case get: return (bool)(LeftArgument->Calculate() >= RightArgument->Calculate()); case let: return (bool)(LeftArgument->Calculate() <= RightArgument->Calculate()); default: return false; #else Boolean BinaryCompOperator::Calculate() { // return LeftArgument->Calculate() Operation RightArgument->Calculate(); switch(Operation) { case eq: return (Boolean)(LeftArgument->Calculate() == RightArgument->Calculate()); case neq: return (Boolean)(LeftArgument->Calculate() != RightArgument->Calculate()); case gt: return (Boolean)(LeftArgument->Calculate() > RightArgument->Calculate()); case lt: return (Boolean)(LeftArgument->Calculate() < RightArgument->Calculate()); case get: return (Boolean)(LeftArgument->Calculate() >= RightArgument->Calculate()); case let: return (Boolean)(LeftArgument->Calculate() <= RightArgument->Calculate()); default: return false; #endif } } void BinaryCompOperator::SetRight(GeneralOperand *itsRightArgument) { RightArgument = itsRightArgument; } #ifndef MAC_UI void BinaryCompOperator::Print() { switch(Operation) { case eq: LeftArgument->Print(); RightArgument->Print(); printf(" == "); break; case neq: LeftArgument->Print(); RightArgument->Print(); printf(" != "); break; case gt: LeftArgument->Print(); RightArgument->Print(); printf(" > "); break; case lt: LeftArgument->Print(); RightArgument->Print(); printf(" < "); break; case get: LeftArgument->Print(); RightArgument->Print(); printf(" >= "); break; case let: LeftArgument->Print(); RightArgument->Print(); printf(" <= "); break; default: printf(" unknown comp \n"); } } #else void BinaryCompOperator::Print(TEHandle txtBuf) { switch(Operation) { case eq: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" == ", 4, txtBuf); break; case neq: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" != ", 4, txtBuf); break; case gt: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" > ", 3, txtBuf); break; case lt: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" < ", 3, txtBuf); break; case get: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" >= ", 4, txtBuf); break; case let: LeftArgument->Print(txtBuf); RightArgument->Print(txtBuf); TEInsert(" <= ", 4, txtBuf); break; default: TEInsert(" unknown comp\r", 14, txtBuf); } } #endif #define OPERAND_BLOCK 5 /* For control structures if else or for while *//* class OperatorIf : public GeneralOperand { private: // Reference to test expression GeneralBoolOperand *Argument; GeneralOperand **IfArithmetic; int numIf; int numBlocksIf; GeneralOperand **ElseArithmetic; // null if no else case int numElse; int numBlocksElse; public : OperatorIf(GeneralBoolOperand *itsTest); ~OperatorIf(); virtual double OperatorIf::Calculate(); #ifdef DEBUG virtual void Print(); #endif }; */ OperatorIf::OperatorIf(GeneralBoolOperand *itsTest) { Argument = itsTest; IfArithmetic = (GeneralOperand **)malloc(OPERAND_BLOCK*sizeof(GeneralOperand *)); // Check if it went right if (NULL==IfArithmetic) { numBlocksIf = 0; printf("Memory allocation for if branch failed\n"); } else { numBlocksIf=1; } numIf = 0; ElseArithmetic = NULL; numElse = 0; } OperatorIf::~OperatorIf() { int idx; delete Argument; for (idx=0; idxCalculate()) { for(idx=0; idxCalculate(); } return result; } else { if (ElseArithmetic != NULL) { for(idx=0; idxCalculate(); } return result; } else return 0; } } #ifndef MAC_UI void OperatorIf::Print() { int idx; printf( "if("); Argument->Print(); printf(") {\n"); for(idx=0; idxPrint(); printf(";\n"); } if (ElseArithmetic != NULL) { printf("\n} else {\n"); for(idx=0; idxPrint(); printf(";\n"); } } printf("}\n"); } #else void OperatorIf::Print(TEHandle txtBuf) { int idx; TEInsert( "if(", 3, txtBuf); Argument->Print(txtBuf); TEInsert(") {\r", 4, txtBuf); for(idx=0; idxPrint(txtBuf); TEInsert(";\r", 2, txtBuf); } if (ElseArithmetic != NULL) { TEInsert("\r} else {\r", 10, txtBuf); for(idx=0; idxPrint(txtBuf); TEInsert(";\r", 2, txtBuf); } } TEInsert("}\r", 2, txtBuf); } #endif /* class OperatorFor : public GeneralOperand { private: // Reference to loop start arithmetic GeneralOperand *Start; // Reference to test expression GeneralBoolOperand *Condition; // Reference to loop instruction GeneralOperand *Increment; GeneralOperand **LoopArithmetic; int numBlockLoop; int numLoop; public : OperatorFor(GeneralOperand *itsStart); ~OperatorFor(); virtual double Calculate(); void SetCondition(GeneralBoolOperand *itsCondition); void SetIncrement(GeneralOperand *itsIncrement); void SetLoop(GeneralOperand *itsLoop); #ifdef DEBUG virtual void Print(); #endif }; */ OperatorFor::OperatorFor(GeneralOperand *itsStart) { Start = itsStart; LoopArithmetic = (GeneralOperand **)malloc(OPERAND_BLOCK*sizeof(GeneralOperand *)); if (LoopArithmetic) { numBlockLoop = 1; } else { printf("Allocation for loop failed\n"); numBlockLoop = 0; } numLoop = 0; } OperatorFor::~OperatorFor() { int idx; delete Start; delete Condition; delete Increment; if (0Calculate(); Condition->Calculate(); Increment->Calculate()) // !!! Legal Fall for(;condition;loopoperation) nicht berücksichtigt for(idx=0; idxCalculate(); return result; } void OperatorFor::SetCondition(GeneralBoolOperand *itsCondition) { Condition = itsCondition; } void OperatorFor::SetIncrement(GeneralOperand *itsIncrement) { Increment = itsIncrement; } void OperatorFor::SetLoop(GeneralOperand *itsLoop) { if (numLoopPrint(); printf(";\n"); Condition->Print(); printf(";\n"); Increment->Print(); printf(") {\n"); for (idx=0; idxPrint(); printf(";\n"); } printf("}\n"); } #else void OperatorFor::Print(TEHandle txtBuf) { int idx; TEInsert("for(", 4, txtBuf); Start->Print(txtBuf); TEInsert(";\r", 2, txtBuf); Condition->Print(txtBuf); TEInsert(";\r", 2, txtBuf); Increment->Print(txtBuf); TEInsert(") {\r", 4, txtBuf); for (idx=0; idxPrint(txtBuf); TEInsert(";\r", 2, txtBuf); } TEInsert("}\r", 2, txtBuf); } #endif /* Classes to optimise the incrementation/decrementation of a variable often used in the for loops */ /* class OperatorIncDec : public GeneralOperand { private: // Indication to pre or post int PrePost; // Indication to increment or decrement int Step; // -1 o +1 // Position of variable in the variable table int Position; public: OperatorIncDec(int itsPrePost, int itsStep,); ~OperatorIncDec(); virtual double Calculate(); void SetPosition(int itsPosition); #ifdef DEBUG virtual void Print(); #endif }; */ OperatorIncDec::OperatorIncDec(int itsPrePost, int itsStep) { #ifdef DEBUG if (itsPrePost != -1 && itsPrePost != 1) { printf("Error invalid Pre or Post inc/decrementation value\n"); } if (itsStep != -1 && itsStep != 1) { printf("Error invalid inc/decrementation value\n"); } #endif PrePost = itsPrePost; Step = itsStep; } OperatorIncDec::~OperatorIncDec() { } double OperatorIncDec::Calculate() { double buffer; if (PrePost == -1) { // Pre - inc/decrementation VarTable[Position].ActValue +=Step; return VarTable[Position].ActValue; } else { // Post - inc/decrementation buffer = VarTable[Position].ActValue; VarTable[Position].ActValue +=Step; return buffer; } } void OperatorIncDec::SetPosition(int itsPosition) { Position = itsPosition; } #ifndef MAC_UI void OperatorIncDec::Print() { if (PrePost == -1) { if(Step==1) printf("++"); else printf("--"); printf(VarTable[Position].VarName); } else { printf(VarTable[Position].VarName); if(Step==1) printf("++"); else printf("--"); } } #else void OperatorIncDec::Print(TEHandle txtBuf) { int colNum; colNum = 0; while (VarTable[Position].VarName[colNum]!=0) colNum++; if (PrePost == -1) { if(Step==1) TEInsert("++", 2, txtBuf); else TEInsert("--", 2, txtBuf); TEInsert(VarTable[Position].VarName, colNum, txtBuf); } else { TEInsert(VarTable[Position].VarName, colNum, txtBuf); if(Step==1) TEInsert("++", 2, txtBuf); else TEInsert("--", 2, txtBuf); } } #endif /* class OperatorWhile : public GeneralOperand { private: // Reference to test expression GeneralBoolOperand *Condition; GeneralOperand **LoopArithmetic; int numBlockLoop; int numLoop; public : OperatorWhile(); ~OperatorWhile(); virtual double Calculate(); void SetLoop(GeneralOperand *itsLoop); #ifdef DEBUG virtual void Print(); #endif }; */ OperatorWhile::OperatorWhile(GeneralBoolOperand *itsCondition) { Condition = itsCondition; LoopArithmetic = (GeneralOperand **)malloc(OPERAND_BLOCK*sizeof(GeneralOperand *)); if (LoopArithmetic) { numBlockLoop = 1; } else { printf("Allocation while loop failed\n"); numBlockLoop = 0; } numLoop = 0; } OperatorWhile::~OperatorWhile() { int idx; delete Condition; if (0Calculate()) for(idx=0; idxCalculate(); return result; } void OperatorWhile::SetLoop(GeneralOperand *itsLoop) { if (numLoopPrint(); printf(") {\n"); for (idx=0; idxPrint(); printf(";\n"); } printf("}\n"); } #else void OperatorWhile::Print(TEHandle txtBuf) { int idx; TEInsert("while(", 6, txtBuf); Condition->Print(txtBuf); TEInsert(") {\r", 4, txtBuf); for (idx=0; idxPrint(txtBuf); TEInsert(";\r", 2, txtBuf); } TEInsert("}\r", 2, txtBuf); } #endif /* class OperatorDo : public GeneralOperand { private: // Reference to test expression GeneralBoolOperand *Condition; // Refence to arithmetics to execute if test true GeneralOperand **LoopArithmetic; public : OperatorDo(); ~OperatorDo(); virtual double Calculate(); void SetLoop(GeneralOperand *itsLoop); void SetCondition(GeneralBoolOperand *itsCondition); #ifdef DEBUG virtual void Print(); #endif }; */ OperatorDo::OperatorDo() { Condition = NULL; LoopArithmetic = (GeneralOperand **)malloc(OPERAND_BLOCK*sizeof(GeneralOperand *)); if (LoopArithmetic) { numBlockLoop = 1; } else { printf("Allocation do while loop failed\n"); numBlockLoop = 0; } numLoop = 0; } OperatorDo::~OperatorDo() { int idx; delete Condition; if (0Calculate(); } while(Condition->Calculate()); return result; } void OperatorDo::SetLoop(GeneralOperand *itsLoop) { if (numLoopPrint(); printf(";\n"); } printf("\n} while("); Condition->Print(); printf(")\n"); } #else void OperatorDo::Print(TEHandle txtBuf) { int idx; TEInsert("do {\r", 5, txtBuf); for (idx=0; idxPrint(txtBuf); TEInsert(";\r", 2, txtBuf); } TEInsert("\r} while(", 9, txtBuf); Condition->Print(txtBuf); TEInsert(")\r", 2, txtBuf); } #endif /* ====*/ #ifdef ADD_FUNCT PrintVarOperat::PrintVarOperat(int varidx): varIndex(varidx) { } double PrintVarOperat::Calculate() { printf("%g\n", VarTable[varIndex].ActValue); return 0; } #ifndef MAC_UI void PrintVarOperat::Print() { printf("print %s\n", VarTable[varIndex].VarName); } #else void PrintVarOperat::Print(TEHandle txtBuf) { Str63 TextLine; int colNum; TEInsert("print ", 6, txtBuf); //colNum = 6; colNum = strlen(VarTable[varIndex].VarName); BlockMove(VarTable[varIndex].VarName, TextLine, colNum); TEInsert(TextLine, colNum, txtBuf); } #endif PrintMsgOperat::PrintMsgOperat(char* msg) { message = new char[strlen(msg)+1]; strcpy(message, msg); } PrintMsgOperat::~PrintMsgOperat() { delete message; } double PrintMsgOperat::Calculate() { printf("%s\n", message); return 0; } #ifndef MAC_UI void PrintMsgOperat::Print() { printf("print %s\n", message); } #else void PrintMsgOperat::Print(TEHandle txtBuf) { Str63 TextLine; int colNum; TEInsert("print ", 6, txtBuf); //colNum = 6; colNum = strlen(message); BlockMove(message, TextLine, colNum); TEInsert(TextLine, colNum, txtBuf); } #endif #endif