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

vermaseren / form / 9364948935

04 Jun 2024 09:49AM UTC coverage: 49.979% (-0.02%) from 49.999%
9364948935

Pull #526

github

web-flow
Merge 7062bd769 into 83e3d4185
Pull Request #526: RFC: better debugging

52 of 415 new or added lines in 46 files covered. (12.53%)

32 existing lines in 2 files now uncovered.

41391 of 82816 relevant lines covered (49.98%)

878690.77 hits per line

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

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

37
#include "form3.h"
38

39
WORD printscratch[2];
40

41
/*
42
          #] Includes : 
43
        #[ Processor :
44
                 #[ Processor :                        WORD Processor()
45
*/
46
/**
47
 *        This is the central processor.
48
 *        It accepts a stream of Expressions which is accessed by calls to GetTerm.
49
 *        The expressions reside either in AR.infile or AR.hidefile
50
 *        The definitions of an expression are seen as an id-statement, so the
51
 *        primary Expressions should be written to the system of scratch files
52
 *        as single terms with an expression pointer. Each expression is terminated
53
 *        with a zero and the whole is terminated by two zeroes.
54
 *
55
 *        The routine DoExecute should determine whether results are to be
56
 *        printed, should revert the scratch I/O directions etc.
57
 *        In principle it is DoExecute that calls Processor.
58
 *
59
 *        @return if everything OK: 0. Otherwise error. The preprocessor
60
 *                may continue with compilation though. Really fatal errors should
61
 *                return on the spot by calling Terminate.
62
 */
63
 
64
WORD Processor(VOID)
3,433✔
65
{
66
        GETIDENTITY
1,010✔
67
        WORD *term, *t, i, retval = 0, size;
3,433✔
68
        EXPRESSIONS e;
3,433✔
69
        POSITION position;
3,433✔
70
        WORD last, LastExpression, fromspectator;
3,433✔
71
        LONG dd = 0;
3,433✔
72
        CBUF *C = cbuf+AC.cbufnum;
3,433✔
73
        int firstterm;
3,433✔
74
        CBUF *CC = cbuf+AT.ebufnum;
3,433✔
75
        WORD **w, *cpo, *cbo;
3,433✔
76
        FILEHANDLE *curfile, *oldoutfile = AR.outfile;
3,433✔
77
        WORD oldBracketOn = AR.BracketOn;
3,433✔
78
        WORD *oldBrackBuf = AT.BrackBuf;
3,433✔
79
        WORD oldbracketindexflag = AT.bracketindexflag;
3,433✔
80
#ifdef WITHPTHREADS
81
        int OldMultiThreaded = AS.MultiThreaded, Oldmparallelflag = AC.mparallelflag;
1,010✔
82
#endif
83
        if ( CC->numrhs > 0 || CC->numlhs > 0 ) {
3,433✔
84
                if ( CC->rhs ) {
×
85
                        w = CC->rhs; i = CC->numrhs;
86
                        do { *w++ = 0; } while ( --i > 0 );
×
87
                }
88
                if ( CC->lhs ) {
×
89
                        w = CC->lhs; i = CC->numlhs;
×
90
                        do { *w++ = 0; } while ( --i > 0 );
×
91
                }
92
                CC->numlhs = CC->numrhs = 0;
×
93
                ClearTree(AT.ebufnum);
×
94
                CC->Pointer = CC->Buffer;
×
95
        }
96

97
        if ( NumExpressions == 0 ) return(0);
3,433✔
98
        AR.expflags = 0;
3,247✔
99
        AR.CompressPointer = AR.CompressBuffer;
3,247✔
100
        AR.NoCompress = AC.NoCompress;
3,247✔
101
        term = AT.WorkPointer;
3,247✔
102
        if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer) ) > AT.WorkTop ) return(MesWork());
3,247✔
103
        UpdatePositions();
3,247✔
104
        C->rhs[C->numrhs+1] = C->Pointer;
3,247✔
105
        AR.KeptInHold = 0;
3,247✔
106
        if ( AC.CollectFun ) AR.DeferFlag = 0;
3,247✔
107
        AR.outtohide = 0;
3,247✔
108
        AN.PolyFunTodo = 0;
3,247✔
109
#ifdef HIDEDEBUG
110
        MesPrint("Status at the start of Processor (HideLevel = %d)",AC.HideLevel);
111
        for ( i = 0; i < NumExpressions; i++ ) {
112
                e = Expressions+i;
113
                ExprStatus(e);
114
        }
115
#endif
116
/*
117
                Next determine the last expression. This is used for removing the
118
                input file when the final stage of the sort of this expression is
119
                reached. That can save up to 1/3 in disk space.
120
*/
121
        for ( i = NumExpressions-1; i >= 0; i-- ) {
4,037✔
122
                e = Expressions+i;
3,981✔
123
                if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
3,981✔
124
                || e->status == HIDELEXPRESSION || e->status == HIDEGEXPRESSION
881✔
125
                || e->status == SKIPLEXPRESSION || e->status == SKIPGEXPRESSION
804✔
126
                || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
804✔
127
                || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION
797✔
128
                ) break;
129
        }
130
        last = i;
21,227✔
131
        for ( i = NumExpressions-1; i >= 0; i-- ) {
21,227✔
132
                AS.OldOnFile[i] = Expressions[i].onfile;
17,980✔
133
                AS.OldNumFactors[i] = Expressions[i].numfactors;
17,980✔
134
/*                AS.Oldvflags[i] = e[i].vflags; */
135
                AS.Oldvflags[i] = Expressions[i].vflags;
17,980✔
136
                AS.Olduflags[i] = Expressions[i].uflags;
17,980✔
137
                Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
17,980✔
138
        }
139
#ifdef WITHPTHREADS
140
/*
141
                When we run with threads we have to make sure that all local input
142
                buffers are pointed correctly. Of course this isn't needed if we
143
                run on a single thread only.
144
*/
145
        if ( AC.partodoflag && AM.totalnumberofthreads > 1 ) {
956✔
146
                AS.MultiThreaded = 1; AC.mparallelflag = PARALLELFLAG;
2✔
147
        }
148
        if ( AS.MultiThreaded && AC.mparallelflag == PARALLELFLAG ) {
956✔
149
                SetWorkerFiles();
932✔
150
        }
151
/*
152
                We start with running the expressions with expr->partodo in parallel.
153
                The current model is: give each worker an expression. Wait for 
154
                workers to finish and tell them where to write.
155
                Then give them a new expression. Workers may have to wait for each
156
                other. This is also the case with the last one.
157
*/
158
        if ( AS.MultiThreaded && AC.mparallelflag == PARALLELFLAG ) {
956✔
159
                if ( InParallelProcessor() ) {
932✔
160
                        retval = 1;
161
                }
162
                AS.MultiThreaded = OldMultiThreaded;
932✔
163
                AC.mparallelflag = Oldmparallelflag;
932✔
164
        }
165
#endif
166
#ifdef WITHMPI
167
         if ( AC.RhsExprInModuleFlag && PF.rhsInParallel && (AC.mparallelflag == PARALLELFLAG || AC.partodoflag) ) {
1,812✔
168
                if ( PF_BroadcastRHS() ) {
196✔
169
                        retval = -1;
170
                }
171
        }
172
        PF.exprtodo = -1; /* This means, the slave does not perform inparallel */
1,812✔
173
        if ( AC.partodoflag > 0 ) {
1,812✔
174
                if ( PF_InParallelProcessor() ) {
4✔
175
                        retval = -1;
176
                }
177
        }
178
#endif
179
        for ( i = 0; i < NumExpressions; i++ ) {
21,179✔
180
#ifdef INNERTEST
181
                if ( AC.InnerTest ) {
182
                        if ( StrCmp(AC.TestValue,(UBYTE *)INNERTEST) == 0 ) {
183
                                MesPrint("Testing(Processor): value = %s",AC.TestValue);
184
                        }
185
                }
186
#endif
187
                e = Expressions+i;
17,962✔
188
#ifdef WITHPTHREADS
189
                if ( AC.partodoflag > 0 && e->partodo > 0 && AM.totalnumberofthreads > 2 ) {
5,176✔
190
                        e->partodo = 0;
2✔
191
                        continue;
2✔
192
                }
193
#endif
194
#ifdef WITHMPI
195
                if ( AC.partodoflag > 0 && e->partodo > 0 && PF.numtasks > 2 ) {
10,180✔
196
                        e->partodo = 0;
4✔
197
                        continue;
4✔
198
                }
199
#endif
200
                AS.CollectOverFlag = 0;
17,956✔
201
                AR.expchanged = 0;
17,956✔
202
                if ( i == last ) LastExpression = 1;
17,956✔
203
                else             LastExpression = 0;
14,774✔
204
                if ( e->inmem ) {
17,956✔
205
/*
206
                        #[ in memory : Memory allocated by poly.c only thusfar.
207
                                       Here GetTerm cannot work.
208
                                       For the moment we ignore this for parallelization.
209
*/
210
                        WORD j;
×
211

212
                        AR.GetFile = 0;
×
213
                        SetScratch(AR.infile,&(e->onfile));
×
214
                        if ( GetTerm(BHEAD term) <= 0 ) {
×
215
                                MesPrint("(1) Expression %d has problems in scratchfile",i);
×
216
                                retval = -1;
×
217
                                break;
×
218
                        }
219
                        term[3] = i;
×
220
                        AR.CurExpr = i;
×
221
                        SeekScratch(AR.outfile,&position);
×
222
                        e->onfile = position;
×
223
                        if ( PutOut(BHEAD term,&position,AR.outfile,0) < 0 ) goto ProcErr;
×
224
                        AR.DeferFlag = AC.ComDefer;
×
225
                        NewSort(BHEAD0);
×
226
                        AN.ninterms = 0;
×
227
                        t = e->inmem;
×
228
                        while ( *t ) {
×
229
                                for ( j = 0; j < *t; j++ ) term[j] = t[j];
×
230
                                t += *t;
×
231
                                AN.ninterms++; dd = AN.deferskipped;
×
232
                                if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)(sizeof(WORD)))) ) {
×
233
                                        if ( GetMoreFromMem(term,&t) ) {
×
234
                                                LowerSortLevel(); goto ProcErr;
×
235
                                        }
236
                                }
237
                                AT.WorkPointer = term + *term;
×
238
                                AN.RepPoint = AT.RepCount + 1;
×
239
                                AN.IndDum = AM.IndDum;
×
240
                                AR.CurDum = ReNumber(BHEAD term);
×
241
                                if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
×
242
                                if ( AN.ncmod ) {
×
243
                                        if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
×
244
                                        else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
×
245
                                }
246
                            else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
×
247
                                if ( Generator(BHEAD term,0) ) {
×
248
                                        LowerSortLevel(); goto ProcErr;
×
249
                                }
250
                                AN.ninterms += dd;
×
251
                        }
252
                        AN.ninterms += dd;
×
253
                        if ( EndSort(BHEAD AM.S0->sBuffer,0) < 0 ) goto ProcErr;
×
254
                        if ( AM.S0->TermsLeft ) e->vflags &= ~ISZERO;
×
255
                        else e->vflags |= ISZERO;
×
256
                        if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
×
257
                                if ( AM.S0->TermsLeft ) AR.expflags |= ISZERO;
×
258
                        if ( AR.expchanged ) AR.expflags |= ISUNMODIFIED;
×
259
                        AR.GetFile = 0;
×
260
/*
261
                        #] in memory : 
262
*/
263
                }
264
                else {
265
                        AR.CurExpr = i;
17,956✔
266
                        switch ( e->status ) {
17,956✔
267
                        case UNHIDELEXPRESSION:
7✔
268
                        case UNHIDEGEXPRESSION:
269
                                AR.GetFile = 2;
7✔
270
#ifdef WITHMPI
271
                    if ( PF.me == MASTER ) SetScratch(AR.hidefile,&(e->onfile));
4✔
272
#else
273
                                SetScratch(AR.hidefile,&(e->onfile));
3✔
274
                                AR.InHiBuf = AR.hidefile->POfull-AR.hidefile->POfill;
3✔
275
#ifdef HIDEDEBUG
276
                                MesPrint("Hidefile: onfile: %15p, POposition: %15p, filesize: %15p",&(e->onfile)
277
                                ,&(AR.hidefile->POposition),&(AR.hidefile->filesize));
278
                                MesPrint("Set hidefile to buffer position %l/%l; AR.InHiBuf = %l"
279
                                        ,(AR.hidefile->POfill-AR.hidefile->PObuffer)*sizeof(WORD)
280
                                        ,(AR.hidefile->POfull-AR.hidefile->PObuffer)*sizeof(WORD)
281
                                        ,AR.InHiBuf
282
                                );
283
#endif
284
#endif
285
                                curfile = AR.hidefile;
7✔
286
                                goto commonread;
7✔
287
                        case INTOHIDELEXPRESSION:
7✔
288
                        case INTOHIDEGEXPRESSION:
289
                                AR.outtohide = 1;
7✔
290
/*
291
                                BugFix 12-feb-2016
292
                                This may not work when the file is open and we move around.
293
                                AR.hidefile->POfill = AR.hidefile->POfull;
294
*/
295
                                SetEndHScratch(AR.hidefile,&position);
7✔
296
                                /* fall through */
297
                        case LOCALEXPRESSION:
14,716✔
298
                        case GLOBALEXPRESSION:
299
                                AR.GetFile = 0;
14,716✔
300
/*[20oct2009 mt]:*/
301
#ifdef WITHMPI
302
                                if( ( PF.me == MASTER ) || (PF.mkSlaveInfile) )
8,328✔
303
#endif
304
                SetScratch(AR.infile,&(e->onfile));
9,349✔
305
/*:[20oct2009 mt]*/
306
                                curfile = AR.infile;
14,716✔
307
commonread:;
14,723✔
308
#ifdef WITHMPI
309
                                if ( PF_Processor(e,i,LastExpression) ) {
8,332✔
310
                                        MesPrint("Error in PF_Processor");
311
                                        goto ProcErr;
312
                                }
313
/*[20oct2009 mt]:*/
314
                                if ( AC.mparallelflag != PARALLELFLAG ){
8,332✔
315
                                        if(PF.me != MASTER)
104✔
316
                                                break;
317
#endif
318
/*:[20oct2009 mt]*/
319
                                if ( GetTerm(BHEAD term) <= 0 ) {
6,417✔
320
#ifdef HIDEDEBUG
321
                                        MesPrint("Error condition 1a");
322
                                        ExprStatus(e);
323
#endif
324
                                        MesPrint("(2) Expression %d has problems in scratchfile(process)",i);
×
325
                                        retval = -1;
×
326
                                        break;
×
327
                                }
328
                                term[3] = i;
6,417✔
329
                                if ( term[5] < 0 ) {        /* Fill with spectator */
6,417✔
330
                                        fromspectator = -term[5];
8✔
331
                                        PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
8✔
332
                                        term[5] = AC.cbufnum;
8✔
333
                                }
334
                                else fromspectator = 0;
335
                                if ( AR.outtohide ) {
6,417✔
336
                                        SeekScratch(AR.hidefile,&position);
3✔
337
                                        e->onfile = position;
3✔
338
                                        if ( PutOut(BHEAD term,&position,AR.hidefile,0) < 0 ) goto ProcErr;
3✔
339
                                }
340
                                else {
341
                                        SeekScratch(AR.outfile,&position);
6,414✔
342
                                        e->onfile = position;
6,414✔
343
                                        if ( PutOut(BHEAD term,&position,AR.outfile,0) < 0 ) goto ProcErr;
6,414✔
344
                                }
345
                                AR.DeferFlag = AC.ComDefer;
6,417✔
346
                                AR.Eside = RHSIDE;
6,417✔
347
                                if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
6,417✔
348
                                        AR.BracketOn = 1;
69✔
349
                                        AT.BrackBuf = AM.BracketFactors;
69✔
350
                                        AT.bracketindexflag = 1;
69✔
351
                                }
352
                                if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
6,417✔
353
#ifdef WITHPTHREADS
354
                                if ( AS.MultiThreaded && AC.mparallelflag == PARALLELFLAG ) {
4,248✔
355
                                        if ( ThreadsProcessor(e,LastExpression,fromspectator) ) {
4,218✔
356
                                                MesPrint("Error in ThreadsProcessor");
357
                                                goto ProcErr;
358
                                        }
359
                                        if ( AR.outtohide ) {
4,198✔
360
                                                AR.outfile = oldoutfile;
2✔
361
                                                AR.hidefile->POfull = AR.hidefile->POfill;
2✔
362
                                        }
363
                                }
364
                                else
365
#endif
366
                                {
367
                                        NewSort(BHEAD0);
2,199✔
368
                                        AR.MaxDum = AM.IndDum;
2,199✔
369
                                        AN.ninterms = 0;
2,199✔
370
                                        for(;;) {
85,965✔
371
                                         if ( fromspectator ) size = GetFromSpectator(term,fromspectator-1);
85,965✔
372
                                         else                 size = GetTerm(BHEAD term);
85,959✔
373
                                         if ( size <= 0 ) break;
85,965✔
374
                                         SeekScratch(curfile,&position);
83,776✔
375
                                         if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
83,776✔
376
                                          StoreTerm(BHEAD term);
×
377
                                         }
378
                                         else {
379
                                          AN.ninterms++; dd = AN.deferskipped;
83,776✔
380
                                          if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)(sizeof(WORD)))) ) {
83,776✔
381
                                                if ( GetMoreTerms(term) < 0 ) {
83✔
382
                                                  LowerSortLevel(); goto ProcErr;
×
383
                                                }
384
                                            SeekScratch(curfile,&position);
83✔
385
                                          }
386
                                          AT.WorkPointer = term + *term;
83,776✔
387
                                          AN.RepPoint = AT.RepCount + 1;
83,776✔
388
                                          if ( AR.DeferFlag ) {
83,776✔
389
                                                AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
42✔
390
                                                AR.CurDum = AN.IndDum;
42✔
391
                                          }
392
                                          else {
393
                                                AN.IndDum = AM.IndDum;
83,734✔
394
                                                AR.CurDum = ReNumber(BHEAD term);
83,734✔
395
                                          }
396
                                          if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
83,776✔
397
                                          if ( AN.ncmod ) {
83,776✔
398
                                                if ( ( AC.modmode & ALSOFUNARGS ) != 0 ) MarkDirty(term,DIRTYFLAG);
1✔
399
                                                else if ( AR.PolyFun ) PolyFunDirty(BHEAD term);
1✔
400
                                          }
401
                                          else if ( AC.PolyRatFunChanged ) PolyFunDirty(BHEAD term);
83,775✔
402
                                          if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
83,776✔
403
                                                && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
710✔
404
                                                PolyFunClean(BHEAD term);
710✔
405
                                          }
406
                                          if ( Generator(BHEAD term,0) ) {
83,776✔
407
                                                LowerSortLevel(); goto ProcErr;
2✔
408
                                          }
409
                                          AN.ninterms += dd;
83,766✔
410
                                         }
411
                                         SetScratch(curfile,&position);
83,766✔
412
                                         if ( AR.GetFile == 2 ) {
83,766✔
413
                                                AR.InHiBuf = (curfile->POfull-curfile->PObuffer)
1✔
414
                                                        -DIFBASE(position,curfile->POposition)/sizeof(WORD);
1✔
415
                                         }
416
                                         else {
417
                                                AR.InInBuf = (curfile->POfull-curfile->PObuffer)
83,765✔
418
                                                        -DIFBASE(position,curfile->POposition)/sizeof(WORD);
83,765✔
419
                                         }
420
                                        }
421
                                        AN.ninterms += dd;
2,189✔
422
                                        if ( LastExpression ) {
2,189✔
423
                                                UpdateMaxSize();
496✔
424
                                                if ( AR.infile->handle >= 0 ) {
496✔
425
                                                        CloseFile(AR.infile->handle);
2✔
426
                                                        AR.infile->handle = -1;
2✔
427
                                                        remove(AR.infile->name);
2✔
428
                                                        PUTZERO(AR.infile->POposition);
2✔
429
                                                }
430
                                                AR.infile->POfill = AR.infile->POfull = AR.infile->PObuffer;
496✔
431
                                        }
432
                                        if ( AR.outtohide ) AR.outfile = AR.hidefile;
2,189✔
433
                                        if ( EndSort(BHEAD AM.S0->sBuffer,0) < 0 ) goto ProcErr;
2,189✔
434
                                        if ( AR.outtohide ) {
2,189✔
435
                                                AR.outfile = oldoutfile;
1✔
436
                                                AR.hidefile->POfull = AR.hidefile->POfill;
1✔
437
                                        }
438
                                        e->numdummies = AR.MaxDum - AM.IndDum;
2,189✔
439
                                        UpdateMaxSize();
2,189✔
440
                                }
441
                                AR.BracketOn = oldBracketOn;
6,387✔
442
                                AT.BrackBuf = oldBrackBuf;
6,387✔
443
                                if ( ( e->vflags & TOBEFACTORED ) != 0 ) {
6,387✔
444
                                        poly_factorize_expression(e);
27✔
445
                                }
446
                                else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
6,360✔
447
                                 && ( ( e->vflags & ISFACTORIZED ) != 0 ) ) {
6,360✔
448
                                        poly_unfactorize_expression(e);
3✔
449
                                }
450
                                AT.bracketindexflag = oldbracketindexflag;
6,387✔
451
                                if ( AM.S0->TermsLeft )   e->vflags &= ~ISZERO;
6,387✔
452
                                else                      e->vflags |= ISZERO;
1,378✔
453
                                if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
6,387✔
454
                                if ( AM.S0->TermsLeft ) AR.expflags |= ISZERO;
6,387✔
455
                                if ( AR.expchanged )    AR.expflags |= ISUNMODIFIED;
6,387✔
456
                                AR.GetFile = 0;
6,387✔
457
                                AR.outtohide = 0;
6,387✔
458
/*[20oct2009 mt]:*/
459
#ifdef WITHMPI
460
                                }
461
#endif
462
#ifdef WITHPTHREADS
463
                                if ( e->status == INTOHIDELEXPRESSION ||
4,228✔
464
                                         e->status == INTOHIDEGEXPRESSION ) {
465
                                        SetHideFiles();
2✔
466
                                }
467
#endif
468
                                break;
2,133✔
469
                        case SKIPLEXPRESSION:
×
470
                        case SKIPGEXPRESSION:
471
/*
472
                                This can be greatly improved of course by file-to-file copy.
473
*/
474
#ifdef WITHMPI
475
                                if ( PF.me != MASTER ) break;
476
#endif
477
                                AR.GetFile = 0;
×
478
                                SetScratch(AR.infile,&(e->onfile));
×
479
                                if ( GetTerm(BHEAD term) <= 0 ) {
×
480
#ifdef HIDEDEBUG
481
                                        MesPrint("Error condition 1b");
482
                                        ExprStatus(e);
483
#endif
484
                                        MesPrint("(3) Expression %d has problems in scratchfile",i);
×
485
                                        retval = -1;
×
486
                                        break;
×
487
                                }
488
                                term[3] = i;
×
489
                                AR.DeferFlag = 0;
×
490
                                SeekScratch(AR.outfile,&position);
×
491
                                e->onfile = position;
×
492
                                *AM.S0->sBuffer = 0; firstterm = -1;
×
493
                                do {
×
494
                                        WORD *oldipointer = AR.CompressPointer;
×
495
                                        WORD *comprtop = AR.ComprTop;
×
496
                                        AR.ComprTop = AM.S0->sTop;
×
497
                                        AR.CompressPointer = AM.S0->sBuffer;
×
498
                                        if ( firstterm > 0 ) {
×
499
                                                if ( PutOut(BHEAD term,&position,AR.outfile,1) < 0 ) goto ProcErr;
×
500
                                        }
501
                                        else if ( firstterm < 0 ) {
×
502
                                                if ( PutOut(BHEAD term,&position,AR.outfile,0) < 0 ) goto ProcErr;
×
503
                                                firstterm++;
×
504
                                        }
505
                                        else {
506
                                                if ( PutOut(BHEAD term,&position,AR.outfile,-1) < 0 ) goto ProcErr;
×
507
                                                firstterm++;
×
508
                                        }
509
                                        AR.CompressPointer = oldipointer;
×
510
                                        AR.ComprTop = comprtop;
×
511
                                } while ( GetTerm(BHEAD term) );
×
512
                                if ( FlushOut(&position,AR.outfile,1) ) goto ProcErr;
×
513
                                UpdateMaxSize();
×
514
                                break;
×
515
                        case HIDELEXPRESSION:
91✔
516
                        case HIDEGEXPRESSION:
517
#ifdef WITHMPI
518
                                if ( PF.me != MASTER ) break;
52✔
519
#endif
520
                                AR.GetFile = 0;
52✔
521
                                SetScratch(AR.infile,&(e->onfile));
52✔
522
                                if ( GetTerm(BHEAD term) <= 0 ) {
52✔
523
#ifdef HIDEDEBUG
524
                                        MesPrint("Error condition 1c");
525
                                        ExprStatus(e);
526
#endif
527
                                        MesPrint("(4) Expression %d has problems in scratchfile",i);
×
528
                                        retval = -1;
×
529
                                        break;
×
530
                                }
531
                                term[3] = i;
52✔
532
                                AR.DeferFlag = 0;
52✔
533
                                SetEndHScratch(AR.hidefile,&position);
52✔
534
                                e->onfile = position;
52✔
535
#ifdef HIDEDEBUG
536
                                if ( AR.hidefile->handle >= 0 ) {
537
                                        POSITION possize,pos;
538
                                        PUTZERO(possize);
539
                                        PUTZERO(pos);
540
                                        SeekFile(AR.hidefile->handle,&pos,SEEK_CUR);
541
                                        SeekFile(AR.hidefile->handle,&possize,SEEK_END);
542
                                        SeekFile(AR.hidefile->handle,&pos,SEEK_SET);
543
                                        MesPrint("Processor Hide1: filesize(th) = %12p, filesize(ex) = %12p",&(position),
544
                                                        &(possize));
545
                                        MesPrint("    in buffer: %l",(AR.hidefile->POfill-AR.hidefile->PObuffer)*sizeof(WORD));
546
                                }
547
#endif
548
                                *AM.S0->sBuffer = 0; firstterm = -1;
52✔
549
                                cbo = cpo = AM.S0->sBuffer;
52✔
550
                                do {
2,236✔
551
                                        WORD *oldipointer = AR.CompressPointer;
2,236✔
552
                                        WORD *oldibuffer = AR.CompressBuffer;
2,236✔
553
                                        WORD *comprtop = AR.ComprTop;
2,236✔
554
                                        AR.ComprTop = AM.S0->sTop;
2,236✔
555
                                        AR.CompressPointer = cpo;
2,236✔
556
                                        AR.CompressBuffer = cbo;
2,236✔
557
                                        if ( firstterm > 0 ) {
2,236✔
558
                                                if ( PutOut(BHEAD term,&position,AR.hidefile,1) < 0 ) goto ProcErr;
2,132✔
559
                                        }
560
                                        else if ( firstterm < 0 ) {
104✔
561
                                                if ( PutOut(BHEAD term,&position,AR.hidefile,0) < 0 ) goto ProcErr;
52✔
562
                                                firstterm++;
52✔
563
                                        }
564
                                        else {
565
                                                if ( PutOut(BHEAD term,&position,AR.hidefile,-1) < 0 ) goto ProcErr;
52✔
566
                                                firstterm++;
52✔
567
                                        }
568
                                        cpo = AR.CompressPointer;
2,236✔
569
                                        cbo = AR.CompressBuffer;
2,236✔
570
                                        AR.CompressPointer = oldipointer;
2,236✔
571
                                        AR.CompressBuffer = oldibuffer;
2,236✔
572
                                        AR.ComprTop = comprtop;
2,236✔
573
                                } while ( GetTerm(BHEAD term) );
2,236✔
574
#ifdef HIDEDEBUG
575
                                if ( AR.hidefile->handle >= 0 ) {
576
                                        POSITION possize,pos;
577
                                        PUTZERO(possize);
578
                                        PUTZERO(pos);
579
                                        SeekFile(AR.hidefile->handle,&pos,SEEK_CUR);
580
                                        SeekFile(AR.hidefile->handle,&possize,SEEK_END);
581
                                        SeekFile(AR.hidefile->handle,&pos,SEEK_SET);
582
                                        MesPrint("Processor Hide2: filesize(th) = %12p, filesize(ex) = %12p",&(position),
583
                                                        &(possize));
584
                                        MesPrint("    in buffer: %l",(AR.hidefile->POfill-AR.hidefile->PObuffer)*sizeof(WORD));
585
                                }
586
#endif
587
                                if ( FlushOut(&position,AR.hidefile,1) ) goto ProcErr;
52✔
588
                                AR.hidefile->POfull = AR.hidefile->POfill;
52✔
589
#ifdef HIDEDEBUG
590
                                if ( AR.hidefile->handle >= 0 ) {
591
                                        POSITION possize,pos;
592
                                        PUTZERO(possize);
593
                                        PUTZERO(pos);
594
                                        SeekFile(AR.hidefile->handle,&pos,SEEK_CUR);
595
                                        SeekFile(AR.hidefile->handle,&possize,SEEK_END);
596
                                        SeekFile(AR.hidefile->handle,&pos,SEEK_SET);
597
                                        MesPrint("Processor Hide3: filesize(th) = %12p, filesize(ex) = %12p",&(position),
598
                                                        &(possize));
599
                                        MesPrint("    in buffer: %l",(AR.hidefile->POfill-AR.hidefile->PObuffer)*sizeof(WORD));
600
                                }
601
#endif
602
/*
603
                                Because we direct the e->onfile already to the hide file, we
604
                                need to change the status of the expression. Otherwise the use
605
                                of parts (or the whole) of the expression looks in the infile
606
                                while the position is that of the hide file.
607
                                We choose to get everything from the hide file. On average that
608
                                should give least file activity.
609
*/
610
                                if ( e->status == HIDELEXPRESSION ) {
52✔
611
                                        e->status = HIDDENLEXPRESSION;
52✔
612
                                        AS.OldOnFile[i] = e->onfile;
52✔
613
                                        AS.OldNumFactors[i] = Expressions[i].numfactors;
52✔
614
                                }
615
                                if ( e->status == HIDEGEXPRESSION ) {
52✔
616
                                        e->status = HIDDENGEXPRESSION;
×
617
                                        AS.OldOnFile[i] = e->onfile;
×
618
                                        AS.OldNumFactors[i] = Expressions[i].numfactors;
×
619
                                }
620
#ifdef WITHPTHREADS
621
                                SetHideFiles();
26✔
622
#endif
623
                                UpdateMaxSize();
52✔
624
                                break;
52✔
625
                        case DROPPEDEXPRESSION:
626
                        case DROPLEXPRESSION:
627
                        case DROPGEXPRESSION:
628
                        case DROPHLEXPRESSION:
629
                        case DROPHGEXPRESSION:
630
                        case STOREDEXPRESSION:
631
                        case HIDDENLEXPRESSION:
632
                        case HIDDENGEXPRESSION:
633
                        case SPECTATOREXPRESSION:
634
                        default:
635
                                break;
636
                }
637
                }
117✔
638
                AR.KeptInHold = 0;
17,926✔
639
        }
640
        AR.DeferFlag = 0;
3,217✔
641
        AT.WorkPointer = term;
3,217✔
642
#ifdef HIDEDEBUG
643
        MesPrint("Status at the end of Processor (HideLevel = %d)",AC.HideLevel);
644
        for ( i = 0; i < NumExpressions; i++ ) {
645
                e = Expressions+i;
646
                ExprStatus(e);
647
        }
648
#endif
649
        return(retval);
3,217✔
650
ProcErr:
2✔
651
        AT.WorkPointer = term;
2✔
652
        if ( AM.tracebackflag ) MesCall("Processor");
2✔
653
        return(-1);
654
}
655
/*
656
                 #] Processor : 
657
                 #[ TestSub :                        WORD TestSub(term,level)
658
*/
659
/**
660
 *        TestSub hunts for subexpression pointers.
661
 *        If one is found its power is given in AN.TeSuOut.
662
 *        and the returnvalue is 'expressionnumber'.
663
 *        If the expression number is negative it is an expression on disk.
664
 *
665
 *        In addition this routine tries to locate subexpression pointers
666
 *        in functions. It also notices that action must be taken with any
667
 *        of the special functions.
668
 *
669
 *        @param  term  The term in which TestSub hunts for potential action
670
 *        @param  level The number of the 'level' in the compiler buffer.
671
 *        @return The number of the (sub)expression that was encountered.
672
 *
673
 *        Other values that are returned are in AN.TeSuOut, AR.TePos, AT.TMbuff,
674
 *                AN.TeInFun, AN.Frozen, AT.TMaddr 
675
 *
676
 *        The level in the compiler buffer is more or less the number of the
677
 *        statement in the module. Hence it refers to the element in the lhs array.
678
 *
679
 *        This routine is one of the most important routines in FORM.
680
 */
681

682
#define DONE(x) { retvalue = x; goto Done; }
683

684
WORD TestSub(PHEAD WORD *term, WORD level)
37,041,840✔
685
{
686
        GETBIDENTITY
687
        WORD *m, *t, *r, retvalue = 0, funflag, j, oldncmod, nexpr, *Tpattern = 0;
37,041,840✔
688
        WORD *stop, *t1, *t2, funnum, wilds, tbufnum, stilldirty = 0;
37,041,840✔
689
        NESTING n;
37,041,840✔
690
        CBUF *C = cbuf+AT.ebufnum;
37,041,840✔
691
        LONG isp, i;
37,041,840✔
692
        TABLES T;
37,041,840✔
693
        COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
37,041,840✔
694
        WORD oldsorttype = AR.SortType;
37,041,840✔
695
ReStart:
1,088,511✔
696
        tbufnum = 0; i = 0; retvalue = 0;
38,130,350✔
697
        AT.TMbuff = AM.rbufnum;
38,130,350✔
698
        funflag = 0;
38,130,350✔
699
        t = term;
38,130,350✔
700
        r = t + *t - 1;
38,130,350✔
701
        m = r - ABS(*r) + 1;
38,130,350✔
702
        t++;
38,130,350✔
703
        if ( t < m ) do {
38,130,350✔
704
                if ( *t == SUBEXPRESSION ) {
165,489,500✔
705
                        /*
706
                                Subexpression encountered
707
                                There may be more than one.
708
                                The old strategy was to take the last.
709
                                A newer strategy was to take the lowest power first.
710
                                The current strategy is that we compute the number of terms
711
                                generated by this subexpression and take the minimum of that.
712
                        */
713

714
#ifdef WHICHSUBEXPRESSION
715

716
                        WORD *tmin = t, AN.nbino;
717
/*                        LONG minval = MAXLONG; */
718
                        LONG minval = -1;
719
                        LONG mm, mnum1 = 1;
720
                        if ( AN.BinoScrat == 0 ) {
721
                                AN.BinoScrat = (UWORD *)Malloc1((AM.MaxTal+2)*sizeof(UWORD),"GetBinoScrat");
722
                        }
723
#endif
724
                        if ( t[3] ) {
5,869,020✔
725
                                r = t + t[1];
5,869,020✔
726
                                while ( AN.subsubveto == 0 &&
30,424,780✔
727
                                                        *r == SUBEXPRESSION && r < m && r[3] ) {
29,211,510✔
728
#ifdef WHICHSUBEXPRESSION
729
                                        mnum1++;
730
#endif
731
                                        if ( r[1] == t[1] && r[2] == t[2] && r[4] == t[4] ) {
24,555,740✔
732
                                                j = t[1] - SUBEXPSIZE;
24,519,400✔
733
                                                t1 = t + SUBEXPSIZE;
24,519,400✔
734
                                                t2 = r + SUBEXPSIZE;
24,519,400✔
735
                                                while ( j > 0 && *t1++ == *t2++ ) j--;
98,082,400✔
736
                                                if ( j <= 0 ) {
24,519,400✔
737
                                                        t[3] += r[3];
7,944✔
738
                                                        if ( t[3] == 0 ) {
7,944✔
739
                                                                t1 = r + r[1];
×
740
                                                                t2 = term + *term;
×
741
                                                                *term -= r[1]+t[1];
×
742
                                                                r = t;
×
743
                                                                while ( t1 < t2 ) *r++ = *t1++;
×
744
                                                                goto ReStart;
×
745
                                                        }
746
                                                        else {
747
                                                                t1 = r + r[1];
7,944✔
748
                                                                t2 = term + *term;
7,944✔
749
                                                                *term -= r[1];
7,944✔
750
                                                                m -= r[1];
7,944✔
751
                                                                while ( t1 < t2 ) *r++ = *t1++;
212,580✔
752
                                                                r = t;
753
                                                        }
754
                                                }
755
                                        }
756
#ifdef WHICHSUBEXPRESSION
757

758
                                        else if ( t[2] >= 0 ) {
759
/*
760
                                                Compute Binom(numterms+power-1,power-1)
761
                                                We need potentially long arithmetic.
762
                                                That is why we had to allocate AN.BinoScrat
763
*/
764
                                                if ( AN.last1 == t[3] && AN.last2 == cbuf[t[4]].NumTerms[t[2]] + t[3] - 1 ) {
765
                                                        if ( AN.last3 > minval ) {
766
                                                                minval = AN.last3; tmin = t;
767
                                                        }
768
                                                }
769
                                                else {
770
                                                AN.last1 = t[3]; mm = AN.last2 = cbuf[t[4]].NumTerms[t[2]] + t[3] - 1;
771
                                                if ( t[3] == 1 ) {
772
                                                        if ( mm > minval ) {
773
                                                                minval = mm; tmin = t;
774
                                                        }
775
                                                }
776
                                                else if ( t[3] > 0 ) {
777
                                                        if ( mm > MAXPOSITIVE ) goto TooMuch;
778
                                                        GetBinom(AN.BinoScrat,&AN.nbino,(WORD)mm,t[3]);
779
                                                        if ( AN.nbino > 2 ) goto TooMuch;
780
                                                        if ( AN.nbino == 2 ) {
781
                                                                mm = AN.BinoScrat[1];
782
                                                                mm = ( mm << BITSINWORD ) + AN.BinoScrat[0];
783
                                                        }
784
                                                        else if ( AN.nbino == 1 ) mm = AN.BinoScrat[0];
785
                                                        else mm = 0;
786
                                                        if ( mm > minval ) {
787
                                                                minval = mm; tmin = t;
788
                                                        }
789
                                                }
790
                                                AN.last3 = mm;
791
                                                }
792
                                        }
793
#endif
794
                                        t = r;
24,555,740✔
795
                                        r += r[1];
24,555,740✔
796
                                }
797
#ifdef WHICHSUBEXPRESSION
798
                                if ( mnum1 > 1 && t[2] >= 0 ) {
799
/*
800
                                        To keep the flowcontrol simple we duplicate some code here
801
*/
802
                                        if ( AN.last1 == t[3] && AN.last2 == cbuf[t[4]].NumTerms[t[2]] + t[3] - 1 ) {
803
                                                if ( AN.last3 > minval ) {
804
                                                        minval = AN.last3; tmin = t;
805
                                                }
806
                                        }
807
                                        else {
808
                                        AN.last1 = t[3]; mm = AN.last2 = cbuf[t[4]].NumTerms[t[2]] + t[3] - 1;
809
                                        if ( t[3] == 1 ) {
810
                                                if ( mm > minval ) {
811
                                                        minval = mm; tmin = t;
812
                                                }
813
                                        }
814
                                        else if ( t[3] > 0 ) {
815
                                                if ( mm > MAXPOSITIVE ) {
816
/*
817
                                                        We will generate more terms than we can count
818
*/
819
TooMuch:;
820
                                                        MLOCK(ErrorMessageLock);
821
                                                        MesPrint("Attempt to generate more terms than FORM can count");
822
                                                        MUNLOCK(ErrorMessageLock);
823
                                                        TERMINATE(-1);
824
                                                }
825
                                                GetBinom(AN.BinoScrat,&AN.nbino,(WORD)mm,t[3]);
826
                                                if ( AN.nbino > 2 ) goto TooMuch;
827
                                                if ( AN.nbino == 2 ) {
828
                                                        mm = AN.BinoScrat[1];
829
                                                        mm = ( mm << BITSINWORD ) + AN.BinoScrat[0];
830
                                                }
831
                                                else if ( AN.nbino == 1 ) mm = AN.BinoScrat[0];
832
                                                else mm = 0;
833
                                                if ( mm > minval ) {
834
                                                        minval = mm; tmin = t;
835
                                                }
836
                                        }
837
                                        AN.last3 = mm;
838
                                        }
839
                                }
840
                                t = tmin;
841
#endif
842
/*                                AR.TePos = 0;  */
843
                                AR.TePos = WORDDIF(t,term);
5,869,020✔
844
                                AT.TMbuff = t[4];
5,869,020✔
845
                                if ( t[4] == AM.dbufnum && (t+t[1]) < m && t[t[1]] == DOLLAREXPR2 ) {
5,869,020✔
846
                                        if ( t[t[1]+2] < 0 ) AT.TMdolfac = -t[t[1]+2];
190✔
847
                                        else {        /* resolve the element number */
848
                                                AT.TMdolfac = GetDolNum(BHEAD t+t[1],m)+1;
174✔
849
                                        }
850
                                }
851
                                else AT.TMdolfac = 0;
5,868,830✔
852
                                if ( t[3] < 0 ) {
5,869,020✔
853
                                        AN.TeInFun = 1;
1,237✔
854
                                        AR.TePos = WORDDIF(t,term);
1,237✔
855
                                        DONE(t[2])
1,237✔
856
                                }
857
                                else {
858
                                        AN.TeInFun = 0;
5,867,790✔
859
                                        AN.TeSuOut = t[3];
5,867,790✔
860
                                }
861
                                if ( t[2] < 0 ) {
5,867,790✔
862
                                        AN.TeSuOut = -t[3];
×
863
                                        DONE(-t[2])
×
864
                                }
865
                                DONE(t[2])
5,867,790✔
866
                        }
867
                }
868
                else if ( *t == EXPRESSION ) {
159,620,300✔
869
                        WORD *toTMaddr;
32,103✔
870
                        i = -t[2] - 1;
32,103✔
871
                        if ( t[3] < 0 ) {
32,103✔
872
                                AN.TeInFun = 1;
×
873
                                AR.TePos = WORDDIF(t,term);
×
874
                                DONE(i)
×
875
                        }
876
                        nexpr = t[3];
32,103✔
877
                        toTMaddr = m = AT.WorkPointer;
32,103✔
878
                        AN.Frozen = 0;
32,103✔
879
/*
880
                        We have to be very careful with respect to setting variables
881
                        like AN.TeInFun, because we may still call Generator and that
882
                        may change those variables. That is why we set them at the
883
                        last moment only.
884
*/
885
                        j = t[1];
32,103✔
886
                        AT.WorkPointer += j;
32,103✔
887
                        r = t;
32,103✔
888
                        NCOPY(m,r,j);
854,002✔
889
                        r = t + t[1];
32,103✔
890
                        t += SUBEXPSIZE;
32,103✔
891
                        while ( t < r ) {
62,103✔
892
                                if ( *t == FROMBRAC ) {
60,136✔
893
                                        WORD *ttstop,*tttstop;
30,136✔
894
/*
895
                                        Note: Convention is that wildcards are done
896
                                        after the expression has been picked up. So
897
                                        no wildcard substitutions are needed here.
898
*/
899
                                        t += 2;
30,136✔
900
                                        AN.Frozen = m = AT.WorkPointer;
30,136✔
901
/*
902
                                        We should check now for subexpressions and if necessary
903
                                        we substitute them. Keep in mind: only one term allowed!
904

905
                                        In retrospect (26-jan-2010): take also functions that
906
                                        have a dirty flag on
907
*/
908
                                        j = *t; tttstop = t + j;
30,136✔
909
                                        GETSTOP(t,ttstop);
30,136✔
910
                                        *m++ = j; t++;
30,136✔
911
                                        while ( t < ttstop ) {
30,136✔
912
                                                if ( *t == SUBEXPRESSION ) break;
30,132✔
913
                                                if ( *t >= FUNCTION && ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) ) break;
30,092✔
914
                                                j = t[1]; NCOPY(m,t,j);
30,596✔
915
                                        }
916
                                        if ( t < ttstop ) {
30,136✔
917
/*
918
                                                We ran into a subexpression or a function with a
919
                                                'dirty' argument. It could also be a $ or
920
                                                just e[(a^2)*b]. In all cases we should evaluate
921
*/
922
                                                while ( t < tttstop ) *m++ = *t++;
270,360✔
923
                                                *AT.WorkPointer = m-AT.WorkPointer;
30,040✔
924
                                                m = AT.WorkPointer;
30,040✔
925
                                                AT.WorkPointer = m + *m;
30,040✔
926
                                                NewSort(BHEAD0);
30,040✔
927
                                                if ( Generator(BHEAD m,AR.Cnumlhs) ) {
30,040✔
928
                                                        LowerSortLevel(); goto EndTest;
×
929
                                                }
930
                                                if ( EndSort(BHEAD m,0) < 0 ) goto EndTest;
30,040✔
931
                                                AN.Frozen = m;
30,040✔
932
                                                if ( *m == 0 ) {
30,040✔
933
                                                        *m++ = 4; *m++ = 1; *m++ = 1; *m++ = 3;
×
934
                                                }
935
                                                else if ( m[*m] != 0 ) {
30,040✔
936
                                                        MLOCK(ErrorMessageLock);
×
937
                                                        MesPrint("Bracket specification in expression should be one single term");
×
938
                                                        MUNLOCK(ErrorMessageLock);
×
NEW
939
                                                        TERMINATE(-1);
×
940
                                                }
941
                                                else {
942
                                                        m += *m;
30,040✔
943
                                                        m -= ABS(m[-1]);
30,040✔
944
                                                        *m++ = 1; *m++ = 1; *m++ = 3;
30,040✔
945
                                                        *AN.Frozen = m - AN.Frozen;
30,040✔
946
                                                }
947
                                        }
948
                                        else {
949
                                                while ( t < tttstop ) *m++ = *t++;
384✔
950
                                                *AT.WorkPointer = m-AT.WorkPointer;
96✔
951
                                                m = AT.WorkPointer;
96✔
952
                                                AT.WorkPointer = m + *m;
96✔
953
                                                if ( Normalize(BHEAD m) ) {
96✔
954
                                                        MLOCK(ErrorMessageLock);
×
955
                                                        MesPrint("Error while picking up contents of bracket");
×
956
                                                        MUNLOCK(ErrorMessageLock);
×
NEW
957
                                                        TERMINATE(-1);
×
958
                                                }
959
                                                if ( !*m ) {
96✔
960
                                                        *m++ = 4; *m++ = 1; *m++ = 1; *m++ = 3;
×
961
                                                }
962
                                                else m += *m;
96✔
963
                                        }
964
                                        AT.WorkPointer = m;
30,136✔
965
                                        break;
30,136✔
966
                                }
967
                                t += t[1];
30,000✔
968
                        }
969
                        AN.TeInFun = 0;
32,103✔
970
                        AR.TePos = 0;
32,103✔
971
                        AN.TeSuOut = nexpr;
32,103✔
972
                        AT.TMaddr = toTMaddr;
32,103✔
973
                        DONE(i)
32,103✔
974
                }
975
                else if ( *t >= FUNCTION ) {
159,588,300✔
976
            if ( t[0] == EXPONENT ) {
114,081,800✔
977
                if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SYMBOL &&
11,624✔
978
                t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+3] < MAXPOWER
16✔
979
                && t[FUNHEAD+3] > -MAXPOWER ) {
×
980
                    t[0] = SYMBOL;
×
981
                    t[1] = 4;
×
982
                    t[2] = t[FUNHEAD+1];
×
983
                    t[3] = t[FUNHEAD+3];
×
984
                    r = term + *term;
×
985
                    m = t + FUNHEAD+4;
×
986
                    t += 4;
×
987
                    while ( m < r ) *t++ = *m++;
×
988
                    *term = WORDDIF(t,term);
×
989
                    goto ReStart;
×
990
                }
991
                                else if ( t[1] == FUNHEAD+ARGHEAD+11 && t[FUNHEAD] == ARGHEAD+9
11,624✔
992
                                 && t[FUNHEAD+ARGHEAD] == 9 && t[FUNHEAD+ARGHEAD+1] == DOTPRODUCT
11,068✔
993
                                 && t[FUNHEAD+ARGHEAD+8] == 3
×
994
                                 && t[FUNHEAD+ARGHEAD+7] == 1
×
995
                                 && t[FUNHEAD+ARGHEAD+6] == 1
×
996
                                 && t[FUNHEAD+ARGHEAD+5] == 1
×
997
                 && t[FUNHEAD+ARGHEAD+9] == -SNUMBER
×
998
                                 && t[FUNHEAD+ARGHEAD+10] < MAXPOWER
×
999
                 && t[FUNHEAD+ARGHEAD+10] > -MAXPOWER ) {
×
1000
                                        t[0] = DOTPRODUCT;
×
1001
                                        t[1] = 5;
×
1002
                                        t[2] = t[FUNHEAD+ARGHEAD+3];
×
1003
                                        t[3] = t[FUNHEAD+ARGHEAD+4];
×
1004
                                        t[4] = t[FUNHEAD+ARGHEAD+10];
×
1005
                    r = term + *term;
×
1006
                    m = t + FUNHEAD+ARGHEAD+11;
×
1007
                    t += 5;
×
1008
                    while ( m < r ) *t++ = *m++;
×
1009
                    *term = WORDDIF(t,term);
×
1010
                    goto ReStart;
×
1011
                                }
1012
            }
1013
                        funnum = *t;
114,081,800✔
1014
                        if ( *t >= FUNCTION + WILDOFFSET ) funnum -= WILDOFFSET;
114,081,800✔
1015
                        if ( *t == EXPONENT ) {
114,081,800✔
1016
/*
1017
                                Test whether the second argument is an integer
1018
*/
1019
                                r = t+FUNHEAD;
11,624✔
1020
                                NEXTARG(r)
11,624✔
1021
                                if ( *r == -SNUMBER && r[1] < MAXPOWER && r+2 == t+t[1] &&
11,624✔
1022
                                t[FUNHEAD] > -FUNCTION && ( t[FUNHEAD] != -SNUMBER
11,160✔
1023
                                || t[FUNHEAD+1] != 0 ) && t[FUNHEAD] != ARGHEAD ) {
11,160✔
1024
                                  if ( r[1] == 0 ) {
11,160✔
1025
                                        if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 ) {
72✔
1026
                                                MLOCK(ErrorMessageLock);
×
1027
                                                MesPrint("Encountered 0^0. Fatal error.");
×
1028
                                                MUNLOCK(ErrorMessageLock);
×
1029
                                                SETERROR(-1);
×
1030
                                        }
1031
                                        *t = DUMMYFUN;
72✔
1032
/*
1033
                                                Now mark it clean to avoid further interference.
1034
                                                Normalize will remove this object.
1035
*/
1036
                                        t[2] = 0;
72✔
1037
                                  }
1038
                                  else {
1039
                                        /* Note that the case 0^ is treated in Normalize */
1040

1041
                                        t1 = AddRHS(AT.ebufnum,1);
11,088✔
1042
                                        m = t + FUNHEAD;
11,088✔
1043
                                        if ( *m > 0 ) {
11,088✔
1044
                                                m += ARGHEAD;
11,068✔
1045
                                                i = t[FUNHEAD] - ARGHEAD;
11,068✔
1046
                                                while ( (t1 + i + 10) > C->Top )
11,068✔
1047
                                                        t1 = DoubleCbuffer(AT.ebufnum,t1,9);
×
1048
                                                while ( --i >= 0 ) *t1++ = *m++;
110,680✔
1049
                                        }
1050
                                        else {
1051
                                                if ( (t1 + 20) > C->Top )
20✔
1052
                                                        t1 = DoubleCbuffer(AT.ebufnum,t1,10);
×
1053
                                                ToGeneral(m,t1,1);
20✔
1054
                                                t1 += *t1;
20✔
1055
                                        }
1056
                                        *t1++ = 0;
11,088✔
1057
                                        C->rhs[C->numrhs+1] = t1;
11,088✔
1058
                                        C->Pointer = t1;
11,088✔
1059

1060
                                        /* No provisions yet for commuting objects */
1061

1062
                                        C->CanCommu[C->numrhs] = 1;
11,088✔
1063
                                        *t++ = SUBEXPRESSION;
11,088✔
1064
                                        *t++ = SUBEXPSIZE;
11,088✔
1065
                                        *t++ = C->numrhs;
11,088✔
1066
                                        *t++ = r[1];
11,088✔
1067
                                        *t++ = AT.ebufnum;
11,088✔
1068
#if SUBEXPSIZE > 5
1069
Important: we may not have enough spots here
1070
#endif
1071
                                        FILLSUB(t)  /* Important: We have maybe only 5 spots! */
1072
                                        r += 2;
11,088✔
1073
                                        m = term + *term;
11,088✔
1074
                                        do { *t++ = *r++; } while ( r < m );
33,664✔
1075
                                        *term -= WORDDIF(r,t);
11,088✔
1076
                                        goto ReStart;
11,088✔
1077
                                  }
1078
                                }
1079
                        }
1080
                        else if ( *t == SUMF1 || *t == SUMF2 ) {
114,070,200✔
1081
/*
1082
                                What we are looking for is:
1083
                                1-st argument:        Single symbol or index.
1084
                                2-nd argument:        Number.
1085
                                3-rd argument:        Number.
1086
                                (4-th argument):Number.
1087
                                One more argument.
1088
                                This would activate the summation procedure.
1089
                                Note that the initiated recursion here can be done
1090
                                without upsetting the regular procedures.
1091
*/
1092
                                WORD *tstop, lcounter, lcmin, lcmax, lcinc;
64✔
1093
                                tstop = t + t[1];
64✔
1094
                                r = t+FUNHEAD;
64✔
1095
                                if ( r+6 < tstop && r[2] == -SNUMBER && r[4] == -SNUMBER 
64✔
1096
                                && ( ( r[0] == -SYMBOL )
16✔
1097
                                || ( r[0] == -INDEX && r[1] >= AM.OffsetIndex
×
1098
                                && r[3] >= 0 && r[3] < AM.OffsetIndex
×
1099
                                && r[5] >= 0 && r[5] < AM.OffsetIndex ) ) ) {
×
1100
                                        lcounter = r[0] == -INDEX ? -r[1]: r[1]; /* The loop counter */
16✔
1101
                                        lcmin = r[3];
16✔
1102
                                        lcmax = r[5];
16✔
1103
                                        r += 6;
16✔
1104
                                        if ( *r == -SNUMBER && r+2 < tstop ) {
16✔
1105
                                                lcinc = r[1];
×
1106
                                                r += 2;
×
1107
                                        }
1108
                                        else lcinc = 1;
1109
                                        if ( r < tstop && ( ( *r > 0 && (r+*r) == tstop )
16✔
1110
                                        || ( *r <= -FUNCTION && r+1 == tstop )
×
1111
                                        || ( *r > -FUNCTION && *r < 0 && r+2 == tstop ) ) ) {
×
1112
                                                m = AddRHS(AT.ebufnum,1);
16✔
1113
                                                if ( *r > 0 ) {
16✔
1114
                                                        i = *r - ARGHEAD;
16✔
1115
                                                        r += ARGHEAD;
16✔
1116
                                                        while ( (m + i + 10) > C->Top )
16✔
1117
                                                                m = DoubleCbuffer(AT.ebufnum,m,11);
×
1118
                                                        while ( --i >= 0 ) *m++ = *r++;
208✔
1119
                                                }
1120
                                                else {
1121
                                                        while ( (m + 20) > C->Top )
×
1122
                                                                m = DoubleCbuffer(AT.ebufnum,m,12);
×
1123
                                                        ToGeneral(r,m,1);
×
1124
                                                        m += *m;
×
1125
                                                }
1126
                                                *m++ = 0;
16✔
1127
                                                C->rhs[C->numrhs+1] = m;
16✔
1128
                                                C->Pointer = m;
16✔
1129
                                                m = AT.TMout;
16✔
1130
                                                *m++ = 6;
16✔
1131
                                                if ( *t == SUMF1 ) *m++ = SUMNUM1;
16✔
1132
                                                else                           *m++ = SUMNUM2;
4✔
1133
                                                *m++ = lcounter;
16✔
1134
                                                *m++ = lcmin;
16✔
1135
                                                *m++ = lcmax;
16✔
1136
                                                *m++ = lcinc;
16✔
1137
                                                m = t + t[1];
16✔
1138
                                                r = C->rhs[C->numrhs];
16✔
1139
/*
1140
                                                Test now if the argument was already evaluated.
1141
                                                In that case it needs a new subexpression prototype.
1142
                                                In either case we replace the function now by a
1143
                                                subexpression prototype.
1144
*/
1145
                                                if ( *r >= (SUBEXPSIZE+4)
16✔
1146
                                                && ABS(*(r+*r-1)) < (*r - 1)
16✔
1147
                                                && r[1] == SUBEXPRESSION ) {
16✔
1148
                                                        r++;
8✔
1149
                                                        i = r[1] - 5;
8✔
1150
                                                        *t++ = *r++; *t++ = *r++; *t++ = C->numrhs;
8✔
1151
                                                        r++; *t++ = *r++; *t++ = AT.ebufnum; r++;
8✔
1152
                                                        while ( --i >= 0 ) *t++ = *r++;
40✔
1153
                                                }
1154
                                                else {
1155
                                                        *t++ = SUBEXPRESSION;
8✔
1156
                                                        *t++ = 4+SUBEXPSIZE;
8✔
1157
                                                        *t++ = C->numrhs;
8✔
1158
                                                        *t++ = 1;
8✔
1159
                                                        *t++ = AT.ebufnum;
8✔
1160
                                                        FILLSUB(t)
1161
                                                        if ( lcounter < 0 ) {
8✔
1162
                                                                *t++ = INDTOIND;
×
1163
                                                                *t++ = 4;
×
1164
                                                                *t++ = -lcounter;
×
1165
                                                        }
1166
                                                        else {
1167
                                                                *t++ = SYMTONUM;
8✔
1168
                                                                *t++ = 4;
8✔
1169
                                                                *t++ = lcounter;
8✔
1170
                                                        }
1171
                                                        *t++ = lcmin;
8✔
1172
                                                }
1173
                                                t2 = term + *term;
16✔
1174
                                                while ( m < t2 ) *t++ = *m++;
64✔
1175
                                                *term = WORDDIF(t,term);
16✔
1176
                                                AN.TeInFun = -C->numrhs;
16✔
1177
                                                AR.TePos = 0;
16✔
1178
                                                AN.TeSuOut = 0;
16✔
1179
                                                AT.TMbuff = AT.ebufnum;
16✔
1180
                                                DONE(C->numrhs)
16✔
1181
                                        }
1182
                                }
1183
                        }
1184
                        else if ( *t == TOPOLOGIES ) {
114,070,200✔
1185
/*
1186
                                Syntax:
1187
                                topologies_(nloops,nlegs,setvertexsizes,setext,setint[,options])
1188
*/
1189
                                t1 = t+FUNHEAD; t2 = t+t[1];
×
1190
                                if ( *t1 == -SNUMBER && t1[1] >= 0 &&
×
1191
                                        t1[2] == -SNUMBER && ( t1[3] >= 0 || t1[3] == -2 ) &&
×
1192
                                        t1[4] == -SETSET && Sets[t1[5]].type == CNUMBER &&
×
1193
                                        t1[6] == -SETSET && Sets[t1[7]].type == CVECTOR &&
×
1194
                                        t1[8] == -SETSET && Sets[t1[9]].type == CVECTOR &&
×
1195
                                        t1+10 <= t2 ) {
×
1196
                                        if ( t1+10 == t2 || ( t1+12 <= t2 && ( t1[10] == -SNUMBER ||
×
1197
                                                ( t1[10] == -SETSET &&
×
1198
                                                        Sets[t1[5]].last-Sets[t1[5]].first ==
×
1199
                                                        Sets[t1[11]].last-Sets[t1[11]].first ) ) ) ) {
×
1200
                                                AN.TeInFun = -15;
×
1201
                                                AN.TeSuOut = 0;
×
1202
                                                AR.TePos = -1;
×
1203
                                                AR.funoffset = t - term;
×
1204
                                                DONE(1)
×
1205
                                        }
1206
                                }
1207
                        }
1208
                        else if ( *t == DIAGRAMS ) {
114,070,200✔
1209
/*
1210
                                Syntax:
1211
                                diagrams_(model,setinparticles,setoutparticles,
1212
                                        setextmomenta,setintmomenta,couplings or loops)
1213
*/
1214
                                if ( AC.nummodels > 0 ) { /* No model, no diagrams */
8✔
1215
                                  t1 = t+FUNHEAD; t2 = t+t[1];
8✔
1216
                                  if ( 
8✔
1217
                                  t1[0] == -SETSET && Sets[t1[1]].type == CMODEL &&
8✔
1218
                                  t1[2] == -SETSET && ( Sets[t1[3]].type == CFUNCTION 
8✔
1219
                                        || ( Sets[t1[3]].type == ANYTYPE && ( Sets[t1[3]].first == Sets[t1[3]].last ) ) ) &&
×
1220
                                  t1[4] == -SETSET && ( Sets[t1[5]].type == CFUNCTION
8✔
1221
                                        || ( Sets[t1[5]].type == ANYTYPE && ( Sets[t1[5]].first == Sets[t1[5]].last ) ) ) &&
8✔
1222
                                  t1[6] == -SETSET && Sets[t1[7]].type == CVECTOR &&
8✔
1223
                                  t1[8] == -SETSET && Sets[t1[9]].type == CVECTOR &&
8✔
1224
                                  t1+12 <= t2 ) {
8✔
1225
/*
1226
                                        Test that the sets of particles correspond to particles
1227
                                        of the set model.
1228
*/
1229
                                        MODEL *m = AC.models[SetElements[Sets[t1[1]].first]];
8✔
1230
                                        int nn0,nn1,nn2;
8✔
1231
                                        for ( nn0 = 3; nn0 <= 5; nn0 += 2 ) {
24✔
1232
                                          for ( nn1 = Sets[t1[nn0]].first; nn1 < Sets[t1[nn0]].last; nn1++ ) {
32✔
1233
                                                for ( nn2 = 0; nn2 < m->nparticles; nn2++ ) {
16✔
1234
                                                        if ( m->vertices[nn2]->particles[0].number == SetElements[nn1]
16✔
1235
                                                          || m->vertices[nn2]->particles[1].number == SetElements[nn1] ) break;
×
1236
                                                }
1237
                                                if ( nn2 >= m->nparticles ) goto doesnotwork;
16✔
1238
                                          }
1239
                                        }
1240
/*
1241
                                        Now test for a single argument indicating the order
1242
                                        in perturbation theory.
1243
*/
1244
                                        if ( ( t1[10] == -SNUMBER && t1[11] >= 0 && t1+12 == t2 )
8✔
1245
                                        || ( t1[10] == -SYMBOL && t1+12 == t2 )
8✔
1246
                                        || ( t1+10+t1[10] == t2 && t1+10+ARGHEAD+t1[10+ARGHEAD] == t2
8✔
1247
                                        && t1[11+ARGHEAD] == SYMBOL ) ) {
×
1248
/*
1249
                                                Now test that all symbols are valid coupling constants.
1250
*/
1251
                                                if ( t1+12 > t2 ) {
×
1252
                                                        WORD *tt1 = t1+13+ARGHEAD, im;
1253
                                                        t2 -=  ABS(t2[-1]);
1254
                                                        while ( tt1 < t2 ) {
1255
                                                                for ( im = 0; im < m->ncouplings; im++ ) {
1256
                                                                        if ( *tt1 == m->couplings[im] ) break;
1257
                                                                }
1258
                                                                if ( im >= m->ncouplings ) goto doesnotwork;
1259
                                                                tt1 += 2;
1260
                                                        }
1261
                                                }
1262
                                                AN.TeInFun = -16;
×
1263
                                                AN.TeSuOut = 0;
×
1264
                                                AR.TePos = -1;
×
1265
                                                AR.funoffset = t - term;
×
1266
                                                DONE(1)
×
1267
                                        }
1268
                                        else if ( ( ( t1[10] == -SNUMBER && t1[11] >= 0 && t1+12 == t2-2 )
8✔
1269
                                        || ( t1[10] == -SYMBOL && t1+12 == t2-2 )
8✔
1270
                                        || ( t1+10+t1[10] == t2-2 && t1+10+ARGHEAD+t1[10+ARGHEAD] == t2-2
4✔
1271
                                        && t1[11+ARGHEAD] == SYMBOL ) ) && t2[-2] == -SNUMBER ) {
4✔
1272
/*
1273
                                                With options at t2[-2],t2[-1]
1274
                                                Now test that all symbols are valid coupling constants.
1275
*/
1276
                                                t2 -= 2;
4✔
1277
                                                if ( t1+12 > t2 ) {
4✔
1278
                                                        WORD *tt1 = t1+13+ARGHEAD, im;
×
1279
                                                        t2 -=  ABS(t2[-1]);
×
1280
                                                        while ( tt1 < t2 ) {
×
1281
                                                                for ( im = 0; im < m->ncouplings; im++ ) {
×
1282
                                                                        if ( *tt1 == m->couplings[im] ) break;
×
1283
                                                                }
1284
                                                                if ( im >= m->ncouplings ) goto doesnotwork;
×
1285
                                                                tt1 += 2;
×
1286
                                                        }
1287
                                                }
1288
                                                AN.TeInFun = -16;
4✔
1289
                                                AN.TeSuOut = 0;
4✔
1290
                                                AR.TePos = -1;
4✔
1291
                                                AR.funoffset = t - term;
4✔
1292
                                                DONE(1)
4✔
1293
                                        }
1294
doesnotwork:;
114,070,200✔
1295
                                  }
1296
                                }
1297
                        }
1298
                        if ( functions[funnum-FUNCTION].spec <= 0
114,070,700✔
1299
                                || ( t[2] & (DIRTYFLAG|MUSTCLEANPRF) ) != 0 ) {
218,997✔
1300
                                funflag = 1;
113,860,300✔
1301
                        }
1302
                        if ( *t <= MAXBUILTINFUNCTION ) {
114,070,700✔
1303
                          if ( *t <= DELTAP && *t >= THETA ) { /* Speeds up by 2 or 3 compares */
411,378✔
1304
                          if ( *t == THETA || *t == THETA2 ) {
1,008✔
1305
                                WORD *tstop, *tt2, kk;
776✔
1306
                                tstop = t + t[1];
776✔
1307
                                tt2 = t + FUNHEAD;
776✔
1308
                                while ( tt2 < tstop ) {
1,328✔
1309
                                        if ( *tt2 > 0 && tt2[1] != 0 ) goto DoSpec;
776✔
1310
                                        NEXTARG(tt2)
552✔
1311
                                }
1312
                                if ( !AT.RecFlag ) {
552✔
1313
                                        if ( ( kk = DoTheta(BHEAD t) ) == 0 ) {
552✔
1314
                                                *term = 0;
292✔
1315
                                                DONE(0)
292✔
1316
                                        }
1317
                                        else if ( kk > 0 ) {
260✔
1318
                                                m = t + t[1];
260✔
1319
                                                r = term + *term;
260✔
1320
                                                while ( m < r ) *t++ = *m++;
23,352✔
1321
                                                *term = WORDDIF(t,term);
260✔
1322
                                                goto ReStart;
260✔
1323
                                        }
1324
                                }
1325
                          }
1326
                          else if ( *t == DELTA2 || *t == DELTAP ) {
232✔
1327
                                WORD *tstop, *tt2, kk;
232✔
1328
                                tstop = t + t[1];
232✔
1329
                                tt2 = t + FUNHEAD;
232✔
1330
                                while ( tt2 < tstop ) {
464✔
1331
                                        if ( *tt2 > 0 && tt2[1] != 0 ) goto DoSpec;
232✔
1332
                                        NEXTARG(tt2)
232✔
1333
                                }
1334
                                if ( !AT.RecFlag ) {
232✔
1335
                                        if ( ( kk = DoDelta(t) ) == 0 ) {
232✔
1336
                                                *term = 0;
164✔
1337
                                                DONE(0)
164✔
1338
                                        }
1339
                                        else if ( kk > 0 ) {
68✔
1340
                                                m = t + t[1];
68✔
1341
                                                r = term + *term;
68✔
1342
                                                while ( m < r ) *t++ = *m++;
1,420✔
1343
                                                *term = WORDDIF(t,term);
68✔
1344
                                                goto ReStart;
68✔
1345
                                        }
1346
                                }
1347
                          } }
1348
                          else if ( *t == DISTRIBUTION && t[FUNHEAD] == -SNUMBER
410,370✔
1349
                          && t[FUNHEAD+1] >= -2 && t[FUNHEAD+1] <= 2
28✔
1350
                          && t[FUNHEAD+2] == -SNUMBER
28✔
1351
                          && t[FUNHEAD+4] <= -FUNCTION
28✔
1352
                          && t[FUNHEAD+5] <= -FUNCTION ) {
28✔
1353
                                WORD *ttt = t+FUNHEAD+6, *tttstop = t+t[1];
28✔
1354
                                while ( ttt < tttstop ) {
28✔
1355
                                        if ( *ttt == -DOLLAREXPRESSION ) break;
132✔
1356
                                        NEXTARG(ttt);
276✔
1357
                                }
1358
                                if ( ttt >= tttstop ) {
28✔
1359
                                        AN.TeInFun = -1;
20✔
1360
                                        AN.TeSuOut = 0;
20✔
1361
                                        AR.TePos = -1;
20✔
1362
                                        DONE(1)
20✔
1363
                                }
1364
                          }
1365
                          else if ( *t == DELTA3 && ((t[1]-FUNHEAD) & 1 ) == 0 ) {
410,342✔
1366
                                AN.TeInFun = -2;
24✔
1367
                                AN.TeSuOut = 0;
24✔
1368
                                AR.TePos = -1;
24✔
1369
                                DONE(1)
24✔
1370
                          }
1371
                          else if ( ( *t == TABLEFUNCTION ) && ( t[FUNHEAD] <= -FUNCTION )
410,318✔
1372
                          && ( T = functions[-t[FUNHEAD]-FUNCTION].tabl ) != 0
4✔
1373
                          && ( t[1] >= FUNHEAD+1+2*ABS(T->numind) )
4✔
1374
                          && ( t[FUNHEAD+1] == -SYMBOL ) ) {
4✔
1375
/*
1376
                                The case of table_(tab,sym1,...,symn)
1377
*/
1378
                                for ( isp = 0; isp < ABS(T->numind); isp++ ) {
8✔
1379
                                        if ( t[FUNHEAD+1+2*isp] != -SYMBOL ) break;
4✔
1380
                                }
1381
                                if ( isp >= ABS(T->numind) ) {
4✔
1382
                                        AN.TeInFun = -3;
4✔
1383
                                        AN.TeSuOut = 0;
4✔
1384
                                        AR.TePos = -1;
4✔
1385
                                        DONE(1)
4✔
1386
                                }
1387
                          }
1388
                          else if ( *t == TABLEFUNCTION && t[FUNHEAD] <= -FUNCTION
410,314✔
1389
                          && ( T = functions[-t[FUNHEAD]-FUNCTION].tabl ) != 0
×
1390
                          && ( t[1] == FUNHEAD+2 )
×
1391
                          && ( t[FUNHEAD+1] <= -FUNCTION ) ) {
×
1392
/*
1393
                                The case of table_(tab,fun)
1394
*/
1395
                                AN.TeInFun = -3;
×
1396
                                AN.TeSuOut = 0;
×
1397
                                AR.TePos = -1;
×
1398
                                DONE(1)
×
1399
                          }
1400
                          else if ( *t == FACTORIN ) {
410,314✔
1401
                                if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -DOLLAREXPRESSION ) {
×
1402
                                        AN.TeInFun = -4;
×
1403
                                        AN.TeSuOut = 0;
×
1404
                                        AR.TePos = -1;
×
1405
                                        DONE(1)
×
1406
                                }
1407
                                else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -EXPRESSION ) {
×
1408
                                        AN.TeInFun = -5;
×
1409
                                        AN.TeSuOut = 0;
×
1410
                                        AR.TePos = -1;
×
1411
                                        DONE(1)
×
1412
                                }
1413
                          }
1414
                          else if ( *t == TERMSINBRACKET ) {
410,314✔
1415
                                if ( t[1] == FUNHEAD || (
×
1416
                                         t[1] == FUNHEAD+2
1417
                                        && t[FUNHEAD] == -SNUMBER
×
1418
                                        && t[FUNHEAD+1] == 0
×
1419
                                 ) ) {
1420
                                        AN.TeInFun = -6;
×
1421
                                        AN.TeSuOut = 0;
×
1422
                                        AR.TePos = -1;
×
1423
                                        DONE(1)
×
1424
                                }
1425
/*
1426
                                The other cases have not yet been implemented
1427
                                We still have to add the case of short arguments
1428
                                First the different bracket in same expression
1429

1430
                                else if ( t[1] > FUNHEAD+ARGHEAD
1431
                                                && t[FUNHEAD] == t[1]-FUNHEAD
1432
                                                && t[FUNHEAD+ARGHEAD] == t[1]-FUNHEAD-ARGHEAD
1433
                                                && t[t[1]-1] == 3
1434
                                                && t[t[1]-2] == 1
1435
                                                && t[t[1]-3] == 1 ) {
1436
                                        AN.TeInFun = -6;
1437
                                        AN.TeSuOut = 0;
1438
                                        AR.TePos = -1;
1439
                                        DONE(1)
1440
                                }
1441

1442
                                Next the bracket in an other expression
1443

1444
                                else if ( t[1] > FUNHEAD+ARGHEAD+2
1445
                                                && t[FUNHEAD] == -EXPRESSION
1446
                                                && t[FUNHEAD+2] == t[1]-FUNHEAD-2
1447
                                                && t[FUNHEAD+ARGHEAD+2] == t[1]-FUNHEAD-ARGHEAD-2
1448
                                                && t[t[1]-1] == 3
1449
                                                && t[t[1]-2] == 1
1450
                                                && t[t[1]-3] == 1 ) {
1451
                                        AN.TeInFun = -6;
1452
                                        AN.TeSuOut = 0;
1453
                                        AR.TePos = -1;
1454
                                        DONE(1)
1455
                                }
1456
*/
1457
                          }
1458
                          else if ( *t == EXTRASYMFUN ) {
410,314✔
1459
                                if ( t[1] == FUNHEAD+2 && (
×
1460
                                        ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] <= cbuf[AM.sbufnum].numrhs
×
1461
                                                        && t[FUNHEAD+1] > 0 ) ||
×
1462
                                        ( t[FUNHEAD] == -SYMBOL && t[FUNHEAD+1] < MAXVARIABLES 
×
1463
                                                        && t[FUNHEAD+1] >= MAXVARIABLES-cbuf[AM.sbufnum].numrhs ) ) ) {
×
1464
                                        AN.TeInFun = -7;
×
1465
                                        AN.TeSuOut = 0;
×
1466
                                        AR.TePos = -1;
×
1467
                                        DONE(1)
×
1468
                                }
1469
                                else if ( t[1] == FUNHEAD ) {
×
1470
                                        AN.TeInFun = -7;
×
1471
                                        AN.TeSuOut = 0;
×
1472
                                        AR.TePos = -1;
×
1473
                                        DONE(1)
×
1474
                                }
1475
                          }
