• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tueda / form / 15241916852

25 May 2025 08:59PM UTC coverage: 47.908% (-2.8%) from 50.743%
15241916852

push

github

tueda
ci: build arm64-windows binaries

39009 of 81425 relevant lines covered (47.91%)

1079780.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.11
/sources/token.c
1
/** @file token.c
2
 * 
3
 *  The tokenizer. This is a part of the compiler that does an intermediate
4
 *  type of translation. It does look up the names etc and can do a number
5
 *        of optimizations. The resulting output is a stream of bytes which can
6
 *        be processed by the code generator (in the file compiler.c)
7
 */
8
/* #[ License : */
9
/*
10
 *   Copyright (C) 1984-2023 J.A.M. Vermaseren
11
 *   When using this file you are requested to refer to the publication
12
 *   J.A.M.Vermaseren "New features of FORM" math-ph/0010025
13
 *   This is considered a matter of courtesy as the development was paid
14
 *   for by FOM the Dutch physics granting agency and we would like to
15
 *   be able to track its scientific use to convince FOM of its value
16
 *   for the community.
17
 *
18
 *   This file is part of FORM.
19
 *
20
 *   FORM is free software: you can redistribute it and/or modify it under the
21
 *   terms of the GNU General Public License as published by the Free Software
22
 *   Foundation, either version 3 of the License, or (at your option) any later
23
 *   version.
24
 *
25
 *   FORM is distributed in the hope that it will be useful, but WITHOUT ANY
26
 *   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
27
 *   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
28
 *   details.
29
 *
30
 *   You should have received a copy of the GNU General Public License along
31
 *   with FORM.  If not, see <http://www.gnu.org/licenses/>.
32
 */
33
/* #] License : */ 
34
/*
35
          #[ Includes :
36
*/
37

38
#include "form3.h"
39

40
/*
41
          #] Includes : 
42
        #[ Compiler :
43
                 #[ tokenize :
44

45
                Takes the input in 'in' and translates it into tokens.
46
                The tokens are put in the token buffer which starts at 'AC.tokens'
47
                and runs till 'AC.toptokens'
48
                We may assume that the various types of brackets match properly.
49
                object = -1: after , or (
50
                object = 0: name/variable/number etc is allowed
51
                object = 1: variable.
52
                object = 2: number
53
                object = 3: ) after subexpression
54
*/
55

56
#define CHECKPOLY {if(polyflag)MesPrint("&Illegal use of polynomial function"); polyflag = 0; }
57

58
int tokenize(UBYTE *in, WORD leftright)
8,346✔
59
{
60
        int error = 0, object, funlevel = 0, bracelevel = 0, explevel = 0, numexp;
8,346✔
61
        int polyflag = 0;
8,346✔
62
        WORD number, type;
8,346✔
63
        UBYTE *s = in, c;
8,346✔
64
        SBYTE *out, *outtop, num[MAXNUMSIZE], *t;
8,346✔
65
        LONG i;
8,346✔
66
        if ( AC.tokens == 0 ) {
8,346✔
67
                SBYTE **ppp = &(AC.tokens); /* to avoid a compiler warning */
847✔
68
                SBYTE **pppp = &(AC.toptokens);
847✔
69
                DoubleBuffer((void **)ppp,(void **)pppp,sizeof(SBYTE),"start tokens");
847✔
70
        }
71
        out = AC.tokens;
8,346✔
72
        outtop = AC.toptokens - MAXNUMSIZE;
8,346✔
73
        AC.dumnumflag = 0;
8,346✔
74
        object = 0;
8,346✔
75
        while ( *in ) {
4,013,578✔
76
                if ( out > outtop ) {
4,005,232✔
77
                        LONG oldsize = (LONG)(out - AC.tokens);
453✔
78
                        SBYTE **ppp = &(AC.tokens); /* to avoid a compiler warning */
453✔
79
                        SBYTE **pppp = &(AC.toptokens);
453✔
80
                        DoubleBuffer((void **)ppp,(void **)pppp,sizeof(SBYTE),"expand tokens");
453✔
81
                        out = AC.tokens + oldsize;
453✔
82
                        outtop = AC.toptokens - MAXNUMSIZE;
453✔
83
                }
84
                switch ( FG.cTable[*in] ) {
4,005,232✔
85
                        case 0:                /* a-zA-Z */
86
                                CHECKPOLY
1,045,058✔
87
                                s = in++;
1,045,058✔
88
                                while ( FG.cTable[*in] == 0 || FG.cTable[*in] == 1
1,045,058✔
89
                                || *in == '_' ) in++;
2,475,902✔
90
dovariable:                c = *in; *in = 0;
1,045,058✔
91
                                if ( object > 0 ) {
1,045,082✔
92
                                        MesPrint("&Illegal position for %s",s);
×
93
                                        if ( !error ) error = 1;
×
94
                                }
95
                                if ( out > AC.tokens && ( out[-1] == TWILDCARD || out[-1] == TNOT ) ) {
1,045,082✔
96
                                    type = GetName(AC.varnames,s,&number,NOAUTO);
4,372✔
97
                                }
98
                                else {
99
                                    type = GetName(AC.varnames,s,&number,WITHAUTO);
1,040,710✔
100
                                }
101
                            if ( type < 0 )
1,045,082✔
102
                                        type = GetName(AC.exprnames,s,&number,NOAUTO);
621✔
103
                                switch ( type ) {
1,045,082✔
104
                                        case CSYMBOL:       *out++ = TSYMBOL;     break;
815,922✔
105
                                        case CINDEX:
687✔
106
                                                if ( number >= (AM.IndDum-AM.OffsetIndex) ) {
687✔
107
                                                        if ( c != '?' ) {
9✔
108
                                                                MesPrint("&Generated indices should be of the type Nnumber_?");
×
109
                                                                error = 1;
×
110
                                                        }
111
                                                        else {
112
                                                                *in++ = c; c = *in; *in = 0;
9✔
113
                                                                AC.dumnumflag = 1;
9✔
114
                                                        }
115
                                                }
116
                                                *out++ = TINDEX;
687✔
117
                                                break;
687✔
118
                                        case CVECTOR:       *out++ = TVECTOR;     break;
8,415✔
119
                                        case CFUNCTION:
215,038✔
120
#ifdef WITHMPI
121
                                                /*
122
                                                 * In the preprocessor, random functions in #$var=... and #inside
123
                                                 * may cause troubles, because the program flow on a slave may be
124
                                                 * different from those on others. We set AC.RhsExprInModuleFlag in order
125
                                                 * to make the change of $-variable be done on the master and thus keep the
126
                                                 * consistency among the master and all slave processes. The previous value
127
                                                 * of AC.RhsExprInModuleFlag will be restored after #$var=... and #inside.
128
                                                 */
129
                                                if ( AP.PreAssignFlag || AP.PreInsideLevel ) {
130
                                                        switch ( number + FUNCTION ) {
131
                                                                case RANDOMFUNCTION:
132
                                                                case RANPERM:
133
                                                                        AC.RhsExprInModuleFlag = 1;
134
                                                        }
135
                                                }
136
#endif
137
                                                *out++ = TFUNCTION;
215,038✔
138
                                                break;
215,038✔
139
                                        case CSET:          *out++ = TSET;        break;
4,384✔
140
                                        case CEXPRESSION:   *out++ = TEXPRESSION;
621✔
141
                                                                                if ( leftright == LHSIDE ) {
621✔
142
                                                                    if ( !error ) error = 1;
×
143
                                                                                        MesPrint("&Expression not allowed in LH-side of substitution: %s",s);
×
144
                                                                                }
145
/*[06nov2003 mt]:*/
146
#ifdef WITHMPI
147
                                                                                else { /*RHSide*/
148
                                                                                        /* NOTE: We always set AC.RhsExprInModuleFlag regardless of
149
                                                                                         *       AP.PreAssignFlag or AP.PreInsideLevel because we have to detect
150
                                                                                         *       RHS expressions even in those cases. */
151
                                                                                        AC.RhsExprInModuleFlag = 1;
152
                                                                                }
153
                                                                                if ( !AP.PreAssignFlag && !AP.PreInsideLevel )
154
                                                                                        Expressions[number].vflags |= ISINRHS;
155
#endif
156
/*:[06nov2003 mt]*/
157
                                                                                if ( AC.exprfillwarning == 0 ) {
621✔
158
                                                                                                AC.exprfillwarning = 1;
174✔
159
                                                                                }
160
                                                                                break;
161
                                        case CDELTA:        *out++ = TDELTA;      *in = c;
15✔
162
                                                                                object = 1; continue;
15✔
163
                                        case CDUBIOUS:      *out++ = TDUBIOUS;    break;
×
164
                                        default:            *out++ = TDUBIOUS;
×
165
                                                            if ( !error ) error = 1;
×
166
                                                                                MesPrint("&Undeclared variable %s",s);
×
167
                                                                                number = AddDubious(s);
×
168
                                                            break;
×
169
                                }
170
                                object = 1;
171
donumber:                i = 0;
1,045,475✔
172
                                do { num[i++] = (SBYTE)(number & 0x7F); number >>= 7; } while ( number );
1,266,317✔
173
                                while ( --i >= 0 ) *out++ = num[i];
2,311,792✔
174
                                *in = c;
1,045,475✔
175
                                break;
1,045,475✔
176
                        case 1:                /* 0-9 */
177
                          {
178
#ifdef WITHFLOAT
179
                                int spec;
180
                                UBYTE *in2;
181
#endif
182
                                CHECKPOLY
818,229✔
183
                                s = in;
818,229✔
184
                                while ( *s == '0' && FG.cTable[s[1]] == 1 ) s++;
818,229✔
185
                                in = s+1; i = 1;
818,190✔
186
                                while ( FG.cTable[*in] == 1 ) { in++; i++; }
1,645,572✔
187
                                if ( object > 0 ) {
818,190✔
188
                                        c = *in; *in = 0;
×
189
                                        MesPrint("&Illegal position for %s",s);
×
190
                                        *in = c;
×
191
                                        if ( !error ) error = 1;
×
192
                                }
193
                                if ( i == 1 && *in == '_' && ( *s == '5' || *s == '6'
818,190✔
194
                                || *s == '7' ) ) {
6✔
195
                                        in++; *out++ = TSGAMMA; *out++ = (SBYTE)(*s - '4');
6✔
196
                                        object = 1;
6✔
197
                                        break;
6✔
198
                                }
199
#ifdef WITHFLOAT
200
                                in2 = CheckFloat(in,&spec);
818,184✔
201
                                if ( in2 > in ) {
818,184✔
202
                                        if ( spec == 1 ) {
×
203
                                                *out++ = TNUMBER; *out++ = 0; s = in2;
×
204
                                        }
205
                                        else if ( spec == -1 ) {
×
206
                                                MesPrint("&The floating point system has not been started: %s",in);
×
207
                            if ( !error ) error = 1;
×
208
                                        }
209
                                        else {
210
                                          in = in2;
×
211
dofloat:
×
212
                                          while ( out + (in-s) >= AC.toptokens ) {
×
213
                                                LONG oldsize = (LONG)(out - AC.tokens);
×
214
                                                SBYTE **ppp = &(AC.tokens); /* to avoid a compiler warning */
×
215
                                                SBYTE **pppp = &(AC.toptokens);
×
216
                                                DoubleBuffer((void **)ppp,(void **)pppp,sizeof(SBYTE),"more tokens");
×
217
                                                out = AC.tokens + oldsize;
×
218
                                                outtop = AC.toptokens - MAXNUMSIZE;
×
219
                                          }
220
                                          *out++ = TFLOAT;
×
221
                                          while ( s < in ) *out++ = *s++;
×
222
                                        }
223
                                }
224
                                else
225
#endif
226
                                {
227
                                *out++ = TNUMBER;
818,184✔
228
                                if ( ( i & 1 ) != 0 ) *out++ = (SBYTE)(*s++ - '0');
818,184✔
229
                                while ( out + (in-s)/2 >= AC.toptokens ) {
818,184✔
230
                                        LONG oldsize = (LONG)(out - AC.tokens);
×
231
                                        SBYTE **ppp = &(AC.tokens); /* to avoid a compiler warning */
×
232
                                        SBYTE **pppp = &(AC.toptokens);
×
233
                                        DoubleBuffer((void **)ppp,(void **)pppp,sizeof(SBYTE),"more tokens");
×
234
                                        out = AC.tokens + oldsize;
×
235
                                        outtop = AC.toptokens - MAXNUMSIZE;
×
236
                                }
237
                                while ( s < in ) {   /* We store in base 100 */
1,322,286✔
238
                                        *out++ = (SBYTE)(( *s - '0' ) * 10 + ( s[1] - '0' ));
504,102✔
239
                                        s += 2;
504,102✔
240
                                }
241
                                }
242
                                object = 2;
818,184✔
243
                          }
244
                          break;
818,184✔
245
                        case 2:                /* . $ _ ? # ' */
246
                                CHECKPOLY
8,863✔
247
                                if ( *in == '?' ) {
8,863✔
248
                                        if ( leftright == LHSIDE ) {
7,948✔
249
                                                if ( object == 1 ) {        /* follows a name */
7,270✔
250
                                                        in++; *out++ = TWILDCARD;
6,667✔
251
                                                        if ( FG.cTable[in[0]] == 0 || in[0] == '[' || in[0] == '{' ) object = 0;
6,667✔
252
                                                }
253
                                                else if ( object == -1 ) {        /* follows comma or ( */
603✔
254
                                                        in++; s = in;
603✔
255
                                                        while ( FG.cTable[*in] == 0 || FG.cTable[*in] == 1 ) in++;
1,230✔
256
                                                        c = *in; *in = 0;
603✔
257
                                                        if ( FG.cTable[*s] != 0 ) {
603✔
258
                                                                MesPrint("&Illegal name for argument list variable %s",s);
×
259
                                                                error = 1;
×
260
                                                        }
261
                                                        else {
262
                                                                i = AddWildcardName((UBYTE *)s);
603✔
263
                                                                *in = c;
603✔
264
                                                                *out++ = TWILDARG;
603✔
265
                                                                *out++ = (SBYTE)i;
603✔
266
                                                        }
267
                                                        object = 1;
268
                                                }
269
                                                else {
270
                                                        MesPrint("&Illegal position for ?");
×
271
                                                        error = 1;
×
272
                                                        in++;
×
273
                                                }
274
                                        }
275
                                        else {
276
                                                if ( object != -1 ) goto IllPos;
678✔
277
                                                in++;
678✔
278
                                                if ( FG.cTable[*in] == 0 || FG.cTable[*in] == 1 ) {
678✔
279
                                                        s = in;
1,338✔
280
                                                        while ( FG.cTable[*in] == 0 || FG.cTable[*in] == 1 ) in++;
1,338✔
281
                                                        c = *in; *in = 0;
669✔
282
                                                        i = GetWildcardName((UBYTE *)s);
669✔
283
                                                        if ( i <= 0 ) {
669✔
284
                                                                MesPrint("&Undefined argument list variable %s",s);
3✔
285
                                                                error = 1;
3✔
286
                                                        }
287
                                                        *in = c;
669✔
288
                                                        *out++ = TWILDARG;
669✔
289
                                                        *out++ = (SBYTE)i;
669✔
290
                                                }
291
                                                else {
292
                                                        if ( AC.vectorlikeLHS == 0 ) {
9✔
293
                                                                MesPrint("&Generated index ? only allowed in vector substitution",s);
3✔
294
                                                                error = 1;
3✔
295
                                                        }
296
                                                        *out++ = TGENINDEX;
9✔
297
                                                }
298
                                                object = 1;
299
                                        }
300
                                }
301
                                else if ( *in == '.' ) {
915✔
302
                                        if ( object == 1 ) {        /* follows a name */
501✔
303
                                                *out++ = TDOT;
501✔
304
                                                object = 0;
501✔
305
                                                in++;
501✔
306
                                        }
307
#ifdef WITHFLOAT
308
                                        else if ( object == 0 || object == -1 ) {
×
309
/*
310
                                                Test for floating point number
311
*/
312
                                                int spec;
×
313
                                                s = CheckFloat(in,&spec);
×
314
                                                if ( s > in ) {
×
315
                                                        if ( spec == 1 ) {
×
316
                                                                *out++ = TNUMBER; *out++ = 0;
×
317
                                                                object = 2; in = s;
×
318
                                                        }
319
                                                        else if ( spec == -1 ) {
×
320
                                                                MesPrint("&The floating point system has not been started: %s",in);
×
321
                                            if ( !error ) error = 1;
×
322
                                                        }
323
                                                        else {
324
                                                                UBYTE *a = s; s = in; in = a;
×
325
                                                                goto dofloat;
×
326
                                                        }
327
                                                }
328
                                                else goto IllPos;
×
329
                                        }
330
#endif
331
                                        else goto IllPos;
×
332
                                }
333
                                else if ( *in == '$' ) {        /* $ variable */
414✔
334
                                        in++;
408✔
335
                                        s = in;
408✔
336
                                        if ( FG.cTable[*in] == 0 ) {
408✔
337
                                                while ( FG.cTable[*in] == 0 || FG.cTable[*in] == 1 ) in++;
1,032✔
338
                                                if ( *in == '_' && AP.PreAssignFlag == 2 ) in++;
408✔
339
                                                c = *in; *in = 0;
408✔
340
                                                if ( object > 0 ) {
408✔
341
                                                        if ( object != 1 || leftright == RHSIDE ) {
27✔
342
                                                                MesPrint("&Illegal position for $%s",s);
×
343
                                                                if ( !error ) error = 1;
×
344
                                                        }        /* else can be assignment in wildcard */
345
                                                        else {
346
                                                                if ( ( number = GetDollar(s) ) < 0 ) {
27✔
347
                                                                        number = AddDollar(s,0,0,0);
24✔
348
                                                                }
349
                                                        }
350
                                                }
351
                                                else if ( ( number = GetDollar(s) ) < 0 ) {
381✔
352
                                                        MesPrint("&Undefined variable $%s",s);
×
353
                                                        if ( !error ) error = 1;
×
354
                                                        number = AddDollar(s,0,0,0);
×
355
                                                }
356
                                                *out++ = TDOLLAR;
408✔
357
                                                object = 1;
408✔
358
                                                if ( ( AC.exprfillwarning == 0 ) &&
408✔
359
                                                     ( ( out > AC.tokens+1 ) && ( out[-2] != TWILDCARD ) ) ) {
114✔
360
                                                        AC.exprfillwarning = 1;
63✔
361
                                                }
362
                                                goto donumber;
408✔
363
                                        }
364
                                        else {
365
                                                MesPrint("Illegal name for $ variable after %s",in);
×
366
                                                if ( !error ) error = 1;
×
367
                                        }
368
                                }
369
                                else if ( *in == '#' ) {
6✔
370
                                        in++;
6✔
371
                                        if ( object == 1 ) {        /* follows a name */
6✔
372
                                                *out++ = TCONJUGATE;
3✔
373
                                        }
374
                                        else {
375
                                                MesPrint("&Illegal position for %#");
3✔
376
                                                error = 1;
3✔
377
                                        }
378
                                }
379
                                else goto IllPos;
×
380
                                break;
381
                        case 3:                /* [ ] */
382
                                CHECKPOLY
222✔
383
                                if ( *in == '[' ) {
222✔
384
                                        if ( object == 1 ) {        /* after name */
123✔
385
                                                t = out-1;
99✔
386
                                                if ( *t == RPARENTHESIS ) {
99✔
387
                                                        *out++ = LBRACE; *out++ = LPARENTHESIS;
×
388
                                                        bracelevel++; explevel = bracelevel;
×
389
                                                }
390
                                                else {
391
                                                        while ( *t >= 0 && t > AC.tokens ) t--;
198✔
392
                                                    if ( *t == TEXPRESSION ) {
99✔
393
                                                                *out++ = LBRACE; *out++ = LPARENTHESIS;
39✔
394
                                                                bracelevel++; explevel = bracelevel;
39✔
395
                                                        }
396
                                                        else {*out++ = LBRACE; bracelevel++; }
60✔
397
                                                }
398
                                                object = 0;
399
                                        }
400
                                        else {                                        /* name. find matching ] */
401
                                                s = in;
24✔
402
                                                in = SkipAName(in);
24✔
403
                                                goto dovariable;
24✔
404
                                        }
405
                                }
406
                                else {
407
                                        if ( explevel > 0 && explevel == bracelevel ) {
99✔
408
                                                *out++ = RPARENTHESIS; explevel = 0;
39✔
409
                                        }
410
                                        *out++ = RBRACE; object = 1; bracelevel--;
99✔
411
                                }
412
                                in++;
198✔
413
                                break;
198✔
414
                        case 4:                /* ( ) = ; , */
588,562✔
415
                                if ( *in == '(' ) {
588,562✔
416
                                        if ( funlevel >= AM.MaxParLevel ) {
232,250✔
417
                                                MesPrint("&More than %d levels of parentheses",AM.MaxParLevel);
×
418
                                                return(-1);
×
419
                                        }
420
                                        if ( object == 1 ) {        /* After name -> function,vector */
232,250✔
421
                                                AC.tokenarglevel[funlevel++] = TYPEISFUN;
214,789✔
422
                                                *out++ = TFUNOPEN;
214,789✔
423
                                                if ( polyflag ) {
214,789✔
424
                                                        if ( in[1] != ')' && in[1] != ',' ) {
425
                                                                *out++ = TNUMBER; *out++ = (SBYTE)(polyflag);
426
                                                                *out++ = TCOMMA;
427
                                                                *out++ = LPARENTHESIS;
428
                                                        }
429
                                                        else {
430
                                                                *out++ = LPARENTHESIS;
431
                                                                *out++ = TNUMBER; *out++ = (SBYTE)(polyflag);
432
                                                        }
433
                                                        polyflag = 0;
434
                                                }
435
                                                else if ( in[1] != ')' && in[1] != ',' ) {
214,789✔
436
                                                        *out++ = LPARENTHESIS;
214,765✔
437
                                                }
438
                                        }
439
                                        else if ( object <= 0 ) {
17,461✔
440
                                                CHECKPOLY
17,461✔
441
                                                AC.tokenarglevel[funlevel++] = TYPEISSUB;
17,461✔
442
                                                *out++ = LPARENTHESIS;
17,461✔
443
                                        }
444
                                        else {
445
                                                polyflag = 0;
×
446
                                                AC.tokenarglevel[funlevel++] = TYPEISMYSTERY;
×
447
                                                MesPrint("&Illegal position for (: %s",in);
×
448
                                                if ( error >= 0 ) error = -1;
×
449
                                        }
450
                                        object = -1;
451
                                }
452
                                else if ( *in == ')' ) {
356,312✔
453
                                        funlevel--;
232,250✔
454
                                        if ( funlevel < 0 ) {
232,250✔
455
/*                                                if ( funflag == 0 ) { */
456
                                                        MesPrint("&There is an unmatched parenthesis");
×
457
                                                        if ( error >= 0 ) error = -1;
×
458
/*                                                } */
459
                                        }
460
                                        else if ( object <= 0
232,250✔
461
                                        && ( AC.tokenarglevel[funlevel] != TYPEISFUN
24✔
462
                                        || out[-1] != TFUNOPEN ) ) {
24✔
463
                                                MesPrint("&Illegal position for closing parenthesis.");
×
464
                                                if ( error >= 0 ) error = -1;
×
465
                                                if ( AC.tokenarglevel[funlevel] == TYPEISFUN ) object = 1;
×
466
                                                else object = 3;
×
467
                                        }
468
                                        else {
469
                                                if ( AC.tokenarglevel[funlevel] == TYPEISFUN ) {
232,250✔
470
                                                        if ( out[-1] == TFUNOPEN ) out--;
214,789✔
471
                                                        else {
472
                                                                if ( out[-1] != TCOMMA ) *out++ = RPARENTHESIS;
214,765✔
473
                                                                *out++ = TFUNCLOSE;
214,765✔
474
                                                        }
475
                                                        object = 1;
476
                                                }
477
                                                else if ( AC.tokenarglevel[funlevel] == TYPEISSUB ) {
17,461✔
478
                                                        *out++ = RPARENTHESIS;
17,461✔
479
                                                        object = 3;
17,461✔
480
                                                }
481
                                        }
482
                                }
483
                                else if ( *in == ',' ) {
124,062✔
484
                                        if ( /* object > 0 && */ funlevel > 0 &&
124,062✔
485
                                        AC.tokenarglevel[funlevel-1] == TYPEISFUN ) {
124,062✔
486
                                                if ( out[-1] != TFUNOPEN && out[-1] != TCOMMA )
124,062✔
487
                                                        *out++ = RPARENTHESIS;
124,062✔
488
                                                else { *out++ = TNUMBER; *out++ = 0; }
×
489
                                                *out++ = TCOMMA;
124,062✔
490
                                                if ( in[1] != ',' && in[1] != ')' )
124,062✔
491
                                                        *out++ = LPARENTHESIS;
124,062✔
492
                                                else if ( in[1] == ')' ) {
×
493
                                                        *out++ = TNUMBER; *out++ = 0;
×
494
                                                }
495
                                        }
496
/*
497
                                        else if ( object > 0 ) {
498
                                        }
499
*/
500
                                        else {
501
                                                MesPrint("&Illegal position for comma: %s",in);
×
502
                                                MesPrint("&Forgotten ; ?");
×
503
                                                if ( error >= 0 ) error = -1;
×
504
                                        }
505
                                        object = -1;
506
                                }
507
                                else goto IllPos;
×
508
                                in++;
588,562✔
509
                                break;
588,562✔
510
                        case 5:                /* + - * % / ^ : */
511
                                CHECKPOLY
1,543,293✔
512
                                if ( *in == ':' || *in == '%' ) goto IllPos;
1,543,293✔
513
                                if ( *in == '*' || *in == '/' || *in == '^' ) {
514
                                        if ( object <= 0 ) {
1,068,103✔
515
                                                MesPrint("&Illegal position for operator: %s",in);
×
516
                                                if ( error >= 0 ) error = -1;
×
517
                                        }
518
                                        else if ( *in == '*' ) *out++ = TMULTIPLY;
1,068,103✔
519
                                        else if ( *in == '/' ) *out++ = TDIVIDE;
337,332✔
520
                                        else                   *out++ = TPOWER;
307,028✔
521
                                        in++;
1,068,103✔
522
                                }
523
                                else {
524
                                        i = 1;
525
                                        while ( *in == '+' || *in == '-' ) {
950,416✔
526
                                                if ( *in == '-' ) i = -i;
475,226✔
527
                                                in++;
475,226✔
528
                                        }
529
                                        if ( i == 1 ) {
475,190✔
530
                                                if ( out > AC.tokens && out[-1] != TFUNOPEN &&
328,849✔
531
                                                out[-1] != LPARENTHESIS && out[-1] != TCOMMA
532
                                                && out[-1] != LBRACE )
533
                                                        *out++ = TPLUS;
326,521✔
534
                                        }
535
                                        else *out++ = TMINUS;
146,341✔
536
                                }
537
                                object = 0;
538
                                break;
539
                        case 6:                /* Whitespace */
×
540
                                in++; break;
×
541
                        case 7:                /* { | } */
542
                                CHECKPOLY
987✔
543
                                if ( *in == '{' ) {
987✔
544
                                        if ( object > 0 ) {
987✔
545
                                                MesPrint("&Illegal position for %s",in);
×
546
                                                if ( !error ) error = 1;
×
547
                                        }
548
                                        s = in+1;
987✔
549
                                        SKIPBRA2(in)
4,206✔
550
                                        number = DoTempSet(s,in);
987✔
551
                                        in++;
987✔
552
                                        if ( number >= 0 ) {
987✔
553
                                                *out++ = TSET;
987✔
554
                                                i = 0;
987✔
555
                                                do { num[i++] = (SBYTE)(number & 0x7F); number >>= 7; } while ( number );
987✔
556
                                                while ( --i >= 0 ) *out++ = num[i];
1,974✔
557
                                        }
558
                                        else if ( error == 0 ) error = 1;
×
559
                                        object = 1;
560
                                }
561
                                else goto IllPos;
×
562
                                break;
563
                        case 8:                /* ! & < > */
564
                                CHECKPOLY
57✔
565
                                if ( *in != '!' || leftright == RHSIDE
57✔
566
                                || object != 1 || out[-1] != TWILDCARD ) goto IllPos;
57✔
567
                                *out++ = TNOT;
57✔
568
                                if ( FG.cTable[in[1]] == 0 || in[1] == '[' || in[1] == '{' ) object = 0;
57✔
569
                                in++;
57✔
570
                                break;
57✔
571
                        default:
572
IllPos:                        MesPrint("&Illegal character at this position: %s",in);
×
573
                                if ( error >= 0 ) error = -1;
×
574
                                in++;
×
575
                                polyflag = 0;
×
576
                                break;
×
577
                }
578
        }
579
        *out++ = TENDOFIT;
8,346✔
580
        AC.endoftokens = out;
8,346✔
581
        if ( funlevel > 0 || bracelevel != 0 ) {
8,346✔
582
                if ( funlevel > 0 ) MesPrint("&Unmatched parentheses");
×
583
                if ( bracelevel != 0 ) MesPrint("&Unmatched braces");
×
584
                return(-1);
×
585
        }
586
        if ( AC.TokensWriteFlag ) WriteTokens(AC.tokens);
8,346✔
587
/*
588
        Simplify fixed set elements
589
*/
590
        if ( error == 0 && simp1token(AC.tokens) ) error = 1;
8,346✔
591
/*
592
        Collect wildcards for the prototype. Simplify the leftover wildcards
593
*/
594
        if ( error == 0 && leftright == LHSIDE && simpwtoken(AC.tokens) )
8,346✔
595
                                error = 1;
×
596
/*
597
        Now prepare the set[n] objects in the RHS.
598
*/
599
        if ( error == 0 && leftright == RHSIDE && simp4token(AC.tokens) )
8,346✔
600
                                error = 1;
601
/*
602
        Simplify simple function arguments (and 1/fac_ and 1/invfac_)
603
*/
604
        if ( error == 0 && simp2token(AC.tokens) ) error = 1;
8,346✔
605
/*
606
        Next we try to remove composite denominators or exponents and
607
        replace them by their internal functions. This may involve expanding
608
        the buffer. The return code of 3a is negative if there is an error
609
        and positive if indeed we need to do some work.
610
        simp3btoken does the work
611
*/
612
        numexp = 0;
8,337✔
613
        if ( error == 0 && ( numexp = simp3atoken(AC.tokens,leftright) ) < 0 )
8,337✔
614
                error = 1;
615
        if ( numexp > 0 ) {
8,337✔
616
                SBYTE *tt;
418✔
617
                out = AC.tokens;
418✔
618
                while ( *out != TENDOFIT ) out++;
13,499✔
619
                while ( out+numexp*9+20 > outtop ) {
421✔
620
                        LONG oldsize = (LONG)(out - AC.tokens);
3✔
621
                        SBYTE **ppp = &(AC.tokens); /* to avoid a compiler warning */
3✔
622
                        SBYTE **pppp = &(AC.toptokens);
3✔
623
                        DoubleBuffer((void **)ppp,(void **)pppp,sizeof(SBYTE),"out tokens");
3✔
624
                        out = AC.tokens + oldsize;
3✔
625
                        outtop = AC.toptokens - MAXNUMSIZE;
3✔
626
                }
627
                tt = out + numexp*9+20;
628
                while ( out >= AC.tokens ) { *tt-- = *out--; }
13,917✔
629
                while ( tt >= AC.tokens ) { *tt-- = TEMPTY; }
13,674✔
630
                if ( error == 0 && simp3btoken(AC.tokens,leftright) ) error = 1;
418✔
631
                if ( error == 0 && simp2token(AC.tokens) ) error = 1;
418✔
632
        }
633
/*
634
        In simp5token we test for special cases like sumvariables that are
635
        already wildcards, etc.
636
*/
637
        if ( error == 0 && simp5token(AC.tokens,leftright) ) error = 1;
8,346✔
638
/*
639
        In simp6token we test for special cases like factorized expressions
640
        that occur in the RHS in an improper way.
641
*/
642
        if ( error == 0 && simp6token(AC.tokens,leftright) ) error = 1;
8,337✔
643

644
        return(error);
645
}
646

