Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

80
Src/ns-eel/megabuf.c Normal file
View File

@ -0,0 +1,80 @@
#include <windows.h>
#include "../ns-eel/ns-eel.h"
#include "../ns-eel/ns-eel-int.h"
#include "megabuf.h"
void megabuf_ppproc(void *data, int data_size, void **userfunc_data)
{
if (data_size > 5 && *(int*)((char *)data+1) == 0xFFFFFFFF)
{
*(int*)((char *)data+1) = (int) (userfunc_data+0);
}
}
void megabuf_cleanup(NSEEL_VMCTX ctx)
{
if (ctx)
{
compileContext *c=(compileContext*)ctx;
if (c->userfunc_data[0])
{
double **blocks = (double **)c->userfunc_data[0];
int x;
for (x = 0; x < MEGABUF_BLOCKS; x ++)
{
if (blocks[x]) VirtualFree(blocks[x], 0/*sizeof(double)*MEGABUF_ITEMSPERBLOCK*/, MEM_RELEASE);
//GlobalFree(blocks[x]);
blocks[x]=0;
}
VirtualFree(blocks, 0/*sizeof(double *)*MEGABUF_BLOCKS*/, MEM_RELEASE);
//GlobalFree((HGLOBAL)blocks);
c->userfunc_data[0]=0;
}
}
}
static double * NSEEL_CGEN_CALL megabuf_(double ***blocks, double *which)
{
static double error;
int w=(int)(*which + 0.0001);
int whichblock = w/MEGABUF_ITEMSPERBLOCK;
if (!*blocks)
{
*blocks = (double **)VirtualAlloc(NULL, sizeof(double *)*MEGABUF_BLOCKS, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//GlobalAlloc(GPTR,sizeof(double *)*MEGABUF_BLOCKS);
}
if (!*blocks) return &error;
if (w >= 0 && whichblock >= 0 && whichblock < MEGABUF_BLOCKS)
{
int whichentry = w%MEGABUF_ITEMSPERBLOCK;
if (!(*blocks)[whichblock])
{
(*blocks)[whichblock]=(double *)VirtualAlloc(NULL, sizeof(double)*MEGABUF_ITEMSPERBLOCK, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//GlobalAlloc(GPTR,sizeof(double)*MEGABUF_ITEMSPERBLOCK);
}
if ((*blocks)[whichblock])
return &(*blocks)[whichblock][whichentry];
}
return &error;
}
static double * (NSEEL_CGEN_CALL *__megabuf)(double ***,double *) = &megabuf_;
__declspec ( naked ) void _asm_megabuf(void)
{
double ***my_ctx;
double *parm_a, *__nextBlock;
__asm { mov edx, 0xFFFFFFFF }
__asm { mov ebp, esp }
__asm { sub esp, __LOCAL_SIZE }
__asm { mov dword ptr my_ctx, edx }
__asm { mov dword ptr parm_a, eax }
__nextBlock = __megabuf(my_ctx,parm_a);
__asm { mov eax, __nextBlock } // this is custom, returning pointer
__asm { mov esp, ebp }
}
__declspec ( naked ) void _asm_megabuf_end(void) {}

21
Src/ns-eel/megabuf.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _MEGABUF_H_
#define _MEGABUF_H_
#ifdef __cplusplus
extern "C" {
#endif
#define MEGABUF_BLOCKS 64
#define MEGABUF_ITEMSPERBLOCK 16384
void _asm_megabuf(void);
void _asm_megabuf_end(void);
void megabuf_ppproc(void *data, int data_size, void **userfunc_data);
void megabuf_cleanup(NSEEL_VMCTX);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,90 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
ns-eel-addfuncs.h: defines macros useful for adding functions to the compiler
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.
*/
#ifndef __NS_EEL_ADDFUNCS_H__
#define __NS_EEL_ADDFUNCS_H__
typedef void (*NSEEL_PPPROC)(void *data, int data_size, void **userfunc_data);
// these are used for making your own naked functions in C.
/*
For example:
static double (*__acos)(double) = &acos;
__declspec ( naked ) void _asm_acos(void)
{
FUNC1_ENTER
*__nextBlock = __acos(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_acos_end(void) {}
If you want to do straight asm, then , well, you can use your imagination
(eax, ebx, ecx are input, eax is output, all points to "double")
if you need 8 bytes of temp space for your output, use esi and increment esi by 8
be sure to preserve edi, too.
*/
#define FUNC1_ENTER \
double *parm_a, *__nextBlock; \
__asm { mov ebp, esp } \
__asm { sub esp, __LOCAL_SIZE } \
__asm { mov dword ptr parm_a, eax } \
__asm { mov __nextBlock, esi }
#define FUNC2_ENTER \
double *parm_a,*parm_b,*__nextBlock; \
__asm { mov ebp, esp } \
__asm { sub esp, __LOCAL_SIZE } \
__asm { mov dword ptr parm_a, eax } \
__asm { mov dword ptr parm_b, ebx } \
__asm { mov __nextBlock, esi }
#define FUNC3_ENTER \
double *parm_a,*parm_b,*parm_c,*__nextBlock; \
__asm { mov ebp, esp } \
__asm { sub esp, __LOCAL_SIZE } \
__asm { mov dword ptr parm_a, eax } \
__asm { mov dword ptr parm_b, ebx } \
__asm { mov dword ptr parm_c, ecx } \
__asm { mov __nextBlock, esi }
#define FUNC_LEAVE \
__asm { mov eax, esi } \
__asm { add esi, 8 } \
__asm { mov esp, ebp }
#define NSEEL_CGEN_CALL __fastcall
#endif//__NS_EEL_ADDFUNCS_H__

156
Src/ns-eel/ns-eel-int.h Normal file
View File

@ -0,0 +1,156 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
ns-eel-int.h: internal code definition header.
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.
*/
#ifndef __NS_EELINT_H__
#define __NS_EELINT_H__
#include "ns-eel.h"
#include "ns-eel-addfuncs.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FN_ASSIGN 0
#define FN_MULTIPLY 1
#define FN_DIVIDE 2
#define FN_MODULO 3
#define FN_ADD 4
#define FN_SUB 5
#define FN_AND 6
#define FN_OR 7
#define FN_UMINUS 8
#define FN_UPLUS 9
#define MATH_SIMPLE 0
#define MATH_FN 1
#define YYSTYPE int
typedef struct
{
double **varTable_Values;
char **varTable_Names;
int varTable_numBlocks;
int errVar;
int colCount;
int result;
char last_error_string[256];
YYSTYPE yylval;
int yychar; /* the lookahead symbol */
int yynerrs; /* number of parse errors so far */
char yytext[256];
char lastVar[256];
char *llsave[16]; /* Look ahead buffer */
char llbuf[100]; /* work buffer */
char *llp1;// = &llbuf[0]; /* pointer to next avail. in token */
char *llp2;// = &llbuf[0]; /* pointer to end of lookahead */
char *llend;// = &llbuf[0]; /* pointer to end of token */
char *llebuf;// = &llbuf[sizeof llbuf];
int lleof;
int yyline;// = 0;
void *tmpblocks_head,*blocks_head;
int computTableTop; // make it abort on potential overflow =)
int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
void *userfunc_data[64];
}
compileContext;
typedef struct {
char *name;
void *afunc;
void *func_e;
int nParams;
NSEEL_PPPROC pProc;
} functionType;
extern functionType *nseel_getFunctionFromTable(int idx);
int nseel_createCompiledValue(compileContext *ctx, double value, double *addrValue);
int nseel_createCompiledFunction1(compileContext *ctx, int fntype, int fn, int code);
int nseel_createCompiledFunction2(compileContext *ctx, int fntype, int fn, int code1, int code2);
int nseel_createCompiledFunction3(compileContext *ctx, int fntype, int fn, int code1, int code2, int code3);
extern double nseel_globalregs[100];
void nseel_resetVars(compileContext *ctx);
double *nseel_getVarPtr(compileContext *ctx, char *varName);
double *nseel_registerVar(compileContext *ctx, char *varName);
// other shat
int nseel_setVar(compileContext *ctx, int varNum);
int nseel_getVar(compileContext *ctx, int varNum);
void *nseel_compileExpression(compileContext *ctx, char *txt);
#define VALUE 258
#define IDENTIFIER 259
#define FUNCTION1 260
#define FUNCTION2 261
#define FUNCTION3 262
#define UMINUS 263
#define UPLUS 264
int nseel_translate(compileContext *ctx, int type);
void nseel_count(compileContext *ctx);
void nseel_setLastVar(compileContext *ctx);
int nseel_lookup(compileContext *ctx, int *typeOfObject);
int nseel_yyerror(compileContext *ctx);
int nseel_yylex(compileContext *ctx, char **exp);
int nseel_yyparse(compileContext *ctx, char *exp);
void nseel_llinit(compileContext *ctx);
int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz);
struct lextab {
int llendst; /* Last state number */
char *lldefault; /* Default state table */
char *llnext; /* Next state table */
char *llcheck; /* Check table */
int *llbase; /* Base table */
int llnxtmax; /* Last in next table */
int (*llmove)(); /* Move between states */
char *llfinal; /* Final state descriptions */
int (*llactr)(); /* Action routine */
int *lllook; /* Look ahead vector if != NULL */
char *llign; /* Ignore char vec if != NULL */
char *llbrk; /* Break char vec if != NULL */
char *llill; /* Illegal char vec if != NULL */
};
extern struct lextab nseel_lextab;
#ifdef __cplusplus
}
#endif
#endif//__NS_EELINT_H__

80
Src/ns-eel/ns-eel.h Normal file
View File

@ -0,0 +1,80 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
ns-eel.h: main application interface header
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.
*/
#ifndef __NS_EEL_H__
#define __NS_EEL_H__
#ifdef __cplusplus
extern "C" {
#endif
int NSEEL_init(); // returns 0 on success
#define NSEEL_addfunction(name,nparms,code,len) NSEEL_addfunctionex((name),(nparms),(code),(len),0)
void NSEEL_addfunctionex(char *name, int nparms, int code_startaddr, int code_len, void *pproc);
void NSEEL_quit();
int *NSEEL_getstats(); // returns a pointer to 5 ints... source bytes, static code bytes, call code bytes, data bytes, number of code handles
double *NSEEL_getglobalregs();
typedef void *NSEEL_VMCTX;
typedef void *NSEEL_CODEHANDLE;
NSEEL_VMCTX NSEEL_VM_alloc(); // return a handle
void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its code have been freed, as well
void NSEEL_VM_resetvars(NSEEL_VMCTX ctx);
double *NSEEL_VM_regvar(NSEEL_VMCTX ctx, char *name);
NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX ctx, char *code);
char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx);
void NSEEL_code_execute(NSEEL_CODEHANDLE code);
void NSEEL_code_free(NSEEL_CODEHANDLE code);
int *NSEEL_code_getstats(NSEEL_CODEHANDLE code); // 4 ints...source bytes, static code bytes, call code bytes, data bytes
// configuration:
//#define NSEEL_REENTRANT_EXECUTION
// defining this allows code to run in different threads at the same time
// this can be slower at times.
//#define NSEEL_MAX_VARIABLE_NAMELEN 8
// define this to override the max variable length (default is 8 bytes)
//#define NSEEL_MAX_TEMPSPACE_ENTRIES 2048
// define this to override the maximum working space in 8 byte units.
// 2048 is the default, and is way more than enough for most applications
//#define NSEEL_LOOPFUNC_SUPPORT
//#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN (4096)
// define this for loop() support
// and define maxlen if you wish to override the maximum loop length (default is 4096 times)
#ifdef __cplusplus
}
#endif
#endif//__NS_EEL_H__

553
Src/ns-eel/nseel-caltab.c Normal file
View File

@ -0,0 +1,553 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
nseel-caltab.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 "ns-eel-int.h"
#define VALUE 258
#define IDENTIFIER 259
#define FUNCTION1 260
#define FUNCTION2 261
#define FUNCTION3 262
#define UMINUS 263
#define UPLUS 264
#define YYSTYPE int
#define YYERROR(x) nseel_yyerror(ctx)
#define YYFINAL 51
#define YYFLAG -32768
#define YYNTBASE 21
#define YYTRANSLATE(x) ((unsigned)(x) <= 264 ? yytranslate[x] : 26)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 14, 9, 2, 18,
19, 12, 10, 20, 11, 2, 13, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
17, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 8, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
6, 7, 15, 16
};
static const short yyr1[] = { 0,
21, 21, 22, 23, 23, 23, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 25, 25, 25
};
static const short yyr2[] = { 0,
1, 3, 1, 1, 1, 3, 1, 3, 3, 3,
3, 3, 3, 3, 2, 2, 1, 4, 6, 8
};
static const short yydefact[] = { 0,
3, 4, 0, 0, 0, 0, 0, 0, 5, 7,
1, 17, 0, 0, 0, 0, 4, 16, 15, 0,
0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
0, 6, 14, 13, 11, 12, 8, 9, 10, 18,
0, 0, 0, 0, 19, 0, 0, 20, 0, 0,
0
};
static const short yydefgoto[] = { 49,
9, 10, 11, 12
};
static const short yypact[] = { 19,
-32768, -11, -7, -5, -4, 38, 38, 38,-32768,-32768,
136,-32768, 38, 38, 38, 38,-32768,-32768,-32768, 88,
38, 38, 38, 38, 38, 38, 38, 136, 100, 49,
62,-32768, 41, 54, -9, -9,-32768,-32768,-32768,-32768,
38, 38, 112, 75,-32768, 38, 124,-32768, 12, 27,
-32768
};
static const short yypgoto[] = {-32768,
-32768,-32768, -6,-32768
};
#define YYLAST 150
static const short yytable[] = { 18,
19, 20, 25, 26, 27, 13, 28, 29, 30, 31,
14, 50, 15, 16, 33, 34, 35, 36, 37, 38,
39, 1, 2, 3, 4, 5, 51, 0, 6, 7,
0, 0, 0, 0, 43, 44, 8, 0, 0, 47,
1, 17, 3, 4, 5, 0, 0, 6, 7, 22,
23, 24, 25, 26, 27, 8, 21, 22, 23, 24,
25, 26, 27, 23, 24, 25, 26, 27, 41, 21,
22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
0, 42, 21, 22, 23, 24, 25, 26, 27, 0,
0, 0, 0, 0, 46, 21, 22, 23, 24, 25,
26, 27, 0, 0, 0, 0, 32, 21, 22, 23,
24, 25, 26, 27, 0, 0, 0, 0, 40, 21,
22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
45, 21, 22, 23, 24, 25, 26, 27, 0, 0,
0, 0, 48, 21, 22, 23, 24, 25, 26, 27
};
static const short yycheck[] = { 6,
7, 8, 12, 13, 14, 17, 13, 14, 15, 16,
18, 0, 18, 18, 21, 22, 23, 24, 25, 26,
27, 3, 4, 5, 6, 7, 0, -1, 10, 11,
-1, -1, -1, -1, 41, 42, 18, -1, -1, 46,
3, 4, 5, 6, 7, -1, -1, 10, 11, 9,
10, 11, 12, 13, 14, 18, 8, 9, 10, 11,
12, 13, 14, 10, 11, 12, 13, 14, 20, 8,
9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
-1, 20, 8, 9, 10, 11, 12, 13, 14, -1,
-1, -1, -1, -1, 20, 8, 9, 10, 11, 12,
13, 14, -1, -1, -1, -1, 19, 8, 9, 10,
11, 12, 13, 14, -1, -1, -1, -1, 19, 8,
9, 10, 11, 12, 13, 14, -1, -1, -1, -1,
19, 8, 9, 10, 11, 12, 13, 14, -1, -1,
-1, -1, 19, 8, 9, 10, 11, 12, 13, 14
};
#define yyerrok (yyerrstatus = 0)
#define yyclearin (ctx->yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYTERROR 1
#define YYERRCODE 256
#define YYLEX nseel_yylex(ctx,&exp)
/* If nonreentrant, generate the variables here */
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#define YYINITDEPTH 5000
#define YYMAXDEPTH 5000
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
#define __yy_bcopy(from,to,count) memcpy(to,from,(count)>0?(count):0)
//#ln 131 "bison.simple"
int nseel_yyparse(compileContext *ctx, char *exp)
{
int yystate;
int yyn;
short *yyssp;
YYSTYPE *yyvsp;
int yyerrstatus; /* number of tokens to shift before error messages enabled */
int yychar1; /* lookahead token as an internal (translated) token number */
short yyssa[YYINITDEPTH]; /* the state stack */
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
int yystacksize = YYINITDEPTH;
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
ctx->yylval = 0;
yystate = 0;
yyerrstatus = 0;
ctx->yynerrs = 0;
ctx->yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack. */
yyssp = yyss - 1;
yyvsp = yyvs;
/* Push a new state, which is found in yystate . */
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks. */
yynewstate:
*++yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Give user a chance to reallocate the stack */
/* Use copies of these so that the &'s don't force the real ones into memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
/* Get the current used size of the three stacks, in elements. */
int size = yyssp - yyss + 1;
if (yystacksize >= YYMAXDEPTH)
{
YYERROR("internal error: parser stack overflow");
return 2;
}
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
if (yyssp >= yyss + yystacksize - 1) YYABORT;
}
// yybackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* yyresume: */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* yychar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (ctx->yychar == YYEMPTY)
{
// yyStackSize = yyssp - (yyss - 1);
ctx->yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (ctx->yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
ctx->yychar = YYEOF; /* Don't call YYLEX any more */
}
else
{
yychar1 = YYTRANSLATE(ctx->yychar);
}
yyn += yychar1;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
goto yydefault;
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state.
Negative => reduce, -yyn is rule number.
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
/* Discard the token being shifted unless it is eof. */
if (ctx->yychar != YYEOF)
ctx->yychar = YYEMPTY;
*++yyvsp = ctx->yylval;
/* count tokens shifted since error; after three, turn off error status. */
if (yyerrstatus) yyerrstatus--;
yystate = yyn;
goto yynewstate;
/* Do the default action for the current state. */
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */
switch (yyn) {
case 1:
//#ln 32 "cal.y"
{ yyval = yyvsp[0]; ctx->result = yyvsp[0]; ;
break;}
case 2:
//#ln 34 "cal.y"
{ {
int i = (int)nseel_setVar(ctx,(int)yyvsp[-2]);
int v=nseel_getVar(ctx,i);
yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_ASSIGN, v, (int)yyvsp[0]);
ctx->result = yyval;
}
;
break;}
case 3:
//#ln 50 "cal.y"
{ yyval = yyvsp[0] ;
break;}
case 4:
//#ln 55 "cal.y"
{ yyval = nseel_getVar(ctx,(int)yyvsp[0]);;
break;}
case 5:
//#ln 57 "cal.y"
{ yyval = yyvsp[0];;
break;}
case 6:
//#ln 59 "cal.y"
{ yyval = yyvsp[-1];;
break;}
case 7:
//#ln 64 "cal.y"
{ yyval = yyvsp[0]; ;
break;}
case 8:
//#ln 66 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_MULTIPLY, yyvsp[-2], yyvsp[0]);
break;}
case 9:
//#ln 72 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_DIVIDE, yyvsp[-2], yyvsp[0]);
break;}
case 10:
//#ln 78 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_MODULO, yyvsp[-2], yyvsp[0]);
break;}
case 11:
//#ln 84 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_ADD, yyvsp[-2], yyvsp[0]);
break;}
case 12:
//#ln 90 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_SUB, yyvsp[-2], yyvsp[0]);
break;}
case 13:
//#ln 96 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_AND, yyvsp[-2], yyvsp[0]);
break;}
case 14:
//#ln 102 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_SIMPLE, FN_OR, yyvsp[-2], yyvsp[0]);
break;}
case 15:
//#ln 108 "cal.y"
{ yyval = nseel_createCompiledFunction1(ctx,MATH_SIMPLE, FN_UMINUS, yyvsp[0]);
break;}
case 16:
//#ln 114 "cal.y"
{ yyval = nseel_createCompiledFunction1(ctx,MATH_SIMPLE, FN_UPLUS, yyvsp[0]);
break;}
case 17:
//#ln 120 "cal.y"
{ yyval = yyvsp[0];
break;}
case 18:
//#ln 125 "cal.y"
{ yyval = nseel_createCompiledFunction1(ctx,MATH_FN, (int)yyvsp[-3], yyvsp[-1]);
break;}
case 19:
//#ln 131 "cal.y"
{ yyval = nseel_createCompiledFunction2(ctx,MATH_FN, (int)yyvsp[-5], yyvsp[-3], yyvsp[-1]);
break;}
case 20:
//#ln 137 "cal.y"
{ yyval = nseel_createCompiledFunction3(ctx,MATH_FN, (int)yyvsp[-7], yyvsp[-5], yyvsp[-3], yyvsp[-1]);
break;}
}
/* the action file gets copied in in place of this dollarsign */
//#ln 362 "bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
*++yyvsp = yyval;
/* Now "shift" the result of the reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error, report this error. */
{
++ctx->yynerrs;
#ifdef YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn < YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
size += strlen(yytname[x]) + 15, count++;
#error this should not compile
msg = (char *) xmalloc(size + 15);
strcpy(msg, "syntax error");
if (count < 5)
{
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
{
strcat(msg, count == 0 ? ", expecting `" : " or `");
strcat(msg, yytname[x]);
strcat(msg, "'");
count++;
}
}
YYERROR(msg);
free(msg);
}
else
#endif /* YYERROR_VERBOSE */
YYERROR("syntax error");
}
//yyerrlab1: /* here on error raised explicitly by an action */
if (yyerrstatus == 3)
{
/* if just tried and failed to reuse lookahead token after an error, discard it. */
/* return failure if at end of input */
if (ctx->yychar == YYEOF) YYABORT;
ctx->yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
yyerrdefault: /* current state does not do anything special for the error token. */
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
if (yyn) goto yydefault;
#endif
yyerrpop: /* pop the current state because it cannot handle the error token */
if (yyssp == yyss) YYABORT;
yyvsp--;
yystate = *--yyssp;
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
*++yyvsp = ctx->yylval;
yystate = yyn;
goto yynewstate;
}

776
Src/ns-eel/nseel-cfunc.c Normal file
View File

@ -0,0 +1,776 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
nseel-cfunc.c: assembly/C implementation of operator/function templates
This file should be ideally compiled with optimizations towards "minimize size"
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 <math.h>
#include "ns-eel-int.h"
// these are used by our assembly code
static float g_cmpaddtab[2]={0.0,1.0};
static float g_signs[2]={1.0,-1.0};
static double g_closefact = 0.00001;
static float g_half=0.5;
static float negativezeropointfive=-0.5f;
static float onepointfive=1.5f;
/// functions called by built code
#define isnonzero(x) (fabs(x) > g_closefact)
#pragma optimize( "", off )
//---------------------------------------------------------------------------------------------------------------
static double NSEEL_CGEN_CALL _rand(double *x)
{
if (*x < 1.0) *x=1.0;
return (double)(rand()%(int)max(*x,1.0));
}
//---------------------------------------------------------------------------------------------------------------
static double NSEEL_CGEN_CALL _band(double *var, double *var2)
{
return isnonzero(*var) && isnonzero(*var2) ? 1 : 0;
}
//---------------------------------------------------------------------------------------------------------------
static double NSEEL_CGEN_CALL _bor(double *var, double *var2)
{
return isnonzero(*var) || isnonzero(*var2) ? 1 : 0;
}
//---------------------------------------------------------------------------------------------------------------
static double NSEEL_CGEN_CALL _sig(double *x, double *constraint)
{
double t = (1+exp(-*x * (*constraint)));
return isnonzero(t) ? 1.0/t : 0;
}
// end functions called by inline code
// these make room on the stack for local variables, but do not need to
// worry about trashing ebp, since none of our code uses ebp and there's
// a pushad+popad surrounding the call
static double (*__asin)(double) = &asin;
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_asin(void)
{
FUNC1_ENTER
*__nextBlock = __asin(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_asin_end(void) {}
static double (*__acos)(double) = &acos;
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_acos(void)
{
FUNC1_ENTER
*__nextBlock = __acos(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_acos_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__atan)(double) = &atan;
__declspec ( naked ) void nseel_asm_atan(void)
{
FUNC1_ENTER
*__nextBlock = __atan(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_atan_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__atan2)(double,double) = &atan2;
__declspec ( naked ) void nseel_asm_atan2(void)
{
FUNC2_ENTER
*__nextBlock = __atan2(*parm_b, *parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_atan2_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (NSEEL_CGEN_CALL * __sig)(double *,double *) = &_sig;
__declspec ( naked ) void nseel_asm_sig(void)
{
FUNC2_ENTER
*__nextBlock = __sig(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_sig_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (NSEEL_CGEN_CALL *__rand)(double *) = &_rand;
__declspec ( naked ) void nseel_asm_rand(void)
{
FUNC1_ENTER
*__nextBlock = __rand(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_rand_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (NSEEL_CGEN_CALL *__band)(double *,double *) = &_band;
__declspec ( naked ) void nseel_asm_band(void)
{
FUNC2_ENTER
*__nextBlock = __band(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_band_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double ( NSEEL_CGEN_CALL *__bor)(double *,double *) = &_bor;
__declspec ( naked ) void nseel_asm_bor(void)
{
FUNC2_ENTER
*__nextBlock = __bor(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_bor_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (* __pow)(double,double) = &pow;
__declspec ( naked ) void nseel_asm_pow(void)
{
FUNC2_ENTER
*__nextBlock = __pow(*parm_b, *parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_pow_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__exp)(double) = &exp;
__declspec ( naked ) void nseel_asm_exp(void)
{
FUNC1_ENTER
*__nextBlock = __exp(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_exp_end(void) {}
//---------------------------------------------------------------------------------------------------------------
//static double (*__floor)(double) = &floor;
__declspec ( naked ) void nseel_asm_floor(void)
{
FUNC1_ENTER
*__nextBlock = __floor(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_floor_end(void) {}
//---------------------------------------------------------------------------------------------------------------
//static double (*__ceil)(double) = &ceil;
__declspec ( naked ) void nseel_asm_ceil(void)
{
FUNC1_ENTER
*__nextBlock = __ceil(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_ceil_end(void) {}
//---------------------------------------------------------------------------------------------------------------
// do nothing, eh
__declspec ( naked ) void nseel_asm_exec2(void)
{
}
__declspec ( naked ) void nseel_asm_exec2_end(void) { }
__declspec ( naked ) void nseel_asm_invsqrt(void)
{
__asm
{
fld qword ptr [eax]
mov edx, 0x5f3759df
fst dword ptr [esi]
// floating point stack has input, as does [eax]
fmul dword ptr [negativezeropointfive]
mov ecx, [esi]
sar ecx, 1
sub edx, ecx
mov [esi], edx
// st(0) = input, [eax] has x
fmul dword ptr [esi]
fmul dword ptr [esi]
fadd dword ptr [onepointfive]
fmul dword ptr [esi]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_invsqrt_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_sin(void)
{
__asm
{
fld qword ptr [eax]
fsin
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_sin_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_cos(void)
{
__asm
{
fld qword ptr [eax]
fcos
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_cos_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_tan(void)
{
__asm
{
fld qword ptr [eax]
fsincos
fdiv
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_tan_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_sqr(void)
{
__asm
{
fld qword ptr [eax]
fmul st(0), st(0)
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_sqr_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_sqrt(void)
{
__asm
{
fld qword ptr [eax]
fabs
fsqrt
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_sqrt_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_log(void)
{
__asm
{
fld1
fldl2e
fdiv
fld qword ptr [eax]
mov eax, esi
fyl2x
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_log_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_log10(void)
{
__asm
{
fld1
fldl2t
fdiv
fld qword ptr [eax]
mov eax, esi
fyl2x
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_log10_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_abs(void)
{
__asm
{
fld qword ptr [eax]
fabs
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_abs_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_assign(void)
{
__asm
{
fld qword ptr [eax]
fstp qword ptr [ebx]
}
}
__declspec ( naked ) void nseel_asm_assign_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_add(void)
{
__asm
{
fld qword ptr [eax]
fadd qword ptr [ebx]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_add_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_sub(void)
{
__asm
{
fld qword ptr [ebx]
fsub qword ptr [eax]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_sub_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_mul(void)
{
__asm
{
fld qword ptr [ebx]
fmul qword ptr [eax]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_mul_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_div(void)
{
__asm
{
fld qword ptr [ebx]
fdiv qword ptr [eax]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_div_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_mod(void)
{
__asm
{
fld qword ptr [ebx]
fld qword ptr [eax]
fsub dword ptr [g_cmpaddtab+4]
fabs
fadd qword ptr [eax]
fadd dword ptr [g_cmpaddtab+4]
fmul dword ptr [g_half]
fistp dword ptr [esi]
fistp dword ptr [esi+4]
mov eax, [esi+4]
xor edx, edx
div dword ptr [esi]
mov [esi], edx
fild dword ptr [esi]
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_mod_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_or(void)
{
__asm
{
fld qword ptr [ebx]
fld qword ptr [eax]
fistp qword ptr [esi]
fistp qword ptr [esi+8]
mov ebx, [esi+8]
or [esi], ebx
mov ebx, [esi+12]
or [esi+4], ebx
fild qword ptr [esi]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_or_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_and(void)
{
__asm
{
fld qword ptr [ebx]
fld qword ptr [eax]
fistp qword ptr [esi]
fistp qword ptr [esi+8]
mov ebx, [esi+8]
and [esi], ebx
mov ebx, [esi+12]
and [esi+4], ebx
fild qword ptr [esi]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_and_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_uplus(void) // this is the same as doing nothing, it seems
{
#if 0
__asm
{
mov ebx, nextBlock
mov ecx, [eax]
mov [ebx], ecx
mov ecx, [eax+4]
mov [ebx+4], ecx
mov eax, ebx
add ebx, 8
mov nextBlock, ebx
}
#endif
}
__declspec ( naked ) void nseel_asm_uplus_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_uminus(void)
{
__asm
{
mov ecx, [eax]
mov ebx, [eax+4]
xor ebx, 0x80000000
mov [esi], ecx
mov [esi+4], ebx
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_uminus_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_sign(void)
{
__asm
{
mov ecx, [eax+4]
mov edx, [eax]
test edx, 0FFFFFFFFh
jnz nonzero
// high dword (minus sign bit) is zero
test ecx, 07FFFFFFFh
jz zero // zero zero, return the value passed directly
nonzero:
shr ecx, 31
fld dword ptr [g_signs+ecx*4]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
zero:
}
}
__declspec ( naked ) void nseel_asm_sign_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_bnot(void)
{
__asm
{
fld qword ptr [eax]
fabs
fcomp qword ptr [g_closefact]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_bnot_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_if(void)
{
__asm
{
fld qword ptr [eax]
fabs
fcomp qword ptr [g_closefact]
fstsw ax
shr eax, 6
mov dword ptr [esi], 0FFFFFFFFh
mov dword ptr [esi+4], 0FFFFFFFFh
and eax, (1<<2)
mov eax, [esi+eax]
call eax // call the proper function
// at this point, the return value will be in eax, as desired
}
}
__declspec ( naked ) void nseel_asm_if_end(void) {}
#ifdef NSEEL_LOOPFUNC_SUPPORT
#ifndef NSEEL_LOOPFUNC_SUPPORT_MAXLEN
#define NSEEL_LOOPFUNC_SUPPORT_MAXLEN (4096)
#endif
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_repeat(void)
{
__asm
{
fld qword ptr [eax]
fistp dword ptr [esi]
mov ecx, [esi]
cmp ecx, 1
jl skip
cmp ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
jl again
mov ecx, NSEEL_LOOPFUNC_SUPPORT_MAXLEN
again:
push ecx
push esi // revert back to last temp workspace
mov ecx, 0FFFFFFFFh
call ecx
pop esi
pop ecx
dec ecx
jnz again
skip:
}
}
__declspec ( naked ) void nseel_asm_repeat_end(void) {}
#endif
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_equal(void)
{
__asm
{
fld qword ptr [eax]
fsub qword ptr [ebx]
fabs
fcomp qword ptr [g_closefact]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_equal_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_below(void)
{
__asm
{
fld qword ptr [ebx]
fcomp qword ptr [eax]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_below_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void nseel_asm_above(void)
{
__asm
{
fld qword ptr [eax]
fcomp qword ptr [ebx]
fstsw ax
shr eax, 6
and eax, (1<<2)
fld dword ptr [g_cmpaddtab+eax]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_above_end(void) {}
__declspec ( naked ) void nseel_asm_min(void)
{
__asm
{
fld qword ptr [eax]
fld qword ptr [ebx]
fld st(1)
fsub st(0), st(1)
fabs // stack contains fabs(1-2),1,2
fchs
fadd
fadd
fmul dword ptr [g_half]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_min_end(void) {}
__declspec ( naked ) void nseel_asm_max(void)
{
__asm
{
fld qword ptr [eax]
fld qword ptr [ebx]
fld st(1)
fsub st(0), st(1)
fabs // stack contains fabs(1-2),1,2
fadd
fadd
fmul dword ptr [g_half]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void nseel_asm_max_end(void) {}
#pragma optimize( "", on )

946
Src/ns-eel/nseel-compiler.c Normal file
View File

@ -0,0 +1,946 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
nseel-compiler.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"
#ifdef NSEEL_REENTRANT_EXECUTION
#include <malloc.h>
#endif
#define ltoupper(x) ((char)CharUpper((LPSTR)x))
static int nseel_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
int *NSEEL_getstats()
{
return nseel_evallib_stats;
}
double *NSEEL_getglobalregs()
{
return nseel_globalregs;
}
static size_t LLB_DSIZE=0;
//#define LLB_DSIZE (65536-64)
typedef struct _llBlockHeader
{
struct _llBlock *next;
size_t sizeused;
} llBlockHeader;
typedef struct _llBlock {
llBlockHeader header;
char block[1];
} llBlock;
typedef struct _startPtr {
struct _startPtr *next;
void *startptr;
} startPtr;
typedef struct {
int workTablePtr_size;
llBlock *blocks;
void *code;
int code_stats[4];
} codeHandleType;
#ifndef NSEEL_MAX_TEMPSPACE_ENTRIES
#define NSEEL_MAX_TEMPSPACE_ENTRIES 2048
#endif
static void *__newBlock(llBlock **start,size_t size);
#define newTmpBlock(x) __newBlock((llBlock **)&ctx->tmpblocks_head,x)
#define newBlock(x) __newBlock((llBlock **)&ctx->blocks_head,x)
static void freeBlocks(llBlock *start);
void nseel_asm_sin(void);
void nseel_asm_sin_end(void);
void nseel_asm_cos(void);
void nseel_asm_cos_end(void);
void nseel_asm_tan(void);
void nseel_asm_tan_end(void);
void nseel_asm_asin(void);
void nseel_asm_asin_end(void);
void nseel_asm_acos(void);
void nseel_asm_acos_end(void);
void nseel_asm_atan(void);
void nseel_asm_atan_end(void);
void nseel_asm_atan2(void);
void nseel_asm_atan2_end(void);
void nseel_asm_sqr(void);
void nseel_asm_sqr_end(void);
void nseel_asm_sqrt(void);
void nseel_asm_sqrt_end(void);
void nseel_asm_pow(void);
void nseel_asm_pow_end(void);
void nseel_asm_exp(void);
void nseel_asm_exp_end(void);
void nseel_asm_log(void);
void nseel_asm_log_end(void);
void nseel_asm_log10(void);
void nseel_asm_log10_end(void);
void nseel_asm_abs(void);
void nseel_asm_abs_end(void);
void nseel_asm_min(void);
void nseel_asm_min_end(void);
void nseel_asm_max(void);
void nseel_asm_max_end(void);
void nseel_asm_sig(void);
void nseel_asm_sig_end(void);
void nseel_asm_sign(void);
void nseel_asm_sign_end(void);
void nseel_asm_rand(void);
void nseel_asm_rand_end(void);
void nseel_asm_band(void);
void nseel_asm_band_end(void);
void nseel_asm_bor(void);
void nseel_asm_bor_end(void);
void nseel_asm_bnot(void);
void nseel_asm_bnot_end(void);
void nseel_asm_if(void);
void nseel_asm_if_end(void);
void nseel_asm_repeat(void);
void nseel_asm_repeat_end(void);
void nseel_asm_equal(void);
void nseel_asm_equal_end(void);
void nseel_asm_below(void);
void nseel_asm_below_end(void);
void nseel_asm_above(void);
void nseel_asm_above_end(void);
void nseel_asm_assign(void);
void nseel_asm_assign_end(void);
void nseel_asm_add(void);
void nseel_asm_add_end(void);
void nseel_asm_sub(void);
void nseel_asm_sub_end(void);
void nseel_asm_mul(void);
void nseel_asm_mul_end(void);
void nseel_asm_div(void);
void nseel_asm_div_end(void);
void nseel_asm_mod(void);
void nseel_asm_mod_end(void);
void nseel_asm_or(void);
void nseel_asm_or_end(void);
void nseel_asm_and(void);
void nseel_asm_and_end(void);
void nseel_asm_uplus(void);
void nseel_asm_uplus_end(void);
void nseel_asm_uminus(void);
void nseel_asm_uminus_end(void);
void nseel_asm_floor(void);
void nseel_asm_floor_end(void);
void nseel_asm_ceil(void);
void nseel_asm_ceil_end(void);
void nseel_asm_invsqrt(void);
void nseel_asm_invsqrt_end(void);
void nseel_asm_exec2(void);
void nseel_asm_exec2_end(void);
/*
#define DECL_ASMFUNC(x) \
void nseel_asm_##x##(void); \
void nseel_asm_##x##_end(void); \
DECL_ASMFUNC(sin)
DECL_ASMFUNC(cos)
DECL_ASMFUNC(tan)
DECL_ASMFUNC(asin)
DECL_ASMFUNC(acos)
DECL_ASMFUNC(atan)
DECL_ASMFUNC(atan2)
DECL_ASMFUNC(sqr)
DECL_ASMFUNC(sqrt)
DECL_ASMFUNC(pow)
DECL_ASMFUNC(exp)
DECL_ASMFUNC(log)
DECL_ASMFUNC(log10)
DECL_ASMFUNC(abs)
DECL_ASMFUNC(min)
DECL_ASMFUNC(min)
DECL_ASMFUNC(max)
DECL_ASMFUNC(sig)
DECL_ASMFUNC(sign)
DECL_ASMFUNC(rand)
DECL_ASMFUNC(band)
DECL_ASMFUNC(bor)
DECL_ASMFUNC(bnot)
DECL_ASMFUNC(if)
DECL_ASMFUNC(repeat)
DECL_ASMFUNC(equal)
DECL_ASMFUNC(below)
DECL_ASMFUNC(above)
DECL_ASMFUNC(assign)
DECL_ASMFUNC(add)
DECL_ASMFUNC(sub)
DECL_ASMFUNC(mul)
DECL_ASMFUNC(div)
DECL_ASMFUNC(mod)
DECL_ASMFUNC(or)
DECL_ASMFUNC(and)
DECL_ASMFUNC(uplus)
DECL_ASMFUNC(uminus)
DECL_ASMFUNC(floor)
DECL_ASMFUNC(ceil)
DECL_ASMFUNC(invsqrt)
DECL_ASMFUNC(exec2)
*/
static functionType fnTable1[] = {
{ "if", nseel_asm_if,nseel_asm_if_end, 3 },
#ifdef NSEEL_LOOPFUNC_SUPPORT
{ "loop", nseel_asm_repeat,nseel_asm_repeat_end, 2 },
#endif
{ "sin", nseel_asm_sin,nseel_asm_sin_end, 1 },
{ "cos", nseel_asm_cos,nseel_asm_cos_end, 1 },
{ "tan", nseel_asm_tan,nseel_asm_tan_end, 1 },
{ "asin", nseel_asm_asin,nseel_asm_asin_end, 1 },
{ "acos", nseel_asm_acos,nseel_asm_acos_end, 1 },
{ "atan", nseel_asm_atan,nseel_asm_atan_end, 1 },
{ "atan2", nseel_asm_atan2,nseel_asm_atan2_end, 2 },
{ "sqr", nseel_asm_sqr,nseel_asm_sqr_end, 1 },
{ "sqrt", nseel_asm_sqrt,nseel_asm_sqrt_end, 1 },
{ "pow", nseel_asm_pow,nseel_asm_pow_end, 2 },
{ "exp", nseel_asm_exp,nseel_asm_exp_end, 1 },
{ "log", nseel_asm_log,nseel_asm_log_end, 1 },
{ "log10", nseel_asm_log10,nseel_asm_log10_end, 1 },
{ "abs", nseel_asm_abs,nseel_asm_abs_end, 1 },
{ "min", nseel_asm_min,nseel_asm_min_end, 2 },
{ "max", nseel_asm_max,nseel_asm_max_end, 2 },
{ "sigmoid",nseel_asm_sig,nseel_asm_sig_end, 2 } ,
{ "sign", nseel_asm_sign,nseel_asm_sign_end, 1 } ,
{ "rand", nseel_asm_rand,nseel_asm_rand_end, 1 } ,
{ "band", nseel_asm_band,nseel_asm_band_end, 2 } ,
{ "bor", nseel_asm_bor,nseel_asm_bor_end, 2 } ,
{ "bnot", nseel_asm_bnot,nseel_asm_bnot_end, 1 } ,
{ "equal", nseel_asm_equal,nseel_asm_equal_end, 2 },
{ "below", nseel_asm_below,nseel_asm_below_end, 2 },
{ "above", nseel_asm_above,nseel_asm_above_end, 2 },
{ "floor", nseel_asm_floor,nseel_asm_floor_end, 1 },
{ "ceil", nseel_asm_ceil,nseel_asm_ceil_end, 1 },
{ "invsqrt", nseel_asm_invsqrt,nseel_asm_invsqrt_end, 1 },
{ "assign",nseel_asm_assign,nseel_asm_assign_end,2},
{ "exec2",nseel_asm_exec2,nseel_asm_exec2_end,2},
{ "exec3",nseel_asm_exec2,nseel_asm_exec2_end,3},
};
static functionType *fnTableUser;
static int fnTableUser_size;
functionType *nseel_getFunctionFromTable(int idx)
{
if (idx<0) return 0;
if (idx>=sizeof(fnTable1)/sizeof(fnTable1[0]))
{
idx -= sizeof(fnTable1)/sizeof(fnTable1[0]);
if (!fnTableUser || idx >= fnTableUser_size) return 0;
return fnTableUser+idx;
}
return fnTable1+idx;
}
int NSEEL_init() // returns 0 on success
{
NSEEL_quit();
return 0;
}
void NSEEL_addfunctionex(char *name, int nparms, int code_startaddr, int code_len, void *pproc)
{
if (!fnTableUser || !(fnTableUser_size&7))
{
fnTableUser=(functionType *)realloc(fnTableUser,(fnTableUser_size+8)*sizeof(functionType));
}
if (fnTableUser)
{
fnTableUser[fnTableUser_size].nParams = nparms;
fnTableUser[fnTableUser_size].name = name;
fnTableUser[fnTableUser_size].afunc = (void *)code_startaddr;
fnTableUser[fnTableUser_size].func_e = (void *)(code_startaddr + code_len);
fnTableUser[fnTableUser_size].pProc = (NSEEL_PPPROC) pproc;
fnTableUser_size++;
}
}
void NSEEL_quit()
{
free(fnTableUser);
fnTableUser_size=0;
fnTableUser=0;
}
//---------------------------------------------------------------------------------------------------------------
static void *realAddress(void *fn, void *fn_e, int *size)
{
#ifdef DISABLED_DEBUG
char *ptr = (char *)fn;
int beg=(*(int *)(ptr+1))+5;
int extrasize=(int)nseel_asm_exec2_end - (int)nseel_asm_exec2;
int extrabeg=(*(int *)(((char *)nseel_asm_exec2)+1))+5;
*size=((int)fn_e - (int)fn) - (extrasize-extrabeg) - beg;
return ptr + beg;
#else
// Release Mode
*size = (int)fn_e - (int) fn;
return fn;
#endif
}
//---------------------------------------------------------------------------------------------------------------
static void freeBlocks(llBlock *start)
{
while (start)
{
llBlock *llB = start->header.next;
VirtualFree(start, 0 /*LLB_DSIZE*/, MEM_RELEASE);
start=llB;
}
}
//---------------------------------------------------------------------------------------------------------------
static void *__newBlock(llBlock **start, size_t size)
{
llBlock *llb = NULL;
size_t alloc_size = 0;
if (!LLB_DSIZE)
{
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
LLB_DSIZE = systemInfo.dwAllocationGranularity;
}
if (*start && (LLB_DSIZE - (*start)->header.sizeused) >= size)
{
void *t=(*start)->block+(*start)->header.sizeused;
(*start)->header.sizeused+=size;
return t;
}
alloc_size=LLB_DSIZE;
size+=sizeof(llBlockHeader); // make sure we have enough room for the block header;
while (size > alloc_size) alloc_size += LLB_DSIZE;
llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
llb->header.sizeused=size;
llb->header.next = *start;
*start = llb;
return llb->block;
}
#define X86_MOV_EAX_DIRECTVALUE 0xB8
#define X86_MOV_ESI_DIRECTVALUE 0xBE
#define X86_MOV_ESI_DIRECTMEMVALUE 0x358B
#define X86_PUSH_EAX 0x50
#define X86_POP_EBX 0x5B
#define X86_POP_ECX 0x59
#define X86_MOV_ESI_EDI 0xF78B
#define X86_PUSH_ESI 0x56
#define X86_POP_ESI 0x5E
#define X86_RET 0xC3
//---------------------------------------------------------------------------------------------------------------
static int *findFBlock(char *p)
{
while (*(int *)p != 0xFFFFFFFF) p++;
return (int*)p;
}
//---------------------------------------------------------------------------------------------------------------
int nseel_createCompiledValue(compileContext *ctx, double value, double *addrValue)
{
unsigned char *block = NULL;
double *dupValue = NULL;
block=(unsigned char *)newTmpBlock(4+5);
if (addrValue == NULL)
{
ctx->l_stats[3]+=sizeof(double);
*(dupValue = (double *)newBlock(sizeof(double))) = value;
}
else
dupValue = addrValue;
((int*)block)[0]=5;
block[4]=X86_MOV_EAX_DIRECTVALUE; // mov eax, <value>
*(int *)(block+5) = (int)dupValue;
return ((int)(block));
}
//---------------------------------------------------------------------------------------------------------------
static int nseel_getFunctionAddress(int fntype, int fn, int *size, NSEEL_PPPROC *pProc)
{
*pProc = NULL;
switch (fntype)
{
case MATH_SIMPLE:
switch (fn)
{
case FN_ASSIGN:
return (int)realAddress(nseel_asm_assign,nseel_asm_assign_end,size);
case FN_ADD:
return (int)realAddress(nseel_asm_add,nseel_asm_add_end,size);
case FN_SUB:
return (int)realAddress(nseel_asm_sub,nseel_asm_sub_end,size);
case FN_MULTIPLY:
return (int)realAddress(nseel_asm_mul,nseel_asm_mul_end,size);
case FN_DIVIDE:
return (int)realAddress(nseel_asm_div,nseel_asm_div_end,size);
case FN_MODULO:
return (int)realAddress(nseel_asm_mod,nseel_asm_mod_end,size);
case FN_AND:
return (int)realAddress(nseel_asm_and,nseel_asm_and_end,size);
case FN_OR:
return (int)realAddress(nseel_asm_or,nseel_asm_or_end,size);
case FN_UPLUS:
return (int)realAddress(nseel_asm_uplus,nseel_asm_uplus_end,size);
case FN_UMINUS:
return (int)realAddress(nseel_asm_uminus,nseel_asm_uminus_end,size);
}
case MATH_FN:
{
functionType *p=nseel_getFunctionFromTable(fn);
if (!p)
{
if (size) *size=0;
return 0;
}
if (p->pProc) *pProc=p->pProc;
return (int)realAddress(p->afunc,p->func_e,size);
}
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------
int nseel_createCompiledFunction3(compileContext *ctx, int fntype, int fn, int code1, int code2, int code3)
{
int sizes1=((int *)code1)[0];
int sizes2=((int *)code2)[0];
int sizes3=((int *)code3)[0];
if (fntype == MATH_FN && fn == 0) // special case: IF
{
void *func3 = NULL;
int size = 0;
int *ptr = NULL;
char *block = NULL;
unsigned char *newblock2,*newblock3 = NULL;
newblock2=newBlock(sizes2+1);
memcpy(newblock2,(char*)code2+4,sizes2);
newblock2[sizes2]=X86_RET;
newblock3=newBlock(sizes3+1);
memcpy(newblock3,(char*)code3+4,sizes3);
newblock3[sizes3]=X86_RET;
ctx->l_stats[2]+=sizes2+sizes3+2;
func3 = realAddress(nseel_asm_if,nseel_asm_if_end,&size);
block=(char *)newTmpBlock(4+sizes1+size);
((int*)block)[0]=sizes1+size;
memcpy(block+4,(char*)code1+4,sizes1);
ptr=(int *)(block+4+sizes1);
memcpy(ptr,func3,size);
ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
ptr=findFBlock((char*)ptr); *ptr=(int)newblock3;
ctx->computTableTop++;
return (int)block;
}
else
{
int size2 = 0;
unsigned char *block = NULL;
unsigned char *outp = NULL;
int myfunc = 0;
NSEEL_PPPROC preProc;
myfunc = nseel_getFunctionAddress(fntype, fn, &size2, &preProc);
block=(unsigned char *)newTmpBlock(4+size2+sizes1+sizes2+sizes3+4);
((int*)block)[0]=4+size2+sizes1+sizes2+sizes3;
outp=block+4;
memcpy(outp,(char*)code1+4,sizes1);
outp+=sizes1;
*outp++ = X86_PUSH_EAX;
memcpy(outp,(char*)code2+4,sizes2);
outp+=sizes2;
*outp++ = X86_PUSH_EAX;
memcpy(outp,(char*)code3+4,sizes3);
outp+=sizes3;
*outp++ = X86_POP_EBX;
*outp++ = X86_POP_ECX;
memcpy(outp,(void*)myfunc,size2);
if (preProc) preProc(outp,size2,ctx->userfunc_data);
ctx->computTableTop++;
return ((int)(block));
}
}
//---------------------------------------------------------------------------------------------------------------
int nseel_createCompiledFunction2(compileContext *ctx, int fntype, int fn, int code1, int code2)
{
int size2 = 0;
unsigned char *block = NULL;
unsigned char *outp = NULL;
int myfunc = 0;
int sizes1=((int *)code1)[0];
int sizes2=((int *)code2)[0];
#ifdef NSEEL_LOOPFUNC_SUPPORT
if (fntype == MATH_FN && fn == 1) // special case: REPEAT
{
void *func3 = NULL;
int size = 0;
int *ptr = NULL;
char *block = NULL;
unsigned char *newblock2 = NULL;
newblock2=newBlock(sizes2+1);
memcpy(newblock2,(char*)code2+4,sizes2);
newblock2[sizes2]=X86_RET;
ctx->l_stats[2]+=sizes2+2;
func3 = realAddress(nseel_asm_repeat,nseel_asm_repeat_end,&size);
block=(char *)newTmpBlock(4+sizes1+size);
((int*)block)[0]=sizes1+size;
memcpy(block+4,(char*)code1+4,sizes1);
ptr=(int *)(block+4+sizes1);
memcpy(ptr,func3,size);
ptr=findFBlock((char*)ptr); *ptr++=(int)newblock2;
ctx->computTableTop++;
return (int)block;
}
else
#endif
{
NSEEL_PPPROC preProc;
myfunc = nseel_getFunctionAddress(fntype, fn, &size2,&preProc);
block=(unsigned char *)newTmpBlock(2+size2+sizes1+sizes2+4);
((int*)block)[0]=2+size2+sizes1+sizes2;
outp=block+4;
memcpy(outp,(char*)code1+4,sizes1);
outp+=sizes1;
*outp++ = X86_PUSH_EAX;
memcpy(outp,(char*)code2+4,sizes2);
outp+=sizes2;
*outp++ = X86_POP_EBX;
memcpy(outp,(void*)myfunc,size2);
if (preProc) preProc(outp,size2,ctx->userfunc_data);
ctx->computTableTop++;
return ((int)(block));
}
}
//---------------------------------------------------------------------------------------------------------------
int nseel_createCompiledFunction1(compileContext *ctx, int fntype, int fn, int code)
{
NSEEL_PPPROC preProc;
int size,size2 = 0;
char *block = NULL;
int myfunc = 0;
void *func1 = NULL;
size =((int *)code)[0];
func1 = (void *)(code+4);
myfunc = nseel_getFunctionAddress(fntype, fn, &size2,&preProc);
block=(char *)newTmpBlock(4+size+size2);
((int*)block)[0]=size+size2;
memcpy(block+4, func1, size);
memcpy(block+size+4,(void*)myfunc,size2);
if (preProc) preProc(block+size+4,size2,ctx->userfunc_data);
ctx->computTableTop++;
return ((int)(block));
}
static char *preprocessCode(compileContext *ctx, char *expression)
{
int len=0;
int alloc_len=strlen(expression)+1+64;
char *buf=(char *)malloc(alloc_len);
while (*expression)
{
if (len > alloc_len-32)
{
alloc_len = len+128;
buf=(char*)realloc(buf,alloc_len);
}
if (expression[0] == '/')
{
if (expression[1] == '/')
{
expression+=2;
while (expression[0] && expression[0] != '\r' && expression[0] != '\n') expression++;
}
else if (expression[1] == '*')
{
expression+=2;
while (expression[0] && (expression[0] != '*' || expression[1] != '/')) expression++;
if (expression[0]) expression+=2; // at this point we KNOW expression[0]=* and expression[1]=/
}
else
{
char c=buf[len++]=*expression++;
if (c != ' ' && c != '\t' && c != '\r' && c != '\n') ctx->l_stats[0]++;
}
}
else if (expression[0] == '$')
{
if (ltoupper(expression[1]) == 'P' && ltoupper(expression[2]) == 'I')
{
static char *str="3.141592653589793";
expression+=3;
memcpy(buf+len,str,17);
len+=17; //strlen(str);
ctx->l_stats[0]+=17;
}
else if (ltoupper(expression[1]) == 'E')
{
static char *str="2.71828183";
expression+=2;
memcpy(buf+len,str,10);
len+=10; //strlen(str);
ctx->l_stats[0]+=10;
}
if (ltoupper(expression[1]) == 'P' && ltoupper(expression[2]) == 'H' && ltoupper(expression[3]) == 'I')
{
static char *str="1.61803399";
expression+=4;
memcpy(buf+len,str,10);
len+=10; //strlen(str);
ctx->l_stats[0]+=10;
}
else
{
char c = buf[len++]=*expression++;
if (c != ' ' && c != '\t' && c != '\r' && c != '\n') ctx->l_stats[0]++;
}
}
else
{
char c=*expression++;
if (c == '\r' || c == '\n' || c == '\t') c=' ';
buf[len++]=c;
if (c != ' ') ctx->l_stats[0]++;
}
}
buf[len]=0;
return buf;
}
static void movestringover(char *str, int amount)
{
char tmp[1024+8];
int l=(int)strlen(str);
l=min(1024-amount-1,l);
memcpy(tmp,str,l+1);
while (l >= 0 && tmp[l]!='\n') l--;
l++;
tmp[l]=0;//ensure we null terminate
memcpy(str+amount,tmp,l+1);
}
//------------------------------------------------------------------------------
NSEEL_CODEHANDLE NSEEL_code_compile(NSEEL_VMCTX _ctx, char *_expression)
{
compileContext *ctx = (compileContext *)_ctx;
char *expression,*expression_start;
int computable_size=0;
codeHandleType *handle;
startPtr *scode=NULL;
startPtr *startpts=NULL;
if (!ctx || !_expression || !*_expression) return 0;
ctx->last_error_string[0]=0;
ctx->blocks_head=0;
ctx->tmpblocks_head=0;
memset(ctx->l_stats,0, sizeof(ctx->l_stats) / sizeof(ctx->l_stats[0]));
handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
if (!handle)
{
return 0;
}
memset(handle,0,sizeof(codeHandleType));
expression_start=expression=preprocessCode(ctx,_expression);
while (*expression)
{
startPtr *tmp;
char *expr;
ctx->colCount=0;
// single out segment
while (*expression == ';' || *expression == ' ') expression++;
if (!*expression) break;
expr=expression;
while (*expression && *expression != ';') expression++;
if (*expression) *expression++ = 0;
// parse
tmp=(startPtr*) newTmpBlock(sizeof(startPtr));
if (!tmp) break;
ctx->computTableTop=0;
tmp->startptr=nseel_compileExpression(ctx,expr);
if (ctx->computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES- /* safety */ 16 - /* alignment */4 ||
!tmp->startptr)
{
lstrcpyn(ctx->last_error_string,expr,sizeof(ctx->last_error_string)/sizeof(ctx->last_error_string[0]));
scode=NULL;
break;
}
if (computable_size < ctx->computTableTop)
{
computable_size=ctx->computTableTop;
}
tmp->next=NULL;
if (!scode) scode=startpts=tmp;
else
{
scode->next=tmp;
scode=tmp;
}
}
// check to see if failed on the first startingCode
if (!scode)
{
freeBlocks((llBlock *)ctx->blocks_head); // free blocks
handle=NULL; // return NULL (after resetting blocks_head)
}
else
{
// now we build one big code segment out of our list of them, inserting a mov esi, computable before each item
unsigned char *writeptr;
int size=1; // for ret at end :)
startPtr *p;
p=startpts;
while (p)
{
size+=2; // mov esi, edi
size+=*(int *)p->startptr;
p=p->next;
}
handle->code = newBlock(size);
if (handle->code)
{
writeptr=(unsigned char *)handle->code;
p=startpts;
while (p)
{
int thissize=*(int *)p->startptr;
*(unsigned short *)writeptr= X86_MOV_ESI_EDI;
writeptr+=2;
memcpy(writeptr,(char*)p->startptr + 4,thissize);
writeptr += thissize;
p=p->next;
}
*writeptr=X86_RET; // ret
ctx->l_stats[1]=size;
}
handle->blocks = ctx->blocks_head;
handle->workTablePtr_size=(computable_size) * sizeof(double);
}
freeBlocks((llBlock *)ctx->tmpblocks_head); // free blocks
ctx->tmpblocks_head=0;
ctx->blocks_head=0;
if (handle)
{
memcpy(handle->code_stats,ctx->l_stats,sizeof(ctx->l_stats));
nseel_evallib_stats[0]+=ctx->l_stats[0];
nseel_evallib_stats[1]+=ctx->l_stats[1];
nseel_evallib_stats[2]+=ctx->l_stats[2];
nseel_evallib_stats[3]+=ctx->l_stats[3];
nseel_evallib_stats[4]++;
}
memset(ctx->l_stats,0,sizeof(ctx->l_stats));
free(expression_start);
return (NSEEL_CODEHANDLE)handle;
}
//------------------------------------------------------------------------------
void NSEEL_code_execute(NSEEL_CODEHANDLE code)
{
#ifdef NSEEL_REENTRANT_EXECUTION
int baseptr;
#else
static double _tab[NSEEL_MAX_TEMPSPACE_ENTRIES];
int baseptr = (int) _tab;
#endif
codeHandleType *h = (codeHandleType *)code;
if (!h || !h->code)
return;
#ifdef NSEEL_REENTRANT_EXECUTION
baseptr = (int) alloca(h->workTablePtr_size + 16*sizeof(double) /*safety*/ + 32 /*alignment*/);
if (!baseptr)
return;
#endif
{
int startPoint=(int)h->code;
__asm
{
mov ebx, baseptr
mov eax, startPoint
pushad // Lets cover our ass
add ebx, 31
and ebx, ~31
mov edi, ebx
call eax
popad
}
}
}
char *NSEEL_code_getcodeerror(NSEEL_VMCTX ctx)
{
compileContext *c=(compileContext *)ctx;
if (ctx && c->last_error_string[0]) return c->last_error_string;
return 0;
}
//------------------------------------------------------------------------------
void NSEEL_code_free(NSEEL_CODEHANDLE code)
{
codeHandleType *h = (codeHandleType *)code;
if (h != NULL)
{
nseel_evallib_stats[0]-=h->code_stats[0];
nseel_evallib_stats[1]-=h->code_stats[1];
nseel_evallib_stats[2]-=h->code_stats[2];
nseel_evallib_stats[3]-=h->code_stats[3];
nseel_evallib_stats[4]--;
freeBlocks(h->blocks);
}
}
//------------------------------------------------------------------------------
void NSEEL_VM_resetvars(NSEEL_VMCTX _ctx)
{
if (_ctx)
{
compileContext *ctx=(compileContext *)_ctx;
int x;
if (ctx->varTable_Names || ctx->varTable_Values) for (x = 0; x < ctx->varTable_numBlocks; x ++)
{
if (ctx->varTable_Names)
free(ctx->varTable_Names[x]);
if (ctx->varTable_Values)
free(ctx->varTable_Values[x]);
}
free(ctx->varTable_Values);
free(ctx->varTable_Names);
ctx->varTable_Values=0;
ctx->varTable_Names=0;
ctx->varTable_numBlocks=0;
}
}
NSEEL_VMCTX NSEEL_VM_alloc() // return a handle
{
compileContext *ctx=calloc(1,sizeof(compileContext));
return ctx;
}
void NSEEL_VM_free(NSEEL_VMCTX ctx) // free when done with a VM and ALL of its code have been freed, as well
{
free(ctx);
}
int *NSEEL_code_getstats(NSEEL_CODEHANDLE code)
{
codeHandleType *h = (codeHandleType *)code;
if (h)
{
return h->code_stats;
}
return 0;
}

282
Src/ns-eel/nseel-eval.c Normal file
View File

@ -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;
}

265
Src/ns-eel/nseel-lextab.c Normal file
View File

@ -0,0 +1,265 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
nseel-lextab.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 "ns-eel-int.h"
#define LEXSKIP (-1)
static int _lmovb(struct lextab *lp, int c, int st)
{
int base;
while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
(lp->llcheck[base] & 0377) != st) {
if (st != lp->llendst) {
base = lp->lldefault[st] & 0377;
st = base;
}
else
return(-1);
}
return(lp->llnext[base]&0377);
}
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
static int _Alextab(compileContext *ctx, int __na__)
{
if (__na__ >= 0 && __na__ <= 19) nseel_count(ctx);
switch (__na__)
{
case 0: ctx->yylval = nseel_translate(ctx,HEXCONST); return VALUE;
case 1: ctx->yylval = nseel_translate(ctx,INTCONST); return VALUE;
case 2: ctx->yylval = nseel_translate(ctx,INTCONST); return VALUE;
case 3: ctx->yylval = nseel_translate(ctx,DBLCONST); return VALUE;
case 4:
case 5: nseel_setLastVar(ctx); ctx->yylval = nseel_lookup(ctx,&__na__); return __na__;
case 6: return '+';
case 7: return '-';
case 8: return '*';
case 9: return '/';
case 10: return '%';
case 11: return '&';
case 12: return '|';
case 13: return '(';
case 14: return ')';
case 15: return '=';
case 16: return ',';
case 17: return ';';
}
return (LEXSKIP);
}
static char _Flextab[] =
{
1, 18, 17, 16, 15, 14, 13, 12,
11, 10, 9, 8, 7, 6, 4, 5,
5, 4, 4, 3, 3, 3, 3, 4,
0, 4, 5, 0, 5, 4, 1, 3,
0, 2, -1, 1, -1,
};
static char _Nlextab[] =
{
36, 36, 36, 36, 36, 36, 36, 36,
36, 1, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
1, 36, 36, 36, 36, 9, 8, 36,
6, 5, 11, 13, 3, 12, 19, 10,
30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 36, 2, 36, 4, 36, 36,
36, 29, 29, 29, 29, 29, 29, 18,
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 36, 36, 36, 36, 18,
36, 29, 29, 29, 29, 29, 23, 18,
18, 18, 18, 18, 18, 18, 18, 18,
18, 18, 18, 18, 18, 18, 14, 18,
18, 18, 18, 36, 7, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 36,
36, 36, 36, 36, 36, 36, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
36, 36, 36, 36, 17, 36, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 36, 36, 36, 36, 36, 36,
36, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 36, 36, 36, 36, 16,
36, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 36,
20, 26, 26, 26, 26, 26, 26, 26,
26, 26, 26, 36, 36, 36, 36, 36,
36, 36, 25, 25, 25, 25, 25, 25,
36, 24, 36, 36, 36, 36, 36, 36,
20, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 25, 25, 25, 25, 25, 25,
36, 24, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, 36, 36, 36, 36,
36, 36, 36, 28, 28, 28, 28, 28,
28, 36, 27, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 28, 28, 28, 28, 28,
28, 31, 27, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 36, 36, 36,
36, 36, 36, 36, 34, 34, 34, 33,
34, 34, 36, 32, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 34, 34, 34, 33,
34, 34, 36, 32, 34, 34, 34, 34,
34, 34, 34, 34, 34, 34, 36, 36,
36, 36, 36, 36, 36, 34, 34, 34,
34, 34, 34, 36, 32, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 34, 34, 34,
34, 34, 34, 36, 32,
};
static char _Clextab[] =
{
-1, -1, -1, -1, -1, -1, -1, -1,
-1, 0, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
0, -1, -1, -1, -1, 0, 0, -1,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, -1, 0, -1, 0, -1, -1,
-1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1, -1, -1, -1, 0,
-1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -1, 0, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, -1,
-1, -1, -1, -1, -1, -1, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
-1, -1, -1, -1, 14, -1, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, -1, -1, -1, -1, -1, -1,
-1, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, -1, -1, -1, -1, 15,
-1, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, -1,
19, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, -1, -1, -1, -1, -1,
-1, -1, 23, 23, 23, 23, 23, 23,
-1, 23, -1, -1, -1, -1, -1, -1,
19, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, 23, 23, 23, 23, 23, 23,
-1, 23, 26, 26, 26, 26, 26, 26,
26, 26, 26, 26, -1, -1, -1, -1,
-1, -1, -1, 26, 26, 26, 26, 26,
26, -1, 26, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 26, 26, 26, 26, 26,
26, 30, 26, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30, -1, -1, -1,
-1, -1, -1, -1, 30, 30, 30, 30,
30, 30, -1, 30, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, 30, 30, 30, 30,
30, 30, -1, 30, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, -1, -1,
-1, -1, -1, -1, -1, 33, 33, 33,
33, 33, 33, -1, 33, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 33, 33, 33,
33, 33, 33, -1, 33,
};
static char _Dlextab[] =
{
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
15, 14, 14, 36, 36, 20, 19, 14,
14, 23, 15, 15, 26, 23, 36, 19,
36, 36, 33, 30,
};
static int _Blextab[] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 77, 152,
0, 0, 0, 227, 237, 0, 0, 249,
0, 0, 306, 0, 0, 0, 363, 0,
0, 420, 0, 0, 0,
};
struct lextab nseel_lextab = {
36,
_Dlextab,
_Nlextab,
_Clextab,
_Blextab,
524,
_lmovb,
_Flextab,
_Alextab,
0,
0,
0,
0,
};

162
Src/ns-eel/nseel-yylex.c Normal file
View File

@ -0,0 +1,162 @@
/*
Nullsoft Expression Evaluator Library (NS-EEL)
Copyright (C) 1999-2003 Nullsoft, Inc.
nseel-yylex.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 "ns-eel-int.h"
#define NBPW 16
#define EOF (-1)
#define ERROR 256 /* yacc's value */
static int llset(compileContext *ctx);
static int llinp(compileContext *ctx, char **exp);
static int lexgetc(char **exp)
{
char c= **exp;
if (c) (*exp)++;
return( c != 0 ? c : -1);
}
static int tst__b(register int c, char tab[])
{
return (tab[(c >> 3) & 037] & (1 << (c & 07)) );
}
int nseel_gettoken(compileContext *ctx, char *lltb, int lltbsiz)
{
register char *lp, *tp, *ep;
tp = lltb;
ep = tp+lltbsiz-1;
for (lp = ctx->llbuf; lp < ctx->llend && tp < ep;)
*tp++ = *lp++;
*tp = 0;
return(tp-lltb);
}
int nseel_yylex(compileContext *ctx, char **exp)
{
register int c, st;
int final, l, llk, i;
register struct lextab *lp;
char *cp;
while (1)
{
llk = 0;
if (llset(ctx)) return(0);
st = 0;
final = -1;
lp = &nseel_lextab;
do {
if (lp->lllook && (l = lp->lllook[st])) {
for (c=0; c<NBPW; c++)
if (l&(1<<c))
ctx->llsave[c] = ctx->llp1;
llk++;
}
if ((i = lp->llfinal[st]) != -1) {
final = i;
ctx->llend = ctx->llp1;
}
if ((c = llinp(ctx,exp)) < 0)
break;
if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
ctx->llp1--;
break;
}
} while ((st = (*lp->llmove)(lp, c, st)) != -1);
if (ctx->llp2 < ctx->llp1)
ctx->llp2 = ctx->llp1;
if (final == -1) {
ctx->llend = ctx->llp1;
if (st == 0 && c < 0)
return(0);
if ((cp = lp->llill) && tst__b(c, cp)) {
continue;
}
return(ERROR);
}
if (c = (final >> 11) & 037)
ctx->llend = ctx->llsave[c-1];
if ((c = (*lp->llactr)(ctx,final&03777)) >= 0)
return(c);
}
}
void nseel_llinit(compileContext *ctx)
{
ctx->llp1 = ctx->llp2 = ctx->llend = ctx->llbuf;
ctx->llebuf = ctx->llbuf + sizeof(ctx->llbuf);
ctx->lleof = ctx->yyline = 0;
}
static int llinp(compileContext *ctx, char **exp)
{
register c;
register struct lextab *lp;
register char *cp;
lp = &nseel_lextab;
cp = lp->llign; /* Ignore class */
for (;;) {
/*
* Get the next character from the save buffer (if possible)
* If the save buffer's empty, then return EOF or the next
* input character. Ignore the character if it's in the
* ignore class.
*/
c = (ctx->llp1 < ctx->llp2) ? *ctx->llp1 & 0377 : (ctx->lleof) ? EOF : lexgetc(exp);
if (c >= 0) { /* Got a character? */
if (cp && tst__b(c, cp))
continue; /* Ignore it */
if (ctx->llp1 >= ctx->llebuf) { /* No, is there room? */
return -1;
}
*ctx->llp1++ = c; /* Store in token buff */
} else
ctx->lleof = 1; /* Set EOF signal */
return(c);
}
}
static int llset(compileContext *ctx)
/*
* Return TRUE if EOF and nothing was moved in the look-ahead buffer
*/
{
register char *lp1, *lp2;
for (lp1 = ctx->llbuf, lp2 = ctx->llend; lp2 < ctx->llp2;)
*lp1++ = *lp2++;
ctx->llend = ctx->llp1 = ctx->llbuf;
ctx->llp2 = lp1;
return(ctx->lleof && lp1 == ctx->llbuf);
}