1476
              else if ( *t == DIVFUNCTION || *t == REMFUNCTION
410,314✔
1477
                        || *t == INVERSEFUNCTION || *t == MULFUNCTION
410,314✔
1478
                                                || *t == GCDFUNCTION ) {
410,125✔
1479
                WORD *tf;
597✔
1480
                                int todo = 1, numargs = 0;
597✔
1481
                tf = t + FUNHEAD;
597✔
1482
                while ( tf < t + t[1] ) {
597✔
1483
                                        DOLLARS d;
1,606✔
1484
                                        if ( *tf == -DOLLAREXPRESSION ) {
1,606✔
1485
                                                d = Dollars + tf[1];
300✔
1486
                                                if ( d->type == DOLWILDARGS ) {
300✔
1487
                                                        WORD *tterm = AT.WorkPointer, *tw;
×
1488
                                                        WORD *ta = term, *tb = tterm, *tc, *td = term + *term;
×
1489
                                                        while ( ta < t ) *tb++ = *ta++;
×
1490
                                                        tc = tb;
×
1491
                                                        while ( ta < tf ) *tb++ = *ta++;
×
1492
                                                        tw = d->where+1;
×
1493
                                                        while ( *tw ) {
×
1494
                                                                if ( *tw < 0 ) {
×
1495
                                                                        if ( *tw > -FUNCTION ) *tb++ = *tw++;
×
1496
                                                                        *tb++ = *tw++;
×
1497
                                                                }
1498
                                                                else {
1499
                                                                        int ia;
1500
                                                                        for ( ia = 0; ia < *tw; ia++ ) *tb++ = *tw++;
×
1501
                                                                }
1502
                                                        }
1503
                                                        NEXTARG(ta)
×
1504
                                                        while ( ta < t+t[1] ) *tb++ = *ta++;
×
1505
                                                        tc[1] = tb-tc;
×
1506
                                                        while ( ta < td ) *tb++ = *ta++;
×
1507
                                                        *tterm = tb - tterm;
×
1508
                                                        {
1509
                                                                int ia, na = *tterm;
×
1510
                                                                ta = tterm; tb  = term;
×
1511
                                                                for ( ia = 0; ia < na; ia++ ) *tb++ = *ta++;
×
1512
                                                        }
1513
                                                        if ( tb > AT.WorkTop ) {
×
1514
                                                                MLOCK(ErrorMessageLock);
×
1515
                                                                MesWork();
×
1516
                                                                goto EndTest2;
×
1517
                                                        }
1518
                                                        AT.WorkPointer = tb;
×
1519
                                                        goto ReStart;
×
1520
                                                }
1521
                                        }
1522
                    NEXTARG(tf);
3,809✔
1523
                }
1524
                tf = t + FUNHEAD;
1525
                while ( tf < t + t[1] ) {
2,203✔
1526
                                        numargs++;
1,606✔
1527
                                        if ( *tf > 0 && tf[1] != 0 ) todo = 0;
1,606✔
1528
                    NEXTARG(tf);
3,809✔
1529
                }
1530
                                if ( todo && numargs == 2 ) {
597✔
1531
                                        if ( *t == DIVFUNCTION ) AN.TeInFun = -9;
353✔
1532
                                        else if ( *t == REMFUNCTION ) AN.TeInFun = -10;
315✔
1533
                                        else if ( *t == INVERSEFUNCTION ) AN.TeInFun = -11;
277✔
1534
                                        else if ( *t == MULFUNCTION ) AN.TeInFun = -14;
255✔
1535
                                        else if ( *t == GCDFUNCTION ) AN.TeInFun = -8;
196✔
1536
                                        AN.TeSuOut = 0;
353✔
1537
                                        AR.TePos = -1;
353✔
1538
                                        DONE(1)
353✔
1539
                                }
1540
                                else if ( todo && numargs == 3 ) {
244✔
1541
                                        if ( *t == DIVFUNCTION ) AN.TeInFun = -9;
8✔
1542
                                        else if ( *t == REMFUNCTION ) AN.TeInFun = -10;
8✔
1543
                                        else if ( *t == GCDFUNCTION ) AN.TeInFun = -8;
8✔
1544
                                        AN.TeSuOut = 0;
8✔
1545
                                        AR.TePos = -1;
8✔
1546
                                        DONE(1)
8✔
1547
                                }
1548
                                else if ( todo && *t == GCDFUNCTION ) {
236✔
1549
                                        AN.TeInFun = -8;
36✔
1550
                                        AN.TeSuOut = 0;
36✔
1551
                                        AR.TePos = -1;
36✔
1552
                                        DONE(1)
36✔
1553
                                }
1554
                          }
1555
                          else if ( *t == PERMUTATIONS && ( ( t[1] >= FUNHEAD+1
409,717✔
1556
                                && t[FUNHEAD] <= -FUNCTION ) || ( t[1] >= FUNHEAD+3
4✔
1557
                                && t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] <= -FUNCTION ) ) ) {
×
1558
                                AN.TeInFun = -12;
4✔
1559
                                AN.TeSuOut = 0;
4✔
1560
                                AR.TePos = -1;
4✔
1561
                                DONE(1)
4✔
1562
                          }
1563
                          else if ( *t == PARTITIONS ) {
409,713✔
1564
                                if ( TestPartitions(t,&(AT.partitions)) ) {
16✔
1565
                                        AT.partitions.where = t-term;
16✔
1566
                                        AN.TeInFun = -13;
16✔
1567
                                        AN.TeSuOut = 0;
16✔
1568
                                        AR.TePos = -1;
16✔
1569
                                        DONE(1)
16✔
1570
                                }
1571
                          }
1572
                        }
1573
                }
1574
                t += t[1];
159,575,800✔
1575
        } while ( t < m );
159,575,800✔
1576
        if ( funflag ) {        /* Search in functions */
26,810,550✔
1577
DoSpec:
6,241,518✔
1578
                t = term;
6,241,734✔
1579
                AT.NestPoin->termsize = t;
6,241,734✔
1580
                if ( AT.NestPoin == AT.Nest ) AN.EndNest = t + *t;
6,241,734✔
1581
                t++;
6,241,734✔
1582
                oldncmod = AN.ncmod;
6,241,734✔
1583
                if ( t < m ) do {
6,241,734✔
1584
                        if ( *t < FUNCTION ) {
67,568,900✔
1585
                                t += t[1]; continue;
3,325,008✔
1586
                        }
1587
                        if ( AN.ncmod && ( ( AC.modmode & ALSOFUNARGS ) == 0 ) ) {
64,243,800✔
1588
                                if ( *t != AR.PolyFun ) AN.ncmod = 0;
×
1589
                                else                    AN.ncmod = oldncmod;
×
1590
                        }
1591
                        r = t + t[1];
64,243,800✔
1592
                        funnum = *t;
64,243,800✔
1593
                        if ( *t >= FUNCTION + WILDOFFSET ) funnum -= WILDOFFSET;
64,243,800✔
1594
                        if ( ( *t == NUMFACTORS || *t == FIRSTTERM || *t == CONTENTTERM )
64,243,800✔
1595
                         && t[1] == FUNHEAD+2 &&
49✔
1596
                        ( t[FUNHEAD] == -EXPRESSION || t[FUNHEAD] == -DOLLAREXPRESSION ) ) {
49✔
1597
/*
1598
                                if ( *t == NUMFACTORS ) {
1599
                                        This we leave for Normalize
1600
                                }
1601
*/                                
1602
                        }
1603
                        else if ( functions[funnum-FUNCTION].spec <= 0 ) {
64,243,700✔
1604
                                AT.NestPoin->funsize = t + 1;
64,232,900✔
1605
                                t1 = t;
64,232,900✔
1606
                                t += FUNHEAD;
64,232,900✔
1607
                                while ( t < r ) {        /* Sum over arguments */
128,518,000✔
1608
                                        if ( *t > 0 && t[1] ) {        /* Argument is dirty  */
66,577,800✔
1609
                                                AT.NestPoin->argsize = t;
2,290,381✔
1610
                                                AT.NestPoin++;
2,290,381✔
1611
/*                                                stop = t + *t; */
1612
                                                t2 = t;
2,290,381✔
1613
                                                t += ARGHEAD;
2,290,381✔
1614
                                                while ( t < AT.NestPoin[-1].argsize+*(AT.NestPoin[-1].argsize) ) {
6,624,540✔
1615
                                                                                        /* Sum over terms */
1616
                                                        AT.RecFlag++;
5,547,430✔
1617
                                                        i = *t;
5,547,430✔
1618
                                                        AN.subsubveto = 1;
5,547,430✔
1619
/*
1620
                                                        AN.subsubveto repairs a bug that became apparent
1621
                                                        in an example by York Schroeder:
1622
                                                                f(k1.k1)*replace_(k1,2*k2)
1623
                                                        Is it possible to repair the counting of the various
1624
                                                        length indicators? (JV 1-jun-2010)
1625
*/
1626
                                                        if ( ( retvalue = TestSub(BHEAD t,level) ) != 0 ) {
5,547,430✔
1627
/*
1628
                                                                Possible size changes:
1629
                                                                Note defs at 471,467,460,400,425,328
1630
*/
1631
redosize:
1,213,278✔
1632
                                                                if ( i > *t ) {
1,213,286✔
1633
/*
1634
                                                                        i -= *t;
1635
                                                                        *t2 -= i;
1636
                                                                        t1[1] -= i;
1637
                                                                        t += *t;
1638
                                                                        r = t + i;
1639
                                                                        m = term + *term;
1640
                                                                        while ( r < m ) *t++ = *r++;
1641
                                                                        *term -= i;
1642
*/
1643
                                                                        i -= *t;
8✔
1644
                                                                        t += *t;
8✔
1645
                                                                        r = t + i;
8✔
1646
                                                                        m = AN.EndNest;
8✔
1647
                                                                        while ( r < m ) *t++ = *r++;
68✔
1648
                                                                        t = AT.NestPoin[-1].argsize + ARGHEAD;
8✔
1649
                                                                        n = AT.Nest;
8✔
1650
                                                                        while ( n < AT.NestPoin ) {
16✔
1651
                                                                                *(n->argsize) -= i;
8✔
1652
                                                                                *(n->funsize) -= i;
8✔
1653
                                                                                *(n->termsize) -= i;
8✔
1654
                                                                                n++;
8✔
1655
                                                                        }
1656
                                                                        AN.EndNest -= i;
8✔
1657
                                                                }
1658
                                                                AN.subsubveto = 0;
1,213,286✔
1659
                                                                t1[2] = 1;
1,213,286✔
1660
                                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 )
1,213,286✔
1661
                                                                        t1[2] |= MUSTCLEANPRF;
39,039✔
1662
                                                                AT.RecFlag--;
1,213,286✔
1663
                                                                AT.NestPoin--;
1,213,286✔
1664
                                                                AN.TeInFun++;
1,213,286✔
1665
                                                                AR.TePos = 0;
1,213,286✔
1666
                                                                AN.ncmod = oldncmod;
1,213,286✔
1667
                                                                DONE(retvalue)
1,213,286✔
1668
                                                        }
1669
                                                        else {
1670
                                                                /*
1671
                                                                 * Somehow the next line fixes Issue #106.
1672
                                                                 */
1673
                                                                i = *t;
4,334,150✔
1674
                                                                Normalize(BHEAD t);
4,334,150✔
1675
/*                                                                if ( i > *t ) { retvalue = 1; goto redosize; } */
1676
                                                                /*
1677
                                                                 * Experimentally, the next line fixes Issue #105.
1678
                                                                 */
1679
                                                                if ( *t == 0 ) { retvalue = 1; goto redosize; }
4,334,150✔
1680
                                                                {
1681
                                                                        WORD *tend = t + *t, *tt = t+1;
4,334,150✔
1682
                                                                        stilldirty = 0;
4,334,150✔
1683
                                                                        tend -= ABS(tend[-1]);
4,334,150✔
1684
                                                                        while ( tt < tend ) {
5,669,910✔
1685
                                                                                if ( *tt == SUBEXPRESSION || *tt == EXPRESSION ) {
1,335,776✔
1686
                                                                                        stilldirty = 1; break;
1687
                                                                                }
1688
                                                                                tt += tt[1];
1,335,776✔
1689
                                                                        }
1690
                                                                }
1691
                                                                if ( i > *t ) {
4,334,150✔
1692
/*
1693
                                                                        We should not forget to correct the Nest
1694
                                                                        stack. That caused trouble in the past.
1695
*/
1696
                                                                        retvalue = 1;
4,040✔
1697
                                                                        i -= *t;
4,040✔
1698
                                                                        t += *t;
4,040✔
1699
                                                                        r = t + i;
4,040✔
1700
                                                                        m = AN.EndNest;
4,040✔
1701
                                                                        while ( r < m ) *t++ = *r++;
48,630,000✔
1702
                                                                        t = AT.NestPoin[-1].argsize + ARGHEAD;
4,040✔
1703
                                                                        n = AT.Nest;
4,040✔
1704
                                                                        while ( n < AT.NestPoin ) {
8,112✔
1705
                                                                                *(n->argsize) -= i;
4,072✔
1706
                                                                                *(n->funsize) -= i;
4,072✔
1707
                                                                                *(n->termsize) -= i;
4,072✔
1708
                                                                                n++;
4,072✔
1709
                                                                        }
1710
                                                                        AN.EndNest -= i;
4,040✔
1711
                                                                }
1712
                                                        }
1713
                                                        AN.subsubveto = 0;
4,334,150✔
1714
                                                        AT.RecFlag--;
4,334,150✔
1715
                                                        t += *t;
4,334,150✔
1716
                                                }
1717
                                                AT.NestPoin--;
1,077,095✔
1718
/*
1719
                                                Argument contains no subexpressions.
1720
                                                It should be normalized and sorted.
1721
                                                The main problem is the storage.
1722
*/
1723
                                                t = AT.NestPoin->argsize;
1,077,095✔
1724
                                                j = *t;
1,077,095✔
1725
                                                t += ARGHEAD;
1,077,095✔
1726
                                                NewSort(BHEAD0);
1,077,095✔
1727
                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 ) {
1,077,095✔
1728
                                                        AR.CompareRoutine = (COMPAREDUMMY)(&CompareSymbols);
37,643✔
1729
                                                        AR.SortType = SORTHIGHFIRST;
37,643✔
1730
                                                }
1731
                                                if ( AT.WorkPointer < term + *term )
1,077,095✔
1732
                                                        AT.WorkPointer = term + *term;
×
1733

1734
                                                while ( t < AT.NestPoin->argsize+*(AT.NestPoin->argsize) ) {
3,463,188✔
1735
                                                        m = AT.WorkPointer;
2,386,093✔
1736
                                                        r = t + *t;
2,386,093✔
1737
                                                        do { *m++ = *t++; } while ( t < r );
16,420,870✔
1738
                                                        r = AT.WorkPointer;
2,386,093✔
1739
                                                        AT.WorkPointer = r + *r;
2,386,093✔
1740
                                                        if ( Normalize(BHEAD r) ) {
2,386,093✔
1741
                                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 ) {
×
1742
                                                                        AR.SortType = oldsorttype;
×
1743
                                                                        AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
×
1744
                                                                        t1[2] |= MUSTCLEANPRF;
×
1745
                                                                }
1746
                                                                LowerSortLevel(); goto EndTest;
×
1747
                                                        }
1748
                                                        if ( AN.ncmod != 0 ) {
2,386,093✔
1749
                                                                if ( *r ) {
×
1750
                                                                        if ( Modulus(r) ) {
×
1751
                                                                                LowerSortLevel();
×
1752
                                                                                AT.WorkPointer = r;
×
1753
                                                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 ) {
×
1754
                                                                                        AR.SortType = oldsorttype;
×
1755
                                                                                        AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
×
1756
                                                                                        t1[2] |= MUSTCLEANPRF;
×
1757
                                                                                }
1758
                                                                                goto EndTest;
×
1759
                                                                        }
1760
                                                                }
1761
                                                        }
1762
                                                        if ( AR.PolyFun > 0 ) {
2,386,093✔
1763
                                                                if ( PrepPoly(BHEAD r,1) != 0 ) goto EndTest;
221,483✔
1764
                                                        }
1765
                                                        if ( *r ) StoreTerm(BHEAD r);
2,386,093✔
1766
                                                        AT.WorkPointer = r;
2,386,093✔
1767
                                                }
1768
                                                if ( EndSort(BHEAD AT.WorkPointer+ARGHEAD,1) < 0 ) goto EndTest;
1,077,095✔
1769
                                                m = AT.WorkPointer+ARGHEAD;
1,077,095✔
1770
                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 ) {
1,077,095✔
1771
                                                        AR.SortType = oldsorttype;
37,643✔
1772
                                                        AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
37,643✔
1773
                                                        t1[2] |= MUSTCLEANPRF;
37,643✔
1774
                                                }
1775
                                                while ( *m ) m += *m;
3,459,148✔
1776
                                                i = WORDDIF(m,AT.WorkPointer);
1,077,095✔
1777
                                                *AT.WorkPointer = i;
1,077,095✔
1778
                                                AT.WorkPointer[1] = stilldirty;
1,077,095✔
1779
                                                if ( ToFast(AT.WorkPointer,AT.WorkPointer) ) {
1,077,095✔
1780
                                                        m = AT.WorkPointer;
172✔
1781
                                                        if ( *m <= -FUNCTION ) { m++; i = 1; }
172✔
1782
                                                        else { m += 2; i = 2; }
164✔
1783
                                                }
1784
                                                j = i - j;
1,077,095✔
1785
                                                if ( j > 0 ) {
1,077,095✔
1786
                                                        r = m + j;
×
1787
                                                        if ( r > AT.WorkTop ) {
×
1788
                                                                MLOCK(ErrorMessageLock);
×
1789
                                                                MesWork();
×
1790
                                                                goto EndTest2;
×
1791
                                                        }
1792
                                                        do { *--r = *--m; } while ( m > AT.WorkPointer );
×
1793
                                                        AT.WorkPointer = r;
×
1794
                                                        m = AN.EndNest;
×
1795
                                                        r = m + j;
×
1796
                                                        stop = AT.NestPoin->argsize+*(AT.NestPoin->argsize);
×
1797
                                                        do { *--r = *--m; } while ( m >= stop );
×
1798
                                                }
1799
                                                else if ( j < 0 ) {
1,077,095✔
1800
                                                        m = AT.NestPoin->argsize+*(AT.NestPoin->argsize);
184✔
1801
                                                        r = m + j;
184✔
1802
                                                        do { *r++ = *m++; } while ( m < AN.EndNest );
1,440✔
1803
                                                }
1804
                                                m = AT.NestPoin->argsize;
1,077,095✔
1805
                                                r = AT.WorkPointer;
1,077,095✔
1806
                                                while ( --i >= 0 ) *m++ = *r++;
19,635,180✔
1807
                                                n = AT.Nest;
1,077,095✔
1808
                                                while ( n <= AT.NestPoin ) {
2,154,318✔
1809
                                                        if ( *(n->argsize) > 0 && n != AT.NestPoin )
1,077,223✔
1810
                                                                *(n->argsize) += j;
128✔
1811
                                                        *(n->funsize) += j;
1,077,223✔
1812
                                                        *(n->termsize) += j;
1,077,223✔
1813
                                                        n++;
1,077,223✔
1814
                                                }
1815
                                                AN.EndNest += j;
1,077,095✔
1816
/*                                                (AT.NestPoin->argsize)[1] = 0;  */
1817
                                                if ( funnum == DENOMINATOR || funnum == EXPONENT ) {
1,077,095✔
1818
                                                        if ( Normalize(BHEAD term) ) {
1,397✔
1819
/*
1820
                                                                In this case something has been substituted
1821
                                                                Either a $ or a replace_?????
1822
                                                                Originally we had here:
1823

1824
                                                                goto EndTest;
1825

1826
                                                                It seems better to restart.
1827
*/
1828
                                                                AN.ncmod = oldncmod;
×
1829
                                                                goto ReStart;
×
1830
                                                        }
1831
/*
1832
                                                        And size changes here?????
1833
*/
1834
                                                }
1835
                                                AN.ncmod = oldncmod;
1,077,095✔
1836
                                                goto ReStart;
1,077,095✔
1837
                                        }
1838
                                        else if ( *t == -DOLLAREXPRESSION ) {
64,287,400✔
1839
                                                if ( ( *t1 == TERMSINEXPR || *t1 == SIZEOFFUNCTION )
2,340✔
1840
                                                                 && t1[1] == FUNHEAD+2 ) {}
40✔
1841
                                                else {
1842
                                                        if ( AR.Eside != LHSIDE ) {
2,300✔
1843
                                                                AN.TeInFun = 1; AR.TePos = 0;
2,300✔
1844
                                                                AT.TMbuff = AM.dbufnum; t1[2] |= DIRTYFLAG;
2,300✔
1845
                                                                AN.ncmod = oldncmod;
2,300✔
1846
                                                                DONE(1)
2,300✔
1847
                                                        }
1848
                                                        AC.lhdollarflag = 1;
×
1849
                                                }
1850
                                        }
1851
                                        else if ( *t == -TERMSINBRACKET ) {
64,285,000✔
1852
                                                if ( AR.Eside != LHSIDE ) {
×
1853
                                                        AN.TeInFun = 1; AR.TePos = 0;
×
1854
                                                        t1[2] |= DIRTYFLAG;
×
1855
                                                        AN.ncmod = oldncmod;
×
1856
                                                        DONE(1)
×
1857
                                                }
1858
                                        }
1859
                                        else if ( AN.ncmod != 0 && *t == -SNUMBER ) {
64,285,000✔
1860
                                                if ( AN.ncmod == 1 || AN.ncmod == -1 ) {
×
1861
                                                        isp = (UWORD)(AC.cmod[0]);
×
1862
                                                        isp = t[1] % isp;
×
1863
                                                        if ( ( AC.modmode & POSNEG ) != 0 ) {
×
1864
                                                                if ( isp > (UWORD)(AC.cmod[0])/2 ) isp = isp - (UWORD)(AC.cmod[0]);
×
1865
                                                                else if ( -isp > (UWORD)(AC.cmod[0])/2 ) isp = isp + (UWORD)(AC.cmod[0]);
×
1866
                                                        }
1867
                                                        else {
1868
                                                                if ( isp < 0 ) isp += (UWORD)(AC.cmod[0]);
×
1869
                                                        }
1870
                                                        if ( isp <= MAXPOSITIVE && isp >= -MAXPOSITIVE ) {
×
1871
                                                                t[1] = isp;
×
1872
                                                        }
1873
                                                }
1874
                                        }
1875
                                        NEXTARG(t)
64,285,000✔
1876
                                }
1877
                                if ( funnum >= FUNCTION && functions[funnum-FUNCTION].tabl ) {
61,940,400✔
1878
/*
1879
                                        Test whether the table catches
1880
                                        Test 1: index arguments and range. i will be the number
1881
                                                of the element in the table.
1882
*/
1883
                                        WORD rhsnumber, *oldwork = AT.WorkPointer;
736✔
1884
                                        WORD ii, *p, *pp, *ppstop;
736✔
1885
                                        MINMAX *mm;
736✔
1886
                                        T = functions[funnum-FUNCTION].tabl;
736✔
1887
/*
1888
                                        Because of tables with a variable number of indices
1889
                                        we need to make a copy of the pattern.
1890
                                        If we do this in the WorkSpace we get problems with EndNest.
1891
                                        This is why we use TermMalloc.
1892
                                        Now Tpattern is a copy that can be modified.
1893
*/
1894
#ifdef WITHPTHREADS
1895
                                        pp = T->pattern[AT.identity];
354✔
1896
#else
1897
                                        pp = T->pattern;
382✔
1898
#endif
1899
                                        if ( Tpattern == 0 ) Tpattern = TermMalloc("Tpattern");
736✔
1900
                                        p = Tpattern;
736✔
1901
                                        ii = pp[1];
736✔
1902
                                        for ( i = 0; i < ii; i++ ) *p++ = *pp++;
12,880✔
1903

1904
                                        p = Tpattern + FUNHEAD+1;
736✔
1905
                                        mm = T->mm;
736✔
1906
                                        if ( T->sparse ) {
736✔
1907
                                                WORD xx;
70✔
1908
                                                t = t1+FUNHEAD;
70✔
1909
                                                if ( T->numind == 0 ) { isp = 0; xx = 0; }
70✔
1910
                                                else {
1911
                                                        if ( T->numind < 0 ) {
70✔
1912
                                                          if ( *t != -SNUMBER && t[2] != -SNUMBER ) {
×
1913
                                                                xx = ABS(T->numind);
×
1914
                                                                goto teststrict;
×
1915
                                                          }
1916
                                                          xx = t[1]+1;
×
1917
                                                          if ( xx < 2 || xx > -T->numind ) goto teststrict;
×
1918
                                                        }
1919
                                                        else xx = T->numind;
1920
                                                        for ( i = 0; i < xx; i++, t += 2 ) {
140✔
1921
                                                                if ( *t != -SNUMBER ) break;
70✔
1922
                                                        }
1923
                                                        if ( i < xx ) goto teststrict;
70✔
1924
                                                        isp = FindTableTree(T,t1+FUNHEAD,2);
70✔
1925
                                                }
1926
                                                if ( isp < 0 ) {
70✔
1927
teststrict:                                        if ( T->strict == -2 ) {
×
1928
                                                                rhsnumber = AM.zerorhs;
×
1929
                                                                tbufnum = AM.zbufnum;
×
1930
                                                        }
1931
                                                        else if ( T->strict == -3 ) {
×
1932
                                                                rhsnumber = AM.onerhs;
×
1933
                                                                tbufnum = AM.zbufnum;
×
1934
                                                        }
1935
                                                        else if ( T->strict < 0 ) goto NextFun;
×
1936
                                                        else {
1937
                                                                MLOCK(ErrorMessageLock);
×
1938
                                                                MesPrint("Element in table is undefined");
×
1939
                                                                if ( Tpattern ) {
×
1940
                                                                        TermFree(Tpattern,"Tpattern");
×
1941
                                                                        Tpattern = 0;
×
1942
                                                                }
1943
                                                                goto showtable;
×
1944
                                                        }
1945
/*
1946
                                                        Copy the indices;
1947
*/
1948
                                                        t = t1+FUNHEAD+1;
×
1949
                                                        for ( i = 0; i < xx; i++ ) {
×
1950
                                                                *p = *t; p+=2; t+=2;
×
1951
                                                        }
1952
                                                }
1953
                                                else {
1954
                                                        rhsnumber = T->tablepointers[isp+ABS(T->numind)];
70✔
1955
#if ( TABLEEXTENSION == 2 )
1956
                                                        tbufnum = T->bufnum;
1957
#else
1958
                                                        tbufnum = T->tablepointers[isp+ABS(T->numind)+1];
70✔
1959
#endif
1960
                                                        t = t1+FUNHEAD+1;
70✔
1961
                                                        ii = xx;
70✔
1962
                                                        while ( --ii >= 0 ) {
140✔
1963
                                                                *p = *t; t += 2; p += 2;
70✔
1964
                                                        }
1965
                                                }
1966
                                                if ( xx < ABS(T->numind) ) {
70✔
1967
                                                        p--; ppstop = Tpattern+Tpattern[1];
×
1968
                                                        pp = p+2*(-T->numind-xx);
×
1969
                                                        while ( pp < ppstop ) *p++ = *pp++;
×
1970
                                                        Tpattern[1] = p - Tpattern;
×
1971
                                                }
1972
                                                goto caughttable;
70✔
1973
                                        }
1974
                                        else {
1975
                                                i = 0;
666✔
1976
                                                t = t1 + FUNHEAD;
666✔
1977
                                                j = T->numind;
666✔
1978
                                                while ( --j >= 0 ) {
760✔
1979
                                                        if ( *t != -SNUMBER ) goto NextFun;
94✔
1980
                                                        t++;
94✔
1981
                                                        if ( *t < mm->mini || *t > mm->maxi ) {
94✔
1982
                                                                if ( T->bounds ) {
×
1983
                                                                        MLOCK(ErrorMessageLock);
×
1984
                                                                        MesPrint("Table boundary check. Argument %d",
×
1985
                                                                        T->numind-j);
×
1986
showtable:                                                        AO.OutFill = AO.OutputLine = (UBYTE *)m;
×
1987
                                                                        AO.OutSkip = 8;
×
1988
                                                                        IniLine(0);
×
1989
                                                                        WriteSubTerm(t1,1);
×
1990
                                                                        FiniLine();
×
1991
                                                                        MUNLOCK(ErrorMessageLock);
×
1992
                                                                        if ( Tpattern ) {
×
1993
                                                                                TermFree(Tpattern,"Tpattern");
×
1994
                                                                                Tpattern = 0;
×
1995
                                                                        }
1996
                                                                        SETERROR(-1)
×
1997
                                                                }
1998
                                                                if ( Tpattern ) {
×
1999
                                                                        TermFree(Tpattern,"Tpattern");
×
2000
                                                                        Tpattern = 0;
×
2001
                                                                }
2002
                                                                goto NextFun;
×
2003
                                                        }
2004
                                                        i += ( *t - mm->mini ) * (LONG)(mm->size);
94✔
2005
                                                        *p = *t++;
94✔
2006
                                                        p += 2;
94✔
2007
                                                        mm++;
94✔
2008
                                                }
2009
/*
2010
                                                Test now whether the entry exists.
2011
*/
2012
                                                i *= TABLEEXTENSION;
666✔
2013
                                                if ( T->tablepointers[i] == -1 ) {
666✔
2014
                                                        if ( T->strict == -2 ) {
×
2015
                                                                rhsnumber = AM.zerorhs;
×
2016
                                                                tbufnum = AM.zbufnum;
×
2017
                                                        }
2018
                                                        else if ( T->strict == -3 ) {
×
2019
                                                                rhsnumber = AM.onerhs;
×
2020
                                                                tbufnum = AM.zbufnum;
×
2021
                                                        }
2022
                                                        else if ( T->strict < 0 ) {
×
2023
                                                                if ( Tpattern ) {
×
2024
                                                                        TermFree(Tpattern,"Tpattern");
×
2025
                                                                        Tpattern = 0;
×
2026
                                                                }
2027
                                                                goto NextFun;
×
2028
                                                        }
2029
                                                        else {
2030
                                                                MLOCK(ErrorMessageLock);
×
2031
                                                                MesPrint("Element in table is undefined");
×
2032
                                                                if ( Tpattern ) {
×
2033
                                                                        TermFree(Tpattern,"Tpattern");
×
2034
                                                                        Tpattern = 0;
×
2035
                                                                }
2036
                                                                goto showtable;
×
2037
                                                        }
2038
                                                }
2039
                                                else {
2040
                                                        rhsnumber = T->tablepointers[i];
666✔
2041
#if ( TABLEEXTENSION == 2 )
2042
                                                        tbufnum = T->bufnum;
2043
#else
2044
                                                        tbufnum = T->tablepointers[i+1];
666✔
2045
#endif
2046
                                                }
2047
                                        }
2048
/*
2049
                                        If there are more arguments we have to do some
2050
                                        pattern matching. This should be easy. We adapted the
2051
                                        pattern, so that the array indices match already.
2052
                                        Note that if there is no match the program will become
2053
                                        very slow.
2054
*/
2055
caughttable:
736✔
2056
#ifdef WITHPTHREADS
2057
                                        AN.FullProto = T->prototype[AT.identity];
354✔
2058
#else
2059
                                        AN.FullProto = T->prototype;
382✔
2060
#endif
2061
                                        AN.WildValue = AN.FullProto + SUBEXPSIZE;
736✔
2062
                                        AN.WildStop = AN.FullProto+AN.FullProto[1];
736✔
2063
                                        ClearWild(BHEAD0);
736✔
2064
                                        AN.RepFunNum = 0;
736✔
2065
                                        AN.RepFunList = AN.EndNest;
736✔
2066
                                    AT.WorkPointer = (WORD *)(((UBYTE *)(AN.EndNest)) + AM.MaxTer/2);
736✔
2067
                                        if ( AT.WorkPointer >= AT.WorkTop ) {
736✔
2068
                                                MLOCK(ErrorMessageLock);
×
2069
                                                MesWork();
×
2070
                                                MUNLOCK(ErrorMessageLock);
177✔
2071
                                        }
2072
                                        wilds = 0;
736✔
2073
                                        if ( MatchFunction(BHEAD Tpattern,t1,&wilds) > 0 ) {
736✔
2074
                                                AT.WorkPointer = oldwork;
736✔
2075
                                                if ( AT.NestPoin != AT.Nest ) {
736✔
2076
                                                        AN.ncmod = oldncmod;
×
2077
                                                        if ( Tpattern ) {
×
2078
                                                                TermFree(Tpattern,"Tpattern");
×
2079
                                                                Tpattern = 0;
×
2080
                                                        }
2081
                                                        DONE(1)
×
2082
                                                }
2083

2084
                                                m = AN.FullProto;
736✔
2085
                                                retvalue = m[2] = rhsnumber;
736✔
2086
                                                m[4] = tbufnum;
736✔
2087
                                                t = t1;
736✔
2088
                                                j = t[1];
736✔
2089
                                                i = m[1];
736✔
2090
                                                if ( j > i ) {
736✔
2091
                                                        j = i - j;
572✔
2092
                                                        NCOPY(t,m,i);
12,568✔
2093
                                                        m = term + *term;
572✔
2094
                                                        while ( r < m ) *t++ = *r++;
2,288✔
2095
                                                        *term += j;
572✔
2096
                                                }
2097
                                                else if ( j < i ) {
164✔
2098
                                                        j = i-j;
×
2099
                                                        t = term + *term;
×
2100
                                                        while ( t >= r ) { t[j] = *t; t--; }
×
2101
                                                        t = t1;
2102
                                                        NCOPY(t,m,i);
×
2103
                                                        *term += j;
×
2104
                                                }
2105
                                                else {
2106
                                                        NCOPY(t,m,j);
984✔
2107
                                                }
2108
                                                AN.TeInFun = 0;
736✔
2109
                                                AR.TePos = 0;
736✔
2110
                                                AN.TeSuOut = -1;
736✔
2111
                                                if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
736✔
2112
                                                AT.TMbuff = tbufnum;
736✔
2113
                                                AN.ncmod = oldncmod;
736✔
2114
                                                DONE(retvalue);
736✔
2115
                                        }
2116
                                        AT.WorkPointer = oldwork;
×
2117
                                        if ( Tpattern ) {
×
2118
                                                TermFree(Tpattern,"Tpattern");
×
2119
                                                Tpattern = 0;
×
2120
                                        }
2121
                                }
2122
NextFun:;
61,939,600✔
2123
                        }
2124
                        else if ( ( t[2] & DIRTYFLAG ) != 0 ) {
10,796✔
2125
                                t += FUNHEAD;
8,676✔
2126
                                while ( t < r ) {
52,880✔
2127
                                        if ( *t == FUNNYDOLLAR ) {
44,204✔
2128
                                                if ( AR.Eside != LHSIDE ) {
×
2129
                                                        AN.TeInFun = 1;
×
2130
                                                        AR.TePos = 0;
×
2131
                                                        AT.TMbuff = AM.dbufnum;
×
2132
                                                        AN.ncmod = oldncmod;
×
2133
                                                        DONE(1)
×
2134
                                                }
2135
                                                AC.lhdollarflag = 1;
×
2136
                                        }
2137
                                        t++;
44,204✔
2138
                                }
2139
                        }
2140
                        t = r;
61,950,400✔
2141
                        AN.ncmod = oldncmod;
61,950,400✔
2142
                } while ( t < m );
65,275,300✔
2143
        }
2144
Done:
24,517,370✔
2145
        if ( Tpattern ) {
37,041,840✔
2146
                TermFree(Tpattern,"Tpattern");
736✔
2147
                Tpattern = 0;
736✔
2148
        }
2149
        return(retvalue);
2150
EndTest:;
×
2151
        MLOCK(ErrorMessageLock);
×
2152
EndTest2:;
×
2153
        MesCall("TestSub");
×
2154
        MUNLOCK(ErrorMessageLock);
×
2155
        SETERROR(-1)
×
2156
}
2157

2158
/*
2159
                 #] TestSub : 
2160
                 #[ InFunction :                        WORD InFunction(term,termout)
2161
*/
2162
/**
2163
 *                Makes the replacement of the subexpression with the number 'replac'
2164
 *                in a function argument. Additional information is passed in some
2165
 *                of the AR, AN, AT variables.
2166
 *
2167
 *                @param term     The input term
2168
 *                @param termout  The output term
2169
 *                @return         0: everything is fine, Negative: fatal, Positive: error.
2170
 *
2171
 *                Special attention should be given to nested functions!
2172
 */
2173