647
/*
648
                 #] tokenize : 
649
                 #[ WriteTokens :
650
*/
651

652
char *ttypes[] = { "\n", "S", "I", "V", "F", "set", "E", "dotp", "#",
653
   "sub", "d_", "$", "dub", "(", ")", "?", "??", ".", "[", "]",
654
   ",", "((", "))", "*", "/", "^", "+", "-", "!", "end", "{{", "}}",
655
   "N_?", "conj", "()", "#d", "^d", "_", "snum"  };
656

657
void WriteTokens(SBYTE *in)
×
658
{
659
        int numinline = 0, x, n = sizeof(ttypes)/sizeof(char *);
×
660
        char outbuf[81], *s, *out, c;
×
661
        out = outbuf;
×
662
        while ( *in != TENDOFIT ) {
×
663
                if ( *in < 0 ) {
×
664
                        if ( *in >= -n ) {
×
665
                                s = ttypes[-*in];
×
666
                                while ( *s ) { *out++ = *s++; numinline++; }
×
667
                        }
668
                        else {
669
                                *out++ = '-'; x = -*in; numinline++;
×
670
                                goto writenumber;
×
671
                        }
672
                }
673
                else {
674
                        x = *in;
×
675
writenumber:
×
676
                        s = out;
×
677
                        do {
×
678
                                *out++ = (char)(( x % 10 ) + '0');
×
679
                                numinline++;
×
680
                                x = x / 10;
×
681
                        } while ( x );
×
682
                        c = out[-1]; out[-1] = *s; *s = c;
×
683
                }
684
                if ( numinline > 70 ) {
×
685
                        *out = 0;
×
686
                        MesPrint("%s",outbuf);
×
687
                        out = outbuf; numinline = 0;
×
688
                }
689
                else {
690
                        *out++ = ' '; numinline++;
×
691
                }
692
                in++;
×
693
        }
694
        if ( numinline > 0 ) { *out = 0; MesPrint("%s",outbuf); }
×
695
}
×
696

697
/*
698
                 #] WriteTokens : 
699
                 #[ simp1token :
700

701
                Routine substitutes set elements if possible.
702
                This means sets with a fixed argument like setname[3].
703
*/
704

705
int simp1token(SBYTE *s)
8,337✔
706
{
707
        int error = 0, n, i, base;
8,337✔
708
        WORD numsub;
8,337✔
709
        SBYTE *fill = s, *start, *t, numtab[10];
8,337✔
710
        SETS set;
8,337✔
711
        while ( *s != TENDOFIT ) {
7,098,911✔
712
                if ( *s == RBRACE ) {
7,090,574✔
713
                        start = fill-1;
99✔
714
                        while ( *start != LBRACE ) start--;
468✔
715
                        t = start - 1;
99✔
716
                        while ( *t >= 0 ) t--;
198✔
717
                        if ( *t == TSET && ( start[1] == TNUMBER || start[1] == TNUMBER1 ) ) {
99✔
718
                                base = start[1] == TNUMBER ? 100: 128;
×
719
                                start += 2;
×
720
                                numsub = *start++;
×
721
                                while ( *start >= 0 && start < fill )
×
722
                                        { numsub = base*numsub + *start++; }
×
723
                                if ( start == fill ) {
×
724
                                        start = t;
×
725
                                        t++; n = *t++; while ( *t >= 0 ) { n = 128*n + *t++; }
×
726
                                        set = Sets+n;
×
727
                                        if ( ( set->type != CRANGE )
×
728
                                        && ( numsub > 0 && numsub <= set->last-set->first ) ) {
×
729
                                                fill = start;
×
730
                                                n = SetElements[set->first+numsub-1];
×
731
                                                switch (set->type) {
×
732
                                                        case CSYMBOL:
×
733
                                                                if ( n > MAXPOWER ) {
×
734
                                                                        n -= 2*MAXPOWER;
×
735
                                                                        if ( n < 0 ) { n = -n; *fill++ = TMINUS; }
×
736
                                                                        *fill++ = TNUMBER1;
×
737
                                                                }
738
                                                                else *fill++ = TSYMBOL;
×
739
                                                                break;
740
                                                        case CINDEX:
×
741
                                                                if ( n < AM.OffsetIndex ) *fill++ = TNUMBER1;
×
742
                                                                else {
743
                                                                        *fill++ = TINDEX;
×
744
                                                                        n -= AM.OffsetIndex;
×
745
                                                                }
746
                                                                break;
747
                                                        case CVECTOR:   *fill++ = TVECTOR;
×
748
                                                                n -= AM.OffsetVector;   break;
×
749
                                                        case CFUNCTION: *fill++ = TFUNCTION;
×
750
                                                                n -= FUNCTION; break;
×
751
                                                        case CNUMBER:   *fill++ = TNUMBER1;  break;
×
752
                                                        case CDUBIOUS:  *fill++ = TDUBIOUS; n = 1; break;
×
753
                                                }
754
                                                i = 0;
×
755
if ( n < 0 ) {
×
756
        MesPrint("Value of n = %d",n);
×
757
}
758
                                                do { numtab[i++] = (SBYTE)(n & 0x7F); n >>= 7; } while ( n );
×
759
                                                while ( --i >= 0 ) *fill++ = numtab[i];
×
760
                                        }
761
                                        else {
762
                                                MesPrint("&Illegal element %d in set",numsub);
×
763
                                                error++;
×
764
                                        }
765
                                        s++; continue;
×
766
                                }
767
                        }
768
                        *fill++ = *s++;
99✔
769
                }
770
                else *fill++ = *s++;
7,090,475✔
771
        }
772
        *fill++ = TENDOFIT;
8,337✔
773
        return(error);
8,337✔
774
}
775

776
/*
777
                 #] simp1token : 
778
                 #[ simpwtoken :
779

780
                Only to be called in the LHS.
781
                Hunts down the wildcards and writes them to the wildcardbuffer.
782
                Next it causes the ProtoType to be constructed.
783
                All wildcards are simplified into the trailing TWILDCARD,
784
                because the specifics are stored in the prototype.
785
                These specifics also include the transfer of wildcard values
786
                to $variables.
787

788
                Types of wildcards:
789
                a?, a?set, a?!set, a?set[i], A?set1?set2, ?a
790
                After this we can strip the set information.
791
                We still need the ? because of the wildcarding offset in code generation
792
*/
793

