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

tueda / form / 15241916852

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

push

github

tueda
ci: build arm64-windows binaries

39009 of 81425 relevant lines covered (47.91%)

1079780.1 hits per line

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

64.15
/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)
1,598✔
65
{
66
        GETIDENTITY
1,064✔
67
        WORD *term, *t, i, retval = 0, size;
1,598✔
68
        EXPRESSIONS e;
1,598✔
69
        POSITION position;
1,598✔
70
        WORD last, LastExpression, fromspectator;
1,598✔
71
        LONG dd = 0;
1,598✔
72
        CBUF *C = cbuf+AC.cbufnum;
1,598✔
73
        int firstterm;
1,598✔
74
        CBUF *CC = cbuf+AT.ebufnum;
1,598✔
75
        WORD **w, *cpo, *cbo;
1,598✔
76
        FILEHANDLE *curfile, *oldoutfile = AR.outfile;
1,598✔
77
        WORD oldBracketOn = AR.BracketOn;
1,598✔
78
        WORD *oldBrackBuf = AT.BrackBuf;
1,598✔
79
        WORD oldbracketindexflag = AT.bracketindexflag;
1,598✔
80
#ifdef WITHPTHREADS
81
        int OldMultiThreaded = AS.MultiThreaded, Oldmparallelflag = AC.mparallelflag;
1,064✔
82
#endif
83
        if ( CC->numrhs > 0 || CC->numlhs > 0 ) {
1,598✔
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);
1,598✔
98
        AR.expflags = 0;
1,517✔
99
        AR.CompressPointer = AR.CompressBuffer;
1,517✔
100
        AR.NoCompress = AC.NoCompress;
1,517✔
101
        term = AT.WorkPointer;
1,517✔
102
        if ( ( (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer) ) > AT.WorkTop ) return(MesWork());
1,517✔
103
        UpdatePositions();
1,517✔
104
        C->rhs[C->numrhs+1] = C->Pointer;
1,517✔
105
        AR.KeptInHold = 0;
1,517✔
106
        if ( AC.CollectFun ) AR.DeferFlag = 0;
1,517✔
107
        AR.outtohide = 0;
1,517✔
108
        AN.PolyFunTodo = 0;
1,517✔
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-- ) {
1,616✔
122
                e = Expressions+i;
1,595✔
123
                if ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION
1,595✔
124
                || e->status == HIDELEXPRESSION || e->status == HIDEGEXPRESSION
125
                || e->status == SKIPLEXPRESSION || e->status == SKIPGEXPRESSION
126
                || e->status == UNHIDELEXPRESSION || e->status == UNHIDEGEXPRESSION
127
                || e->status == INTOHIDELEXPRESSION || e->status == INTOHIDEGEXPRESSION
128
                ) break;
129
        }
130
        last = i;
131
        for ( i = NumExpressions-1; i >= 0; i-- ) {
4,930✔
132
                AS.OldOnFile[i] = Expressions[i].onfile;
3,413✔
133
                AS.OldNumFactors[i] = Expressions[i].numfactors;
3,413✔
134
/*                AS.Oldvflags[i] = e[i].vflags; */
135
                AS.Oldvflags[i] = Expressions[i].vflags;
3,413✔
136
                AS.Olduflags[i] = Expressions[i].uflags;
3,413✔
137
                Expressions[i].vflags &= ~(ISUNMODIFIED|ISZERO);
3,413✔
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 ) {
1,010✔
146
                AS.MultiThreaded = 1; AC.mparallelflag = PARALLELFLAG;
2✔
147
        }
148
        if ( AS.MultiThreaded && AC.mparallelflag == PARALLELFLAG ) {
1,010✔
149
                SetWorkerFiles();
986✔
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 ) {
1,010✔
159
                if ( InParallelProcessor() ) {
986✔
160
                        retval = 1;
161
                }
162
                AS.MultiThreaded = OldMultiThreaded;
986✔
163
                AC.mparallelflag = Oldmparallelflag;
986✔
164
        }
165
#endif
166
#ifdef WITHMPI
167
         if ( AC.RhsExprInModuleFlag && PF.rhsInParallel && (AC.mparallelflag == PARALLELFLAG || AC.partodoflag) ) {
168
                if ( PF_BroadcastRHS() ) {
169
                        retval = -1;
170
                }
171
        }
172
        PF.exprtodo = -1; /* This means, the slave does not perform inparallel */
173
        if ( AC.partodoflag > 0 ) {
174
                if ( PF_InParallelProcessor() ) {
175
                        retval = -1;
176
                }
177
        }
178
#endif
179
        for ( i = 0; i < NumExpressions; i++ ) {
4,852✔
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;
3,395✔
188
#ifdef WITHPTHREADS
189
                if ( AC.partodoflag > 0 && e->partodo > 0 && AM.totalnumberofthreads > 2 ) {
2,262✔
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 ) {
196
                        e->partodo = 0;
197
                        continue;
198
                }
199
#endif
200
                AS.CollectOverFlag = 0;
3,393✔
201
                AR.expchanged = 0;
3,393✔
202
                if ( i == last ) LastExpression = 1;
3,393✔
203
                else             LastExpression = 0;
1,902✔
204
                if ( e->inmem ) {
3,393✔
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;
3,393✔
266
                        switch ( e->status ) {
3,393✔
267
                        case UNHIDELEXPRESSION:
3✔
268
                        case UNHIDEGEXPRESSION:
269
                                AR.GetFile = 2;
3✔
270
#ifdef WITHMPI
271
                    if ( PF.me == MASTER ) SetScratch(AR.hidefile,&(e->onfile));
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;
3✔
286
                                goto commonread;
3✔
287
                        case INTOHIDELEXPRESSION:
3✔
288
                        case INTOHIDEGEXPRESSION:
289
                                AR.outtohide = 1;
3✔
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);
3✔
296
                                /* fall through */
297
                        case LOCALEXPRESSION:
2,901✔
298
                        case GLOBALEXPRESSION:
299
                                AR.GetFile = 0;
2,901✔
300
/*[20oct2009 mt]:*/
301
#ifdef WITHMPI
302
                                if( ( PF.me == MASTER ) || (PF.mkSlaveInfile) )
303
#endif
304
                SetScratch(AR.infile,&(e->onfile));
2,901✔
305
/*:[20oct2009 mt]*/
306
                                curfile = AR.infile;
2,901✔
307
commonread:;
2,904✔
308
#ifdef WITHMPI
309
                                if ( PF_Processor(e,i,LastExpression) ) {
310
                                        MesPrint("Error in PF_Processor");
311
                                        goto ProcErr;
312
                                }
313
/*[20oct2009 mt]:*/
314
                                if ( AC.mparallelflag != PARALLELFLAG ){
315
                                        if(PF.me != MASTER)
316
                                                break;
317
#endif
318
/*:[20oct2009 mt]*/
319
                                if ( GetTerm(BHEAD term) <= 0 ) {
2,904✔
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;
2,904✔
329
                                if ( term[5] < 0 ) {        /* Fill with spectator */
2,904✔
330
                                        fromspectator = -term[5];
6✔
331
                                        PUTZERO(AM.SpectatorFiles[fromspectator-1].readpos);
6✔
332
                                        term[5] = AC.cbufnum;
6✔
333
                                }
334
                                else fromspectator = 0;
335
                                if ( AR.outtohide ) {
2,904✔
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);
2,901✔
342
                                        e->onfile = position;
2,901✔
343
                                        if ( PutOut(BHEAD term,&position,AR.outfile,0) < 0 ) goto ProcErr;
2,901✔
344
                                }
345
                                AR.DeferFlag = AC.ComDefer;
2,904✔
346
                                AR.Eside = RHSIDE;
2,904✔
347
                                if ( ( e->vflags & ISFACTORIZED ) != 0 ) {
2,904✔
348
                                        AR.BracketOn = 1;
69✔
349
                                        AT.BrackBuf = AM.BracketFactors;
69✔
350
                                        AT.bracketindexflag = 1;
69✔
351
                                }
352
                                if ( AT.bracketindexflag > 0 ) OpenBracketIndex(i);
2,904✔
353
#ifdef WITHPTHREADS
354
                                if ( AS.MultiThreaded && AC.mparallelflag == PARALLELFLAG ) {
1,934✔
355
                                        if ( ThreadsProcessor(e,LastExpression,fromspectator) ) {
1,904✔
356
                                                MesPrint("Error in ThreadsProcessor");
357
                                                goto ProcErr;
358
                                        }
359
                                        if ( AR.outtohide ) {
1,864✔
360
                                                AR.outfile = oldoutfile;
2✔
361
                                                AR.hidefile->POfull = AR.hidefile->POfill;
2✔
362
                                        }
363
                                }
364
                                else
365
#endif
366
                                {
367
                                        NewSort(BHEAD0);
1,000✔
368
                                        AR.MaxDum = AM.IndDum;
1,000✔
369
                                        AN.ninterms = 0;
1,000✔
370
                                        for(;;) {
454,987✔
371
                                         if ( fromspectator ) size = GetFromSpectator(term,fromspectator-1);
454,987✔
372
                                         else                 size = GetTerm(BHEAD term);
454,984✔
373
                                         if ( size <= 0 ) break;
454,987✔
374
                                         SeekScratch(curfile,&position);
454,006✔
375
                                         if ( ( e->vflags & ISFACTORIZED ) != 0 && term[1] == HAAKJE ) {
454,006✔
376
                                          StoreTerm(BHEAD term);
×
377
                                         }
378
                                         else {
379
                                          AN.ninterms++; dd = AN.deferskipped;
454,006✔
380
                                          if ( AC.CollectFun && *term <= (AM.MaxTer/(2*(LONG)(sizeof(WORD)))) ) {
454,006✔
381
                                                if ( GetMoreTerms(term) < 0 ) {
5✔
382
                                                  LowerSortLevel(); goto ProcErr;
×
383
                                                }
384
                                            SeekScratch(curfile,&position);
5✔
385
                                          }
386
                                          AT.WorkPointer = term + *term;
454,006✔
387
                                          AN.RepPoint = AT.RepCount + 1;
454,006✔
388
                                          if ( AR.DeferFlag ) {
454,006✔
389
                                                AN.IndDum = Expressions[AR.CurExpr].numdummies + AM.IndDum;
133✔
390
                                                AR.CurDum = AN.IndDum;
133✔
391
                                          }
392
                                          else {
393
                                                AN.IndDum = AM.IndDum;
453,873✔
394
                                                AR.CurDum = ReNumber(BHEAD term);
453,873✔
395
                                          }
396
                                          if ( AC.SymChangeFlag ) MarkDirty(term,DIRTYSYMFLAG);
454,006✔
397
                                          if ( AN.ncmod ) {
454,006✔
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);
454,005✔
402
                                          if ( ( AR.PolyFunType == 2 ) && ( AC.PolyRatFunChanged == 0 )
454,006✔
403
                                                && ( e->status == LOCALEXPRESSION || e->status == GLOBALEXPRESSION ) ) {
1,138✔
404
                                                PolyFunClean(BHEAD term);
1,138✔
405
                                          }
406
                                          if ( Generator(BHEAD term,0) ) {
454,006✔
407
                                                LowerSortLevel(); goto ProcErr;
2✔
408
                                          }
409
                                          AN.ninterms += dd;
453,987✔
410
                                         }
411
                                         SetScratch(curfile,&position);
453,987✔
412
                                         if ( AR.GetFile == 2 ) {
453,987✔
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)
453,986✔
418
                                                        -DIFBASE(position,curfile->POposition)/sizeof(WORD);
453,986✔
419
                                         }
420
                                        }
421
                                        AN.ninterms += dd;
981✔
422
                                        if ( LastExpression ) {
981✔
423
                                                UpdateMaxSize();
494✔
424
                                                if ( AR.infile->handle >= 0 ) {
494✔
425
                                                        CloseFile(AR.infile->handle);
3✔
426
                                                        AR.infile->handle = -1;
3✔
427
                                                        remove(AR.infile->name);
3✔
428
                                                        PUTZERO(AR.infile->POposition);
3✔
429
                                                }
430
                                                AR.infile->POfill = AR.infile->POfull = AR.infile->PObuffer;
494✔
431
                                        }
432
                                        if ( AR.outtohide ) AR.outfile = AR.hidefile;
981✔
433
                                        if ( EndSort(BHEAD AM.S0->sBuffer,0) < 0 ) goto ProcErr;
981✔
434
                                        if ( AR.outtohide ) {
980✔
435
                                                AR.outfile = oldoutfile;
1✔
436
                                                AR.hidefile->POfull = AR.hidefile->POfill;
1✔
437
                                        }
438
                                        e->numdummies = AR.MaxDum - AM.IndDum;
980✔
439
                                        UpdateMaxSize();
980✔
440
                                }
441
                                AR.BracketOn = oldBracketOn;
2,844✔
442
                                AT.BrackBuf = oldBrackBuf;
2,844✔
443
                                if ( ( e->vflags & TOBEFACTORED ) != 0 ) {
2,844✔
444
                                        poly_factorize_expression(e);
27✔
445
                                }
446
                                else if ( ( ( e->vflags & TOBEUNFACTORED ) != 0 )
2,817✔
447
                                 && ( ( e->vflags & ISFACTORIZED ) != 0 ) ) {
2,817✔
448
                                        poly_unfactorize_expression(e);
3✔
449
                                }
450
                                AT.bracketindexflag = oldbracketindexflag;
2,844✔
451
                                if ( AM.S0->TermsLeft )   e->vflags &= ~ISZERO;
2,844✔
452
                                else                      e->vflags |= ISZERO;
234✔
453
                                if ( AR.expchanged == 0 ) e->vflags |= ISUNMODIFIED;
2,844✔
454
                                if ( AM.S0->TermsLeft ) AR.expflags |= ISZERO;
2,844✔
455
                                if ( AR.expchanged )    AR.expflags |= ISUNMODIFIED;
2,844✔
456
                                AR.GetFile = 0;
2,844✔
457
                                AR.outtohide = 0;
2,844✔
458
/*[20oct2009 mt]:*/
459
#ifdef WITHMPI
460
                                }
461
#endif
462
#ifdef WITHPTHREADS
463
                                if ( e->status == INTOHIDELEXPRESSION ||
1,894✔
464
                                         e->status == INTOHIDEGEXPRESSION ) {
465
                                        SetHideFiles();
2✔
466
                                }
467
#endif
468
                                break;
950✔
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:
42✔
516
                        case HIDEGEXPRESSION:
517
#ifdef WITHMPI
518
                                if ( PF.me != MASTER ) break;
519
#endif
520
                                AR.GetFile = 0;
42✔
521
                                SetScratch(AR.infile,&(e->onfile));
42✔
522
                                if ( GetTerm(BHEAD term) <= 0 ) {
42✔
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;
42✔
532
                                AR.DeferFlag = 0;
42✔
533
                                SetEndHScratch(AR.hidefile,&position);
42✔
534
                                e->onfile = position;
42✔
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;
42✔
549
                                cbo = cpo = AM.S0->sBuffer;
42✔
550
                                do {
1,683✔
551
                                        WORD *oldipointer = AR.CompressPointer;
1,683✔
552
                                        WORD *oldibuffer = AR.CompressBuffer;
1,683✔
553
                                        WORD *comprtop = AR.ComprTop;
1,683✔
554
                                        AR.ComprTop = AM.S0->sTop;
1,683✔
555
                                        AR.CompressPointer = cpo;
1,683✔
556
                                        AR.CompressBuffer = cbo;
1,683✔
557
                                        if ( firstterm > 0 ) {
1,683✔
558
                                                if ( PutOut(BHEAD term,&position,AR.hidefile,1) < 0 ) goto ProcErr;
1,599✔
559
                                        }
560
                                        else if ( firstterm < 0 ) {
84✔
561
                                                if ( PutOut(BHEAD term,&position,AR.hidefile,0) < 0 ) goto ProcErr;
42✔
562
                                                firstterm++;
42✔
563
                                        }
564
                                        else {
565
                                                if ( PutOut(BHEAD term,&position,AR.hidefile,-1) < 0 ) goto ProcErr;
42✔
566
                                                firstterm++;
42✔
567
                                        }
568
                                        cpo = AR.CompressPointer;
1,683✔
569
                                        cbo = AR.CompressBuffer;
1,683✔
570
                                        AR.CompressPointer = oldipointer;
1,683✔
571
                                        AR.CompressBuffer = oldibuffer;
1,683✔
572
                                        AR.ComprTop = comprtop;
1,683✔
573
                                } while ( GetTerm(BHEAD term) );
1,683✔
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;
42✔
588
                                AR.hidefile->POfull = AR.hidefile->POfill;
42✔
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 ) {
42✔
611
                                        e->status = HIDDENLEXPRESSION;
42✔
612
                                        AS.OldOnFile[i] = e->onfile;
42✔
613
                                        AS.OldNumFactors[i] = Expressions[i].numfactors;
42✔
614
                                }
615
                                if ( e->status == HIDEGEXPRESSION ) {
42✔
616
                                        e->status = HIDDENGEXPRESSION;
×
617
                                        AS.OldOnFile[i] = e->onfile;
×
618
                                        AS.OldNumFactors[i] = Expressions[i].numfactors;
×
619
                                }
620
#ifdef WITHPTHREADS
621
                                SetHideFiles();
28✔
622
#endif
623
                                UpdateMaxSize();
42✔
624
                                break;
42✔
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
                }
638
                AR.KeptInHold = 0;
3,333✔
639
        }
640
        AR.DeferFlag = 0;
1,457✔
641
        AT.WorkPointer = term;
1,457✔
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);
1,457✔
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,381,556✔
685
{
686
        GETBIDENTITY
687
        WORD *m, *t, *r, retvalue = 0, funflag, j, oldncmod, nexpr, *Tpattern = 0;
37,381,556✔
688
        WORD *stop, *t1, *t2, funnum, wilds, tbufnum, stilldirty = 0;
37,381,556✔
689
        NESTING n;
37,381,556✔
690
        CBUF *C = cbuf+AT.ebufnum;
37,381,556✔
691
        LONG isp, i;
37,381,556✔
692
        TABLES T;
37,381,556✔
693
        COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
37,381,556✔
694
        WORD oldsorttype = AR.SortType;
37,381,556✔
695
ReStart:
1,612,695✔
696
        tbufnum = 0; i = 0; retvalue = 0;
38,994,251✔
697
        AT.TMbuff = AM.rbufnum;
38,994,251✔
698
        funflag = 0;
38,994,251✔
699
        t = term;
38,994,251✔
700
        r = t + *t - 1;
38,994,251✔
701
        m = r - ABS(*r) + 1;
38,994,251✔
702
        t++;
38,994,251✔
703
        if ( t < m ) do {
38,994,251✔
704
                if ( *t == SUBEXPRESSION ) {
138,331,257✔
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] ) {
7,051,124✔
725
                                r = t + t[1];
7,051,088✔
726
                                while ( AN.subsubveto == 0 &&
7,051,088✔
727
                                                        *r == SUBEXPRESSION && r < m && r[3] ) {
25,466,189✔
728
#ifdef WHICHSUBEXPRESSION
729
                                        mnum1++;
730
#endif
731
                                        if ( r[1] == t[1] && r[2] == t[2] && r[4] == t[4] ) {
18,415,101✔
732
                                                j = t[1] - SUBEXPSIZE;
18,379,818✔
733
                                                t1 = t + SUBEXPSIZE;
18,379,818✔
734
                                                t2 = r + SUBEXPSIZE;
18,379,818✔
735
                                                while ( j > 0 && *t1++ == *t2++ ) j--;
73,519,275✔
736
                                                if ( j <= 0 ) {
18,379,818✔
737
                                                        t[3] += r[3];
21✔
738
                                                        if ( t[3] == 0 ) {
21✔
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];
21✔
748
                                                                t2 = term + *term;
21✔
749
                                                                *term -= r[1];
21✔
750
                                                                m -= r[1];
21✔
751
                                                                while ( t1 < t2 ) *r++ = *t1++;
129✔
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;
18,415,101✔
795
                                        r += r[1];
18,415,101✔
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);
7,051,088✔
844
                                AT.TMbuff = t[4];
7,051,088✔
845
                                if ( t[4] == AM.dbufnum && (t+t[1]) < m && t[t[1]] == DOLLAREXPR2 ) {
7,051,088✔
846
                                        if ( t[t[1]+2] < 0 ) AT.TMdolfac = -t[t[1]+2];
186✔
847
                                        else {        /* resolve the element number */
848
                                                AT.TMdolfac = GetDolNum(BHEAD t+t[1],m)+1;
174✔
849
                                        }
850
                                }
851
                                else AT.TMdolfac = 0;
7,050,902✔
852
                                if ( t[3] < 0 ) {
7,051,088✔
853
                                        AN.TeInFun = 1;
1,353✔
854
                                        AR.TePos = WORDDIF(t,term);
1,353✔
855
                                        DONE(t[2])
1,353✔
856
                                }
857
                                else {
858
                                        AN.TeInFun = 0;
7,049,735✔
859
                                        AN.TeSuOut = t[3];
7,049,735✔
860
                                }
861
                                if ( t[2] < 0 ) {
7,049,735✔
862
                                        AN.TeSuOut = -t[3];
×
863
                                        DONE(-t[2])
×
864
                                }
865
                                DONE(t[2])
7,049,735✔
866
                        }
867
                }
868
                else if ( *t == EXPRESSION ) {
131,280,133✔
869
                        WORD *toTMaddr;
30,918✔
870
                        i = -t[2] - 1;
30,918✔
871
                        if ( t[3] < 0 ) {
30,918✔
872
                                AN.TeInFun = 1;
×
873
                                AR.TePos = WORDDIF(t,term);
×
874
                                DONE(i)
×
875
                        }
876
                        nexpr = t[3];
30,918✔
877
                        toTMaddr = m = AT.WorkPointer;
30,918✔
878
                        AN.Frozen = 0;
30,918✔
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];
30,918✔
886
                        AT.WorkPointer += j;
30,918✔
887
                        r = t;
30,918✔
888
                        NCOPY(m,r,j);
846,546✔
889
                        r = t + t[1];
30,918✔
890
                        t += SUBEXPSIZE;
30,918✔
891
                        while ( t < r ) {
60,918✔
892
                                if ( *t == FROMBRAC ) {
60,102✔
893
                                        WORD *ttstop,*tttstop;
30,102✔
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,102✔
900
                                        AN.Frozen = m = AT.WorkPointer;
30,102✔
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,102✔
909
                                        GETSTOP(t,ttstop);
30,102✔
910
                                        *m++ = j; t++;
30,102✔
911
                                        while ( t < ttstop ) {
30,102✔
912
                                                if ( *t == SUBEXPRESSION ) break;
30,099✔
913
                                                if ( *t >= FUNCTION && ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) ) break;
30,069✔
914
                                                j = t[1]; NCOPY(m,t,j);
30,447✔
915
                                        }
916
                                        if ( t < ttstop ) {
30,102✔
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,270✔
923
                                                *AT.WorkPointer = m-AT.WorkPointer;
30,030✔
924
                                                m = AT.WorkPointer;
30,030✔
925
                                                AT.WorkPointer = m + *m;
30,030✔
926
                                                NewSort(BHEAD0);
30,030✔
927
                                                if ( Generator(BHEAD m,AR.Cnumlhs) ) {
30,030✔
928
                                                        LowerSortLevel(); goto EndTest;
×
929
                                                }
930
                                                if ( EndSort(BHEAD m,0) < 0 ) goto EndTest;
30,030✔
931
                                                AN.Frozen = m;
30,030✔
932
                                                if ( *m == 0 ) {
30,030✔
933
                                                        *m++ = 4; *m++ = 1; *m++ = 1; *m++ = 3;
×
934
                                                }
935
                                                else if ( m[*m] != 0 ) {
30,030✔
936
                                                        MLOCK(ErrorMessageLock);
×
937
                                                        MesPrint("Bracket specification in expression should be one single term");
×
938
                                                        MUNLOCK(ErrorMessageLock);
×
939
                                                        Terminate(-1);
×
940
                                                }
941
                                                else {
942
                                                        m += *m;
30,030✔
943
                                                        m -= ABS(m[-1]);
30,030✔
944
                                                        *m++ = 1; *m++ = 1; *m++ = 3;
30,030✔
945
                                                        *AN.Frozen = m - AN.Frozen;
30,030✔
946
                                                }
947
                                        }
948
                                        else {
949
                                                while ( t < tttstop ) *m++ = *t++;
288✔
950
                                                *AT.WorkPointer = m-AT.WorkPointer;
72✔
951
                                                m = AT.WorkPointer;
72✔
952
                                                AT.WorkPointer = m + *m;
72✔
953
                                                if ( Normalize(BHEAD m) ) {
72✔
954
                                                        MLOCK(ErrorMessageLock);
×
955
                                                        MesPrint("Error while picking up contents of bracket");
×
956
                                                        MUNLOCK(ErrorMessageLock);
×
957
                                                        Terminate(-1);
×
958
                                                }
959
                                                if ( !*m ) {
72✔
960
                                                        *m++ = 4; *m++ = 1; *m++ = 1; *m++ = 3;
×
961
                                                }
962
                                                else m += *m;
72✔
963
                                        }
964
                                        AT.WorkPointer = m;
30,102✔
965
                                        break;
30,102✔
966
                                }
967
                                t += t[1];
30,000✔
968
                        }
969
                        AN.TeInFun = 0;
30,918✔
970
                        AR.TePos = 0;
30,918✔
971
                        AN.TeSuOut = nexpr;
30,918✔
972
                        AT.TMaddr = toTMaddr;
30,918✔
973
                        DONE(i)
30,918✔
974
                }
975
                else if ( *t >= FUNCTION ) {
131,249,215✔
976
            if ( t[0] == EXPONENT ) {
92,858,311✔
977
                if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SYMBOL &&
1,494✔
978
                t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+3] < MAXPOWER
12✔
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
1,494✔
992
                                 && t[FUNHEAD+ARGHEAD] == 9 && t[FUNHEAD+ARGHEAD+1] == DOTPRODUCT
24✔
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;
92,858,311✔
1014
                        if ( *t >= FUNCTION + WILDOFFSET ) funnum -= WILDOFFSET;
92,858,311✔
1015
                        if ( *t == EXPONENT ) {
92,858,311✔
1016
/*
1017
                                Test whether the second argument is an integer
1018
*/
1019
                                r = t+FUNHEAD;
1,494✔
1020
                                NEXTARG(r)
1,494✔
1021
                                if ( *r == -SNUMBER && r[1] < MAXPOWER && r+2 == t+t[1] &&
1,494✔
1022
                                t[FUNHEAD] > -FUNCTION && ( t[FUNHEAD] != -SNUMBER
1,035✔
1023
                                || t[FUNHEAD+1] != 0 ) && t[FUNHEAD] != ARGHEAD ) {
1,035✔
1024
                                  if ( r[1] == 0 ) {
1,035✔
1025
                                        if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 ) {
162✔
1026
                                                MLOCK(ErrorMessageLock);
×
1027
                                                MesPrint("Encountered 0^0. Fatal error.");
×
1028
                                                MUNLOCK(ErrorMessageLock);
×
1029
                                                SETERROR(-1);
×
1030
                                        }
1031
                                        *t = DUMMYFUN;
162✔
1032
/*
1033
                                                Now mark it clean to avoid further interference.
1034
                                                Normalize will remove this object.
1035
*/
1036
                                        t[2] = 0;
162✔
1037
                                  }
1038
                                  else {
1039
                                        /* Note that the case 0^ is treated in Normalize */
1040

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

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

1062
                                        C->CanCommu[C->numrhs] = 1;
873✔
1063
                                        *t++ = SUBEXPRESSION;
873✔
1064
                                        *t++ = SUBEXPSIZE;
873✔
1065
                                        *t++ = C->numrhs;
873✔
1066
                                        *t++ = r[1];
873✔
1067
                                        *t++ = AT.ebufnum;
873✔
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;
873✔
1073
                                        m = term + *term;
873✔
1074
                                        do { *t++ = *r++; } while ( r < m );
3,207✔
1075
                                        *term -= WORDDIF(r,t);
873✔
1076
                                        goto ReStart;
873✔
1077
                                  }
1078
                                }
1079
                        }
1080
                        else if ( *t == SUMF1 || *t == SUMF2 ) {
92,856,817✔
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;
55✔
1093
                                tstop = t + t[1];
55✔
1094
                                r = t+FUNHEAD;
55✔
1095
                                if ( r+6 < tstop && r[2] == -SNUMBER && r[4] == -SNUMBER 
55✔
1096
                                && ( ( r[0] == -SYMBOL )
19✔
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 */
19✔
1101
                                        lcmin = r[3];
19✔
1102
                                        lcmax = r[5];
19✔
1103
                                        r += 6;
19✔
1104
                                        if ( *r == -SNUMBER && r+2 < tstop ) {
19✔
1105
                                                lcinc = r[1];
×
1106
                                                r += 2;
×
1107
                                        }
1108
                                        else lcinc = 1;
1109
                                        if ( r < tstop && ( ( *r > 0 && (r+*r) == tstop )
19✔
1110
                                        || ( *r <= -FUNCTION && r+1 == tstop )
×
1111
                                        || ( *r > -FUNCTION && *r < 0 && r+2 == tstop ) ) ) {
×
1112
                                                m = AddRHS(AT.ebufnum,1);
19✔
1113
                                                if ( *r > 0 ) {
19✔
1114
                                                        i = *r - ARGHEAD;
19✔
1115
                                                        r += ARGHEAD;
19✔
1116
                                                        while ( (m + i + 10) > C->Top )
19✔
1117
                                                                m = DoubleCbuffer(AT.ebufnum,m,11);
×
1118
                                                        while ( --i >= 0 ) *m++ = *r++;
254✔
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;
19✔
1127
                                                C->rhs[C->numrhs+1] = m;
19✔
1128
                                                C->Pointer = m;
19✔
1129
                                                m = AT.TMout;
19✔
1130
                                                *m++ = 6;
19✔
1131
                                                if ( *t == SUMF1 ) *m++ = SUMNUM1;
19✔
1132
                                                else                           *m++ = SUMNUM2;
3✔
1133
                                                *m++ = lcounter;
19✔
1134
                                                *m++ = lcmin;
19✔
1135
                                                *m++ = lcmax;
19✔
1136
                                                *m++ = lcinc;
19✔
1137
                                                m = t + t[1];
19✔
1138
                                                r = C->rhs[C->numrhs];
19✔
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)
19✔
1146
                                                && ABS(*(r+*r-1)) < (*r - 1)
19✔
1147
                                                && r[1] == SUBEXPRESSION ) {
19✔
1148
                                                        r++;
13✔
1149
                                                        i = r[1] - 5;
13✔
1150
                                                        *t++ = *r++; *t++ = *r++; *t++ = C->numrhs;
13✔
1151
                                                        r++; *t++ = *r++; *t++ = AT.ebufnum; r++;
13✔
1152
                                                        while ( --i >= 0 ) *t++ = *r++;
65✔
1153
                                                }
1154
                                                else {
1155
                                                        *t++ = SUBEXPRESSION;
6✔
1156
                                                        *t++ = 4+SUBEXPSIZE;
6✔
1157
                                                        *t++ = C->numrhs;
6✔
1158
                                                        *t++ = 1;
6✔
1159
                                                        *t++ = AT.ebufnum;
6✔
1160
                                                        FILLSUB(t)
1161
                                                        if ( lcounter < 0 ) {
6✔
1162
                                                                *t++ = INDTOIND;
×
1163
                                                                *t++ = 4;
×
1164
                                                                *t++ = -lcounter;
×
1165
                                                        }
1166
                                                        else {
1167
                                                                *t++ = SYMTONUM;
6✔
1168
                                                                *t++ = 4;
6✔
1169
                                                                *t++ = lcounter;
6✔
1170
                                                        }
1171
                                                        *t++ = lcmin;
6✔
1172
                                                }
1173
                                                t2 = term + *term;
19✔
1174
                                                while ( m < t2 ) *t++ = *m++;
76✔
1175
                                                *term = WORDDIF(t,term);
19✔
1176
                                                AN.TeInFun = -C->numrhs;
19✔
1177
                                                AR.TePos = 0;
19✔
1178
                                                AN.TeSuOut = 0;
19✔
1179
                                                AT.TMbuff = AT.ebufnum;
19✔
1180
                                                DONE(C->numrhs)
19✔
1181
                                        }
1182
                                }
1183
                        }
1184
                        else if ( *t == TOPOLOGIES ) {
92,856,762✔
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 ) {
92,856,762✔
1209
/*
1210
                                Syntax:
1211
                                diagrams_(model,setinparticles,setoutparticles,
1212
                                        setextmomenta,setintmomenta,couplings or loops)
1213
*/
1214
                                if ( AC.nummodels > 0 ) { /* No model, no diagrams */
6✔
1215
                                  t1 = t+FUNHEAD; t2 = t+t[1];
6✔
1216
                                  if ( 
6✔
1217
                                  t1[0] == -SETSET && Sets[t1[1]].type == CMODEL &&
6✔
1218
                                  t1[2] == -SETSET && ( Sets[t1[3]].type == CFUNCTION 
6✔
1219
                                        || ( Sets[t1[3]].type == ANYTYPE && ( Sets[t1[3]].first == Sets[t1[3]].last ) ) ) &&
×
1220
                                  t1[4] == -SETSET && ( Sets[t1[5]].type == CFUNCTION
6✔
1221
                                        || ( Sets[t1[5]].type == ANYTYPE && ( Sets[t1[5]].first == Sets[t1[5]].last ) ) ) &&
6✔
1222
                                  t1[6] == -SETSET && Sets[t1[7]].type == CVECTOR &&
6✔
1223
                                  t1[8] == -SETSET && Sets[t1[9]].type == CVECTOR &&
6✔
1224
                                  t1+12 <= t2 ) {
6✔
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]];
6✔
1230
                                        int nn0,nn1,nn2;
6✔
1231
                                        for ( nn0 = 3; nn0 <= 5; nn0 += 2 ) {
18✔
1232
                                          for ( nn1 = Sets[t1[nn0]].first; nn1 < Sets[t1[nn0]].last; nn1++ ) {
24✔
1233
                                                for ( nn2 = 0; nn2 < m->nparticles; nn2++ ) {
12✔
1234
                                                        if ( m->vertices[nn2]->particles[0].number == SetElements[nn1]
12✔
1235
                                                          || m->vertices[nn2]->particles[1].number == SetElements[nn1] ) break;
×
1236
                                                }
1237
                                                if ( nn2 >= m->nparticles ) goto doesnotwork;
12✔
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 )
6✔
1245
                                        || ( t1[10] == -SYMBOL && t1+12 == t2 )
6✔
1246
                                        || ( t1+10+t1[10] == t2 && t1+10+ARGHEAD+t1[10+ARGHEAD] == t2
6✔
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 )
6✔
1269
                                        || ( t1[10] == -SYMBOL && t1+12 == t2-2 )
6✔
1270
                                        || ( t1+10+t1[10] == t2-2 && t1+10+ARGHEAD+t1[10+ARGHEAD] == t2-2
3✔
1271
                                        && t1[11+ARGHEAD] == SYMBOL ) ) && t2[-2] == -SNUMBER ) {
3✔
1272
/*
1273
                                                With options at t2[-2],t2[-1]
1274
                                                Now test that all symbols are valid coupling constants.
1275
*/
1276
                                                t2 -= 2;
3✔
1277
                                                if ( t1+12 > t2 ) {
3✔
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;
3✔
1289
                                                AN.TeSuOut = 0;
3✔
1290
                                                AR.TePos = -1;
3✔
1291
                                                AR.funoffset = t - term;
3✔
1292
                                                DONE(1)
3✔
1293
                                        }
1294
doesnotwork:;
3✔
1295
                                  }
1296
                                }
1297
                        }
1298
                        if ( functions[funnum-FUNCTION].spec <= 0
92,857,416✔
1299
                                || ( t[2] & (DIRTYFLAG|MUSTCLEANPRF) ) != 0 ) {
164,226✔
1300
                                funflag = 1;
92,699,700✔
1301
                        }
1302
                        if ( *t <= MAXBUILTINFUNCTION ) {
92,857,416✔
1303
                          if ( *t <= DELTAP && *t >= THETA ) { /* Speeds up by 2 or 3 compares */
301,131✔
1304
                          if ( *t == THETA || *t == THETA2 ) {
756✔
1305
                                WORD *tstop, *tt2, kk;
582✔
1306
                                tstop = t + t[1];
582✔
1307
                                tt2 = t + FUNHEAD;
582✔
1308
                                while ( tt2 < tstop ) {
996✔
1309
                                        if ( *tt2 > 0 && tt2[1] != 0 ) goto DoSpec;
582✔
1310
                                        NEXTARG(tt2)
414✔
1311
                                }
1312
                                if ( !AT.RecFlag ) {
414✔
1313
                                        if ( ( kk = DoTheta(BHEAD t) ) == 0 ) {
414✔
1314
                                                *term = 0;
219✔
1315
                                                DONE(0)
219✔
1316
                                        }
1317
                                        else if ( kk > 0 ) {
195✔
1318
                                                m = t + t[1];
195✔
1319
                                                r = term + *term;
195✔
1320
                                                while ( m < r ) *t++ = *m++;
17,514✔
1321
                                                *term = WORDDIF(t,term);
195✔
1322
                                                goto ReStart;
195✔
1323
                                        }
1324
                                }
1325
                          }
1326
                          else if ( *t == DELTA2 || *t == DELTAP ) {
174✔
1327
                                WORD *tstop, *tt2, kk;
174✔
1328
                                tstop = t + t[1];
174✔
1329
                                tt2 = t + FUNHEAD;
174✔
1330
                                while ( tt2 < tstop ) {
348✔
1331
                                        if ( *tt2 > 0 && tt2[1] != 0 ) goto DoSpec;
174✔
1332
                                        NEXTARG(tt2)
174✔
1333
                                }
1334
                                if ( !AT.RecFlag ) {
174✔
1335
                                        if ( ( kk = DoDelta(t) ) == 0 ) {
174✔
1336
                                                *term = 0;
123✔
1337
                                                DONE(0)
123✔
1338
                                        }
1339
                                        else if ( kk > 0 ) {
51✔
1340
                                                m = t + t[1];
51✔
1341
                                                r = term + *term;
51✔
1342
                                                while ( m < r ) *t++ = *m++;
1,065✔
1343
                                                *term = WORDDIF(t,term);
51✔
1344
                                                goto ReStart;
51✔
1345
                                        }
1346
                                }
1347
                          } }
1348
                          else if ( *t == DISTRIBUTION && t[FUNHEAD] == -SNUMBER
300,375✔
1349
                          && t[FUNHEAD+1] >= -2 && t[FUNHEAD+1] <= 2
21✔
1350
                          && t[FUNHEAD+2] == -SNUMBER
21✔
1351
                          && t[FUNHEAD+4] <= -FUNCTION
21✔
1352
                          && t[FUNHEAD+5] <= -FUNCTION ) {
21✔
1353
                                WORD *ttt = t+FUNHEAD+6, *tttstop = t+t[1];
21✔
1354
                                while ( ttt < tttstop ) {
21✔
1355
                                        if ( *ttt == -DOLLAREXPRESSION ) break;
99✔
1356
                                        NEXTARG(ttt);
207✔
1357
                                }
1358
                                if ( ttt >= tttstop ) {
21✔
1359
                                        AN.TeInFun = -1;
15✔
1360
                                        AN.TeSuOut = 0;
15✔
1361
                                        AR.TePos = -1;
15✔
1362
                                        DONE(1)
15✔
1363
                                }
1364
                          }
1365
                          else if ( *t == DELTA3 && ((t[1]-FUNHEAD) & 1 ) == 0 ) {
300,354✔
1366
                                AN.TeInFun = -2;
18✔
1367
                                AN.TeSuOut = 0;
18✔
1368
                                AR.TePos = -1;
18✔
1369
                                DONE(1)
18✔
1370
                          }
1371
                          else if ( ( *t == TABLEFUNCTION ) && ( t[FUNHEAD] <= -FUNCTION )
300,336✔
1372
                          && ( T = functions[-t[FUNHEAD]-FUNCTION].tabl ) != 0
3✔
1373
                          && ( t[1] >= FUNHEAD+1+2*ABS(T->numind) )
3✔
1374
                          && ( t[FUNHEAD+1] == -SYMBOL ) ) {
3✔
1375
/*
1376
                                The case of table_(tab,sym1,...,symn)
1377
*/
1378
                                for ( isp = 0; isp < ABS(T->numind); isp++ ) {
6✔
1379
                                        if ( t[FUNHEAD+1+2*isp] != -SYMBOL ) break;
3✔
1380
                                }
1381
                                if ( isp >= ABS(T->numind) ) {
3✔
1382
                                        AN.TeInFun = -3;
3✔
1383
                                        AN.TeSuOut = 0;
3✔
1384
                                        AR.TePos = -1;
3✔
1385
                                        DONE(1)
3✔
1386
                                }
1387
                          }
1388
                          else if ( *t == TABLEFUNCTION && t[FUNHEAD] <= -FUNCTION
300,333✔
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 ) {
300,333✔
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 ) {
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 ) {
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
1477
                        || *t == INVERSEFUNCTION || *t == MULFUNCTION
1478
                                                || *t == GCDFUNCTION ) {
1479
                WORD *tf;
450✔
1480
                                int todo = 1, numargs = 0;
450✔
1481
                tf = t + FUNHEAD;
450✔
1482
                while ( tf < t + t[1] ) {
450✔
1483
                                        DOLLARS d;
1,209✔
1484
                                        if ( *tf == -DOLLAREXPRESSION ) {
1,209✔
1485
                                                d = Dollars + tf[1];
225✔
1486
                                                if ( d->type == DOLWILDARGS ) {
225✔
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);
2,868✔
1523
                }
1524
                tf = t + FUNHEAD;
1525
                while ( tf < t + t[1] ) {
1,659✔
1526
                                        numargs++;
1,209✔
1527
                                        if ( *tf > 0 && tf[1] != 0 ) todo = 0;
1,209✔
1528
                    NEXTARG(tf);
2,868✔
1529
                }
1530
                                if ( todo && numargs == 2 ) {
450✔
1531
                                        if ( *t == DIVFUNCTION ) AN.TeInFun = -9;
267✔
1532
                                        else if ( *t == REMFUNCTION ) AN.TeInFun = -10;
30✔
1533
                                        else if ( *t == INVERSEFUNCTION ) AN.TeInFun = -11;
18✔
1534
                                        else if ( *t == MULFUNCTION ) AN.TeInFun = -14;
42✔
1535
                                        else if ( *t == GCDFUNCTION ) AN.TeInFun = -8;
147✔
1536
                                        AN.TeSuOut = 0;
267✔
1537
                                        AR.TePos = -1;
267✔
1538
                                        DONE(1)
267✔
1539
                                }
1540
                                else if ( todo && numargs == 3 ) {
183✔
1541
                                        if ( *t == DIVFUNCTION ) AN.TeInFun = -9;
6✔
1542
                                        else if ( *t == REMFUNCTION ) AN.TeInFun = -10;
6✔
1543
                                        else if ( *t == GCDFUNCTION ) AN.TeInFun = -8;
6✔
1544
                                        AN.TeSuOut = 0;
6✔
1545
                                        AR.TePos = -1;
6✔
1546
                                        DONE(1)
6✔
1547
                                }
1548
                                else if ( todo && *t == GCDFUNCTION ) {
177✔
1549
                                        AN.TeInFun = -8;
27✔
1550
                                        AN.TeSuOut = 0;
27✔
1551
                                        AR.TePos = -1;
27✔
1552
                                        DONE(1)
27✔
1553
                                }
1554
                          }
1555
                          else if ( *t == PERMUTATIONS && ( ( t[1] >= FUNHEAD+1
3✔
1556
                                && t[FUNHEAD] <= -FUNCTION ) || ( t[1] >= FUNHEAD+3
3✔
1557
                                && t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] <= -FUNCTION ) ) ) {
×
1558
                                AN.TeInFun = -12;
3✔
1559
                                AN.TeSuOut = 0;
3✔
1560
                                AR.TePos = -1;
3✔
1561
                                DONE(1)
3✔
1562
                          }
1563
                          else if ( *t == PARTITIONS ) {
299,880✔
1564
                                if ( TestPartitions(t,&(AT.partitions)) ) {
12✔
1565
                                        AT.partitions.where = t-term;
12✔
1566
                                        AN.TeInFun = -13;
12✔
1567
                                        AN.TeSuOut = 0;
12✔
1568
                                        AR.TePos = -1;
12✔
1569
                                        DONE(1)
12✔
1570
                                }
1571
                          }
1572
                        }
1573
                }
1574
                t += t[1];
131,247,249✔
1575
        } while ( t < m );
131,247,249✔
1576
        if ( funflag ) {        /* Search in functions */
26,987,621✔
1577
DoSpec:
8,307,867✔
1578
                t = term;
8,308,035✔
1579
                AT.NestPoin->termsize = t;
8,308,035✔
1580
                if ( AT.NestPoin == AT.Nest ) AN.EndNest = t + *t;
8,308,035✔
1581
                t++;
8,308,035✔
1582
                oldncmod = AN.ncmod;
8,308,035✔
1583
                if ( t < m ) do {
8,308,035✔
1584
                        if ( *t < FUNCTION ) {
58,066,986✔
1585
                                t += t[1]; continue;
3,232,710✔
1586
                        }
1587
                        if ( AN.ncmod && ( ( AC.modmode & ALSOFUNARGS ) == 0 ) ) {
54,834,276✔
1588
                                if ( *t != AR.PolyFun ) AN.ncmod = 0;
×
1589
                                else                    AN.ncmod = oldncmod;
×
1590
                        }
1591
                        r = t + t[1];
54,834,276✔
1592
                        funnum = *t;
54,834,276✔
1593
                        if ( *t >= FUNCTION + WILDOFFSET ) funnum -= WILDOFFSET;
54,834,276✔
1594
                        if ( ( *t == NUMFACTORS || *t == FIRSTTERM || *t == CONTENTTERM )
54,834,276✔
1595
                         && t[1] == FUNHEAD+2 &&
42✔
1596
                        ( t[FUNHEAD] == -EXPRESSION || t[FUNHEAD] == -DOLLAREXPRESSION ) ) {
42✔
1597
/*
1598
                                if ( *t == NUMFACTORS ) {
1599
                                        This we leave for Normalize
1600
                                }
1601
*/                                
1602
                        }
1603
                        else if ( functions[funnum-FUNCTION].spec <= 0 ) {
54,834,234✔
1604
                                AT.NestPoin->funsize = t + 1;
54,826,155✔
1605
                                t1 = t;
54,826,155✔
1606
                                t += FUNHEAD;
54,826,155✔
1607
                                while ( t < r ) {        /* Sum over arguments */
109,221,906✔
1608
                                        if ( *t > 0 && t[1] ) {        /* Argument is dirty  */
57,756,684✔
1609
                                                AT.NestPoin->argsize = t;
3,357,690✔
1610
                                                AT.NestPoin++;
3,357,690✔
1611
/*                                                stop = t + *t; */
1612
                                                t2 = t;
3,357,690✔
1613
                                                t += ARGHEAD;
3,357,690✔
1614
                                                while ( t < AT.NestPoin[-1].argsize+*(AT.NestPoin[-1].argsize) ) {
8,203,380✔
1615
                                                                                        /* Sum over terms */
1616
                                                        AT.RecFlag++;
6,591,804✔
1617
                                                        i = *t;
6,591,804✔
1618
                                                        AN.subsubveto = 1;
6,591,804✔
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 ) {
6,591,804✔
1627
/*
1628
                                                                Possible size changes:
1629
                                                                Note defs at 471,467,460,400,425,328
1630
*/
1631
redosize:
1,746,108✔
1632
                                                                if ( i > *t ) {
1,746,114✔
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;
54✔
1644
                                                                        t += *t;
54✔
1645
                                                                        r = t + i;
54✔
1646
                                                                        m = AN.EndNest;
54✔
1647
                                                                        while ( r < m ) *t++ = *r++;
453✔
1648
                                                                        t = AT.NestPoin[-1].argsize + ARGHEAD;
54✔
1649
                                                                        n = AT.Nest;
54✔
1650
                                                                        while ( n < AT.NestPoin ) {
108✔
1651
                                                                                *(n->argsize) -= i;
54✔
1652
                                                                                *(n->funsize) -= i;
54✔
1653
                                                                                *(n->termsize) -= i;
54✔
1654
                                                                                n++;
54✔
1655
                                                                        }
1656
                                                                        AN.EndNest -= i;
54✔
1657
                                                                }
1658
                                                                AN.subsubveto = 0;
1,746,114✔
1659
                                                                t1[2] = 1;
1,746,114✔
1660
                                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 )
1,746,114✔
1661
                                                                        t1[2] |= MUSTCLEANPRF;
838,800✔
1662
                                                                AT.RecFlag--;
1,746,114✔
1663
                                                                AT.NestPoin--;
1,746,114✔
1664
                                                                AN.TeInFun++;
1,746,114✔
1665
                                                                AR.TePos = 0;
1,746,114✔
1666
                                                                AN.ncmod = oldncmod;
1,746,114✔
1667
                                                                DONE(retvalue)
1,746,114✔
1668
                                                        }
1669
                                                        else {
1670
                                                                /*
1671
                                                                 * Somehow the next line fixes Issue #106.
1672
                                                                 */
1673
                                                                i = *t;
4,845,696✔
1674
                                                                Normalize(BHEAD t);
4,845,696✔
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,845,696✔
1680
                                                                {
1681
                                                                        WORD *tend = t + *t, *tt = t+1;
4,845,690✔
1682
                                                                        stilldirty = 0;
4,845,690✔
1683
                                                                        tend -= ABS(tend[-1]);
4,845,690✔
1684
                                                                        while ( tt < tend ) {
6,632,364✔
1685
                                                                                if ( *tt == SUBEXPRESSION || *tt == EXPRESSION ) {
1,786,674✔
1686
                                                                                        stilldirty = 1; break;
1687
                                                                                }
1688
                                                                                tt += tt[1];
1,786,674✔
1689
                                                                        }
1690
                                                                }
1691
                                                                if ( i > *t ) {
4,845,690✔
1692
/*
1693
                                                                        We should not forget to correct the Nest
1694
                                                                        stack. That caused trouble in the past.
1695
*/
1696
                                                                        retvalue = 1;
3,030✔
1697
                                                                        i -= *t;
3,030✔
1698
                                                                        t += *t;
3,030✔
1699
                                                                        r = t + i;
3,030✔
1700
                                                                        m = AN.EndNest;
3,030✔
1701
                                                                        while ( r < m ) *t++ = *r++;
36,472,503✔
1702
                                                                        t = AT.NestPoin[-1].argsize + ARGHEAD;
3,030✔
1703
                                                                        n = AT.Nest;
3,030✔
1704
                                                                        while ( n < AT.NestPoin ) {
6,084✔
1705
                                                                                *(n->argsize) -= i;
3,054✔
1706
                                                                                *(n->funsize) -= i;
3,054✔
1707
                                                                                *(n->termsize) -= i;
3,054✔
1708
                                                                                n++;
3,054✔
1709
                                                                        }
1710
                                                                        AN.EndNest -= i;
3,030✔
1711
                                                                }
1712
                                                        }
1713
                                                        AN.subsubveto = 0;
4,845,690✔
1714
                                                        AT.RecFlag--;
4,845,690✔
1715
                                                        t += *t;
4,845,690✔
1716
                                                }
1717
                                                AT.NestPoin--;
1,611,576✔
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,611,576✔
1724
                                                j = *t;
1,611,576✔
1725
                                                t += ARGHEAD;
1,611,576✔
1726
                                                NewSort(BHEAD0);
1,611,576✔
1727
                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 ) {
1,611,576✔
1728
                                                        AR.CompareRoutine = (COMPAREDUMMY)(&CompareSymbols);
839,196✔
1729
                                                        AR.SortType = SORTHIGHFIRST;
839,196✔
1730
                                                }
1731
                                                if ( AT.WorkPointer < term + *term )
1,611,576✔
1732
                                                        AT.WorkPointer = term + *term;
×
1733

1734
                                                while ( t < AT.NestPoin->argsize+*(AT.NestPoin->argsize) ) {
4,996,200✔
1735
                                                        m = AT.WorkPointer;
3,384,624✔
1736
                                                        r = t + *t;
3,384,624✔
1737
                                                        do { *m++ = *t++; } while ( t < r );
21,833,448✔
1738
                                                        r = AT.WorkPointer;
3,384,624✔
1739
                                                        AT.WorkPointer = r + *r;
3,384,624✔
1740
                                                        if ( Normalize(BHEAD r) ) {
3,384,624✔
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 ) {
3,384,624✔
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 ) {
3,384,624✔
1763
                                                                if ( PrepPoly(BHEAD r,1) != 0 ) goto EndTest;
1,769,559✔
1764
                                                        }
1765
                                                        if ( *r ) StoreTerm(BHEAD r);
3,384,624✔
1766
                                                        AT.WorkPointer = r;
3,384,624✔
1767
                                                }
1768
                                                if ( EndSort(BHEAD AT.WorkPointer+ARGHEAD,1) < 0 ) goto EndTest;
1,611,576✔
1769
                                                m = AT.WorkPointer+ARGHEAD;
1,611,576✔
1770
                                                if ( *t1 == AR.PolyFun && AR.PolyFunType == 2 ) {
1,611,576✔
1771
                                                        AR.SortType = oldsorttype;
839,196✔
1772
                                                        AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
839,196✔
1773
                                                        t1[2] |= MUSTCLEANPRF;
839,196✔
1774
                                                }
1775
                                                while ( *m ) m += *m;
4,993,170✔
1776
                                                i = WORDDIF(m,AT.WorkPointer);
1,611,576✔
1777
                                                *AT.WorkPointer = i;
1,611,576✔
1778
                                                AT.WorkPointer[1] = stilldirty;
1,611,576✔
1779
                                                if ( ToFast(AT.WorkPointer,AT.WorkPointer) ) {
1,611,576✔
1780
                                                        m = AT.WorkPointer;
129✔
1781
                                                        if ( *m <= -FUNCTION ) { m++; i = 1; }
129✔
1782
                                                        else { m += 2; i = 2; }
123✔
1783
                                                }
1784
                                                j = i - j;
1,611,576✔
1785
                                                if ( j > 0 ) {
1,611,576✔
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,611,576✔
1800
                                                        m = AT.NestPoin->argsize+*(AT.NestPoin->argsize);
138✔
1801
                                                        r = m + j;
138✔
1802
                                                        do { *r++ = *m++; } while ( m < AN.EndNest );
1,080✔
1803
                                                }
1804
                                                m = AT.NestPoin->argsize;
1,611,576✔
1805
                                                r = AT.WorkPointer;
1,611,576✔
1806
                                                while ( --i >= 0 ) *m++ = *r++;
26,655,438✔
1807
                                                n = AT.Nest;
1,611,576✔
1808
                                                while ( n <= AT.NestPoin ) {
3,223,248✔
1809
                                                        if ( *(n->argsize) > 0 && n != AT.NestPoin )
1,611,672✔
1810
                                                                *(n->argsize) += j;
96✔
1811
                                                        *(n->funsize) += j;
1,611,672✔
1812
                                                        *(n->termsize) += j;
1,611,672✔
1813
                                                        n++;
1,611,672✔
1814
                                                }
1815
                                                AN.EndNest += j;
1,611,576✔
1816
/*                                                (AT.NestPoin->argsize)[1] = 0;  */
1817
                                                if ( funnum == DENOMINATOR || funnum == EXPONENT ) {
1,611,576✔
1818
                                                        if ( Normalize(BHEAD term) ) {
1,527✔
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,611,576✔
1836
                                                goto ReStart;
1,611,576✔
1837
                                        }
1838
                                        else if ( *t == -DOLLAREXPRESSION ) {
54,398,994✔
1839
                                                if ( ( *t1 == TERMSINEXPR || *t1 == SIZEOFFUNCTION )
3,273✔
1840
                                                                 && t1[1] == FUNHEAD+2 ) {}
30✔
1841
                                                else {
1842
                                                        if ( AR.Eside != LHSIDE ) {
3,243✔
1843
                                                                AN.TeInFun = 1; AR.TePos = 0;
3,243✔
1844
                                                                AT.TMbuff = AM.dbufnum; t1[2] |= DIRTYFLAG;
3,243✔
1845
                                                                AN.ncmod = oldncmod;
3,243✔
1846
                                                                DONE(1)
3,243✔
1847
                                                        }
1848
                                                        AC.lhdollarflag = 1;
×
1849
                                                }
1850
                                        }
1851
                                        else if ( *t == -TERMSINBRACKET ) {
54,395,721✔
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 ) {
54,395,721✔
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)
54,395,751✔
1876
                                }
1877
                                if ( funnum >= FUNCTION && functions[funnum-FUNCTION].tabl ) {
51,465,222✔
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;
531✔
1884
                                        WORD ii, *p, *pp, *ppstop;
531✔
1885
                                        MINMAX *mm;
531✔
1886
                                        T = functions[funnum-FUNCTION].tabl;
531✔
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;
177✔
1898
#endif
1899
                                        if ( Tpattern == 0 ) Tpattern = TermMalloc("Tpattern");
531✔
1900
                                        p = Tpattern;
531✔
1901
                                        ii = pp[1];
531✔
1902
                                        for ( i = 0; i < ii; i++ ) *p++ = *pp++;
9,534✔
1903

1904
                                        p = Tpattern + FUNHEAD+1;
531✔
1905
                                        mm = T->mm;
531✔
1906
                                        if ( T->sparse ) {
531✔
1907
                                                WORD xx;
30✔
1908
                                                t = t1+FUNHEAD;
30✔
1909
                                                if ( T->numind == 0 ) { isp = 0; xx = 0; }
30✔
1910
                                                else {
1911
                                                        if ( T->numind < 0 ) {
30✔
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 ) {
60✔
1921
                                                                if ( *t != -SNUMBER ) break;
30✔
1922
                                                        }
1923
                                                        if ( i < xx ) goto teststrict;
30✔
1924
                                                        isp = FindTableTree(T,t1+FUNHEAD,2);
30✔
1925
                                                }
1926
                                                if ( isp < 0 ) {
30✔
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)];
30✔
1955
#if ( TABLEEXTENSION == 2 )
1956
                                                        tbufnum = T->bufnum;
1957
#else
1958
                                                        tbufnum = T->tablepointers[isp+ABS(T->numind)+1];
30✔
1959
#endif
1960
                                                        t = t1+FUNHEAD+1;
30✔
1961
                                                        ii = xx;
30✔
1962
                                                        while ( --ii >= 0 ) {
60✔
1963
                                                                *p = *t; t += 2; p += 2;
30✔
1964
                                                        }
1965
                                                }
1966
                                                if ( xx < ABS(T->numind) ) {
30✔
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;
30✔
1973
                                        }
1974
                                        else {
1975
                                                i = 0;
501✔
1976
                                                t = t1 + FUNHEAD;
501✔
1977
                                                j = T->numind;
501✔
1978
                                                while ( --j >= 0 ) {
573✔
1979
                                                        if ( *t != -SNUMBER ) goto NextFun;
72✔
1980
                                                        t++;
72✔
1981
                                                        if ( *t < mm->mini || *t > mm->maxi ) {
72✔
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);
72✔
2005
                                                        *p = *t++;
72✔
2006
                                                        p += 2;
72✔
2007
                                                        mm++;
72✔
2008
                                                }
2009
/*
2010
                                                Test now whether the entry exists.
2011
*/
2012
                                                i *= TABLEEXTENSION;
501✔
2013
                                                if ( T->tablepointers[i] == -1 ) {
501✔
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];
501✔
2041
#if ( TABLEEXTENSION == 2 )
2042
                                                        tbufnum = T->bufnum;
2043
#else
2044
                                                        tbufnum = T->tablepointers[i+1];
501✔
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:
531✔
2056
#ifdef WITHPTHREADS
2057
                                        AN.FullProto = T->prototype[AT.identity];
354✔
2058
#else
2059
                                        AN.FullProto = T->prototype;
177✔
2060
#endif
2061
                                        AN.WildValue = AN.FullProto + SUBEXPSIZE;
531✔
2062
                                        AN.WildStop = AN.FullProto+AN.FullProto[1];
531✔
2063
                                        ClearWild(BHEAD0);
531✔
2064
                                        AN.RepFunNum = 0;
531✔
2065
                                        AN.RepFunList = AN.EndNest;
531✔
2066
                                    AT.WorkPointer = (WORD *)(((UBYTE *)(AN.EndNest)) + AM.MaxTer/2);
531✔
2067
                                        if ( AT.WorkPointer >= AT.WorkTop ) {
531✔
2068
                                                MLOCK(ErrorMessageLock);
×
2069
                                                MesWork();
×
2070
                                                MUNLOCK(ErrorMessageLock);
177✔
2071
                                        }
2072
                                        wilds = 0;
531✔
2073
                                        if ( MatchFunction(BHEAD Tpattern,t1,&wilds) > 0 ) {
531✔
2074
                                                AT.WorkPointer = oldwork;
531✔
2075
                                                if ( AT.NestPoin != AT.Nest ) {
531✔
2076
                                                        AN.ncmod = oldncmod;
×
2077
                                                        if ( Tpattern ) {
×
2078
                                                                TermFree(Tpattern,"Tpattern");
×
2079
                                                                Tpattern = 0;
×
2080
                                                        }
2081
                                                        DONE(1)
×
2082
                                                }
2083

2084
                                                m = AN.FullProto;
531✔
2085
                                                retvalue = m[2] = rhsnumber;
531✔
2086
                                                m[4] = tbufnum;
531✔
2087
                                                t = t1;
531✔
2088
                                                j = t[1];
531✔
2089
                                                i = m[1];
531✔
2090
                                                if ( j > i ) {
531✔
2091
                                                        j = i - j;
429✔
2092
                                                        NCOPY(t,m,i);
9,426✔
2093
                                                        m = term + *term;
429✔
2094
                                                        while ( r < m ) *t++ = *r++;
1,716✔
2095
                                                        *term += j;
429✔
2096
                                                }
2097
                                                else if ( j < i ) {
102✔
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);
612✔
2107
                                                }
2108
                                                AN.TeInFun = 0;
531✔
2109
                                                AR.TePos = 0;
531✔
2110
                                                AN.TeSuOut = -1;
531✔
2111
                                                if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
531✔
2112
                                                AT.TMbuff = tbufnum;
531✔
2113
                                                AN.ncmod = oldncmod;
531✔
2114
                                                DONE(retvalue);
531✔
2115
                                        }
2116
                                        AT.WorkPointer = oldwork;
×
2117
                                        if ( Tpattern ) {
×
2118
                                                TermFree(Tpattern,"Tpattern");
×
2119
                                                Tpattern = 0;
×
2120
                                        }
2121
                                }
2122
NextFun:;
51,464,691✔
2123
                        }
2124
                        else if ( ( t[2] & DIRTYFLAG ) != 0 ) {
8,079✔
2125
                                t += FUNHEAD;
6,489✔
2126
                                while ( t < r ) {
39,579✔
2127
                                        if ( *t == FUNNYDOLLAR ) {
33,090✔
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++;
33,090✔
2138
                                }
2139
                        }
2140
                        t = r;
51,472,812✔
2141
                        AN.ncmod = oldncmod;
51,472,812✔
2142
                } while ( t < m );
54,705,522✔
2143
        }
2144
Done:
23,626,325✔
2145
        if ( Tpattern ) {
37,381,556✔
2146
                TermFree(Tpattern,"Tpattern");
531✔
2147
                Tpattern = 0;
531✔
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,750,707✔
2175
{
2176
        GETBIDENTITY
2177
        WORD *m, *t, *r, *rr, sign = 1, oldncmod;
1,750,707✔
2178
        WORD *u, *v, *w, *from, *to, 
1,750,707✔
2179
                ipp, olddefer = AR.DeferFlag, oldPolyFun = AR.PolyFun, i, j;
1,750,707✔
2180
        LONG numterms;
1,750,707✔
2181
        from = t = term;
1,750,707✔
2182
        r = t + *t - 1;
1,750,707✔
2183
        m = r - ABS(*r) + 1;
1,750,707✔
2184
        t++;
1,750,707✔
2185
        while ( t < m ) {
21,678,447✔
2186
                if ( *t >= FUNCTION+WILDOFFSET ) ipp = *t - WILDOFFSET;
21,678,447✔
2187
                else ipp = *t;
2188
                if ( AR.TePos ) {
21,678,447✔
2189
                        if ( ( term + AR.TePos ) == t ) {
2,694✔
2190
                                m = termout;
2191
                                while ( from < t ) *m++ = *from++;
11,283✔
2192
                                *m++ = DENOMINATOR;
1,353✔
2193
                                *m++ = t[1] + 4 + FUNHEAD + ARGHEAD;
1,353✔
2194
                                *m++ = DIRTYFLAG;
1,353✔
2195
                                FILLFUN3(m)
2196
                                *m++ = t[1] + 4 + ARGHEAD;
1,353✔
2197
                                *m++ = 1;
1,353✔
2198
                                FILLARG(m)
2199
                                *m++ = t[1] + 4;
1,353✔
2200
                                t[3] = -t[3];
1,353✔
2201
                                v = t + t[1];
1,353✔
2202
                                while ( t < v ) *m++ = *t++;
8,118✔
2203
                                from[3] = -from[3];
1,353✔
2204
                                *m++ = 1;
1,353✔
2205
                                *m++ = 1;
1,353✔
2206
                                *m++ = 3;
1,353✔
2207
                                r = term + *term;
1,353✔
2208
                                while ( t < r ) *m++ = *t++;
5,448✔
2209
                                if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
1,353✔
2210
                                *termout = WORDDIF(m,termout);
1,353✔
2211
                                return(0);
1,353✔
2212
                        }
2213
                }
2214
                else if ( ( *t >= FUNCTION && functions[ipp-FUNCTION].spec <= 0 )
21,675,753✔
2215
                && ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) {
21,675,447✔
2216
                        m = termout;
21,030,738✔
2217
                        r = t + t[1];
21,030,738✔
2218
                        u = t;
21,030,738✔
2219
                        t += FUNHEAD;
21,030,738✔
2220
                        oldncmod = AN.ncmod;
21,030,738✔
2221
                        while ( t < r ) {        /* t points at an argument */
40,975,533✔
2222
                                if ( *t > 0 && t[1] ) {        /* Argument has been modified */
21,694,149✔
2223
                                        WORD oldsorttype = AR.SortType;
1,746,111✔
2224
                                        /* This whole argument must be redone */
2225

2226
                                        if ( ( AN.ncmod != 0 )
1,746,111✔
2227
                                                && ( ( AC.modmode & ALSOFUNARGS ) == 0 )
×
2228
                                                && ( *u != AR.PolyFun ) ) { AN.ncmod = 0; }
×
2229
                                        AR.DeferFlag = 0;
1,746,111✔
2230
                                        v = t + *t;
1,746,111✔
2231
                                        t += ARGHEAD;                /* First term */
1,746,111✔
2232
                                        w = 0;        /* to appease the compilers warning devices */
1,746,111✔
2233
                                        while ( from < t ) {
342,962,448✔
2234
                                                if ( from == u ) w = m;
341,216,337✔
2235
                                                *m++ = *from++;
341,216,337✔
2236
                                        }
2237
                                        to = m;
1,746,111✔
2238
                                        NewSort(BHEAD0);
1,746,111✔
2239
                                        if ( *u == AR.PolyFun && AR.PolyFunType == 2 ) {
1,746,111✔
2240
                                                AR.CompareRoutine = (COMPAREDUMMY)(&CompareSymbols);
838,800✔
2241
                                                AR.SortType = SORTHIGHFIRST;
838,800✔
2242
                                        }
2243
/*
2244
                                        AR.PolyFun = 0;
2245
*/
2246
                                        while ( t < v ) {
3,527,820✔
2247
                                                i = *t;
1,781,709✔
2248
                                                NCOPY(m,t,i);
23,141,925✔
2249
                                                m = to;
1,781,709✔
2250
                        if ( AT.WorkPointer < m+*m ) AT.WorkPointer = m + *m;
1,781,709✔
2251
                                                if ( Generator(BHEAD m,AR.Cnumlhs) ) {
1,781,709✔
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,746,111✔
2262
                                        if ( EndSort(BHEAD m,1) < 0 ) {
1,746,111✔
2263
                                                AN.ncmod = oldncmod;
×
2264
                                                goto InFunc;
×
2265
                                        }
2266
                                        AR.PolyFun = oldPolyFun;
1,746,111✔
2267
                                        if ( *u == AR.PolyFun && AR.PolyFunType == 2 ) {
1,746,111✔
2268
                                                AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
838,800✔
2269
                                                AR.SortType = oldsorttype;
838,800✔
2270
                                        }
2271
                                        while ( *m ) m += *m;
5,189,433✔
2272
                                        *to = WORDDIF(m,to);
1,746,111✔
2273
                                        to[1] = 1;  /* ??????? or rather 0?. 24-mar-2006 JV */
1,746,111✔
2274
                                        if ( ToFast(to,to) ) {
1,746,111✔
2275
                                                if ( *to <= -FUNCTION ) m = to+1;
137,997✔
2276
                                                else m = to+2;
2277
                                        }
2278
                                        w[1] = WORDDIF(m,w) + WORDDIF(r,v);
1,746,111✔
2279
                                        r = term + *term;
1,746,111✔
2280
                                        t = v;
1,746,111✔
2281
                                        while ( t < r ) *m++ = *t++;
286,290,771✔
2282
                                        if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
1,746,111✔
2283
                                        *termout = WORDDIF(m,termout);
1,746,111✔
2284
                                        AR.DeferFlag = olddefer;
1,746,111✔
2285
                                        AN.ncmod = oldncmod;
1,746,111✔
2286
                                        return(0);
1,746,111✔
2287
                                }
2288
                                else if ( *t == -DOLLAREXPRESSION ) {
19,948,038✔
2289
                                        if ( AR.Eside == LHSIDE ) {
3,243✔
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];
3,243✔
2298
#ifdef WITHPTHREADS
2299
                                        int nummodopt, dtype = -1;
2,162✔
2300
                                        if ( AS.MultiThreaded ) {
2,162✔
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;
3,243✔
2316
                                        if ( ( AN.ncmod != 0 )
3,243✔
2317
                                                && ( ( AC.modmode & ALSOFUNARGS ) == 0 )
×
2318
                                                && ( *u != AR.PolyFun ) ) { AN.ncmod = 0; }
×
2319
                                        AR.DeferFlag = 0;
3,243✔
2320
                                        v = t + 2;
3,243✔
2321
                                        w = 0;        /* to appease the compilers warning devices */
3,243✔
2322
                                        while ( from < t ) {
163,389✔
2323
                                                if ( from == u ) w = m;
160,146✔
2324
                                                *m++ = *from++;
160,146✔
2325
                                        }
2326
                                        to = m;
3,243✔
2327
                                        switch ( d->type ) {
3,243✔
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:
6✔
2335
                                                        *m++ = -SNUMBER; *m++ = 0; break;
6✔
2336
                                                case DOLNUMBER:
3,201✔
2337
                                                        if ( d->where[0] == 4 &&
3,201✔
2338
                                                        ( d->where[1] & MAXPOSITIVE ) == d->where[1] ) {
3,201✔
2339
                                                                *m++ = -SNUMBER;
3,201✔
2340
                                                                if ( d->where[3] >= 0 ) *m++ = d->where[1];
3,201✔
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;
30✔
2352
                                                        *m++ = 0; *m++ = 1;
30✔
2353
                                                        FILLARG(m)
2354
                                                        while ( *r ) {
63✔
2355
                                                                i = *r; NCOPY(m,r,i)
297✔
2356
                                                        }
2357
                                                        *to = m-to;
30✔
2358
                                                        if ( ToFast(to,to) ) {
30✔
2359
                                                                if ( *to <= -FUNCTION ) m = to+1;
24✔
2360
                                                                else m = to+2;
2361
                                                        }
2362
                                                        else if ( *u == AR.PolyFun && AR.PolyFunType == 2 ) {
6✔
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();
×
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);
30✔
2395
                                                        break;
30✔
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:
6✔
2422
                                                        to = m; r = d->where;
6✔
2423
                                                        if ( *r > 0 ) { /* Tensor arguments */
6✔
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++;
6✔
2437
                                                                while ( *r ) {
33✔
2438
                                                                        if ( *r > 0 ) {
27✔
2439
                                                                                i = *r - 2;
×
2440
                                                                                *m++ = *r++; *m++ = 1; r++;
×
2441
                                                                                while ( --i >= 0 ) *m++ = *r++;
×
2442
                                                                        }
2443
                                                                        else if ( *r <= -FUNCTION ) *m++ = *r++;
27✔
2444
                                                                        else { *m++ = *r++; *m++ = *r++; }
27✔
2445
                                                                }
2446
                                                        }
2447
                                                        w[1] = w[1] - 2 + (m-to);
6✔
2448
                                                        break;
6✔
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
2458
                                                        Terminate(-1);
×
2459
                                        }
2460
#ifdef WITHPTHREADS
2461
                                        if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
2,162✔
2462
#endif
2463
                                        r = term + *term;
3,243✔
2464
                                        t = v;
3,243✔
2465
                                        while ( t < r ) *m++ = *t++;
13,203✔
2466
                                        if ( (m-termout) > (LONG)(AM.MaxTer/sizeof(WORD)) ) goto TooLarge;
3,243✔
2467
                                        *termout = WORDDIF(m,termout);
3,243✔
2468
                                        AR.DeferFlag = olddefer;
3,243✔
2469
                                        AN.ncmod = oldncmod;
3,243✔
2470
                                        return(0);
3,243✔
2471
                                }
2472
                                }
2473
                                else if ( *t == -TERMSINBRACKET ) {
19,944,795✔
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) }
19,944,795✔
2513
                        }
2514
                        t = u;
2515
                }
2516
                else if ( ( *t >= FUNCTION && functions[ipp-FUNCTION].spec > 0 )
645,015✔
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];
19,927,740✔
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,375,663✔
2721
                WORD tepos)
2722
{
2723
        GETBIDENTITY
2724
        WORD *m, *t, *r, i, l2, j;
14,375,663✔
2725
        WORD *u, *v, l1, *coef;
14,375,663✔
2726
        coef = AT.WorkPointer;
14,375,663✔
2727
        if ( ( AT.WorkPointer = coef + 2*AM.MaxTal ) > AT.WorkTop ) {
14,375,663✔
2728
                MLOCK(ErrorMessageLock);
×
2729
                MesWork();
×
2730
                MUNLOCK(ErrorMessageLock);
×
2731
                return(-1);
×
2732
        }
2733
        t = term;
14,375,663✔
2734
        r = t + *t;
14,375,663✔
2735
        l1 = l2 = r[-1];
14,375,663✔
2736
        m = r - ABS(l2);
14,375,663✔
2737
        if ( tepos > 0 ) {
14,375,663✔
2738
                t = term + tepos;
8,012,179✔
2739
                goto foundit;
8,012,179✔
2740
        }
2741
        t++;
6,363,484✔
2742
        while ( t < m ) {
12,457,330✔
2743
                if ( *t == SUBEXPRESSION && t[2] == replac && t[3] && t[4] == extractbuff ) {
6,363,541✔
2744
                        r = t + t[1];
269,695✔
2745
                        while ( *r == SUBEXPRESSION && r[2] == replac && r[3] && r < m && r[4] == extractbuff ) {
269,695✔
2746
                                t = r; r += r[1];
×
2747
                        }
2748
foundit:;
269,695✔
2749
                        u = m;
8,281,874✔
2750
                        r = term;
8,281,874✔
2751
                        m = termout;
8,281,874✔
2752
                        do { *m++ = *r++; } while ( r < t );
181,448,906✔
2753
                        if ( t[1] > SUBEXPSIZE ) {
8,281,874✔
2754
/*
2755
                                if this is a dollar expression there are no wildcards
2756
*/
2757
                                i = *--m;
4,536,126✔
2758
                                if ( ( l2 = WildFill(BHEAD m,position,t) ) < 0 ) goto InsCall;
4,536,126✔
2759
                                *m = i;
4,536,126✔
2760
                                m += l2-1;
4,536,126✔
2761
                                l2 = *m;
4,536,126✔
2762
                                i = ( j = ABS(l2) ) - 1;
4,536,126✔
2763
                                r = coef + i;
4,536,126✔
2764
                                do { *--r = *--m; } while ( --i > 0 );
9,072,252✔
2765
                        }
2766
                        else {
2767
                                v = t;
3,745,748✔
2768
                                t = position;
3,745,748✔
2769
                                r = t + *t;
3,745,748✔
2770
                                l2 = r[-1];
3,745,748✔
2771
                                r -= ( j = ABS(l2) );
3,745,748✔
2772
                                t++;
3,745,748✔
2773
                                if ( t < r ) do { *m++ = *t++; } while ( t < r );
9,295,070✔
2774
                                t = v;
2775
                        }
2776
                        t += t[1];
8,281,874✔
2777
                        while ( t < u && *t == DOLLAREXPR2 ) t += t[1];
8,282,234✔
2778
ComAct:                if ( t < u ) do { *m++ = *t++; } while ( t < u );
33,304,310✔
2779
                        if ( *r == 1 && r[1] == 1 && j == 3 ) {
14,375,663✔
2780
                                if ( l2 < 0 ) l1 = -l1;
11,916,821✔
2781
                                i = ABS(l1)-1;
11,916,821✔
2782
                                NCOPY(m,t,i);
36,254,751✔
2783
                                *m++ = l1;
11,916,821✔
2784
                        }
2785
                        else {
2786
                                if ( MulRat(BHEAD (UWORD *)u,REDLENG(l1),(UWORD *)r,REDLENG(l2),
2,458,842✔
2787
                                (UWORD *)m,&l1) ) goto InsCall;
×
2788
                                l2 = l1;
2,458,842✔
2789
                                l2 *= 2;
2,458,842✔
2790
                                if ( l2 < 0 ) {
2,458,842✔
2791
                                        m -= l2;
405,239✔
2792
                                        *m++ = l2-1;
405,239✔
2793
                                }
2794
                                else {
2795
                                        m += l2;
2,053,603✔
2796
                                        *m++ = l2+1;
2,053,603✔
2797
                                }
2798
                        }
2799
                        *termout = WORDDIF(m,termout);
14,375,663✔
2800
                        if ( (*termout)*((LONG)sizeof(WORD)) > AM.MaxTer ) {
14,375,663✔
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,375,663✔
2806
                        return(0);
14,375,663✔
2807
                }
2808
                t += t[1];
6,093,846✔
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;
115,603,959✔
2816
        u = m;
115,603,959✔
2817
        r = term;
2818
        m = termout;
2819
        do { *m++ = *r++; } while ( r < t );
115,603,959✔
2820
        t = position;
6,093,789✔
2821
        r = t + *t;
6,093,789✔
2822
        l2 = r[-1];
6,093,789✔
2823
        r -= ( j = ABS(l2) );
6,093,789✔
2824
        t++;
6,093,789✔
2825
        if ( t < r ) do { *m++ = *t++; } while ( t < r );
6,154,788✔
2826
        t = v;
6,093,789✔
2827
        goto ComAct;
6,093,789✔
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)
1,565,316✔
2979
{
2980
        GETBIDENTITY
2981
        WORD *t, *r, x, y, z;
1,565,316✔
2982
        WORD *m, *u, l1, a[2];
1,565,316✔
2983
    m = (WORD *)(((UBYTE *)(accum)) + AM.MaxTer);
1,565,316✔
2984
/*    m = (WORD *)(((UBYTE *)(accum)) + 2*AM.MaxTer); */
2985
        *accum++ = number;
1,565,316✔
2986
        while ( --number >= 0 ) accum += *accum;
28,402,731✔
2987
        if ( times == divby ) {
1,565,316✔
2988
                t = position;
719,586✔
2989
                r = t + *t;
719,586✔
2990
                if ( t < r ) do { *accum++ = *t++; } while ( t < r );
13,784,217✔
2991
        }
2992
        else {
2993
                u = accum;
845,730✔
2994
                t = position;
845,730✔
2995
                r = t + *t - 1;
845,730✔
2996
                l1 = *r;
845,730✔
2997
                r -= ABS(*r) - 1;
845,730✔
2998
                if ( t < r ) do { *accum++ = *t++; } while ( t < r );
4,254,501✔
2999
                if ( divby > times ) { x = divby; y = times; }
845,730✔
3000
                else { x = times; y = divby; }
845,730✔
3001
                z = x%y;
845,730✔
3002
                while ( z ) { x = y; y = z; z = x%y; }
1,961,724✔
3003
                if ( y != 1 ) { divby /= y; times /= y; }
845,730✔
3004
                a[1] = divby;
845,730✔
3005
                a[0] = times;
845,730✔
3006
                if ( MulRat(BHEAD (UWORD *)t,REDLENG(l1),(UWORD *)a,1,(UWORD *)accum,&l1) ) {
845,730✔
3007
                        MLOCK(ErrorMessageLock);
×
3008
                        MesCall("PasteTerm");
×
3009
                        MUNLOCK(ErrorMessageLock);
×
3010
                        return(0);
×
3011
                }
3012
                x = l1;
845,730✔
3013
                x *= 2;
845,730✔
3014
                if ( x < 0 ) { accum -= x; *accum++ = x - 1; }
845,730✔
3015
                else                 { accum += x; *accum++ = x + 1; }
828,501✔
3016
                *u = WORDDIF(accum,u);
845,730✔
3017
        }
3018
        if ( accum >= m ) {
1,565,316✔
3019
                MLOCK(ErrorMessageLock);
×
3020
                MesPrint("Buffer too small in PasteTerm");
×
3021
                MUNLOCK(ErrorMessageLock);
×
3022
                return(0);
×
3023
        }
3024
        *accum = 0;
1,565,316✔
3025
        return(accum);
1,565,316✔
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,258,252✔
3044
{
3045
        GETBIDENTITY
3046
        WORD *m, *t, *r, i, numacc, l2, ipp;
3,258,252✔
3047
        WORD *u, *v, l1, *coef = AT.WorkPointer, *oldaccum;
3,258,252✔
3048
        if ( ( AT.WorkPointer = coef + 2*AM.MaxTal ) > AT.WorkTop ) {
3,258,252✔
3049
                MLOCK(ErrorMessageLock);
×
3050
                MesWork();
×
3051
                MUNLOCK(ErrorMessageLock);
×
3052
                return(-1);
×
3053
        }
3054
        oldaccum = accum;
3,258,252✔
3055
        t = term;
3,258,252✔
3056
        m = t + *t - 1;
3,258,252✔
3057
        l1 = REDLENG(*m);
3,258,252✔
3058
        i = ABS(*m) - 1;
3,258,252✔
3059
        r = coef + i;
3,258,252✔
3060
        do { *--r = *--m; } while ( --i > 0 ); /* Copies coefficient */
6,733,488✔
3061
        if ( tepos > 0 ) {
3,258,252✔
3062
                t = term + tepos;
186,660✔
3063
                goto foundit;
186,660✔
3064
        }
3065
        t++;
3,071,592✔
3066
        if ( t < m ) do {
3,071,592✔
3067
                if ( ( ( *t == SUBEXPRESSION && ( *(r=t+t[1]) != SUBEXPRESSION
6,124,770✔
3068
                || r >= m || !r[3] ) ) || *t == EXPRESSION ) && t[2] == number && t[3] ) {
6,124,770✔
3069
foundit:;
3,071,592✔
3070
                        u = m;
3,258,252✔
3071
                        r = term;
3,258,252✔
3072
                        m = termout;
3,258,252✔
3073
                        if ( r < t ) do { *m++ = *r++; } while ( r < t );
18,999,771✔
3074
                        numacc = *accum++;
3,258,252✔
3075
                        if ( numacc >= 0 ) do {
3,258,252✔
3076
                                if ( *t == EXPRESSION ) {
6,599,913✔
3077
                                        v = t + t[1];
3,071,613✔
3078
                                        r = t + SUBEXPSIZE;
3,071,613✔
3079
                                        while ( r < v ) {
3,071,856✔
3080
                                                if ( *r == WILDCARDS ) {
3,000,243✔
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];
243✔
3087
                                        }
3088
                                        goto NoWild;
71,613✔
3089
                                }
3090
                                else if ( t[1] > SUBEXPSIZE && t[SUBEXPSIZE] != FROMBRAC ) {
3,528,300✔
3091
                                        i = *--m;
127,464✔
3092
                                        if ( ( l2 = WildFill(BHEAD m,accum,t) ) < 0 ) goto FiniCall;
127,464✔
3093
AllWild:                        *m = i;
127,464✔
3094
                                        m += l2-1;
3,127,464✔
3095
                                        l2 = *m;
3,127,464✔
3096
                                        m -= ABS(l2) - 1;
3,127,464✔
3097
                                        r = m;
3,127,464✔
3098
                                }
3099
                                else {
3100
NoWild:                                r = accum;
3,400,836✔
3101
                                        v = r + *r - 1;
3,472,449✔
3102
                                        l2 = *v;
3,472,449✔
3103
                                        v -= ABS(l2) - 1;
3,472,449✔
3104
                                        r++;
3,472,449✔
3105
                                        if ( r < v ) do { *m++ = *r++; } while ( r < v );
22,608,432✔
3106
                                }
3107
                                if ( *r == 1 && r[1] == 1 && ABS(l2) == 3 ) {
6,599,913✔
3108
                                        if ( l2 < 0 ) l1 = -l1;
4,334,097✔
3109
                                }
3110
                                else {
3111
                                        l2 = REDLENG(l2);
2,265,816✔
3112
                                        if ( l2 == 0 ) {
2,265,816✔
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,265,816✔
3129
                                        if ( AN.ncmod != 0 && TakeModulus((UWORD *)coef,&l1,AC.cmod,AN.ncmod,UNPACK|AC.modmode) ) goto FiniCall;
2,265,816✔
3130
                                }
3131
                                accum += *accum;
6,599,913✔
3132
                        } while ( --numacc >= 0 );
6,599,913✔
3133
                        if ( *t == SUBEXPRESSION ) {
3,258,252✔
3134
                                 while ( t+t[1] < u && t[t[1]] == DOLLAREXPR2 ) t += t[1];
186,660✔
3135
                        }
3136
                        t += t[1];
3,258,252✔
3137
                        if ( t < u ) do { *m++ = *t++; } while ( t < u );
4,231,527✔
3138
                        l2 = l1;
3,258,252✔
3139
/*
3140
                        Code to economize when taking x = (a+b)/2
3141
*/
3142
                        r = termout+1;
3,258,252✔
3143
                        while ( r < m ) {
3,258,252✔
3144
                                if ( *r == SUBEXPRESSION ) {
13,071,042✔
3145
                                        t = r + r[1];
31,041✔
3146
                                        l1 = (WORD)(cbuf[r[4]].CanCommu[r[2]]);
31,041✔
3147
                                        while ( t < m ) {
845,472✔
3148
                                                if ( *t == SUBEXPRESSION &&
817,032✔
3149
                                                        t[1] == r[1] && t[2] == r[2] && t[4] == r[4] ) {
62,703✔
3150
                                                                i = t[1] - SUBEXPSIZE;
2,601✔
3151
                                                                u = r + SUBEXPSIZE; v = t + SUBEXPSIZE;
2,601✔
3152
                                                                while ( i > 0 ) {
9,369✔
3153
                                                                        if ( *v++ != *u++ ) break;
6,768✔
3154
                                                                        i--;
6,768✔
3155
                                                                }
3156
                                                                if ( i <= 0 ) {
×
3157
                                                                        u = r;
2,601✔
3158
                                                                        r[3] += t[3];
2,601✔
3159
                                                                        r = t + t[1];
2,601✔
3160
                                                                        while ( r < m ) *t++ = *r++;
780,657✔
3161
                                                                        m = t;
2,601✔
3162
                                                                        r = u;
2,601✔
3163
                                                                        goto Nextr;
2,601✔
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,431✔
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,431✔
3179
                                        }
3180
                                        r += r[1];
3181
                                }
3182
                                else r += r[1];
13,040,001✔
3183
Nextr:;
16,329,294✔
3184
                        }
3185

3186
                        i = ABS(l2);
3,258,252✔
3187
                        i *= 2;
3,258,252✔
3188
                        i++;
3,258,252✔
3189
                        l2 = ( l2 >= 0 ) ? i: -i;
3,258,252✔
3190
                        r = coef;
3,258,252✔
3191
                        while ( --i > 0 ) *m++ = *r++;
10,251,036✔
3192
                        *m++ = l2;
3,258,252✔
3193
                        *termout = WORDDIF(m,termout);
3,258,252✔
3194
                        AT.WorkPointer = coef;
3,258,252✔
3195
                        return(0);
3,258,252✔
3196
                }
3197
                t += t[1];
3,053,178✔
3198
        } while ( t < m );
3,053,178✔
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)
29,828,688✔
3243
{
3244
        GETBIDENTITY
3245
        WORD replac, *accum, *termout, *t, i, j, tepos, applyflag = 0, *StartBuf;
29,828,688✔
3246
        WORD *a, power, power1, DumNow = AR.CurDum, oldtoprhs, oldatoprhs, retnorm, extractbuff;
29,828,688✔
3247
        int *RepSto = AN.RepPoint, iscopy = 0;
29,828,688✔
3248
        CBUF *C = cbuf+AM.rbufnum, *CC = cbuf + AT.ebufnum, *CCC = cbuf + AT.aebufnum;
29,828,688✔
3249
        LONG posisub, oldcpointer, oldacpointer;
29,828,688✔
3250
        DOLLARS d = 0;
29,828,688✔
3251
        WORD numfac[5], idfunctionflag;
29,828,688✔
3252
#ifdef WITHPTHREADS
3253
        int nummodopt, dtype = -1, id;
19,174,041✔
3254
#endif
3255
        oldtoprhs = CC->numrhs;
29,828,688✔
3256
        oldcpointer = CC->Pointer - CC->Buffer;
29,828,688✔
3257
        oldatoprhs = CCC->numrhs;
29,828,688✔
3258
        oldacpointer = CCC->Pointer - CCC->Buffer;
29,828,688✔
3259
ReStart:
16,063✔
3260
        if ( ( replac = TestSub(BHEAD term,level) ) == 0 ) {
29,844,751✔
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;
23,703,635✔
3271
                AN.idfunctionflag = 0;
23,703,635✔
3272
                if ( ( retnorm = Normalize(BHEAD term) ) != 0 ) {
23,703,635✔
3273
                        if ( retnorm > 0 ) {
1,461✔
3274
                                if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
1,455✔
3275
                                goto ReStart;
1,455✔
3276
                        }
3277
                        goto GenCall;
6✔
3278
                }
3279
                idfunctionflag = AN.idfunctionflag;
23,702,174✔
3280
                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
23,702,174✔
3281

3282
                if ( AN.PolyNormFlag ) {
23,699,317✔
3283
                        if ( AN.PolyFunTodo == 0 ) {
16,524✔
3284
                                if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
16,503✔
3285
                                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
16,503✔
3286
                        }
3287
                        else {
3288
                                WORD oldPolyFunExp = AR.PolyFunExp;
21✔
3289
                                AR.PolyFunExp = 0;
21✔
3290
                                if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
21✔
3291
                                AT.WorkPointer = term+*term;
21✔
3292
                                AR.PolyFunExp = oldPolyFunExp;
21✔
3293
                                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
21✔
3294
                                if ( Normalize(BHEAD term) < 0 ) goto GenCall;
21✔
3295
                                if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
21✔
3296
                                AT.WorkPointer = term+*term;
21✔
3297
                                if ( AN.PolyNormFlag ) {
21✔
3298
                                        if ( PolyFunMul(BHEAD term) < 0 ) goto GenCall;
21✔
3299
                                        if ( !*term ) { AN.PolyNormFlag = 0; goto Return0; }
21✔
3300
                                        AT.WorkPointer = term+*term;
21✔
3301
                                }
3302
                                AN.PolyFunTodo = 0;
21✔
3303
                        }
3304
                }
3305
                if ( idfunctionflag > 0 ) {
23,699,317✔
3306
                        if ( TakeIDfunction(BHEAD term) ) {
×
3307
                                AT.WorkPointer = term + *term;
×
3308
                                goto ReStart;
×
3309
                        }
3310
                }
3311
                if ( AT.WorkPointer < (WORD *)(((UBYTE *)(term)) + AM.MaxTer) )
23,699,317✔
3312
                         AT.WorkPointer = (WORD *)(((UBYTE *)(term)) + AM.MaxTer);
23,693,496✔
3313
                do {
24,316,268✔
3314
SkipCount:        level++;
316,514✔
3315
                        if ( level > AR.Cnumlhs ) {
24,316,268✔
3316
                                if ( AR.DeferFlag && AR.sLevel <= 0 ) {
22,737,503✔
3317
#ifdef WITHMPI
3318
                                        if ( PF.me != MASTER && AC.mparallelflag == PARALLELFLAG && PF.exprtodo < 0 ) {
3319
                                                if ( PF_Deferred(term,level) ) goto GenCall;
3320
                                        }
3321
                                        else
3322
#endif
3323
                                        {
3324
                                                if ( Deferred(BHEAD term,level) ) goto GenCall;
6,081,711✔
3325
                                        }
3326
                                        goto Return0;
6,081,711✔
3327
                                }
3328
                                if ( AN.ncmod != 0 ) {
16,655,792✔
3329
                                        if ( Modulus(term) ) goto GenCall;
3✔
3330
                                        if ( !*term ) goto Return0;
3✔
3331
                                }
3332
                                if ( AR.CurDum > AM.IndDum && AR.sLevel <= 0 ) {
16,655,792✔
3333
                                        WORD olddummies = AN.IndDum;
87✔
3334
                                        AN.IndDum = AM.IndDum;
87✔
3335
                                        ReNumber(BHEAD term);
87✔
3336
                                        Normalize(BHEAD term);
87✔
3337
                                        AN.IndDum = olddummies;
87✔
3338
                                        if ( !*term ) goto Return0;
87✔
3339
                                        olddummies = DetCurDum(BHEAD term);
87✔
3340
                                        if ( olddummies > AR.MaxDum ) AR.MaxDum = olddummies;
87✔
3341
                                }
3342
                                if ( AR.PolyFun > 0 && ( AR.sLevel <= 0 || AN.FunSorts[AR.sLevel]->PolyFlag > 0 ) ) {
16,655,792✔
3343
                                        if ( PrepPoly(BHEAD term,0) != 0 ) goto Return0;
433,563✔
3344
                                }
3345
                                else if ( AR.PolyFun > 0 ) {
16,222,229✔
3346
                                        if ( PrepPoly(BHEAD term,1) != 0 ) goto Return0;
1,816,455✔
3347
                                }
3348
                                if ( AR.sLevel <= 0 && AR.BracketOn ) {
16,655,765✔
3349
                                        if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
41,043✔
3350
                                        termout = AT.WorkPointer;
41,043✔
3351
                                        if ( AT.WorkPointer + *term + 3 > AT.WorkTop ) goto OverWork;
41,043✔
3352
                                        if ( PutBracket(BHEAD term) ) return(-1);
41,043✔
3353
                                        AN.RepPoint = RepSto;
41,043✔
3354
                                        *AT.WorkPointer = 0;
41,043✔
3355
                                        i = StoreTerm(BHEAD termout);
41,043✔
3356
                                        AT.WorkPointer = termout;
41,043✔
3357
                                        CC->numrhs = oldtoprhs;
41,043✔
3358
                                        CC->Pointer = CC->Buffer + oldcpointer;
41,043✔
3359
                                        CCC->numrhs = oldatoprhs;
41,043✔
3360
                                        CCC->Pointer = CCC->Buffer + oldacpointer;
41,043✔
3361
                                        return(i);
41,043✔
3362
                                }
3363
                                else {
3364
                                        if ( AT.WorkPointer < term + *term ) AT.WorkPointer = term + *term;
16,614,722✔
3365
                                        if ( AT.WorkPointer >= AT.WorkTop ) goto OverWork;
16,614,722✔
3366
                                        *AT.WorkPointer = 0;
16,614,722✔
3367
                                        AN.RepPoint = RepSto;
16,614,722✔
3368
                                        i = StoreTerm(BHEAD term);
16,614,722✔
3369
                                        CC->numrhs = oldtoprhs;
16,614,719✔
3370
                                        CC->Pointer = CC->Buffer + oldcpointer;
16,614,719✔
3371
                                        CCC->numrhs = oldatoprhs;
16,614,719✔
3372
                                        CCC->Pointer = CCC->Buffer + oldacpointer;
16,614,719✔
3373
                                        return(i);
16,614,719✔
3374
                                }
3375
                        }
3376
                        i = C->lhs[level][0];
1,578,765✔
3377
                        if ( i >= TYPECOUNT ) {
1,578,765✔
3378
/*
3379
                        #[ Special action :
3380
*/
3381
                                switch ( i ) {
321,502✔
3382
                                  case TYPECOUNT:
×
3383
                                        if ( CountDo(term,C->lhs[level]) < C->lhs[level][2] ) {
×
3384
                                                AT.WorkPointer = term + *term;
×
3385
                                                goto Return0;
×
3386
                                        }
3387
                                        break;
3388
                                  case TYPEMULT:
5,158✔
3389
                                        if ( MultDo(BHEAD term,C->lhs[level]) ) goto GenCall;
5,158✔
3390
                                        goto ReStart;
5,158✔
3391
                                  case TYPEGOTO:
×
3392
                                        level = AC.Labels[C->lhs[level][2]];
×
3393
                                        break;
×
3394
                                  case TYPEDISCARD:
3✔
3395
                                        AT.WorkPointer = term + *term;
3✔
3396
                                        goto Return0;
3✔
3397
                                  case TYPEIF:
3,790✔
3398
#ifdef WITHPTHREADS
3399
                                        {
3400
/*
3401
                                                We may be writing in the space here when wildcards
3402
                                                are involved in a match(). Hence we have to make
3403
                                                a private copy here!!!!
3404
*/
3405
                                                WORD ic, jc, *ifcode, *jfcode;
3,790✔
3406
                                                jfcode = C->lhs[level]; jc = jfcode[1];
3,790✔
3407
                                                ifcode = AT.WorkPointer; AT.WorkPointer += jc;
3,790✔
3408
                                                for ( ic = 0; ic < jc; ic++ ) ifcode[ic] = jfcode[ic];
57,202✔
3409
                                                while ( !DoIfStatement(BHEAD ifcode,term) ) {
3,790✔
3410
                                                        level = C->lhs[level][2];
3,479✔
3411
                                                        if ( C->lhs[level][0] != TYPEELIF ) break;
3,479✔
3412
                                                }
3413
                                                AT.WorkPointer = ifcode;
3,790✔
3414
                                        }
3415
#else
3416
                                        while ( !DoIfStatement(BHEAD C->lhs[level],term) ) {
1,895✔
3417
                                                level = C->lhs[level][2];
1,741✔
3418
                                                if ( C->lhs[level][0] != TYPEELIF ) break;
1,741✔
3419
                                        }
3420
#endif
3421
                                        break;
3,790✔
3422
                                  case TYPEELIF:
×
3423
                                        do {
×
3424
                                                level = C->lhs[level][2];
×
3425
                                        } while ( C->lhs[level][0] == TYPEELIF );
×
3426
                                        break;
3427
                                  case TYPEELSE:
459✔
3428
                                  case TYPEENDIF:
3429
                                        level = C->lhs[level][2];
459✔
3430
                                        break;
459✔
3431
                                  case TYPESUMFIX:
384✔
3432
                                        {
3433
                                                WORD *cp = AR.CompressPointer, *op = AR.CompressPointer;
384✔
3434
                                                WORD *tlhs = C->lhs[level] + 3, *m, jlhs;
384✔
3435
                                                WORD theindex = C->lhs[level][2];
384✔
3436
                                                if ( theindex < 0 ) {        /* $-variable */
384✔
3437
#ifdef WITHPTHREADS
3438
                                                        int ddtype = -1;
3439
                                                        theindex = -theindex;
3440
                                                        d = Dollars + theindex;
3441
                                                        if ( AS.MultiThreaded ) {
3442
                                                                for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
3443
                                                                        if ( theindex == ModOptdollars[nummodopt].number ) break;
3444
                                                                }
3445
                                                                if ( nummodopt < NumModOptdollars ) {
3446
                                                                        ddtype = ModOptdollars[nummodopt].type;
3447
                                                                        if ( ddtype == MODLOCAL ) {
3448
                                                                                d = ModOptdollars[nummodopt].dstruct+AT.identity;
3449
                                                                        }
3450
                                                                        else {
3451
                                                                                LOCK(d->pthreadslockread);
3452
                                                                        }
3453
                                                                }
3454
                                                        }
3455
#else
3456
                                                        theindex = -theindex;
3457
                                                        d = Dollars + theindex;
3458
#endif
3459

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

3987
        if ( AN.TeInFun ) {        /* Match in function argument */
7,086,159✔
3988
                if ( AN.TeInFun < 0 && !AN.TeSuOut ) {
1,751,080✔
3989

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

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

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

4422
                        AT.pWorkSpace[comprev++] = AR.CompressPointer;
×
4423

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5493
                t = term + 1; t1 = term + *term; t1 -= ABS(t1[-1]);
4,761✔
5494
                while ( t < t1 ) {
14,283✔
5495
                        if ( *t == AR.PolyFun ) {
9,522✔
5496
                          t2 = t + t[1]; tt2 = t+FUNHEAD; count3 = 0;
4,761✔
5497
                          while ( tt2 < t2 ) { count3++; NEXTARG(tt2); }
14,283✔
5498
                          if ( count3 == 2 ) {
4,761✔
5499
                                count2++;
4,761✔
5500
                          }
5501
                        }
5502
                        t += t[1];
9,522✔
5503
                }
5504
                if ( count1 >= count2 ) {
4,761✔
5505
                        t = term + 1;
5506
                        while ( t < t1 ) {
14,283✔
5507
                                if ( *t == AR.PolyFun ) {
9,522✔
5508
                                        t2 = t;
4,761✔
5509
                                        t = t + t[1];
4,761✔
5510
                                        t2[2] |= (DIRTYFLAG|MUSTCLEANPRF);
4,761✔
5511
                                        t2 += FUNHEAD;
4,761✔
5512
                                        while ( t2 < t ) {
4,761✔
5513
                                                if ( *t2 > 0 ) t2[1] = DIRTYFLAG;
9,522✔
5514
                                                NEXTARG(t2);
23,805✔
5515
                                        }
5516
                                }
5517
                                else t += t[1];
4,761✔
5518
                        }
5519
                }
5520

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

5763
/*
5764
                 #] PolyFunMul : 
5765
        #] Processor :
5766
*/
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc