📄 parser.c
字号:
ExpectingArg = 1;
}
break;
case '&':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
if(Str[n+1] == '&') {
n++;
o[posp].f = StkAND;
o[posp++].p = 7 - (paren + Equals)*15;
}
else
SyntaxErr = 4;
break;
case '!':
if(Str[n+1] == '=') {
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
n++;
o[posp].f = StkNE;
o[posp++].p = 6 - (paren + Equals)*15;
}
else
SyntaxErr = 4;
break;
case '<':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
if(Str[n+1] == '=') {
n++;
o[posp].f = StkLTE;
}
else
o[posp].f = StkLT;
o[posp++].p = 6 - (paren + Equals)*15;
break;
case '>':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
if(Str[n+1] == '=') {
n++;
o[posp].f = StkGTE;
}
else
o[posp].f = StkGT;
o[posp++].p = 6 - (paren + Equals)*15;
break;
case '*':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
o[posp].f = StkMul;
o[posp++].p = 3 - (paren + Equals)*15;
break;
case '/':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
o[posp].f = StkDiv;
o[posp++].p = 3 - (paren + Equals)*15;
break;
case '^':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
o[posp].f = StkPwr;
o[posp++].p = 2 - (paren + Equals)*15;
break;
case '=':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
if(Str[n+1] == '=') {
n++;
o[posp].f = StkEQ;
o[posp++].p = 6 - (paren + Equals)*15;
}
else
{
o[posp-1].f = StkSto;
o[posp-1].p = 5 - (paren + Equals)*15;
Store[StoPtr++] = Load[--LodPtr];
Equals++;
}
break;
default:
if(isalnum(Str[n]) || Str[n] == '.') {
while(isalnum(Str[n+1]) || Str[n+1] == '.')
n++;
if(!ExpectingArg) {
SyntaxErr = 1;
}
NewStatement = ExpectingArg = 0;
Len = (n+1)-InitN;
o[posp].f = isfunct(&Str[InitN], Len);
if(o[posp].f != NotAFnct) {
if(o[posp].f == FnctNotFound) {
e[ErrPtr].n = InitN;
e[ErrPtr++].s = 5;
}
else
o[posp++].p = 1 - (paren + Equals)*15;
ExpectingArg = 1;
}
else {
c = isconst(&Str[InitN], Len);
Load[LodPtr++] = &(c->a);
o[posp].f = StkLod;
o[posp++].p = 1 - (paren + Equals)*15;
n = InitN + c->len - 1;
if(vsp >= MAX_ARGS-1) { /* PB 910417 safety test */
e[ErrPtr].n = InitN;
e[ErrPtr++].s = 7;
break;
}
}
}
else {
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
e[ErrPtr].n = InitN;
e[ErrPtr++].s = 4;
}
break;
}
if(SyntaxErr >= 0) {
e[ErrPtr].n = InitN;
e[ErrPtr++].s = SyntaxErr;
SyntaxErr = -1;
}
if(posp >= MAX_OPS-1) { /* PB 901103 added safety test here */
e[ErrPtr].n = InitN;
e[ErrPtr++].s = 7;
break;
}
if(ErrPtr > 50) /* PB 910417 safety test */
break;
}
o[posp].f = (void(far*)(void))0;
o[posp++].p = 16;
if(paren > 0) {
e[ErrPtr].n = n;
e[ErrPtr++].s = 3;
}
if (ErrPtr) {
int i, j, k, m;
char msgbuf[700]; /* PB replaced printf loop by build msgbuf & stopmsg */
/* stopmsg defined to have max 9 lines, show at most first 3 errors */
msgbuf[0] = 0;
for(n = 0; n < ErrPtr && n < 3; n++) {
if (n)
strcat(msgbuf,"\n");
#ifndef XFRACT
sprintf(&msgbuf[strlen(msgbuf)], "Error(%d): %Fs\n ", e[n].s, /*TIW 03-31-91 added %Fs*/
ErrStrings[e[n].s]);
#else
sprintf(&msgbuf[strlen(msgbuf)], "Error(%d): %s\n ", e[n].s,
ErrStrings[e[n].s]);
#endif
j = 24;
if ((i = e[n].n - j) < 0) {
j = e[n].n;
i = 0;
}
else {
strcat(msgbuf,"...");
j += 3;
}
k = strlen(msgbuf);
m = i + 66;
while (i < m && Str[i]) {
if ((msgbuf[k] = Str[i]) == '\n' || msgbuf[k] == '\t')
msgbuf[k] = ' ';
++i;
++k;
}
if (Str[i]) {
msgbuf[k++] = '.';
msgbuf[k++] = '.';
msgbuf[k++] = '.';
}
msgbuf[k++] = '\n';
while (--j >= -2)
msgbuf[k++] = ' ';
msgbuf[k++] = '^';
msgbuf[k] = 0;
}
stopmsg(8,msgbuf);
}
if(!ErrPtr) {
NextOp = 0;
LastOp = posp;
while(NextOp < posp) {
if(o[NextOp].f)
RecSortPrec();
else {
NextOp++;
LastOp--;
}
}
}
else
posp = 0;
farmemfree(o);
farmemfree(e);
/* PB 910417 free all arrays if error */
if (ErrPtr)
free_workarea();
return(ErrPtr);
}
int Formula(void) {
if(FormName[0] == 0 || overflow) return(1);
LodPtr = InitLodPtr;
StoPtr = InitStoPtr;
OpPtr = InitOpPtr;
/* Set the random number, MCP 11-21-91 */
if(SetRandom || Randomized)
{
switch(MathType)
{
case D_MATH:
dRandom();
break;
#ifndef XFRACT
case L_MATH:
lRandom();
break;
case M_MATH:
mRandom();
#endif
}
}
Arg1 = &s[0];
Arg2 = Arg1-1;
while(OpPtr < LastOp) {
f[OpPtr++]();
#ifdef WATCH_MP
x1 = *MP2d(Arg1->m.x);
y1 = *MP2d(Arg1->m.y);
x2 = *MP2d(Arg2->m.x);
y2 = *MP2d(Arg2->m.y);
#endif
}
switch(MathType) {
case D_MATH:
old = new = v[3].a.d;
return(Arg1->d.x == 0.0);
#ifndef XFRACT
case M_MATH:
old = new = MPC2cmplx(v[3].a.m);
return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0);
case L_MATH:
lold = lnew = v[3].a.l;
if(overflow)
return(1);
return(Arg1->l.x == 0L);
#endif
}
return(1);
}
int form_per_pixel(void) {
if (FormName[0] == 0) return(1);
overflow = LodPtr = StoPtr = OpPtr = 0;
Arg1 = &s[0];
Arg2 = Arg1;
Arg2--;
if(Transparent3D)
{
TranspPerPixel(MathType, &v[5].a, &v[6].a);
v[0].a = v[5].a;
}
else
{
switch(MathType)
{
case D_MATH:
v[5].a.d.x = (v[0].a.d.x = dx0[col]+dShiftx);
v[5].a.d.x = (v[0].a.d.y = dy0[row]+dShifty);
break;
#ifndef XFRACT
case M_MATH:
v[5].a.m.x = (v[0].a.m.x = *d2MP(dx0[col]+dShiftx));
v[5].a.m.x = (v[0].a.m.y = *d2MP(dy0[row]+dShifty));
break;
case L_MATH:
v[5].a.l.x = (v[0].a.l.x = lx0[col]+lShiftx);
v[5].a.l.x = (v[0].a.l.y = ly0[row]+lShifty);
break;
#endif
}
}
if(LastInitOp)
LastInitOp = LastOp;
while(OpPtr < LastInitOp)
f[OpPtr++]();
InitLodPtr = LodPtr;
InitStoPtr = StoPtr;
InitOpPtr = OpPtr;
if(overflow)
return(0);
else
return(1);
}
char *FormStr;
extern char FormFileName[]; /* BDT file to find the formulas in */
extern char FormName[]; /* BDT Name of the Formula (if not null) */
char *FindFormula(char *Str) {
char *FormulaStr = (char *)0;
char StrBuff[201]; /* PB, to match a safety fix in parser */
/* MCP, changed to an automatic variable */
char fullfilename[100]; /* BDT Full file name */
unsigned Done;
int c;
FILE *File;
findpath(FormFileName, fullfilename); /* BDT get full path name */
symmetry = 0;
if((File = fopen(fullfilename, "rt")) != NULL) { /* BDT use variable files */
while(StrBuff[0]=0,/* TIW 04-22-91 */ fscanf(File, "%200[^ \n\t({]", StrBuff) != EOF) {
if(!stricmp(StrBuff, Str) || !Str[0]) {
while((c = getc(File)) != EOF) {
if(c == '(') {
StrBuff[0]=0; /* TIW 04-22-91 */
fscanf(File, "%200[^)]", StrBuff);
for(n = 0; SymStr[n].s[0]; n++) {
if(!stricmp(SymStr[n].s, StrBuff)) {
symmetry = SymStr[n].n;
break;
}
}
if(!SymStr[n].s[0]) {
sprintf(fullfilename,"Undefined symmetry:\n %.76s",
StrBuff);
stopmsg(0,fullfilename); /* PB printf -> stopmsg */
FormulaStr = (char *)0; /* PB 910511 */
Exit:
fclose(File);
return(FormulaStr);
}
}
else if(c == '{')
break;
}
/* MCP 4-9-91, Strip the comments inside the formula. Might
as well allow unlimited formula lengths while
we're at it.
*/
FormulaStr = boxx;
n = Done = 0;
while(!Done) {
switch(c = getc(File)) {
static char far msg[]={"Unexpected EOF: missing a '}'"};
case EOF:
UnexpectedEOF:
stopmsg(0, msg);
FormulaStr = (char *)0;
goto Exit;
case '}':
FormulaStr[n++] = 0;
Done = 1;
break;
case ';':
while((c = getc(File)) != '\n') {
if(c == EOF)
goto UnexpectedEOF;
}
FormulaStr[n++] = ',';
break;
case ' ': /* Also strip out the
white spaces */
case '\t':
break;
case '\n':
FormulaStr[n++] = ',';
break;
default:
FormulaStr[n++] = c;
}
if (n >= 8192) { /* PB 4-9-91, added safety test */
static char far msg[]={"Definition too large, missing a '}'?"};
stopmsg(0, msg);
FormulaStr = (char *)0;
goto Exit;
}
}
goto Exit;
}
StrBuff[0]=0; /* TIW 04-22-91 */
fscanf(File, "%200[ \n\t({]", StrBuff);
if(StrBuff[strcspn(StrBuff, "({")]) {
skipcomments:
fscanf(File, "%200[^}]", StrBuff);
if (getc(File)!= '}') goto skipcomments;
}
}
sprintf(fullfilename, "Formula \"%s\" not found", Str);
stopmsg(0,fullfilename); /* PB printf -> stopmsg */
FormulaStr = (char *)0; /* PB 910511 */
goto Exit;
}
sprintf(fullfilename, "Unable to open %s", FormFileName);
stopmsg(0,fullfilename); /* PB printf -> stopmsg */
return((char *)0); /* PB 910511 */
}
int BadFormula() {
/* moved from Parsera.Asm by CAE 12 July 1993 */
/* this is called when a formula is bad, instead of calling */
/* the normal functions which will produce undefined results */
return 1;
}
int RunForm(char *Name) { /* returns 1 if an error occurred */
/* CAE changed fn 12 July 1993 to fix problem when formula not found */
/* first set the pointers so they point to a fn which always returns 1 */
curfractalspecific->per_pixel = BadFormula;
curfractalspecific->orbitcalc = BadFormula;
if (FormName[0] == 0 ){
return 1; /* and don't reset the pointers */
}
parser_allocate(); /* ParseStr() will test if this alloc worked */
if((FormStr = FindFormula(Name)) != NULL ){
/* formula was found */
if (ParseStr(FormStr)){
/* parse failed, don't change fn pointers */
return 1;
}
else {
/* parse succeeded so set the pointers back to good functions */
curfractalspecific->per_pixel = form_per_pixel;
curfractalspecific->orbitcalc = Formula;
return 0;
}
}
else {
/* formula not found, leave pointers set to BadFormula */
return 1; /* PB, msg moved to FindFormula */
}
}
int fpFormulaSetup(void) {
#ifndef XFRACT
int RunFormRes; /* CAE fp */
if (fpu > 0) {
MathType = D_MATH;
/* CAE changed below for fp */
RunFormRes = !RunForm(FormName); /* RunForm() returns 1 for failure */
if (RunFormRes && fpu >=387 && debugflag != 90 )
return CvtStk(); /* run fast assembler code in parsera.asm */
return RunFormRes;
}
else {
MathType = M_MATH;
return !RunForm(FormName);
}
#else
MathType = D_MATH;
return(!RunForm(FormName));
#endif
}
int intFormulaSetup(void) {
#ifdef XFRACT
printf("intFormulaSetup called!!!\n");
exit(-1);
#endif
MathType = L_MATH;
fg = (double)(1L << bitshift);
fgLimit = (double)0x7fffffffL / fg;
ShiftBack = 32 - bitshift;
return(!RunForm(FormName));
}
/* TIW added 06-20-90 so functions can be called from fractals.c */
void init_misc()
{
static struct ConstArg far vv[5];
static union Arg argfirst,argsecond;
if(!v) /* PB 901103 added this test to avoid clobbering the real thing */
v = vv; /* this is needed by lStkSqr and dStkSqr */
Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */
fg = (double)(1L << bitshift);
fgLimit = (double)0x7fffffffL / fg;
ShiftBack = 32 - bitshift;
Delta16 = bitshift - 16;
bitshiftless1 = bitshift-1;
}
/* PB 910417 here to end changed.
Allocate sub-arrays from one main farmemalloc, using global variable
typespecific_workarea; calcfrac.c releases this area when calculation
ends or is terminated.
Moved the "f" array to be allocated as part of this.
*/
static void parser_allocate(void)
{
/* CAE fp changed below for v18 */
/* Note that XFRACT will waste about 6k here for pfls */
/* Somewhat more memory is now allocated than in v17 here */
/* however Store and Load were reduced in size to help make up for it */
unsigned int f_size,Store_size,Load_size,v_size, p_size;
free_workarea();
f_size = sizeof(void(far * far *)(void)) * MAX_OPS;
Store_size = sizeof(union Arg far *) * MAX_STORES;
Load_size = sizeof(union Arg far *) * MAX_LOADS;
v_size = sizeof(struct ConstArg) * MAX_ARGS;
p_size = sizeof(struct fls far *) * MAX_OPS;
typespecific_workarea =
farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size));
f = (void(far * far *)(void))typespecific_workarea;
Store = (union Arg far * far *)(f + MAX_OPS);
Load = (union Arg far * far *)(Store + MAX_STORES);
v = (struct ConstArg far *)(Load + MAX_LOADS);
pfls = (struct fls far *)(v + MAX_ARGS);
}
void free_workarea()
{
if(typespecific_workarea) {
farmemfree(typespecific_workarea);
typespecific_workarea = NULL;
}
Store = (union Arg far * far *)0;
Load = (union Arg far * far *)0;
v = (struct ConstArg far *)0;
f = (void(far * far *)(void))0; /* CAE fp */
pfls = (struct fls far * )0; /* CAE fp */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -