ref: 7d02e382d314d5bdde7978ccb7a64ea9201d03db
dir: /ficlcompatibility.h/
#ifndef FICL_FORCE_COMPATIBILITY struct ficl_word; typedef struct ficl_word FICL_WORD; struct vm; typedef struct vm FICL_VM; struct ficl_dict; typedef struct ficl_dict FICL_DICT; struct ficl_system; typedef struct ficl_system FICL_SYSTEM; struct ficl_system_info; typedef struct ficl_system_info FICL_SYSTEM_INFO; #define ficlFILE ficlFile typedef ficlUnsigned FICL_UNS; typedef ficlInteger FICL_INT; typedef ficlFloat FICL_FLOAT; typedef ficlUnsigned16 UNS16; typedef ficlUnsigned8 UNS8; #define _cell ficlCell #define CELL ficlCell #define LVALUEtoCELL(v) (*(ficlCell *)&v) #define PTRtoCELL (ficlCell *)(void *) #define PTRtoSTRING (ficlCountedString *)(void *) typedef unsigned char FICL_COUNT; #define FICL_STRING_MAX UCHAR_MAX typedef struct _ficl_string { ficlUnsigned8 count; char text[1]; } FICL_STRING; typedef struct { ficlUnsigned count; char *cp; } STRINGINFO; #define SI_COUNT(si) (si.count) #define SI_PTR(si) (si.cp) #define SI_SETLEN(si, len) (si.count = (FICL_UNS)(len)) #define SI_SETPTR(si, ptr) (si.cp = (char *)(ptr)) #define SI_PSZ(si, psz) \ {si.cp = psz; si.count = (FICL_COUNT)strlen(psz);} #define SI_PFS(si, pfs) \ {si.cp = pfs->text; si.count = pfs->count;} typedef struct { ficlInteger index; char *end; char *cp; } TIB; typedef struct _ficlStack { ficlUnsigned nCells; /* size of the stack */ CELL *pFrame; /* link reg for stack frame */ CELL *sp; /* stack pointer */ ficlVm *vm; char *name; CELL base[1]; /* Top of stack */ } FICL_STACK; FICL_STACK *stackCreate (unsigned nCells); void stackDelete (FICL_STACK *pStack); int stackDepth (FICL_STACK *pStack); void stackDrop (FICL_STACK *pStack, int n); CELL stackFetch (FICL_STACK *pStack, int n); CELL stackGetTop (FICL_STACK *pStack); void stackLink (FICL_STACK *pStack, int nCells); void stackPick (FICL_STACK *pStack, int n); CELL stackPop (FICL_STACK *pStack); void *stackPopPtr (FICL_STACK *pStack); FICL_UNS stackPopUNS (FICL_STACK *pStack); FICL_INT stackPopINT (FICL_STACK *pStack); void stackPush (FICL_STACK *pStack, CELL c); void stackPushPtr (FICL_STACK *pStack, void *ptr); void stackPushUNS (FICL_STACK *pStack, FICL_UNS u); void stackPushINT (FICL_STACK *pStack, FICL_INT i); void stackReset (FICL_STACK *pStack); void stackRoll (FICL_STACK *pStack, int n); void stackSetTop (FICL_STACK *pStack, CELL c); void stackStore (FICL_STACK *pStack, int n, CELL c); void stackUnlink (FICL_STACK *pStack); #if (FICL_WANT_FLOAT) float stackPopFloat (FICL_STACK *pStack); void stackPushFloat(FICL_STACK *pStack, FICL_FLOAT f); #endif #define PUSHPTR(p) stackPushPtr(pVM->pStack,p) #define PUSHUNS(u) stackPushUNS(pVM->pStack,u) #define PUSHINT(i) stackPushINT(pVM->pStack,i) #define PUSHFLOAT(f) stackPushFloat(pVM->fStack,f) #define PUSH(c) stackPush(pVM->pStack,c) #define POPPTR() stackPopPtr(pVM->pStack) #define POPUNS() stackPopUNS(pVM->pStack) #define POPINT() stackPopINT(pVM->pStack) #define POPFLOAT() stackPopFloat(pVM->fStack) #define POP() stackPop(pVM->pStack) #define GETTOP() stackGetTop(pVM->pStack) #define SETTOP(c) stackSetTop(pVM->pStack,LVALUEtoCELL(c)) #define GETTOPF() stackGetTop(pVM->fStack) #define SETTOPF(c) stackSetTop(pVM->fStack,LVALUEtoCELL(c)) #define STORE(n,c) stackStore(pVM->pStack,n,LVALUEtoCELL(c)) #define DEPTH() stackDepth(pVM->pStack) #define DROP(n) stackDrop(pVM->pStack,n) #define DROPF(n) stackDrop(pVM->fStack,n) #define FETCH(n) stackFetch(pVM->pStack,n) #define PICK(n) stackPick(pVM->pStack,n) #define PICKF(n) stackPick(pVM->fStack,n) #define ROLL(n) stackRoll(pVM->pStack,n) #define ROLLF(n) stackRoll(pVM->fStack,n) typedef FICL_WORD ** IPTYPE; /* the VM's instruction pointer */ typedef void (*OUTFUNC)(FICL_VM *pVM, char *text, int fNewline); /* values of STATE */ #define INTERPRET FICL_STATE_INTERPRET #define COMPILE FICL_STATE_COMPILE #if !defined nPAD #define nPAD FICL_PAD_SIZE #endif #if !defined nFICLNAME #define nFICLNAME FICL_NAME_LENGTH #endif #define FICL_DEFAULT_STACK FICL_DEFAULT_STACK_SIZE #define FICL_DEFAULT_DICT FICL_DEFAULT_DICTIONARY_SIZE #define FICL_DEFAULT_ENV FICL_DEFAULT_ENVIRONMENT_SIZE #define FICL_DEFAULT_VOCS FICL_MAX_WORDLISTS struct vm { void *pExtend; ficlOutputFunction textOut; ficlOutputFunction errorOut; ficlSystem *pSys; ficlVm *pVM; FICL_VM *link; /* Ficl keeps a VM list for simple teardown */ jmp_buf *pState; /* crude exception mechanism... */ short fRestart; /* Set TRUE to restart runningWord */ IPTYPE ip; /* instruction pointer */ FICL_WORD *runningWord;/* address of currently running word (often just *(ip-1) ) */ FICL_UNS state; /* compiling or interpreting */ FICL_UNS base; /* number conversion base */ FICL_STACK *pStack; /* param stack */ FICL_STACK *rStack; /* return stack */ #if FICL_WANT_FLOAT FICL_STACK *fStack; /* float stack (optional) */ #endif CELL sourceID; /* -1 if EVALUATE, 0 if normal input */ TIB tib; /* address of incoming text string */ #if FICL_WANT_USER CELL user[FICL_USER_CELLS]; #endif char pad[nPAD]; /* the scratch area (see above) */ }; /* ** A FICL_CODE points to a function that gets called to help execute ** a word in the dictionary. It always gets passed a pointer to the ** running virtual machine, and from there it can get the address ** of the parameter area of the word it's supposed to operate on. ** For precompiled words, the code is all there is. For user defined ** words, the code assumes that the word's parameter area is a list ** of pointers to the code fields of other words to execute, and ** may also contain inline data. The first parameter is always ** a pointer to a code field. */ typedef void (*FICL_CODE)(FICL_VM *pVm); #if 0 #define VM_ASSERT(pVM) assert((*(pVM->ip - 1)) == pVM->runningWord) #else #define VM_ASSERT(pVM) #endif #define nName length #define ficl_word ficlWord #define FICL_WORD ficlWord #define CELLS_PER_WORD \ ( (sizeof (FICL_WORD) + nFICLNAME + sizeof (CELL)) \ / (sizeof (CELL)) ) int wordIsImmediate(FICL_WORD *pFW); int wordIsCompileOnly(FICL_WORD *pFW); #define FW_IMMEDIATE FICL_WORD_IMMEDIATE #define FW_COMPILE FICL_WORD_COMPILE_ONLY #define FW_SMUDGE FICL_WORD_SMUDGED #define FW_ISOBJECT FICL_WORD_OBJECT #define FW_COMPIMMED (FW_IMMEDIATE | FW_COMPILE_ONLY) #define FW_DEFAULT 0 /* ** Exit codes for vmThrow */ #define VM_INNEREXIT FICL_VM_STATUS_INNER_EXIT #define VM_OUTOFTEXT FICL_VM_STATUS_OUT_OF_TEXT #define VM_RESTART FICL_VM_STATUS_RESTART #define VM_USEREXIT FICL_VM_STATUS_USER_EXIT #define VM_ERREXIT FICL_VM_STATUS_ERROR_EXIT #define VM_BREAK FICL_VM_STATUS_BREAK #define VM_ABORT FICL_VM_STATUS_ABORT #define VM_ABORTQ FICL_VM_STATUS_ABORTQ #define VM_QUIT FICL_VM_STATUS_QUIT void vmBranchRelative(FICL_VM *pVM, int offset); FICL_VM * vmCreate (FICL_VM *pVM, unsigned nPStack, unsigned nRStack); void vmDelete (FICL_VM *pVM); void vmExecute (FICL_VM *pVM, FICL_WORD *pWord); FICL_DICT *vmGetDict (FICL_VM *pVM); char * vmGetString (FICL_VM *pVM, FICL_STRING *spDest, char delimiter); STRINGINFO vmGetWord (FICL_VM *pVM); STRINGINFO vmGetWord0 (FICL_VM *pVM); int vmGetWordToPad (FICL_VM *pVM); STRINGINFO vmParseString (FICL_VM *pVM, char delimiter); STRINGINFO vmParseStringEx(FICL_VM *pVM, char delimiter, char fSkipLeading); CELL vmPop (FICL_VM *pVM); void vmPush (FICL_VM *pVM, CELL c); void vmPopIP (FICL_VM *pVM); void vmPushIP (FICL_VM *pVM, IPTYPE newIP); void vmQuit (FICL_VM *pVM); void vmReset (FICL_VM *pVM); void vmSetTextOut (FICL_VM *pVM, OUTFUNC textOut); void vmTextOut (FICL_VM *pVM, char *text, int fNewline); void vmThrow (FICL_VM *pVM, int except); void vmThrowErr (FICL_VM *pVM, char *fmt, ...); #define vmGetRunningWord(pVM) ((pVM)->runningWord) #define M_VM_STEP(pVM) \ FICL_WORD *tempFW = *(pVM)->ip++; \ ficlVmInnerLoop((ficlVm *)pVM, (ficlWord *)tempFW); \ #define M_INNER_LOOP(pVM) \ ficlVmInnerLoop((ficlVm *)pVm); void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells); #if FICL_WANT_FLOAT void vmCheckFStack(FICL_VM *pVM, int popCells, int pushCells); #endif void vmPushTib (FICL_VM *pVM, char *text, FICL_INT nChars, TIB *pSaveTib); void vmPopTib (FICL_VM *pVM, TIB *pTib); #define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index) #define vmGetInBufLen(pVM) ((pVM)->tib.end - (pVM)->tib.cp) #define vmGetInBufEnd(pVM) ((pVM)->tib.end) #define vmGetTibIndex(pVM) (pVM)->tib.index #define vmSetTibIndex(pVM, i) (pVM)->tib.index = i #define vmUpdateTib(pVM, str) (pVM)->tib.index = (str) - (pVM)->tib.cp #if defined(_WIN32) /* #SHEESH ** Why do Microsoft Meatballs insist on contaminating ** my namespace with their string functions??? */ #pragma warning(disable: 4273) #endif int isPowerOfTwo(FICL_UNS u); char *ltoa( FICL_INT value, char *string, int radix ); char *ultoa(FICL_UNS value, char *string, int radix ); char digit_to_char(int value); char *strrev( char *string ); char *skipSpace(char *cp, char *end); char *caseFold(char *cp); int strincmp(char *cp1, char *cp2, FICL_UNS count); #if defined(_WIN32) #pragma warning(default: 4273) #endif #if !defined HASHSIZE /* Default size of hash table. For most uniform */ #define HASHSIZE FICL_HASHSIZE /* performance, use a prime number! */ #endif #define ficl_hash ficlHash #define FICL_HASH ficlHash void hashForget (FICL_HASH *pHash, void *where); UNS16 hashHashCode (STRINGINFO si); void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW); FICL_WORD *hashLookup (FICL_HASH *pHash, STRINGINFO si, UNS16 hashCode); void hashReset (FICL_HASH *pHash); struct ficl_dict { CELL *here; void *context; FICL_WORD *smudge; FICL_HASH *pForthWords; FICL_HASH *pCompile; FICL_HASH *pSearch[FICL_DEFAULT_VOCS]; int nLists; unsigned size; /* Number of cells in dict (total)*/ ficlSystem *system; CELL dict[1]; /* Base of dictionary memory */ }; void *alignPtr(void *ptr); void dictAbortDefinition(FICL_DICT *pDict); void dictAlign (FICL_DICT *pDict); int dictAllot (FICL_DICT *pDict, int n); int dictAllotCells (FICL_DICT *pDict, int nCells); void dictAppendCell (FICL_DICT *pDict, CELL c); void dictAppendChar (FICL_DICT *pDict, char c); FICL_WORD *dictAppendWord (FICL_DICT *pDict, char *name, FICL_CODE pCode, UNS8 flags); FICL_WORD *dictAppendWord2(FICL_DICT *pDict, STRINGINFO si, FICL_CODE pCode, UNS8 flags); void dictAppendUNS (FICL_DICT *pDict, FICL_UNS u); int dictCellsAvail (FICL_DICT *pDict); int dictCellsUsed (FICL_DICT *pDict); void dictCheck (FICL_DICT *pDict, FICL_VM *pVM, int n); FICL_DICT *dictCreate(unsigned nCELLS); FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash); FICL_HASH *dictCreateWordlist(FICL_DICT *dp, int nBuckets); void dictDelete (FICL_DICT *pDict); void dictEmpty (FICL_DICT *pDict, unsigned nHash); #if FICL_WANT_FLOAT void dictHashSummary(FICL_VM *pVM); #endif int dictIncludes (FICL_DICT *pDict, void *p); FICL_WORD *dictLookup (FICL_DICT *pDict, STRINGINFO si); #if FICL_WANT_LOCALS FICL_WORD *ficlLookupLoc (FICL_SYSTEM *pSys, STRINGINFO si); #endif void dictResetSearchOrder(FICL_DICT *pDict); void dictSetFlags (FICL_DICT *pDict, UNS8 set, UNS8 clr); void dictSetImmediate(FICL_DICT *pDict); void dictUnsmudge (FICL_DICT *pDict); CELL *dictWhere (FICL_DICT *pDict); typedef int (*FICL_PARSE_STEP)(FICL_VM *pVM, STRINGINFO si); int ficlAddParseStep(FICL_SYSTEM *pSys, FICL_WORD *pFW); /* ficl.c */ void ficlAddPrecompiledParseStep(FICL_SYSTEM *pSys, char *name, FICL_PARSE_STEP pStep); void ficlListParseSteps(FICL_VM *pVM); typedef struct FICL_BREAKPOINT { void *address; FICL_WORD *origXT; } FICL_BREAKPOINT; struct ficl_system { void *pExtend; ficlOutputFunction textOut; ficlOutputFunction errorTextOut; ficlSystem *pSys; ficlVm *vm; FICL_SYSTEM *link; FICL_VM *vmList; FICL_DICT *dp; FICL_DICT *envp; FICL_WORD *pInterp[3]; FICL_WORD *parseList[FICL_MAX_PARSE_STEPS]; FICL_WORD *pExitInner; FICL_WORD *pInterpret; #if FICL_WANT_LOCALS FICL_DICT *localp; FICL_INT nLocals; CELL *pMarkLocals; #endif ficlInteger stackSize; FICL_BREAKPOINT bpStep; }; struct ficl_system_info { int size; /* structure size tag for versioning */ void *pExtend; /* Initializes VM's pExtend pointer - for application use */ int nDictCells; /* Size of system's Dictionary */ int stackSize; /* Size of system's Dictionary */ OUTFUNC textOut; /* default textOut function */ int nEnvCells; /* Size of Environment dictionary */ }; #define ficlInitInfo(x) { memset((x), 0, sizeof(FICL_SYSTEM_INFO)); \ (x)->size = sizeof(FICL_SYSTEM_INFO); } FICL_SYSTEM *ficlInitSystemEx(FICL_SYSTEM_INFO *fsi); FICL_SYSTEM *ficlInitSystem(int nDictCells); void ficlTermSystem(FICL_SYSTEM *pSys); int ficlEvaluate(FICL_VM *pVM, char *pText); int ficlExec (FICL_VM *pVM, char *pText); int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT nChars); int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord); FICL_VM *ficlNewVM(FICL_SYSTEM *pSys); void ficlFreeVM(FICL_VM *pVM); int ficlSetStackSize(int nStackCells); FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name); FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys); FICL_DICT *ficlGetEnv (FICL_SYSTEM *pSys); void ficlSetEnv (FICL_SYSTEM *pSys, char *name, FICL_UNS value); void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, FICL_UNS hi, FICL_UNS lo); #if FICL_WANT_LOCALS FICL_DICT *ficlGetLoc (FICL_SYSTEM *pSys); #endif int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code, char flags); void ficlCompileCore(FICL_SYSTEM *pSys); void ficlCompilePrefix(FICL_SYSTEM *pSys); void ficlCompileSearch(FICL_SYSTEM *pSys); void ficlCompileSoftCore(FICL_SYSTEM *pSys); void ficlCompileTools(FICL_SYSTEM *pSys); void ficlCompileFile(FICL_SYSTEM *pSys); #if FICL_WANT_FLOAT void ficlCompileFloat(FICL_SYSTEM *pSys); int ficlParseFloatNumber( FICL_VM *pVM, STRINGINFO si ); /* float.c */ #endif #if FICL_WANT_PLATFORM void ficlCompilePlatform(FICL_SYSTEM *pSys); #endif int ficlParsePrefix(FICL_VM *pVM, STRINGINFO si); void constantParen(FICL_VM *pVM); void twoConstParen(FICL_VM *pVM); int ficlParseNumber(FICL_VM *pVM, STRINGINFO si); void ficlTick(FICL_VM *pVM); void parseStepParen(FICL_VM *pVM); int isAFiclWord(FICL_DICT *pd, FICL_WORD *pFW); /* we define it ourselves, for naughty programs that call it directly. */ void ficlTextOut (FICL_VM *pVM, char *text, int fNewline); /* but you can use this one! */ void ficlTextOutLocal (FICL_VM *pVM, char *text, int fNewline); #endif /* FICL_FORCE_COMPATIBILITY */