aboutsummaryrefslogtreecommitdiff
path: root/Src/ns-eel/nseel-eval.c
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/ns-eel/nseel-eval.c
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/ns-eel/nseel-eval.c')
-rw-r--r--Src/ns-eel/nseel-eval.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/Src/ns-eel/nseel-eval.c b/Src/ns-eel/nseel-eval.c
new file mode 100644
index 00000000..2259fca4
--- /dev/null
+++ b/Src/ns-eel/nseel-eval.c
@@ -0,0 +1,282 @@
+/*
+ Nullsoft Expression Evaluator Library (NS-EEL)
+ 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 <windows.h>
+#include "ns-eel-int.h"
+
+#define NSEEL_VARS_PER_BLOCK 64
+#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 INTCONST 1
+#define DBLCONST 2
+#define HEXCONST 3
+#define VARIABLE 4
+#define OTHER 5
+
+double 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));
+}
+
+static int register_var(compileContext *ctx, char *name, double **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 = (double **)realloc(ctx->varTable_Values,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(double *));
+ ctx->varTable_Names = (char **)realloc(ctx->varTable_Names,(ctx->varTable_numBlocks+NSEEL_VARS_MALLOC_CHUNKSIZE) * sizeof(char *));
+ }
+ ctx->varTable_numBlocks++;
+
+ ctx->varTable_Values[wb] = (double *)calloc(sizeof(double),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 nseel_setVar(compileContext *ctx, int 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 nseel_getVar(compileContext *ctx, int 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);
+}
+
+
+
+//------------------------------------------------------------------------------
+double *NSEEL_VM_regvar(NSEEL_VMCTX _ctx, char *var)
+{
+ compileContext *ctx = (compileContext *)_ctx;
+ double *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 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,(double)atoi(ctx->yytext), NULL);
+ case DBLCONST: return nseel_createCompiledValue(ctx,(double)atof(ctx->yytext), NULL);
+ case HEXCONST:
+ v=0;
+ n=0;
+ while (1)
+ {
+ int a=ctx->yytext[n++];
+ if (a >= '0' && a <= '9') v+=a-'0';
+ else if (a >= 'A' && a <= 'F') v+=10+a-'A';
+ else if (a >= 'a' && a <= 'f') v+=10+a-'a';
+ else break;
+ v<<=4;
+ }
+ return nseel_createCompiledValue(ctx,(double)v, NULL);
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+int nseel_lookup(compileContext *ctx, int *typeOfObject)
+{
+ int i;
+ 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;
+ }
+
+
+ {
+ int wb;
+ int ti=0;
+ 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;
+ }
+ }
+
+
+ for (i=0;nseel_getFunctionFromTable(i);i++)
+ {
+ functionType *f=nseel_getFunctionFromTable(i);
+ if (!strcmpi(f->name, ctx->yytext))
+ {
+ 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;
+} \ No newline at end of file