123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /*
- Expression Evaluator Library (NS-EEL) v2
- Copyright (C) 2004-2008 Cockos Incorporated
- Copyright (C) 1999-2003 Nullsoft, Inc.
-
- nseel-eval.c
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #include <string.h>
- #include <ctype.h>
- #include "ns-eel-int.h"
- #define NSEEL_VARS_MALLOC_CHUNKSIZE 8
- #define NSEEL_GLOBALVAR_BASE (1<<24)
- #ifndef NSEEL_MAX_VARIABLE_NAMELEN
- #define NSEEL_MAX_VARIABLE_NAMELEN 8
- #endif
- #define strnicmp(x,y,z) strncasecmp(x,y,z)
- #define INTCONST 1
- #define DBLCONST 2
- #define HEXCONST 3
- #define VARIABLE 4
- #define OTHER 5
- EEL_F nseel_globalregs[100];
- //------------------------------------------------------------------------------
- void *nseel_compileExpression(compileContext *ctx, char *exp)
- {
- ctx->errVar=0;
- nseel_llinit(ctx);
- if (!nseel_yyparse(ctx,exp) && !ctx->errVar)
- {
- return (void*)ctx->result;
- }
- return 0;
- }
- //------------------------------------------------------------------------------
- void nseel_setLastVar(compileContext *ctx)
- {
- nseel_gettoken(ctx,ctx->lastVar, sizeof(ctx->lastVar));
- }
- void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F *val, void *ctx), void *userctx)
- {
- compileContext *tctx = (compileContext *) ctx;
- int wb;
- if (!tctx) return;
- for (wb = 0; wb < tctx->varTable_numBlocks; wb ++)
- {
- int ti;
- int namepos=0;
- for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++)
- {
- char *p=tctx->varTable_Names[wb]+namepos;
- if (!*p) break;
- if (!func(p,&tctx->varTable_Values[wb][ti],userctx))
- break;
- namepos += NSEEL_MAX_VARIABLE_NAMELEN;
- }
- if (ti < NSEEL_VARS_PER_BLOCK)
- break;
- }
- }
- static INT_PTR register_var(compileContext *ctx, const char *name, EEL_F **ptr)
- {
- int wb;
- int ti=0;
- int i=0;
- char *nameptr;
- for (wb = 0; wb < ctx->varTable_numBlocks; wb ++)
- {
- int namepos=0;
- for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++)
- {
- if (!ctx->varTable_Names[wb][namepos] || !strnicmp(ctx->varTable_Names[wb]+namepos,name,NSEEL_MAX_VARIABLE_NAMELEN))
- {
- break;
- }
- namepos += NSEEL_MAX_VARIABLE_NAMELEN;
- i++;
- }
- if (ti < NSEEL_VARS_PER_BLOCK)
- break;
- }
- if (wb == ctx->varTable_numBlocks)
- {
- ti=0;
- // add new block
- if (!(ctx->varTable_numBlocks&(NSEEL_VARS_MALLOC_CHUNKSIZE-1)) || !ctx->varTable_Values || !ctx->varTable_Names )
- {
- ctx->varTable_Values = (EEL_F **)realloc(ctx->varTable_Values,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(EEL_F *));
- ctx->varTable_Names = (char **)realloc(ctx->varTable_Names,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(char *));
- }
- ctx->varTable_numBlocks++;
- ctx->varTable_Values[wb] = (EEL_F *)calloc(sizeof(EEL_F),NSEEL_VARS_PER_BLOCK);
- ctx->varTable_Names[wb] = (char *)calloc(NSEEL_MAX_VARIABLE_NAMELEN,NSEEL_VARS_PER_BLOCK);
- }
- nameptr=ctx->varTable_Names[wb]+ti*NSEEL_MAX_VARIABLE_NAMELEN;
- if (!nameptr[0])
- {
- strncpy(nameptr,name,NSEEL_MAX_VARIABLE_NAMELEN);
- }
- if (ptr) *ptr = ctx->varTable_Values[wb] + ti;
- return i;
- }
- //------------------------------------------------------------------------------
- INT_PTR nseel_setVar(compileContext *ctx, INT_PTR varNum)
- {
- if (varNum < 0) // adding new var
- {
- char *var=ctx->lastVar;
- if (!strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
- {
- int i,x=atoi(var+3);
- if (x < 0 || x > 99) x=0;
- i=NSEEL_GLOBALVAR_BASE+x;
- return i;
- }
- return register_var(ctx,ctx->lastVar,NULL);
- }
- // setting/getting oldvar
- if (varNum >= NSEEL_GLOBALVAR_BASE && varNum < NSEEL_GLOBALVAR_BASE+100)
- {
- return varNum;
- }
- {
- int wb,ti;
- char *nameptr;
- if (varNum < 0 || varNum >= ctx->varTable_numBlocks*NSEEL_VARS_PER_BLOCK) return -1;
- wb=varNum/NSEEL_VARS_PER_BLOCK;
- ti=(varNum%NSEEL_VARS_PER_BLOCK);
- nameptr=ctx->varTable_Names[wb]+ti*NSEEL_MAX_VARIABLE_NAMELEN;
- if (!nameptr[0])
- {
- strncpy(nameptr,ctx->lastVar,NSEEL_MAX_VARIABLE_NAMELEN);
- }
- return varNum;
- }
- }
- //------------------------------------------------------------------------------
- INT_PTR nseel_getVar(compileContext *ctx, INT_PTR i)
- {
- if (i >= 0 && i < (NSEEL_VARS_PER_BLOCK*ctx->varTable_numBlocks))
- return nseel_createCompiledValue(ctx,0, ctx->varTable_Values[i/NSEEL_VARS_PER_BLOCK] + i%NSEEL_VARS_PER_BLOCK);
- if (i >= NSEEL_GLOBALVAR_BASE && i < NSEEL_GLOBALVAR_BASE+100)
- return nseel_createCompiledValue(ctx,0, nseel_globalregs+i-NSEEL_GLOBALVAR_BASE);
- return nseel_createCompiledValue(ctx,0, NULL);
- }
- //------------------------------------------------------------------------------
- EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX _ctx, const char *var)
- {
- compileContext *ctx = (compileContext *)_ctx;
- EEL_F *r;
- if (!ctx) return 0;
- if (!strnicmp(var,"reg",3) && strlen(var) == 5 && isdigit(var[3]) && isdigit(var[4]))
- {
- int x=atoi(var+3);
- if (x < 0 || x > 99) x=0;
- return nseel_globalregs + x;
- }
- register_var(ctx,var,&r);
- return r;
- }
- //------------------------------------------------------------------------------
- INT_PTR nseel_translate(compileContext *ctx, int type)
- {
- int v;
- int n;
- *ctx->yytext = 0;
- nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
- switch (type)
- {
- case INTCONST: return nseel_createCompiledValue(ctx,(EEL_F)atoi(ctx->yytext), NULL);
- case DBLCONST: return nseel_createCompiledValue(ctx,(EEL_F)atof(ctx->yytext), NULL);
- case HEXCONST:
- v=0;
- n=0;
- while (1)
- {
- int a=ctx->yytext[n++];
- if (a >= '0' && a <= '9') v=(v<<4)+a-'0';
- else if (a >= 'A' && a <= 'F') v=(v<<4)+10+a-'A';
- else if (a >= 'a' && a <= 'f') v=(v<<4)+10+a-'a';
- else break;
- }
- return nseel_createCompiledValue(ctx,(EEL_F)v, NULL);
- }
- return 0;
- }
- //------------------------------------------------------------------------------
- INT_PTR nseel_lookup(compileContext *ctx, int *typeOfObject)
- {
- int i, ti, wb;
- const char *nptr;
- nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
- if (!strnicmp(ctx->yytext,"reg",3) && strlen(ctx->yytext) == 5 && isdigit(ctx->yytext[3]) && isdigit(ctx->yytext[4]) && (i=atoi(ctx->yytext+3))>=0 && i<100)
- {
- *typeOfObject=IDENTIFIER;
- return i+NSEEL_GLOBALVAR_BASE;
- }
- i=0;
- for (wb = 0; wb < ctx->varTable_numBlocks; wb ++)
- {
- int namepos=0;
- for (ti = 0; ti < NSEEL_VARS_PER_BLOCK; ti ++)
- {
- if (!ctx->varTable_Names[wb][namepos]) break;
- if (!strnicmp(ctx->varTable_Names[wb]+namepos,ctx->yytext,NSEEL_MAX_VARIABLE_NAMELEN))
- {
- *typeOfObject = IDENTIFIER;
- return i;
- }
- namepos += NSEEL_MAX_VARIABLE_NAMELEN;
- i++;
- }
- if (ti < NSEEL_VARS_PER_BLOCK) break;
- }
- nptr = ctx->yytext;
- if (!strcasecmp(nptr,"if")) nptr="_if";
- else if (!strcasecmp(nptr,"bnot")) nptr="_not";
- else if (!strcasecmp(nptr,"assign")) nptr="_set";
- else if (!strcasecmp(nptr,"equal")) nptr="_equal";
- else if (!strcasecmp(nptr,"below")) nptr="_below";
- else if (!strcasecmp(nptr,"above")) nptr="_above";
- else if (!strcasecmp(nptr,"megabuf")) nptr="_mem";
- else if (!strcasecmp(nptr,"gmegabuf")) nptr="_gmem";
- else if (!strcasecmp(nptr,"int")) nptr="floor";
- for (i=0;nseel_getFunctionFromTable(i);i++)
- {
- functionType *f=nseel_getFunctionFromTable(i);
- if (!strcasecmp(f->name, nptr))
- {
- switch (f->nParams)
- {
- case 1: *typeOfObject = FUNCTION1; break;
- case 2: *typeOfObject = FUNCTION2; break;
- case 3: *typeOfObject = FUNCTION3; break;
- default: *typeOfObject = IDENTIFIER; break;
- }
- return i;
- }
- }
- *typeOfObject = IDENTIFIER;
- nseel_setLastVar(ctx);
- return nseel_setVar(ctx,-1);
- }
- //---------------------------------------------------------------------------
- void nseel_count(compileContext *ctx)
- {
- nseel_gettoken(ctx,ctx->yytext, sizeof(ctx->yytext));
- ctx->colCount+=strlen(ctx->yytext);
- }
- //---------------------------------------------------------------------------
- int nseel_yyerror(compileContext *ctx)
- {
- ctx->errVar = ctx->colCount;
- return 0;
- }
|