📄 parser.c
字号:
o[posp].f = (void(far*)(void))0;
o[posp++].p = 15;
o[posp].f = EndInit;
o[posp++].p = -30000;
Equals = paren = 0;
LastInitOp = 10000;
NewStatement = 1;
break;
case '+':
if(ExpectingArg)
SyntaxErr = 0;
ExpectingArg = 1;
o[posp].f = StkAdd;
o[posp++].p = 4 - (paren + Equals)*15;
break;
case '-':
if(ExpectingArg) {
o[posp].f = StkNeg;
o[posp++].p = 2 - (paren + Equals)*15;
}
else {
o[posp].f = StkSub;
o[posp++].p = 4 - (paren + Equals)*15;
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] == '.' || Str[n] == '_') {
while(isalnum(Str[n+1]) || 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,
ParseErrs(e[n].s));
#else
sprintf(&msgbuf[strlen(msgbuf)], "Error(%d): %s\n ", e[n].s,
ParseErrs(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;
}
if(pass > 0)
stopmsg(8,msgbuf);
}
if(!ErrPtr) {
NextOp = 0;
LastOp = posp;
while(NextOp < posp) {
if(o[NextOp].f)
RecSortPrec();
else {
NextOp++;
LastOp--;
}
}
}
else
posp = 0;
if(pass > 0 && used_extra == 0)
farmemfree(o);
farmemfree(e);
/* PB 910417 free all arrays if error */
if (ErrPtr)
free_workarea();
return(ErrPtr);
}
#if (_MSC_VER >= 700)
#pragma code_seg () /* back to normal segment */
#endif
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 < (int)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--;
v[10].a.d.x = (double)col;
v[10].a.d.y = (double)row;
switch(MathType) {
case D_MATH:
if((row+col)&1)
v[9].a.d.x = 1.0;
else
v[9].a.d.x = 0.0;
v[9].a.d.y = 0.0;
break;
#ifndef XFRACT
case M_MATH:
if((row+col)&1)
v[9].a.m = MPCone;
else {
v[9].a.m.x.Mant = v[9].a.m.x.Exp = 0;
v[9].a.m.y.Mant = v[9].a.m.y.Exp = 0;
}
v[10].a.m = cmplx2MPC(v[10].a.d);
break;
case L_MATH:
v[9].a.l.x = (long) (((row+col)&1) * fg);
v[9].a.l.y = 0L;
v[10].a.l.x = col; v[10].a.l.x <<= bitshift;
v[10].a.l.y = row; v[10].a.l.y <<= bitshift;
break;
#endif
}
/* TW started additions for inversion support here 4/17/94 */
{
if(invert)
{
invertz2(&old);
switch(MathType)
{
case D_MATH:
v[0].a.d.x = old.x;
v[0].a.d.y = old.y;
break;
#ifndef XFRACT
case M_MATH:
v[0].a.m.x = *d2MP(old.x);
v[0].a.m.y = *d2MP(old.y);
break;
case L_MATH:
/* watch out for overflow */
if(sqr(old.x)+sqr(old.y) >= 127)
{
old.x = 8; /* value to bail out in one iteration */
old.y = 8;
}
/* convert to fudged longs */
v[0].a.l.x = (long)(old.x*fg);
v[0].a.l.y = (long)(old.y*fg);
break;
#endif
}
}
else
/* TW end of inversion support changes here 4/17/94 */
switch(MathType)
{
case D_MATH:
v[0].a.d.x = dx0[col]+dShiftx;
v[0].a.d.y = dy0[row]+dShifty;
break;
#ifndef XFRACT
case M_MATH:
v[0].a.m.x = *d2MP(dx0[col]+dShiftx);
v[0].a.m.y = *d2MP(dy0[row]+dShifty);
break;
case L_MATH:
v[0].a.l.x = lx0[col]+lShiftx;
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;
/* Set old variable for orbits TIW 12-18-93 */
switch(MathType) {
case D_MATH:
old = v[3].a.d;
break;
#ifndef XFRACT
case M_MATH:
old = MPC2cmplx(v[3].a.m);
break;
case L_MATH:
lold = v[3].a.l;
break;
#endif
}
if(overflow)
return(0);
else
return(1);
}
char *FormStr;
#if (_MSC_VER >= 700)
#pragma code_seg ("parser1_text") /* place following in an overlay */
#endif
char *PrepareFormula(FILE * File) {
/* GGM 5-23-96: replaces FindFormula(). This function sets the
symmetry and converts a formula into a string with no spaces,
and one comma after each expression except where the ':' is placed
and except the final expression in the formula. The open file passed
as an argument is open in "rb" mode and is positioned at the first
letter of the name of the formula to be prepared. This function
is called from RunForm() below.
*/
FILE *debug_fp = NULL;
char *FormulaStr = NULL;
char *StrBuff = (char *)boxx;
int Done;
int array_pos;
int c;
int message_code = 0;
int not_a_repeat = 1;
int carryover_line;
static char far last_formula_file[FILE_MAX_PATH];
static char far last_formula_name[ITEMNAMELEN+1];
/*Test for a repeat*/
if(strlen(FormName) > ITEMNAMELEN)
FormName[ITEMNAMELEN] = '\0';
if(!far_strnicmp(last_formula_file, FormFileName, FILE_MAX_PATH-1) &&
!far_strnicmp(last_formula_name, FormName, ITEMNAMELEN))
not_a_repeat = 0;
far_strncpy(last_formula_file, FormFileName, FILE_MAX_PATH-1);
far_strncpy(last_formula_name, FormName, ITEMNAMELEN);
Done = symmetry = 0;
StrBuff[0]='\0';
while((c = getc(File)) != '{' && c != '\032' && c != EOF)
{
if(c == '(') /* start of symmetry option */
{
array_pos = 0;
while((c = getc(File)) != ')' && c != '{' && c != '\r' && c != '\n'
&& c != '\032' && c != EOF && array_pos < MAX_BOXX - 1)
StrBuff[array_pos++] = (char)c;
if (c == '{' || c == '\r' || c == '\n' || array_pos >= MAX_BOXX - 1)
{
Done = 1; /* didn't find matching ')' */
message_code = NO_MATCH_RIGHT_PAREN;
break;
}
else if (c == '\032' || c == EOF)
break; /* message_code and Done will be set after end of loop*/
else /* ')' is all that's left*/
{
StrBuff[array_pos] = '\0';
despace(StrBuff); /* squeeze out spaces */
for(array_pos = 0; SymStr[array_pos].s[0]; array_pos++)
{
if(!stricmp(SymStr[array_pos].s, StrBuff))
{
symmetry = SymStr[array_pos].n;
break;
}
}
if(SymStr[array_pos].s[0] == '\0')
message_code = INVALID_SYM_USING_NOSYM;
}
/*symmetry set - go to beginning of formula*/
while( (c = getc(File)) != '{' && c != '\r' && c != '\n'
&& c != '\032' && c != EOF)
;
if (c == '\r' || c == '\n')
{
Done = 1;
message_code = NO_LEFT_BRACKET_FIRST_LINE;
}
break;
}
}
if (c == '\032' || c == EOF)
{
Done = 1;
message_code = UNEXPECTED_EOF;
}
if(not_a_repeat && debugflag == 96 && Done == 0)
{
if((debug_fp = fopen("debugfrm.txt","at")) != NULL)
{
fprintf(debug_fp,"%s\n",FormName);
if(symmetry != 0)
fprintf(debug_fp," %s\n",StrBuff);
else if (message_code == INVALID_SYM_USING_NOSYM)
#ifndef XFRACT
fprintf(debug_fp,"%Fs\n",ParseErrs(message_code));
#else
fprintf(deb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -