LANDRU_DECL_FN(ColorVarObj, getV3f) { ColorVarObj* o = (ColorVarObj*) p->vo.get(); p->stack->pop(); pushReal(p, o->b); pushReal(p, o->g); pushReal(p, o->r); }
LANDRU_DECL_FN(ColorVarObj, getV2f) { ColorVarObj* o = (ColorVarObj*) p->vo.get(); p->stack->pop(); pushReal(p, o->a); float Y = 0.3f * o->r + 0.59f * o->g + 0.11f * o->b; pushReal(p, Y); }
void allocLocal(TypePtr typePtr) { if(typePtr == IntegerTypePtr) pushInteger(0); else if(typePtr == RealTypePtr) pushReal((float)0.0); else if(typePtr == BooleanTypePtr) pushByte(0); else if(typePtr == CharTypePtr) pushByte(0); else switch(typePtr->form) { case FRM_ENUM: pushInteger(0); break; // NOTE: We currently are not supporting sub ranges, until // we really want 'em... // case FRM_SUBRANGE: // allocLocal(typePtr->info.subrange.rangeTypePtr); // break; case FRM_ARRAY: PSTR ptr = (PSTR)ABLStackMallocCallback(typePtr->size); if(!ptr) ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc local array "); pushAddress((Address)ptr); break; } }
TypePtr execConstant(SymTableNodePtr idPtr) { TypePtr typePtr = idPtr->typePtr; if ((typePtr == IntegerTypePtr) || (typePtr->form == FRM_ENUM)) pushInteger(idPtr->defn.info.constant.value.integer); else if (typePtr == RealTypePtr) pushReal(idPtr->defn.info.constant.value.real); else if (typePtr == CharTypePtr) pushInteger(idPtr->defn.info.constant.value.character); else if (typePtr->form == FRM_ARRAY) pushAddress(idPtr->defn.info.constant.value.stringPtr); if (debugger) debugger->traceDataFetch(idPtr, typePtr, tos); getCodeToken(); return (typePtr); }
int32_t ABLModule::execute(ABLParamPtr moduleParamList, SymTableNodePtr functionIdPtr) { CurModule = this; if(debugger) debugger->setModule(this); //-------------------------- // Execute the ABL module... SymTableNodePtr moduleIdPtr = ModuleRegistry[handle].moduleIdPtr; if(moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) CurFSM = this; else CurFSM = nullptr; NumStateTransitions = 0; //-------------------------------------------- // Point to this module's static data space... StaticDataPtr = staticData; OrderCompletionFlags = orderCallFlags; //--------------------------------- // Init some important variables... CurModuleIdPtr = nullptr; CurRoutineIdPtr = nullptr; FileNumber = -1; errorCount = 0; execStatementCount = 0; NumExecutions++; NewStateSet = false; //------------------ // Init the stack... stackFrameBasePtr = tos = (stack + eternalOffset); //--------------------------------------- // Initialize the module's stack frame... level = 1; CallStackLevel = 0; stackFrameBasePtr = tos + 1; //------------------------- // Function return value... pushInteger(0); //--------------- // Static Link... pushAddress(nullptr); //---------------- // Dynamic Link... pushAddress(nullptr); //------------------ // Return Address... pushAddress(nullptr); //initDebugger(); //---------- // Run it... if(moduleParamList) { //------------------------------------------------------------------------------ // NOTE: Currently, parameter passing of arrays is not functioning. This MUST be // done... int32_t curParam = 0; for(SymTableNodePtr formalIdPtr = (SymTableNodePtr)(moduleIdPtr->defn.info.routine.params); formalIdPtr != nullptr; formalIdPtr = formalIdPtr->next) { TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr); if(formalIdPtr->defn.key == DFN_VALPARAM) { if(formalTypePtr == RealTypePtr) { if(moduleParamList[curParam].type == ABL_PARAM_INTEGER) { //--------------------------------------------- // Real formal parameter, but integer actual... pushReal((float)(moduleParamList[curParam].integer)); } else if(moduleParamList[curParam].type == ABL_PARAM_REAL) pushReal(moduleParamList[curParam].real); } else if(formalTypePtr == IntegerTypePtr) { if(moduleParamList[curParam].type == ABL_PARAM_INTEGER) pushInteger(moduleParamList[curParam].integer); else return(0); } //---------------------------------------------------------- // 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 dest = (PSTR)ABLStackMallocCallback((size_t)size); if(!dest) { char err[255]; sprintf(err, "ABL: Unable to AblStackHeap->malloc array parameter [Module %d]", id); ABL_Fatal(0, err); } PSTR src = tos->address; PSTR savePtr = dest; memcpy(dest, src, size); tos->address = savePtr; } } else { //------------------------------- // pass by reference parameter... if(formalTypePtr == RealTypePtr) pushAddress((Address) & (moduleParamList[curParam].real)); else if(formalTypePtr == IntegerTypePtr) pushAddress((Address) & (moduleParamList[curParam].integer)); else return(0); } curParam++; } } CurModuleHandle = handle; CallModuleInit = !initCalled; initCalled = true; ::executeChild(moduleIdPtr, functionIdPtr); memcpy(&returnVal, &returnValue, sizeof(StackItem)); //----------- // Summary... return(execStatementCount); }
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); }