void dictHashSummary(FICL_VM *pVM) { FICL_DICT *dp = vmGetDict(pVM); FICL_HASH *pFHash; FICL_WORD **pHash; unsigned size; FICL_WORD *pFW; unsigned i; int nMax = 0; int nWords = 0; int nFilled; double avg = 0.0; double best; int nAvg, nRem, nDepth; dictCheck(dp, pVM, 0); pFHash = dp->pSearch[dp->nLists - 1]; pHash = pFHash->table; size = pFHash->size; nFilled = size; for (i = 0; i < size; i++) { int n = 0; pFW = pHash[i]; while (pFW) { ++n; ++nWords; pFW = pFW->link; } avg += (double)(n * (n+1)) / 2.0; if (n > nMax) nMax = n; if (n == 0) --nFilled; } /* Calc actual avg search depth for this hash */ avg = avg / nWords; /* Calc best possible performance with this size hash */ nAvg = nWords / size; nRem = nWords % size; nDepth = size * (nAvg * (nAvg+1))/2 + (nAvg+1)*nRem; best = (double)nDepth/nWords; sprintf(pVM->pad, "%d bins, %2.0f%% filled, Depth: Max=%d, Avg=%2.1f, Best=%2.1f, Score: %2.0f%%", size, (double)nFilled * 100.0 / size, nMax, avg, best, 100.0 * best / avg); ficlTextOut(pVM, pVM->pad, 1); return; }
int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT size) { FICL_SYSTEM *pSys = pVM->pSys; FICL_DICT *dp = pSys->dp; int except; jmp_buf vmState; jmp_buf *oldState; TIB saveTib; assert(pVM); assert(pSys->pInterp[0]); if (size < 0) size = strlen(pText); vmPushTib(pVM, pText, size, &saveTib); /* ** Save and restore VM's jmp_buf to enable nested calls to ficlExec */ oldState = pVM->pState; pVM->pState = &vmState; /* This has to come before the setjmp! */ except = setjmp(vmState); switch (except) { case 0: if (pVM->fRestart) { pVM->runningWord->code(pVM); pVM->fRestart = 0; } else { /* set VM up to interpret text */ vmPushIP(pVM, &(pSys->pInterp[0])); } vmInnerLoop(pVM); break; case VM_RESTART: pVM->fRestart = 1; except = VM_OUTOFTEXT; break; case VM_OUTOFTEXT: vmPopIP(pVM); #ifdef TESTMAIN if ((pVM->state != COMPILE) && (pVM->sourceID.i == 0)) ficlTextOut(pVM, FICL_PROMPT, 0); #endif break; case VM_USEREXIT: case VM_INNEREXIT: case VM_BREAK: break; case VM_QUIT: if (pVM->state == COMPILE) { dictAbortDefinition(dp); #if FICL_WANT_LOCALS dictEmpty(pSys->localp, pSys->localp->pForthWords->size); #endif } vmQuit(pVM); break; case VM_ERREXIT: case VM_ABORT: case VM_ABORTQ: default: /* user defined exit code?? */ if (pVM->state == COMPILE) { dictAbortDefinition(dp); #if FICL_WANT_LOCALS dictEmpty(pSys->localp, pSys->localp->pForthWords->size); #endif } dictResetSearchOrder(dp); vmReset(pVM); break; } pVM->pState = oldState; vmPopTib(pVM, &saveTib); return (except); }