794
int simpwtoken(SBYTE *s)
2,824✔
795
{
796
        int error = 0, first = 1, notflag;
2,824✔
797
        WORD num, numto, numdollar, *w = AC.WildC, *wstart, *wtop;
2,824✔
798
        SBYTE *fill = s, *t, *v, *s0 = s;
2,824✔
799
        while ( *s != TENDOFIT ) {
64,027✔
800
                if ( *s == TWILDCARD ) {
61,203✔
801
                        notflag = 0; t = fill;
13,388✔
802
                        while ( t > s0 && t[-1] >= 0 ) t--;
13,388✔
803
                        v = t; num = 0; *fill++ = *s++;
6,667✔
804
                        while ( *v >= 0 ) num = 128*num + *v++;
13,388✔
805
                        if ( t > s0 ) t--;
6,667✔
806
                        AC.NwildC += 4;
6,667✔
807
                        if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
6,667✔
808
                        switch ( *t ) {
6,667✔
809
                                case TSYMBOL:
5,896✔
810
                                case TDUBIOUS:
811
                                        *w++ = SYMTOSYM; *w++ = 4; *w++ = num; *w++ = num; break;
5,896✔
812
                                case TINDEX:
84✔
813
                                        num += AM.OffsetIndex;
84✔
814
                                        *w++ = INDTOIND; *w++ = 4; *w++ = num; *w++ = num;  break;
84✔
815
                                case TVECTOR:
633✔
816
                                        num += AM.OffsetVector;
633✔
817
                                        *w++ = VECTOVEC; *w++ = 4; *w++ = num; *w++ = num;  break;
633✔
818
                                case TFUNCTION:
54✔
819
                                        num += FUNCTION;
54✔
820
                                        *w++ = FUNTOFUN; *w++ = 4; *w++ = num; *w++ = num;  break;
54✔
821
                                default:
×
822
                                        MesPrint("&Illegal type of wildcard in LHS");
×
823
                                        error = -1;
×
824
                                        *w++ = SYMTOSYM; *w++ = 4; *w++ = num; *w++ = num;  break;
×
825
                                        break;
826
                        }
827
/*
828
                        Now the sets. The s pointer sits after the ?
829
*/
830
                        wstart = w;
6,667✔
831
                        if ( *s == TNOT && s[1] == TSET ) { notflag = 1; s++; }
6,667✔
832
                        if ( *s == TSET ) {
6,667✔
833
                                s++; num = 0; while ( *s >= 0 ) num = 128*num + *s++;
10,664✔
834
                                if ( notflag == 0 && *s == TWILDCARD && s[1] == TSET ) {
5,332✔
835
                                        s += 2; numto = 0; while ( *s >= 0 ) numto = 128*numto + *s++;
×
836
                                        if ( num < AM.NumFixedSets || numto < AM.NumFixedSets
×
837
                                        || Sets[num].type == CRANGE || Sets[numto].type == CRANGE ) {
×
838
                                                MesPrint("&This type of set not allowed in this wildcard construction");
×
839
                                                error = 1;
×
840
                                        }
841
                                        else {
842
                                        AC.NwildC += 4;
×
843
                                        if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
×
844
                                        *w++ = FROMSET; *w++ = 4; *w++ = num; *w++ = numto;
×
845
                                        wstart = w;
×
846
                                        }
847
                                }
848
                                else if ( notflag == 0 && *s == LBRACE && s[1] == TSYMBOL ) {
5,275✔
849
                                        if ( num < AM.NumFixedSets || Sets[num].type == CRANGE ) {
21✔
850
                                                MesPrint("&This type of set not allowed in this wildcard construction");
×
851
                                                error = 1;
×
852
                                        }
853
                                        v = s; s += 2;
21✔
854
                                        numto = 0; while ( *s >= 0 ) numto = 128*numto + *s++;
42✔
855
                                        if ( *s == TWILDCARD ) s++; /* most common mistake */
21✔
856
                                        if ( *s == RBRACE ) {
21✔
857
                                                s++;
21✔
858
                                                AC.NwildC += 8;
21✔
859
                                                if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
21✔
860
                                                *w++ = SETTONUM; *w++ = 4; *w++ = num; *w++ = numto;
21✔
861
                                                wstart = w;
21✔
862
                                                *w++ = SYMTOSYM; *w++ = 4; *w++ = numto; *w++ = 0;
21✔
863
                                        }
864
                                        else if ( *s == TDOLLAR ) {
×
865
                                                s++; numdollar = 0;
×
866
                                                while ( *s >= 0 ) numdollar = 128*numdollar + *s++;
×
867
                                                if ( *s == RBRACE ) {
×
868
                                                        s++;
×
869
                                                        AC.NwildC += 12;
×
870
                                                        if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
×
871
                                                        *w++ = SETTONUM; *w++ = 4; *w++ = num; *w++ = numto;
×
872
                                                        wstart = w;
×
873
                                                        *w++ = SYMTOSYM; *w++ = 4; *w++ = numto; *w++ = 0;
×
874
                                                        *w++ = LOADDOLLAR; *w++ = 4; *w++ = numdollar;
×
875
                                                        *w++ = numdollar;
×
876
                                                }
877
                                                else { s = v; goto singlewild; }
×
878
                                        }
879
                                        else { s = v; goto singlewild; }
×
880
                                }
881
                                else {
882
singlewild:                        num += notflag * 2*WILDOFFSET;
5,254✔
883
                                        AC.NwildC += 4;
5,311✔
884
                                        if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
5,311✔
885
                                        *w++ = FROMSET; *w++ = 4; *w++ = num; *w++ = -WILDOFFSET;
5,311✔
886
                                        wstart = w;
5,311✔
887
                                }
888
                        }
889
                        else if ( *s != TDOLLAR && *s != TENDOFIT && *s != RPARENTHESIS
1,335✔
890
                        && *s != RBRACE && *s != TCOMMA && *s != TFUNCLOSE && *s != TMULTIPLY
891
                        && *s != TPOWER && *s != TDIVIDE && *s != TPLUS && *s != TMINUS
892
                        && *s != TPOWER1 && *s != TEMPTY && *s != TFUNOPEN && *s != TDOT ) {
893
                                MesPrint("&Illegal type of wildcard in LHS");
×
894
                                error = -1;
×
895
                        }
896
                        if ( *s == TDOLLAR ) {
6,667✔
897
                                s++; numdollar = 0;
15✔
898
                                while ( *s >= 0 ) numdollar = 128*numdollar + *s++;
30✔
899
                                AC.NwildC += 4;
15✔
900
                                if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
15✔
901
                                wtop = w + 4;
15✔
902
                                if ( wstart < w ) {
15✔
903
                                        while ( w > wstart ) { w[4] = w[0]; w--; }
×
904
                                }
905
                                *w++ = LOADDOLLAR; *w++ = 4; *w++ = numdollar; *w++ = numdollar;
15✔
906
                                w = wtop;
15✔
907
                        }
908
                }
909
                else if ( *s == TWILDARG ) {
54,536✔
910
                        *fill++ = *s++;
603✔
911
                        num = 0;
603✔
912
                        while ( *s >= 0 ) { num = 128*num + *s;  *fill++ = *s++; }
1,206✔
913
                        AC.NwildC += 4;
603✔
914
                        if ( AC.NwildC > 4*AM.MaxWildcards ) {
603✔
915
firsterr:                if ( first ) {
×
916
                                        MesPrint("&More than %d wildcards",AM.MaxWildcards);
×
917
                                        error = -1;
×
918
                                        first = 0;
×
919
                                }
920
                        }
921
                        else { *w++ = ARGTOARG; *w++ = 4; *w++ = num; *w++ = -1; }
603✔
922
                        if ( *s == TDOLLAR ) {
603✔
923
                                s++; num = 0; while ( *s >= 0 ) num = 128*num + *s++;
24✔
924
                                AC.NwildC += 4;
12✔
925
                                if ( AC.NwildC > 4*AM.MaxWildcards ) goto firsterr;
12✔
926
                                *w++ = LOADDOLLAR; *w++ = 4; *w++ = num; *w++ = num;
12✔
927
                        }
928
                }
929
                else *fill++ = *s++;
53,933✔
930
        }
931
        *fill++ = TENDOFIT;
2,824✔
932
        AC.WildC = w;
2,824✔
933
        return(error);
2,824✔
934
}
935

936
/*
937
                 #] simpwtoken : 
938
                 #[ simp2token :
939

940
                Deals with function arguments.
941
                The tokenizer has given function arguments extra parentheses.
942
                We remove the double parentheses.
943
                Next we remove the parentheses around the simple arguments.
944

945
                It also replaces /fac_() by *invfac_() and /invfac_() by *fac_()
946
*/
947

948
int simp2token(SBYTE *s)
8,755✔
949
{
950
        SBYTE *to, *fill, *t, *v, *w, *s0 = s, *vv;
8,755✔
951
        int error = 0, n;
8,755✔
952
/*
953
        Set substitutions
954
*/
955
        fill = to = s;
8,755✔
956
        while ( *s != TENDOFIT ) {
7,103,865✔
957
                if ( *s == LPARENTHESIS && s[1] == LPARENTHESIS ) {
7,095,110✔
958
                        t = s+1; n = 0;
438✔
959
                        while ( n >= 0 ) {
9,375✔
960
                                t++;
8,937✔
961
                                if ( *t == LPARENTHESIS ) n++;
8,937✔
962
                                else if ( *t == RPARENTHESIS ) n--;
8,769✔
963
                        }
964
                        if ( t[1] == RPARENTHESIS ) {
438✔
965
                                *t = TEMPTY; s++;
384✔
966
                        }
967
                        *fill++ = *s++;
438✔
968
                }
969
                else if ( *s == TEMPTY ) s++;
7,094,672✔
970
                else if ( *s == AM.facnum && ( fill > (s0+1) ) && fill[-2] == TDIVIDE
7,094,288✔
971
                 && fill[-1] == TFUNCTION ) {
606✔
972
                        fill[-2] = TMULTIPLY; *fill++ = (SBYTE)(AM.invfacnum); s++;
×
973
                }
974
                else if ( *s == AM.invfacnum && ( fill > (s0+1) ) && fill[-2] == TDIVIDE
7,094,288✔
975
                 && fill[-1] == TFUNCTION ) {
606✔
976
                        fill[-2] = TMULTIPLY; *fill++ = (SBYTE)(AM.facnum); s++;
×
977
                }
978
                else *fill++ = *s++;
7,094,288✔
979
        }
980
        *fill++ = TENDOFIT;
8,755✔
981
/*
982
        Second round: try to locate 'simple' arguments and strip their brackets
983

984
        We add (9-feb-2010) to the simple arguments integers of any size
985
*/
986
        fill = s = to;
8,755✔
987
        while ( *s != TENDOFIT ) {
7,103,307✔
988
                if ( *s == LPARENTHESIS ) {
7,094,552✔
989
                        t = s; n = 0;
990
                        while ( n >= 0 ) {
7,290,419✔
991
                                t++;
6,933,277✔
992
                                if ( *t == LPARENTHESIS ) n++;
6,933,277✔
993
                                else if ( *t == RPARENTHESIS ) n--;
6,884,389✔
994
                        }
995
                        if ( t[1] == TFUNCLOSE && s[1] != TWILDARG ) { /* Check for last argument in sum */
357,142✔
996
                                v = fill - 1; n = 0;
214,322✔
997
                                while ( n >= 0 && v >= to ) {
2,764,529✔
998
                                        if ( *v == TFUNOPEN ) n--;
2,550,207✔
999
                                        else if ( *v == TFUNCLOSE ) n++;
2,335,459✔
1000
                                        v--;
2,550,207✔
1001
                                }
1002
                                if ( v > to ) {
214,322✔
1003
                                        while ( *v >= 0 ) v--;
641,755✔
1004
                                        if ( *v == TFUNCTION ) { v++;
214,310✔
1005
                                                n = 0; while ( *v >= 0 && v < fill ) n = 128*n + *v++;
641,677✔
1006
                                                if ( n == AM.sumnum || n == AM.sumpnum ) {
214,262✔
1007
                                                        *fill++ = *s++; continue;
32✔
1008
                                                }
1009
                                                else if ( ( n == (FIRSTBRACKET-FUNCTION)
214,230✔
1010
                                                || n == (TERMSINEXPR-FUNCTION)
214,230✔
1011
                                                || n == (SIZEOFFUNCTION-FUNCTION)
214,230✔
1012
                                                || n == (NUMFACTORS-FUNCTION)
1013
                                                || n == (GCDFUNCTION-FUNCTION)
1014
                                                || n == (DIVFUNCTION-FUNCTION)
1015
                                                || n == (REMFUNCTION-FUNCTION)
1016
                                                || n == (INVERSEFUNCTION-FUNCTION)
1017
                                                || n == (MULFUNCTION-FUNCTION)
1018
                                                || n == (FACTORIN-FUNCTION)
1019
                                                || n == (FIRSTTERM-FUNCTION)
1020
                                                || n == (CONTENTTERM-FUNCTION) )
1021
                                                && fill[-1] == TFUNOPEN ) {
351✔
1022
                                                        v = s+1;
51✔
1023
                                                        if ( *v == TEXPRESSION ) {
51✔
1024
                                                                v++;
36✔
1025
                                                                n = 0; while ( *v >= 0 ) n = 128*n + *v++;
72✔
1026
                                                                if ( v == t ) {
36✔
1027
                                                                        *t = TEMPTY; s++;
36✔
1028
                                                                }
1029
                                                        }
1030
                                                }
1031
                                        }
1032
                                }
1033
                        }
1034
                        if ( ( fill > to )
357,110✔
1035
                         && ( ( fill[-1] == TFUNOPEN || fill[-1] == TCOMMA )
356,831✔
1036
                           && ( t[1] == TFUNCLOSE || t[1] == TCOMMA ) ) ) {
339,597✔
1037
                                v = s + 1;
339,597✔
1038
                                switch ( *v ) {
339,597✔
1039
                                        case TMINUS:
27,717✔
1040
                                                v++;
27,717✔
1041
                                                if ( *v == TVECTOR ) {
27,717✔
1042
                                                        w = v+1; while ( *w >= 0 ) w++;
864✔
1043
                                                        if ( w == t ) {
432✔
1044
                                                                *t = TEMPTY; s++;
138✔
1045
                                                        }
1046
                                                }
1047
                                                else {
1048
                                                        if ( *v == TNUMBER || *v == TNUMBER1 ) {
27,285✔
1049
                                                          if ( BITSINWORD == 16 ) { ULONG x; WORD base;
24,513✔
1050
                                                                base = ( *v == TNUMBER ) ? 100: 128;
1051
                                                                vv = v+1; x = 0; while ( *vv >= 0 ) { x = x*base + *vv++; }
1052
                                                                if ( ( vv != t ) || ( ( vv - v ) > 4 ) || ( x > (MAXPOSITIVE+1) ) )
1053
                                                                        *fill++ = *s++;
1054
                                                                else { *t = TEMPTY; s++; break; }
1055
                                                          }
1056
                                                          else if ( BITSINWORD == 32 ) { ULONG x; WORD base;
24,513✔
1057
                                                                base = ( *v == TNUMBER ) ? 100: 128;
24,513✔
1058
                                                                vv = v+1; x = 0; while ( *vv >= 0 ) { x = x*base + *vv++; }
49,560✔
1059
                                                                if ( ( vv != t ) || ( ( vv - v ) > 6 ) || ( x > (MAXPOSITIVE+1) ) )
24,513✔
1060
                                                                        *fill++ = *s++;
23,820✔
1061
                                                                else { *t = TEMPTY; s++; break; }
693✔
1062
                                                          }
1063
                                                          else {
1064
                                                                if ( ( v+2 == t ) || ( v+3 == t && v[2] >= 0 ) )
1065
                                                                        { *t = TEMPTY; s++; break; }
1066
                                                                else *fill++ = *s++;
1067
                                                          }
1068
                                                        }
1069
                                                        else if ( *v == LPARENTHESIS && t[-1] == RPARENTHESIS ) {
2,772✔
1070
                                                                w = v; n = 0;
1071
                                                                while ( n >= 0 ) {
1,524✔
1072
                                                                        w++;
1,332✔
1073
                                                                        if ( *w == LPARENTHESIS ) n++;
1,332✔
1074
                                                                        else if ( *w == RPARENTHESIS ) n--;
1,332✔
1075
                                                                }
1076
                                                                if ( w == ( t-1 ) ) { *t = TEMPTY; s++; }
192✔
1077
                                                                else *fill++ = *s++;
×
1078
                                                        }
1079
                                                        else *fill++ = *s++;
2,580✔
1080
                                                        break;
1081
                                                }
1082
                                                /* fall through */
1083
                                        case TSETNUM:
1084
                                                v++; while ( *v >= 0 ) v++;
906✔
1085
                                                goto tcommon;
453✔
1086
                                        case TSYMBOL:
43,567✔
1087
                                                if ( ( v[1] == COEFFSYMBOL || v[1] == NUMERATORSYMBOL
43,567✔
1088
                                                || v[1] == DENOMINATORSYMBOL ) && v[2] < 0 ) {
43,567✔
1089
                                                        *fill++ = *s++; break;
×
1090
                                                }
1091
                                                /* fall through */
1092
                                        case TSET:
1093
                                        case TVECTOR:
1094
                                        case TINDEX:
1095
                                        case TFUNCTION:
1096
                                        case TDOLLAR:
1097
                                        case TDUBIOUS:
1098
                                        case TSGAMMA:
1099
tcommon:                                v++; while ( *v >= 0 ) v++;
105,230✔
1100
                                                if ( v == t || ( v[0] == TWILDCARD && v+1 == t ) )
52,579✔
1101
                                                { *t = TEMPTY; s++; }
34,240✔
1102
                                                else *fill++ = *s++;
18,339✔
1103
                                                break;
1104
                                        case TGENINDEX:
6✔
1105
                                                v++;
6✔
1106
                                                if ( v == t ) { *t = TEMPTY; s++; }
6✔
1107
                                                else *fill++ = *s++;
×
1108
                                                break;
1109
                                        case TNUMBER:
1110
                                        case TNUMBER1:
1111
                                                if ( BITSINWORD == 16 ) { ULONG x; WORD base;
258,161✔
1112
                                                        base = ( *v == TNUMBER ) ? 100: 128;
1113
                                                        vv = v+1; x = 0; while ( *vv >= 0 ) { x = x*base + *vv++; }
1114
                                                        if ( ( vv != t ) || ( ( vv - v ) > 4 ) || ( x > MAXPOSITIVE ) )
1115
                                                                *fill++ = *s++;
1116
                                                        else { *t = TEMPTY; s++; break; }
1117
                                                }
1118
                                                else if ( BITSINWORD == 32 ) { ULONG x; WORD base;
258,161✔
1119
                                                        base = ( *v == TNUMBER ) ? 100: 128;
258,161✔
1120
                                                        vv = v+1; x = 0; while ( *vv >= 0 ) { x = x*base + *vv++; }
809,148✔
1121
                                                        if ( ( vv != t ) || ( ( vv - v ) > 6 ) || ( x > MAXPOSITIVE ) )
258,161✔
1122
                                                                *fill++ = *s++;
38,574✔
1123
                                                        else { *t = TEMPTY; s++; break; }
219,587✔
1124
                                                }
1125
                                                else {
1126
                                                        if ( ( v+2 == t ) || ( v+3 == t && v[2] >= 0 ) )
1127
                                                                { *t = TEMPTY; s++; break; }
1128
                                                        else *fill++ = *s++;
1129
                                                }
1130
                                                break;
38,574✔
1131
                                        case TWILDARG:
1,269✔
1132
                                                v++; while ( *v >= 0 ) v++;
2,538✔
1133
                                                if ( v == t ) { *t = TEMPTY; s++; }
1,269✔
1134
                                                else *fill++ = *s++;
×
1135
                                                break;
1136
                                        case TEXPRESSION:
1137
/*
1138
                                                First establish that there is only the expression
1139
                                                in this argument.
1140
*/
1141
                                                vv = s+1;
1142
                                                while ( vv < t ) {
468✔
1143
                                                        if ( *vv != TEXPRESSION ) break;
240✔
1144
                                                        vv++; while ( *vv >= 0 ) vv++;
468✔
1145
                                                }
1146
                                                if ( vv < t ) { *fill++ = *s++; break; }
234✔
1147
/*
1148
                                                Find the function
1149
*/
1150
                                                w = fill-1; n = 0;
228✔
1151
                                                while ( n >= 0 && w >= to ) {
1,071✔
1152
                                                        if ( *w == TFUNOPEN ) n--;
843✔
1153
                                                        else if ( *w == TFUNCLOSE ) n++;
615✔
1154
                                                        w--;
843✔
1155
                                                }
1156
                                                w--; while ( w > to && *w >= 0 ) w--;
276✔
1157
                                                if ( *w != TFUNCTION ) { *fill++ = *s++; break; }
228✔
1158
                                                w++; n = 0;
228✔
1159
                                                while ( *w >= 0 ) { n = 128*n + *w++; }
504✔
1160
                                                if ( n == GCDFUNCTION-FUNCTION
228✔
1161
                                                || n == DIVFUNCTION-FUNCTION
1162
                                                || n == REMFUNCTION-FUNCTION
228✔
1163
                                                || n == INVERSEFUNCTION-FUNCTION
228✔
1164
                                                || n == MULFUNCTION-FUNCTION ) {
1165
                                                        *t = TEMPTY; s++;
180✔
1166
                                                }
1167
                                                else *fill++ = *s++;
48✔
1168
                                                break;
1169
                                        default: *fill++ = *s++; break;
63✔
1170
                                }
1171
                        }
1172
                        else *fill++ = *s++;
17,513✔
1173
                }
1174
                else if ( *s == TEMPTY ) s++;
6,737,410✔
1175
                else *fill++ = *s++;
6,481,069✔
1176
        }
1177
        *fill++ = TENDOFIT;
8,755✔
1178
        return(error);
8,755✔
1179
}
1180

