Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

Binary file not shown.

View file

@ -0,0 +1,576 @@
#include <windows.h>
#include <stdio.h>
#include "Compiler.h"
#include "eval.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
int yyerror(char *);
int yylex(char **exp);
extern int result;
typedef struct
{
int timestamp;
int first_line;
int first_column;
int last_line;
int last_column;
char *text;
} yyltype;
#define YYLTYPE yyltype
#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 YYPURE 1
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYIMPURE
#define YYLEX yylex(&exp)
#endif
#ifndef YYPURE
#define YYLEX yylex(&yylval)//, &yylloc) MY MODIF!
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYIMPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
int yynerrs; /* number of parse errors so far */
#endif /* YYIMPURE */
/* 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 yyparse(char *exp)
{
register int yystate;
register int yyn;
register short *yyssp;
register 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;
#ifndef YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#endif
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
yylval = 0;
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
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 (yychar == YYEMPTY)
{
// yyStackSize = yyssp - (yyss - 1);
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
}
else
{
yychar1 = YYTRANSLATE(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 (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = 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]; result = yyvsp[0]; ;
break;}
case 2:
//#ln 34 "cal.y"
{ {
int i = (int)setVar((int)yyvsp[-2], 0);
int v;
if (i < 0) v=createCompiledValue(0, NULL);
else if (i < EVAL_MAX_VARS) v= createCompiledValue(0, &(varTable[i].value));
else if (i < EVAL_MAX_VARS+100) v= createCompiledValue(0, globalregs+i-EVAL_MAX_VARS);
else v=createCompiledValue(0, NULL);
yyval = createCompiledFunction2(MATH_SIMPLE, FN_ASSIGN, v, (int)yyvsp[0]);
result = yyval;
}
;
break;}
case 3:
//#ln 50 "cal.y"
{ yyval = yyvsp[0] ;
break;}
case 4:
//#ln 55 "cal.y"
{ yyval = getVar((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 = createCompiledFunction2(MATH_SIMPLE, FN_MULTIPLY, yyvsp[-2], yyvsp[0]);
break;}
case 9:
//#ln 72 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_DIVIDE, yyvsp[-2], yyvsp[0]);
break;}
case 10:
//#ln 78 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_MODULO, yyvsp[-2], yyvsp[0]);
break;}
case 11:
//#ln 84 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_ADD, yyvsp[-2], yyvsp[0]);
break;}
case 12:
//#ln 90 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_SUB, yyvsp[-2], yyvsp[0]);
break;}
case 13:
//#ln 96 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_AND, yyvsp[-2], yyvsp[0]);
break;}
case 14:
//#ln 102 "cal.y"
{ yyval = createCompiledFunction2(MATH_SIMPLE, FN_OR, yyvsp[-2], yyvsp[0]);
break;}
case 15:
//#ln 108 "cal.y"
{ yyval = createCompiledFunction1(MATH_SIMPLE, FN_UMINUS, yyvsp[0]);
break;}
case 16:
//#ln 114 "cal.y"
{ yyval = createCompiledFunction1(MATH_SIMPLE, FN_UPLUS, yyvsp[0]);
break;}
case 17:
//#ln 120 "cal.y"
{ yyval = yyvsp[0];
break;}
case 18:
//#ln 125 "cal.y"
{ yyval = createCompiledFunction1(MATH_FN, (int)yyvsp[-3], yyvsp[-1]);
break;}
case 19:
//#ln 131 "cal.y"
{ yyval = createCompiledFunction2(MATH_FN, (int)yyvsp[-5], yyvsp[-3], yyvsp[-1]);
break;}
case 20:
//#ln 137 "cal.y"
{ yyval = createCompiledFunction3(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. */
{
++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 (yychar == YYEOF) YYABORT;
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 = yylval;
yystate = yyn;
goto yynewstate;
}

View file

@ -0,0 +1,747 @@
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include "Compiler.h"
#include "eval.h"
// defining this allows code to run in different threads at the same time
// it tends however, to be slower. We leave this OFF for AVS, since most of our shit runs in one thread
// anyhow.
//#define NSEEL_REENTRANT_EXECUTION
#ifdef NSEEL_REENTRANT_EXECUTION
#include <malloc.h>
#endif
#define NSEEL_USE_CRITICAL_SECTION g_eval_cs
// note that compiling can only happen in one thread at a time, always.
int g_evallib_stats[5]; // source bytes, static code bytes, call code bytes, data bytes, segments
#ifdef NSEEL_USE_CRITICAL_SECTION
CRITICAL_SECTION NSEEL_USE_CRITICAL_SECTION;
#endif
#define LLB_DSIZE (65536-64)
typedef struct _llBlock {
struct _llBlock *next;
int sizeused;
char block[LLB_DSIZE];
} llBlock;
typedef struct _startPtr {
struct _startPtr *next;
void *startptr;
} startPtr;
typedef struct {
int workTablePtr_size;
llBlock *blocks;
void *code;
int code_stats[4];
} codeHandleType;
static llBlock *blocks_head = NULL;
static llBlock *tmpblocks_head = NULL; // used only during compile
#define NSEEL_MAX_TEMPSPACE_ENTRIES 8192
static int g_evallib_computTableTop; // make it abort on potential overflow =)
static int l_stats[4]; // source bytes, static code bytes, call code bytes, data bytes
static void *__newBlock(llBlock **start,int size);
#define newTmpBlock(x) __newBlock(&tmpblocks_head,x)
#define newBlock(x) __newBlock(&blocks_head,x)
static void freeBlocks(llBlock *start);
char *g_evallib_visdata;
#define DECL_ASMFUNC(x) \
void _asm_##x##(void); \
void _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(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)
DECL_ASMFUNC(getosc)
DECL_ASMFUNC(getspec)
DECL_ASMFUNC(gettime)
DECL_ASMFUNC(getmouse)
DECL_ASMFUNC(setmousepos)
static functionType fnTable1[36] = {
{ "if", _asm_if,_asm_if_end, 3 },
{ "sin", _asm_sin,_asm_sin_end, 1 },
{ "cos", _asm_cos,_asm_cos_end, 1 },
{ "tan", _asm_tan,_asm_tan_end, 1 },
{ "asin", _asm_asin,_asm_asin_end, 1 },
{ "acos", _asm_acos,_asm_acos_end, 1 },
{ "atan", _asm_atan,_asm_atan_end, 1 },
{ "atan2", _asm_atan2,_asm_atan2_end, 2 },
{ "sqr", _asm_sqr,_asm_sqr_end, 1 },
{ "sqrt", _asm_sqrt,_asm_sqrt_end, 1 },
{ "pow", _asm_pow,_asm_pow_end, 2 },
{ "exp", _asm_exp,_asm_exp_end, 1 },
{ "log", _asm_log,_asm_log_end, 1 },
{ "log10", _asm_log10,_asm_log10_end, 1 },
{ "abs", _asm_abs,_asm_abs_end, 1 },
{ "min", _asm_min,_asm_min_end, 2 },
{ "max", _asm_max,_asm_max_end, 2 },
{ "sigmoid",_asm_sig,_asm_sig_end, 2 } ,
{ "sign", _asm_sign,_asm_sign_end, 1 } ,
{ "rand", _asm_rand,_asm_rand_end, 1 } ,
{ "band", _asm_band,_asm_band_end, 2 } ,
{ "bor", _asm_bor,_asm_bor_end, 2 } ,
{ "bnot", _asm_bnot,_asm_bnot_end, 1 } ,
{ "equal", _asm_equal,_asm_equal_end, 2 },
{ "below", _asm_below,_asm_below_end, 2 },
{ "above", _asm_above,_asm_above_end, 2 },
{ "floor", _asm_floor,_asm_floor_end, 1 },
{ "ceil", _asm_ceil,_asm_ceil_end, 1 },
{ "invsqrt", _asm_invsqrt,_asm_invsqrt_end, 1 },
{ "assign",_asm_assign,_asm_assign_end,2},
{ "exec2",_asm_exec2,_asm_exec2_end,2},
// these will be seperated since they are AVS specific
{ "getosc", _asm_getosc,_asm_getosc_end,3 },
{ "getspec",_asm_getspec,_asm_getspec_end,3 },
{ "gettime", _asm_gettime,_asm_gettime_end,1},
{ "getkbmouse",_asm_getmouse,_asm_getmouse_end,1},
{ "setmousepos",_asm_setmousepos,_asm_setmousepos_end,2},
};
functionType *getFunctionFromTable(int idx)
{
// todo: add API for adding functions to a seperate table :)
if (idx<0 || idx>=sizeof(fnTable1)/sizeof(fnTable1[0])) return 0;
return fnTable1+idx;
}
//---------------------------------------------------------------------------------------------------------------
static void *realAddress(void *fn, void *fn_e, int *size)
{
#ifdef _DEBUG
// Debug Mode
*siiiize=0; // fucko, need to figure this out
char *ptr = (char *)fn;
return ptr + (*(int *)(ptr+1))+5;
#else
// Release Mode
*size = (int)fn_e - (int) fn;
return fn;
#endif
}
//---------------------------------------------------------------------------------------------------------------
static void freeBlocks(llBlock *start)
{
while (start)
{
llBlock *llB = start->next;
GlobalFree(start);
start=llB;
}
}
//---------------------------------------------------------------------------------------------------------------
static void *__newBlock(llBlock **start, int size)
{
llBlock *llb;
int alloc_size;
if (*start && (LLB_DSIZE - (*start)->sizeused) >= size)
{
void *t=(*start)->block+(*start)->sizeused;
(*start)->sizeused+=size;
return t;
}
alloc_size=sizeof(llBlock);
if ((int)size > LLB_DSIZE) alloc_size += size - LLB_DSIZE;
llb = (llBlock *)VirtualAlloc(NULL, alloc_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// benski> CUT: llb = (llBlock *)GlobalAlloc(GMEM_FIXED,alloc_size); // grab bigger block if absolutely necessary (heh)
llb->sizeused=size;
llb->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 createCompiledValue(double value, double *addrValue)
{
unsigned char *block;
double *dupValue;
block=(unsigned char *)newTmpBlock(4+5);
if (addrValue == NULL)
{
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));
}
//---------------------------------------------------------------------------------------------------------------
int getFunctionAddress(int fntype, int fn, int *size)
{
switch (fntype)
{
case MATH_SIMPLE:
switch (fn)
{
case FN_ASSIGN:
return (int)realAddress(_asm_assign,_asm_assign_end,size);
case FN_ADD:
return (int)realAddress(_asm_add,_asm_add_end,size);
case FN_SUB:
return (int)realAddress(_asm_sub,_asm_sub_end,size);
case FN_MULTIPLY:
return (int)realAddress(_asm_mul,_asm_mul_end,size);
case FN_DIVIDE:
return (int)realAddress(_asm_div,_asm_div_end,size);
case FN_MODULO:
return (int)realAddress(_asm_mod,_asm_mod_end,size);
case FN_AND:
return (int)realAddress(_asm_and,_asm_and_end,size);
case FN_OR:
return (int)realAddress(_asm_or,_asm_or_end,size);
case FN_UPLUS:
return (int)realAddress(_asm_uplus,_asm_uplus_end,size);
case FN_UMINUS:
return (int)realAddress(_asm_uminus,_asm_uminus_end,size);
}
case MATH_FN:
{
functionType *p=getFunctionFromTable(fn);
if (!p)
{
if (size) *size=0;
return 0;
}
return (int)realAddress(p->afunc,p->func_e,size);
}
}
return 0;
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction3(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;
int size;
int *ptr;
char *block;
unsigned char *newblock2,*newblock3;
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;
l_stats[2]+=sizes2+sizes3+2;
func3 = realAddress(_asm_if,_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;
return (int)block;
}
else
{
int size2;
unsigned char *block;
unsigned char *outp;
int myfunc;
myfunc = getFunctionAddress(fntype, fn, &size2);
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(block+4+4+sizes1+sizes2+sizes3,(void*)myfunc,size2);
g_evallib_computTableTop++;
return ((int)(block));
}
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction2(int fntype, int fn, int code1, int code2)
{
int size2;
unsigned char *block;
unsigned char *outp;
int myfunc;
int sizes1=((int *)code1)[0];
int sizes2=((int *)code2)[0];
myfunc = getFunctionAddress(fntype, fn, &size2);
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(block+4+2+sizes1+sizes2,(void*)myfunc,size2);
g_evallib_computTableTop++;
return ((int)(block));
}
//---------------------------------------------------------------------------------------------------------------
int createCompiledFunction1(int fntype, int fn, int code)
{
int size,size2;
char *block;
int myfunc;
void *func1;
size =((int *)code)[0];
func1 = (void *)(code+4);
myfunc = getFunctionAddress(fntype, fn, &size2);
block=(char *)newTmpBlock(4+size+size2);
((int*)block)[0]=size+size2;
memcpy(block+4, func1, size);
memcpy(block+size+4,(void*)myfunc,size2);
g_evallib_computTableTop++;
return ((int)(block));
}
static char *preprocessCode(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') l_stats[0]++;
}
}
else if (expression[0] == '$')
{
if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'I')
{
static char *str="3.141592653589793";
expression+=3;
memcpy(buf+len,str,17);
len+=17; //strlen(str);
l_stats[0]+=17;
}
else if (toupper(expression[1]) == 'E')
{
static char *str="2.71828183";
expression+=2;
memcpy(buf+len,str,10);
len+=10; //strlen(str);
l_stats[0]+=10;
}
if (toupper(expression[1]) == 'P' && toupper(expression[2]) == 'H' && toupper(expression[3]) == 'I')
{
static char *str="1.61803399";
expression+=4;
memcpy(buf+len,str,10);
len+=10; //strlen(str);
l_stats[0]+=10;
}
else
{
char c = buf[len++]=*expression++;
if (c != ' ' && c != '\t' && c != '\r' && c != '\n') l_stats[0]++;
}
}
else
{
char c=*expression++;
if (c == '\r' || c == '\n' || c == '\t') c=' ';
buf[len++]=c;
if (c != ' ') l_stats[0]++;
}
}
buf[len]=0;
return buf;
}
int g_log_errors;
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);
}
//------------------------------------------------------------------------------
int compileCode(char *_expression)
{
char *expression,*expression_start;
int computable_size=0;
codeHandleType *handle;
startPtr *scode=NULL;
startPtr *startpts=NULL;
if (!_expression || !*_expression) return 0;
if (!varTable) return 0;
#ifdef NSEEL_USE_CRITICAL_SECTION
EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
blocks_head=0;
tmpblocks_head=0;
memset(l_stats,0,sizeof(l_stats));
handle = (codeHandleType*)newBlock(sizeof(codeHandleType));
if (!handle)
{
#ifdef NSEEL_USE_CRITICAL_SECTION
LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
return 0;
}
memset(handle,0,sizeof(codeHandleType));
expression_start=expression=preprocessCode(_expression);
while (*expression)
{
startPtr *tmp;
char *expr;
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;
g_evallib_computTableTop=0;
tmp->startptr=compileExpression(expr);
if (computable_size < g_evallib_computTableTop)
{
computable_size=g_evallib_computTableTop;
}
if (g_evallib_computTableTop > NSEEL_MAX_TEMPSPACE_ENTRIES-32)
{
tmp->startptr=0; // overflow in this mode
}
if (!tmp->startptr)
{
if (g_log_errors)
{
int l=strlen(expr);
if (l > 512) l=512;
movestringover(last_error_string,l+2);
memcpy(last_error_string,expr,l);
last_error_string[l]='\r';
last_error_string[l+1]='\n';
}
scode=NULL;
break;
}
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(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
l_stats[1]=size;
}
handle->blocks = blocks_head;
handle->workTablePtr_size=(computable_size+4) * sizeof(double);
}
freeBlocks(tmpblocks_head); // free blocks
tmpblocks_head=0;
blocks_head=0;
if (handle)
{
memcpy(handle->code_stats,l_stats,sizeof(l_stats));
g_evallib_stats[0]+=l_stats[0];
g_evallib_stats[1]+=l_stats[1];
g_evallib_stats[2]+=l_stats[2];
g_evallib_stats[3]+=l_stats[3];
g_evallib_stats[4]++;
}
memset(l_stats,0,sizeof(l_stats));
#ifdef NSEEL_USE_CRITICAL_SECTION
LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
free(expression_start);
return (int)handle;
}
//------------------------------------------------------------------------------
void executeCode(int handle, char visdata[2][2][576])
{
#ifdef NSEEL_REENTRANT_EXECUTION
int baseptr;
#else
static double _tab[NSEEL_MAX_TEMPSPACE_ENTRIES];
int baseptr = (int) _tab;
#endif
codeHandleType *h = (codeHandleType *)handle;
if (!h || !h->code) return;
#ifdef NSEEL_USE_CRITICAL_SECTION
EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
g_evallib_visdata=(char*)visdata;
#ifdef NSEEL_REENTRANT_EXECUTION
baseptr = (int) alloca(h->workTablePtr_size);
if (!baseptr) return;
#endif
{
int startPoint=(int)h->code;
__asm
{
mov ebx, baseptr
mov eax, startPoint
pushad // Lets cover our ass
mov edi, ebx
call eax
popad
}
}
g_evallib_visdata=NULL;
#ifdef NSEEL_USE_CRITICAL_SECTION
LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
}
//------------------------------------------------------------------------------
void freeCode(int handle)
{
codeHandleType *h = (codeHandleType *)handle;
if (h != NULL)
{
g_evallib_stats[0]-=h->code_stats[0];
g_evallib_stats[1]-=h->code_stats[1];
g_evallib_stats[2]-=h->code_stats[2];
g_evallib_stats[3]-=h->code_stats[3];
g_evallib_stats[4]--;
freeBlocks(h->blocks);
}
}
//------------------------------------------------------------------------------
void resetVars(varType *vars)
{
#ifdef NSEEL_USE_CRITICAL_SECTION
if (vars) EnterCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
varTable=vars;
#ifdef NSEEL_USE_CRITICAL_SECTION
if (!vars) LeaveCriticalSection(& NSEEL_USE_CRITICAL_SECTION);
#endif
}

View file

@ -0,0 +1,47 @@
#ifndef __COMPILER_H
#define __COMPILER_H
#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
#ifdef __cplusplus
extern "C" {
#endif
int compileCode(char *exp);
void executeCode(int handle, char visdata[2][2][576]);
void freeCode(int handle);
typedef struct {
char *name;
void *afunc;
void *func_e;
int nParams;
} functionType;
extern functionType *getFunctionFromTable(int idx);
int createCompiledValue(double value, double *addrValue);
int createCompiledFunction1(int fntype, int fn, int code);
int createCompiledFunction2(int fntype, int fn, int code1, int code2);
int createCompiledFunction3(int fntype, int fn, int code1, int code2, int code3);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,6 @@
/*
* Bob Denny 28-Aug-82 Remove reference to stdio.h
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
*/
#include <lex.h>

Binary file not shown.

View file

@ -0,0 +1,53 @@
/*
* Bob Denny 28-Aug-82 Remove reference to FILE *lexin to
* eliminate dependency on standard I/O library. Only
* lexgetc() used it, and it's there now.
* Add EOF definition for standalone uses.
* Corrected comment for llnxtmax.
*
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C. Removed
* equivalence of yylval and lexval since
* a multi-typed parser wants yylval to be
* typed to be the union of the types (YYSTYPE).
*/
/*
* lex library header file -- accessed through
* #include <lex.h>
*/
#include <stdio.h>
/*
* Description of scanning tables. The entries at the front of
* the struct must remain in place for the assembler routines to find.
*/
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 */
};
#define NBPW 16
#define LEXERR 256
#define LEXSKIP (-1)
#define EOF (-1)
//#define NULL (0)
#define LEXECHO(fp) {lexecho((fp));}
#define lextext llbuf
#define lexlast llend
extern FILE *lexin;
extern llstin();

View file

@ -0,0 +1,20 @@
/*
* lexget.c
*
* Bob Denny 28-Aug-82 Move stdio dependencies to lexerr(), lexget(),
* lexech() and mapch(). This is one of 4 modules
* in lexlib which depend upon the standard I/O package.
*
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C.
*/
#include <stdio.h>
#include <lex.h>
extern char expression[4096];
extern int pos;
lexgetc()
{
char c = expression[pos];
if (c) pos++;
return( c != 0 ? c : -1);
}

View file

@ -0,0 +1,23 @@
/*
* lexswitch -- switch lex tables
*/
/*
* Bob Denny 28-Aug-82 Remove reference to stdio.h
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
*/
#include <lex.h>
extern struct lextab *_tabp;
struct lextab *
lexswitch(lp)
struct lextab *lp;
{
register struct lextab *olp;
olp = _tabp;
_tabp = lp;
return(olp);
}

View file

@ -0,0 +1,260 @@
/*
* Created by IBM PC LEX from file "scan.l"
* - for use with standard I/O
*/
#include <stdio.h>
#include <lex.h>
#define LL16BIT int
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);
}
int lexval;
char lbuf[];
#define YYSTYPE int
#include "cal_tab.h"
int c;
extern YYSTYPE yylval;
int translate(int type);
void count(void);
void setLastVar(void);
int lookup(int *typeOfObject);
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
int _Alextab(__na__)
{
if (__na__ >= 0 && __na__ <= 19) count();
switch (__na__)
{
case 0: yylval = translate(HEXCONST); return VALUE;
case 1: yylval = translate(INTCONST); return VALUE;
case 2: yylval = translate(INTCONST); return VALUE;
case 3: yylval = translate(DBLCONST); return VALUE;
case 4:
case 5: setLastVar(); yylval = lookup(&__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);
}
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,
};
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,
};
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,
};
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,
};
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 lextab = {
36,
_Dlextab,
_Nlextab,
_Clextab,
_Blextab,
524,
_lmovb,
_Flextab,
_Alextab,
NULL,
0,
0,
0,
};

View file

@ -0,0 +1,6 @@
/*
* This is linked from lexlib to resolve a global in yylex which
* will be undefined if the user grammar has not defined any rules
* with right-context (look-ahead)
*/
char *llsave[1]; /* Look ahead buffer */

View file

@ -0,0 +1,29 @@
/*
* Bob Denny 28-Aug-82 Remove reference to stdio.h
* Scott Guthery 20-Nov-83 Adapt for IBM PC & DeSmet C
*/
#include <lex.h>
_lmovb(lp, c, st)
register int c, st;
register struct lextab *lp;
{
int base;
while ((base = lp->llbase[st]+c) > lp->llnxtmax ||
(lp->llcheck[base] & 0377) != st) {
if (st != lp->llendst) {
/*
* This miscompiled on Decus C many years ago:
* st = lp->lldefault[st] & 0377;
*/
base = lp->lldefault[st] & 0377;
st = base;
}
else
return(-1);
}
return(lp->llnext[base]&0377);
}

View file

@ -0,0 +1,54 @@
%{
#define YYSTYPE double
#include "cal_tab.h"
int c;
extern YYSTYPE yylval;
double translate(int type);
void count(void);
void setLastVar(void);
int lookup(int *typeOfObject);
struct lextab *lexswitch(struct lextab *lp);
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
%}
digit = [0-9];
letter = [a-zA-Z_];
hex = [a-fA-F0-9];
/* -- */
space = [\40];
/*number = (digit* | "-" digit*);*/
number = digit*;
exp = [Ee] number;
doubl = number "." (digit* | digit* exp);
%%
hex hex* [hH] { count(); yylval = translate(HEXCONST); return VALUE; }
digit* { count(); yylval = translate(INTCONST); return VALUE; }
digit digit* [Dd] { count(); yylval = translate(INTCONST); return VALUE; }
doubl { count(); yylval = translate(DBLCONST); return VALUE; }
letter* { count(); { int typeOfObject; setLastVar(); yylval = lookup(&typeOfObject); return typeOfObject; }}
letter (letter|digit)* { count(); { int typeOfObject; setLastVar(); yylval = lookup(&typeOfObject); return typeOfObject; }}
'+' { count(); return '+'; }
'-' { count(); return '-'; }
'*' { count(); return '*'; }
'/' { count(); return '/'; }
'%' { count(); return '%'; }
'&' { count(); return '&'; }
'|' { count(); return '|'; }
'(' { count(); return '('; }
')' { count(); return ')'; }
'=' { count(); return '='; }
',' { count(); return ','; }
';' { count(); return ';'; }
[ \t\v\f] { count(); }
. { count(); }
%%

View file

@ -0,0 +1,143 @@
#include <lex.h>
#define ERROR 256 /* yacc's value */
static int llset(void);
static int llinp(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)) );
}
static char *llsave[16]; /* Look ahead buffer */
static char llbuf[100]; /* work buffer */
static char *llp1 = &llbuf[0]; /* pointer to next avail. in token */
static char *llp2 = &llbuf[0]; /* pointer to end of lookahead */
static char *llend = &llbuf[0]; /* pointer to end of token */
static char *llebuf = &llbuf[sizeof llbuf];
static int lleof;
static int yyline = 0;
extern struct lextab lextab;
int gettoken(char *lltb, int lltbsiz)
{
register char *lp, *tp, *ep;
tp = lltb;
ep = tp+lltbsiz-1;
for (lp = llbuf; lp < llend && tp < ep;)
*tp++ = *lp++;
*tp = 0;
return(tp-lltb);
}
int yylex(char **exp)
{
register int c, st;
int final, l, llk, i;
register struct lextab *lp;
char *cp;
while (1)
{
llk = 0;
if (llset()) return(0);
st = 0;
final = -1;
lp = &lextab;
do {
if (lp->lllook && (l = lp->lllook[st])) {
for (c=0; c<NBPW; c++)
if (l&(1<<c))
llsave[c] = llp1;
llk++;
}
if ((i = lp->llfinal[st]) != -1) {
final = i;
llend = llp1;
}
if ((c = llinp(exp)) < 0)
break;
if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
llp1--;
break;
}
} while ((st = (*lp->llmove)(lp, c, st)) != -1);
if (llp2 < llp1)
llp2 = llp1;
if (final == -1) {
llend = llp1;
if (st == 0 && c < 0)
return(0);
if ((cp = lp->llill) && tst__b(c, cp)) {
continue;
}
return(ERROR);
}
if (c = (final >> 11) & 037)
llend = llsave[c-1];
if ((c = (*lp->llactr)(final&03777)) >= 0)
return(c);
}
}
void llinit(viud)
{
llp1 = llp2 = llend = llbuf;
llebuf = llbuf + sizeof(llbuf);
lleof = yyline = 0;
}
static int llinp(char **exp)
{
register c;
register struct lextab *lp;
register char *cp;
lp = &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 = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc(exp);
if (c >= 0) { /* Got a character? */
if (cp && tst__b(c, cp))
continue; /* Ignore it */
if (llp1 >= llebuf) { /* No, is there room? */
return -1;
}
*llp1++ = c; /* Store in token buff */
} else
lleof = 1; /* Set EOF signal */
return(c);
}
}
static int llset(void)
/*
* Return TRUE if EOF and nothing was moved in the look-ahead buffer
*/
{
register char *lp1, *lp2;
for (lp1 = llbuf, lp2 = llend; lp2 < llp2;)
*lp1++ = *lp2++;
llend = llp1 = llbuf;
llp2 = lp1;
return(lleof && lp1 == llbuf);
}

View file

@ -0,0 +1,334 @@
extern int timeclock;
int yyerror; /* Yyerror and yycost are set by guards. */
int yycost; /* If yyerror is set to a nonzero value by a */
/* guard, the reduction with which the guard */
/* is associated is not performed, and the */
/* error recovery mechanism is invoked. */
/* Yycost indicates the cost of performing */
/* the reduction given the attributes of the */
/* symbols. */
/* YYMAXDEPTH indicates the size of the parser's state and value */
/* stacks. */
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 500
#endif
/* YYMAXRULES must be at least as large as the number of rules that */
/* could be placed in the rule queue. That number could be determined */
/* from the grammar and the size of the stack, but, as yet, it is not. */
#ifndef YYMAXRULES
#define YYMAXRULES 100
#endif
#ifndef YYMAXBACKUP
#define YYMAXBACKUP 100
#endif
short yyss[YYMAXDEPTH]; /* the state stack */
YYSTYPE yyvs[YYMAXDEPTH]; /* the semantic value stack */
YYLTYPE yyls[YYMAXDEPTH]; /* the location stack */
short yyrq[YYMAXRULES]; /* the rule queue */
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
YYSTYPE yytval; /* the semantic value for the state */
/* at the top of the state stack. */
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
YYLTYPE yytloc; /* location data for the state at the */
/* top of the state stack */
int yynunlexed;
short yyunchar[YYMAXBACKUP];
YYSTYPE yyunval[YYMAXBACKUP];
YYLTYPE yyunloc[YYMAXBACKUP];
short *yygssp; /* a pointer to the top of the state */
/* stack; only set during error */
/* recovery. */
YYSTYPE *yygvsp; /* a pointer to the top of the value */
/* stack; only set during error */
/* recovery. */
YYLTYPE *yyglsp; /* a pointer to the top of the */
/* location stack; only set during */
/* error recovery. */
/* Yyget is an interface between the parser and the lexical analyzer. */
/* It is costly to provide such an interface, but it avoids requiring */
/* the lexical analyzer to be able to back up the scan. */
yyget()
{
if (yynunlexed > 0)
{
yynunlexed--;
yychar = yyunchar[yynunlexed];
yylval = yyunval[yynunlexed];
yylloc = yyunloc[yynunlexed];
}
else if (yychar <= 0)
yychar = 0;
else
{
yychar = yylex();
if (yychar < 0)
yychar = 0;
else yychar = YYTRANSLATE(yychar);
}
}
yyunlex(chr, val, loc)
int chr;
YYSTYPE val;
YYLTYPE loc;
{
yyunchar[yynunlexed] = chr;
yyunval[yynunlexed] = val;
yyunloc[yynunlexed] = loc;
yynunlexed++;
}
yyrestore(first, last)
register short *first;
register short *last;
{
register short *ssp;
register short *rp;
register int symbol;
register int state;
register int tvalsaved;
ssp = yygssp;
yyunlex(yychar, yylval, yylloc);
tvalsaved = 0;
while (first != last)
{
symbol = yystos[*ssp];
if (symbol < YYNTBASE)
{
yyunlex(symbol, yytval, yytloc);
tvalsaved = 1;
ssp--;
}
ssp--;
if (first == yyrq)
first = yyrq + YYMAXRULES;
first--;
for (rp = yyrhs + yyprhs[*first]; symbol = *rp; rp++)
{
if (symbol < YYNTBASE)
state = yytable[yypact[*ssp] + symbol];
else
{
state = yypgoto[symbol - YYNTBASE] + *ssp;
if (state >= 0 && state <= YYLAST && yycheck[state] == *ssp)
state = yytable[state];
else
state = yydefgoto[symbol - YYNTBASE];
}
*++ssp = state;
}
}
if ( ! tvalsaved && ssp > yyss)
{
yyunlex(yystos[*ssp], yytval, yytloc);
ssp--;
}
yygssp = ssp;
}
int
yyparse()
{
register int yystate;
register int yyn;
register short *yyssp;
register short *yyrq0;
register short *yyptr;
register YYSTYPE *yyvsp;
int yylen;
YYLTYPE *yylsp;
short *yyrq1;
short *yyrq2;
yystate = 0;
yyssp = yyss - 1;
yyvsp = yyvs - 1;
yylsp = yyls - 1;
yyrq0 = yyrq;
yyrq1 = yyrq0;
yyrq2 = yyrq0;
yychar = yylex();
if (yychar < 0)
yychar = 0;
else yychar = YYTRANSLATE(yychar);
yynewstate:
if (yyssp >= yyss + YYMAXDEPTH - 1)
{
yyabort("Parser Stack Overflow");
YYABORT;
}
*++yyssp = yystate;
yyresume:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
yyn += yychar;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar)
goto yydefault;
yyn = yytable[yyn];
if (yyn < 0)
{
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
yystate = yyn;
yyptr = yyrq2;
while (yyptr != yyrq1)
{
yyn = *yyptr++;
yylen = yyr2[yyn];
yyvsp -= yylen;
yylsp -= yylen;
yyguard(yyn, yyvsp, yylsp);
if (yyerror)
goto yysemerr;
yyaction(yyn, yyvsp, yylsp);
*++yyvsp = yyval;
yylsp++;
if (yylen == 0)
{
yylsp->timestamp = timeclock;
yylsp->first_line = yytloc.first_line;
yylsp->first_column = yytloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
if (yyptr == yyrq + YYMAXRULES)
yyptr = yyrq;
}
if (yystate == YYFINAL)
YYACCEPT;
yyrq2 = yyptr;
yyrq1 = yyrq0;
*++yyvsp = yytval;
*++yylsp = yytloc;
yytval = yylval;
yytloc = yylloc;
yyget();
goto yynewstate;
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
yyreduce:
*yyrq0++ = yyn;
if (yyrq0 == yyrq + YYMAXRULES)
yyrq0 = yyrq;
if (yyrq0 == yyrq2)
{
yyabort("Parser Rule Queue Overflow");
YYABORT;
}
yyssp -= yyr2[yyn];
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;
yysemerr:
*--yyptr = yyn;
yyrq2 = yyptr;
yyvsp += yyr2[yyn];
yyerrlab:
yygssp = yyssp;
yygvsp = yyvsp;
yyglsp = yylsp;
yyrestore(yyrq0, yyrq2);
yyrecover();
yystate = *yygssp;
yyssp = yygssp;
yyvsp = yygvsp;
yyrq0 = yyrq;
yyrq1 = yyrq0;
yyrq2 = yyrq0;
goto yyresume;
}
$

View file

@ -0,0 +1,577 @@
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
//#ln 3 "bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* Not GNU C. */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
#include <alloca.h>
#endif /* Sparc. */
#endif /* Not GNU C. */
/* This is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
used when %semantic_parser is specified. */
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
as one case of the switch. */
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror.
This remains here temporarily to ease the
transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(token, value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ yychar = (token), yylval = (value); \
yychar1 = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ yyerror ("Syntax error, cannot back up!"); YYERROR; } \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYIMPURE
#define YYLEX yylex()
#endif
#ifndef YYPURE
#define YYLEX yylex(&yylval)//, &yylloc) MY MODIF!
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYIMPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
#ifdef YYLSP_NEEDED
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
#endif
int yynerrs; /* number of parse errors so far */
#endif /* YYIMPURE */
#if YYDEBUG != 0
int yydebug; /* nonzero means print parse trace */
/* Since this is uninitialized, it does not stop multiple parsers
from coexisting. */
#endif
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#ifndef YYINITDEPTH
#define YYINITDEPTH 200
#endif
/* YYMAXDEPTH is the maximum size the stacks can grow to
(effective only if the built-in stack extension method is used). */
#if YYMAXDEPTH == 0
#undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__yy_bcopy (from, to, count)
char *from;
char *to;
int count;
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
//#ln 131 "bison.simple"
int
yyparse()
{
register int yystate;
register int yyn;
register short *yyssp;
register 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 */
#ifdef YYLSP_NEEDED
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
#define YYPOPSTACK (yyvsp--, yysp--, yylsp--)
#else
#define YYPOPSTACK (yyvsp--, yysp--)
#endif
int yystacksize = YYINITDEPTH;
#ifndef YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#ifdef YYLSP_NEEDED
YYLTYPE yylloc;
#endif
#endif
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Starting parse\n");
#endif
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
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;
#ifdef YYLSP_NEEDED
yylsp = yyls;
#endif
/* 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;
#ifdef YYLSP_NEEDED
YYLTYPE *yyls1 = yyls;
#endif
/* Get the current used size of the three stacks, in elements. */
int size = yyssp - yyss + 1;
#ifdef yyoverflow
/* Each stack pointer address is followed by the size of
the data in use in that stack, in bytes. */
yyoverflow("internal error: parser stack overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
#ifdef YYLSP_NEEDED
&yyls1, size * sizeof (*yylsp),
#endif
&yystacksize);
yyss = yyss1; yyvs = yyvs1;
#ifdef YYLSP_NEEDED
yyls = yyls1;
#endif
#else /* no yyoverflow */
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
{
yyerror("internal error: parser stack overflow");
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
__yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
__yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
__yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
#ifdef YYLSP_NEEDED
yylsp = yyls + size - 1;
#endif
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "stack size increased to %d\n", yystacksize);
#endif
if (yyssp >= yyss + yystacksize - 1)
YYABORT;
}
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "entering state %d\n", yystate);
#endif
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 (yychar == YYEMPTY)
{
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "reading a token: ");
#endif
yyStackSize = yyssp - (yyss - 1);
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "now at end of input.\n");
#endif
}
else
{
yychar1 = YYTRANSLATE(yychar);
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "next token is %d (%s)\n", yychar, yytname[yychar1]);
#endif
}
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. */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "shifting token %d (%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
/* 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 */
#if YYDEBUG != 0
if (yydebug)
{
if (yylen == 1)
fprintf (stderr, "reducing 1 value via rule %d (line %d), ",
yyn, yyrline[yyn]);
else
fprintf (stderr, "reducing %d values via rule %d (line %d), ",
yylen, yyn, yyrline[yyn]);
}
#endif
$ /* the action file gets copied in in place of this dollarsign */
//#ln 362 "bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
#ifdef YYLSP_NEEDED
yylsp -= yylen;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
*++yyvsp = yyval;
#ifdef YYLSP_NEEDED
yylsp++;
if (yylen == 0)
{
yylsp->first_line = yylloc.first_line;
yylsp->first_column = yylloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
#endif
/* 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. */
{
++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++;
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 (yychar == YYEOF)
YYABORT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "discarding token %d (%s).\n", yychar, yytname[yychar1]);
#endif
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;
#ifdef YYLSP_NEEDED
yylsp--;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "error: state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
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;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "shifting error token, ");
#endif
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
}

View file

@ -0,0 +1,155 @@
%{
#define YYSTYPE double
#include <malloc.h>
#include <memory.h>
#include "Compiler.h"
#include "eval.h"
yyerror(char *);
yylex();
extern int yyStackSize;
extern double result;
int regs[26];
int base;
%}
%token VALUE IDENTIFIER FUNCTION1 FUNCTION2 FUNCTION3
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */
%left UPLUS /*supplies precedence for unary plus */
%% /*beginning of rules section */
stat : math_expr
{ $$ = $1; result = $1; }
| IDENTIFIER '=' math_expr
{ if (parseType == PARSE_EVAL)
{
setVar((int)$1, $3);
$$ = $3;
result = $3;
}
else
{
double i = setVar((int)$1, 0);
double v = createCompiledValue(0, &(varTable[(int)i].value));
$$ = createCompiledFunction2(MATH_SIMPLE, FN_ASSIGN, v, $3);
result = $$;
}
}
;
value : VALUE { $$ = $1 }
primary_expr
: IDENTIFIER
{ $$ = getVar((int)$1);}
| value
{ $$ = $1;}
| '(' math_expr ')'
{ $$ = $2;}
;
math_expr
: primary_expr
{ $$ = $1; }
| math_expr '*' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 * $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_MULTIPLY, $1, $3);
}
| math_expr '/' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 / $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_DIVIDE, $1, $3);
}
| math_expr '%' math_expr
{ if (parseType == PARSE_EVAL)
$$ = (double)((int)$1 % (int)$3);
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_MODULO, $1, $3);
}
| math_expr '+' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 + $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_ADD, $1, $3);
}
| math_expr '-' math_expr
{ if (parseType == PARSE_EVAL)
$$ = $1 - $3;
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_SUB, $1, $3);
}
| math_expr '&' math_expr
{ if (parseType == PARSE_EVAL)
$$ = (double)((int)$1 & (int)$3);
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_AND, $1, $3);
}
| math_expr '|' math_expr
{ if (parseType == PARSE_EVAL)
$$ = (double)((int)$1 | (int)$3);
else
$$ = createCompiledFunction2(MATH_SIMPLE, FN_OR, $1, $3);
}
| '-' math_expr %prec UMINUS
{ if (parseType == PARSE_EVAL)
$$ = -$2;
else
$$ = createCompiledFunction1(MATH_SIMPLE, FN_UMINUS, $2);
}
| '+' math_expr %prec UPLUS
{ if (parseType == PARSE_EVAL)
$$ = +$2;
else
$$ = createCompiledFunction1(MATH_SIMPLE, FN_UPLUS, $2);
}
| fonction
{ $$ = $1; }
;
fonction
: FUNCTION1 '(' math_expr ')'
{ if (parseType == PARSE_EVAL)
$$ = calcFunction1((int)$1, $3);
else
$$ = createCompiledFunction1(MATH_FN, (int)$1, $3);
}
| FUNCTION2 '(' math_expr ',' math_expr ')'
{ if (parseType == PARSE_EVAL)
$$ = calcFunction2((int)$1, $3, $5);
else
$$ = createCompiledFunction2(MATH_FN, (int)$1, $3, $5);
}
| FUNCTION3 '(' math_expr ',' math_expr ',' math_expr ')'
{ if (parseType == PARSE_EVAL)
$$ = calcFunction3((int)$1, $3, $5, $7);
else
$$ = createCompiledFunction3(MATH_FN, (int)$1, $3, $5, $7);
}
;
%%
main()
{
return(yyparse());
}
yywrap()
{
return(1);
}

View file

@ -0,0 +1,13 @@
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#define VALUE 258
#define IDENTIFIER 259
#define FUNCTION1 260
#define FUNCTION2 261
#define FUNCTION3 262
#define UMINUS 263
#define UPLUS 264
extern YYSTYPE yylval;

View file

@ -0,0 +1,901 @@
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include "Compiler.h"
#include "eval.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 SHITCALL __fastcall
#define isnonzero(x) (fabs(x) > g_closefact)
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _rand(double *x)
{
if (*x < 1.0) *x=1.0;
return (double)(rand()%(int)max(*x,1.0));
}
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _band(double *var, double *var2)
{
return isnonzero(*var) && isnonzero(*var2) ? 1 : 0;
}
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _bor(double *var, double *var2)
{
return isnonzero(*var) || isnonzero(*var2) ? 1 : 0;
}
//---------------------------------------------------------------------------------------------------------------
static double SHITCALL _sig(double *x, double *constraint)
{
double t = (1+exp(-*x * (*constraint)));
return isnonzero(t) ? 1.0/t : 0;
}
extern char *g_evallib_visdata;
static double SHITCALL getvis(unsigned char *visdata, int bc, int bw, int ch, int xorv)
{
int x;
int accum=0;
if (ch && ch != 1 && ch != 2) return 0.0;
if (bw < 1) bw=1;
bc-=bw/2;
if (bc < 0)
{
bw+=bc;
bc=0;
}
if (bc > 575) bc=575;
if (bc+bw > 576) bw=576-bc;
if (!ch)
{
for (x = 0; x < bw; x ++)
{
accum+=(visdata[bc]^xorv)-xorv;
accum+=(visdata[bc+576]^xorv)-xorv;
bc++;
}
return (double)accum / ((double)bw*255.0);
}
else
{
if (ch == 2) visdata+=576;
for (x = 0; x < bw; x ++) accum+=(visdata[bc++]^xorv)-xorv;
return (double)accum / ((double)bw*127.5);
}
}
static double SHITCALL getspec_(double *band, double *bandw, double *chan)
{
if (!g_evallib_visdata) return 0.0;
return getvis((unsigned char *)g_evallib_visdata,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),0)*0.5;
}
static double SHITCALL getosc_(double *band, double *bandw, double *chan)
{
if (!g_evallib_visdata) return 0.0;
return getvis((unsigned char *)g_evallib_visdata+576*2,(int)(*band*576.0),(int)(*bandw*576.0),(int)(*chan+0.5),128);
}
static double SHITCALL gettime_(double *sc)
{
int ispos;
if ((ispos=(*sc > -1.001 && *sc < -0.999)) || (*sc > -2.001 && *sc < -1.999))
{
int pos=0;
extern HWND hwnd_WinampParent;
if (IsWindow(hwnd_WinampParent))
{
if (!SendMessageTimeout( hwnd_WinampParent, WM_USER,(WPARAM)!ispos,(LPARAM)105,SMTO_BLOCK,50,(LPDWORD)&pos)) pos=0;
}
if (!ispos) return (double)pos;
return pos / 1000.0;
}
return GetTickCount()/1000.0 - *sc;
}
static double SHITCALL setmousepos_(double *x, double *y)
{
//fucko: implement me
return 0.0;
}
static double SHITCALL getmouse_(double *which)
{
int w=(int)(*which+0.5);
if (w > 5)
return (GetAsyncKeyState(w)&0x8000)?1.0:0.0;
if (w == 1 || w == 2)
{
double DDraw_translatePoint(POINT p, int isY);
POINT p;
GetCursorPos(&p);
return DDraw_translatePoint(p,w==2);
}
if (w == 3) return (GetAsyncKeyState(MK_LBUTTON)&0x8000)?1.0:0.0;
if (w == 4) return (GetAsyncKeyState(MK_RBUTTON)&0x8000)?1.0:0.0;
if (w == 5) return (GetAsyncKeyState(MK_MBUTTON)&0x8000)?1.0:0.0;
return 0.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
#if 0 // dont seem to need to do this
#define CF_PUSHREGS __asm { push esi } __asm { push edi }
#define CF_POPREGS __asm { pop edi } __asm { pop esi }
#else
#define CF_PUSHREGS
#define CF_POPREGS
#endif
#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 } \
CF_PUSHREGS
#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 } \
CF_PUSHREGS
#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 } \
CF_PUSHREGS
#define FUNC_LEAVE \
__asm { mov eax, esi } \
__asm { add esi, 8 } \
__asm { mov esp, ebp } \
CF_POPREGS
static double (*__asin)(double) = &asin;
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_asin(void)
{
FUNC1_ENTER
*__nextBlock = __asin(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_asin_end(void) {}
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) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__atan)(double) = &atan;
__declspec ( naked ) void _asm_atan(void)
{
FUNC1_ENTER
*__nextBlock = __atan(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_atan_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__atan2)(double,double) = &atan2;
__declspec ( naked ) void _asm_atan2(void)
{
FUNC2_ENTER
*__nextBlock = __atan2(*parm_b, *parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_atan2_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL * __sig)(double *,double *) = &_sig;
__declspec ( naked ) void _asm_sig(void)
{
FUNC2_ENTER
*__nextBlock = __sig(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_sig_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL *__rand)(double *) = &_rand;
__declspec ( naked ) void _asm_rand(void)
{
FUNC1_ENTER
*__nextBlock = __rand(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_rand_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL *__band)(double *,double *) = &_band;
__declspec ( naked ) void _asm_band(void)
{
FUNC2_ENTER
*__nextBlock = __band(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_band_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double ( SHITCALL *__bor)(double *,double *) = &_bor;
__declspec ( naked ) void _asm_bor(void)
{
FUNC2_ENTER
*__nextBlock = __bor(parm_b, parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_bor_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (* __pow)(double,double) = &pow;
__declspec ( naked ) void _asm_pow(void)
{
FUNC2_ENTER
*__nextBlock = __pow(*parm_b, *parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_pow_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__exp)(double) = &exp;
__declspec ( naked ) void _asm_exp(void)
{
FUNC1_ENTER
*__nextBlock = __exp(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_exp_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__floor)(double) = &floor;
__declspec ( naked ) void _asm_floor(void)
{
FUNC1_ENTER
*__nextBlock = __floor(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_floor_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (*__ceil)(double) = &ceil;
__declspec ( naked ) void _asm_ceil(void)
{
FUNC1_ENTER
*__nextBlock = __ceil(*parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_ceil_end(void) {}
//---------------------------------------------------------------------------------------------------------------
static double (SHITCALL *__getosc)(double *,double *,double *) = &getosc_;
__declspec ( naked ) void _asm_getosc(void)
{
FUNC3_ENTER
*__nextBlock = __getosc(parm_c,parm_b,parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_getosc_end(void) {}
static double (SHITCALL *__getspec)(double *,double *,double *) = &getspec_;
__declspec ( naked ) void _asm_getspec(void)
{
FUNC3_ENTER
*__nextBlock = __getspec(parm_c,parm_b,parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_getspec_end(void) {}
static double (SHITCALL *__gettime)(double *) = &gettime_;
__declspec ( naked ) void _asm_gettime(void)
{
FUNC1_ENTER
*__nextBlock = __gettime(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_gettime_end(void) {}
// do nothing, eh
__declspec ( naked ) void _asm_exec2(void)
{
}
__declspec ( naked ) void _asm_exec2_end(void) { }
static double (SHITCALL *__getmouse)(double *) = &getmouse_;
__declspec ( naked ) void _asm_getmouse(void)
{
FUNC1_ENTER
*__nextBlock = __getmouse(parm_a);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_getmouse_end(void) {}
static double (SHITCALL *__setmousepos)(double *,double *) = &setmousepos_;
__declspec ( naked ) void _asm_setmousepos(void)
{
FUNC2_ENTER
*__nextBlock = __setmousepos(parm_a,parm_b);
FUNC_LEAVE
}
__declspec ( naked ) void _asm_setmousepos_end(void) {}
__declspec ( naked ) void _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 _asm_invsqrt_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sin(void)
{
__asm
{
fld qword ptr [eax]
fsin
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_sin_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_cos(void)
{
__asm
{
fld qword ptr [eax]
fcos
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_cos_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_tan(void)
{
__asm
{
fld qword ptr [eax]
fsincos
fdiv
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_tan_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_sqr_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sqrt(void)
{
__asm
{
fld qword ptr [eax]
fabs
fsqrt
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_sqrt_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_log_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_log10_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_abs(void)
{
__asm
{
fld qword ptr [eax]
fabs
mov eax, esi
fstp qword ptr [esi]
add esi, 8
}
}
__declspec ( naked ) void _asm_abs_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_assign(void)
{
__asm
{
fld qword ptr [eax]
fstp qword ptr [ebx]
}
}
__declspec ( naked ) void _asm_assign_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_add_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_sub_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_mul_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_div_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_mod_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_or_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_and_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_uplus_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_uminus_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _asm_sign(void)
{
__asm
{
mov ecx, [eax+4]
shr ecx, 31
fld dword ptr [g_signs+ecx*4]
fstp qword ptr [esi]
mov eax, esi
add esi, 8
}
}
__declspec ( naked ) void _asm_sign_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_bnot_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_if_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_equal_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_below_end(void) {}
//---------------------------------------------------------------------------------------------------------------
__declspec ( naked ) void _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 _asm_above_end(void) {}
__declspec ( naked ) void _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 _asm_min_end(void) {}
__declspec ( naked ) void _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 _asm_max_end(void) {}

View file

@ -0,0 +1,238 @@
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include "cal_tab.h"
#include "compiler.h"
#include "eval.h"
#define INTCONST 1
#define DBLCONST 2
#define HEXCONST 3
#define VARIABLE 4
#define OTHER 5
int yyparse(char *exp);
void llinit(void);
int gettoken(char *lltb, int lltbsiz);
char yytext[256]="";
char lastVar[256]="";
int *errPtr;
int result;
int colCount=0;
varType *varTable;
char last_error_string[1024];
double globalregs[100];
//------------------------------------------------------------------------------
void *compileExpression(char *exp)
{
int errv=0;
errPtr=&errv;
llinit();
if (!yyparse(exp) && !*errPtr)
{
return (void*)result;
}
return 0;
}
//------------------------------------------------------------------------------
void setLastVar(void)
{
gettoken(lastVar, sizeof lastVar);
}
//------------------------------------------------------------------------------
int setVar(int varNum, double value)
{
int i=varNum;
if (varNum < 0)
{
char *var=lastVar;
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;
i=EVAL_MAX_VARS+x;
}
else
{
for (i=0;i<EVAL_MAX_VARS;i++)
{
if (!varTable[i].name[0] || !_strnicmp(varTable[i].name,lastVar,sizeof(varTable[i].name)))
break;
}
if (i==EVAL_MAX_VARS) return -1;
}
}
if (i < 0 || i >= EVAL_MAX_VARS+100)
{
return -1;
}
if (i >= EVAL_MAX_VARS && i < EVAL_MAX_VARS+100)
{
globalregs[i - EVAL_MAX_VARS]=value;
}
else if (!varTable[i].name[0])
{
strncpy(varTable[i].name,lastVar,sizeof(varTable[i].name));
varTable[i].value = value;
}
return i;
}
//------------------------------------------------------------------------------
int getVar(int varNum)
{
if (varNum >= EVAL_MAX_VARS && varNum < EVAL_MAX_VARS+100)
return createCompiledValue(0, globalregs + (varNum - EVAL_MAX_VARS));
if (varNum >= 0 && varNum < EVAL_MAX_VARS)
return createCompiledValue(0, &(varTable[varNum].value));
return createCompiledValue(0, NULL);
}
#if 0
//------------------------------------------------------------------------------
double *getVarPtr(char *var)
{
int i;
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 globalregs + x;
}
for (i=0;i<EVAL_MAX_VARS;i++)
if (!_strnicmp(varTable[i].name, yytext,sizeof(varTable[i].name)))
return &(varTable[i].value);
return NULL;
}
#endif
//------------------------------------------------------------------------------
double *registerVar(char *var)
{
int i;
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 globalregs + x;
}
for (i=0;i<EVAL_MAX_VARS;i++)
if (!varTable[i].name[0] ||
!_strnicmp(varTable[i].name,var,sizeof(varTable[i].name)))
break;
if (i==EVAL_MAX_VARS) return NULL;
if (!varTable[i].name[0])
{
strncpy(varTable[i].name,var,sizeof(varTable[i].name));
varTable[i].value = 0.0;
}
return &(varTable[i].value);
}
//------------------------------------------------------------------------------
int translate(int type)
{
int v;
int n;
*yytext = 0;
gettoken(yytext, sizeof yytext);
switch (type)
{
case INTCONST: return createCompiledValue((double)atoi(yytext), NULL);
case DBLCONST: return createCompiledValue((double)atof(yytext), NULL);
case HEXCONST:
v=0;
n=0;
while (1)
{
int a=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 createCompiledValue((double)v, NULL);
}
return 0;
}
//------------------------------------------------------------------------------
int objectId(int nParams)
{
switch (nParams)
{
case 1: return FUNCTION1;
case 2: return FUNCTION2;
case 3: return FUNCTION3;
}
return IDENTIFIER;
}
//------------------------------------------------------------------------------
int lookup(int *typeOfObject)
{
int i;
gettoken(yytext, sizeof yytext);
if (!_strnicmp(yytext,"reg",3) && strlen(yytext) == 5 && isdigit(yytext[3]) && isdigit(yytext[4]) && (i=atoi(yytext+3))>=0 && i<100)
{
*typeOfObject=IDENTIFIER;
return i+EVAL_MAX_VARS;
}
for (i=0;i<EVAL_MAX_VARS;i++)
if (!_strnicmp(varTable[i].name, yytext,sizeof(varTable[i].name)))
{
*typeOfObject = IDENTIFIER;
return i;
}
for (i=0;getFunctionFromTable(i);i++)
{
functionType *f=getFunctionFromTable(i);
if (!strcmpi(f->name, yytext))
{
*typeOfObject = objectId(f->nParams);
return i;
}
}
*typeOfObject = IDENTIFIER;
setLastVar();
i = setVar(-1, 0);
return i;
}
//---------------------------------------------------------------------------
void count(void)
{
gettoken(yytext, sizeof yytext);
colCount+=strlen(yytext);
}
//---------------------------------------------------------------------------
int yyerror(char *txt)
{
*errPtr = colCount;
return 0;
}

View file

@ -0,0 +1,41 @@
#ifndef __EVAL_H
#define __EVAL_H
#ifdef __cplusplus
extern "C" {
#endif
// stuff that apps will want to use
#define EVAL_MAX_VARS 256
typedef struct
{
char name[8];
double value;
} varType;
extern double globalregs[100];
extern char last_error_string[1024];
void resetVars(varType *vars);
double *getVarPtr(char *varName);
double *registerVar(char *varName);
// other shat
extern varType *varTable;
extern int *errPtr;
extern int colCount;
extern int result;
int setVar(int varNum, double value);
int getVar(int varNum);
void *compileExpression(char *txt);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1 @@
lex -i scan.l

View file

@ -0,0 +1,2 @@
bison -d cal.y

View file

@ -0,0 +1,84 @@
Expression evaluation library v1.0 - by lone
--------------------------------------------
How to use
~~~~~~~~~~
¦ resetVars
-----------
void resetVars(void);
Resets the variables table. It is necessary to call it prior to evaluate your first
expression or variables contents may be random instead of zero
¦ evaluate
----------
double evaluate(char *expression, int *col);
Evaluates an expression and returns the result.
If a syntax error was encountered during the parsing of the expression, then col will
be non-null and col-1 will be the index of the char which triggered the error.
Limitations
~~~~~~~~~~~
¦ you can set only up to 1024 variables.
¦ only decimal and hexadecimal bases available
¦ operators are limited to :
+ - / * % & |
¦ functions are limited to :
sin, cos, tan,
asin, acos, atan,
atan2, sqr, sqrt,
pow, exp, log, log10
Some examples
~~~~~~~~~~~~~
- assignments :
pi=3.1415927
a=atan2(cos(pi/4),2)
- direct evaluations :
cos(pi/4)
sin(45)
- base notations :
3bh (this is 0x3B)
17d (this is 17)
17dh (this is 0x17D)
Adding new functions
~~~~~~~~~~~~~~~~~~~~
The file EVAL.C contains the functions table (fnTable). Just add an entry with the name,
the number of parameters, and a pointer to the function body. Implement the body and
you're done. If your function ahs more than 2 parameters, you'll need to extend the grammar
description file (CAL.Y) to add the FUNCTION3 (and eventually subsequent) token(s) and
parsing informations.
SCAN.L & CAL.Y
~~~~~~~~~~~~~~
SCAN.L contains description for the lexical analyzer generator (LEX). Use makel.bat to rebuild
LEXTAB.C
CAL.Y contains the LALR formal grammar description for the parser generator (BISON). Use makey.bat
to rebuild CAL_TAB.C
Compiling
~~~~~~~~~
Just include all source files to your project, and include EVAL.H into your main source code.