2174
WORD InFunction(PHEAD WORD *term, WORD *termout)
1,216,819✔
2175
{
2176
        GETBIDENTITY
2177
        WORD *m, *t, *r, *rr, sign = 1, oldncmod;
1,216,819✔
2178
        WORD *u, *v, *w, *from, *to, 
1,216,819✔
2179
                ipp, olddefer = AR.DeferFlag, oldPolyFun = AR.PolyFun, i, j;
1,216,819✔
2180
        LONG numterms;
1,216,819✔
2181
        from = t = term;
1,216,819✔
2182
        r = t + *t - 1;
1,216,819✔
2183
        m = r - ABS(*r) + 1;
1,216,819✔
2184
        t++;
1,216,819✔
2185
        while ( t < m ) {
27,008,090✔
2186
                if ( *t >= FUNCTION+WILDOFFSET ) ipp = *t - WILDOFFSET;
27,008,090✔
2187
                else ipp = *t;
2188
                if ( AR.TePos ) {
27,008,090✔
2189
                        if ( ( term + AR.TePos ) == t ) {
2,458✔
2190
                                m = termout;
2191
                                while ( from < t ) *m++ = *from++;
8,579✔
2192
                                *m++ = DENOMINATOR;
1,237✔
2193
                                *m++ = t[1] + 4 + FUNHEAD + ARGHEAD;
1,237✔
2194
                                *m++ = DIRTYFLAG;
1,237✔
2195
                                FILLFUN3(m)
2196
                                *m++ = t[1] + 4 + ARGHEAD;
1,237✔
2197
                                *m++ = 1;
1,237✔
2198
                                FILLARG(m)
2199
                                *m++ = t[1] + 4;
1,237✔
2200
                                t[3] = -t[3];
1,237✔
2201
                                v = t + t[1];
1,237✔
2202
                                while ( t < v ) *m++ = *t++;
7,422✔
2203
                                from[3] = -from[3];
1,237✔
2204
                                *m++ = 1;
1,237✔
2205
                                *m++ = 1;
1,237✔
2206
                                *m++ = 3;
1,237✔
2207
                                r = term + *term;
1,237✔
2208
                                while ( t < r ) *m++ = *t++;
4,996✔
2209
                                if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
1,237✔
2210
                                *termout = WORDDIF(m,termout);
1,237✔
2211
                                return(0);
1,237✔
2212
                        }
2213
                }
2214
                else if ( ( *t >= FUNCTION && functions[ipp-FUNCTION].spec <= 0 )
27,005,630✔
2215
                && ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) {
26,961,740✔
2216
                        m = termout;
26,943,900✔
2217
                        r = t + t[1];
26,943,900✔
2218
                        u = t;
26,943,900✔
2219
                        t += FUNHEAD;
26,943,900✔
2220
                        oldncmod = AN.ncmod;
26,943,900✔
2221
                        while ( t < r ) {        /* t points at an argument */
53,017,900✔
2222
                                if ( *t > 0 && t[1] ) {        /* Argument has been modified */
27,289,500✔
2223
                                        WORD oldsorttype = AR.SortType;
1,213,282✔
2224
                                        /* This whole argument must be redone */
2225

2226
                                        if ( ( AN.ncmod != 0 )
1,213,282✔
2227
                                                && ( ( AC.modmode & ALSOFUNARGS ) == 0 )
×
2228
                                                && ( *u != AR.PolyFun ) ) { AN.ncmod = 0; }
×
2229
                                        AR.DeferFlag = 0;
1,213,282✔
2230
                                        v = t + *t;
1,213,282✔
2231
                                        t += ARGHEAD;                /* First term */
1,213,282✔
2232
                                        w = 0;        /* to appease the compilers warning devices */
1,213,282✔
2233
                                        while ( from < t ) {
438,378,000✔
2234
                                                if ( from == u ) w = m;
437,164,000✔
2235
                                                *m++ = *from++;
437,164,000✔
2236
                                        }
2237
                                        to = m;
1,213,282✔
2238
                                        NewSort(BHEAD0);
1,213,282✔
2239
                                        if ( *u == AR.PolyFun && AR.PolyFunType == 2 ) {
1,213,282✔
2240
                                                AR.CompareRoutine = (COMPAREDUMMY)(&CompareSymbols);
39,039✔
2241
                                                AR.SortType = SORTHIGHFIRST;
39,039✔
2242
                                        }
2243
/*
2244
                                        AR.PolyFun = 0;
2245
*/
2246
                                        while ( t < v ) {
2,473,996✔
2247
                                                i = *t;
1,260,714✔
2248
                                                NCOPY(m,t,i);
15,213,720✔
2249
                                                m = to;
1,260,714✔
2250
                        if ( AT.WorkPointer < m+*m ) AT.WorkPointer = m + *m;
1,260,714✔
2251
                                                if ( Generator(BHEAD m,AR.Cnumlhs) ) {
1,260,714✔
2252
                                                        AN.ncmod = oldncmod;
×
2253
                                                        LowerSortLevel(); goto InFunc;
×
2254
                                                }
2255
                                        }
2256
                                        /* w = the function */
2257
                                        /* v = the next argument */
2258
                                        /* u = the function */
2259
                                        /* to is new argument */
2260

2261
                                        to -= ARGHEAD;
1,213,282✔
2262
                                        if ( EndSort(BHEAD m,1) < 0 ) {
1,213,282✔
2263
                                                AN.ncmod = oldncmod;
×
2264
                                                goto InFunc;
×
2265
                                        }
2266
                                        AR.PolyFun = oldPolyFun;
1,213,282✔
2267
                                        if ( *u == AR.PolyFun && AR.PolyFunType == 2 ) {
1,213,282✔
2268
                                                AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
39,039✔
2269
                                                AR.SortType = oldsorttype;
39,039✔
2270
                                        }
2271
                                        while ( *m ) m += *m;
3,621,281✔
2272
                                        *to = WORDDIF(m,to);
1,213,282✔
2273
                                        to[1] = 1;  /* ??????? or rather 0?. 24-mar-2006 JV */
1,213,282✔
2274
                                        if ( ToFast(to,to) ) {
1,213,282✔
2275
                                                if ( *to <= -FUNCTION ) m = to+1;
143,591✔
2276
                                                else m = to+2;
143,591✔
2277
                                        }
2278
                                        w[1] = WORDDIF(m,w) + WORDDIF(r,v);
1,213,282✔
2279
                                        r = term + *term;
1,213,282✔
2280
                                        t = v;
1,213,282✔
2281
                                        while ( t < r ) *m++ = *t++;
367,652,000✔
2282
                                        if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
1,213,282✔
2283
                                        *termout = WORDDIF(m,termout);
1,213,282✔
2284
                                        AR.DeferFlag = olddefer;
1,213,282✔
2285
                                        AN.ncmod = oldncmod;
1,213,282✔
2286
                                        return(0);
1,213,282✔
2287
                                }
2288
                                else if ( *t == -DOLLAREXPRESSION ) {
26,076,210✔
2289
                                        if ( AR.Eside == LHSIDE ) {
2,300✔
2290
                                                NEXTARG(t)
×
2291
                                                AC.lhdollarflag = 1;
×
2292
                                        }
2293
                                        else {
2294
/*
2295
                                                This whole argument must be redone
2296
*/
2297
                                        DOLLARS d = Dollars + t[1];
2,300✔
2298
#ifdef WITHPTHREADS
2299
                                        int nummodopt, dtype = -1;
1,150✔
2300
                                        if ( AS.MultiThreaded ) {
1,150✔
2301
                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
4✔
2302
                                                        if ( t[1] == ModOptdollars[nummodopt].number ) break;
2303
                                                }
2304
                                                if ( nummodopt < NumModOptdollars ) {
4✔
2305
                                                        dtype = ModOptdollars[nummodopt].type;
2306
                                                        if ( dtype == MODLOCAL ) {
2307
                                                                d = ModOptdollars[nummodopt].dstruct+AT.identity;
2308
                                                        }
2309
                                                        else {
2310
                                                                LOCK(d->pthreadslockread);
2311
                                                        }
2312
                                                }
2313
                                        }
2314
#endif
2315
                                        oldncmod = AN.ncmod;
2,300✔
2316
                                        if ( ( AN.ncmod != 0 )
2,300✔
2317
                                                && ( ( AC.modmode & ALSOFUNARGS ) == 0 )
×
2318
                                                && ( *u != AR.PolyFun ) ) { AN.ncmod = 0; }
×
2319
                                        AR.DeferFlag = 0;
2,300✔
2320
                                        v = t + 2;
2,300✔
2321
                                        w = 0;        /* to appease the compilers warning devices */
2,300✔
2322
                                        while ( from < t ) {
114,012✔
2323
                                                if ( from == u ) w = m;
111,712✔
2324
                                                *m++ = *from++;
111,712✔
2325
                                        }
2326
                                        to = m;
2,300✔
2327
                                        switch ( d->type ) {
2,300✔
2328
                                                case DOLINDEX:
×
2329
                                                        if ( d->index >= 0 && d->index < AM.OffsetIndex ) {
×
2330
                                                                *m++ = -SNUMBER; *m++ = d->index;
×
2331
                                                        }
2332
                                                        else { *m++ = -INDEX; *m++ = d->index; }
×
2333
                                                        break;
2334
                                                case DOLZERO:
8✔
2335
                                                        *m++ = -SNUMBER; *m++ = 0; break;
8✔
2336
                                                case DOLNUMBER:
2,244✔
2337
                                                        if ( d->where[0] == 4 &&
2,244✔
2338
                                                        ( d->where[1] & MAXPOSITIVE ) == d->where[1] ) {
2,244✔
2339
                                                                *m++ = -SNUMBER;
2,244✔
2340
                                                                if ( d->where[3] >= 0 ) *m++ = d->where[1];
2,244✔
2341
                                                                else *m++ = -d->where[1];
×
2342
                                                                break;
2343
                                                        }
2344
                                                        /* fall through */
2345
                                                case DOLTERMS:
2346
/*
2347
                                                        Here we have the special case of the PolyRatFun
2348
                                                        That function may have a different sort of the
2349
                                                        terms in the argument.
2350
*/
2351
                                                        to = m; r = d->where;
40✔
2352
                                                        *m++ = 0; *m++ = 1;
40✔
2353
                                                        FILLARG(m)
2354
                                                        while ( *r ) {
84✔
2355
                                                                i = *r; NCOPY(m,r,i)
396✔
2356
                                                        }
2357
                                                        *to = m-to;
40✔
2358
                                                        if ( ToFast(to,to) ) {
40✔
2359
                                                                if ( *to <= -FUNCTION ) m = to+1;
32✔
2360
                                                                else m = to+2;
32✔
2361
                                                        }
2362
                                                        else if ( *u == AR.PolyFun && AR.PolyFunType == 2 ) {
8✔
2363
                                                                AR.PolyFun = 0;
×
2364
                                                                NewSort(BHEAD0);
×
2365
                                                                AR.CompareRoutine = (COMPAREDUMMY)(&CompareSymbols);
×
2366
                                                                r = to + ARGHEAD;
×
2367
                                                                while ( r < m ) {
×
2368
                                                                        rr = r; r += *r;
×
2369
                                                                        if ( SymbolNormalize(rr) ) goto InFunc;
×
2370
                                                                        if ( StoreTerm(BHEAD rr) ) {
×
2371
                                                                                AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
×
2372
                                                                                LowerSortLevel();
×
NEW
2373
                                                                                TERMINATE(-1);
×
2374
                                                                        }
2375
                                                                }
2376
                                                                if ( EndSort(BHEAD to+ARGHEAD,1) < 0 ) goto InFunc;
×
2377
                                                                AR.PolyFun = oldPolyFun;
×
2378
                                                                AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
×
2379
                                                                m = to+ARGHEAD;
×
2380
                                                                if ( *m == 0 ) {
×
2381
                                                                        *to = -SNUMBER;
×
2382
                                                                        to[1] = 0;
×
2383
                                                                        m = to + 2;
×
2384
                                                                }
2385
                                                                else {
2386
                                                                        while ( *m ) m += *m;
×
2387
                                                                        *t = m - to;
×
2388
                                                                        if ( ToFast(to,to) ) {
×
2389
                                                                                if ( *to <= -FUNCTION ) m = to+1;
×
2390
                                                                                else m = to+2;
×
2391
                                                                        }
2392
                                                                }
2393
                                                        }
2394
                                                        w[1] = w[1] - 2 + (m-to);
40✔
2395
                                                        break;
40✔
2396
                                                case DOLSUBTERM:
×
2397
                                                        to = m; r = d->where;
×
2398
                                                        i = r[1];
×
2399
                                                        *m++ = i+4+ARGHEAD; *m++ = 1;
×
2400
                                                        FILLARG(m)
2401
                                                        *m++ = i+4;
×
2402
                                                        while ( --i >= 0 ) *m++ = *r++;
×
2403
                                                        *m++ = 1; *m++ = 1; *m++ = 3;
×
2404
                                                        if ( ToFast(to,to) ) {
×
2405
                                                                if ( *to <= -FUNCTION ) m = to+1;
×
2406
                                                                else m = to+2;
×
2407
                                                        }
2408
                                                        w[1] = w[1] - 2 + (m-to);
×
2409
                                                        break;
×
2410
                                                case DOLARGUMENT:
×
2411
                                                        to = m; r = d->where;
×
2412
                                                        if ( *r > 0 ) {
×
2413
                                                                i = *r - 2;
×
2414
                                                                *m++ = *r++; *m++ = 1; r++;
×
2415
                                                                while ( --i >= 0 ) *m++ = *r++;
×
2416
                                                        }
2417
                                                        else if ( *r <= -FUNCTION ) *m++ = *r++;
×
2418
                                                        else { *m++ = *r++; *m++ = *r++; }
×
2419
                                                        w[1] = w[1] - 2 + (m-to);
×
2420
                                                        break;
×
2421
                                                case DOLWILDARGS:
8✔
2422
                                                        to = m; r = d->where;
8✔
2423
                                                        if ( *r > 0 ) { /* Tensor arguments */
8✔
2424
                                                                i = *r++;
×
2425
                                                                while ( --i >= 0 ) {
×
2426
                                                                        if ( *r < 0 ) {
×
2427
                                                                                *m++ = -VECTOR; *m++ = *r++;
×
2428
                                                                        }
2429
                                                                        else if ( *r >= AM.OffsetIndex ) {
×
2430
                                                                                *m++ = -INDEX; *m++ = *r++;
×
2431
                                                                        }
2432
                                                                        else { *m++ = -SNUMBER; *m++ = *r++; }
×
2433
                                                                }
2434
                                                        }
2435
                                                        else { /* Regular arguments */
2436
                                                                r++;
8✔
2437
                                                                while ( *r ) {
44✔
2438
                                                                        if ( *r > 0 ) {
36✔
2439
                                                                                i = *r - 2;
×
2440
                                                                                *m++ = *r++; *m++ = 1; r++;
×
2441
                                                                                while ( --i >= 0 ) *m++ = *r++;
×
2442
                                                                        }
2443
                                                                        else if ( *r <= -FUNCTION ) *m++ = *r++;
36✔
2444
                                                                        else { *m++ = *r++; *m++ = *r++; }
36✔
2445
                                                                }
2446
                                                        }
2447
                                                        w[1] = w[1] - 2 + (m-to);
8✔
2448
                                                        break;
8✔
2449
                                                case DOLUNDEFINED:
×
2450
                                                default:
2451
                                                        MLOCK(ErrorMessageLock);
×
2452
                                                        MesPrint("!!!Undefined $-variable: $%s!!!",
×
2453
                                                        AC.dollarnames->namebuffer+d->name);
×
2454
                                                        MUNLOCK(ErrorMessageLock);
×
2455
#ifdef WITHPTHREADS
2456
                                                        if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2457
#endif
NEW
2458
                                                        TERMINATE(-1);
×
2459
                                        }
2460
#ifdef WITHPTHREADS
2461
                                        if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
1,150✔
2462
#endif
2463
                                        r = term + *term;
2,300✔
2464
                                        t = v;
2,300✔
2465
                                        while ( t < r ) *m++ = *t++;
9,508✔
2466
                                        if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
2,300✔
2467
                                        *termout = WORDDIF(m,termout);
2,300✔
2468
                                        AR.DeferFlag = olddefer;
2,300✔
2469
                                        AN.ncmod = oldncmod;
2,300✔
2470
                                        return(0);
2,300✔
2471
                                }
2472
                                }
2473
                                else if ( *t == -TERMSINBRACKET ) {
26,073,930✔
2474
                                        if ( AC.ComDefer ) numterms = CountTerms1(BHEAD0);
×
2475
                                        else               numterms = 1;
2476
/*
2477
                                        Compose the output term
2478
                                        First copy the part till this function argument
2479
                                        m points at the output term space
2480
                                        u points at the start of the function
2481
                                        t points at the start of the argument
2482
*/
2483
                                        w = 0;
×
2484
                                        while ( from < t ) {
×
2485
                                                if ( from == u ) w = m;
×
2486
                                                *m++ = *from++;
×
2487
                                        }
2488
                                        if ( ( numterms & MAXPOSITIVE ) == numterms ) {
×
2489
                                                *m++ = -SNUMBER; *m++ =  numterms & MAXPOSITIVE;
×
2490
                                                w[1] += 1;
×
2491
                                        }
2492
                                        else if ( ( i = numterms >> BITSINWORD ) == 0 ) {
×
2493
                                                *m++ = ARGHEAD+4;
×
2494
                                                for ( j = 1; j < ARGHEAD; j++ ) *m++ = 0;
×
2495
                                                *m++ = 4; *m++ = numterms & WORDMASK; *m++ = 1; *m++ = 3;
×
2496
                                                w[1] += ARGHEAD+3;
×
2497
                                        }
2498
                                        else {
2499
                                                *m++ = ARGHEAD+6;
×
2500
                                                for ( j = 1; j < ARGHEAD; j++ ) *m++ = 0;
×
2501
                                                *m++ = 6; *m++ = numterms & WORDMASK;
×
2502
                                                *m++ = i; *m++ = 1; *m++ = 0; *m++ = 5;
×
2503
                                                w[1] += ARGHEAD+5;
×
2504
                                        }
2505
                                        from++;  /* Skip our function */
×
2506
                                        r = term + *term;
×
2507
                                        while ( from < r ) *m++ = *from++;
×
2508
                                        if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
×
2509
                                        *termout = WORDDIF(m,termout);
×
2510
                                        return(0);
×
2511
                                }
2512
                                else { NEXTARG(t) }
26,073,930✔
2513
                        }
2514
                        t = u;
2515
                }
2516
                else if ( ( *t >= FUNCTION && functions[ipp-FUNCTION].spec > 0 )
61,726✔
2517
                && ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) { /* Could be FUNNYDOLLAR */
×
2518
                        u = t; v = t + t[1];
×
2519
                        t += FUNHEAD;
×
2520
                        while ( t < v ) {
×
2521
                                if ( *t == FUNNYDOLLAR ) {
×
2522
                                        if ( AR.Eside != LHSIDE ) {
×
2523
                                        DOLLARS d = Dollars + t[1];
×
2524
#ifdef WITHPTHREADS
2525
                                        int nummodopt, dtype = -1;
2526
                                        if ( AS.MultiThreaded ) {
2527
                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
2528
                                                        if ( t[1] == ModOptdollars[nummodopt].number ) break;
2529
                                                }
2530
                                                if ( nummodopt < NumModOptdollars ) {
2531
                                                        dtype = ModOptdollars[nummodopt].type;
2532
                                                        if ( dtype == MODLOCAL ) {
2533
                                                                d = ModOptdollars[nummodopt].dstruct+AT.identity;
2534
                                                        }
2535
                                                        else {
2536
                                                                LOCK(d->pthreadslockread);
2537
                                                        }
2538
                                                }
2539
                                        }
2540
#endif
2541
                                        oldncmod = AN.ncmod;
×
2542
                                        if ( ( AN.ncmod != 0 )
×
2543
                                                && ( ( AC.modmode & ALSOFUNARGS ) == 0 )
×
2544
                                                && ( *u != AR.PolyFun ) ) { AN.ncmod = 0; }
×
2545
                                        m = termout; w = 0;
2546
                                        while ( from < t ) {
×
2547
                                                if ( from == u ) w = m;
×
2548
                                                *m++ = *from++;
×
2549
                                        }
2550
                                        to = m;
×
2551
                                        switch ( d->type ) {
×
2552
                                                case DOLINDEX:
×
2553
                                                        *m++ = d->index; break;
×
2554
                                                case DOLZERO:
×
2555
                                                        *m++ = 0; break;
×
2556
                                                case DOLNUMBER:
×
2557
                                                case DOLTERMS:
2558
                                                        if ( d->where[0] == 4 && d->where[4] == 0
×
2559
                                                        && d->where[3] == 3 && d->where[2] == 1
×
2560
                                                        && d->where[1] < AM.OffsetIndex ) {
×
2561
                                                                *m++ = d->where[1];
×
2562
                                                        }
2563
                                                        else {
2564
wrongtype:;
×
2565
#ifdef WITHPTHREADS
2566
                                                                if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2567
#endif
2568
                                                                MLOCK(ErrorMessageLock);
×
2569
                                                                MesPrint("$%s has wrong type for tensor substitution",
×
2570
                                                                AC.dollarnames->namebuffer+d->name);
×
2571
                                                                MUNLOCK(ErrorMessageLock);
×
2572
                                                                AN.ncmod = oldncmod;
×
2573
                                                                return(-1);
×
2574
                                                        }
2575
                                                        break;
×
2576
                                                case DOLARGUMENT:
×
2577
                                                        if ( d->where[0] == -INDEX ) {
×
2578
                                                                *m++ = d->where[1]; break;
×
2579
                                                        }
2580
                                                        else if ( d->where[0] == -VECTOR ) {
×
2581
                                                                *m++ = d->where[1]; break;
×
2582
                                                        }
2583
                                                        else if ( d->where[0] == -MINVECTOR ) {
×
2584
                                                                *m++ = d->where[1];
×
2585
                                                                sign = -sign;
×
2586
                                                                break;
×
2587
                                                        }
2588
                                                        else if ( d->where[0] == -SNUMBER ) {
×
2589
                                                                if ( d->where[1] >= 0
×
2590
                                                                && d->where[1] < AM.OffsetIndex ) {
×
2591
                                                                        *m++ = d->where[1]; break;
×
2592
                                                                }
2593
                                                        }
2594
                                                        goto wrongtype;
×
2595
                                                case DOLWILDARGS:
×
2596
                                                        if ( d->where[0] > 0 ) {
×
2597
                                                                r = d->where; i = *r++;
×
2598
                                                                while ( --i >= 0 ) *m++ = *r++;
×
2599
                                                        }
2600
                                                        else {
2601
                                                                r = d->where + 1;
×
2602
                                                                while ( *r ) {
×
2603
                                                                        if ( *r == -INDEX ) {
×
2604
                                                                                *m++ = r[1]; r += 2; continue;
×
2605
                                                                        }
2606
                                                                        else if ( *r == -VECTOR ) {
×
2607
                                                                                *m++ = r[1]; r += 2; continue;
×
2608
                                                                        }
2609
                                                                        else if ( *r == -MINVECTOR ) {
×
2610
                                                                                *m++ = r[1]; r += 2;
×
2611
                                                                                sign = -sign; continue;
×
2612
                                                                        }
2613
                                                                        else if ( *r == -SNUMBER ) {
×
2614
                                                                                if ( r[1] >= 0
×
2615
                                                                                && r[1] < AM.OffsetIndex ) {
×
2616
                                                                                        *m++ = r[1]; r += 2; continue;
×
2617
                                                                                }
2618
                                                                        }
2619
                                                                        goto wrongtype;
×
2620
                                                                }
2621
                                                        }
2622
                                                        break;
2623
                                                case DOLSUBTERM:
×
2624
                                                        r = d->where;
×
2625
                                                        if ( *r == INDEX && r[1] == 3 ) {
×
2626
                                                                *m++ = r[2];
×
2627
                                                        }
2628
                                                        else goto wrongtype;
×
2629
                                                        break;
×
2630
                                                case DOLUNDEFINED:
×
2631
#ifdef WITHPTHREADS
2632
                                                        if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2633
#endif
2634
                                                        MLOCK(ErrorMessageLock);
×
2635
                                                        MesPrint("$%s is undefined in tensor substitution",
×
2636
                                                        AC.dollarnames->namebuffer+d->name);
×
2637
                                                        MUNLOCK(ErrorMessageLock);
×
2638
                                                        AN.ncmod = oldncmod;
×
2639
                                                        return(-1);
×
2640
                                        }
2641
#ifdef WITHPTHREADS
2642
                                        if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2643
#endif
2644
                                        w[1] = w[1] - 2 + (m-to);
×
2645
                                        from += 2;
×
2646
                                        term += *term;
×
2647
                                        while ( from < term ) *m++ = *from++;
×
2648
                                        if ( sign < 0 ) m[-1] = -m[-1];
×
2649
                                        if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
×
2650
                                        *termout = m - termout;
×
2651
                                        AN.ncmod = oldncmod;
×
2652
                                        return(0);
×
2653
                                }
2654
                                else {
2655
                                        AC.lhdollarflag = 1;
×
2656
                                }
2657
                                }
2658
                                t++;
×
2659
                        }
2660
                        t = u;
2661
                }
2662
                t += t[1];
25,791,250✔
2663
        }
2664
        MLOCK(ErrorMessageLock);
×
2665
        MesPrint("Internal error in InFunction: Function not encountered.");
×
2666
        if ( AM.tracebackflag ) {
×
2667
                MesPrint("%w: AR.TePos = %d",AR.TePos);
×
2668
                MesPrint("%w: AN.TeInFun = %d",AN.TeInFun);
×
2669
                termout = term;
×
2670
                AO.OutFill = AO.OutputLine = (UBYTE *)AT.WorkPointer + AM.MaxTer;
×
2671
                AO.OutSkip = 3;
×
2672
                FiniLine();
×
2673
                i = *termout;
×
2674
                while ( --i >= 0 ) {
×
2675
                        TalToLine((UWORD)(*termout++));
×
2676
                        TokenToLine((UBYTE *)"  ");
×
2677
                }
2678
                AO.OutSkip = 0;
×
2679
                FiniLine();
×
2680
                MesCall("InFunction");
×
2681
        }
2682
        MUNLOCK(ErrorMessageLock);
2683
        return(1);
2684

2685
InFunc:
×
2686
        MLOCK(ErrorMessageLock);
×
2687
        MesCall("InFunction");
×
2688
        MUNLOCK(ErrorMessageLock);
×
2689
        SETERROR(-1)
×
2690

2691
TooLarge:
×
2692
        MLOCK(ErrorMessageLock);
×
2693
        MesPrint("Output term too large. Try to increase MaxTermSize in the setup.");
×
2694
        MesCall("InFunction");
×
2695
        MUNLOCK(ErrorMessageLock);
×
2696
        SETERROR(-1)
×
2697
}
2698
                 
2699
/*
2700
                 #] InFunction : 
2701
                 #[ InsertTerm :                        WORD InsertTerm(term,replac,extractbuff,position,termout)
2702
*/
2703
/**
2704
 *                Puts the terms 'term' and 'position' together into a single
2705
 *                legal term in termout. replac is the number of the subexpression
2706
 *                that should be replaced. It must be a positive term.
2707
 *                When action is needed in the argument of a function all terms
2708
 *                in that argument are dealt with recursively. The subexpression
2709
 *                is sorted. Only one subexpression is done at a time this way.
2710
 *
2711
 *                @param term        the input term
2712
 *                @param replac      number of the subexpression pointer to replace
2713
 *                @param extractbuff number of the compiler buffer replac refers to
2714
 *                @param position    position from where to take the term in the compiler buffer
2715
 *                @param termout     the output term
2716
 *                @param tepos       offset in term where the subexpression is.
2717
 *                @return  Normal conventions (OK = 0).
2718
 */
2719

2720
WORD InsertTerm(PHEAD WORD *term, WORD replac, WORD extractbuff, WORD *position, WORD *termout,
14,575,630✔
2721
                WORD tepos)
2722
{
2723
        GETBIDENTITY
2724
        WORD *m, *t, *r, i, l2, j;
14,575,630✔
2725
        WORD *u, *v, l1, *coef;
14,575,630✔
2726
        coef = AT.WorkPointer;
14,575,630✔
2727
        if ( ( AT.WorkPointer = coef + 2*AM.MaxTal ) > AT.WorkTop ) {
14,575,630✔
2728
                MLOCK(ErrorMessageLock);
×
2729
                MesWork();
×
2730
                MUNLOCK(ErrorMessageLock);
×
2731
                return(-1);
×
2732
        }
2733
        t = term;
14,575,630✔
2734
        r = t + *t;
14,575,630✔
2735
        l1 = l2 = r[-1];
14,575,630✔
2736
        m = r - ABS(l2);
14,575,630✔
2737
        if ( tepos > 0 ) {
14,575,630✔
2738
                t = term + tepos;
6,465,310✔
2739
                goto foundit;
6,465,310✔
2740
        }
2741
        t++;
8,110,340✔
2742
        while ( t < m ) {
16,218,660✔
2743
                if ( *t == SUBEXPRESSION && t[2] == replac && t[3] && t[4] == extractbuff ) {
8,110,420✔
2744
                        r = t + t[1];
2,086✔
2745
                        while ( *r == SUBEXPRESSION && r[2] == replac && r[3] && r < m && r[4] == extractbuff ) {
2,086✔
2746
                                t = r; r += r[1];
×
2747
                        }
2748
foundit:;
2,086✔
2749
                        u = m;
6,467,390✔
2750
                        r = term;
6,467,390✔
2751
                        m = termout;
6,467,390✔
2752
                        do { *m++ = *r++; } while ( r < t );
235,569,200✔
2753
                        if ( t[1] > SUBEXPSIZE ) {
6,467,390✔
2754
/*
2755
                                if this is a dollar expression there are no wildcards
2756
*/
2757
                                i = *--m;
2,017,616✔
2758
                                if ( ( l2 = WildFill(BHEAD m,position,t) ) < 0 ) goto InsCall;
2,017,616✔
2759
                                *m = i;
2,017,616✔
2760
                                m += l2-1;
2,017,616✔
2761
                                l2 = *m;
2,017,616✔
2762
                                i = ( j = ABS(l2) ) - 1;
2,017,616✔
2763
                                r = coef + i;
2,017,616✔
2764
                                do { *--r = *--m; } while ( --i > 0 );
4,035,244✔
2765
                        }
2766
                        else {
2767
                                v = t;
4,449,760✔
2768
                                t = position;
4,449,760✔
2769
                                r = t + *t;
4,449,760✔
2770
                                l2 = r[-1];
4,449,760✔
2771
                                r -= ( j = ABS(l2) );
4,449,760✔
2772
                                t++;
4,449,760✔
2773
                                if ( t < r ) do { *m++ = *t++; } while ( t < r );
9,719,510✔
2774
                                t = v;
2775
                        }
2776
                        t += t[1];
6,467,390✔
2777
                        while ( t < u && *t == DOLLAREXPR2 ) t += t[1];
6,467,750✔
2778
ComAct:                if ( t < u ) do { *m++ = *t++; } while ( t < u );
37,560,100✔
2779
                        if ( *r == 1 && r[1] == 1 && j == 3 ) {
14,575,630✔
2780
                                if ( l2 < 0 ) l1 = -l1;
11,353,330✔
2781
                                i = ABS(l1)-1;
11,353,330✔
2782
                                NCOPY(m,t,i);
34,732,350✔
2783
                                *m++ = l1;
11,353,330✔
2784
                        }
2785
                        else {
2786
                                if ( MulRat(BHEAD (UWORD *)u,REDLENG(l1),(UWORD *)r,REDLENG(l2),
3,222,313✔
2787
                                (UWORD *)m,&l1) ) goto InsCall;
×
2788
                                l2 = l1;
3,222,313✔
2789
                                l2 *= 2;
3,222,313✔
2790
                                if ( l2 < 0 ) {
3,222,313✔
2791
                                        m -= l2;
541,445✔
2792
                                        *m++ = l2-1;
541,445✔
2793
                                }
2794
                                else {
2795
                                        m += l2;
2,680,868✔
2796
                                        *m++ = l2+1;
2,680,868✔
2797
                                }
2798
                        }
2799
                        *termout = WORDDIF(m,termout);
14,575,630✔
2800
                        if ( (*termout)*((LONG)sizeof(WORD)) > AM.MaxTer ) {
14,575,630✔
2801
                                MLOCK(ErrorMessageLock);
×
2802
                                MesPrint("Term too complex during substitution. MaxTermSize of %l is too small",AM.MaxTer);
×
2803
                                goto InsCall2;
×
2804
                        }
2805
                        AT.WorkPointer = coef;
14,575,630✔
2806
                        return(0);
14,575,630✔
2807
                }
2808
                t += t[1];
8,108,320✔
2809
        }
2810
/*
2811
        The next action is for when there is no subexpression pointer.
2812
        We append the extra term. Effectively the routine becomes now a
2813
        merge routine for two terms.
2814
*/
2815
        v = t;
154,054,800✔
2816
        u = m;
154,054,800✔
2817
        r = term;
2818
        m = termout;
2819
        do { *m++ = *r++; } while ( r < t );
154,054,800✔
2820
        t = position;
8,108,240✔
2821
        r = t + *t;
8,108,240✔
2822
        l2 = r[-1];
8,108,240✔
2823
        r -= ( j = ABS(l2) );
8,108,240✔
2824
        t++;
8,108,240✔
2825
        if ( t < r ) do { *m++ = *t++; } while ( t < r );
8,108,800✔
2826
        t = v;
8,108,240✔
2827
        goto ComAct;
8,108,240✔
2828

2829
InsCall:
×
2830
        MLOCK(ErrorMessageLock);
×
2831
InsCall2:
×
2832
        MesCall("InsertTerm");
×
2833
        MUNLOCK(ErrorMessageLock);
×
2834
        SETERROR(-1)
×
2835
}
2836

2837
/*
2838
                 #] InsertTerm : 
2839
                 #[ PasteFile :                        WORD PasteFile(num,acc,pos,accf,renum,freeze,nexpr)
2840
*/
2841
/**
2842
 *                Gets a term from stored expression expr and puts it in
2843
 *                the accumulator at position number. It returns the length of the
2844
 *                term that came from file.
2845
 *
2846
 *                @param number   number of partial terms to skip in accum
2847
 *                @param accum    the accumulator
2848
 *                @param position file position from where to get the stored term
2849
 *                @param accfill  returns tail position in accum
2850
 *                @param renumber the renumber struct for the variables in the stored expression
2851
 *                @param freeze   information about if we need only the contents of a bracket
2852
 *                @param nexpr    the number of the stored expression
2853
 *                @return Normal conventions (OK = 0).
2854
 */
2855

2856
LONG PasteFile(PHEAD WORD number, WORD *accum, POSITION *position, WORD **accfill,
×
2857
               RENUMBER renumber, WORD *freeze, WORD nexpr)
2858
{
2859
        GETBIDENTITY
2860
        WORD *r, l, *m, i;
×
2861
        WORD *stop, *s1, *s2;
×
2862
/*        POSITION AccPos; bug 12-apr-2008 JV */
2863
        WORD InCompState;
×
2864
        WORD *oldipointer;
×
2865
        LONG retlength;
×
2866
    stop = (WORD *)(((UBYTE *)(accum)) + 2*AM.MaxTer);
×
2867
        *accum++ = number;
×
2868
        while ( --number >= 0 ) accum += *accum;
×
2869
        if ( freeze ) {
×
2870
/*                AccPos = *position; bug 12-apr-2008 JV */
2871
                oldipointer = AR.CompressPointer;
×
2872
                do {
×
2873
                        AR.CompressPointer = oldipointer;
×
2874
/*                        if ( ( l = GetFromStore(accum,&AccPos,renumber,&InCompState,nexpr) ) < 0 ) bug 12-apr-2008 JV */
2875
                        if ( ( l = GetFromStore(accum,position,renumber,&InCompState,nexpr) ) < 0 )
×
2876
                                goto PasErr;
×
2877
                        if ( !l ) { *accum = 0; return(0); }
×
2878
                        r = accum;
×
2879
                        m = r + *r;
×
2880
                        m -= ABS(m[-1]);
×
2881
                        r++;
×
2882
                        while ( r < m && *r != HAAKJE ) r += r[1];
×
2883
                        if ( r >= m ) {
×
2884
                                if ( *freeze != 4 ) l = -1;
×
2885
                        }
2886
                        else {
2887
/*
2888
                                The algorithm for accepting terms with a given (freeze)
2889
                                representation outside brackets is rather crude. A refinement
2890
                                would be to store the part outside the bracket and skip the
2891
                                term when this part doesn't alter (and is unacceptable).
2892
                                Once accepting one can keep accepting till the bracket alters
2893
                                and then one may stop the generation. It is necessary to
2894
                                set up a struct to remember the bracket and the progress
2895
                                status.
2896
*/
2897
                                m = AT.WorkPointer;
×
2898
                                s2 = r;
×
2899
                                r = accum;
×
2900
                                *m++ = WORDDIF(s2,r) + 3;
×
2901
                                r++;
×
2902
                                while ( r < s2 ) *m++ = *r++;
×
2903
                                *m++ = 1; *m++ = 1; *m++ = 3;
×
2904
                                m = AT.WorkPointer;
×
2905
                                if ( Normalize(BHEAD AT.WorkPointer) ) goto PasErr;
×
2906
                                r = freeze;
×
2907
                                i = *m;
×
2908
                                while ( --i >= 0 && *m++ == *r++ ) {}
×
2909
                                if ( i > 0 ) {
×
2910
                                        l = -1;
2911
                                }
2912
                                else {        /* Term to be accepted */
2913
                                        r = accum;
×
2914
                                        s1 = r + *r;
×
2915
                                        r++;
×
2916
                                        m = s2;
×
2917
                                        m += m[1];
×
2918
                                        do { *r++ = *m++; } while ( m < s1 );
×
2919
                                        *accum = l = WORDDIF(r,accum);
×
2920
                                }
2921
                        }
2922
                } while ( l < 0 );
×
2923
                retlength = InCompState;
×
2924
/*                retlength = DIFBASE(AccPos,*position) / sizeof(WORD);  bug 12-apr-2008 JV */
2925
        }
2926
        else {
2927
                if ( ( l = GetFromStore(accum,position,renumber,&InCompState,nexpr) ) < 0 ) {
×
2928
                        MLOCK(ErrorMessageLock);
×
2929
                        MesCall("PasteFile");
×
2930
                        MUNLOCK(ErrorMessageLock);
×
2931
                        SETERROR(-1)
×
2932
                }
2933
                if ( l == 0 ) { *accum = 0; return(0); }
×
2934
                retlength = InCompState;
×
2935
        }
2936
        accum += l;
×
2937
        if ( accum > stop ) {
×
2938
                MLOCK(ErrorMessageLock);
×
2939
                MesPrint("Buffer too small in PasteFile");
×
2940
                MUNLOCK(ErrorMessageLock);
×
2941
                SETERROR(-1)
×
2942
        }
2943
        *accum = 0;
×
2944
        *accfill = accum;
×
2945
        return(retlength);
×
2946
PasErr:
×
2947
        MLOCK(ErrorMessageLock);
×
2948
        MesCall("PasteFile");
×
2949
        MUNLOCK(ErrorMessageLock);
×
2950
        SETERROR(-1)
×
2951
}
2952
                 
2953
/*
2954
                 #] PasteFile : 
2955
                 #[ PasteTerm :                        WORD PasteTerm(number,accum,position,times,divby)
2956
*/
2957
/**
2958
 *                Puts the term at position in the accumulator accum at position
2959
 *                'number+1'. if times > 0 the coefficient of this term is
2960
 *                multiplied by times/divby.
2961
 *
2962
 *                @param number The number of term fragments in accum that should be skipped
2963
 *                @param accum  The accumulator of term fragments
2964
 *                @param position A position in (typically) a compiler buffer from where
2965
 *                                a (piece of a) term comes.
2966
 *                @param times  Multiply the result by this
2967
 *                @param divby  Divide the result by this.
2968
 *
2969
 *                This routine is typically used when we have to replace a (sub)expression
2970
 *                pointer by a power of a (sub)expression. This uses mostly a binomial
2971
 *                expansion and the new term is the old term multiplied one by one
2972
 *                by terms of the new expression. The factors times and divby keep track
2973
 *                of the binomial coefficient.
2974
 *                Once this is complete, the routine FiniTerm will make the contents
2975
 *                of the accumulator into a proper term that still needs to be normalized.
2976
 */
2977

2978
WORD *PasteTerm(PHEAD WORD number, WORD *accum, WORD *position, WORD times, WORD divby)
2,002,508✔
2979
{
2980
        GETBIDENTITY
2981
        WORD *t, *r, x, y, z;
2,002,508✔
2982
        WORD *m, *u, l1, a[2];
2,002,508✔
2983
    m = (WORD *)(((UBYTE *)(accum)) + AM.MaxTer);
2,002,508✔
2984
/*    m = (WORD *)(((UBYTE *)(accum)) + 2*AM.MaxTer); */
2985
        *accum++ = number;
2,002,508✔
2986
        while ( --number >= 0 ) accum += *accum;
34,539,920✔
2987
        if ( times == divby ) {
2,002,508✔
2988
                t = position;
1,006,056✔
2989
                r = t + *t;
1,006,056✔
2990
                if ( t < r ) do { *accum++ = *t++; } while ( t < r );
19,070,740✔
2991
        }
2992
        else {
2993
                u = accum;
996,452✔
2994
                t = position;
996,452✔
2995
                r = t + *t - 1;
996,452✔
2996
                l1 = *r;
996,452✔
2997
                r -= ABS(*r) - 1;
996,452✔
2998
                if ( t < r ) do { *accum++ = *t++; } while ( t < r );
5,016,740✔
2999
                if ( divby > times ) { x = divby; y = times; }
996,452✔
3000
                else { x = times; y = divby; }
996,452✔
3001
                z = x%y;
996,452✔
3002
                while ( z ) { x = y; y = z; z = x%y; }
2,331,463✔
3003
                if ( y != 1 ) { divby /= y; times /= y; }
996,452✔
3004
                a[1] = divby;
996,452✔
3005
                a[0] = times;
996,452✔
3006
                if ( MulRat(BHEAD (UWORD *)t,REDLENG(l1),(UWORD *)a,1,(UWORD *)accum,&l1) ) {
996,452✔
3007
                        MLOCK(ErrorMessageLock);
×
3008
                        MesCall("PasteTerm");
×
3009
                        MUNLOCK(ErrorMessageLock);
×
3010
                        return(0);
×
3011
                }
3012
                x = l1;
996,452✔
3013
                x *= 2;
996,452✔
3014
                if ( x < 0 ) { accum -= x; *accum++ = x - 1; }
996,452✔
3015
                else                 { accum += x; *accum++ = x + 1; }
993,280✔
3016
                *u = WORDDIF(accum,u);
996,452✔
3017
        }
3018
        if ( accum >= m ) {
2,002,508✔
3019
                MLOCK(ErrorMessageLock);
×
3020
                MesPrint("Buffer too small in PasteTerm");
×
3021
                MUNLOCK(ErrorMessageLock);
×
3022
                return(0);
×
3023
        }
3024
        *accum = 0;
2,002,508✔
3025
        return(accum);
2,002,508✔
3026
}
3027

3028
/*
3029
                 #] PasteTerm : 
3030
                 #[ FiniTerm :                        WORD FiniTerm(term,accum,termout,number)
3031
*/
3032
/**
3033
 *                Concatenates the contents of the accumulator into a single
3034
 *                legal term, which replaces the subexpression pointer
3035
 *
3036
 *                @param term    the input term with the (sub)expression subterm
3037
 *                @param accum   the accumulator with the term fragments
3038
 *                @param termout the location where the output should be written
3039
 *                @param number  the number of term fragments in the accumulator
3040
 *                @param tepos   the position of the subterm in term to be replaced
3041
 */
3042

3043
WORD FiniTerm(PHEAD WORD *term, WORD *accum, WORD *termout, WORD number, WORD tepos)
3,331,300✔
3044
{
3045
        GETBIDENTITY
3046
        WORD *m, *t, *r, i, numacc, l2, ipp;
3,331,300✔
3047
        WORD *u, *v, l1, *coef = AT.WorkPointer, *oldaccum;
3,331,300✔
3048
        if ( ( AT.WorkPointer = coef + 2*AM.MaxTal ) > AT.WorkTop ) {
3,331,300✔
3049
                MLOCK(ErrorMessageLock);
×
3050
                MesWork();
×
3051
                MUNLOCK(ErrorMessageLock);
×
3052
                return(-1);
×
3053
        }
3054
        oldaccum = accum;
3,331,300✔
3055
        t = term;
3,331,300✔
3056
        m = t + *t - 1;
3,331,300✔
3057
        l1 = REDLENG(*m);
3,331,300✔
3058
        i = ABS(*m) - 1;
3,331,300✔
3059
        r = coef + i;
3,331,300✔
3060
        do { *--r = *--m; } while ( --i > 0 ); /* Copies coefficient */
6,946,158✔
3061
        if ( tepos > 0 ) {
3,331,300✔
3062
                t = term + tepos;
233,311✔
3063
                goto foundit;
233,311✔
3064
        }
3065
        t++;
3,097,989✔
3066
        if ( t < m ) do {
3,097,989✔
3067
                if ( ( ( *t == SUBEXPRESSION && ( *(r=t+t[1]) != SUBEXPRESSION
6,168,757✔
3068
                || r >= m || !r[3] ) ) || *t == EXPRESSION ) && t[2] == number && t[3] ) {
6,168,757✔
3069
foundit:;
3,097,989✔
3070
                        u = m;
3,331,300✔
3071
                        r = term;
3,331,300✔
3072
                        m = termout;
3,331,300✔
3073
                        if ( r < t ) do { *m++ = *r++; } while ( r < t );
19,579,476✔
3074
                        numacc = *accum++;
3,331,300✔
3075
                        if ( numacc >= 0 ) do {
3,331,300✔
3076
                                if ( *t == EXPRESSION ) {
7,540,190✔
3077
                                        v = t + t[1];
3,097,996✔
3078
                                        r = t + SUBEXPSIZE;
3,097,996✔
3079
                                        while ( r < v ) {
3,098,347✔
3080
                                                if ( *r == WILDCARDS ) {
3,000,321✔
3081
                                                        r += 2;
3,000,000✔
3082
                                                        i = *--m;
3,000,000✔
3083
                                                        if ( ( l2 = WildFill(BHEAD m,accum,r) ) < 0 ) goto FiniCall;
3,000,000✔
3084
                                                        goto AllWild;
3,000,000✔
3085
                                                }
3086
                                                r += r[1];
324✔
3087
                                        }
3088
                                        goto NoWild;
98,008✔
3089
                                }
3090
                                else if ( t[1] > SUBEXPSIZE && t[SUBEXPSIZE] != FROMBRAC ) {
4,442,170✔
3091
                                        i = *--m;
9,292✔
3092
                                        if ( ( l2 = WildFill(BHEAD m,accum,t) ) < 0 ) goto FiniCall;
9,292✔
3093
AllWild:                        *m = i;
9,292✔
3094
                                        m += l2-1;
3,009,283✔
3095
                                        l2 = *m;
3,009,283✔
3096
                                        m -= ABS(l2) - 1;
3,009,283✔
3097
                                        r = m;
3,009,283✔
3098
                                }
3099
                                else {
3100
NoWild:                                r = accum;
4,432,880✔
3101
                                        v = r + *r - 1;
4,530,880✔
3102
                                        l2 = *v;
4,530,880✔
3103
                                        v -= ABS(l2) - 1;
4,530,880✔
3104
                                        r++;
4,530,880✔
3105
                                        if ( r < v ) do { *m++ = *r++; } while ( r < v );
30,272,280✔
3106
                                }
3107
                                if ( *r == 1 && r[1] == 1 && ABS(l2) == 3 ) {
7,540,190✔
3108
                                        if ( l2 < 0 ) l1 = -l1;
4,700,740✔
3109
                                }
3110
                                else {
3111
                                        l2 = REDLENG(l2);
2,839,451✔
3112
                                        if ( l2 == 0 ) {
2,839,451✔
3113
                                                t = oldaccum;
×
3114
                                                numacc = *t++;
×
3115
                                                AO.OutSkip = 3;
×
3116
                                                FiniLine();
×
3117
                                                while ( --numacc >= 0 ) {
×
3118
                                                        i = *t;
×
3119
                                                        while ( --i >= 0 ) {
×
3120
                                                                TalToLine((UWORD)(*t++));
×
3121
                                                                TokenToLine((UBYTE *)"  ");
×
3122
                                                        }
3123
                                                }
3124
                                                AO.OutSkip = 0;
×
3125
                                                FiniLine();
×
3126
                                                goto FiniCall;
×
3127
                                        }
3128
                                        if ( MulRat(BHEAD (UWORD *)coef,l1,(UWORD *)r,l2,(UWORD *)coef,&l1) ) goto FiniCall;
2,839,451✔
3129
                                        if ( AN.ncmod != 0 && TakeModulus((UWORD *)coef,&l1,AC.cmod,AN.ncmod,UNPACK|AC.modmode) ) goto FiniCall;
2,839,451✔
3130
                                }
3131
                                accum += *accum;
7,540,190✔
3132
                        } while ( --numacc >= 0 );
7,540,190✔
3133
                        if ( *t == SUBEXPRESSION ) {
3,331,300✔
3134
                                 while ( t+t[1] < u && t[t[1]] == DOLLAREXPR2 ) t += t[1];
233,311✔
3135
                        }
3136
                        t += t[1];
3,331,300✔
3137
                        if ( t < u ) do { *m++ = *t++; } while ( t < u );
4,338,485✔
3138
                        l2 = l1;
3,331,300✔
3139
/*
3140
                        Code to economize when taking x = (a+b)/2
3141
*/
3142
                        r = termout+1;
3,331,300✔
3143
                        while ( r < m ) {
3,331,300✔
3144
                                if ( *r == SUBEXPRESSION ) {
14,224,720✔
3145
                                        t = r + r[1];
76,725✔
3146
                                        l1 = (WORD)(cbuf[r[4]].CanCommu[r[2]]);
76,725✔
3147
                                        while ( t < m ) {
891,188✔
3148
                                                if ( *t == SUBEXPRESSION &&
852,127✔
3149
                                                        t[1] == r[1] && t[2] == r[2] && t[4] == r[4] ) {
97,766✔
3150
                                                                i = t[1] - SUBEXPSIZE;
37,664✔
3151
                                                                u = r + SUBEXPSIZE; v = t + SUBEXPSIZE;
37,664✔
3152
                                                                while ( i > 0 ) {
37,664✔
3153
                                                                        if ( *v++ != *u++ ) break;
×
3154
                                                                        i--;
×
3155
                                                                }
3156
                                                                if ( i <= 0 ) {
37,664✔
3157
                                                                        u = r;
37,664✔
3158
                                                                        r[3] += t[3];
37,664✔
3159
                                                                        r = t + t[1];
37,664✔
3160
                                                                        while ( r < m ) *t++ = *r++;
1,221,188✔
3161
                                                                        m = t;
37,664✔
3162
                                                                        r = u;
37,664✔
3163
                                                                        goto Nextr;
37,664✔
3164
                                                                }
3165
                                                                if ( l1 && cbuf[t[4]].CanCommu[t[2]] ) break;
×
3166
                                                                while ( t+t[1] < m && t[t[1]] == DOLLAREXPR2 ) t += t[1];
×
3167
                                                }
3168
                                                else if ( l1 ) {
814,463✔
3169
                                                        if ( *t == SUBEXPRESSION && cbuf[t[4]].CanCommu[t[2]] )
×
3170
                                                                break;
3171
                                                        if ( *t >= FUNCTION+WILDOFFSET )
×
3172
                                                                ipp = *t - WILDOFFSET;
×
3173
                                                        else ipp = *t;
3174
                                                        if ( *t >= FUNCTION
×
3175
                                                         && functions[ipp-FUNCTION].commute && l1 ) break;
×
3176
                                                        if ( *t == EXPRESSION ) break;
×
3177
                                                }
3178
                                                t += t[1];
814,463✔
3179
                                        }
3180
                                        r += r[1];
3181
                                }
3182
                                else r += r[1];
14,148,020✔
3183
Nextr:;
17,556,020✔
3184
                        }
3185

3186
                        i = ABS(l2);
3,331,300✔
3187
                        i *= 2;
3,331,300✔
3188
                        i++;
3,331,300✔
3189
                        l2 = ( l2 >= 0 ) ? i: -i;
3,331,300✔
3190
                        r = coef;
3,331,300✔
3191
                        while ( --i > 0 ) *m++ = *r++;
10,620,164✔
3192
                        *m++ = l2;
3,331,300✔
3193
                        *termout = WORDDIF(m,termout);
3,331,300✔
3194
                        AT.WorkPointer = coef;
3,331,300✔
3195
                        return(0);
3,331,300✔
3196
                }
3197
                t += t[1];
3,070,798✔
3198
        } while ( t < m );
3,070,798✔
3199
        AT.WorkPointer = coef;
×
3200
        return(1);
×
3201

3202
FiniCall:
×
3203
        MLOCK(ErrorMessageLock);
×
3204
        MesCall("FiniTerm");
×
3205
        MUNLOCK(ErrorMessageLock);
×
3206
        SETERROR(-1)
×
3207
}
3208

3209
/*
3210
                 #] FiniTerm : 
3211
                 #[ Generator :                        WORD Generator(BHEAD term,level)
3212
*/
3213
 
3214
static WORD zeroDollar[] = { 0, 0 };
3215
/*
3216
static LONG debugcounter = 0;
3217
*/
3218

3219
/**
3220
 *                The heart of the program.
3221
 *                Here the expansion tree is set up in one giant recursion
3222
 *
3223
 *                @param term   the input term. may be overwritten
3224
 *                @param level  the level in the compiler buffer (number of statement)
3225
 *                @return Normal conventions (OK = 0).
3226
 *
3227
 *                The routine looks first whether there are unsubstituted (sub)expressions.
3228
 *                If so, one of them gets inserted term by term and the new term is
3229
 *                used in a renewed call to Generator.
3230
 *                If there are no (sub)expressions, the term is normalized, the
3231
 *                compiler level is raised (next statement) and the program looks
3232
 *                what type of statement this is. If this is a special statement it
3233
 *                is either treated on the spot or the appropriate routine is called.
3234
 *                If it is a substitution, the pattern matcher is called (TestMatch)
3235
 *                which tells whether there was a match. If so we need to call
3236
 *                TestSub again to test for (sub)expressions.
3237
 *                If we run out of levels, the term receives a final treatment for
3238
 *                modulus calculus and/or brackets and is then sent off to the
3239
 *                sorting routines.
3240
 */
3241

3242
WORD Generator(PHEAD WORD *term, WORD level)
31,139,610✔
3243
{
3244
        GETBIDENTITY
3245
        WORD replac, *accum, *termout, *t, i, j, tepos, applyflag = 0, *StartBuf;
31,139,610✔
3246
        WORD *a, power, power1, DumNow = AR.CurDum, oldtoprhs, oldatoprhs, retnorm, extractbuff;
31,139,610✔
3247
        int *RepSto = AN.RepPoint, iscopy = 0;
31,139,610✔
3248
        CBUF *C = cbuf+AM.rbufnum, *CC = cbuf + AT.ebufnum, *CCC = cbuf + AT.aebufnum;
31,139,610✔
3249
        LONG posisub, oldcpointer, oldacpointer;
31,139,610✔
3250
        DOLLARS d = 0;
31,139,610✔
3251
        WORD numfac[5], idfunctionflag;
31,139,610✔
3252
#ifdef WITHPTHREADS
3253
        int nummodopt, dtype = -1, id;
16,293,810✔
3254
#endif
3255
        oldtoprhs = CC->numrhs;
31,139,610✔
3256
        oldcpointer = CC->Pointer - CC->Buffer;
31,139,610✔
3257
        oldatoprhs = CCC->numrhs;
31,139,610✔
3258
        oldacpointer = CCC->Pointer - CCC->Buffer;
31,139,610✔
3259
ReStart:
50,175✔
3260
        if ( ( replac = TestSub(BHEAD term,level) ) == 0 ) {
31,189,800✔
3261
                if ( applyflag ) { TableReset(); applyflag = 0; }
3262
/*
3263
                if ( AN.PolyNormFlag > 1 ) {
3264
                        if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
3265
                        AN.PolyNormFlag = 0;
3266
                        if ( !*term ) goto Return0;
3267
                }
3268
*/
3269
Renormalize:
3270
                AN.PolyNormFlag = 0;
25,589,800✔
3271
                AN.idfunctionflag = 0;
25,589,800✔
3272
                if ( ( retnorm = Normalize(BHEAD term) ) != 0 ) {
25,589,800✔
3273
                        if ( retnorm > 0 ) {
4,565✔
3274
                                if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
4,559✔
3275
                                goto ReStart;
4,559✔
3276
                        }
3277
                        goto GenCall;
6✔
3278
                }
3279
                idfunctionflag = AN.idfunctionflag;
25,585,240✔
3280
                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
25,585,240✔
3281

3282
                if ( AN.PolyNormFlag ) {
25,579,240✔
3283
                        if ( AN.PolyFunTodo == 0 ) {
34,760✔
3284
                                if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
34,732✔
3285
                                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
34,732✔
3286
                        }
3287
                        else {
3288
                                WORD oldPolyFunExp = AR.PolyFunExp;
28✔
3289
                                AR.PolyFunExp = 0;
28✔
3290
                                if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
28✔
3291
                                AT.WorkPointer = term+*term;
28✔
3292
                                AR.PolyFunExp = oldPolyFunExp;
28✔
3293
                                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
28✔
3294
                                if ( Normalize(BHEAD term) < 0 ) goto GenCall;
28✔
3295
                                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
28✔
3296
                                AT.WorkPointer = term+*term;
28✔
3297
                                if ( AN.PolyNormFlag ) {
28✔
3298
                                        if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
28✔
3299
                                        if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
28✔
3300
                                        AT.WorkPointer = term+*term;
28✔
3301
                                }
3302
                                AN.PolyFunTodo = 0;
28✔
3303
                        }
3304
                }
3305
                if ( idfunctionflag > 0 ) {
25,579,240✔
3306
                        if ( TakeIDfunction(BHEAD term) ) {
×
3307
                                AT.WorkPointer = term + *term;
×
3308
                                goto ReStart;
×
3309
                        }
3310
                }
3311
                if ( AT.WorkPointer < (WORD *)(((UBYTE *)(term)) + AM.MaxTer) )
25,579,240✔
3312
                         AT.WorkPointer = (WORD *)(((UBYTE *)(term)) + AM.MaxTer);
25,560,870✔
3313
                do {
26,269,170✔
3314
SkipCount:        level++;
275,470✔
3315
                        if ( level > AR.Cnumlhs ) {
26,269,170✔
3316
                                if ( AR.DeferFlag && AR.sLevel <= 0 ) {
25,213,950✔
3317
#ifdef WITHMPI
3318
                                  if ( PF.me != MASTER && AC.mparallelflag == PARALLELFLAG && PF.exprtodo < 0 ) {
2,027,040✔
3319
                                        if ( PF_Deferred(term,level) ) goto GenCall;
2,027,030✔
3320
                                  }
3321
                                  else
3322
#endif
3323
                                        if ( Deferred(BHEAD term,level) ) goto GenCall;
6,081,130✔
3324
                                        goto Return0;
8,108,160✔
3325
                                }
3326
                                if ( AN.ncmod != 0 ) {
17,105,800✔
3327
                                        if ( Modulus(term) ) goto GenCall;
4✔
3328
                                        if ( !*term ) goto Return0;
4✔
3329
                                }
3330
                                if ( AR.CurDum > AM.IndDum && AR.sLevel <= 0 ) {
17,105,800✔
3331
                                        WORD olddummies = AN.IndDum;
116✔
3332
                                        AN.IndDum = AM.IndDum;
116✔
3333
                                        ReNumber(BHEAD term);
116✔
3334
                                        Normalize(BHEAD term);
116✔
3335
                                        AN.IndDum = olddummies;
116✔
3336
                                        if ( !*term ) goto Return0;
116✔
3337
                                        olddummies = DetCurDum(BHEAD term);
116✔
3338
                                        if ( olddummies > AR.MaxDum ) AR.MaxDum = olddummies;
116✔
3339
                                }
3340
                                if ( AR.PolyFun > 0 && ( AR.sLevel <= 0 || AN.FunSorts[AR.sLevel]->PolyFlag > 0 ) ) {
17,105,800✔
3341
                                        if ( PrepPoly(BHEAD term,0) != 0 ) goto Return0;
47,619✔
3342
                                }
3343
                                else if ( AR.PolyFun > 0 ) {
17,058,190✔
3344
                                        if ( PrepPoly(BHEAD term,1) != 0 ) goto Return0;
306,433✔
3345
                                }
3346
                                if ( AR.sLevel <= 0 && AR.BracketOn ) {
17,105,800✔
3347
                                        if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
34,996✔
3348
                                        termout = AT.WorkPointer;
34,996✔
3349
                                        if ( AT.WorkPointer + *term + 3 > AT.WorkTop ) goto OverWork;
34,996✔
3350
                                        if ( PutBracket(BHEAD term) ) return(-1);
34,996✔
3351
                                        AN.RepPoint = RepSto;
34,996✔
3352
                                        *AT.WorkPointer = 0;
34,996✔
3353
                                        i = StoreTerm(BHEAD termout);
34,996✔
3354
                                        AT.WorkPointer = termout;
34,996✔
3355
                                        CC->numrhs = oldtoprhs;
34,996✔
3356
                                        CC->Pointer = CC->Buffer + oldcpointer;
34,996✔
3357
                                        CCC->numrhs = oldatoprhs;
34,996✔
3358
                                        CCC->Pointer = CCC->Buffer + oldacpointer;
34,996✔
3359
                                        return(i);
34,996✔
3360
                                }
3361
                                else {
3362
                                        if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
17,070,800✔
3363
                                        if ( AT.WorkPointer >= AT.WorkTop ) goto OverWork;
17,070,800✔
3364
                                        *AT.WorkPointer = 0;
17,070,800✔
3365
                                        AN.RepPoint = RepSto;
17,070,800✔
3366
                                        i = StoreTerm(BHEAD term);
17,070,800✔
3367
                                        CC->numrhs = oldtoprhs;
17,070,800✔
3368
                                        CC->Pointer = CC->Buffer + oldcpointer;
17,070,800✔
3369
                                        CCC->numrhs = oldatoprhs;
17,070,800✔
3370
                                        CCC->Pointer = CCC->Buffer + oldacpointer;
17,070,800✔
3371
                                        return(i);
17,070,800✔
3372
                                }
3373
                        }
3374
                        i = C->lhs[level][0];
1,055,227✔
3375
                        if ( i >= TYPECOUNT ) {
1,055,227✔
3376
/*
3377
                        #[ Special action :
3378
*/
3379
                                switch ( i ) {
491,426✔
3380
                                  case TYPECOUNT:
×
3381
                                        if ( CountDo(term,C->lhs[level]) < C->lhs[level][2] ) {
×
3382
                                                AT.WorkPointer = term + *term;
×
3383
                                                goto Return0;
×
3384
                                        }
3385
                                        break;
3386
                                  case TYPEMULT:
7,390✔
3387
                                        if ( MultDo(BHEAD term,C->lhs[level]) ) goto GenCall;
7,390✔
3388
                                        goto ReStart;
7,390✔
3389
                                  case TYPEGOTO:
×
3390
                                        level = AC.Labels[C->lhs[level][2]];
×
3391
                                        break;
×
3392
                                  case TYPEDISCARD:
11,840✔
3393
                                        AT.WorkPointer = term + *term;
11,840✔
3394
                                        goto Return0;
11,840✔
3395
                                  case TYPEIF:
28,740✔
3396
#ifdef WITHPTHREADS
3397
                                        {
3398
/*
3399
                                                We may be writing in the space here when wildcards
3400
                                                are involved in a match(). Hence we have to make
3401
                                                a private copy here!!!!
3402
*/
3403
                                                WORD ic, jc, *ifcode, *jfcode;
28,740✔
3404
                                                jfcode = C->lhs[level]; jc = jfcode[1];
28,740✔
3405
                                                ifcode = AT.WorkPointer; AT.WorkPointer += jc;
28,740✔
3406
                                                for ( ic = 0; ic < jc; ic++ ) ifcode[ic] = jfcode[ic];
518,580✔
3407
                                                while ( !DoIfStatement(BHEAD ifcode,term) ) {
28,740✔
3408
                                                        level = C->lhs[level][2];
21,637✔
3409
                                                        if ( C->lhs[level][0] != TYPEELIF ) break;
21,637✔
3410
                                                }
3411
                                                AT.WorkPointer = ifcode;
28,740✔
3412
                                        }
3413
#else
3414
                                        while ( !DoIfStatement(BHEAD C->lhs[level],term) ) {
28,740✔
3415
                                                level = C->lhs[level][2];
21,628✔
3416
                                                if ( C->lhs[level][0] != TYPEELIF ) break;
21,628✔
3417
                                        }
3418
#endif
3419
                                        break;
28,740✔
3420
                                  case TYPEELIF:
×
3421
                                        do {
×
3422
                                                level = C->lhs[level][2];
×
3423
                                        } while ( C->lhs[level][0] == TYPEELIF );
×
3424
                                        break;
3425
                                  case TYPEELSE:
3,575✔
3426
                                  case TYPEENDIF:
3427
                                        level = C->lhs[level][2];
3,575✔
3428
                                        break;
3,575✔
3429
                                  case TYPESUMFIX:
512✔
3430
                                        {
3431
                                                WORD *cp = AR.CompressPointer, *op = AR.CompressPointer;
512✔
3432
                                                WORD *tlhs = C->lhs[level] + 3, *m, jlhs;
512✔
3433
                                                WORD theindex = C->lhs[level][2];
512✔
3434
                                                if ( theindex < 0 ) {        /* $-variable */
512✔
3435
#ifdef WITHPTHREADS
3436
                                                        int ddtype = -1;
3437
                                                        theindex = -theindex;
3438
                                                        d = Dollars + theindex;
3439
                                                        if ( AS.MultiThreaded ) {
3440
                                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3441
                                                                        if ( theindex == ModOptdollars[nummodopt].number ) break;
3442
                                                                }
3443
                                                                if ( nummodopt < NumModOptdollars ) {
3444
                                                                        ddtype = ModOptdollars[nummodopt].type;
3445
                                                                        if ( ddtype == MODLOCAL ) {
3446
                                                                                d = ModOptdollars[nummodopt].dstruct+AT.identity;
3447
                                                                        }
3448
                                                                        else {
3449
                                                                                LOCK(d->pthreadslockread);
3450
                                                                        }
3451
                                                                }
3452
                                                        }
3453
#else
3454
                                                        theindex = -theindex;
3455
                                                        d = Dollars + theindex;
3456
#endif
3457

3458
                                                        if ( d->type != DOLINDEX
×
3459
                                                        || d->index < AM.OffsetIndex
×
3460
                                                        || d->index >= AM.OffsetIndex + WILDOFFSET ) {
×
3461
                                                                MLOCK(ErrorMessageLock);
×
3462
                                                                MesPrint("$%s should have been an index"
×
3463
                                                                ,AC.dollarnames->namebuffer+d->name);
×
3464
                                                                AN.currentTerm = term;
×
3465
                                                                MesPrint("Current term: %t");
×
3466
                                                                AN.listinprint = printscratch;
×
3467
                                                                printscratch[0] = DOLLAREXPRESSION;
×
3468
                                                                printscratch[1] = theindex;
×
3469
                                                                MesPrint("$%s = %$"
×
3470
                                                                ,AC.dollarnames->namebuffer+d->name);
×
3471
                                                                MUNLOCK(ErrorMessageLock);
×
3472
#ifdef WITHPTHREADS
3473
                                                        if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3474
#endif
3475
                                                                goto GenCall;
×
3476
                                                        }
3477
                                                        theindex = d->index;
3478
#ifdef WITHPTHREADS
3479
                                                        if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3480
#endif
3481
                                                }
3482
                                                cp[1] = SUBEXPSIZE+4;
512✔
3483
                                                cp += SUBEXPSIZE;
512✔
3484
                                                *cp++ = INDTOIND;
512✔
3485
                                                *cp++ = 4;
512✔
3486
                                                *cp++ = theindex;
512✔
3487
                                                i = C->lhs[level][1] - 3;
512✔
3488
                                                cp++;
512✔
3489
                                                AR.CompressPointer = cp;
512✔
3490
                                                while ( --i >= 0 ) {
2,048✔
3491
                                                        cp[-1] = *tlhs++;
1,536✔
3492
                                                        termout = AT.WorkPointer;
1,536✔
3493
                                                        if ( ( jlhs = WildFill(BHEAD termout,term,op)) < 0 )
1,536✔
3494
                                                                goto GenCall;
×
3495
                                                        m = term;
1,536✔
3496
                                                        jlhs = *m;
1,536✔
3497
                                                        while ( --jlhs >= 0 ) {
12,480✔
3498
                                                                if ( *m++ != *termout++ ) break;
12,480✔
3499
                                                        }
3500
                                                        if ( jlhs >= 0 ) {
1,536✔
3501
                                                                termout = AT.WorkPointer;
1,536✔
3502
                                                                AT.WorkPointer = termout + *termout;
1,536✔
3503
                                                                if ( Generator(BHEAD termout,level) ) goto GenCall;
1,536✔
3504
                                                                AT.WorkPointer = termout;
1,536✔
3505
                                                        }
3506
                                                        else {
3507
                                                                AR.CompressPointer = op;
×
3508
                                                                goto SkipCount;
×
3509
                                                        }
3510
                                                }
3511
                                                AR.CompressPointer = op;
512✔
3512
                                                goto CommonEnd;
512✔
3513
                                        }
3514
                                  case TYPESUM:
49✔
3515
                                        {
3516
                                                WORD *wp, *cp = AR.CompressPointer, *op = AR.CompressPointer;
49✔
3517
                                                WORD theindex;
49✔
3518
                                                WORD *ow;
49✔
3519
/*
3520
                                                At this point it is safest to determine CurDum
3521
*/
3522
                                                AR.CurDum = DetCurDum(BHEAD term);
49✔
3523
                                                i = C->lhs[level][1]-2;
49✔
3524
                                                wp = C->lhs[level] + 2;
49✔
3525
                                                cp[1] = SUBEXPSIZE+4*i;
49✔
3526
                                                cp += SUBEXPSIZE;
49✔
3527
                                                while ( --i >= 0 ) {
126✔
3528
                                                        theindex = *wp++;
77✔
3529
                                                        if ( theindex < 0 ) {        /* $-variable */
77✔
3530
#ifdef WITHPTHREADS
3531
                                                                int ddtype = -1;
3532
                                                                theindex = -theindex;
3533
                                                                d = Dollars + theindex;
3534
                                                                if ( AS.MultiThreaded ) {
3535
                                                                        for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3536
                                                                                if ( theindex == ModOptdollars[nummodopt].number ) break;
3537
                                                                        }
3538
                                                                        if ( nummodopt < NumModOptdollars ) {
3539
                                                                                ddtype = ModOptdollars[nummodopt].type;
3540
                                                                                if ( ddtype == MODLOCAL ) {
3541
                                                                                        d = ModOptdollars[nummodopt].dstruct+AT.identity;
3542
                                                                                }
3543
                                                                                else {
3544
                                                                                        LOCK(d->pthreadslockread);
3545
                                                                                }
3546
                                                                        }
3547
                                                                }
3548
#else
3549
                                                                theindex = -theindex;
3550
                                                                d = Dollars + theindex;
3551
#endif
3552
                                                                if ( d->type != DOLINDEX
×
3553
                                                                || d->index < AM.OffsetIndex
×
3554
                                                                || d->index >= AM.OffsetIndex + WILDOFFSET ) {
×
3555
                                                                        MLOCK(ErrorMessageLock);
×
3556
                                                                        MesPrint("$%s should have been an index"
×
3557
                                                                        ,AC.dollarnames->namebuffer+d->name);
×
3558
                                                                        AN.currentTerm = term;
×
3559
                                                                        MesPrint("Current term: %t");
×
3560
                                                                        AN.listinprint = printscratch;
×
3561
                                                                        printscratch[0] = DOLLAREXPRESSION;
×
3562
                                                                        printscratch[1] = theindex;
×
3563
                                                                        MesPrint("$%s = %$"
×
3564
                                                                        ,AC.dollarnames->namebuffer+d->name);
×
3565
                                                                        MUNLOCK(ErrorMessageLock);
×
3566
#ifdef WITHPTHREADS
3567
                                                                        if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3568
#endif
3569
                                                                        goto GenCall;
×
3570
                                                                }
3571
                                                                theindex = d->index;
3572
#ifdef WITHPTHREADS
3573
                                                                if ( ddtype > 0 && ddtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
3574
#endif
3575
                                                        }
3576
                                                        *cp++ = INDTOIND;
77✔
3577
                                                        *cp++ = 4;
77✔
3578
                                                        *cp++ = theindex;
77✔
3579
                                                        *cp++ = ++AR.CurDum;
77✔
3580
                                                }
3581
                                                ow = AT.WorkPointer;
49✔
3582
                                                AR.CompressPointer = cp;
49✔
3583
                                                if ( WildFill(BHEAD ow,term,op) < 0 ) goto GenCall;
49✔
3584
                                                AR.CompressPointer = op;
49✔
3585
                                                i = ow[0];
49✔
3586
                                                for ( j = 0; j < i; j++ ) term[j] = ow[j];
932✔
3587
                                                AT.WorkPointer = ow;
49✔
3588
                                                ReNumber(BHEAD term);
49✔
3589
                                                goto Renormalize;
49✔
3590
                                        }
3591
                                  case TYPECHISHOLM:
4✔
3592
                                        if ( Chisholm(BHEAD term,level) ) goto GenCall;
4✔
3593
CommonEnd:
4✔
3594
                                        AT.WorkPointer = term + *term;
516✔
3595
                                        goto Return0;
516✔
3596
                                  case TYPEARG:
260,681✔
3597
                                        if ( ( i = execarg(BHEAD term,level) ) < 0 ) goto GenCall;
260,681✔
3598
                                        level = C->lhs[level][2];
260,678✔
3599
                                        if ( i > 0 ) goto ReStart;
260,678✔
3600
                                        break;
3601
                                  case TYPENORM:
32,044✔
3602
                                  case TYPENORM2:
3603
                                  case TYPENORM3:
3604
                                  case TYPENORM4:
3605
                                  case TYPESPLITARG:
3606
                                  case TYPESPLITARG2:
3607
                                  case TYPESPLITFIRSTARG:
3608
                                  case TYPESPLITLASTARG:
3609
                                  case TYPEARGTOEXTRASYMBOL:
3610
                                        if ( execarg(BHEAD term,level) < 0 ) goto GenCall;
32,044✔
3611
                                        level = C->lhs[level][2];
32,044✔
3612
                                        break;
32,044✔
3613
                                  case TYPEFACTARG:
9,712✔
3614
                                  case TYPEFACTARG2:
3615
                                        { WORD jjj;
9,712✔
3616
                                        if ( ( jjj = execarg(BHEAD term,level) ) < 0 ) goto GenCall;
9,712✔
3617
                                        if ( jjj > 0 ) goto ReStart;
9,712✔
3618
                                        level = C->lhs[level][2];
1,313✔
3619
                                        break; }
1,313✔
3620
                                  case TYPEEXIT:
×
3621
                                        if ( C->lhs[level][2] > 0 ) {
×
3622
                                                MLOCK(ErrorMessageLock);
×
3623
                                                MesPrint("%s",C->lhs[level]+3);
×
3624
                                                MUNLOCK(ErrorMessageLock);
×
3625
                                        }
NEW
3626
                                        TERMINATE(-1);
×
3627
                                        goto GenCall;
×
3628
                                  case TYPESETEXIT:
×
3629
                                        AM.exitflag = 1; /* no danger of race conditions */
×
3630
                                        break;
×
3631
                                  case TYPEPRINT:
112✔
3632
                                        AN.currentTerm = term;
112✔
3633
                                        AN.numlistinprint = (C->lhs[level][1] - C->lhs[level][4] - 5)/2;
112✔
3634
                                        AN.listinprint = C->lhs[level]+5+C->lhs[level][4];
112✔
3635
                                        MLOCK(ErrorMessageLock);
112✔
3636
                                        AO.ErrorBlock = 1;
112✔
3637
                                        MesPrint((char *)(C->lhs[level]+5));
112✔
3638
                                        AO.ErrorBlock = 0;
112✔
3639
                                        MUNLOCK(ErrorMessageLock);
112✔
3640
                                        break;
84✔
3641
                                  case TYPEFPRINT:
880✔
3642
                                        {
3643
                                        int oldFOflag;
880✔
3644
                                        WORD oldPrintType, oldLogHandle = AC.LogHandle;
880✔
3645
                                        AC.LogHandle = C->lhs[level][2];
880✔
3646
                                        MLOCK(ErrorMessageLock);
880✔
3647
                                        oldFOflag = AM.FileOnlyFlag;
880✔
3648
                                        oldPrintType = AO.PrintType;
880✔
3649
                                        if ( AC.LogHandle >= 0 ) {
880✔
3650
                                                AM.FileOnlyFlag = 1;
×
3651
                                                AO.PrintType |= PRINTLFILE;
×
3652
                                        }
3653
                                        AO.PrintType |= C->lhs[level][3];
880✔
3654
                                        AN.currentTerm = term;
880✔
3655
                                        AN.numlistinprint = (C->lhs[level][1] - C->lhs[level][4] - 5)/2;
880✔
3656
                                        AN.listinprint = C->lhs[level]+5+C->lhs[level][4];
880✔
3657
                                        MesPrint((char *)(C->lhs[level]+5));
880✔
3658
                                        AO.PrintType = oldPrintType;
880✔
3659
                                        AM.FileOnlyFlag = oldFOflag;
880✔
3660
                                        MUNLOCK(ErrorMessageLock);
880✔
3661
                                        AC.LogHandle = oldLogHandle;
880✔
3662
                                        }
3663
                                        break;
880✔
3664
                                  case TYPEREDEFPRE:
264✔
3665
                                        j = C->lhs[level][2];
264✔
3666
#ifdef WITHMPI
3667
                                        {
3668
                                                /*
3669
                                                 * Regardless of parallel/nonparallel switch, we need to set
3670
                                                 * AC.inputnumbers[ii], which indicates that the corresponding
3671
                                                 * preprocessor variable is redefined and so we need to
3672
                                                 * send/broadcast it.
3673
                                                 */
3674
                                                int ii;
66✔
3675
                                                for ( ii = 0; ii < AC.numpfirstnum; ii++ ) {
66✔
3676
                                                        if ( AC.pfirstnum[ii] == j ) break;
66✔
3677
                                                }
3678
                                                AC.inputnumbers[ii] = AN.ninterms;
66✔
3679
                                        }
3680
#endif
3681
#ifdef WITHPTHREADS
3682
                                        if ( AS.MultiThreaded ) {
132✔
3683
                                                int ii;
3684
                                                for ( ii = 0; ii < AC.numpfirstnum; ii++ ) {
132✔
3685
                                                        if ( AC.pfirstnum[ii] == j ) break;
132✔
3686
                                                }
3687
                                                if ( AN.inputnumber < AC.inputnumbers[ii] ) break;
132✔
3688
                                                LOCK(AP.PreVarLock);
95✔
3689
                                                if ( AN.inputnumber >= AC.inputnumbers[ii] ) {
95✔
3690
                                                        a = C->lhs[level]+4;
95✔
3691
                                                        if ( a[a[-1]] == 0 )
95✔
3692
                                                                PutPreVar(PreVar[j].name,(UBYTE *)(a),0,1);
95✔
3693
                                                        else
3694
                                                                PutPreVar(PreVar[j].name,(UBYTE *)(a)
3695
                                                                        ,(UBYTE *)(a+a[-1]+1),1);
3696
/*
3697
                                                        PutPreVar(PreVar[j].name,(UBYTE *)(C->lhs[level]+4),0,1);
3698
*/
3699
                                                        AC.inputnumbers[ii] = AN.inputnumber;
95✔
3700
                                                }
3701
                                                UNLOCK(AP.PreVarLock);
95✔
3702
                                        }
3703
                                        else
3704
#endif
3705
                                        {
3706
                                                a = C->lhs[level]+4;
132✔
3707
                                                LOCK(AP.PreVarLock);
132✔
3708
                                                if ( a[a[-1]] == 0 )
132✔
3709
                                                        PutPreVar(PreVar[j].name,(UBYTE *)(a),0,1);
132✔
3710
                                                else
3711
                                                        PutPreVar(PreVar[j].name,(UBYTE *)(a)
×
3712
                                                                ,(UBYTE *)(a+a[-1]+1),1);
×
3713
                                                UNLOCK(AP.PreVarLock);
3714
                                        }
3715
                                        break;
3716
                                  case TYPERENUMBER:
×
3717
                                        AT.WorkPointer = term + *term;
×
3718
                                        if ( FullRenumber(BHEAD term,C->lhs[level][2]) ) goto GenCall;
×
3719
                                        AT.WorkPointer = term + *term;
×
3720
                                        if ( *term == 0 ) goto Return0;
×
3721
                                        break;
3722
                                  case TYPETRY:
×
3723
                                        if ( TryDo(BHEAD term,C->lhs[level],level) ) goto GenCall;
×
3724
                                        AT.WorkPointer = term + *term;
×
3725
                                        goto Return0;
×
3726
                                  case TYPEASSIGN:
20,826✔
3727
                                        { WORD onc = AR.NoCompress, oldEside = AR.Eside;
20,826✔
3728
                                        WORD oldrepeat = *AN.RepPoint;
20,826✔
3729
/*
3730
                                        Here we have to assign an expression to a $ variable.
3731
*/
3732
                                        AR.Eside = RHSIDE;
20,826✔
3733
                                        AR.NoCompress = 1;
20,826✔
3734
                                        AN.cTerm = AN.currentTerm = term;
20,826✔
3735
                                        AT.WorkPointer = term + *term;
20,826✔
3736
                                        *AT.WorkPointer++ = 0;
20,826✔
3737
                                        if ( AssignDollar(BHEAD term,level) ) goto GenCall;
20,826✔
3738
                                        AT.WorkPointer = term + *term;
20,826✔
3739
                                        AN.cTerm = 0;
20,826✔
3740
                                        *AN.RepPoint = oldrepeat;
20,826✔
3741
                                        AR.NoCompress = onc;
20,826✔
3742
                                        AR.Eside = oldEside;
20,826✔
3743
                                        break;
20,826✔
3744
                                        }
3745
                                  case TYPEFINDLOOP:
8✔
3746
                                        if ( Lus(term,C->lhs[level][3],C->lhs[level][4],
8✔
3747
                                        C->lhs[level][5],C->lhs[level][6],C->lhs[level][2]) ) {
3748
                                                AT.WorkPointer = term + *term;
8✔
3749
                                                goto Renormalize;
8✔
3750
                                        }
3751
                                        break;
3752
                                  case TYPEINSIDE:
4✔
3753
                                        if ( InsideDollar(BHEAD C->lhs[level],level) < 0 ) goto GenCall;
4✔
3754
                                        level = C->lhs[level][2];
4✔
3755
                                        break;
4✔
3756
                                  case TYPETERM:
320✔
3757
                                        retnorm = execterm(BHEAD term,level);
320✔
3758
                                        AN.RepPoint = RepSto;
320✔
3759
                                        AR.CurDum = DumNow;
320✔
3760
                                        CC->numrhs = oldtoprhs;
320✔
3761
                                        CC->Pointer = CC->Buffer + oldcpointer;
320✔
3762
                                        CCC->numrhs = oldatoprhs;
320✔
3763
                                        CCC->Pointer = CCC->Buffer + oldacpointer;
320✔
3764
                                        return(retnorm);
320✔
3765
                                  case TYPEDETCURDUM:
324✔
3766
                                        AT.WorkPointer = term + *term;
324✔
3767
                                        AR.CurDum = DetCurDum(BHEAD term);
324✔
3768
                                        break;
324✔
3769
                                  case TYPEINEXPRESSION:
19,570✔
3770
                                        {WORD *ll = C->lhs[level];
19,570✔
3771
                                        int numexprs = (int)(ll[1]-3);
19,570✔
3772
                                        ll += 3;
19,570✔
3773
                                        while ( numexprs-- >= 0 ) {
162,932✔
3774
                                                if ( *ll == AR.CurExpr ) break;
155,861✔
3775
                                                ll++;
143,362✔
3776
                                        }
3777
                                        if ( numexprs < 0 ) level = C->lhs[level][2];
19,570✔
3778
                                        }
3779
                                        break;
3780
                                  case TYPEMERGE:
28✔
3781
                                        AT.WorkPointer = term + *term;
28✔
3782
                                        if ( DoShuffle(term,level,C->lhs[level][2],C->lhs[level][3]) )
28✔
3783
                                                goto GenCall;
×
3784
                                        AT.WorkPointer = term + *term;
28✔
3785
                                        goto Return0;
28✔
3786
                                  case TYPESTUFFLE:
4✔
3787
                                        AT.WorkPointer = term + *term;
4✔
3788
                                        if ( DoStuffle(term,level,C->lhs[level][2],C->lhs[level][3]) )
4✔
3789
                                                goto GenCall;
×
3790
                                        AT.WorkPointer = term + *term;
4✔
3791
                                        goto Return0;
4✔
3792
                                  case TYPETESTUSE:
×
3793
                                        AT.WorkPointer = term + *term;
×
3794
                                        if ( TestUse(term,level) ) goto GenCall;
×
3795
                                        AT.WorkPointer = term + *term;
×
3796
                                        break;
×
3797
                                  case TYPEAPPLY:
×
3798
                                        AT.WorkPointer = term + *term;
×
3799
                                        if ( ApplyExec(term,C->lhs[level][2],level) < C->lhs[level][2] ) {
×
3800
                                                AT.WorkPointer = term + *term;
×
3801
                                                *AN.RepPoint = 1;
×
3802
                                                goto ReStart;
×
3803
                                        }
3804
                                        AT.WorkPointer = term + *term;
×
3805
                                        break;
×
3806
/*
3807
                                  case TYPEAPPLYRESET:
3808
                                        AT.WorkPointer = term + *term;
3809
                                        if ( ApplyReset(level) ) goto GenCall;
3810
                                        AT.WorkPointer = term + *term;
3811
                                        break;
3812
*/
3813
                                  case TYPECHAININ:
164✔
3814
                                        { int lter = *term;
164✔
3815
                                        AT.WorkPointer = term + *term;
164✔
3816
                                        if ( ChainIn(BHEAD term,C->lhs[level][2]) ) goto GenCall;
164✔
3817
                                        AT.WorkPointer = term + *term;
164✔
3818
                                        if ( *term != lter ) *AN.RepPoint = 1;
164✔
3819
                                        }
3820
                                        break;
3821
                                  case TYPECHAINOUT:
9,536✔
3822
                                        { int lter = *term;
9,536✔
3823
                                        AT.WorkPointer = term + *term;
9,536✔
3824
                                        if ( ChainOut(BHEAD term,C->lhs[level][2]) ) goto GenCall;
9,536✔
3825
                                        AT.WorkPointer = term + *term;
9,536✔
3826
                                        if ( *term != lter ) *AN.RepPoint = 1;
9,536✔
3827
                                        }
3828
                                        break;
3829
                                  case TYPEFACTOR:
11✔
3830
                                        AT.WorkPointer = term + *term;
11✔
3831
                                        if ( DollarFactorize(BHEAD C->lhs[level][2]) ) goto GenCall;
11✔
3832
                                        AT.WorkPointer = term + *term;
11✔
3833
                                        break;
11✔
3834
                                  case TYPEARGIMPLODE:
16✔
3835
                                        AT.WorkPointer = term + *term;
16✔
3836
                                        if ( ArgumentImplode(BHEAD term,C->lhs[level]) ) goto GenCall;
16✔
3837
                                        AT.WorkPointer = term + *term;
16✔
3838
                                        break;
16✔
3839
                                  case TYPEARGEXPLODE:
16✔
3840
                                        AT.WorkPointer = term + *term;
16✔
3841
                                        if ( ArgumentExplode(BHEAD term,C->lhs[level]) ) goto GenCall;
16✔
3842
                                        AT.WorkPointer = term + *term;
16✔
3843
                                        break;
16✔
3844
                                  case TYPEDENOMINATORS:
16✔
3845
                                        if ( DenToFunction(term,C->lhs[level][2]) ) goto ReStart;
16✔
3846
                                        break;
3847
                                  case TYPEDROPCOEFFICIENT:
4,608✔
3848
                                        DropCoefficient(BHEAD term);
4,608✔
3849
                                        break;
4,608✔
3850
                                  case TYPETRANSFORM:
13,675✔
3851
                                        AT.WorkPointer = term + *term;
13,675✔
3852
                                        if ( RunTransform(BHEAD term,C->lhs[level]+2) ) goto GenCall;
13,675✔
3853
                                        AT.WorkPointer = term + *term;
13,675✔
3854
                                        if ( *term == 0 ) goto Return0;
13,675✔
3855
                                        goto ReStart;
13,675✔
3856
                                  case TYPETOPOLYNOMIAL:
52✔
3857
                                        AT.WorkPointer = term + *term;
52✔
3858
                                        termout = AT.WorkPointer;
52✔
3859
                                        if ( ConvertToPoly(BHEAD term,termout,C->lhs[level],0) < 0 ) goto GenCall;
52✔
3860
                                        if ( *termout == 0 ) goto Return0;
52✔
3861
                                        i = termout[0]; t = term; NCOPY(t,termout,i);
540✔
3862
                                        AT.WorkPointer = term + *term;
52✔
3863
                                        break;
52✔
3864
                                  case TYPEFROMPOLYNOMIAL:
6,028✔
3865
                                        AT.WorkPointer = term + *term;
6,028✔
3866
                                        termout = AT.WorkPointer;
6,028✔
3867
                                        if ( ConvertFromPoly(BHEAD term,termout,0,numxsymbol,0,0) < 0 ) goto GenCall;
6,028✔
3868
                                        if ( *term == 0 ) goto Return0;
6,028✔
3869
                                        i = termout[0]; t = term; NCOPY(t,termout,i);
60,328✔
3870
                                        AT.WorkPointer = term + *term;
6,028✔
3871
                                        goto ReStart;
6,028✔
3872
                                  case TYPEDOLOOP:
11✔
3873
                                        level = TestDoLoop(BHEAD C->lhs[level],level);
11✔
3874
                                        if ( level < 0 ) goto GenCall;
11✔
3875
                                        break;
3876
                                  case TYPEENDDOLOOP:
210✔
3877
                                        level = TestEndDoLoop(BHEAD C->lhs[C->lhs[level][2]],C->lhs[level][2]);
210✔
3878
                                        if ( level < 0 ) goto GenCall;
210✔
3879
                                        break;
3880
                                  case TYPEDROPSYMBOLS:
×
3881
                                        DropSymbols(BHEAD term);
×
3882
                                        break;
×
3883
                                  case TYPEPUTINSIDE:
212✔
3884
                                        AT.WorkPointer = term + *term;
212✔
3885
                                        if ( PutInside(BHEAD term,C->lhs[level]) < 0 ) goto GenCall;
212✔
3886
                                        AT.WorkPointer = term + *term;
212✔
3887
                                        /*
3888
                                         * We need to call Generator() to convert slow notation to
3889
                                         * fast notation, which fixes Issue #30.
3890
                                         */
3891
                                        if ( Generator(BHEAD term,level) < 0 ) goto GenCall;
212✔
3892
                                        goto Return0;
212✔
3893
                                  case TYPETOSPECTATOR:
8✔
3894
                                        if ( PutInSpectator(term,C->lhs[level][2]) < 0 ) goto GenCall;
8✔
3895
                                        goto Return0;
8✔
3896
                                  case TYPECANONICALIZE:
×
3897
                                        AT.WorkPointer = term + *term;
×
3898
                                        if ( DoCanonicalize(BHEAD term,C->lhs[level]) ) goto GenCall;
×
3899
                                        AT.WorkPointer = term + *term;
×
3900
                                        if ( *term == 0 ) goto Return0;
×
3901
                                        break;
3902
                                  case TYPESWITCH:
×
3903
                                        AT.WorkPointer = term + *term;
×
3904
                                        if ( DoSwitch(BHEAD term,C->lhs[level]) ) goto GenCall;
×
3905
                                        goto Return0;
×
3906
                                  case TYPEENDSWITCH:
×
3907
                                        AT.WorkPointer = term + *term;
×
3908
                                        if ( DoEndSwitch(BHEAD term,C->lhs[level]) ) goto GenCall;
×
3909
                                        goto Return0;
×
3910
                                  case TYPESETUSERFLAG:
×
3911
                                        Expressions[AR.CurExpr].uflags |= 1 << (C->lhs[level][2]);
×
3912
                                        break;
×
3913
                                  case TYPECLEARUSERFLAG:
×
3914
                                        Expressions[AR.CurExpr].uflags &= ~(1 << (C->lhs[level][2]));
×
3915
                                        break;
×
3916
                                  case TYPEALLLOOPS:
×
3917
                                        AT.WorkPointer = term + *term;
×
3918
                                        if ( AllLoops(BHEAD term,level) ) goto GenCall;
×
3919
                                        goto Return0;
×
3920
                                  case TYPEALLPATHS:
×
3921
                                        AT.WorkPointer = term + *term;
×
3922
                                        if ( AllPaths(BHEAD term,level) ) goto GenCall;
×
3923
                                        goto Return0;
×
3924
#ifdef WITHFLOAT
3925
                                  case TYPEEVALUATE:
×
3926
                                        AT.WorkPointer = term + *term;
×
3927
                                        if ( C->lhs[level][2] == MZV
×
3928
                                                 || C->lhs[level][2] == EULER
3929
                                                 || C->lhs[level][2] == MZVHALF
3930
                                                 || C->lhs[level][2] == ALLMZVFUNCTIONS
×
3931
                                                 ) {
3932
                                                if ( EvaluateEuler(BHEAD term,level,C->lhs[level][2]) ) goto GenCall;
×
3933
                                        }
3934
                                        else {
3935
                                                if ( EvaluateFun(BHEAD term,level,C->lhs[level]) ) goto GenCall;
×
3936
                                        }
3937
/*
3938
                                        else if ( C->lhs[level][2] == SQRTFUNCTION ) {
3939
                                                if ( EvaluateSqrt(BHEAD term,level,C->lhs[level][2]) ) goto GenCall;
3940
                                        }
3941
                                        else {
3942
                                                MLOCK(ErrorMessageLock);
3943
                                                MesPrint("Illegal function %d in evaluate statement.",C->lhs[level][2]);
3944
                                                MUNLOCK(ErrorMessageLock);
3945
                                                goto GenCall;
3946
                                        }
3947
*/
3948
                                        goto Return0;
×
3949
                                  case TYPETOFLOAT:
×
3950
                                        AT.WorkPointer = term + *term;
×
3951
                                        if ( ToFloat(BHEAD term,level) ) goto GenCall;
×
3952
                                        goto Return0;
×
3953
                                  case TYPETORAT:
×
3954
                                        AT.WorkPointer = term + *term;
×
3955
                                        if ( ToRat(BHEAD term,level) ) goto GenCall;
×
3956
                                        goto Return0;
×
3957
#endif
3958
                                }
3959
                                goto SkipCount;
432,822✔
3960
/*
3961
                        #] Special action : 
3962
*/
3963
                        }
3964
                } while ( ( i = TestMatch(BHEAD term,&level) ) == 0 );
563,801✔
3965
                if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
306,700✔
3966
                if ( i > 0 ) replac = TestSub(BHEAD term,level);
306,700✔
3967
                else replac = i;
3968
                if ( replac >= 0 || AT.TMout[1] != SYMMETRIZE ) {
306,700✔
3969
                        *AN.RepPoint = 1;
306,684✔
3970
                        AR.expchanged = 1;
306,684✔
3971
                }
3972
                if ( replac < 0 ) {                /* Terms come from automatic generation */
306,700✔
3973
AutoGen:        i = *AT.TMout;
2,092✔
3974
                        t = termout = AT.WorkPointer;
2,108✔
3975
                        if ( ( AT.WorkPointer += i ) > AT.WorkTop ) goto OverWork;
2,108✔
3976
                        accum = AT.TMout;
1,054✔
3977
                        while ( --i >= 0 ) *t++ = *accum++;
30,704✔
3978
                        if ( (*(FG.Operation[termout[1]]))(BHEAD term,termout,replac,level) ) goto GenCall;
2,108✔
3979
                        AT.WorkPointer = termout;
2,108✔
3980
                        goto Return0;
2,108✔
3981
                }
3982
        }
3983
        if ( applyflag ) { TableReset(); applyflag = 0; }
5,904,660✔
3984

3985
        if ( AN.TeInFun ) {        /* Match in function argument */
5,904,660✔
3986
                if ( AN.TeInFun < 0 && !AN.TeSuOut ) {
1,217,304✔
3987

3988
                        if ( AR.TePos >= 0 ) goto AutoGen;
485✔
3989
                        switch ( AN.TeInFun ) {
469✔
3990
                                case -1:
20✔
3991
                                        if ( DoDistrib(BHEAD term,level) ) goto GenCall;
20✔
3992
                                        break;
3993
                                case -2:
24✔
3994
                                        if ( DoDelta3(BHEAD term,level) ) goto GenCall;
24✔
3995
                                        break;
3996
                                case -3:
4✔
3997
                                        if ( DoTableExpansion(term,level) ) goto GenCall;
4✔
3998
                                        break;
3999
                                case -4:
×
4000
                                        if ( FactorIn(BHEAD term,level) ) goto GenCall;
×
4001
                                        break;
4002
                                case -5:
×
4003
                                        if ( FactorInExpr(BHEAD term,level) ) goto GenCall;
×
4004
                                        break;
4005
                                case -6:
×
4006
                                        if ( TermsInBracket(BHEAD term,level) < 0 ) goto GenCall;
×
4007
                                        break;
4008
                                case -7:
×
4009
                                        if ( ExtraSymFun(BHEAD term,level) < 0 ) goto GenCall;
×
4010
                                        break;
4011
                                case -8:
240✔
4012
                                        if ( GCDfunction(BHEAD term,level) < 0 ) goto GenCall;
240✔
4013
                                        break;
4014
                                case -9:
38✔
4015
                                        if ( DIVfunction(BHEAD term,level,0) < 0 ) goto GenCall;
38✔
4016
                                        break;
4017
                                case -10:
38✔
4018
                                        if ( DIVfunction(BHEAD term,level,1) < 0 ) goto GenCall;
38✔
4019
                                        break;
4020
                                case -11:
22✔
4021
                                        if ( DIVfunction(BHEAD term,level,2) < 0 ) goto GenCall;
22✔
4022
                                        break;
4023
                                case -12:
4✔
4024
                                        if ( DoPermutations(BHEAD term,level) ) goto GenCall;
4✔
4025
                                        break;
4026
                                case -13:
16✔
4027
                                        if ( DoPartitions(BHEAD term,level) ) goto GenCall;
16✔
4028
                                        break;
4029
                                case -14:
59✔
4030
                                        if ( DIVfunction(BHEAD term,level,3) < 0 ) goto GenCall;
59✔
4031
                                        break;
4032
                                case -15:
×
4033
                                        if ( GenTopologies(BHEAD term,level) < 0 ) goto GenCall;
×
4034
                                        break;
4035
                                case -16:
4✔
4036
                                        if ( GenDiagrams(BHEAD term,level) < 0 ) goto GenCall;
4✔
4037
                                        break;
4038
                        }
4039
                }
4040
                else {
4041
                        termout = AT.WorkPointer;
1,216,819✔
4042
                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
1,216,819✔
4043
                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
1,216,819✔
4044
                        if ( InFunction(BHEAD term,termout) ) goto GenCall;
1,216,819✔
4045
                        AT.WorkPointer = termout + *termout;
1,216,819✔
4046
                        *AN.RepPoint = 1;
1,216,819✔
4047
                        AR.expchanged = 1;
1,216,819✔
4048
                        if ( *termout && Generator(BHEAD termout,level) < 0 ) goto GenCall;
1,216,819✔
4049
                        AT.WorkPointer = termout;
1,216,798✔
4050
                }
4051
        }
4052
        else if ( replac > 0 ) {
4,687,350✔
4053
                power = AN.TeSuOut;
4,655,260✔
4054
                tepos = AR.TePos;
4,655,260✔
4055
                if ( power < 0 ) {        /* Table expansion */
4,655,260✔
4056
                        power = -power; tepos = 0;
736✔
4057
                }
4058
                extractbuff = AT.TMbuff;
4,655,260✔
4059
                if ( extractbuff == AM.dbufnum ) {
4,655,260✔
4060
                        d = DolToTerms(BHEAD replac);
11,543✔
4061
                        if ( d && d->where != 0 ) {
11,543✔
4062
                                iscopy = 1;
11,543✔
4063
                                if ( AT.TMdolfac > 0 ) {        /* We need a factor */
11,543✔
4064
                                  if ( AT.TMdolfac == 1 ) {
190✔
4065
                                        if ( d->nfactors ) {
×
4066
                                                numfac[0] = 4;
×
4067
                                                numfac[1] = d->nfactors;
×
4068
                                                numfac[2] = 1;
×
4069
                                                numfac[3] = 3;
×
4070
                                                numfac[4] = 0;
×
4071
                                        }
4072
                                        else {
4073
                                                numfac[0] = 0;
×
4074
                                        }
4075
                                        StartBuf = numfac;
4076
                                  }
4077
                                  else {
4078
                                        if ( (AT.TMdolfac-1) > d->nfactors && d->nfactors > 0 ) {
190✔
4079
                                                MLOCK(ErrorMessageLock);
×
4080
                                                MesPrint("Attempt to use an nonexisting factor %d of a $-variable",(WORD)(AT.TMdolfac-1));
×
4081
                                                if ( d->nfactors == 1 )
×
4082
                                                        MesPrint("There is only one factor");
×
4083
                                                else
4084
                                                        MesPrint("There are only %d factors",(WORD)(d->nfactors));
×
4085
                                                MUNLOCK(ErrorMessageLock);
×
4086
                                                goto GenCall;
×
4087
                                        }
4088
                                        if ( d->nfactors > 1 ) {
190✔
4089
                                                DOLLARS dd;
190✔
4090
                                                LONG dsize;
190✔
4091
                                                WORD *td1, *td2;
190✔
4092
                                                dd = Dollars + replac;
190✔
4093
#ifdef WITHPTHREADS
4094
                                                {
4095
                                                        int nummodopt, dtype = -1;
124✔
4096
                                                        if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
124✔
4097
                                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
8✔
4098
                                                                        if ( replac == ModOptdollars[nummodopt].number ) break;
4099
                                                                }
4100
                                                                if ( nummodopt < NumModOptdollars ) {
8✔
4101
                                                                        dtype = ModOptdollars[nummodopt].type;
4102
                                                                        if ( dtype == MODLOCAL ) {
4103
                                                                                dd = ModOptdollars[nummodopt].dstruct+AT.identity;
4104
                                                                        }
4105
                                                                }
4106
                                                        }
4107
                                                }
4108
#endif
4109
                                                dsize = dd->factors[AT.TMdolfac-2].size;
190✔
4110
/*
4111
                                                We copy only the factor we need
4112
*/
4113
                                                if ( dsize == 0 ) {
190✔
4114
                                                        numfac[0] = 4;
4✔
4115
                                                        numfac[1] = d->factors[AT.TMdolfac-2].value;
4✔
4116
                                                        numfac[2] = 1;
4✔
4117
                                                        numfac[3] = 3;
4✔
4118
                                                        numfac[4] = 0;
4✔
4119
                                                        StartBuf = numfac;
4✔
4120
                                                        if ( numfac[1] < 0 ) {
4✔
4121
                                                                numfac[1] = -numfac[1];
4✔
4122
                                                                numfac[3] = -numfac[3];
4✔
4123
                                                        }
4124
                                                }
4125
                                                else {
4126
                                                d->factors[AT.TMdolfac-2].where = td2 = (WORD *)Malloc1(
372✔
4127
                                                        (dsize+1)*sizeof(WORD),"Copy of factor");
186✔
4128
                                                td1 = dd->factors[AT.TMdolfac-2].where;
186✔
4129
                                                StartBuf = td2;
186✔
4130
                                                d->size = dsize; d->type = DOLTERMS;
186✔
4131
                                                NCOPY(td2,td1,dsize);
3,252✔
4132
                                                *td2 = 0;
186✔
4133
                                                }
4134
                                        }
4135
                                        else if ( d->nfactors == 1 ) {
×
4136
                                                StartBuf = d->where;
4137
                                        }
4138
                                        else {
4139
                                                MLOCK(ErrorMessageLock);
×
4140
                                                if ( d->nfactors == 0 ) {
×
4141
                                                        MesPrint("Attempt to use factor %d of an unfactored $-variable",(WORD)(AT.TMdolfac-1));
×
4142
                                                }
4143
                                                else {
4144
                                                        MesPrint("Internal error. Illegal number of factors for $-variable");
×
4145
                                                }
4146
                                                MUNLOCK(ErrorMessageLock);
×
4147
                                                goto GenCall;
×
4148
                                        }
4149
                                  }
4150
                                }
4151
                                else StartBuf = d->where;
4152
                        }
4153
                        else {
4154
                                d = Dollars + replac;
×
4155
                                StartBuf = zeroDollar;
×
4156
                        }
4157
                        posisub = 0;
11,543✔
4158
                        i = DetCommu(d->where);
11,543✔
4159
#ifdef WITHPTHREADS
4160
                        if ( AS.MultiThreaded ) {
5,760✔
4161
                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
4,480✔
4162
                                        if ( replac == ModOptdollars[nummodopt].number ) break;
4,400✔
4163
                                }
4164
                                if ( nummodopt < NumModOptdollars ) {
4,480✔
4165
                                        dtype = ModOptdollars[nummodopt].type;
4,400✔
4166
                                        if ( dtype != MODLOCAL && dtype != MODSUM ) {
4,400✔
4167
                                                if ( StartBuf[0] && StartBuf[StartBuf[0]] ) {
4168
                                                        MLOCK(ErrorMessageLock);
4169
                                                        MesPrint("A dollar variable with modoption max or min can have only one term");
4170
                                                        MUNLOCK(ErrorMessageLock);
4171
                                                        goto GenCall;
4172
                                                }
4173
                                                LOCK(d->pthreadslockread);
4174
                                        }
4175
                                }
4176
                        }
4177
#endif
4178
                }
4179
                else {
4180
                        StartBuf = cbuf[extractbuff].Buffer;
4,643,710✔
4181
                        posisub = cbuf[extractbuff].rhs[replac] - StartBuf;
4,643,710✔
4182
                        i = (WORD)cbuf[extractbuff].CanCommu[replac];
4,643,710✔
4183
                }
4184
                if ( power == 1 ) {                /* Just a single power */
4,655,260✔
4185
                        termout = AT.WorkPointer;
4,559,190✔
4186
                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
4,559,190✔
4187
                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
4,559,190✔
4188
                        while ( StartBuf[posisub] ) {
11,021,330✔
4189
                                if ( extractbuff == AT.allbufnum ) WildDollars(BHEAD &(StartBuf[posisub]));
6,466,570✔
4190
                            AT.WorkPointer = (WORD *)(((UBYTE *)(termout)) + AM.MaxTer);
6,466,570✔
4191
                                if ( InsertTerm(BHEAD term,replac,extractbuff,
6,466,570✔
4192
                                        &(StartBuf[posisub]),termout,tepos) < 0 ) goto GenCall;
×
4193
                                AT.WorkPointer = termout + *termout;
6,466,570✔
4194
                                *AN.RepPoint = 1;
6,466,570✔
4195
                                AR.expchanged = 1;
6,466,570✔
4196
                                posisub += StartBuf[posisub];
6,466,570✔
4197
/*
4198
                                        For multiple table substitutions it may be better to
4199
                                        do modulus arithmetic right here
4200
                                        Turns out to be not very effective.
4201

4202
                                if ( AN.ncmod != 0 ) {
4203
                                        if ( Modulus(termout) ) goto GenCall;
4204
                                        if ( !*termout ) goto Return0;
4205
                                }
4206
*/
4207
#ifdef WITHPTHREADS
4208
                                if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); }
3,380,440✔
4209
                                if ( ( AS.Balancing && CC->numrhs == 0 ) && StartBuf[posisub] ) {
3,380,440✔
4210
                                        if ( ( id = ConditionalGetAvailableThread() ) >= 0 ) {
4211
                                                if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall;
4212
                                        }
4213
                                }
4214
                                else
4215
#endif
4216
                                if ( Generator(BHEAD termout,level) < 0 ) goto GenCall;
6,466,570✔
4217
#ifdef WITHPTHREADS
4218
                                if ( dtype > 0 && dtype != MODLOCAL ) { dtype = 0; break; }
3,380,420✔
4219
#endif
4220
                                if ( iscopy == 0 && ( extractbuff != AM.dbufnum ) ) {
6,462,140✔
4221
/*
4222
                                        There are cases in which a bigger buffer is created
4223
                                        on the fly, like with wildcard buffers.
4224
                                        We play it safe here. Maybe we can be more selective
4225
                                        in some distant future?
4226
*/
4227
                                        StartBuf = cbuf[extractbuff].Buffer;
6,453,560✔
4228
                                }
4229
                        }
4230
                        if ( extractbuff == AT.allbufnum ) {
4,559,160✔
4231
                                CBUF *Ce = cbuf + extractbuff;
8✔
4232
                                Ce->Pointer = Ce->rhs[Ce->numrhs--];
8✔
4233
                        }
4234
#ifdef WITHPTHREADS
4235
                        if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); dtype = 0; }
2,336,740✔
4236
#endif
4237
                        if ( iscopy ) {
4,559,160✔
4238
                                if ( d->nfactors > 1 ) {
11,532✔
4239
                                        int j;
4240
                                        for ( j = 0; j < d->nfactors; j++ ) {
10,346✔
4241
                                                if ( d->factors[j].where ) M_free(d->factors[j].where,"Copy of factor");
10,156✔
4242
                                        }
4243
                                        M_free(d->factors,"Dollar factors");
190✔
4244
                                }
4245
                                M_free(d,"Copy of dollar variable");
11,532✔
4246
                                d = 0; iscopy = 0;
11,532✔
4247
                        }
4248
                        AT.WorkPointer = termout;
4,559,160✔
4249
                }
4250
                else if ( i <= 1 ) {                /* Use binomials */
96,060✔
4251
                        LONG posit, olw;
96,060✔
4252
                        WORD *same, *ow = AT.WorkPointer;
96,060✔
4253
                        LONG olpw = AT.posWorkPointer;
96,060✔
4254
                        power1 = power+1;
96,060✔
4255
                        WantAddLongs(power1);
96,322✔
4256
                        olw = posit = AT.lWorkPointer; AT.lWorkPointer += power1;
96,060✔
4257
                        same = ++AT.WorkPointer;
96,060✔
4258
                        a = accum = ( AT.WorkPointer += power1+1 );
96,060✔
4259
                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2*AM.MaxTer);
96,060✔
4260
                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
96,060✔
4261
                        AT.lWorkSpace[posit] = posisub;
96,060✔
4262
                        same[-1] = 0;
96,060✔
4263
                        *same = 1;
96,060✔
4264
                        *accum = 0;
96,060✔
4265
                        tepos = AR.TePos;
96,060✔
4266
                        i = 1;
96,060✔
4267
                        do {
3,867,765✔
4268
                                if ( StartBuf[AT.lWorkSpace[posit]] ) {
3,867,765✔
4269
                                        if ( ( a = PasteTerm(BHEAD i-1,accum,
2,002,508✔
4270
                                                &(StartBuf[AT.lWorkSpace[posit]]),i,*same) ) == 0 )
4271
                                                goto GenCall;
×
4272
                                        AT.lWorkSpace[posit+1] = AT.lWorkSpace[posit];
2,002,508✔
4273
                                        same[1] = *same + 1;
2,002,508✔
4274
                                        if ( i > 1 && AT.lWorkSpace[posit] < AT.lWorkSpace[posit-1] ) *same = 1;
2,002,508✔
4275
                                        AT.lWorkSpace[posit] += StartBuf[AT.lWorkSpace[posit]];
2,002,508✔
4276
                                        i++;
2,002,508✔
4277
                                        posit++;
2,002,508✔
4278
                                        same++;
2,002,508✔
4279
                                }
4280
                                else {
4281
                                        i--; posit--; same--;
1,865,257✔
4282
                                }
4283
                                if ( i > power ) {
3,867,765✔
4284
                                        termout = AT.WorkPointer = a;
233,311✔
4285
                                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2*AM.MaxTer);
233,311✔
4286
                                        if ( AT.WorkPointer > AT.WorkTop )
233,311✔
4287
                                                goto OverWork;
×
4288
                                        if ( FiniTerm(BHEAD term,accum,termout,replac,tepos) ) goto GenCall;
233,311✔
4289
                                        AT.WorkPointer = termout + *termout;
233,311✔
4290
                                        *AN.RepPoint = 1;
233,311✔
4291
                                        AR.expchanged = 1;
233,311✔
4292
#ifdef WITHPTHREADS
4293
                                        if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); }
117,860✔
4294
                                        if ( ( AS.Balancing && CC->numrhs == 0 ) && ( i > 0 )
117,860✔
4295
                                        && ( id = ConditionalGetAvailableThread() ) >= 0 ) {
4296
                                                if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall;
4297
                                        }
4298
                                        else
4299
#endif
4300
                                        if ( Generator(BHEAD termout,level) ) goto GenCall;
233,311✔
4301
#ifdef WITHPTHREADS
4302
                                        if ( dtype > 0 && dtype != MODLOCAL ) { dtype = 0; break; }
117,860✔
4303
#endif
4304
                                        if ( iscopy == 0 && ( extractbuff != AM.dbufnum ) )
233,311✔
4305
                                                        StartBuf = cbuf[extractbuff].Buffer;
230,763✔
4306
                                        i--; posit--; same--;
233,311✔
4307
                                }
4308
                        } while ( i > 0 );
3,867,765✔
4309
#ifdef WITHPTHREADS
4310
                        if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); dtype = 0; }
49,190✔
4311
#endif
4312
                        if ( iscopy ) {
96,060✔
4313
                                if ( d->nfactors > 1 ) {
11✔
4314
                                        int j;
4315
                                        for ( j = 0; j < d->nfactors; j++ ) {
×
4316
                                                if ( d->factors[j].where ) M_free(d->factors[j].where,"Copy of factor");
×
4317
                                        }
4318
                                        M_free(d->factors,"Dollar factors");
×
4319
                                }
4320
                                M_free(d,"Copy of dollar variable");
11✔
4321
                                d = 0; iscopy = 0;
11✔
4322
                        }
4323
                        AT.WorkPointer = ow; AT.lWorkPointer = olw; AT.posWorkPointer = olpw;
96,060✔
4324
                }
4325
                else {                                                        /* No binomials */
4326
                        LONG posit, olw, olpw = AT.posWorkPointer;
×
4327
                        WantAddLongs(power);
×
4328
                        posit = olw = AT.lWorkPointer; AT.lWorkPointer += power;
×
4329
                        a = accum = AT.WorkPointer;
×
4330
                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2*AM.MaxTer);
×
4331
                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
×
4332
                        for ( i = 0; i < power; i++ ) AT.lWorkSpace[posit++] = posisub;
×
4333
                        posit = olw;
×
4334
                        *accum = 0;
×
4335
                        tepos = AR.TePos;
×
4336
                        i = 0;
×
4337
                        while ( i >= 0 ) {
×
4338
                                if ( StartBuf[AT.lWorkSpace[posit]] ) {
×
4339
                                        if ( ( a = PasteTerm(BHEAD i,accum,
×
4340
                                                &(StartBuf[AT.lWorkSpace[posit]]),1,1) ) == 0 ) goto GenCall;
×
4341
                                        AT.lWorkSpace[posit] += StartBuf[AT.lWorkSpace[posit]];
×
4342
                                        i++; posit++;
×
4343
                                }
4344
                                else {
4345
                                        AT.lWorkSpace[posit--] = posisub;
×
4346
                                        i--;
×
4347
                                }
4348
                                if ( i >= power ) {
×
4349
                                        termout = AT.WorkPointer = a;
×
4350
                                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2*AM.MaxTer);
×
4351
                                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
×
4352
                                        if ( FiniTerm(BHEAD term,accum,termout,replac,tepos) ) goto GenCall;
×
4353
                                        AT.WorkPointer = termout + *termout;
×
4354
                                        *AN.RepPoint = 1;
×
4355
                                        AR.expchanged = 1;
×
4356
#ifdef WITHPTHREADS
4357
                                        if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); }
4358
                                        if ( ( AS.Balancing && CC->numrhs == 0 ) && ( i > 0 ) && ( id = ConditionalGetAvailableThread() ) >= 0 ) {
4359
                                                if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall;
4360
                                        }
4361
                                        else
4362
#endif
4363
                                        if ( Generator(BHEAD termout,level) ) goto GenCall;
×
4364
#ifdef WITHPTHREADS
4365
                                        if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { dtype = 0; break; }
4366
#endif
4367
                                        if ( iscopy == 0 && ( extractbuff != AM.dbufnum ) )
×
4368
                                                        StartBuf = cbuf[extractbuff].Buffer;
×
4369
                                        i--; posit--;
×
4370
                                }
4371
                        }
4372
#ifdef WITHPTHREADS
4373
                        if ( dtype > 0 && dtype != MODLOCAL && dtype != MODSUM ) { UNLOCK(d->pthreadslockread); dtype = 0; }
4374
#endif
4375
                        if ( iscopy ) {
×
4376
                                if ( d->nfactors > 1 ) {
×
4377
                                        int j;
4378
                                        for ( j = 0; j < d->nfactors; j++ ) {
×
4379
                                                if ( d->factors[j].where ) M_free(d->factors[j].where,"Copy of factor");
×
4380
                                        }
4381
                                        M_free(d->factors,"Dollar factors");
×
4382
                                }
4383
                                M_free(d,"Copy of dollar variable");
×
4384
                                d = 0; iscopy = 0;
×
4385
                        }
4386
                        AT.WorkPointer = accum;
×
4387
                        AT.lWorkPointer = olw;
×
4388
                        AT.posWorkPointer = olpw;
×
4389
                }
4390
        }
4391
        else {                                                                /* Expression from disk */
4392
                POSITION StartPos;
32,103✔
4393
                LONG position, olpw, opw, comprev, extra;
32,103✔
4394
                RENUMBER renumber;
32,103✔
4395
                WORD *Freeze, *aa, *dummies;
32,103✔
4396
                replac = -replac-1;
32,103✔
4397
                power = AN.TeSuOut;
32,103✔
4398
                Freeze = AN.Frozen;
32,103✔
4399
                if ( Expressions[replac].status == STOREDEXPRESSION ) {
32,103✔
4400
                        POSITION firstpos;
×
4401
                        SETSTARTPOS(firstpos);
×
4402

4403
/*                        Note that AT.TMaddr is needed for GetTable just once! */
4404
/*
4405
                        We need space for the previous term in the compression
4406
                        This is made available in AR.CompressBuffer, although we may get
4407
                        problems with this sooner or later. Hence we need to keep
4408
                        a set of pointers in AR.CompressBuffer
4409
                        Note that after the last call there has been no use made
4410
                        of AR.CompressPointer, so it points automatically at its original
4411
                        position!
4412
*/
4413
                        WantAddPointers(power+1);
×
4414
                        comprev = opw = AT.pWorkPointer;
×
4415
                        AT.pWorkPointer += power+1;
×
4416
                        WantAddPositions(power+1);
×
4417
                        position = olpw = AT.posWorkPointer;
×
4418
                        AT.posWorkPointer += power + 1;
×
4419

4420
                        AT.pWorkSpace[comprev++] = AR.CompressPointer;
×
4421

4422
                        for ( i = 0; i < power; i++ ) {
×
4423
                                PUTZERO(AT.posWorkSpace[position]); position++;
×
4424
                        }
4425
                        position = olpw;
×
4426
                        if ( ( renumber = GetTable(replac,&(AT.posWorkSpace[position]),1) ) == 0 ) goto GenCall;
×
4427
                        dummies = AT.WorkPointer;
×
4428
                        *dummies++ = AR.CurDum;
×
4429
                        AT.WorkPointer += power+2;
×
4430
                        accum = AT.WorkPointer;
×
4431
                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2*AM.MaxTer);
×
4432
                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
×
4433
                        aa = AT.WorkPointer;
×
4434
                        *accum = 0;
×
4435
                        i = 0; StartPos = AT.posWorkSpace[position];
×
4436
                        dummies[i] = AR.CurDum;
×
4437
                        while ( i >= 0 ) {
×
4438
skippedfirst:
×
4439
                                AR.CompressPointer = AT.pWorkSpace[comprev-1];
×
4440
                                if ( ( extra = PasteFile(BHEAD i,accum,&(AT.posWorkSpace[position])
×
4441
                                                ,&a,renumber,Freeze,replac) ) < 0 ) goto GenCall;
×
4442
                                if ( Expressions[replac].numdummies > 0 ) {
×
4443
                                        AR.CurDum = dummies[i] + Expressions[replac].numdummies;
×
4444
                                }
4445
                                if ( NOTSTARTPOS(firstpos) ) {
×
4446
                                        if ( ISMINPOS(firstpos) || ISEQUALPOS(firstpos,AT.posWorkSpace[position]) ) {
×
4447
                                                firstpos = AT.posWorkSpace[position];
×
4448
/*
4449
                                                ADDPOS(AT.posWorkSpace[position],extra * sizeof(WORD));
4450
*/
4451
                                                goto skippedfirst;
×
4452
                                        }
4453
                                }
4454
                                if ( extra ) { 
×
4455
/*
4456
                                        ADDPOS(AT.posWorkSpace[position],extra * sizeof(WORD));
4457
*/
4458
                                        i++; AT.posWorkSpace[++position] = StartPos;
×
4459
                                        AT.pWorkSpace[comprev++] = AR.CompressPointer;
×
4460
                                        dummies[i] = AR.CurDum;
×
4461
                                }
4462
                                else {
4463
                                        PUTZERO(AT.posWorkSpace[position]); position--; i--;
×
4464
                                        AR.CurDum = dummies[i];
×
4465
                                        comprev--;
×
4466
                                }
4467
                                if ( i >= power ) {
×
4468
                                        termout = AT.WorkPointer = a;
×
4469
                                    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2*AM.MaxTer);
×
4470
                                        if ( AT.WorkPointer > AT.WorkTop ) goto OverWork;
×
4471
                                        if ( FiniTerm(BHEAD term,accum,termout,replac,0) ) goto GenCall;
×
4472
                                        if ( *termout ) {
×
4473
                                                AT.WorkPointer = termout + *termout;
×
4474
                                                *AN.RepPoint = 1;
×
4475
                                                AR.expchanged = 1;
×
4476
#ifdef WITHPTHREADS
4477
                                                if ( ( AS.Balancing && CC->numrhs == 0 ) && ( i > 0 ) && ( id = ConditionalGetAvailableThread() ) >= 0 ) {
4478
                                                        if ( BalanceRunThread(BHEAD id,termout,level) < 0 ) goto GenCall;
4479

4480
                                                }
4481
                                                else
4482
#endif
4483
                                                if ( Generator(BHEAD termout,level) ) goto GenCall;
×
4484
                                        }
4485
                                        i--; position--;
×
4486
                                        AR.CurDum = dummies[i];
×
4487
                                        comprev--;
×
4488
                                }
4489
                                AT.WorkPointer = aa;
×
4490
                        }
4491
                        AT.WorkPointer = accum;
×
4492
                        AT.posWorkPointer = olpw;
×
4493
                        AT.pWorkPointer = opw;
×
4494
/*
4495
                Bug fix. See also GetTable
4496
#ifdef WITHPTHREADS
4497
                        M_free(renumber->symb.lo,"VarSpace");
4498
                        M_free(renumber,"Renumber");
4499
#endif
4500
*/
4501
                        if ( renumber->symb.lo != AN.dummyrenumlist )
×
4502
                                M_free(renumber->symb.lo,"VarSpace");
×
4503
                        M_free(renumber,"Renumber");
×
4504

4505
                }
4506
                else {                        /* Active expression */
4507
                        aa = accum = AT.WorkPointer;
32,103✔
4508
                        if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + 2 * AM.MaxTer + sizeof(WORD)) ) > AT.WorkTop )
32,103✔
4509
                                        goto OverWork;
×
4510
                        *accum++ = -1; AT.WorkPointer++;
32,103✔
4511
                        if ( DoOnePow(BHEAD term,power,replac,accum,aa,level,Freeze) ) goto GenCall;
32,103✔
4512
                        AT.WorkPointer = aa;
32,103✔
4513
                }
4514
          }
4515
Return0:
14,033,420✔
4516
        AR.CurDum = DumNow;
14,033,420✔
4517
        AN.RepPoint = RepSto;
14,033,420✔
4518
        CC->numrhs = oldtoprhs;
14,033,420✔
4519
        CC->Pointer = CC->Buffer + oldcpointer;
14,033,420✔
4520
        CCC->numrhs = oldatoprhs;
14,033,420✔
4521
        CCC->Pointer = CCC->Buffer + oldacpointer;
14,033,420✔
4522
        return(0);
14,033,420✔
4523

4524
GenCall:
30✔
4525
        if ( AM.tracebackflag ) {
30✔
4526
                termout = term;
20✔
4527
                MLOCK(ErrorMessageLock);
20✔
4528
                AO.OutFill = AO.OutputLine = (UBYTE *)AT.WorkPointer;
20✔
4529
                AO.OutSkip = 3;
20✔
4530
                FiniLine();
20✔
4531
                i = *termout;
20✔
4532
                while ( --i >= 0 ) {
33,702✔
4533
                        TalToLine((UWORD)(*termout++));
33,682✔
4534
                        TokenToLine((UBYTE *)"  ");
33,682✔
4535
                }
4536
                AO.OutSkip = 0;
20✔
4537
                FiniLine();
20✔
4538
                MesCall("Generator");
20✔
4539
                MUNLOCK(ErrorMessageLock);
30✔
4540
        }
4541
        CC->numrhs = oldtoprhs;
30✔
4542
        CC->Pointer = CC->Buffer + oldcpointer;
30✔
4543
        CCC->numrhs = oldatoprhs;
30✔
4544
        CCC->Pointer = CCC->Buffer + oldacpointer;
30✔
4545
        return(-1);
30✔
4546
OverWork:
×
4547
        CC->numrhs = oldtoprhs;
×
4548
        CC->Pointer = CC->Buffer + oldcpointer;
×
4549
        CCC->numrhs = oldatoprhs;
×
4550
        CCC->Pointer = CCC->Buffer + oldacpointer;
×
4551
        MLOCK(ErrorMessageLock);
×
4552
        MesWork();
×
4553
        MUNLOCK(ErrorMessageLock);
×
4554
        return(-1);
4555
}
4556

4557
/*
4558
                 #] Generator : 
4559
                 #[ DoOnePow :                        WORD DoOnePow(term,power,nexp,accum,aa,level,freeze)
4560
*/
4561
/**
4562
 *                Routine gets one power of an expression in the scratch system.
4563
 *                If there are more powers needed there will be a recursion.
4564
 *
4565
 *                No attempt is made to use binomials because we have no
4566
 *                information about commuting properties.
4567
 *
4568
 *                There is a searching for the contents of brackets if needed.
4569
 *                This searching may be rather slow because of the single links.
4570
 *
4571
 *                @param term   is the term we are adding to.
4572
 *                @param power  is the power of the expression that we need.
4573
 *                @param nexp   is the number of the expression.
4574
 *                @param accum  is the accumulator of terms. It accepts the termfragments
4575
 *                                  that are made into a proper term in FiniTerm
4576
 *                @param aa          points to the start of the entire accumulator. In *aa
4577
 *                                  we store the number of term fragments that are in the
4578
 *                                  accumulator.
4579
 *                @param level  is the current depth in the tree of statements. It is
4580
 *                                  needed to continue to the next operation/substitution
4581
 *                                  with each generated term
4582
 *                @param freeze is the pointer to the bracket information that should
4583
 *                                  be matched.
4584
 */
4585
#ifdef WITHPTHREADS
4586
char freezestring[] = "freeze<-xxxx";
4587
#endif
4588

4589
WORD DoOnePow(PHEAD WORD *term, WORD power, WORD nexp, WORD * accum,
32,131✔
4590
              WORD *aa, WORD level, WORD *freeze)
4591
{
4592
        GETBIDENTITY
4593
        POSITION oldposition, startposition;
32,131✔
4594
        WORD *acc, *termout, fromfreeze = 0;
32,131✔
4595
        WORD *oldipointer = AR.CompressPointer;
32,131✔
4596
        FILEHANDLE *fi;
32,131✔
4597
        WORD type, retval;
32,131✔
4598
        WORD oldGetOneFile = AR.GetOneFile;
32,131✔
4599
        WORD olddummies = AR.CurDum;
32,131✔
4600
        WORD extradummies = Expressions[nexp].numdummies;
32,131✔
4601
/*
4602
        The next code is for some tricky debugging. (5-jan-2010 JV)
4603
        Normally it should be disabled.
4604
*/
4605
/*
4606
#ifdef WITHPTHREADS
4607
        if ( freeze ) {
4608
                MLOCK(ErrorMessageLock);
4609
                if ( AT.identity < 10 ) {
4610
                        freezestring[8] = '0'+AT.identity;
4611
                        freezestring[9] = '>';
4612
                        freezestring[10] = 0;
4613
                }
4614
                else if ( AT.identity < 100 ) {
4615
                        freezestring[8] = '0'+AT.identity/10;
4616
                        freezestring[9] = '0'+AT.identity%10;
4617
                        freezestring[10] = '>';
4618
                        freezestring[11] = 0;
4619
                }
4620
                else {
4621
                        freezestring[8] = 0;
4622
                }
4623
                PrintTerm(freeze,freezestring);
4624
                MUNLOCK(ErrorMessageLock);
4625
        }
4626
#else
4627
        if ( freeze ) PrintTerm(freeze,"freeze");
4628
#endif
4629
*/
4630
        type = Expressions[nexp].status;
32,131✔
4631
        if ( type == HIDDENLEXPRESSION || type == HIDDENGEXPRESSION
32,131✔
4632
         || type == DROPHLEXPRESSION || type == DROPHGEXPRESSION
32,081✔
4633
         || type == UNHIDELEXPRESSION || type == UNHIDEGEXPRESSION ) {
32,037✔
4634
                AR.GetOneFile = 2; fi = AR.hidefile;
94✔
4635
        }
4636
        else {
4637
                AR.GetOneFile = 0; fi = AR.infile;
32,037✔
4638
        }
4639
        if ( fi->handle >= 0 ) {
32,131✔
4640
                PUTZERO(oldposition);
30,000✔
4641
#ifdef WITHSEEK
4642
                LOCK(AS.inputslock);
4643
                SeekFile(fi->handle,&oldposition,SEEK_CUR);
4644
                UNLOCK(AS.inputslock);
4645
#endif
4646
        }
4647
        else {
4648
                SETBASEPOSITION(oldposition,fi->POfill-fi->PObuffer);
2,131✔
4649
        }
4650
        if ( freeze && ( Expressions[nexp].bracketinfo != 0 ) ) {
32,131✔
4651
                POSITION *brapos;
30,109✔
4652
/*
4653
                There is a bracket index
4654
                AR.CompressPointer = oldipointer;
4655
*/
4656
                (*aa)++;
30,109✔
4657
                power--;
30,109✔
4658
                if ( ( brapos = FindBracket(nexp,freeze) ) == 0 )
30,109✔
4659
                        goto EndExpr;
×
4660
                startposition = *brapos;
30,109✔
4661
                goto doterms;
30,109✔
4662
        }
4663
        startposition = AS.OldOnFile[nexp];
2,022✔
4664
        retval = GetOneTerm(BHEAD accum,fi,&startposition,0);
2,022✔
4665
        if ( retval > 0 ) {                        /* Skip prototype */
2,022✔
4666
                (*aa)++;
2,022✔
4667
                power--;
2,022✔
4668
doterms:
32,131✔
4669
                AR.CompressPointer = oldipointer;
32,131✔
4670
                for (;;) {
6,228,235✔
4671
                        retval = GetOneTerm(BHEAD accum,fi,&startposition,0);
3,130,177✔
4672
                        if ( retval <= 0 ) break;
3,130,177✔
4673
/*
4674
                        Here should come the code to test for [].
4675
*/
4676
                        if ( freeze ) {
3,127,841✔
4677
                                WORD *t, *m, *r, *mstop;
3,030,166✔
4678
                                WORD *tset;
3,030,166✔
4679
                                t = accum;
3,030,166✔
4680
                                m = freeze;
3,030,166✔
4681
                                m += *m;
3,030,166✔
4682
                                m -= ABS(m[-1]);
3,030,166✔
4683
                                mstop = m;
3,030,166✔
4684
                                m = freeze + 1;
3,030,166✔
4685
                                r = t;
3,030,166✔
4686
                                r += *t;
3,030,166✔
4687
                                r -= ABS(r[-1]);
3,030,166✔
4688
                                t++;
3,030,166✔
4689
                                tset = t;
3,030,166✔
4690
                                while ( t < r && *t != HAAKJE ) t += t[1];
6,060,374✔
4691
                                if ( t >= r ) {
3,030,166✔
4692
                                        if ( m < mstop ) {
×
4693
                                                if ( fromfreeze ) goto EndExpr;
×
4694
                                                goto NextTerm;
×
4695
                                        }
4696
                                        t = tset;
4697
                                }
4698
                                else {
4699
                                        r = tset;
4700
                                        while ( r < t && m < mstop ) {
18,150,541✔
4701
                                                if ( *r == *m ) { m++; r++; }
15,150,180✔
4702
                                                else {
4703
                                                        if ( fromfreeze ) goto EndExpr;
29,793✔
4704
                                                        goto NextTerm;
33✔
4705
                                                }
4706
                                        }
4707
                                        if ( r < t || m < mstop ) {
3,000,361✔
4708
                                                if ( fromfreeze ) goto EndExpr;
40✔
4709
                                                goto NextTerm;
8✔
4710
                                        }
4711
                                }
4712
                                fromfreeze = 1;
36,003,553✔
4713
                                r = tset;
4714
                                m = accum;
4715
                                m += *m;
36,003,553✔
4716
                                while ( t < m ) *r++ = *t++;
36,003,553✔
4717
                                *accum = WORDDIF(r,accum);
3,000,321✔
4718
                        }
4719
                        if ( extradummies > 0 ) {
3,097,996✔
4720
                                if ( olddummies > AM.IndDum ) {
24✔
4721
                                        MoveDummies(BHEAD accum,olddummies-AM.IndDum);
24✔
4722
                                }
4723
                                AR.CurDum = olddummies+extradummies;
24✔
4724
                        }
4725
                        acc = accum;
3,097,996✔
4726
                        acc += *acc;
3,097,996✔
4727
                        if ( power <= 0 ) {
3,097,996✔
4728
                                termout = acc;
3,097,989✔
4729
                            AT.WorkPointer = (WORD *)(((UBYTE *)(acc)) + 2*AM.MaxTer);
3,097,989✔
4730
                                if ( AT.WorkPointer > AT.WorkTop ) {
3,097,989✔
4731
                                        MLOCK(ErrorMessageLock);
×
4732
                                        MesWork();
×
4733
                                        MUNLOCK(ErrorMessageLock);
×
4734
                                        return(-1);
×
4735
                                }
4736
                                if ( FiniTerm(BHEAD term,aa,termout,nexp,0) ) goto PowCall;
3,097,989✔
4737
                                if ( *termout ) {
3,097,989✔
4738
                                        MarkPolyRatFunDirty(termout)
3,116,429✔
4739
/*                                        PolyFunDirty(BHEAD termout); */
4740
                                        AT.WorkPointer = termout + *termout;
3,097,989✔
4741
                                        *AN.RepPoint = 1;
3,097,989✔
4742
                                        AR.expchanged = 1;
3,097,989✔
4743
                                        if ( Generator(BHEAD termout,level) ) goto PowCall;
3,097,989✔
4744
                                }
4745
                        }
4746
                        else {
4747
                                if ( acc > AT.WorkTop ) {
28✔
4748
                                        MLOCK(ErrorMessageLock);
×
4749
                                        MesWork();
×
4750
                                        MUNLOCK(ErrorMessageLock);
×
4751
                                        return(-1);
×
4752
                                }
4753
                                if ( DoOnePow(BHEAD term,power,nexp,acc,aa,level,freeze) ) goto PowCall;
28✔
4754
                        }
4755
NextTerm:;
28✔
4756
                        AR.CompressPointer = oldipointer;
3,098,058✔
4757
                }
4758
EndExpr:
2,339✔
4759
                (*aa)--;
32,131✔
4760
        }
4761
        AR.CompressPointer = oldipointer;
32,131✔
4762
        if ( fi->handle >= 0 ) {
32,131✔
4763
#ifdef WITHSEEK
4764
                LOCK(AS.inputslock);
4765
                SeekFile(fi->handle,&oldposition,SEEK_SET);
4766
                UNLOCK(AS.inputslock);
4767
                if ( ISNEGPOS(oldposition) ) {
4768
                        MLOCK(ErrorMessageLock);
4769
                        MesPrint("File error");
4770
                        goto PowCall2;
4771
                }
4772
#endif
4773
        }
4774
        else {
4775
                fi->POfill = fi->PObuffer + BASEPOSITION(oldposition);
2,131✔
4776
        }
4777
        AR.GetOneFile = oldGetOneFile;
32,131✔
4778
        AR.CurDum = olddummies;
32,131✔
4779
        return(0);
32,131✔
4780
PowCall:;
×
4781
        MLOCK(ErrorMessageLock);
×
4782
#ifdef WITHSEEK
4783
PowCall2:;
4784
#endif
4785
        MesCall("DoOnePow");
×
4786
        MUNLOCK(ErrorMessageLock);
×
4787
        SETERROR(-1)
×
4788
}
4789

4790
/*
4791
                 #] DoOnePow : 
4792
                 #[ Deferred :                        WORD Deferred(term,level)
4793
*/
4794
/**
4795
 *                Picks up the deferred brackets.
4796
 *                These are the bracket contents of which we postpone the reading
4797
 *                when we use the 'Keep Brackets' statement. These contents are
4798
 *                multiplying the terms just before they are sent to the sorting
4799
 *                system.
4800
 *                Special attention goes to having it thread-safe
4801
 *                We have to lock positioning the file and reading it in
4802
 *                a thread specific buffer.
4803
 *
4804
 *                @param term  The term that must be multiplied by the contents of the
4805
 *                             current bracket
4806
 *                @param level The compiler level. This is needed because after
4807
 *                             multiplying term by term we call Generator again.
4808
 */
4809

4810
WORD Deferred(PHEAD WORD *term, WORD level)
6,081,130✔
4811
{
4812
        GETBIDENTITY
4813
        POSITION startposition;
6,081,130✔
4814
        WORD *t, *m, *mstop, *tstart, decr, oldb, *termout, i, *oldwork, retval;
6,081,130✔
4815
        WORD *oldipointer = AR.CompressPointer, *oldPOfill = AR.infile->POfill;
6,081,130✔
4816
        WORD oldGetOneFile = AR.GetOneFile;
6,081,130✔
4817
        AR.GetOneFile = 1;
6,081,130✔
4818
        oldwork = AT.WorkPointer;
6,081,130✔
4819
    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
6,081,130✔
4820
        termout = AT.WorkPointer;
6,081,130✔
4821
        AR.DeferFlag = 0;
6,081,130✔
4822
        startposition = AR.DefPosition;
6,081,130✔
4823
/*
4824
                Store old position
4825
*/
4826
        if ( AR.infile->handle >= 0 ) {
6,081,130✔
4827
/*
4828
                PUTZERO(oldposition);
4829
                SeekFile(AR.infile->handle,&oldposition,SEEK_CUR);
4830
*/
4831
        }
4832
        else {
4833
/*
4834
                SETBASEPOSITION(oldposition,AR.infile->POfill-AR.infile->PObuffer);
4835
*/
4836
                AR.infile->POfill = (WORD *)((UBYTE *)(AR.infile->PObuffer)
6,081,130✔
4837
                                        +BASEPOSITION(startposition));
6,081,130✔
4838
        }
4839
/*
4840
                Look in the CompressBuffer where the bracket contents start
4841
*/
4842
        t = m = AR.CompressBuffer;
6,081,130✔
4843
        t += *t;
6,081,130✔
4844
        mstop = t - ABS(t[-1]);
6,081,130✔
4845
        m++;
6,081,130✔
4846
        while ( *m != HAAKJE && m < mstop ) m += m[1];
12,162,270✔
4847
        if ( m >= mstop ) {        /* No deferred action! */
6,081,130✔
4848
                AT.WorkPointer = term + *term;
×
4849
                if ( Generator(BHEAD term,level) ) goto DefCall;
×
4850
                AR.DeferFlag = 1;
×
4851
                AT.WorkPointer = oldwork;
×
4852
                AR.GetOneFile = oldGetOneFile;
×
4853
                return(0);
×
4854
        }
4855
        mstop = m + m[1];
6,081,130✔
4856
        decr = WORDDIF(mstop,AR.CompressBuffer)-1;
6,081,130✔
4857
        tstart = AR.CompressPointer + decr;
6,081,130✔
4858

4859
        m = AR.CompressBuffer;
6,081,130✔
4860
        t = AR.CompressPointer;
6,081,130✔
4861
        i = *m;
6,081,130✔
4862
        NCOPY(t,m,i);
170,270,864✔
4863
        oldb = *tstart;
6,081,130✔
4864
        AR.TePos = 0;
6,081,130✔
4865
        AN.TeSuOut = 0;
6,081,130✔
4866
/*
4867
                Status:
4868
                First bracket content starts at mstop.
4869
                Next term starts at startposition.
4870
                Decompression information is in AR.CompressPointer.
4871
                The outside of the bracket runs from AR.CompressBuffer+1 to mstop.
4872
*/
4873
        for(;;) {
6,081,215✔
4874
                *tstart = *(AR.CompressPointer)-decr;
6,081,215✔
4875
                AR.CompressPointer = AR.CompressPointer+AR.CompressPointer[0];
6,081,215✔
4876
                if ( InsertTerm(BHEAD term,0,AM.rbufnum,tstart,termout,0) < 0 ) {
6,081,215✔
4877
                        goto DefCall;
×
4878
                }
4879
                *tstart = oldb;
6,081,215✔
4880
                AT.WorkPointer = termout + *termout;
6,081,215✔
4881
                if ( Generator(BHEAD termout,level) ) goto DefCall;
6,081,215✔
4882
                AR.CompressPointer = oldipointer;
6,081,215✔
4883
                AT.WorkPointer = termout;
6,081,215✔
4884
                retval = GetOneTerm(BHEAD AT.WorkPointer,AR.infile,&startposition,0);
6,081,215✔
4885
                if ( retval >= 0 ) AR.CompressPointer = oldipointer;
6,081,215✔
4886
                if ( retval <= 0 ) break;
6,081,215✔
4887
                t = AR.CompressPointer;
139✔
4888
                if ( *t < (1 + decr + ABS(*(t+*t-1))) ) break;
139✔
4889
                t++;
139✔
4890
                m = AR.CompressBuffer+1;
139✔
4891
                while ( m < mstop ) {
865✔
4892
                        if ( *m != *t ) goto Thatsit;
762✔
4893
                        m++; t++;
726✔
4894
                }
4895
        }
4896
Thatsit:;
6,081,091✔
4897
/*
4898
                Finished. Reposition the file, restore information and return.
4899
*/
4900
        if ( AR.infile->handle < 0 ) AR.infile->POfill = oldPOfill;
6,081,130✔
4901
        AR.DeferFlag = 1;
6,081,130✔
4902
        AR.GetOneFile = oldGetOneFile;
6,081,130✔
4903
        AT.WorkPointer = oldwork;
6,081,130✔
4904
        return(0);
6,081,130✔
4905
DefCall:;
×
4906
        MLOCK(ErrorMessageLock);
×
4907
        MesCall("Deferred");
×
4908
        MUNLOCK(ErrorMessageLock);
×
4909
        SETERROR(-1)
×
4910
}
4911

4912
/*
4913
                 #] Deferred : 
4914
                 #[ PrepPoly :                        WORD PrepPoly(term,par)
4915
*/
4916
/**
4917
 *                Routine checks whether the count of function AR.PolyFun is zero
4918
 *                or one. If it is one and it has one scalarlike argument the
4919
 *                coefficient of the term is pulled inside the argument.
4920
 *                If the count is zero a new function is made with the coefficient
4921
 *                as its only argument. The function should be placed at its
4922
 *                proper position.
4923
 *
4924
 *                When this function is active it places the PolyFun as last
4925
 *                object before the coefficient. This is needed because otherwise
4926
 *                the compress algorithm has problems in MergePatches.
4927
 *
4928
 *                The bracket routine should also place the PolyFun at a
4929
 *                comparable spot.
4930
 *                The compression should then stop at the PolyFun. It doesn't
4931
 *                really have to stop when writing the final result but this may
4932
 *                be too complicated.
4933
 *
4934
 *                The parameter par tells whether we are at groundlevel or
4935
 *                inside a function or dollar variable.
4936
 */
4937

4938
WORD PrepPoly(PHEAD WORD *term,WORD par)
575,535✔
4939
{
4940
        GETBIDENTITY
4941
        WORD count = 0, i, jcoef, ncoef;
575,535✔
4942
        WORD *t, *m, *r, *tstop, *poly = 0, *v, *w, *vv, *ww;
575,535✔
4943
        WORD *oldworkpointer = AT.WorkPointer;
575,535✔
4944
/*
4945
        The problem here is that the function will be forced into 'long'
4946
        notation. After this -SNUMBER,1 becomes 6,0,4,1,1,3 and the
4947
        pattern matcher cannot match a short 1 with a long 1.
4948
        But because this is an undocumented feature for very special
4949
        purposes, we don't do anything about it. (30-aug-2011)
4950
*/
4951
        if ( AR.PolyFunType == 2 && AR.PolyFunExp != 2 ) {
575,535✔
4952
                WORD oldtype = AR.SortType;
569,243✔
4953
                AR.SortType = SORTHIGHFIRST;
569,243✔
4954
                if ( poly_ratfun_normalize(BHEAD term) != 0 ) TERMINATE(-1);
569,243✔
4955
/*                if ( ReadPolyRatFun(BHEAD term) != 0 ) TERMINATE(-1); */
4956
                oldworkpointer = AT.WorkPointer;
569,240✔
4957
                AR.SortType = oldtype;
569,240✔
4958
        }
4959
        AT.PolyAct = 0;
575,532✔
4960
        t = term;
575,532✔
4961
        GETSTOP(t,tstop);
575,532✔
4962
        t++;
575,532✔
4963
        while ( t < tstop ) {
974,759✔
4964
                if ( *t == AR.PolyFun ) {
399,227✔
4965
                        if ( count > 0 ) return(0);
45,808✔
4966
                        poly = t;
45,808✔
4967
                        count++;
45,808✔
4968
                }
4969
                t += t[1];
399,227✔
4970
        }
4971
        r = m = term + *term;
575,532✔
4972
        i = ABS(m[-1]);
575,532✔
4973
        if ( par > 0 ) {
575,532✔
4974
                if ( count == 0 ) return(0);
527,916✔
4975
                else if ( AR.PolyFunType == 1 || (AR.PolyFunType == 2 && AR.PolyFunExp == 2) )
152✔
4976
                        goto DoOne;
×
4977
                else if ( AR.PolyFunType == 2 )
152✔
4978
                        goto DoTwo;
152✔
4979
                else
4980
                        goto DoError;
×
4981
        }
4982
        else if ( count == 0 ) {
47,616✔
4983
/*
4984
                 #[ Create a PolyFun :
4985
*/
4986
                poly = t = tstop;
1,960✔
4987
                if ( i == 3 && m[-2] == 1 && (m[-3]&MAXPOSITIVE) == m[-3] ) {
1,960✔
4988
                        *m++ = AR.PolyFun;
1,940✔
4989
                        if ( AR.PolyFunType == 1 || (AR.PolyFunType == 2 && AR.PolyFunExp == 2) ) {
1,940✔
4990
                                *m++ = FUNHEAD+2;
12✔
4991
                                FILLFUN(m)
12✔
4992
                                *m++ = -SNUMBER;
12✔
4993
                                *m = m[-2-FUNHEAD] < 0 ? -m[-4-FUNHEAD]: m[-4-FUNHEAD];
12✔
4994
                                m++;
12✔
4995
                        }
4996
                        else if ( AR.PolyFunType == 2 ) {
1,928✔
4997
                                *m++ = FUNHEAD+4;
1,928✔
4998
                                FILLFUN(m)
1,928✔
4999
                                *m++ = -SNUMBER;
1,928✔
5000
                                *m = m[-2-FUNHEAD] < 0 ? -m[-4-FUNHEAD]: m[-4-FUNHEAD];
1,928✔
5001
                                m++;
1,928✔
5002
                                *m++ = -SNUMBER;
1,928✔
5003
                                *m++ = 1;
1,928✔
5004
                        }
5005
                }
5006
                else {
5007
                        WORD *vm;
20✔
5008
                        r = tstop;
20✔
5009
                        if ( AR.PolyFunType == 1 || (AR.PolyFunType == 2 && AR.PolyFunExp == 2) ) {
20✔
5010
                                *m++ = AR.PolyFun;
8✔
5011
                                *m++ = FUNHEAD+ARGHEAD+i+1;
8✔
5012
                                FILLFUN(m)
8✔
5013
                                *m++ = ARGHEAD+i+1;
8✔
5014
                                *m++ = 0;
8✔
5015
                                FILLARG(m)
5016
                                *m++ = i+1;
8✔
5017
                                NCOPY(m,r,i);
72✔
5018
                        }
5019
                        else if ( AR.PolyFunType == 2 ) {
12✔
5020
                                WORD *num, *den, size, sign, sizenum, sizeden;
12✔
5021
                                if ( m[-1] < 0 ) { sign = -1; size = -m[-1]; }
12✔
5022
                                else             { sign =  1; size =  m[-1]; }
5023
                                num = m - size; size = (size-1)/2; den = num + size;
12✔
5024
                                sizenum = size; while ( num[sizenum-1] == 0 ) sizenum--;
12✔
5025
                                sizeden = size; while ( den[sizeden-1] == 0 ) sizeden--;
12✔
5026
                                v = m;
12✔
5027
                                AT.PolyAct = WORDDIF(v,term);
12✔
5028
                                *v++ = AR.PolyFun;
12✔
5029
                                v++;
12✔
5030
                                FILLFUN(v);
12✔
5031
                                vm = v;
12✔
5032
                                *v++ = ARGHEAD+2*sizenum+2;
12✔
5033
                                *v++ = 0;
12✔
5034
                                FILLARG(v);
12✔
5035
                                *v++ = 2*sizenum+2;
12✔
5036
                                for ( i = 0; i < sizenum; i++ ) *v++ = num[i];
24✔
5037
                                *v++ = 1;
12✔
5038
                                for ( i = 1; i < sizenum; i++ ) *v++ = 0;
12✔
5039
                                *v++ = sign*(2*sizenum+1);
12✔
5040
                                if ( ToFast(vm,vm) ) v = vm+2;
12✔
5041
                                vm = v;
12✔
5042
                                *v++ = ARGHEAD+2*sizeden+2;
12✔
5043
                                *v++ = 0;
12✔
5044
                                FILLARG(v);
12✔
5045
                                *v++ = 2*sizeden+2;
12✔
5046
                                for ( i = 0; i < sizeden; i++ ) *v++ = den[i];
24✔
5047
                                *v++ = 1;
12✔
5048
                                for ( i = 1; i < sizeden; i++ ) *v++ = 0;
12✔
5049
                                *v++ = 2*sizeden+1;
12✔
5050
                                if ( ToFast(vm,vm) ) v = vm+2;
12✔
5051
                                i = v-m;
12✔
5052
                                m[1] = i;
12✔
5053
                                w = num;
12✔
5054
                                NCOPY(w,m,i);
96✔
5055
                                *w++ = 1; *w++ = 1; *w++ = 3; *term = w - term;
12✔
5056
                                return(0);
12✔
5057
                        }
5058
                }
5059
/*
5060
                 #] Create a PolyFun : 
5061
*/
5062
        }
5063
        else if ( AR.PolyFunType == 1 || (AR.PolyFunType == 2 && AR.PolyFunExp == 2) ) {
45,656✔
5064
                DoOne:;
116✔
5065
/*
5066
                 #[ One argument :
5067
*/
5068
                m = term + *term;
116✔
5069
                r = poly + poly[1];
116✔
5070
                if ( ( poly[1] == FUNHEAD+2 && poly[FUNHEAD+1] == 0
116✔
5071
                && poly[FUNHEAD] == -SNUMBER ) || poly[1] == FUNHEAD ) return(1);
116✔
5072
                t = poly + FUNHEAD;
116✔
5073
                if ( t >= r ) return(0);
116✔
5074
                if ( m[-1] == 3 && *tstop == 1 && tstop[1] == 1 ) {
116✔
5075
                        i = poly[1];
5076
                        t = poly;
5077
                        NCOPY(m,t,i);
1,528✔
5078
                }
5079
                else if ( *t <= -FUNCTION ) {
64✔
5080
                        if ( t+1 < r ) return(0);        /* More than one argument */
×
5081
                        r = tstop;
×
5082
                        *m++ = AR.PolyFun;
×
5083
                        *m++ = FUNHEAD*2+ARGHEAD+i+1;
×
5084
                        FILLFUN(m)
×
5085
                        *m++ = FUNHEAD+ARGHEAD+i+1;
×
5086
                        *m++ = 0;
×
5087
                        FILLARG(m)
5088
                        *m++ = FUNHEAD+i+1;
×
5089
                        *m++ = -*t++;
×
5090
                        *m++ = FUNHEAD;
×
5091
                        FILLFUN(m)
×
5092
                        NCOPY(m,r,i);
×
5093
                }
5094
                else if ( *t < 0 ) {
64✔
5095
                        if ( t+2 < r ) return(0);        /* More than one argument */
12✔
5096
                        r = tstop;
12✔
5097
                        if ( *t == -SNUMBER ) {
12✔
5098
                                if ( t[1] == 0 ) return(1);        /* Term should be zero now */
8✔
5099
                                *m = AR.PolyFun;
8✔
5100
                                w = m+1;
8✔
5101
                                m += FUNHEAD+ARGHEAD;
8✔
5102
                                v = m;
8✔
5103
                                *m++ = 5+i;
8✔
5104
                                *m++ = SNUMBER;
8✔
5105
                                *m++ = 4;
8✔
5106
                                *m++ = t[1];
8✔
5107
                                *m++ = 1;
8✔
5108
                                NCOPY(m,r,i);
32✔
5109
                                if ( m >= AT.WorkSpace && m < AT.WorkTop )
8✔
5110
                                        AT.WorkPointer = m;
8✔
5111
                                if ( Normalize(BHEAD v) ) TERMINATE(-1);
8✔
5112
                                AT.WorkPointer = oldworkpointer;
8✔
5113
                                m = w;
8✔
5114
                                if ( *v == 4 && v[2] == 1 && (v[1]&MAXPOSITIVE) == v[1] ) {
8✔
5115
                                        *m++ = FUNHEAD+2;
8✔
5116
                                        FILLFUN(m)
8✔
5117
                                        *m++ = -SNUMBER;
8✔
5118
                                        *m++ = v[3] < 0 ? -v[1] : v[1];
8✔
5119
                                }
5120
                                else if ( *v == 0 ) return(1);
×
5121
                                else {
5122
                                        *m++ = FUNHEAD+ARGHEAD+*v;
×
5123
                                        FILLFUN(m)
×
5124
                                        *m++ = ARGHEAD+*v;
×
5125
                                        *m++ = 0;
×
5126
                                        FILLARG(m)
5127
                                        m = v + *v;
×
5128
                                }
5129
                        }
5130
                        else if ( *t == -SYMBOL ) {
4✔
5131
                                *m++ = AR.PolyFun;
4✔
5132
                                *m++ = FUNHEAD+ARGHEAD+5+i;
4✔
5133
                                FILLFUN(m)
4✔
5134
                                *m++ = ARGHEAD+5+i;
4✔
5135
                                *m++ = 0;
4✔
5136
                                FILLARG(m)
5137
                                *m++ = 5+i;
4✔
5138
                                *m++ = SYMBOL;
4✔
5139
                                *m++ = 4;
4✔
5140
                                *m++ = t[1];
4✔
5141
                                *m++ = 1;
4✔
5142
                                NCOPY(m,r,i);
16✔
5143
                        }
5144
                        else return(0);                        /* Not symbol-like */
5145
                }
5146
                else {
5147
                        if ( t + *t < r ) return(0); /* More than one argument */
52✔
5148
                        i = m[-1];
52✔
5149
                        *m++ = AR.PolyFun;
52✔
5150
                        w = m;
52✔
5151
                        m += ARGHEAD+FUNHEAD-1;
52✔
5152
                        t += ARGHEAD;
52✔
5153
                        jcoef = i < 0 ? (i+1)>>1:(i-1)>>1;
52✔
5154
                        v = t;
52✔
5155
/*
5156
                        Test now the scalar nature of the argument.
5157
                        No indices allowed.
5158
*/
5159
                        while ( t < r ) {
200✔
5160
                                WORD *vstop;
148✔
5161
                                vv = t + *t;
148✔
5162
                                vstop = vv - ABS(vv[-1]);
148✔
5163
                                t++;
148✔
5164
                                while( t < vstop ) {
260✔
5165
                                        if ( *t == INDEX ) return(0);
112✔
5166
                                        t += t[1];
112✔
5167
                                }
5168
                                t = vv;
5169
                        }
5170
/*
5171
                        Now multiply each term by the coefficient.
5172
*/
5173
                        t = v;
5174
                        while ( t < r ) {
200✔
5175
                                ww = m;
148✔
5176
                                v = t + *t;
148✔
5177
                                ncoef = v[-1];
148✔
5178
                                vv = v - ABS(ncoef);
148✔
5179
                if ( ncoef < 0 ) ncoef++;
148✔
5180
                                else ncoef--;
120✔
5181
                                ncoef >>= 1;
148✔
5182
                                while ( t < vv ) *m++ = *t++;
744✔
5183
                                if ( MulRat(BHEAD (UWORD *)vv,ncoef,(UWORD *)tstop,jcoef,
148✔
NEW
5184
                                        (UWORD *)m,&ncoef) ) TERMINATE(-1);
×
5185
                                ncoef *= 2;
148✔
5186
                                m += ABS(ncoef);
148✔
5187
                                if ( ncoef < 0 ) ncoef--;
148✔
5188
                                else ncoef++;
120✔
5189
                                *m++ = ncoef;
148✔
5190
                                *ww = WORDDIF(m,ww);
148✔
5191
                                if ( AN.ncmod != 0 ) {
148✔
NEW
5192
                                        if ( Modulus(ww) ) TERMINATE(-1);
×
5193
                                        if ( *ww == 0 ) return(1);
×
5194
                                        m = ww + *ww;
×
5195
                                }
5196
                                t = v;
5197
                        }
5198
                        *w = (WORDDIF(m,w))+1;
52✔
5199
                        w[FUNHEAD-1] = w[0] - FUNHEAD;
52✔
5200
                        w[FUNHEAD] = 0;
52✔
5201
                        w[1] = 0; /* omission survived for years. 23-mar-2006 JV */
52✔
5202
                        w += FUNHEAD-1;
52✔
5203
                        if ( ToFast(w,w) ) {
52✔
5204
                                if ( *w <= -FUNCTION ) { w[-FUNHEAD+1] = FUNHEAD+1; m = w+1; }
×
5205
                                else { w[-FUNHEAD+1] = FUNHEAD+2; m = w+2; }
×
5206
                                
5207
                        }
5208
                }
5209
                t = poly + poly[1];
116✔
5210
                while ( t < tstop ) *poly++ = *t++;
148✔
5211
/*
5212
                 #] One argument : 
5213
*/
5214
        }
5215
        else if ( AR.PolyFunType == 2 ) {
45,540✔
5216
                DoTwo:;
45,540✔
5217
/*
5218
                 #[ Two arguments :
5219
*/
5220
                WORD *num, *den, size, sign, sizenum, sizeden;
45,692✔
5221
/*
5222
                First make sure that the PolyFun is last
5223
*/
5224
                m = term + *term;
45,692✔
5225
                if ( poly + poly[1] < tstop ) {
45,692✔
5226
                        for ( i = 0; i < poly[1]; i++ ) m[i] = poly[i];
479,568✔
5227
                        t = poly; v = poly + poly[1];
8,708✔
5228
                        while ( v < tstop ) *t++ = *v++;
135,988✔
5229
                        poly = t;
479,568✔
5230
                        for ( i = 0; i < m[1]; i++ ) t[i] = m[i];
479,568✔
5231
                        t += m[1];
45,692✔
5232
                }
5233
                AT.PolyAct = WORDDIF(poly,term);
45,692✔
5234
/*
5235
                If needed we convert the coefficient into a PolyRatFun and then
5236
                we call poly_ratfun_normalize
5237
*/
5238
                if ( m[-1] == 3 && m[-2] == 1 && m[-3] == 1 ) return(0);
45,692✔
5239
                if ( AR.PolyFunExp != 1 ) {
×
5240
                if ( m[-1] < 0 ) { sign = -1; size = -m[-1]; } else { sign = 1; size = m[-1]; }
×
5241
                num = m - size; size = (size-1)/2; den = num + size;
×
5242
                sizenum = size; while ( num[sizenum-1] == 0 ) sizenum--;
×
5243
                sizeden = size; while ( den[sizeden-1] == 0 ) sizeden--;
×
5244
                v = m;
×
5245
                *v++ = AR.PolyFun;
×
5246
                *v++ = FUNHEAD + 2*(ARGHEAD+sizenum+sizeden+2);
×
5247
/*                *v++ = MUSTCLEANPRF; */
5248
                *v++ = 0;
×
5249
                FILLFUN3(v);
×
5250
                *v++ = ARGHEAD+2*sizenum+2;
×
5251
                *v++ = 0;
×
5252
                FILLARG(v);
×
5253
                *v++ = 2*sizenum+2;
×
5254
                for ( i = 0; i < sizenum; i++ ) *v++ = num[i];
×
5255
                *v++ = 1;
×
5256
                for ( i = 1; i < sizenum; i++ ) *v++ = 0;
×
5257
                *v++ = sign*(2*sizenum+1);
×
5258
                *v++ = ARGHEAD+2*sizeden+2;
×
5259
                *v++ = 0;
×
5260
                FILLARG(v);
×
5261
                *v++ = 2*sizeden+2;
×
5262
                for ( i = 0; i < sizeden; i++ ) *v++ = den[i];
×
5263
                *v++ = 1;
×
5264
                for ( i = 1; i < sizeden; i++ ) *v++ = 0;
×
5265
                *v++ = 2*sizeden+1;
×
5266
                w = num;
×
5267
                i = v - m;
×
5268
                NCOPY(w,m,i);
×
5269
                }
5270
                else {
5271
                        w = m-ABS(m[-1]);
×
5272
                }
5273
                *w++ = 1; *w++ = 1; *w++ = 3; *term = w - term;
×
5274
                {
5275
                        WORD oldtype = AR.SortType;
×
5276
                        AR.SortType = SORTHIGHFIRST;
×
5277
/*
5278
                        if ( count > 0 )
5279
                                poly_ratfun_normalize(BHEAD term);
5280
                        else
5281
                                ReadPolyRatFun(BHEAD term);
5282
*/
5283
                        poly_ratfun_normalize(BHEAD term);
×
5284

5285
/*                        oldworkpointer = AT.WorkPointer; */
5286
                        AR.SortType = oldtype;
×
5287
                }
5288
                goto endofit;
×
5289
/*
5290
                 #] Two arguments : 
5291
*/
5292
        }
5293
        else {
5294
                DoError:;
×
5295
                MLOCK(ErrorMessageLock);
×
5296
                MesPrint("Illegal value for PolyFunType in PrepPoly");
×
5297
                MUNLOCK(ErrorMessageLock);
×
NEW
5298
                TERMINATE(-1);
×
5299
        }
5300
        r = term + *term;
2,064✔
5301
        AT.PolyAct = WORDDIF(poly,term);
2,064✔
5302
        while ( r < m ) *poly++ = *r++;
18,600✔
5303
        *poly++ = 1;
2,064✔
5304
        *poly++ = 1;
2,064✔
5305
        *poly++ = 3;
2,064✔
5306
        *term = WORDDIF(poly,term);
2,064✔
5307
endofit:;
5308
        return(0);
5309
}
5310

5311
/*
5312
                 #] PrepPoly : 
5313
                 #[ PolyFunMul :                        WORD PolyFunMul(term)
5314
*/
5315
/**
5316
 *                Multiplies the arguments of multiple occurrences of the polyfun.
5317
 *                In this routine we do the original PolyFun with one argument only.
5318
 *                The PolyRatFun (PolyFunType = 2) is done in a dedicated routine
5319
 *                in the file polywrap.cc
5320
 *                The new result is written over the old result.
5321
 *
5322
 *                @param term It contains the input term and later the output.
5323
 *                @return Normal conventions (OK = 0).
5324
 */
5325

5326
WORD PolyFunMul(PHEAD WORD *term)
34,788✔
5327
{
5328
        GETBIDENTITY
5329
        WORD *t, *fun1, *fun2, *t1, *t2, *m, *w, *ww, *tt1, *tt2, *tt4, *arg1, *arg2;
34,788✔
5330
        WORD *tstop, i, dirty = 0, OldPolyFunPow = AR.PolyFunPow, minp1, minp2;
34,788✔
5331
        WORD n1, n2, i1, i2, l1, l2, l3, l4, action = 0, noac = 0, retval = 0;
34,788✔
5332
        if ( AR.PolyFunType == 2 && AR.PolyFunExp == 1 ) {
34,788✔
5333
                WORD pow = 0, pow1;
×
5334
                t = term + 1; t1 = term + *term; t1 -= ABS(t1[-1]);
×
5335
                w = t;
×
5336
                while ( t < t1 ) {
×
5337
                        if ( *t != AR.PolyFun ) {
×
5338
SkipFun:
×
5339
                                if ( t == w ) { t += t[1]; w = t; }
×
5340
                                else { i = t[1]; NCOPY(w,t,i) }
×
5341
                                continue;
×
5342
                        }
5343
                        pow1 = 0;
×
5344
                        t2 = t + t[1]; t += FUNHEAD;
×
5345
                        if ( *t < 0 ) {
×
5346
                                if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) pow1++;
×
5347
                                else if ( *t != -SNUMBER ) goto NoLegal;
×
5348
                                t += 2;
×
5349
                        }
5350
                        else if ( t[0] == ARGHEAD+8 && t[ARGHEAD] == 8
×
5351
                         && t[ARGHEAD+1] == SYMBOL && t[ARGHEAD+3] == AR.PolyFunVar
×
5352
                         && t[ARGHEAD+5] == 1 && t[ARGHEAD+6] == 1 && t[ARGHEAD+7] == 3 ) {
×
5353
                                pow1 += t[ARGHEAD+4];
×
5354
                                t += *t;
×
5355
                        }
5356
                        else {
5357
NoLegal:
×
5358
                                MLOCK(ErrorMessageLock);
×
5359
                                MesPrint("Illegal term with divergence in PolyRatFun");
×
5360
                                MesCall("PolyFunMul");
×
5361
                                MUNLOCK(ErrorMessageLock);
×
NEW
5362
                                TERMINATE(-1);
×
5363
                        }
5364
                        if ( *t < 0 ) {
×
5365
                                if ( *t == -SYMBOL && t[1] == AR.PolyFunVar ) pow1--;
×
5366
                                else if ( *t != -SNUMBER ) goto NoLegal;
×
5367
                                t += 2;
×
5368
                        }
5369
                        else if ( t[0] == ARGHEAD+8 && t[ARGHEAD] == 8
×
5370
                         && t[ARGHEAD+1] == SYMBOL && t[ARGHEAD+3] == AR.PolyFunVar
×
5371
                         && t[ARGHEAD+5] == 1 && t[ARGHEAD+6] == 1 && t[ARGHEAD+7] == 3 ) {
×
5372
                                pow1 -= t[ARGHEAD+4];
×
5373
                                t += *t;
×
5374
                        }
5375
                        else goto NoLegal;
×
5376
                        if ( t == t2 ) pow += pow1;
×
5377
                        else goto SkipFun;
×
5378
                }
5379
                m = w;
×
5380
                *w++ = AR.PolyFun; *w++ = 0; FILLFUN(w);
×
5381
                if ( pow > 1 ) {
×
5382
                        *w++ = 8+ARGHEAD; *w++ = 0; FILLARG(w);
×
5383
                        *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = AR.PolyFunVar; *w++ = pow;
×
5384
                        *w++ = 1; *w++ = 1; *w++ = 3; *w++ = -SNUMBER; *w++ = 1;
×
5385
                }
5386
                else if ( pow == 1 ) {
×
5387
                        *w++ = -SYMBOL; *w++ = AR.PolyFunVar; *w++ = -SNUMBER; *w++ = 1;
×
5388
                }
5389
                else if ( pow < -1 ) {
×
5390
                        *w++ = -SNUMBER; *w++ = 1; *w++ = 8+ARGHEAD; *w++ = 0; FILLARG(w);
×
5391
                        *w++ = 8; *w++ = SYMBOL; *w++ = 4; *w++ = AR.PolyFunVar; *w++ = -pow;
×
5392
                        *w++ = 1; *w++ = 1; *w++ = 3;
×
5393
                }
5394
                else if ( pow == -1 ) {
×
5395
                        *w++ = -SNUMBER; *w++ = 1; *w++ = -SYMBOL; *w++ = AR.PolyFunVar;
×
5396
                }
5397
                else {
5398
                        *w++ = -SNUMBER; *w++ = 1; *w++ = -SNUMBER; *w++ = 1;
×
5399
                }
5400
                m[1] = w - m;
×
5401
                *w++ = 1; *w++ = 1; *w++ = 3;
×
5402
                *term = w - term;
×
5403
                if ( w > AT.WorkSpace && w < AT.WorkTop ) AT.WorkPointer = w;
×
5404
                return(0);
×
5405
        }
5406
ReStart:
34,788✔
5407
        if ( AR.PolyFunType == 2 && ( ( AR.PolyFunExp != 2 )
65,632✔
5408
         || ( AR.PolyFunExp == 2 && AN.PolyNormFlag > 1 ) ) ) {
88✔
5409
                WORD count1 = 0, count2 = 0, count3;
65,544✔
5410
                WORD oldtype = AR.SortType;
65,544✔
5411
                t = term + 1; t1 = term + *term; t1 -= ABS(t1[-1]);
65,544✔
5412
                while ( t < t1 ) {
157,416✔
5413
                        if ( *t == AR.PolyFun ) {
122,716✔
5414
                          if ( t[2] && dirty == 0 ) { /* Any dirty flag on? */
72,136✔
5415
                                dirty = 1;
30,844✔
5416
/*                                ReadPolyRatFun(BHEAD term); */
5417
/*                                ToPolyFunGeneral(BHEAD term); */
5418
                                poly_ratfun_normalize(BHEAD term);
30,844✔
5419
                                if ( term[0] == 0 ) return(0);
30,844✔
5420
                                count1 = 0;
30,844✔
5421
                                action++;
30,844✔
5422
                                goto ReStart;
30,844✔
5423
                          }
5424
                          t2 = t + t[1]; tt2 = t+FUNHEAD; count3 = 0;
41,292✔
5425
                          while ( tt2 < t2 ) { count3++; NEXTARG(tt2); }
123,864✔
5426
                          if ( count3 == 2 ) {
41,292✔
5427
                                count1++;
41,280✔
5428
                                if ( ( t[2] & MUSTCLEANPRF ) != 0 ) {        /* Better civilize this guy */
41,280✔
5429
                                        action++;
×
5430
                                        w = AT.WorkPointer;
×
5431
                                        AR.SortType = SORTHIGHFIRST;
×
5432
                                        t2 = t + t[1]; tt2 = t+FUNHEAD;
×
5433
                                        while ( tt2 < t2 ) {
×
5434
                                                if ( *tt2 > 0 ) {
×
5435
                                                        tt4 = tt2; tt1 = tt2 + ARGHEAD; tt2 += *tt2;
×
5436
                                                        NewSort(BHEAD0);
×
5437
                                                        while ( tt1 < tt2 ) {
×
5438
                                                                i = *tt1; ww = w; NCOPY(ww,tt1,i);
×
5439
                                                                AT.WorkPointer = ww;
×
5440
                                                                Normalize(BHEAD w);
×
5441
                                                                StoreTerm(BHEAD w);
×
5442
                                                        }
5443
                                                        EndSort(BHEAD w,1);
×
5444
                                                        ww = w; while ( *ww ) ww += *ww;
×
5445
                                                        if ( ww-w != *tt4-ARGHEAD ) { /* Little problem */
×
5446
/*
5447
                                                                Solution: brute force copy
5448
                                                                Maybe it will never come here????
5449
*/
5450
                                                                WORD *r1 = TermMalloc("PolyFunMul");
×
5451
                                                                WORD ii = (ww-w)-(*tt4-ARGHEAD); /* increment */
×
5452
                                                                WORD *r2 = tt4+ARGHEAD, *r3, *r4 = r1;
×
5453
                                                                i = r2 - term; r3 = term; NCOPY(r4,r3,i);
×
5454
                                                                i = ww-w; ww = w; NCOPY(r4,ww,i);
×
5455
                                                                r3 = tt2; i = term+*term-tt2; NCOPY(r4,r3,i);
×
5456
                                                                *r1 = i = r4-r1; r4 = term; r3 = r1;
×
5457
                                                                NCOPY(r4,r3,i);
×
5458
                                                                t[1] += ii; t1 += ii; *tt4 += ii;
×
5459
                                                                tt2 = tt4 + *tt4;
×
5460
                                                                TermFree(r1,"PolyFunMul");
×
5461
                                                        }
5462
                                                        else {
5463
                                                                i = ww-w; ww = w; tt1 = tt4+ARGHEAD;
×
5464
                                                                NCOPY(tt1,ww,i);
×
5465
                                                                AT.WorkPointer = w;
×
5466
                                                        }
5467
                                                }
5468
                                                else if ( *tt2 <= -FUNCTION ) tt2++;
×
5469
                                                else tt2 += 2;
×
5470
                                        }
5471
                                        AR.SortType = oldtype;
×
5472
                                }
5473
                          }
5474
                        }
5475
                        t += t[1];
91,872✔
5476
                }
5477
                if ( count1 <= 1 ) { goto checkaction; }
34,700✔
5478
                if ( AR.PolyFunExp == 1 ) {
3,856✔
5479
                        t = term + *term; t -= ABS(t[-1]);
×
5480
                        *t++ = 1; *t++ = 1; *t++ = 3; *term = t - term;
×
5481
                }
5482
                {
5483
                        AR.SortType = SORTHIGHFIRST;
3,856✔
5484
/*                        retval = ReadPolyRatFun(BHEAD term); */
5485
/*                        ToPolyFunGeneral(BHEAD term); */
5486
                        retval = poly_ratfun_normalize(BHEAD term);
3,856✔
5487
                        if ( *term == 0 ) return(retval);
3,856✔
5488
                        AR.SortType = oldtype;
3,856✔
5489
                }
5490

5491
                t = term + 1; t1 = term + *term; t1 -= ABS(t1[-1]);
3,856✔
5492
                while ( t < t1 ) {
11,972✔
5493
                        if ( *t == AR.PolyFun ) {
8,116✔
5494
                          t2 = t + t[1]; tt2 = t+FUNHEAD; count3 = 0;
3,856✔
5495
                          while ( tt2 < t2 ) { count3++; NEXTARG(tt2); }
11,568✔
5496
                          if ( count3 == 2 ) {
3,856✔
5497
                                count2++;
3,856✔
5498
                          }
5499
                        }
5500
                        t += t[1];
8,116✔
5501
                }
5502
                if ( count1 >= count2 ) {
3,856✔
5503
                        t = term + 1;
5504
                        while ( t < t1 ) {
11,972✔
5505
                                if ( *t == AR.PolyFun ) {
8,116✔
5506
                                        t2 = t;
3,856✔
5507
                                        t = t + t[1];
3,856✔
5508
                                        t2[2] |= (DIRTYFLAG|MUSTCLEANPRF);
3,856✔
5509
                                        t2 += FUNHEAD;
3,856✔
5510
                                        while ( t2 < t ) {
3,856✔
5511
                                                if ( *t2 > 0 ) t2[1] = DIRTYFLAG;
7,712✔
5512
                                                NEXTARG(t2);
19,280✔
5513
                                        }
5514
                                }
5515
                                else t += t[1];
4,260✔
5516
                        }
5517
                }
5518

5519
                w = term + *term;
3,856✔
5520
                if ( w > AT.WorkSpace && w < AT.WorkTop ) AT.WorkPointer = w;
3,856✔
5521
checkaction:
×
5522
                if ( action ) retval = action;
34,700✔
5523
                return(retval);
34,700✔
5524
        }
5525
retry:
88✔
5526
        if ( term >= AT.WorkSpace && term+*term < AT.WorkTop )
100✔
5527
                AT.WorkPointer = term + *term;
100✔
5528
        GETSTOP(term,tstop);
100✔
5529
        t = term+1;
100✔
5530
        while ( *t != AR.PolyFun && t < tstop ) t += t[1];
100✔
5531
        while ( t < tstop && *t == AR.PolyFun ) {
100✔
5532
                if ( t[1] > FUNHEAD ) {
100✔
5533
                        if ( t[FUNHEAD] < 0 ) {
100✔
5534
                                if ( t[FUNHEAD] <= -FUNCTION && t[1] == FUNHEAD+1 ) break;
8✔
5535
                                if ( t[FUNHEAD]  > -FUNCTION && t[1] == FUNHEAD+2 ) {
8✔
5536
                                        if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 ) {
8✔
5537
                                                *term = 0;
×
5538
                                                return(0);
×
5539
                                        }
5540
                                        break;
5541
                                }
5542
                        }
5543
                        else if ( t[FUNHEAD] == t[1] - FUNHEAD ) break;
92✔
5544
                }
5545
                noac = 1;
×
5546
                t += t[1];
×
5547
        }
5548
        if ( *t != AR.PolyFun || t >= tstop ) goto done;
100✔
5549
        fun1 = t;
100✔
5550
        t += t[1];
100✔
5551
        while ( t < tstop && *t == AR.PolyFun ) {
100✔
5552
                if ( t[1] > FUNHEAD ) {
12✔
5553
                        if ( t[FUNHEAD] < 0 ) {
12✔
5554
                                if ( t[FUNHEAD] <= -FUNCTION && t[1] == FUNHEAD+1 ) break;
×
5555
                                if ( t[FUNHEAD]  > -FUNCTION && t[1] == FUNHEAD+2 ) {
×
5556
                                        if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 ) {
×
5557
                                                *term = 0;
×
5558
                                                return(0);
×
5559
                                        }
5560
                                        break;
5561
                                }
5562
                        }
5563
                        else if ( t[FUNHEAD] == t[1] - FUNHEAD ) break;
12✔
5564
                }
5565
                noac = 1;
×
5566
                t += t[1];
×
5567
        }
5568
        if ( *t != AR.PolyFun || t >= tstop ) goto done;
100✔
5569
        fun2 = t;
12✔
5570
/*
5571
        We have two functions of the proper type.
5572
        Count terms (needed for the specials)
5573
*/
5574
        t = fun1 + FUNHEAD;
12✔
5575
        if ( *t < 0 ) {
12✔
5576
                n1 = 1; arg1 = AT.WorkPointer;
×
5577
                ToGeneral(t,arg1,1);
×
5578
                AT.WorkPointer = arg1 + *arg1;
×
5579
        }
5580
        else {
5581
                t += ARGHEAD;
12✔
5582
                n1 = 0; t1 = fun1 + fun1[1]; arg1 = t;
12✔
5583
                while ( t < t1 ) { n1++; t += *t; }
40✔
5584
        }
5585
        t = fun2 + FUNHEAD;
12✔
5586
        if ( *t < 0 ) {
12✔
5587
                n2 = 1; arg2 = AT.WorkPointer;
×
5588
                ToGeneral(t,arg2,1);
×
5589
                AT.WorkPointer = arg2 + *arg2;
×
5590
        }
5591
        else {
5592
                t += ARGHEAD;
12✔
5593
                n2 = 0; t2 = fun2 + fun2[1]; arg2 = t;
12✔
5594
                while ( t < t2 ) { n2++; t += *t; }
36✔
5595
        }
5596
/*
5597
        Now we can start the multiplications. We first multiply the terms
5598
        without coefficients, then normalize, and finally put the coefficients
5599
        in place. This is because one has often truncated series and the
5600
        high powers may get killed, while their coefficients are the most
5601
        expensive ones.
5602
        Note: We may run into fun(-SNUMBER,value)
5603
*/
5604
        w = AT.WorkPointer;
12✔
5605
        NewSort(BHEAD0);
12✔
5606
        if ( AR.PolyFunType == 2 && AR.PolyFunExp == 2 ) {
12✔
5607
                AT.TrimPower = 1;
12✔
5608
/*
5609
                We have to find the lowest power in both polynomials.
5610
                This will be needed to temporarily correct the AR.PolyFunPow
5611
*/
5612
                minp1 = MAXPOWER;
12✔
5613
                for ( t1 = arg1, i1 = 0; i1 < n1; i1++, t1 += *t1 ) {
40✔
5614
                        if ( *t1 == 4 ) {
28✔
5615
                                if ( minp1 > 0 ) minp1 = 0;
12✔
5616
                        }
5617
                        else if ( ABS(t1[*t1-1]) == (*t1-1) ) {
16✔
5618
                                if ( minp1 > 0 ) minp1 = 0;
×
5619
                        }
5620
                        else {
5621
                                if ( t1[1] == SYMBOL && t1[2] == 4 && t1[3] == AR.PolyFunVar ) {
16✔
5622
                                        if ( t1[4] < minp1 ) minp1 = t1[4];
16✔
5623
                                }
5624
                                else {
5625
                                        MesPrint("Illegal term in expanded polyratfun.");
×
5626
                                        goto PolyCall;
×
5627
                                }
5628
                        }
5629
                }
5630
                minp2 = MAXPOWER;
5631
                for ( t2 = arg2, i2 = 0; i2 < n2; i2++, t2 += *t2 ) {
36✔
5632
                        if ( *t2 == 4 ) {
24✔
5633
                                if ( minp2 > 0 ) minp2 = 0;
12✔
5634
                        }
5635
                        else if ( ABS(t2[*t2-1]) == (*t2-1) ) {
12✔
5636
                                if ( minp2 > 0 ) minp2 = 0;
×
5637
                        }
5638
                        else {
5639
                                if ( t2[1] == SYMBOL && t2[2] == 4 && t2[3] == AR.PolyFunVar ) {
12✔
5640
                                        if ( t2[4] < minp2 ) minp2 = t2[4];
12✔
5641
                                }
5642
                                else {
5643
                                        MesPrint("Illegal term in expanded polyratfun.");
×
5644
                                        goto PolyCall;
×
5645
                                }
5646
                        }
5647
                }
5648
                AR.PolyFunPow += minp1+minp2;
12✔
5649
        }
5650
        for ( t1 = arg1, i1 = 0; i1 < n1; i1++, t1 += *t1 ) {
40✔
5651
        for ( t2 = arg2, i2 = 0; i2 < n2; i2++, t2 += *t2 ) {
84✔
5652
                m = w;
56✔
5653
                m++;
56✔
5654
                GETSTOP(t1,tt1);
56✔
5655
                t = t1 + 1;
56✔
5656
                while ( t < tt1 ) *m++ = *t++;
184✔
5657
                GETSTOP(t2,tt2);
56✔
5658
                t = t2+1;
56✔
5659
                while ( t < tt2 ) *m++ = *t++;
168✔
5660
                *m++ = 1; *m++ = 1; *m++ = 3; *w = WORDDIF(m,w);
56✔
5661
                AT.WorkPointer = m;
56✔
5662
                if ( Normalize(BHEAD w) ) { LowerSortLevel(); goto PolyCall; }
56✔
5663
                if ( *w ) {
56✔
5664
                        m = w + *w;
52✔
5665
                        if ( m[-1] != 3 || m[-2] != 1 || m[-3] != 1 ) {
52✔
5666
                                l3 = REDLENG(m[-1]);
×
5667
                                m -= ABS(m[-1]);
×
5668
                                t = t1 + *t1 - 1;
×
5669
                                l1 = REDLENG(*t);
×
5670
                                if ( MulRat(BHEAD (UWORD *)m,l3,(UWORD *)tt1,l1,(UWORD *)m,&l4) ) {
×
5671
                                        LowerSortLevel(); goto PolyCall; }
×
5672
                                if ( AN.ncmod != 0 && TakeModulus((UWORD *)m,&l4,AC.cmod,AN.ncmod,UNPACK|AC.modmode) ) {
×
5673
                                        LowerSortLevel(); goto PolyCall; }
×
5674
                                if ( l4 == 0 ) continue;
×
5675
                                t = t2 + *t2 - 1;
×
5676
                                l2 = REDLENG(*t);
×
5677
                                if ( MulRat(BHEAD (UWORD *)m,l4,(UWORD *)tt2,l2,(UWORD *)m,&l3) ) {
×
5678
                                        LowerSortLevel(); goto PolyCall; }
×
5679
                                if ( AN.ncmod != 0 && TakeModulus((UWORD *)m,&l3,AC.cmod,AN.ncmod,UNPACK|AC.modmode) ) {
×
5680
                                        LowerSortLevel(); goto PolyCall; }
×
5681
                        }
5682
                        else {
5683
                                m -= 3;
52✔
5684
                                t = t1 + *t1 - 1;
52✔
5685
                                l1 = REDLENG(*t);
52✔
5686
                                t = t2 + *t2 - 1;
52✔
5687
                                l2 = REDLENG(*t);
52✔
5688
                                if ( MulRat(BHEAD (UWORD *)tt1,l1,(UWORD *)tt2,l2,(UWORD *)m,&l3) ) {
52✔
5689
                                        LowerSortLevel(); goto PolyCall; }
×
5690
                                if ( AN.ncmod != 0 && TakeModulus((UWORD *)m,&l3,AC.cmod,AN.ncmod,UNPACK|AC.modmode) ) {
52✔
5691
                                        LowerSortLevel(); goto PolyCall; }
×
5692
                        }
5693
                        if ( l3 == 0 ) continue;
52✔
5694
                        l3 = INCLENG(l3);
52✔
5695
                        m += ABS(l3);
52✔
5696
                        m[-1] = l3;
52✔
5697
                        *w = WORDDIF(m,w);
52✔
5698
                        AT.WorkPointer = m;
52✔
5699
                        if ( StoreTerm(BHEAD w) ) { LowerSortLevel(); goto PolyCall; }
52✔
5700
                }
5701
        }        
5702
        }        
5703
        if ( EndSort(BHEAD w,0) < 0 ) goto PolyCall;
12✔
5704
        AR.PolyFunPow = OldPolyFunPow;
12✔
5705
        AT.TrimPower = 0;
12✔
5706
        if ( *w == 0 ) {
12✔
5707
                *term = 0;
×
5708
                return(0);
×
5709
        }
5710
        t = w;
5711
        while ( *t ) t += *t;
48✔
5712
        AT.WorkPointer = t;
12✔
5713
        n1 = WORDDIF(t,w);
12✔
5714
        t1 = term;
12✔
5715
        while ( t1 < fun1 ) *t++ = *t1++;
24✔
5716
        t2 = t;
12✔
5717
        *t++ = AR.PolyFun;
12✔
5718
        *t++ = FUNHEAD+ARGHEAD+n1;
12✔
5719
        *t++ = 0;
12✔
5720
        FILLFUN3(t)
5721
        *t++ = ARGHEAD+n1;
12✔
5722
        *t++ = 0;
12✔
5723
        FILLARG(t)
5724
        NCOPY(t,w,n1);
252✔
5725
        if ( ToFast(t2+FUNHEAD,t2+FUNHEAD) ) {
12✔
5726
                if ( t2[FUNHEAD] > -FUNCTION ) t2[1] = FUNHEAD+2;
×
5727
                else t2[FUNHEAD] = FUNHEAD+1;
×
5728
                t = t2 + t2[1];
×
5729
        }
5730
        t1 = fun1 + fun1[1];
12✔
5731
        while ( t1 < fun2 ) *t++ = *t1++;
12✔
5732
        t1 = fun2 + fun2[1];
12✔
5733
        t2 = term + *term;
12✔
5734
        while ( t1 < t2 ) *t++ = *t1++;
116✔
5735
        *AT.WorkPointer = n1 = WORDDIF(t,AT.WorkPointer);
12✔
5736
        if ( n1*((LONG)sizeof(WORD)) > AM.MaxTer ) {
12✔
5737
                MLOCK(ErrorMessageLock);
×
5738
                MesPrint("Term too complex. Maybe increasing MaxTermSize can help");
×
5739
                goto PolyCall2;
×
5740
        }
5741
        m = term; t = AT.WorkPointer;
12✔
5742
        NCOPY(m,t,n1);
428✔
5743
        action++;
12✔
5744
        goto retry;
12✔
5745
done:
88✔
5746
        AT.WorkPointer = term + *term;
88✔
5747
        if ( action && noac ) {
88✔
5748
                if ( Normalize(BHEAD term) ) goto PolyCall;
×
5749
                AT.WorkPointer = term + *term;
×
5750
        }
5751
        return(0);
5752
PolyCall:;
×
5753
        MLOCK(ErrorMessageLock);
×
5754
PolyCall2:;
×
5755
        AR.PolyFunPow = OldPolyFunPow;
×
5756
        MesCall("PolyFunMul");
×
5757
        MUNLOCK(ErrorMessageLock);
×
5758
        SETERROR(-1)
×
5759
}
5760

5761
/*
5762
                 #] PolyFunMul : 
5763
        #] Processor :
5764
*/
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

© 2025 Coveralls, Inc