1181
/*
1182
                 #] simp2token : 
1183
                 #[ simp3atoken :
1184

1185
                We hunt for denominators and exponents that seem hidden.
1186
                For the denominators we have to recognize:
1187
                        /fun  /fun()  /fun^power  /fun()^power
1188
                        /set[n]  /set[n]()  /set[n]^power  /set[n]()^power
1189
                        /symbol^power (power no number or symbol wildcard)
1190
                        /dotpr^power (id)
1191
                        /#^power (id)
1192
                        /()  /()^power
1193
                        /vect /index /vect(anything) /vect(anything)^power
1194
*/
1195

1196
int simp3atoken(SBYTE *s, int mode)
8,337✔
1197
{
1198
        int error = 0, n, numexp = 0, denom, base, numprot, i;
8,337✔
1199
        SBYTE *t, c;
8,337✔
1200
        LONG num;
8,337✔
1201
        WORD *prot;
8,337✔
1202
        if ( mode == RHSIDE ) {
8,337✔
1203
                prot = AC.ProtoType;
5,513✔
1204
                numprot = prot[1] - SUBEXPSIZE;
5,513✔
1205
                prot += SUBEXPSIZE;
5,513✔
1206
        }
1207
        else { prot = 0; numprot = 0; }
8,337✔
1208
        while ( *s != TENDOFIT ) {
3,335,038✔
1209
                denom = 1;
3,326,701✔
1210
                if ( *s == TDIVIDE ) { denom = -1; s++; }
3,326,701✔
1211
                c = *s;
3,326,701✔
1212
                switch(c) {
3,326,701✔
1213
                        case TSYMBOL:
1,342,627✔
1214
                        case TNUMBER:
1215
                        case TNUMBER1:
1216
                                s++; while ( *s >= 0 ) s++;        /* skip the object */
3,015,104✔
1217
                                if ( *s == TWILDCARD ) s++;        /* and the possible wildcard */
1,342,627✔
1218
dosymbol:
1,336,834✔
1219
                                if ( *s != TPOWER ) continue;        /* No power -> done */
1,343,128✔
1220
                                s++;                                                        /* Skip the power */
291,635✔
1221
                                if ( *s == TMINUS ) s++;                /* negative: no difference here */
291,635✔
1222
                                if ( *s == TNUMBER || *s == TNUMBER1 ) {
291,635✔
1223
                                        base = *s == TNUMBER ? 100: 128; /* NUMBER = base 100 */
291,207✔
1224
                                        s++;                                /* Now we compose the power */
291,207✔
1225
                                        num = *s++;                        /* If the number is way too large */
291,207✔
1226
                                        while ( *s >= 0 ) {        /* it may look like not too big */
291,210✔
1227
                                                if ( num > MAXPOWER ) break;        /* Hence... */
3✔
1228
                                                num = base*num + *s++;
3✔
1229
                                        }
1230
                                        while ( *s >= 0 ) s++;        /* Finish the number if needed */
291,207✔
1231
                                        if ( *s == TPOWER ) goto doublepower;
291,207✔
1232
                                        if ( num <= MAXPOWER ) continue;        /* Simple case */
291,207✔
1233
                                }
1234
                                else if ( *s == TSYMBOL && c != TNUMBER && c != TNUMBER1 ) {
428✔
1235
                                        s++; n = 0; while ( *s >= 0 ) { n = 128*n + *s++; }
490✔
1236
                                        if ( *s == TWILDCARD ) { s++;
245✔
1237
                                                if ( *s == TPOWER ) goto doublepower;
103✔
1238
                                                continue; }
103✔
1239
/*
1240
                                        Now we have to test whether n happens to be a wildcard
1241
*/
1242
                                        if ( mode == RHSIDE ) {
142✔
1243
                                                n += 2*MAXPOWER;
142✔
1244
                                                for ( i = 0; i < numprot; i += 4 ) {
310✔
1245
                                                        if ( prot[i+2] == n && prot[i] == SYMTOSYM ) break;
168✔
1246
                                                }
1247
                                                if ( i < numprot ) break;
142✔
1248
                                        }
1249
                                        if ( *s == TPOWER ) goto doublepower;
142✔
1250
                                }
1251
                                numexp++;
325✔
1252
                                break;
325✔
1253
                        case TINDEX:
657✔
1254
                                s++; while ( *s >= 0 ) s++;
1,326✔
1255
                                if ( *s == TWILDCARD ) s++;
657✔
1256
doindex:
573✔
1257
                                if ( denom < 0 || *s == TPOWER ) {
657✔
1258
                                        MesPrint("&Index to a power or in denominator is illegal");
×
1259
                                        error = 1;
×
1260
                                }
1261
                                break;
1262
                        case TVECTOR:
7,914✔
1263
                                s++; while ( *s >= 0 ) s++;
15,828✔
1264
                                if ( *s == TWILDCARD ) s++;
7,914✔
1265
dovector:
7,290✔
1266
                                if ( *s == TFUNOPEN ) {
7,920✔
1267
                                        s++; n = 1;
30✔
1268
                                        for(;;) {
198✔
1269
                                                if ( *s == TFUNOPEN ) {
114✔
1270
                                                        n++;
×
1271
                                                        MesPrint("&Illegal vector index");
×
1272
                                                        error = 1;
×
1273
                                                }
1274
                                                else if ( *s == TFUNCLOSE ) {
114✔
1275
                                                        n--;
30✔
1276
                                                        if ( n <= 0 ) break;
30✔
1277
                                                }
1278
                                                s++;
84✔
1279
                                        }
1280
                                        s++;
30✔
1281
                                }
1282
                                else if ( *s == TDOT ) goto dodot;
7,890✔
1283
                                if ( denom < 0 || *s == TPOWER || *s == TPOWER1 ) numexp++;
7,419✔
1284
                                break;
1285
                        case TFUNCTION:
215,035✔
1286
                                s++; while ( *s >= 0 ) s++;
644,297✔
1287
                                if ( *s == TWILDCARD ) s++;
215,035✔
1288
dofunction:
214,981✔
1289
                                t = s;
215,038✔
1290
                                if ( *t == TFUNOPEN ) {
215,038✔
1291
                                        t++; n = 1;
214,714✔
1292
                                        for(;;) {
10,680,880✔
1293
                                                if ( *t == TFUNOPEN ) n++;
5,447,797✔
1294
                                                else if ( *t == TFUNCLOSE ) { if ( --n <= 0 ) break; }
5,441,197✔
1295
                                                t++;
5,233,083✔
1296
                                        }
1297
                                        t++; s++;
214,714✔
1298
                                }
1299
                                if ( denom < 0 || *t == TPOWER || *t == TPOWER1 ) numexp++;
215,038✔
1300
                                break;
1301
#ifdef WITHFLOAT
1302
                        case TFLOAT:
×
1303
                                s++; while ( *s >= 0 ) s++;
×
1304
                                if ( denom < 0 || *s == TPOWER || *s == TPOWER1 ) numexp++;
×
1305
                                break;
1306
#endif
1307
                        case TEXPRESSION:
621✔
1308
                                s++; while ( *s >= 0 ) s++;
1,242✔
1309
                                t = s;
621✔
1310
                                if ( *t == TFUNOPEN ) {
621✔
1311
                                        t++; n = 1;
×
1312
                                        for(;;) {
×
1313
                                                if ( *t == TFUNOPEN ) n++;
×
1314
                                                else if ( *t == TFUNCLOSE ) { if ( --n <= 0 ) break; }
×
1315
                                                t++;
×
1316
                                        }
1317
                                        t++;
×
1318
                                }
1319
                                if ( *t == LBRACE ) {
621✔
1320
                                        t++; n = 1;
39✔
1321
                                        for(;;) {
525✔
1322
                                                if ( *t == LBRACE ) n++;
282✔
1323
                                                else if ( *t == RBRACE ) { if ( --n <= 0 ) break; }
282✔
1324
                                                t++;
243✔
1325
                                        }
1326
                                        t++;
39✔
1327
                                }
1328
                                if ( denom < 0 || ( ( *t == TPOWER || *t == TPOWER1 )
621✔
1329
                                && t[1] == TMINUS ) ) numexp++;
24✔
1330
                                break;
1331
                        case TDOLLAR:
381✔
1332
                                s++; while ( *s >= 0 ) s++;
762✔
1333
                                if ( denom < 0 || ( ( *s == TPOWER || *s == TPOWER1 )
381✔
1334
                                && s[1] == TMINUS ) ) numexp++;
21✔
1335
                                break;
1336
                        case LPARENTHESIS:
100,238✔
1337
                                s++; n = 1; t = s;
100,238✔
1338
                                for(;;) {
11,546,738✔
1339
                                        if ( *t == LPARENTHESIS ) n++;
5,823,488✔
1340
                                        else if ( *t == RPARENTHESIS ) { if ( --n <= 0 ) break; }
5,789,480✔
1341
                                        t++;
5,723,250✔
1342
                                }
1343
                                t++;
100,238✔
1344
                                if ( denom > 0 && ( *t == TPOWER || *t == TPOWER1 ) ) {
100,238✔
1345
                                        if ( ( t[1] == TNUMBER || t[1] == TNUMBER1 ) && t[2] >= 0
15,342✔
1346
                                        && t[3] < 0 ) break;
15,219✔
1347
                                        numexp++;
132✔
1348
                                }
1349
                                else if ( denom < 0 && ( *t == TPOWER || *t == TPOWER1 ) ) {
84,896✔
1350
                                        if ( t[1] == TMINUS && ( t[2] == TNUMBER
×
1351
                                         || t[2] == TNUMBER1 ) && t[3] >= 0
×
1352
                                        && t[4] < 0 ) break;
×
1353
                                        numexp++;
×
1354
                                }
1355
                                else if ( denom < 0 || ( ( *t == TPOWER || *t == TPOWER1 )
84,833✔
1356
                                && ( t[1] == TMINUS || t[1] == LPARENTHESIS ) ) ) numexp++;
63✔
1357
                                break;
1358
                        case TSET:
15✔
1359
                                s++; n = *s++; while ( *s >= 0 ) { n = 128*n + *s++; }
15✔
1360
                                n = Sets[n].type;
15✔
1361
                                switch ( n ) {
15✔
1362
                                        case CSYMBOL: goto dosymbol;
×
1363
                                        case CINDEX: goto doindex;
×
1364
                                        case CVECTOR: goto dovector;
6✔
1365
                                        case CFUNCTION: goto dofunction;
3✔
1366
                                        case CNUMBER: goto dosymbol;
×
1367
                                        case CMODEL: 
3✔
1368
                                                if ( denom < 0 || *s == TPOWER ) {
3✔
1369
                                                        MesPrint("&A model to a power or in denominator is illegal");
×
1370
                                                        error = 1;
×
1371
                                                }
1372
                                                break;
1373
                                        case ANYTYPE: 
3✔
1374
                                                if ( denom < 0 || *s == TPOWER ) {
3✔
1375
                                                        MesPrint("&A set without type to a power or in denominator is illegal");
×
1376
                                                        error = 1;
×
1377
                                                }
1378
                                                break;
1379
                                        default: error = 1; break;
1380
                                }
1381
                                break;
1382
                        case TDOT:
1383
dodot:                        s++;
501✔
1384
                                if ( *s == TVECTOR ) { s++; while ( *s >= 0 ) s++; }
1,002✔
1385
                                else if ( *s == TSET ) {
×
1386
                                        s++; n = *s++; while ( *s >= 0 ) { n = 128*n + *s++; }
×
1387
                                        if ( Sets[n].type != CVECTOR ) {
×
1388
                                                MesPrint("&Set in dotproduct is not a set of vectors");
×
1389
                                                error = 1;
×
1390
                                        }
1391
                                        if ( *s == LBRACE ) {
×
1392
                                                s++; n = 1;
×
1393
                                                for(;;) {
×
1394
                                                        if ( *s == LBRACE ) n++;
×
1395
                                                        else if ( *s == RBRACE ) { if ( --n <= 0 ) break; }
×
1396
                                                        s++;
×
1397
                                                }
1398
                                                s++;
×
1399
                                        }
1400
                                        else {
1401
                                                MesPrint("&Set without argument in dotproduct");
×
1402
                                                error = 1;
×
1403
                                        }
1404
                                }
1405
                                else if ( *s == TSETNUM ) {
×
1406
                                        s++; n = *s++; while ( *s >= 0 ) { n = 128*n + *s++; }
×
1407
                                        if ( *s != TVECTOR ) goto nodot;
×
1408
                                        s++; n = *s++; while ( *s >= 0 ) { n = 128*n + *s++; }
×
1409
                                        if ( Sets[n].type != CVECTOR ) {
×
1410
                                                MesPrint("&Set in dotproduct is not a set of vectors");
×
1411
                                                error = 1;
×
1412
                                        }
1413
                                }
1414
                                else {
1415
nodot:                                MesPrint("&Illegal second element in dotproduct");
×
1416
                                        error = 1;
×
1417
                                        s++; while ( *s >= 0 ) s++;
×
1418
                                }
1419
                                goto dosymbol;
501✔
1420
                        default:
1,659,213✔
1421
                                s++; while ( *s >= 0 ) s++;
1,660,512✔
1422
                                break;
1423
                }
1424
        }
1425
        if ( error ) return(-1);
8,337✔
1426
        return(numexp);
1427
doublepower:
×
1428
        MesPrint("&Dubious notation with object^power1^power2");
×
1429
        return(-1);
×
1430
}
1431

1432
/*
1433
                 #] simp3atoken : 
1434
                 #[ simp3btoken :
1435
*/
1436

1437
int simp3btoken(SBYTE *s, int mode)
418✔
1438
{
1439
        int error = 0, i, numprot, n, denom, base, inset = 0, dotp, sube = 0;
418✔
1440
        SBYTE *t, c, *fill, *ff, *ss;
418✔
1441
        LONG num;
418✔
1442
        WORD *prot;
418✔
1443
        if ( mode == RHSIDE ) {
418✔
1444
                prot = AC.ProtoType;
418✔
1445
                numprot = prot[1] - SUBEXPSIZE;
418✔
1446
                prot += SUBEXPSIZE;
418✔
1447
        }
1448
        else { prot = 0; numprot = 0; }
1449
        fill = s;
418✔
1450
        while ( *s == TEMPTY ) s++;
13,674✔
1451
        while ( *s != TENDOFIT ) {
10,248✔
1452
                if ( *s == TEMPTY ) { s++; continue; }
9,830✔
1453
                denom = 1;
9,830✔
1454
                if ( *s == TDIVIDE ) { denom = -1; *fill++ = *s++; }
9,830✔
1455
                ff = fill; ss = s; c = *s;
9,830✔
1456
                if ( c == TSETNUM ) {
9,830✔
1457
                        *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1458
                        c = *s;
1459
                }
1460
                dotp = 0;
9,830✔
1461
                switch(c) {
9,830✔
1462
                        case TSYMBOL:
2,486✔
1463
                        case TNUMBER:
1464
                        case TNUMBER1:
1465
                                *fill++ = *s++;
2,486✔
1466
                                while ( *s >= 0 ) *fill++ = *s++;
4,996✔
1467
                                if ( *s == TWILDCARD ) *fill++ = *s++;
2,486✔
1468
dosymbol:
2,486✔
1469
                                t = s;
2,804✔
1470
                                if ( *s != TPOWER ) continue;
2,804✔
1471
                                *fill++ = *s++;
358✔
1472
                                if ( *s == TMINUS ) *fill++ = *s++;
358✔
1473
                                if ( *s == TPLUS ) s++;
358✔
1474
                                if ( *s == TSETNUM ) {
358✔
1475
                                        *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1476
                                        inset = 1;
1477
                                }
1478
                                else inset = 0;
1479
                                if ( *s == TNUMBER || *s == TNUMBER1 ) {
358✔
1480
                                        base = *s == TNUMBER ? 100: 128;
69✔
1481
                                        *fill++ = *s++;
69✔
1482
                                        num = *s++; *fill++ = num;
69✔
1483
                                        while ( *s >= 0 ) {
69✔
1484
                                                if ( num > MAXPOWER ) break;
×
1485
                                                *fill++ = *s;
×
1486
                                                num = base*num + *s++;
×
1487
                                        }
1488
                                        while ( *s >= 0 ) *fill++ = *s++;
69✔
1489
                                        if ( num <= MAXPOWER ) continue;
69✔
1490
                                        goto putexp1;
×
1491
                                }
1492
                                else if ( *s == TSYMBOL && c != TNUMBER && c != TNUMBER1 ) {
289✔
1493
                                        *fill++ = *s++;
142✔
1494
                                        n = 0; while ( *s >= 0 ) { n = 128*n + *s; *fill++ = *s++; }
284✔
1495
                                        if ( *s == TWILDCARD ) { *fill++ = *s++;
142✔
1496
                                                if ( *s == TPOWER ) goto doublepower;
×
1497
                                        break; }
1498
/*
1499
                                        Now we have to test whether n happens to be a wildcard
1500
*/
1501
                                        if ( mode == RHSIDE && inset == 0 ) {
142✔
1502
/*                                                n += WILDOFFSET;*/
1503
                                                for ( i = 0; i < numprot; i += 4 ) {
178✔
1504
                                                        if ( prot[i+2] == n && prot[i] == SYMTOSYM ) break;
165✔
1505
                                                }
1506
                                                if ( i < numprot ) break;
142✔
1507
                                        }
1508

1509
putexp1:                        fill = ff;
13✔
1510
                                        if ( denom < 0 ) fill[-1] = TMULTIPLY;
13✔
1511
                                        *fill++ = TFUNCTION; *fill++ = (SBYTE)(AM.expnum); *fill++ = TFUNOPEN;
13✔
1512
                                        if ( dotp ) *fill++ = LPARENTHESIS;
13✔
1513
                                        while ( ss < t ) *fill++ = *ss++;
39✔
1514
                                        if ( dotp ) *fill++ = RPARENTHESIS;
13✔
1515
                                        *fill++ = TCOMMA;
13✔
1516
                                        ss++;                                                /* Skip TPOWER */
13✔
1517
                                        if ( *ss == TMINUS ) { denom = -denom; ss++; }
13✔
1518
                                        if ( denom < 0 ) {
13✔
1519
                                                *fill++ = LPARENTHESIS;
×
1520
                                                *fill++ = TMINUS;
×
1521
                                                while ( ss < s ) *fill++ = *ss++;
×
1522
                                                *fill++ = RPARENTHESIS;
×
1523
                                        }
1524
                                        else {
1525
                                                while ( ss < s ) *fill++ = *ss++;
39✔
1526
                                        }
1527
                                        *fill++ = TFUNCLOSE;
13✔
1528
                                        if ( *ss == TPOWER ) goto doublepower;
13✔
1529
                                }
1530
                                else {        /* other objects can be composite */
1531
                                        goto dofunpower;
147✔
1532
                                }
1533
                                break;
1534
                        case TINDEX:
×
1535
                                *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1536
                                if ( *s == TWILDCARD ) *fill++ = *s++;
×
1537
                                break;
1538
                        case TVECTOR:
336✔
1539
                                *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
672✔
1540
                                if ( *s == TWILDCARD ) *fill++ = *s++;
336✔
1541
dovector:
336✔
1542
                                if ( *s == TFUNOPEN ) {
336✔
1543
                                        while ( *s != TFUNCLOSE ) *fill++ = *s++;
×
1544
                                        *fill++ = *s++;
×
1545
                                }
1546
                                else if ( *s == TDOT ) goto dodot;
336✔
1547
                                t = s;
36✔
1548
                                goto dofunpower;
36✔
1549
#ifdef WITHFLOAT
1550
                        case TFLOAT:
×
1551
                                *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1552
                                t = s;
×
1553
                                sube = 0;
×
1554
                                goto dofunpower;
×
1555
#endif
1556
                        case TFUNCTION:
895✔
1557
                                *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
2,309✔
1558
                                if ( *s == TWILDCARD ) *fill++ = *s++;
895✔
1559
dofunction:
895✔
1560
                                t = s;
895✔
1561
                                if ( *t == TFUNOPEN ) {
895✔
1562
                                        t++; n = 1;
883✔
1563
                                        for(;;) {
34,639✔
1564
                                                if ( *t == TFUNOPEN ) n++;
17,761✔
1565
                                                else if ( *t == TFUNCLOSE ) { if ( --n <= 0 ) break; }
17,407✔
1566
                                                t++;
16,878✔
1567
                                        }
1568
                                        t++; *fill++ = *s++;
883✔
1569
                                }
1570
                                sube = 0;
1571
dofunpower:
2,478✔
1572
                                if ( *t == TPOWER || *t == TPOWER1 ) {
2,478✔
1573
                                        if ( sube ) {
294✔
1574
                                                if ( ( t[1] == TNUMBER || t[1] == TNUMBER1 )
132✔
1575
                                                 && denom > 0 ) {
9✔
1576
                                                        if ( t[2] >= 0 && t[3] < 0 ) { sube = 0; break; }
9✔
1577
                                                }
1578
                                                else if ( t[1] == TMINUS && denom < 0 &&
123✔
1579
                                                ( t[2] == TNUMBER || t[2] == TNUMBER1 ) ) {
×
1580
                                                        if ( t[2] >= 0 && t[3] < 0 ) { sube = 0; break; }
×
1581
                                                }
1582
                                                sube = 0;
294✔
1583
                                        }
1584
                                        fill = ff;
294✔
1585
                                        *fill++ = TFUNCTION; *fill++ = (SBYTE)(AM.expnum); *fill++ = TFUNOPEN;
294✔
1586
                                        *fill++ = LPARENTHESIS;
294✔
1587
                                        while ( ss < t ) *fill++ = *ss++;
7,815✔
1588
                                        t++;
294✔
1589
                                        *fill++ = RPARENTHESIS; *fill++ = TCOMMA;
294✔
1590
                                        if ( *t == TMINUS ) { t++; denom = -denom; }
294✔
1591
                                        *fill++ = LPARENTHESIS;
294✔
1592
                                        if ( denom < 0 ) *fill++ = TMINUS;
294✔
1593
                                        if ( *t == LPARENTHESIS ) {
294✔
1594
                                                *fill++ = *t++; n = 0;
186✔
1595
                                                while ( n >= 0 ) {
894✔
1596
                                                        if ( *t == LPARENTHESIS ) n++;
708✔
1597
                                                        else if ( *t == RPARENTHESIS ) n--;
708✔
1598
                                                        *fill++ = *t++;
708✔
1599
                                                }
1600
                                        }
1601
                                        else if ( *t == TFUNCTION || *t == TDUBIOUS ) {
1602
                                                *fill++ = *t++; while ( *t >= 0 ) *fill++ = *t++;
×
1603
                                                if ( *t == TWILDCARD ) *fill++ = *t++;
×
1604
                                                if ( *t == TFUNOPEN ) {
×
1605
                                                        *fill++ = *t++; n = 0;
×
1606
                                                        while ( n >= 0 ) {
×
1607
                                                                if ( *t == TFUNOPEN ) n++;
×
1608
                                                                else if ( *t == TFUNCLOSE ) n--;
×
1609
                                                                *fill++ = *t++;
×
1610
                                                        }
1611
                                                }
1612
                                        }
1613
                                        else if ( *t == TSET ) {
1614
                                                *fill++ = *t++; n = 0;
×
1615
                                                while ( *t >= 0 ) { n = 128*n + *t; *fill++ = *t++; }
×
1616
                                                if ( *t == LBRACE ) {
×
1617
                                                        if ( n < AM.NumFixedSets || Sets[n].type == CRANGE ) {
×
1618
                                                                MesPrint("&This type of usage of sets is not allowed");
×
1619
                                                                error = 1;
×
1620
                                                        }
1621
                                                        *fill++ = *t++; n = 0;
×
1622
                                                        while ( n >= 0 ) {
×
1623
                                                                if ( *t == LBRACE ) n++;
×
1624
                                                                else if ( *t == RBRACE ) n--;
×
1625
                                                                *fill++ = *t++;
×
1626
                                                        }
1627
                                                }
1628
                                        }
1629
                                        else if ( *t == TEXPRESSION ) {
1630
                                                *fill++ = *t++; while ( *t >= 0 ) *fill++ = *t++;
×
1631
                                                if ( *t == TFUNOPEN ) {
×
1632
                                                        *fill++ = *t++; n = 0;
×
1633
                                                        while ( n >= 0 ) {
×
1634
                                                                if ( *t == TFUNOPEN ) n++;
×
1635
                                                                else if ( *t == TFUNCLOSE ) n--;
×
1636
                                                                *fill++ = *t++;
×
1637
                                                        }
1638
                                                }
1639
                                                if ( *t == LBRACE ) {
×
1640
                                                        *fill++ = *t++; n = 0;
×
1641
                                                        while ( n >= 0 ) {
×
1642
                                                                if ( *t == LBRACE ) n++;
×
1643
                                                                else if ( *t == RBRACE ) n--;
×
1644
                                                                *fill++ = *t++;
×
1645
                                                        }
1646
                                                }
1647
                                        }
1648
                                        else if ( *t == TVECTOR ) {
1649
                                                *fill++ = *t++; while ( *t >= 0 ) *fill++ = *t++;
×
1650
                                                if ( *t == TFUNOPEN ) {
×
1651
                                                        *fill++ = *t++; n = 0;
×
1652
                                                        while ( n >= 0 ) {
×
1653
                                                                if ( *t == TFUNOPEN ) n++;
×
1654
                                                                else if ( *t == TFUNCLOSE ) n--;
×
1655
                                                                *fill++ = *t++;
×
1656
                                                        }
1657
                                                }
1658
                                                else if ( *t == TDOT ) {
×
1659
                                                        *fill++ = *t++;
×
1660
                                                        if ( *t == TVECTOR || *t == TDUBIOUS ) {
×
1661
                                                                *fill++ = *t++; while ( *t >= 0 ) *fill++ = *t++;
×
1662
                                                        }
1663
                                                        else if ( *t == TSET ) {
×
1664
                                                                *fill++ = *t++; num = 0;
×
1665
                                                                while ( *t >= 0 ) { num = 128*num + *t; *fill++ = *t++; }
×
1666
                                                                if ( Sets[num].type != CVECTOR ) {
×
1667
                                                                        MesPrint("&Illegal set type in dotproduct");
×
1668
                                                                        error = 1;
×
1669
                                                                }
1670
                                                                if ( *t == LBRACE ) {
×
1671
                                                                        *fill++ = *t++; n = 0;
×
1672
                                                                        while ( n >= 0 ) {
×
1673
                                                                                if ( *t == LBRACE ) n++;
×
1674
                                                                                else if ( *t == RBRACE ) n--;
×
1675
                                                                                *fill++ = *t++;
×
1676
                                                                        }
1677
                                                                }
1678
                                                        }
1679
                                                        else if ( *t == TSETNUM ) {
×
1680
                                                                *fill++ = *t++;
×
1681
                                                                while ( *t >= 0 ) { *fill++ = *t++; }
×
1682
                                                                *fill++ = *t++;
×
1683
                                                                while ( *t >= 0 ) { *fill++ = *t++; }
×
1684
                                                        }
1685
                                                }
1686
                                                else {
1687
                                                        MesPrint("&Illegal second element in dotproduct");
×
1688
                                                        error = 1;
×
1689
                                                }
1690
                                        }
1691
                                        else {
1692
                                                *fill++ = *t++; while ( *t >= 0 ) *fill++ = *t++;
228✔
1693
                                                if ( *t == TWILDCARD ) *fill++ = *t++;
108✔
1694
                                        }
1695
                                        *fill++ = RPARENTHESIS; *fill++ = TFUNCLOSE;
294✔
1696
                                        if ( *t == TPOWER ) goto doublepower;
294✔
1697
                                        while ( fill > ff ) *--t = *--fill;
11,619✔
1698
                                        s = t;
1699
                                }
1700
                                else if ( denom < 0 ) {
2,184✔
1701
                                        fill = ff; ff[-1] = TMULTIPLY;
63✔
1702
                                        *fill++ = TFUNCTION; *fill++ = (SBYTE)(AM.denomnum);
63✔
1703
                                        *fill++ = TFUNOPEN; *fill++ = LPARENTHESIS;
63✔
1704
                                        while ( ss < t ) *fill++ = *ss++;
780✔
1705
                                        *fill++ = RPARENTHESIS; *fill++ = TFUNCLOSE;
63✔
1706
                                        while ( fill > ff ) *--t = *--fill;
1,158✔
1707
                                        s = t; denom = 1; sube = 0;
10,248✔
1708
                                        break;
1709
                                }
1710
                                sube = 0;
1711
                                break;
1712
                        case TEXPRESSION:
×
1713
                                *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1714
                                t = s;
×
1715
                                if ( *t == TFUNOPEN ) {
×
1716
                                        t++; n = 1;
×
1717
                                        for(;;) {
×
1718
                                                if ( *t == TFUNOPEN ) n++;
×
1719
                                                else if ( *t == TFUNCLOSE ) { if ( --n <= 0 ) break; }
×
1720
                                                t++;
×
1721
                                        }
1722
                                        t++;
×
1723
                                }
1724
                                if ( *t == LBRACE ) {
×
1725
                                        t++; n = 1;
×
1726
                                        for(;;) {
×
1727
                                                if ( *t == LBRACE ) n++;
×
1728
                                                else if ( *t == RBRACE ) { if ( --n <= 0 ) break; }
×
1729
                                                t++;
×
1730
                                        }
1731
                                        t++;
×
1732
                                }
1733
                                if ( t > s || denom < 0 || ( ( *t == TPOWER || *t == TPOWER1 )
×
1734
                                && t[1] == TMINUS ) ) goto dofunpower;
×
1735
                                else goto dosymbol;
×
1736
                        case TDOLLAR:
18✔
1737
                                *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
36✔
1738
                                goto dosymbol;
18✔
1739
                        case LPARENTHESIS:
1,400✔
1740
                                *fill++ = *s++; n = 1; t = s;
1,400✔
1741
                                for(;;) {
51,554✔
1742
                                        if ( *t == LPARENTHESIS ) n++;
26,477✔
1743
                                        else if ( *t == RPARENTHESIS ) { if ( --n <= 0 ) break; }
25,856✔
1744
                                        t++;
25,077✔
1745
                                }
1746
                                t++; sube = 1;
1,400✔
1747
                                goto dofunpower;
1,400✔
1748
                        case TSET:
×
1749
                                *fill++ = *s++; n = *s++; *fill++ = (SBYTE)n;
×
1750
                                while ( *s >= 0 ) { *fill++ = *s; n = 128*n + *s++; }
×
1751
                                n = Sets[n].type;
×
1752
                                switch ( n ) {
×
1753
                                        case CSYMBOL: goto dosymbol;
×
1754
                                        case CINDEX: break;
1755
                                        case CVECTOR: goto dovector;
×
1756
                                        case CFUNCTION: goto dofunction;
×
1757
                                        case CNUMBER: goto dosymbol;
×
1758
                                        case CMODEL: break;
1759
                                        case ANYTYPE: break;
1760
                                        default: error = 1; break;
×
1761
                                }
1762
                                break;
1763
                        case TDOT:
1764
dodot:                        *fill++ = *s++;
300✔
1765
                                if ( *s == TVECTOR ) {
300✔
1766
                                        *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
600✔
1767
                                }
1768
                                else if ( *s == TSET ) {
×
1769
                                        *fill++ = *s++; n = *s++; *fill++ = (SBYTE)n;
×
1770
                                        while ( *s >= 0 ) { *fill++ = *s; n = 128*n + *s++; }
×
1771
                                        if ( *s == LBRACE ) {
×
1772
                                                if ( n < AM.NumFixedSets || Sets[n].type == CRANGE ) {
×
1773
                                                        MesPrint("&This type of usage of sets is not allowed");
×
1774
                                                        error = 1;
×
1775
                                                }
1776
                                                *fill++ = *s++; n = 1;
×
1777
                                                for(;;) {
×
1778
                                                        if ( *s == LBRACE ) n++;
×
1779
                                                        else if ( *s == RBRACE ) { if ( --n <= 0 ) break; }
×
1780
                                                        *fill++ = *s++;
×
1781
                                                }
1782
                                                *fill++ = *s++;
×
1783
                                        }
1784
                                        else {
1785
                                                MesPrint("&Set without argument in dotproduct");
×
1786
                                                error = 1;
×
1787
                                        }
1788
                                }
1789
                                else if ( *s == TSETNUM ) {
×
1790
                                        *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1791
                                        if ( *s != TVECTOR ) goto nodot;
×
1792
                                        *fill++ = *s++; while ( *s >= 0 ) *fill++ = *s++;
×
1793
                                }
1794
                                else {
1795
nodot:                                MesPrint("&Illegal second element in dotproduct");
×
1796
                                        error = 1;
×
1797
                                        *fill++ = *s++;
×
1798
                                        while ( *s >= 0 ) *fill++ = *s++;
×
1799
                                }
1800
                                dotp = 1;
300✔
1801
                                goto dosymbol;
300✔
1802
                        default:
4,695✔
1803
                                *fill++ = *s++;
4,695✔
1804
                                while ( *s >= 0 ) *fill++ = *s++;
4,695✔
1805
                                break;
1806
                }
1807
        }
1808
        *fill = TENDOFIT;
418✔
1809
        return(error);
418✔
1810
doublepower:;
×
1811
        MesPrint("&Dubious notation with power of power");
×
1812
        return(-1);
×
1813
}
1814

1815
/*
1816
                 #] simp3btoken : 
1817
                 #[ simp4token :
1818

1819
                Deal with the set[n] objects in the RHS.
1820
*/
1821

1822
int simp4token(SBYTE *s)
5,513✔
1823
{
1824
        int error = 0, n, nsym, settype;
5,513✔
1825
        WORD i, *w, *wstop, level;
5,513✔
1826
        SBYTE *const s0 = s;
5,513✔
1827
        SBYTE *fill = s, *s1, *s2, *s3, type, s1buf[10];
5,513✔
1828
        SBYTE *tbuf = s, *t, *t1;
5,513✔
1829

1830
        while ( *s != TENDOFIT ) {
7,023,287✔
1831
                if ( *s != TSET ) {
7,017,774✔
1832
                        if ( *s == TEMPTY ) s++;
7,017,735✔
1833
                        else *fill++ = *s++;
7,017,735✔
1834
                        continue;
7,017,735✔
1835
                }
1836
                if ( fill >= (s0+1) && fill[-1] == TWILDCARD ) { *fill++ = *s++; continue; }
39✔
1837
                if ( fill >= (s0+2) && fill[-1] == TNOT && fill[-2] == TWILDCARD ) { *fill++ = *s++; continue; }
39✔
1838
                s1 = s++; n = 0; while ( *s >= 0 ) { n = 128*n + *s++; }
78✔
1839
                i = Sets[n].type;
39✔
1840
                if ( *s != LBRACE ) { while ( s1 < s ) *fill++ = *s1++; continue; }
84✔
1841
                if ( n < AM.NumFixedSets || i == CRANGE ) {
24✔
1842
                        MesPrint("&It is not allowed to refer to individual elements of built in or ranged sets");
×
1843
                        error = 1;
×
1844
                }
1845
                s++;
24✔
1846
                if ( *s != TSYMBOL && *s != TDOLLAR ) {
24✔
1847
                        MesPrint("&Set index in RHS is not a wildcard symbol or $-variable");
×
1848
                        error = 1;
×
1849
                        while ( s1 < s ) *fill++ = *s1++;
×
1850
                        continue;
×
1851
                }
1852
                settype = ( *s == TDOLLAR );
24✔
1853
                s++; nsym = 0; s2 = s;
24✔
1854
                while ( *s >= 0 ) nsym = 128*nsym + *s++;
48✔
1855
                if ( *s != RBRACE ) {
24✔
1856
                        MesPrint("&Improper set argument in RHS");
×
1857
                        error = 1;
×
1858
                        while ( s1 < s ) *fill++ = *s1++;
×
1859
                        continue;
×
1860
                }
1861
                s++;
24✔
1862
/*
1863
                Verify that nsym is a wildcard
1864
*/
1865
                if ( !settype ) {
24✔
1866
                        w = AC.ProtoType; wstop = w + w[1]; w += SUBEXPSIZE;
24✔
1867
                        while ( w < wstop ) {
72✔
1868
                                if ( *w == SYMTOSYM && w[2] == nsym ) break;
72✔
1869
                                w += w[1];
48✔
1870
                        }
1871
                        if ( w >= wstop ) {
24✔
1872
/*
1873
                                It could still be a summation parameter!
1874
*/
1875
                                t = fill - 1;
×
1876
                                while ( t >= tbuf ) {
×
1877
                                        if ( *t == TFUNCLOSE ) {
×
1878
                                                level = 1; t--;
×
1879
                                                while ( t >= tbuf ) {
×
1880
                                                        if ( *t == TFUNCLOSE ) level++;
×
1881
                                                        else if ( *t == TFUNOPEN ) {
×
1882
                                                                level--;
×
1883
                                                                if ( level == 0 ) break;
×
1884
                                                        }
1885
                                                        t--;
×
1886
                                                }
1887
                                        }
1888
                                        else if ( *t == RBRACE ) {
×
1889
                                                level = 1; t--;
×
1890
                                                while ( t >= tbuf ) {
×
1891
                                                        if ( *t == RBRACE ) level++;
×
1892
                                                        else if ( *t == LBRACE ) {
×
1893
                                                                level--;
×
1894
                                                                if ( level == 0 ) break;
×
1895
                                                        }
1896
                                                        t--;
×
1897
                                                }
1898
                                        }
1899
                                        else if ( *t == RPARENTHESIS ) {
×
1900
                                                level = 1; t--;
×
1901
                                                while ( t >= tbuf ) {
×
1902
                                                        if ( *t == RPARENTHESIS ) level++;
×
1903
                                                        else if ( *t == LPARENTHESIS ) {
×
1904
                                                                level--;
×
1905
                                                                if ( level == 0 ) break;
×
1906
                                                        }
1907
                                                        t--;
×
1908
                                                }
1909
                                        }
1910
                                        else if ( *t == TFUNOPEN ) {
×
1911
                                                t1 = t-1;
×
1912
                                                while ( *t1 > 0 && t1 > tbuf ) t1--;
×
1913
                                                if ( *t1 == TFUNCTION ) {
×
1914
                                                        t1++; level = 0;
×
1915
                                                        while ( *t1 > 0 ) level = level*128+*t1++;
×
1916
                                                        if ( level == (SUMF1-FUNCTION)
×
1917
                                                         || level == (SUMF2-FUNCTION) ) {
×
1918
                                                                t1 = t + 1;
×
1919
                                                                if ( *t1 == LPARENTHESIS ) t1++;
×
1920
                                                                if ( *t1 == TSYMBOL ) {
×
1921
                                                                  if ( ( t1[1] == COEFFSYMBOL
×
1922
                                                                  || t1[1] == NUMERATORSYMBOL
1923
                                                                  || t1[1] == DENOMINATORSYMBOL )
×
1924
                                                                  && t1[2] < 0 ) {}
×
1925
                                                                  else {
1926
                                                                        t1++; level = 0;
×
1927
                                                                        while ( *t1 >= 0 && t1 < fill ) level = 128*level + *t1++;
×
1928
                                                                        if ( level == nsym && t1 < fill ) {
×
1929
                                                                                if ( t[1] == LPARENTHESIS
×
1930
                                                                                 && *t1 == RPARENTHESIS && t1[1] == TCOMMA ) break;
×
1931
                                                                                if ( t[1] != LPARENTHESIS && *t1 == TCOMMA ) break;
×
1932
                                                                  }
1933
                                                                        }
1934
                                                                }
1935
                                                        }
1936
                                                }
1937
                                        }
1938
                                        t--;
×
1939
                                }
1940
                                if ( t < tbuf ) {
×
1941
                                        fill--;
×
1942
                                        MesPrint("&Set index in RHS is not a wildcard symbol");
×
1943
                                        error = 1;
×
1944
                                        while ( s1 < s ) *fill++ = *s1++;
×
1945
                                        continue;
×
1946
                                }
1947
                        }
1948
                }
1949
/*
1950
                Now replace by a set marker: TSETNUM,nsym,TYPE,setnumber
1951
*/
1952
                switch ( i ) {
24✔
1953
                        case CSYMBOL: type = TSYMBOL; break;
1954
                        case CINDEX: type = TINDEX; break;
×
1955
                        case CVECTOR: type = TVECTOR; break;
×
1956
                        case CFUNCTION: type = TFUNCTION; break;
3✔
1957
                        case CNUMBER: type = TNUMBER1; break;
6✔
1958
                        case CDUBIOUS: type = TDUBIOUS; break;
×
1959
                        default:
×
1960
                                MesPrint("&Unknown set type in simp4token");
×
1961
                                error = 1; type = CDUBIOUS; break;
×
1962
                }
1963
                s3 = s1buf; s1++;
24✔
1964
                while ( *s1 >= 0 ) *s3++ = *s1++;
48✔
1965
                *s3 = -1; s1 = s1buf;
24✔
1966
                if ( settype ) *fill++ = TSETDOL;
24✔
1967
                else           *fill++ = TSETNUM;
24✔
1968
                while ( *s2 >= 0 ) *fill++ = *s2++;
48✔
1969
                *fill++ = type; while ( *s1 >= 0 ) *fill++ = *s1++;
48✔
1970
        }
1971
        *fill++ = TENDOFIT;
5,513✔
1972
        return(error);
5,513✔
1973
}
1974

1975
/*
1976
                 #] simp4token : 
1977
                 #[ simp5token :
1978

1979
        Making sure that first argument of sumfunction is not a wildcard already
1980
*/
1981

1982
int simp5token(SBYTE *s, int mode)
8,337✔
1983
{
1984
        int error = 0, n, type;
8,337✔
1985
        WORD *w, *wstop;
8,337✔
1986
        if ( mode == RHSIDE ) {
8,337✔
1987
                while ( *s != TENDOFIT ) {
6,105,421✔
1988
                        if ( *s == TFUNCTION ) {
6,099,908✔
1989
                                s++; n = 0; while ( *s >= 0 ) n = 128*n + *s++;
636,931✔
1990
                                if ( n == AM.sumnum || n == AM.sumpnum ) {
212,699✔
1991
                                        if ( *s != TFUNOPEN ) continue;
19✔
1992
                                        s++;
19✔
1993
                                        if ( *s != TSYMBOL && *s != TINDEX ) continue;
19✔
1994
                                        type = *s++;
19✔
1995
                                        n = 0; while ( *s >= 0 ) n = 128*n + *s++;
38✔
1996
                                        if ( type == TINDEX ) n += AM.OffsetIndex;
19✔
1997
                                        if ( *s != TCOMMA ) continue;
19✔
1998
                                        w = AC.ProtoType;
19✔
1999
                                        wstop = w + w[1];
19✔
2000
                                        w += SUBEXPSIZE;
19✔
2001
                                        while ( w < wstop ) {
19✔
2002
                                                if ( w[2] == n ) {
×
2003
                                                        if ( ( type == TSYMBOL && ( w[0] == SYMTOSYM
×
2004
                                                        || w[0] == SYMTONUM || w[0] == SYMTOSUB ) ) || (
×
2005
                                                        type == TINDEX && ( w[0] == INDTOIND
×
2006
                                                        || w[0] == INDTOSUB ) ) ) {
×
2007
                                                                error = 1;
×
2008
                                                                MesPrint("&Parameter of sum function is already a wildcard");
×
2009
                                                        }
2010
                                                }
2011
                                                w += w[1];
×
2012
                                        }
2013
                                }
2014
                        }
2015
                        else s++;
5,887,209✔
2016
                }
2017
        }
2018
        return(error);
8,337✔
2019
}
2020

2021
/*
2022
                 #] simp5token : 
2023
                 #[ simp6token :
2024

2025
        Making sure that factorized expressions are used properly
2026
*/
2027

2028
int simp6token(SBYTE *tokens, int mode)
8,337✔
2029
{
2030
/*        EXPRESSIONS e = Expressions; */
2031
        int error = 0, n;
8,337✔
2032
        int level = 0, haveone = 0;
8,337✔
2033
        SBYTE *s = tokens, *ss;
8,337✔
2034
        LONG numterms;
8,337✔
2035
        WORD funnum = 0;
8,337✔
2036
        GETIDENTITY
5,556✔
2037
        if ( mode == RHSIDE ) {
8,337✔
2038
                while ( *s == TPLUS || *s == TMINUS ) s++;
5,600✔
2039
                numterms = 1;
2040
                while ( *s != TENDOFIT ) {
6,104,770✔
2041
                        if ( *s == LPARENTHESIS ) level++;
100,184✔
2042
                        else if ( *s == RPARENTHESIS ) level--;
100,184✔
2043
                        else if ( *s == TFUNOPEN ) level++;
212,456✔
2044
                        else if ( *s == TFUNCLOSE ) level--;
212,456✔
2045
                        else if ( ( *s == TPLUS || *s == TMINUS ) && level == 0 ) {
5,473,977✔
2046
/*
2047
                                Special exception: x^-1 etc.
2048
*/
2049
                                if ( s[-1] != TPOWER && s[-1] != TPLUS && s[-1] != TMINUS ) {
153,445✔
2050
                                        numterms++;
153,346✔
2051
                                }
2052
                        }
2053
                        else if ( *s == TEXPRESSION ) {
5,320,532✔
2054
                                ss = s;
621✔
2055
                                s++; n = 0; while ( *s >= 0 ) n = 128*n + *s++;
1,242✔
2056

2057
                                if ( Expressions[n].status == STOREDEXPRESSION ) {
621✔
2058
                                        POSITION position;
×
2059
/*
2060
#ifdef WITHPTHREADS
2061
                                        RENUMBER renumber;
2062
#endif
2063
*/
2064
                                        RENUMBER renumber;
×
2065

2066
                                        WORD TMproto[SUBEXPSIZE];
×
2067
                                        TMproto[0] = EXPRESSION;
×
2068
                                        TMproto[1] = SUBEXPSIZE;
×
2069
                                        TMproto[2] = n;
×
2070
                                        TMproto[3] = 1;
×
2071
                                        { int ie; for ( ie = 4; ie < SUBEXPSIZE; ie++ ) TMproto[ie] = 0; }
×
2072
                                        AT.TMaddr = TMproto;
×
2073
                                        PUTZERO(position);
×
2074
/*
2075
                                        if ( (
2076
#ifdef WITHPTHREADS
2077
                                                renumber = 
2078
#endif
2079
                                                        GetTable(n,&position,0) ) == 0 )
2080
*/
2081
                                        if ( ( renumber = GetTable(n,&position,0) ) == 0 )
×
2082
                                        {
2083
                                                error = 1;
×
2084
                                                MesPrint("&Problems getting information about stored expression %s(4)"
×
2085
                                                ,EXPRNAME(n));
×
2086
                                        }
2087
/*
2088
#ifdef WITHPTHREADS
2089
*/
2090
                                        if ( renumber->symb.lo != AN.dummyrenumlist )
×
2091
                                                M_free(renumber->symb.lo,"VarSpace");
×
2092
                                        M_free(renumber,"Renumber");
×
2093
/*
2094
#endif
2095
*/
2096
                                }
2097

2098
                                if ( ( ( AS.Oldvflags[n] & ISFACTORIZED ) != 0 ) && *s != LBRACE ) {
621✔
2099
                                        if ( level == 0 ) {
24✔
2100
                                                haveone = 1;
2101
                                        }
2102
                                        else if ( error == 0 ) {
15✔
2103
                                                if ( ss[-1] != TFUNOPEN || funnum != NUMFACTORS-FUNCTION ) {
15✔
2104
                                                        MesPrint("&Illegal use of factorized expression(s) in RHS");
×
2105
                                                        error = 1;
×
2106
                                                }
2107
                                        }
2108
                                }
2109
                                continue;
621✔
2110
                        }
2111
                        else if ( *s == TFUNCTION ) {
5,319,911✔
2112
                                s++; funnum = 0; while ( *s >= 0 ) funnum = 128*funnum + *s++;
636,931✔
2113
                                continue;
212,699✔
2114
                        }
2115
                        s++;
5,885,937✔
2116
                }
2117
                if ( haveone ) {
5,513✔
2118
                        if ( numterms > 1 ) {
9✔
2119
                                MesPrint("&Factorized expression in RHS in an expression of more than one term.");
×
2120
                                error = 1;
×
2121
                        }
2122
                        else if ( AC.ToBeInFactors == 0 ) {
9✔
2123
                                MesPrint("&Attempt to put a factorized expression inside an unfactorized expression.");
×
2124
                                error = 1;
×
2125
                        }
2126
                }
2127
        }
2128
        return(error);
8,337✔
2129
}
2130

2131
/*
2132
                 #] simp6token : 
2133
        #] Compiler :
2134
*/
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc