int Expression::execExpression() { if(altNum==1) { return this->getTrmInstance()->execTrm(); } else if (altNum==2) { return (this->getTrmInstance()->execTrm() + execExpression()); } else { return (this->getTrmInstance()->execTrm() - execExpression()); } }
int Expression1::execExpression() { if(altNum==1) { return trm->execTrm(); } else if (altNum==2) { return (trm->execTrm() + execExpression()); } else { return (trm->execTrm() - execExpression()); } }
void execSwitchStatement (void) { getCodeToken(); char* branchTableLocation = getCodeAddressMarker(); getCodeToken(); TypePtr switchExpressionTypePtr = execExpression(); long switchExpressionValue; if ((switchExpressionTypePtr == IntegerTypePtr) || (switchExpressionTypePtr->form == FRM_ENUM)) switchExpressionValue = tos->integer; else switchExpressionValue = tos->byte; pop(); //--------------------------------------------------------- // Now, search the branch table for the expression value... codeSegmentPtr = branchTableLocation; getCodeToken(); long caseLabelCount = getCodeInteger(); bool done = false; char* caseBranchLocation = NULL; while (!done && caseLabelCount--) { long caseLabelValue = getCodeInteger(); caseBranchLocation = getCodeAddress(); done = (caseLabelValue == switchExpressionValue); } //----------------------------------------------- // If found, go to the aprropriate branch code... if (caseLabelCount >= 0) { codeSegmentPtr = caseBranchLocation; getCodeToken(); if (codeToken != TKN_END_CASE) do { execStatement(); if (ExitWithReturn) return; } while (codeToken != TKN_END_CASE); //---------------------------------- // Grab the end case and semi-colon... getCodeToken(); getCodeToken(); codeSegmentPtr = getCodeAddressMarker(); getCodeToken(); } else { //----------------------------------------------------------------- // Since the branch table is located at the end of the case blocks, // the code directly after the switch statement follows our // current code location, already. Just grab the endswitch // and semi-colon... getCodeToken(); getCodeToken(); } }
void execRepeatStatement(void) { PSTR loopStartLocation = codeSegmentPtr; int32_t iterations = 0; do { getCodeToken(); if(codeToken != TKN_UNTIL) do { execStatement(); if(ExitWithReturn) return; } while(codeToken != TKN_UNTIL); //--------------------------- // Check for infinite loop... iterations++; if(iterations == MaxLoopIterations) runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP); //------------------------------- // Eval the boolean expression... getCodeToken(); execExpression(); if(tos->integer == 0) codeSegmentPtr = loopStartLocation; //-------------------------- // Grab the boolean value... pop(); } while(codeSegmentPtr == loopStartLocation); }
TypePtr execSubscripts(TypePtr typePtr) { //---------------------------------------- // Loop to execute bracketed subscripts... while (codeToken == TKN_LBRACKET) { do { getCodeToken(); execExpression(); int32_t subscriptValue = tos->integer; pop(); //------------------------- // Range check the index... if ((subscriptValue < 0) || (subscriptValue >= typePtr->info.array.elementCount)) runtimeError(ABL_ERR_RUNTIME_VALUE_OUT_OF_RANGE); tos->address += (subscriptValue * typePtr->info.array.elementTypePtr->size); if (codeToken == TKN_COMMA) typePtr = typePtr->info.array.elementTypePtr; } while (codeToken == TKN_COMMA); getCodeToken(); if (codeToken == TKN_LBRACKET) typePtr = typePtr->info.array.elementTypePtr; } return (typePtr->info.array.elementTypePtr); }
void execAssignmentStatement(SymTableNodePtr idPtr) { StackItemPtr targetPtr; TypePtr targetTypePtr; TypePtr expressionTypePtr; //-------------------------- // Assignment to variable... targetTypePtr = execVariable(idPtr, USE_TARGET); targetPtr = (StackItemPtr)tos->address; //------------------------------ // Pop off the target address... pop(); //------------------------ // Pop the size, if nec... //if (targetTypePtr->form == FRM_ARRAY) // pop(); //--------------------------------------------------------------- // Routine execExpression() leaves the expression value on top of // stack... getCodeToken(); expressionTypePtr = execExpression(); //-------------------------- // Now, do the assignment... if((targetTypePtr == RealTypePtr) && (expressionTypePtr == IntegerTypePtr)) { //------------------------- // integer assigned to real targetPtr->real = (float)(tos->integer); } else if(targetTypePtr->form == FRM_ARRAY) { //------------------------- // Copy the array/record... PSTR dest = (PSTR)targetPtr; PSTR src = tos->address; int32_t size = targetTypePtr->size; memcpy(dest, src, size); } else if((targetTypePtr == IntegerTypePtr) || (targetTypePtr->form == FRM_ENUM)) { //------------------------------------------------------ // Range check assignment to integer or enum subrange... targetPtr->integer = tos->integer; } else if(targetTypePtr == CharTypePtr) targetPtr->byte = tos->byte; else { //----------------------- // Assign real to real... targetPtr->real = tos->real; } //----------------------------- // Grab the expression value... pop(); if(debugger) debugger->traceDataStore(idPtr, idPtr->typePtr, targetPtr, targetTypePtr); }
bool ABLi_popBoolean (void) { getCodeToken(); execExpression(); long val = tos->integer; pop(); return(val == 1); }
float ABLi_popReal (void) { getCodeToken(); execExpression(); float val = tos->real; pop(); return(val); }
long ABLi_popInteger (void) { getCodeToken(); execExpression(); long val = tos->integer; pop(); return(val); }
char ABLi_popChar (void) { getCodeToken(); execExpression(); char val = (char)tos->integer; pop(); return(val); }
void execIfStatement(void) { getCodeToken(); PSTR falseLocation = getCodeAddressMarker(); //------------------------------- // Eval the boolean expression. Note that, unlike C/C++, the expression // must be true(1) or false(0). In C/C++, an expression is true if it's // non-zero. Not the case in ABL using this current implementation. Do we // want to change this? getCodeToken(); execExpression(); bool test = (tos->integer == 1); pop(); if(test) { //--------------------------- // execute the TRUE branch... getCodeToken(); if((codeToken != TKN_END_IF) && (codeToken != TKN_ELSE)) do { execStatement(); if(ExitWithReturn) return; } while((codeToken != TKN_END_IF) && (codeToken != TKN_ELSE)); if(codeToken == TKN_ELSE) { getCodeToken(); codeSegmentPtr = getCodeAddressMarker(); getCodeToken(); } } else { //---------------------------- // Execute the FALSE branch... codeSegmentPtr = falseLocation; getCodeToken(); if(codeToken == TKN_ELSE) { getCodeToken(); getCodeAddressMarker(); getCodeToken(); if(codeToken != TKN_END_IF) do { execStatement(); if(ExitWithReturn) return; } while(codeToken != TKN_END_IF); } } getCodeToken(); }
void execStdPrint (void) { //--------------------------- // Grab the opening LPAREN... getCodeToken(); //---------------------------- // Get parameter expression... getCodeToken(); TypePtr paramTypePtr = execExpression(); char buffer[20]; char* s = buffer; if (paramTypePtr == IntegerTypePtr) sprintf(buffer, "%d", tos->integer); else if (paramTypePtr == BooleanTypePtr) sprintf(buffer, "%s", tos->integer ? "true" : "false"); else if (paramTypePtr == CharTypePtr) sprintf(buffer, "%c", tos->byte); else if (paramTypePtr == RealTypePtr) sprintf(buffer, "%.4f", tos->real); else if ((paramTypePtr->form == FRM_ARRAY) && (paramTypePtr->info.array.elementTypePtr == CharTypePtr)) s = (char*)tos->address; pop(); if (debugger) { char message[512]; sprintf(message, "PRINT: \"%s\"", s); debugger->print(message); sprintf(message, " MODULE %s", CurModule->getName()); debugger->print(message); sprintf(message, " FILE %s", CurModule->getSourceFile(FileNumber)); debugger->print(message); sprintf(message, " LINE %d", execLineNumber); debugger->print(message); } /* else if (TACMAP) { aChatWindow* chatWin = TACMAP->getChatWindow(); if (chatWin) chatWin->processChatString(0, s, -1); else { #ifdef _DEBUG OutputDebugString(s); #endif } } */ else { #ifdef _DEBUG ABLDebugPrintCallback(s); #endif } //----------------------- // Grab closing RPAREN... getCodeToken(); }
TypePtr execStdConcat (void) { //------------------- // Grab the LPAREN... getCodeToken(); //-------------------------- // Get destination string... getCodeToken(); execExpression(); char* dest = (char*)tos->address; pop(); //---------------------- // Get item to append... getCodeToken(); TypePtr paramTypePtr = execExpression(); char buffer[20]; if (paramTypePtr == IntegerTypePtr) { sprintf(buffer, "%d", tos->integer); strcat(dest, buffer); } else if (paramTypePtr == CharTypePtr) { sprintf(buffer, "%c", tos->byte); strcat(dest, buffer); } else if (paramTypePtr == RealTypePtr) { sprintf(buffer, "%.2f", tos->real); strcat(dest, buffer); } else if (paramTypePtr == BooleanTypePtr) { sprintf(buffer, "%s", tos->integer ? "true" : "false"); strcat(dest, buffer); } else if ((paramTypePtr->form == FRM_ARRAY) && (paramTypePtr->info.array.elementTypePtr == CharTypePtr)) strcat(dest, (char*)tos->address); tos->integer = 0; getCodeToken(); return(IntegerTypePtr); }
char* ABLi_popBooleanPtr (void) { //-------------------------- // Get destination string... getCodeToken(); execExpression(); char* charPtr = (char*)tos->address; pop(); return(charPtr); }
float ABLi_popIntegerReal (void) { getCodeToken(); TypePtr paramTypePtr = execExpression(); float val = 0.0; if (paramTypePtr == IntegerTypePtr) val = (float)tos->integer; else val = tos->real; pop(); return(val); }
void execActualParams(SymTableNodePtr routineIdPtr) { //-------------------------- // Execute the parameters... for(SymTableNodePtr formalIdPtr = (SymTableNodePtr)(routineIdPtr->defn.info.routine.params); formalIdPtr != nullptr; formalIdPtr = formalIdPtr->next) { TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr); getCodeToken(); if(formalIdPtr->defn.key == DFN_VALPARAM) { //------------------- // pass by value parameter... TypePtr actualTypePtr = execExpression(); if((formalTypePtr == RealTypePtr) && (actualTypePtr == IntegerTypePtr)) { //--------------------------------------------- // Real formal parameter, but integer actual... tos->real = (float)(tos->integer); } //---------------------------------------------------------- // Formal parameter is an array or record, so make a copy... if((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/) { //------------------------------------------------------------------------------ // The following is a little inefficient, but is kept this way to keep it clear. // Once it's verified to work, optimize... int32_t size = formalTypePtr->size; PSTR src = tos->address; PSTR dest = (PSTR)ABLStackMallocCallback((size_t)size); if(!dest) { char err[255]; sprintf(err, " ABL: Unable to AblStackHeap->malloc actual array param in module %s)", CurModule->getName()); ABL_Fatal(0, err); } PSTR savePtr = dest; memcpy(dest, src, size); tos->address = savePtr; } } else { //------------------------------- // pass by reference parameter... SymTableNodePtr idPtr = getCodeSymTableNodePtr(); execVariable(idPtr, USE_REFPARAM); } } }
void execWhileStatement (void) { getCodeToken(); char* loopEndLocation = getCodeAddressMarker(); char* testLocation = codeSegmentPtr; bool loopDone = false; long iterations = 0; do { //------------------------------- // Eval the boolean expression... getCodeToken(); execExpression(); if (tos->integer == 0) { codeSegmentPtr = loopEndLocation; loopDone = true; } //------------------------- // Get the boolean value... pop(); //---------------------------------- // If TRUE, execute the statement... if (!loopDone) { getCodeToken(); if (codeToken != TKN_END_WHILE) do { execStatement(); if (ExitWithReturn) return; } while (codeToken != TKN_END_WHILE); codeSegmentPtr = testLocation; //--------------------------- // Check for infinite loop... iterations++; if (iterations == MaxLoopIterations) runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP); } } while (!loopDone); getCodeToken(); }
long ABLi_popAnything (ABLStackItem* value) { getCodeToken(); TypePtr paramTypePtr = execExpression(); long type = -1; if (paramTypePtr == IntegerTypePtr) { value->type = type = ABL_STACKITEM_INTEGER; value->data.integer = tos->integer; } else if (paramTypePtr == BooleanTypePtr) { value->type = type = ABL_STACKITEM_BOOLEAN; value->data.boolean = (tos->integer ? true : false); } else if (paramTypePtr == CharTypePtr) { value->type = type = ABL_STACKITEM_CHAR; value->data.character = tos->byte; } else if (paramTypePtr == RealTypePtr) { value->type = type = ABL_STACKITEM_REAL; value->data.real = tos->real; } else if (paramTypePtr->form == FRM_ARRAY) { if (paramTypePtr->info.array.elementTypePtr == CharTypePtr) { value->type = type = ABL_STACKITEM_CHAR_PTR; value->data.characterPtr = (char*)tos->address; } else if (paramTypePtr->info.array.elementTypePtr == IntegerTypePtr) { value->type = type = ABL_STACKITEM_INTEGER_PTR; value->data.integerPtr = (long*)tos->address; } else if (paramTypePtr->info.array.elementTypePtr == RealTypePtr) { value->type = type = ABL_STACKITEM_REAL_PTR; value->data.realPtr = (float*)tos->address; } else if (paramTypePtr->info.array.elementTypePtr == BooleanTypePtr) { value->type = type = ABL_STACKITEM_BOOLEAN_PTR; value->data.booleanPtr = (bool*)tos->address; } } pop(); return(type); }
void Debugger::showValue (void) { getToken(); if (curToken == TKN_SEMICOLON) print("Bad Expression.\n"); else { //------------------------------------------------------------ // NOTE: Need a SOFT FATAL for parsing expressions here so the // debugger's errors don't Fatal out of the game! //------------------------------------------------------------ //--------------------------------------------------------------- // It's important that the expression parser return an error code // rather than fatal! TypePtr typePtr = expression(); if (errorCount > 0) return; char* savedCodeSegmentPtr = codeSegmentPtr; TokenCodeType savedCodeToken = codeToken; execExpression(); if (typePtr->form == FRM_ARRAY) { print("SHOW ARRAY\n"); } else { char message[255]; sprintDataValue(message, tos, typePtr); strcat(message, "\n"); print(message); } pop(); codeSegmentPtr = savedCodeSegmentPtr; codeToken = savedCodeToken; } }
float ABLi_peekReal (void) { getCodeToken(); execExpression(); return(tos->real); }
bool ABLi_peekBoolean (void) { getCodeToken(); execExpression(); return(tos->integer == 1); }
char* ABLi_peekCharPtr (void) { getCodeToken(); execExpression(); return((char*)tos->address); }
void execForStatement(void) { getCodeToken(); //--------------------------------------- // Grab address of the end of the loop... PSTR loopEndLocation = getCodeAddressMarker(); //-------------------------------------------------------- // Get the address of the control variable's stack item... getCodeToken(); SymTableNodePtr controlIdPtr = getCodeSymTableNodePtr(); TypePtr controlTypePtr = execVariable(controlIdPtr, USE_TARGET); StackItemPtr targetPtr = (StackItemPtr)tos->address; //------------------------------------ // Control variable address... pop(); //------------------------------- // Eval the initial expression... getCodeToken(); execExpression(); int32_t initialValue; if(controlTypePtr == IntegerTypePtr) initialValue = tos->integer; else initialValue = tos->byte; //--------------------- // The initial value... pop(); int32_t deltaValue; if(codeToken == TKN_TO) deltaValue = 1; else deltaValue = -1; //---------------------------------- // Now, eval the final expression... getCodeToken(); execExpression(); int32_t finalValue; if(controlTypePtr == IntegerTypePtr) finalValue = tos->integer; else finalValue = tos->byte; //------------------- // The final value... pop(); //---------------------------- // Address of start of loop... PSTR loopStartLocation = codeSegmentPtr; int32_t controlValue = initialValue; //----------------------------- // Now, execute the FOR loop... int32_t iterations = 0; if(deltaValue == 1) while(controlValue <= finalValue) { if(controlTypePtr == IntegerTypePtr) targetPtr->integer = controlValue; else targetPtr->byte = (uint8_t)controlValue; getCodeToken(); if(codeToken != TKN_END_FOR) do { execStatement(); if(ExitWithReturn) return; } while(codeToken != TKN_END_FOR); //--------------------------- // Check for infinite loop... if(++iterations == MaxLoopIterations) runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP); controlValue++; codeSegmentPtr = loopStartLocation; } else while(controlValue >= finalValue) { if(controlTypePtr == IntegerTypePtr) targetPtr->integer = controlValue; else targetPtr->byte = (uint8_t)controlValue; getCodeToken(); if(codeToken != TKN_END_FOR) do { execStatement(); if(ExitWithReturn) return; } while(codeToken != TKN_END_FOR); //--------------------------- // Check for infinite loop... if(++iterations == MaxLoopIterations) runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP); controlValue--; codeSegmentPtr = loopStartLocation; } codeSegmentPtr = loopEndLocation; getCodeToken(); }
void execStdReturn (void) { memset(&returnValue, 0, sizeof(StackItem)); if (CurRoutineIdPtr->typePtr) { //----------------------------- // Assignment to function id... StackFrameHeaderPtr headerPtr = (StackFrameHeaderPtr)stackFrameBasePtr; long delta = level - CurRoutineIdPtr->level - 1; while (delta-- > 0) headerPtr = (StackFrameHeaderPtr)headerPtr->staticLink.address; StackItemPtr targetPtr = (StackItemPtr)headerPtr; TypePtr targetTypePtr = (TypePtr)(CurRoutineIdPtr->typePtr); getCodeToken(); //--------------------------------------------------------------- // Routine execExpression() leaves the expression value on top of // stack... getCodeToken(); TypePtr expressionTypePtr = execExpression(); //-------------------------- // Now, do the assignment... if ((targetTypePtr == RealTypePtr) && (expressionTypePtr == IntegerTypePtr)) { //------------------------- // integer assigned to real targetPtr->real = (float)(tos->integer); } else if (targetTypePtr->form == FRM_ARRAY) { //------------------------- // Copy the array/record... char* dest = (char*)targetPtr; char* src = tos->address; long size = targetTypePtr->size; memcpy(dest, src, size); } else if ((targetTypePtr == IntegerTypePtr) || (targetTypePtr->form == FRM_ENUM)) { //------------------------------------------------------ // Range check assignment to integer or enum subrange... targetPtr->integer = tos->integer; } else { //----------------------- // Assign real to real... targetPtr->real = tos->real; } //----------------------------- // Grab the expression value... pop(); //---------------------------------------------------------------------- // Preserve the return value, in case we need it for the calling user... memcpy(&returnValue, targetPtr, sizeof(StackItem)); if (debugger) debugger->traceDataStore(CurRoutineIdPtr, CurRoutineIdPtr->typePtr, targetPtr, targetTypePtr); } //----------------------- // Grab the semi-colon... getCodeToken(); if (CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) codeSegmentPtr = (char*)ExitOrderCodeSegment; else if (CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE) codeSegmentPtr = (char*)ExitStateCodeSegment; else codeSegmentPtr = (char*)ExitRoutineCodeSegment; ExitWithReturn = true; getCodeToken(); }
long ABLi_peekInteger (void) { getCodeToken(); execExpression(); return(tos->integer); }
int procSetUnit(unitPtr uPtr,char *sendBuf,short *sendLen,char bitpos,char *pRecvPtr) { char string[256]; char error[1000]; char buffer[MAXBUF]; char input[MAXBUF]; char *errPtr=error; /* short t; */ float erg=0.0; int ergI=0; short count; char ergType; float floatV; char *inPtr; /* hier die Typen fuer die Umrechnung in <type> Tag */ int8_t charV; uint8_t ucharV; int16_t shortV; int16_t tmpS; uint16_t ushortV; uint16_t tmpUS; int32_t intV; int32_t tmpI; uint32_t tmpUI; uint32_t uintV; bzero(errPtr,sizeof(error)); /* etwas logging */ int n=0; char *ptr; char dumBuf[10]; bzero(dumBuf,sizeof(dumBuf)); bzero(buffer,sizeof(buffer)); /* wir kopieren uns den sendBuf, da dieser auch als return genutzt wird */ strncpy(input,sendBuf,sizeof(input)); bzero(sendBuf,sizeof(sendBuf)); if (strstr(uPtr->type,"cycletime")==uPtr->type) { /* Schaltzeit */ if (! *input) return(-1); if (!(*sendLen=setCycleTime(input,sendBuf))) return(-1); else { return(1); } } if (strstr(uPtr->type,"systime")==uPtr->type) { /* Schaltzeit */ if (!(*sendLen=setSysTime(input,sendBuf,*sendLen))) return(-1); else { return(1); } } else if (strstr(uPtr->type,"enum")==uPtr->type) { /*enum*/ if (! *input) return(-1); if(!(count=text2Enum(uPtr->ePtr,input,&ptr,sendLen))) { sprintf(sendBuf,"Kein passendes Enum gefunden"); return(-1); } else { memcpy(sendBuf,ptr,count); return(1); } } if (! *input) return(-1); /* hier der uebergebene Wert */ if (uPtr->sCalc && *uPtr->sCalc) { /* <calc im XML und set darin definiert */ floatV=atof(input); inPtr=uPtr->sCalc; logIT(LOG_INFO,"Send Exp:%s [V=%f]",inPtr,floatV); erg=execExpression(&inPtr,dumBuf,floatV,errPtr); if (*errPtr) { snprintf(string, sizeof(string),"Exec %s: %s",uPtr->sCalc,error); logIT(LOG_ERR,string); strcpy(sendBuf,string); return(-1); } ergType=FLOAT; } if (uPtr->sICalc && *uPtr->sICalc) { /* <icalc im XML und set darin definiert */ inPtr=uPtr->sICalc; if( uPtr->ePtr) {/* es gibt enums hier */ if (! *input) { sprintf(sendBuf,"Input fehlt"); return(-1); } if(!(count=text2Enum(uPtr->ePtr,input,&ptr,sendLen))) { sprintf(sendBuf,"Kein passendes Enum gefunden"); return(-1); } else { bzero(dumBuf,sizeof(dumBuf)); memcpy(dumBuf,ptr,count); logIT(LOG_INFO,"(INT) Exp:%s [BP:%d]",inPtr,bitpos); ergI=execIExpression(&inPtr,dumBuf,bitpos,pRecvPtr,errPtr); if (*errPtr) { snprintf(string, sizeof(string),"Exec %s: %s",uPtr->sICalc,error); logIT(LOG_ERR,string); strcpy(sendBuf,string); return(-1); } ergType=INT; snprintf(string, sizeof(string),"Erg: (Hex max. 4Byte) %08x",ergI); } } } /* das Ergebnis steht in erg und muss nun je nach typ umgewandelt werden */ if (uPtr->type) { if (strstr(uPtr->type,"char")==uPtr->type) { /* Umrechnung in Short 2Byte */ /* je nach CPU Typ wird hier die Wandlung vorgenommen */ (ergType==FLOAT) ? (charV=erg) : (charV=ergI); memcpy(sendBuf,&charV,1); *sendLen=1; } else if (strstr(uPtr->type,"uchar")==uPtr->type) { /* je nach CPU Typ wird hier die Wandlung vorgenommen */ (ergType==FLOAT) ? (ucharV=erg) : (ucharV=ergI); memcpy(sendBuf,&ucharV,1); *sendLen=1; } else if (strstr(uPtr->type,"short")==uPtr->type) { /* je nach CPU Typ wird hier die Wandlung vorgenommen */ (ergType==FLOAT) ? (tmpS=erg) : (tmpS=ergI); shortV=__cpu_to_le16(tmpS); memcpy(sendBuf,&shortV,2); *sendLen=2; } else if (strstr(uPtr->type,"ushort")==uPtr->type) { /* je nach CPU Typ wird hier die Wandlung vorgenommen */ (ergType==FLOAT) ? (tmpUS=erg) : (tmpUS=ergI); ushortV=__cpu_to_le16(tmpUS); memcpy(sendBuf,&ushortV,2); *sendLen=2; } else if (strstr(uPtr->type,"int")==uPtr->type) { /* je nach CPU Typ wird hier die Wandlung vorgenommen */ (ergType==FLOAT) ? (tmpI=erg) : (tmpI=ergI); intV=__cpu_to_le32(tmpI); memcpy(sendBuf,&intV,2); *sendLen=4; } else if (strstr(uPtr->type,"uint")==uPtr->type) { /* je nach CPU Typ wird hier die Wandlung vorgenommen */ (ergType==FLOAT) ? (tmpUI=erg) : (tmpUI=ergI); uintV=__cpu_to_le32(tmpUI); memcpy(sendBuf,&uintV,2); } else if (uPtr->type) { bzero(string,sizeof(string)); snprintf(string, sizeof(string),"Unbekannter Typ %s in Unit %s",uPtr->type,uPtr->name); logIT(LOG_ERR,string); return(-1); } bzero(buffer,sizeof(buffer)); ptr=sendBuf; while(*ptr) { bzero(string,sizeof(string)); unsigned char byte=*ptr++ & 255; snprintf(string, sizeof(string),"%02X ",byte); strcat(buffer,string); if (n >= MAXBUF-3) /* FN Wo wird 'n' eigentlich initialisiert */ break; } snprintf(string, sizeof(string),"Typ: %s (Bytes: %s) ",uPtr->type,buffer); logIT(LOG_INFO,string); return(1); } return (0); /* Wenn ich das richtig verstehe, sollten wir hier nie landen FN, deshalb; keep compiler happy */ }
int procGetUnit(unitPtr uPtr,char *recvBuf,int recvLen,char *result,char bitpos,char *pRecvPtr) { char string[256]; char error[1000]; char buffer[MAXBUF]; char *errPtr=error; /* short t; */ float erg; int ergI; char formatI[20]; float floatV=0; char *inPtr; char *tPtr; /* hier die Typen fuer die Umrechnung in <type> Tag */ int8_t charV; uint8_t ucharV; int16_t shortV; int16_t tmpS; uint16_t ushortV; uint16_t tmpUS; int32_t intV; int32_t tmpI; uint32_t tmpUI; uint32_t uintV; bzero(errPtr,sizeof(error)); /* wir behandeln die verschiedenen <type> Eintraege */ if (strstr(uPtr->type,"cycletime")==uPtr->type) { /* Schaltzeit */ if (getCycleTime(recvBuf,recvLen,result)) return(1); else return(-1); } else if (strstr(uPtr->type,"systime")==uPtr->type) { /* Systemzeit */ if (getSysTime(recvBuf,recvLen,result)) return(1); else return(-1); } else if (strstr(uPtr->type,"errstate")==uPtr->type) { /* Errrocode + Systemzeit */ if (getErrState(uPtr->ePtr,recvBuf,recvLen,result)) return(1); else return(-1); } else if (strstr(uPtr->type,"enum")==uPtr->type) { /*enum*/ if(bytes2Enum(uPtr->ePtr,recvBuf,&tPtr,recvLen)) { strcpy(result,tPtr); return(1); } else { sprintf(result,"Kein passendes Enum gefunden"); return(-1); } } /* hier kommen die ganzen numerischen Typen */ if (strstr(uPtr->type,"char")==uPtr->type) { /* Umrechnung in Char 1Byte */ memcpy(&charV,recvBuf,1); floatV=charV; /* impliziete Typumnwandlung nach float fuer unsere Arithmetic */ sprintf(formatI,"%%02X %%s"); } else if (strstr(uPtr->type,"uchar")==uPtr->type) { /* Umrechnung in Unsigned Char 1Byte */ memcpy(&ucharV,recvBuf,1); floatV=ucharV; /* impliziete Typumnwandlung nach float fuer unsere Arithmetic */ sprintf(formatI,"%%02X %%s"); } else if (strstr(uPtr->type,"short")==uPtr->type) { /* Umrechnung in Short 2Byte */ memcpy(&tmpS,recvBuf,2); /* je nach CPU Typ wird hier die Wandlung vorgenommen */ shortV=__le16_to_cpu(tmpS); floatV=shortV; /* impliziete Typumnwandlung nach float fuer unsere Arithmetic */ sprintf(formatI,"%%04X %%s"); } else if (strstr(uPtr->type,"ushort")==uPtr->type) { /* Umrechnung in Short 2Byte */ memcpy(&tmpUS,recvBuf,2); /* je nach CPU Typ wird hier die Wandlung vorgenommen */ ushortV=__le16_to_cpu(tmpUS); floatV=ushortV; /* impliziete Typumnwandlung nach float fuer unsere Arithmetic */ sprintf(formatI,"%%04X %%s"); } else if (strstr(uPtr->type,"int")==uPtr->type) { /* Umrechnung in Int 4Byte */ memcpy(&tmpI,recvBuf,4); /* je nach CPU Typ wird hier die Wandlung vorgenommen */ intV=__le32_to_cpu(tmpI); floatV=intV; /* impliziete Typumnwandlung nach float fuer unsere Arithmetic */ sprintf(formatI,"%%08X %%s"); } else if (strstr(uPtr->type,"uint")==uPtr->type) { /* Umrechnung in Unsigned Int 4Byte */ memcpy(&tmpUI,recvBuf,4); /* je nach CPU Typ wird hier die Wandlung vorgenommen */ uintV=__le32_to_cpu(tmpUI); floatV=uintV; /* impliziete Typumnwandlung nach float fuer unsere Arithmetic */ sprintf(formatI,"%%08X %%s"); } else if (uPtr->type) { bzero(string,sizeof(string)); snprintf(string, sizeof(string),"Unbekannter Typ %s in Unit %s",uPtr->type,uPtr->name); logIT(LOG_ERR,string); return(-1); } /* etwas logging */ int n; char *ptr; char res; ptr=recvBuf; bzero(buffer,sizeof(buffer)); for(n=0;n<=9;n++) {/* Bytes 0..9 sind von Interesse */ bzero(string,sizeof(string)); unsigned char byte=*ptr++ & 255; snprintf(string, sizeof(string),"B%d:%02X ",n,byte); strcat(buffer,string); if (n >= MAXBUF-3) break; } if (uPtr->gCalc && *uPtr->gCalc) { /* <calc im XML und get darin definiert */ snprintf(string, sizeof(string),"Typ: %s (in float: %f)",uPtr->type,floatV); logIT(LOG_INFO,string); inPtr=uPtr->gCalc; snprintf(string, sizeof(string),"(FLOAT) Exp:%s [%s]",inPtr,buffer); logIT(LOG_INFO,string); erg=execExpression(&inPtr,recvBuf,floatV,errPtr); if (*errPtr) { snprintf(string, sizeof(string),"Exec %s: %s",uPtr->gCalc,error); logIT(LOG_ERR,string); strcpy(result,string); return(-1); } sprintf(result,"%f %s",erg,uPtr->entity); } else if (uPtr->gICalc && *uPtr->gICalc) { /* <icalc im XML und get darin definiert */ inPtr=uPtr->gICalc; snprintf(string, sizeof(string),"(INT) Exp:%s [BP:%d] [%s]",inPtr,bitpos,buffer); logIT(LOG_INFO,string); ergI=execIExpression(&inPtr,recvBuf,bitpos,pRecvPtr,errPtr); if (*errPtr) { snprintf(string, sizeof(string),"Exec %s: %s",uPtr->gCalc,error); logIT(LOG_ERR,string); strcpy(result,string); return(-1); } snprintf(string, sizeof(string),"Erg: (Hex max. 4Byte) %08x",ergI); logIT(LOG_INFO,string); res=ergI; if( uPtr->ePtr && bytes2Enum(uPtr->ePtr,&res,&tPtr,recvLen)) { strcpy(result,tPtr); return(1); } else { sprintf(result,formatI,ergI,uPtr->entity); return(1); } /* hier noch das durchsuchen der enums ggf durchfuehren */ } return(1); }
TypePtr execFactor(void) { TypePtr resultTypePtr = nullptr; switch (codeToken) { case TKN_IDENTIFIER: { SymTableNodePtr idPtr = getCodeSymTableNodePtr(); if (idPtr->defn.key == DFN_FUNCTION) { SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr; resultTypePtr = execRoutineCall(idPtr, false); CurRoutineIdPtr = thisRoutineIdPtr; } else if (idPtr->defn.key == DFN_CONST) resultTypePtr = execConstant(idPtr); else resultTypePtr = execVariable(idPtr, USE_EXPR); } break; case TKN_NUMBER: { SymTableNodePtr numberPtr = getCodeSymTableNodePtr(); if (numberPtr->typePtr == IntegerTypePtr) { pushInteger(numberPtr->defn.info.constant.value.integer); resultTypePtr = IntegerTypePtr; } else { pushReal(numberPtr->defn.info.constant.value.real); resultTypePtr = RealTypePtr; } getCodeToken(); } break; case TKN_STRING: { SymTableNodePtr nodePtr = getCodeSymTableNodePtr(); int32_t length = strlen(nodePtr->name); if (length > 1) { //----------------------------------------------------------------------- // Remember, the double quotes are on the back and front of the // string... pushAddress(nodePtr->info); resultTypePtr = nodePtr->typePtr; } else { //---------------------------------------------- // Just push the one character in this string... pushByte(nodePtr->name[0]); resultTypePtr = CharTypePtr; } getCodeToken(); } break; case TKN_NOT: getCodeToken(); resultTypePtr = execFactor(); //-------------------------------------- // Following flips 1 to 0, and 0 to 1... tos->integer = 1 - tos->integer; break; case TKN_LPAREN: getCodeToken(); resultTypePtr = execExpression(); getCodeToken(); break; } return (resultTypePtr); }