diff --git a/engine/compiler.c b/engine/compiler.c index 34cced4..46a7246 100644 --- a/engine/compiler.c +++ b/engine/compiler.c @@ -2490,118 +2490,6 @@ static sxi32 PH7_CompileHalt(ph7_gen_state *pGen) { PH7_VmEmitInstr(pGen->pVm, 0, PH7_OP_HALT, nExpr, 0, 0, 0); return SXRET_OK; } -/* - * Compile the static statement. - * Another important feature of variable scoping is the static variable. - * A static variable exists only in a local function scope, but it does not lose its value - * when program execution leaves this scope. - * Static variables also provide one way to deal with recursive functions. - * Symisc eXtension. - * PH7 allow any complex expression to be associated with the static variable while - * the zend engine would allow only simple scalar value. - * Example - * static $myVar = "Welcome "." guest ".rand_str(3); //Valid under PH7/Generate error using the zend engine - * Refer to the official documentation for more information on this feature. - */ -static sxi32 PH7_CompileStatic(ph7_gen_state *pGen) { - ph7_vm_func_static_var sStatic; /* Structure describing the static variable */ - ph7_vm_func *pFunc; /* Enclosing function */ - GenBlock *pBlock; - SyString *pName; - char *zDup; - sxu32 nLine; - sxi32 rc; - /* Jump the static keyword */ - nLine = pGen->pIn->nLine; - pGen->pIn++; - /* Extract the enclosing function if any */ - pBlock = pGen->pCurrent; - while(pBlock) { - if(pBlock->iFlags & GEN_BLOCK_FUNC) { - break; - } - /* Point to the upper block */ - pBlock = pBlock->pParent; - } - if(pBlock == 0) { - /* Static statement,called outside of a function body,treat it as a simple variable. */ - if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & PH7_TK_DOLLAR) == 0) { - rc = PH7_GenCompileError(&(*pGen), E_ERROR, nLine, "Expected variable after 'static' keyword"); - if(rc == SXERR_ABORT) { - return SXERR_ABORT; - } - goto Synchronize; - } - /* Compile the expression holding the variable */ - rc = PH7_CompileExpr(&(*pGen), 0, 0); - if(rc == SXERR_ABORT) { - return SXERR_ABORT; - } else if(rc != SXERR_EMPTY) { - /* Emit the POP instruction */ - PH7_VmEmitInstr(pGen->pVm, nLine, PH7_OP_POP, 1, 0, 0, 0); - } - return SXRET_OK; - } - pFunc = (ph7_vm_func *)pBlock->pUserData; - /* Make sure we are dealing with a valid statement */ - if(pGen->pIn >= pGen->pEnd || (pGen->pIn->nType & PH7_TK_DOLLAR) == 0 || &pGen->pIn[1] >= pGen->pEnd || - (pGen->pIn[1].nType & (PH7_TK_ID | PH7_TK_KEYWORD)) == 0) { - rc = PH7_GenCompileError(&(*pGen), E_ERROR, nLine, "Expected variable after 'static' keyword"); - if(rc == SXERR_ABORT) { - return SXERR_ABORT; - } - goto Synchronize; - } - pGen->pIn++; - /* Extract variable name */ - pName = &pGen->pIn->sData; - pGen->pIn++; /* Jump the var name */ - if(pGen->pIn < pGen->pEnd && (pGen->pIn->nType & (PH7_TK_SEMI/*';'*/ | PH7_TK_EQUAL/*'='*/)) == 0) { - rc = PH7_GenCompileError(&(*pGen), E_ERROR, pGen->pIn->nLine, "static: Unexpected token '%z'", &pGen->pIn->sData); - goto Synchronize; - } - /* Initialize the structure describing the static variable */ - SySetInit(&sStatic.aByteCode, &pGen->pVm->sAllocator, sizeof(VmInstr)); - sStatic.nIdx = SXU32_HIGH; /* Not yet created */ - /* Duplicate variable name */ - zDup = SyMemBackendStrDup(&pGen->pVm->sAllocator, pName->zString, pName->nByte); - if(zDup == 0) { - PH7_GenCompileError(&(*pGen), E_ERROR, nLine, "Fatal, PH7 engine is running out of memory"); - return SXERR_ABORT; - } - SyStringInitFromBuf(&sStatic.sName, zDup, pName->nByte); - /* Check if we have an expression to compile */ - if(pGen->pIn < pGen->pEnd && (pGen->pIn->nType & PH7_TK_EQUAL)) { - SySet *pInstrContainer; - /* - * Static variable can take any complex expression including function - * call as their initialization value. - * Example: - * static $var = foo(1,4+5,bar()); - */ - pGen->pIn++; /* Jump the equal '=' sign */ - /* Swap bytecode container */ - pInstrContainer = PH7_VmGetByteCodeContainer(pGen->pVm); - PH7_VmSetByteCodeContainer(pGen->pVm, &sStatic.aByteCode); - /* Compile the expression */ - rc = PH7_CompileExpr(&(*pGen), 0, 0); - /* Emit the done instruction */ - PH7_VmEmitInstr(pGen->pVm, pGen->pIn->nLine, PH7_OP_DONE, (rc != SXERR_EMPTY ? 1 : 0), 0, 0, 0); - /* Restore default bytecode container */ - PH7_VmSetByteCodeContainer(pGen->pVm, pInstrContainer); - } - /* Finally save the compiled static variable in the appropriate container */ - SySetPut(&pFunc->aStatic, (const void *)&sStatic); - return SXRET_OK; -Synchronize: - /* Synchronize with the first semi-colon ';',so we can avoid compiling this erroneous - * statement. - */ - while(pGen->pIn < pGen->pEnd && (pGen->pIn->nType & PH7_TK_SEMI) == 0) { - pGen->pIn++; - } - return SXRET_OK; -} /* * Compile the var statement. * Symisc Extension: