/* * Free an expression tree. */ static void ExprFreeTree(jx9_gen_state *pGen, jx9_expr_node *pNode) { if( pNode->pLeft ){ /* Release the left tree */ ExprFreeTree(&(*pGen), pNode->pLeft); } if( pNode->pRight ){ /* Release the right tree */ ExprFreeTree(&(*pGen), pNode->pRight); } if( pNode->pCond ){ /* Release the conditional tree used by the ternary operator */ ExprFreeTree(&(*pGen), pNode->pCond); } if( SySetUsed(&pNode->aNodeArgs) > 0 ){ jx9_expr_node **apArg; sxu32 n; /* Release node arguments */ apArg = (jx9_expr_node **)SySetBasePtr(&pNode->aNodeArgs); for( n = 0 ; n < SySetUsed(&pNode->aNodeArgs) ; ++n ){ ExprFreeTree(&(*pGen), apArg[n]); } SySetRelease(&pNode->aNodeArgs); } /* Finally, release this node */ SyMemBackendPoolFree(&pGen->pVm->sAllocator, pNode); }
/* * Free an expression tree. * This function is a wrapper around ExprFreeTree() defined above. */ JX9_PRIVATE sxi32 jx9ExprFreeTree(jx9_gen_state *pGen, SySet *pNodeSet) { jx9_expr_node **apNode; sxu32 n; apNode = (jx9_expr_node **)SySetBasePtr(pNodeSet); for( n = 0 ; n < SySetUsed(pNodeSet) ; ++n ){ if( apNode[n] ){ ExprFreeTree(&(*pGen), apNode[n]); } } return SXRET_OK; }
/* * Exported JSON decoding interface */ JX9_PRIVATE int jx9JsonDecode(jx9_context *pCtx,const char *zJSON,int nByte) { jx9_vm *pVm = pCtx->pVm; json_decoder sDecoder; SySet sToken; SyLex sLex; sxi32 rc; /* Tokenize the input */ SySetInit(&sToken, &pVm->sAllocator, sizeof(SyToken)); rc = SXRET_OK; SyLexInit(&sLex, &sToken, VmJsonTokenize, &rc); SyLexTokenizeInput(&sLex,zJSON,(sxu32)nByte, 0, 0, 0); if( rc != SXRET_OK ){ /* Something goes wrong while tokenizing input. [i.e: Unexpected token] */ SyLexRelease(&sLex); SySetRelease(&sToken); /* return NULL */ jx9_result_null(pCtx); return JX9_OK; } /* Fill the decoder */ sDecoder.pCtx = pCtx; sDecoder.pErr = &rc; sDecoder.pIn = (SyToken *)SySetBasePtr(&sToken); sDecoder.pEnd = &sDecoder.pIn[SySetUsed(&sToken)]; sDecoder.iFlags = 0; sDecoder.rec_count = 0; /* Set a default consumer */ sDecoder.xConsumer = VmJsonDefaultDecoder; sDecoder.pUserData = 0; /* Decode the raw JSON input */ rc = VmJsonDecode(&sDecoder, 0); if( rc == SXERR_ABORT ){ /* * Something goes wrong while decoding JSON input.Return NULL. */ jx9_result_null(pCtx); } /* Clean-up the mess left behind */ SyLexRelease(&sLex); SySetRelease(&sToken); /* All done */ return JX9_OK; }
/* * Build an expression tree from the freshly extracted raw tokens. * If successful, the root of the tree is stored in ppRoot. * When errors, JX9 take care of generating the appropriate error message. * This is the public interface used by the most code generator routines. */ JX9_PRIVATE sxi32 jx9ExprMakeTree(jx9_gen_state *pGen, SySet *pExprNode, jx9_expr_node **ppRoot) { jx9_expr_node **apNode; jx9_expr_node *pNode; sxi32 rc; /* Reset node container */ SySetReset(pExprNode); pNode = 0; /* Prevent compiler warning */ /* Extract nodes one after one until we hit the end of the input */ while( pGen->pIn < pGen->pEnd ){ rc = ExprExtractNode(&(*pGen), &pNode); if( rc != SXRET_OK ){ return rc; } /* Save the extracted node */ SySetPut(pExprNode, (const void *)&pNode); } if( SySetUsed(pExprNode) < 1 ){ /* Empty expression [i.e: A semi-colon;] */ *ppRoot = 0; return SXRET_OK; } apNode = (jx9_expr_node **)SySetBasePtr(pExprNode); /* Make sure we are dealing with valid nodes */ rc = ExprVerifyNodes(&(*pGen), apNode, (sxi32)SySetUsed(pExprNode)); if( rc != SXRET_OK ){ /* Don't worry about freeing memory, upper layer will * cleanup the mess left behind. */ *ppRoot = 0; return rc; } /* Build the tree */ rc = ExprMakeTree(&(*pGen), apNode, (sxi32)SySetUsed(pExprNode)); if( rc != SXRET_OK ){ /* Something goes wrong [i.e: Syntax error] */ *ppRoot = 0; return rc; } /* Point to the root of the tree */ *ppRoot = apNode[0]; return SXRET_OK; }