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

form-dev / form / 16800283938

07 Aug 2025 09:14AM UTC coverage: 52.867% (+0.01%) from 52.854%
16800283938

push

github

jodavies
Simplify 32-bit detection using stdint.h

43936 of 83106 relevant lines covered (52.87%)

2237251.77 hits per line

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

54.03
/sources/notation.c
1
/** @file notation.c
2
 * 
3
 *  Contains the functions that deal with the rewriting and manipulation
4
 *        of expressions/terms in polynomial representation.
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
          #[ Includes :
34
*/
35

36
#include "form3.h"
37

38
/*
39
          #] Includes : 
40
                 #[ NormPolyTerm :
41

42
                Brings a term to normal form.
43

44
                This routine knows objects of the following types:
45
                        SYMBOL
46
                        HAAKJE
47
                        SNUMBER
48
                        LNUMBER
49
                The SNUMBER and LNUMBER are worked into the coefficient.
50
                One of the essences here is that everything can be done in place.
51
*/
52

53
int NormPolyTerm(PHEAD WORD *term)
2,843,754✔
54
{
55
        WORD *tcoef, ncoef, *tstop, *tfill, *t, *tt;
2,843,754✔
56
        int equal, i;
2,843,754✔
57
        WORD *r1, *r2, *r3, *r4, *r5, *rfirst, rv;
2,843,754✔
58
        WORD *lnum, nnum;                /* Scratch, originally for factorials */
2,843,754✔
59
/*
60
        One: find the coefficient
61
*/
62
        tcoef = term+*term;
2,843,754✔
63
        ncoef = tcoef[-1];
2,843,754✔
64
        tstop = tcoef - ABS(tcoef[-1]);
2,843,754✔
65
        tfill = t = term + 1;
2,843,754✔
66
        rfirst = 0;
2,843,754✔
67
        if ( t >= tstop ) { return(*term); }
2,843,754✔
68
        while ( t < tstop ) {
8,461,350✔
69
                switch ( *t ) {
5,720,652✔
70
                        case SYMBOL:
5,720,652✔
71
                                if ( rfirst == 0 ) {
5,720,652✔
72
/*
73
                                        Here we only need to sort
74
                                        1: assume no equals. Bubble.
75
*/
76
                                        rfirst = t;
2,740,698✔
77
                                        r2 = rfirst+4; tt = r3 = t + t[1]; equal = 0;
2,740,698✔
78
                                        while ( r2 < r3 ) {
2,740,698✔
79
                                                r1 = r2 - 2;
×
80
                                                if ( *r2 > *r1 ) { r2 += 2; continue; }
×
81
                                                if ( *r2 == *r1 ) { r2 += 2; equal = 1; continue; }
×
82
                                                rv = *r1; *r1 = *r2; *r2 = rv;
×
83
                                                r1 -= 2; r2 -= 2; r4 = r2 + 2;
×
84
                                                while ( r1 > t ) {
×
85
                                                        if ( *r2 >= *r1 ) { r2 = r4; break; }
×
86
                                                        rv = *r1; *r1 = *r2; *r2 = rv;
×
87
                                                        r1 -= 2; r2 -= 2;
×
88
                                                }
89
                                        }
90
/*
91
                                        2: hunt down the equal objects
92
                                           postpone eliminating zero powers.
93
*/
94
                                        if ( equal ) {
2,740,698✔
95
                                                r1 = t+2; r2 = r1+2;
×
96
                                                while ( r2 < r3 ) {
×
97
                                                        if ( *r1 == *r2 ) {
×
98
                                                                r1[1] += r2[1];
×
99
                                                                r4 = r2+2;
×
100
                                                                while ( r4 < r3 ) *r2++ = *r4++;
×
101
                                                                t[1] -= 2;
×
102
                                                                r2 = r1 + 2; r3 -= 2;
×
103
                                                        }
104
                                                }
105
                                        }
106
                                }
107
                                else {
108
/*
109
                                        Here we only need to insert
110
*/
111
                                        r1 = t + 2; tt = r3 = t + t[1];
2,979,954✔
112
                                        while ( r1 < r3 ) {
5,959,908✔
113
                                                r2 = rfirst+2; r4 = rfirst + rfirst[1];
2,979,954✔
114
                                                while ( r2 < r4 ) {
8,779,104✔
115
                                                        if ( *r1 == *r2 ) {
5,800,224✔
116
                                                                r2[1] += r1[1];
18✔
117
                                                                break;
18✔
118
                                                        }
119
                                                        else if ( *r2 > *r1 ) {
5,800,206✔
120
                                                                r5 = r4;
121
                                                                while ( r5 > r2 ) { r5[1] = r5[-1]; r5[0] = r5[-2]; r5 -= 2; }
2,118✔
122
                                                                rfirst[1] += 2;
1,056✔
123
                                                                *r2 = *r1; r2[1] = r1[1];
1,056✔
124
                                                                break;
1,056✔
125
                                                        }
126
                                                        r2 += 2;
5,799,150✔
127
                                                }
128
                                                if ( r2 == r4 ) {
2,979,954✔
129
                                                        rfirst[1] += 2;
2,978,880✔
130
                                                        *r2++ = *r1++; *r2++ = *r1++;
2,978,880✔
131
                                                }
132
                                                else r1 += 2;
1,074✔
133
                                        }
134
                                }
135
                                t = tt;
136
                                break;
137
                        case HAAKJE:        /* Here we skip brackets */
×
138
                                t += t[1];
×
139
                                break;
×
140
                        case SNUMBER:
×
141
                                if ( t[2] < 0 ) {
×
142
                                        t[2] = -t[2];
×
143
                                        if ( t[3] & 1 ) ncoef = -ncoef;
×
144
                                }
145
                                else if ( t[2] == 0 ) {
×
146
                                        if ( t[3] < 0 ) goto NormInf;
×
147
                                        goto NormZero;
×
148
                                }
149
                                lnum = TermMalloc("lnum");
×
150
                                lnum[0] = t[2];
×
151
                                nnum = 1;
×
152
                                if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) ) goto FromNorm;
×
153
                                ncoef = REDLENG(ncoef);
×
154
                                if ( t[3] < 0 ) {
×
155
                                        if ( Divvy(BHEAD (UWORD *)tstop,&ncoef,(UWORD *)lnum,nnum) )
×
156
                                                goto FromNorm;
×
157
                                }
158
                                else if ( t[3] > 0 ) {
×
159
                                        if ( Mully(BHEAD (UWORD *)tstop,&ncoef,(UWORD *)lnum,nnum) )
×
160
                                                goto FromNorm;
×
161
                                }
162
                                ncoef = INCLENG(ncoef);
×
163
                                t += t[1];
×
164
                                TermFree(lnum,"lnum");
×
165
                                break;
×
166
                        case LNUMBER:
×
167
                                ncoef = REDLENG(ncoef);
×
168
                                if ( Mully(BHEAD (UWORD *)tstop,&ncoef,(UWORD *)(t+3),t[2]) ) goto FromNorm;
×
169
                                ncoef = INCLENG(ncoef);
×
170
                                t += t[1];
×
171
                                break;
×
172
                        default:
×
173
                                MLOCK(ErrorMessageLock);
×
174
                                MesPrint("Illegal code in NormPolyTerm");
×
175
                                MUNLOCK(ErrorMessageLock);
×
176
                                Terminate(-1);
×
177
                                break;
×
178
                }
179
        }
180
/*
181
        Now we try to eliminate objects to the power zero.
182
*/
183
        if ( rfirst ) {
2,740,698✔
184
                r2 = rfirst+2;
2,740,698✔
185
                r3 = rfirst + rfirst[1];
2,740,698✔
186
                while ( r2 < r3 ) {
8,461,332✔
187
                        if ( r2[1] == 0 ) {
5,720,634✔
188
                                r1 = r2 + 2;
×
189
                                while ( r1 < r3 ) { r1[-2] = r1[0]; r1[-1] = r1[1]; r1 += 2; }
×
190
                                r3 -= 2;
×
191
                                rfirst[1] -= 2;
×
192
                        }
193
                        else { r2 += 2; }
5,720,634✔
194
                }
195
                if ( rfirst[1] < 4 ) rfirst = 0;
2,740,698✔
196
        }
197
/*
198
        Finally we put the term together
199
*/
200
        if ( rfirst ) {
201
                i = rfirst[1];
202
                NCOPY(tfill,rfirst,i)
19,663,362✔
203
        }
204
        i = ABS(ncoef)-1;
2,740,698✔
205
        NCOPY(tfill,tstop,i)
8,225,418✔
206
        *tfill++ = ncoef;
2,740,698✔
207
        *term = tfill - term;
2,740,698✔
208
        return(*term);
2,740,698✔
209
NormZero:
×
210
        *term = 0;
×
211
        return(0);
×
212
NormInf:
×
213
        MLOCK(ErrorMessageLock);
×
214
        MesPrint("0^0 in NormPolyTerm");
×
215
        MUNLOCK(ErrorMessageLock);
×
216
        Terminate(-1);
×
217
        return(-1);
×
218
FromNorm:
×
219
        MLOCK(ErrorMessageLock);
×
220
        MesCall("NormPolyTerm");
×
221
        MUNLOCK(ErrorMessageLock);
×
222
        Terminate(-1);
×
223
        return(-1);
×
224
}
225

226
/*
227
                 #] NormPolyTerm : 
228
                 #[ ComparePoly :
229
*/
230
/**
231
 *        Compares two terms. The answer is:
232
 *        0        equal ( with exception of the coefficient )
233
 *        >0        term1 comes first.
234
 *        <0        term2 comes first.
235
 *        This routine should not return an error condition.
236
 *
237
 *        The address of this routine is to be put in AR.CompareRoutine when we
238
 *        want to use it for sorting.
239
 *        This makes all existing code work properly and we can just replace the
240
 *        routine on a thread by thread basis (each thread has its own AR struct).
241
 *        Don't forget to put the old routine back afterwards!
242
 *
243
 *        @param term1 First input term
244
 *        @param term2 Second input term
245
 *        @param level Not used for polynomials
246
 *        @return 0        equal ( with exception of the coefficient if level == 0. )
247
 *                >0        term1 comes first.
248
 *                <0        term2 comes first.
249
 */
250

251
#ifdef WITHCOMPAREPOLY
252

253
WORD ComparePoly(WORD *term1, WORD *term2, WORD level)
254
{
255
        WORD *t1, *t2, *t3, *t4, *tstop1, *tstop2;
256
        tstop1 = term1 + *term1;
257
        tstop1 -= ABS(tstop1[-1]);
258
        tstop2 = term2 + *term2;
259
        tstop2 -= ABS(tstop2[-1]);
260
        t1 = term1+1;
261
        t2 = term2+1;
262
        while ( t1 < tstop1 && t2 < tstop2 ) {
263
                if ( *t1 == *t2 ) {
264
                        if ( *t1 == HAAKJE ) {
265
                                if ( t1[2] != t2[2] ) return(t2[2]-t1[2]);
266
                                t1 += t1[1]; t2 += t2[1];
267
                        }
268
                        else {        /* must be type SYMBOL */
269
                                t3 = t1 + t1[1]; t4 = t2 + t2[1];
270
                                t1 += 2; t2 += 2;
271
                                while ( t1 < t3 && t2 < t4 ) {
272
                                        if ( *t1 != *t2 ) return(*t2-*t1);
273
                                        if ( t1[1] != t2[1] ) return(t2[1]-t1[1]);
274
                                        t1 += 2; t2 += 2;
275
                                }
276
                                if ( t1 < t3 ) return(-1);
277
                                if ( t2 < t4 ) return(1);
278
                        }
279
                }
280
                else return(*t2-*t1);
281
        }
282
        if ( t1 < tstop1 ) return(-1);
283
        if ( t2 < tstop2 ) return(1);
284
        return(0);
285
}
286

287
#endif
288

289
/*
290
                 #] ComparePoly : 
291
                 #[ ConvertToPoly :
292
*/
293
/**
294
 *                Converts a generic term to polynomial notation in which there are
295
 *                only symbols and brackets.
296
 *                During conversion there will be only symbols. Brackets are stripped.
297
 *                Objects that need 'translation' are put inside a special compiler
298
 *                buffer and represented by a symbol. The numbering of the extra
299
 *                symbols is down from the maximum. In principle there can be a
300
 *                problem when running into the already assigned ones.
301
 *                The output overwrites the input.
302
 *                comlist is the compiler code. Used for the various options
303
 */
304

305
static int FirstWarnConvertToPoly = 1;
306

307
int ConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD *comlist, WORD par)
44,244✔
308
{
309
        WORD *tout, *tstop, ncoef, *t, *r, *tt, *ttwo = 0;
44,244✔
310
        int i, action = 0;
44,244✔
311
        tt = term + *term;
44,244✔
312
        ncoef = ABS(tt[-1]);
44,244✔
313
        tstop = tt - ncoef;
44,244✔
314
        tout = outterm+1;
44,244✔
315
        t = term + 1;
44,244✔
316
        if ( comlist[2] == DOALL ) {
44,244✔
317
          while ( t < tstop ) {
88,560✔
318
                if ( *t == SYMBOL ) {
44,316✔
319
                        r = t+2;
44,184✔
320
                        t += t[1];
44,184✔
321
                        while ( r < t ) {
196,236✔
322
                                if ( r[1] > 0 ) {
152,052✔
323
                                        *tout++ = SYMBOL;
152,040✔
324
                                        *tout++ = 4;
152,040✔
325
                                        *tout++ = r[0];
152,040✔
326
                                        *tout++ = r[1];
152,040✔
327
                                }
328
                                else {
329
                                        tout[1] = SYMBOL;
12✔
330
                                        tout[2] = 4;
12✔
331
                                        tout[3] = r[0];
12✔
332
                                        tout[4] = -1;
12✔
333
                                        i = FindSubterm(tout+1);
12✔
334
                                        *tout++ = SYMBOL;
12✔
335
                                        *tout++ = 4;
12✔
336
                                        *tout++ = MAXVARIABLES-i;
12✔
337
                                        *tout++ = -r[1];
12✔
338
                                        action = 1;
12✔
339
                                }
340
                                r += 2;
152,052✔
341
                        }
342
                }
343
                else if ( *t == DOTPRODUCT ) {
344
                        r = t + 2;
×
345
                        t += t[1];
×
346
                        while ( r < t ) {
×
347
                                tout[1] = DOTPRODUCT;
×
348
                                tout[2] = 5;
×
349
                                tout[3] = r[0];
×
350
                                tout[4] = r[1];
×
351
                                if ( r[2] < 0 ) {
×
352
                                        tout[5] = -1;
×
353
                                }
354
                                else {
355
                                        tout[5] = 1;
×
356
                                }
357
                                i = FindSubterm(tout+1);
×
358
                                *tout++ = SYMBOL;
×
359
                                *tout++ = 4;
×
360
                                *tout++ = MAXVARIABLES-i;
×
361
                                *tout++ = ABS(r[2]);
×
362
                                r += 3;
×
363
                                action = 1;
×
364
                        }
365
                }
366
                else if ( *t == VECTOR ) {
367
                        r = t + 2;
×
368
                        t += t[1];
×
369
                        while ( r < t ) {
×
370
                                tout[1] = VECTOR;
×
371
                                tout[2] = 4;
×
372
                                tout[3] = r[0];
×
373
                                tout[4] = r[1];
×
374
                                i = FindSubterm(tout+1);
×
375
                                *tout++ = SYMBOL;
×
376
                                *tout++ = 4;
×
377
                                *tout++ = MAXVARIABLES-i;
×
378
                                *tout++ = 1;
×
379
                                r += 2;
×
380
                                action = 1;
×
381
                        }
382
                }
383
                else if ( *t == INDEX ) {
384
                        r = t + 2;
×
385
                        t += t[1];
×
386
                        while ( r < t ) {
×
387
                                tout[1] = INDEX;
×
388
                                tout[2] = 3;
×
389
                                tout[3] = r[0];
×
390
                                i = FindSubterm(tout+1);
×
391
                                *tout++ = SYMBOL;
×
392
                                *tout++ = 4;
×
393
                                *tout++ = MAXVARIABLES-i;
×
394
                                *tout++ = 1;
×
395
                                r++;
×
396
                                action = 1;
×
397
                        }
398
                }
399
                else if ( *t == HAAKJE) {
400
                        if ( par ) { 
24✔
401
                                tout[0] = 1; tout[1] = 1; tout[2] = 3;
24✔
402
                                *outterm = (tout+3)-outterm;
24✔
403
                                if ( NormPolyTerm(BHEAD outterm) < 0 ) return(-1);
24✔
404
                                tout = outterm + *outterm;
24✔
405
                                tout -= 3;
24✔
406
                                i = t[1]; NCOPY(tout,t,i);
96✔
407
                                ttwo = tout-1;
24✔
408
                        }
409
                        else { t += t[1]; }
×
410
                }
411
                else if ( *t >= FUNCTION ) {
108✔
412
                        i = FindSubterm(t);
108✔
413
                        t += t[1];
108✔
414
                        *tout++ = SYMBOL;
108✔
415
                        *tout++ = 4;
108✔
416
                        *tout++ = MAXVARIABLES-i;
108✔
417
                        *tout++ = 1;
108✔
418
                        action = 1;
108✔
419
                }
420
                else {
421
                        if ( FirstWarnConvertToPoly ) {
×
422
                                MLOCK(ErrorMessageLock);
×
423
                                MesPrint("Illegal object in conversion to polynomial notation");
×
424
                                MUNLOCK(ErrorMessageLock);
×
425
                                FirstWarnConvertToPoly = 0;
×
426
                        }
427
                        return(-1);
×
428
                }
429
          }
430
          NCOPY(tout,tstop,ncoef)
176,976✔
431
          if ( ttwo ) {
44,244✔
432
                WORD hh = *ttwo;
24✔
433
                *ttwo = tout-ttwo;
24✔
434
                if ( ( i = NormPolyTerm(BHEAD ttwo) ) >= 0 ) i = action;
24✔
435
                tout = ttwo + *ttwo;
24✔
436
                *ttwo = hh;
24✔
437
                *outterm = tout - outterm;
24✔
438
          }
439
          else {
440
                *outterm = tout-outterm;
44,220✔
441
                if ( ( i = NormPolyTerm(BHEAD outterm) ) >= 0 ) i = action;
44,220✔
442
          }
443
        }
444
        else if ( comlist[2] == ONLYFUNCTIONS ) {
×
445
          while ( t < tstop ) {
×
446
                if ( *t >= FUNCTION ) {
×
447
                        if ( comlist[1] == 3 ) {
×
448
                                i = FindSubterm(t);
×
449
                                t += t[1];
×
450
                                *tout++ = SYMBOL;
×
451
                                *tout++ = 4;
×
452
                                *tout++ = MAXVARIABLES-i;
×
453
                                *tout++ = 1;
×
454
                                action = 1;
×
455
                        }
456
                        else {
457
                                for ( i = 3; i < comlist[1]; i++ ) {
×
458
                                        if ( *t == comlist[i] ) break;
×
459
                                }
460
                                if ( i < comlist[1] ) {
×
461
                                        i = FindSubterm(t);
×
462
                                        t += t[1];
×
463
                                        *tout++ = SYMBOL;
×
464
                                        *tout++ = 4;
×
465
                                        *tout++ = MAXVARIABLES-i;
×
466
                                        *tout++ = 1;
×
467
                                        action = 1;
×
468
                                }
469
                                else {
470
                                        i = t[1]; NCOPY(tout,t,i);
×
471
                                }
472
                        }
473
                }
474
                else {
475
                        i = t[1]; NCOPY(tout,t,i);
×
476
                }
477
          }
478
          NCOPY(tout,tstop,ncoef)
×
479
          *outterm = tout-outterm;
×
480
          Normalize(BHEAD outterm);
×
481
          i = action;
×
482
        }
483
        else {
484
                MLOCK(ErrorMessageLock);
×
485
                MesPrint("Illegal internal code in conversion to polynomial notation");
×
486
                MUNLOCK(ErrorMessageLock);
×
487
                i = -1;
×
488
        }
489
        return(i);
490
}
491

492
/*
493
                 #] ConvertToPoly : 
494
                 #[ LocalConvertToPoly :
495
*/
496
/**
497
 *                Converts a generic term to polynomial notation in which there are
498
 *                only symbols and brackets.
499
 *                During conversion there will be only symbols. Brackets are stripped.
500
 *                Objects that need 'translation' are put inside a special compiler
501
 *                buffer and represented by a symbol. The numbering of the extra
502
 *                symbols is down from the maximum. In principle there can be a
503
 *                problem when running into the already assigned ones.
504
 *                This uses the FindTree for searching in the global tree and
505
 *                then looks further in the AT.ebufnum. This allows fully parallel
506
 *                processing. Hence we need no locks. Cannot be used in the same
507
 *                module as ConvertToPoly.
508
 */
509

510
int LocalConvertToPoly(PHEAD WORD *term, WORD *outterm, WORD startebuf, WORD par)
2,799,486✔
511
{
512
        WORD *tout, *tstop, ncoef, *t, *r, *tt, *ttwo = 0;
2,799,486✔
513
        int i, action = 0;
2,799,486✔
514
        tt = term + *term;
2,799,486✔
515
        ncoef = ABS(tt[-1]);
2,799,486✔
516
        tstop = tt - ncoef;
2,799,486✔
517
        tout = outterm+1;
2,799,486✔
518
        t = term + 1;
2,799,486✔
519
        while ( t < tstop ) {
5,497,116✔
520
                if ( *t == SYMBOL ) {
2,697,630✔
521
                        r = t+2;
2,695,830✔
522
                        t += t[1];
2,695,830✔
523
                        while ( r < t ) {
8,262,774✔
524
                                if ( r[1] > 0 ) {
5,566,944✔
525
                                        *tout++ = SYMBOL;
5,566,614✔
526
                                        *tout++ = 4;
5,566,614✔
527
                                        *tout++ = r[0];
5,566,614✔
528
                                        *tout++ = r[1];
5,566,614✔
529
                                }
530
                                else {
531
                                        tout[1] = SYMBOL;
330✔
532
                                        tout[2] = 4;
330✔
533
                                        tout[3] = r[0];
330✔
534
                                        tout[4] = -1;
330✔
535
                                        i = FindLocalSubterm(BHEAD tout+1,startebuf);
330✔
536
                                        *tout++ = SYMBOL;
330✔
537
                                        *tout++ = 4;
330✔
538
                                        *tout++ = MAXVARIABLES-i;
330✔
539
                                        *tout++ = -r[1];
330✔
540
                                        action = 1;
330✔
541
                                }
542
                                r += 2;
5,566,944✔
543
                        }
544
                }
545
                else if ( *t == DOTPRODUCT ) {
546
                        r = t + 2;
×
547
                        t += t[1];
×
548
                        while ( r < t ) {
×
549
                                tout[1] = DOTPRODUCT;
×
550
                                tout[2] = 5;
×
551
                                tout[3] = r[0];
×
552
                                tout[4] = r[1];
×
553
                                if ( r[2] < 0 ) {
×
554
                                        tout[5] = -1;
×
555
                                }
556
                                else {
557
                                        tout[5] = 1;
×
558
                                }
559
                                i = FindLocalSubterm(BHEAD tout+1,startebuf);
×
560
                                *tout++ = SYMBOL;
×
561
                                *tout++ = 4;
×
562
                                *tout++ = MAXVARIABLES-i;
×
563
                                *tout++ = ABS(r[2]);
×
564
                                r += 3;
×
565
                                action = 1;
×
566
                        }
567
                }
568
                else if ( *t == VECTOR ) {
569
                        r = t + 2;
×
570
                        t += t[1];
×
571
                        while ( r < t ) {
×
572
                                tout[1] = VECTOR;
×
573
                                tout[2] = 4;
×
574
                                tout[3] = r[0];
×
575
                                tout[4] = r[1];
×
576
                                i = FindLocalSubterm(BHEAD tout+1,startebuf);
×
577
                                *tout++ = SYMBOL;
×
578
                                *tout++ = 4;
×
579
                                *tout++ = MAXVARIABLES-i;
×
580
                                *tout++ = 1;
×
581
                                r += 2;
×
582
                                action = 1;
×
583
                        }
584
                }
585
                else if ( *t == INDEX ) {
586
                        r = t + 2;
×
587
                        t += t[1];
×
588
                        while ( r < t ) {
×
589
                                tout[1] = INDEX;
×
590
                                tout[2] = 3;
×
591
                                tout[3] = r[0];
×
592
                                i = FindLocalSubterm(BHEAD tout+1,startebuf);
×
593
                                *tout++ = SYMBOL;
×
594
                                *tout++ = 4;
×
595
                                *tout++ = MAXVARIABLES-i;
×
596
                                *tout++ = 1;
×
597
                                r++;
×
598
                                action = 1;
×
599
                        }
600
                }
601
                else if ( *t == HAAKJE) {
602
                        if ( par ) { 
252✔
603
                                tout[0] = 1; tout[1] = 1; tout[2] = 3;
×
604
                                *outterm = (tout+3)-outterm;
×
605
                                if ( NormPolyTerm(BHEAD outterm) < 0 ) return(-1);
×
606
                                tout = outterm + *outterm;
×
607
                                tout -= 3;
×
608
                                i = t[1]; NCOPY(tout,t,i);
×
609
                                ttwo = tout-1;
×
610
                        }
611
                        else { t += t[1]; }
252✔
612
                }
613
                else if ( *t >= FUNCTION ) {
1,548✔
614
                        i = FindLocalSubterm(BHEAD t,startebuf);
1,548✔
615
                        t += t[1];
1,548✔
616
                        *tout++ = SYMBOL;
1,548✔
617
                        *tout++ = 4;
1,548✔
618
                        *tout++ = MAXVARIABLES-i;
1,548✔
619
                        *tout++ = 1;
1,548✔
620
                        action = 1;
1,548✔
621
                }
622
                else {
623
                        if ( FirstWarnConvertToPoly ) {
×
624
                                MLOCK(ErrorMessageLock);
×
625
                                MesPrint("Illegal object in conversion to polynomial notation");
×
626
                                MUNLOCK(ErrorMessageLock);
×
627
                                FirstWarnConvertToPoly = 0;
×
628
                        }
629
                        return(-1);
×
630
                }
631
        }
632
        NCOPY(tout,tstop,ncoef)
11,201,352✔
633
        if ( ttwo ) {
2,799,486✔
634
                WORD hh = *ttwo;
×
635
                *ttwo = tout-ttwo;
×
636
                if ( ( i = NormPolyTerm(BHEAD ttwo) ) >= 0 ) i = action;
×
637
                tout = ttwo + *ttwo;
×
638
                *ttwo = hh;
×
639
                *outterm = tout - outterm;
×
640
        }
641
        else {
642
                *outterm = tout-outterm;
2,799,486✔
643
                if ( ( i = NormPolyTerm(BHEAD outterm) ) >= 0 ) i = action;
2,799,486✔
644
        }
645
        return(i);
646
}
647

648
/*
649
                 #] LocalConvertToPoly : 
650
                 #[ ConvertFromPoly :
651

652
                Converts a generic term from polynomial notation to the original
653
                in which the extra symbols have been replaced by their values.
654
                The output is in outterm.
655
                We only deal with the extra symbols in the range from < i <= to
656
                The output has to be sent to TestSub because it may contain
657
                subexpressions when extra symbols have been replaced.
658
*/
659

660
int ConvertFromPoly(PHEAD WORD *term, WORD *outterm, WORD from, WORD to, WORD offset, WORD par)
26,886✔
661
{
662
        WORD *tout, *tstop, *tstop1, ncoef, *t, *r, *tt;
26,886✔
663
        int i;
26,886✔
664
/*        first = 1; */
665
        tt = term + *term;
26,886✔
666
        tout = outterm+1;
26,886✔
667
        ncoef = ABS(tt[-1]);
26,886✔
668
        tstop = tt - ncoef;
26,886✔
669
/*
670
        r = t = term + 1;
671
        while ( t < tstop ) {
672
                if ( *t == SYMBOL ) {
673
                        tstop1 = t + t[1];
674
                        tt = t + 2;
675
                        while ( tt < tstop1 ) {
676
                                if ( ( *tt < MAXVARIABLES - to )
677
                                  || ( *tt >= MAXVARIABLES - from ) ) {
678
                                        tt += 2;
679
                                }
680
                                else break;
681
                        }
682
                        if ( tt >= tstop1 ) { t = tstop1; continue; }
683
                        while ( r < t ) *tout++ = *r++;
684
                        t += 2;
685
                        first = 0;
686
                        while ( t < tstop1 ) {
687
                                if ( ( *t < MAXVARIABLES - to )
688
                                  || ( *t >= MAXVARIABLES - from ) ) {
689
                                        *tout++ = SYMBOL;
690
                                        *tout++ = 4;
691
                                        *tout++ = *t++;
692
                                        *tout++ = *t++;
693
                                }
694
                                else {
695
                                        *tout++ = SUBEXPRESSION;
696
                                        *tout++ = SUBEXPSIZE;
697
                                        *tout++ = MAXVARIABLES - *t++ + offset;
698
                                        *tout++ = *t++;
699
                                        if ( par ) *tout++ = AT.ebufnum;
700
                                        else       *tout++ = AM.sbufnum;
701
                                        FILLSUB(tout)
702
                                }
703
                        }
704
                        r = t;
705
                }
706
                else {
707
                        t += t[1];
708
                }
709
        }
710
        if ( first ) {
711
                i = *term; t = term;
712
                NCOPY(outterm,t,i);
713
                return(*term);
714
        }
715
        while ( r < t ) *tout++ = *r++;
716
        NCOPY(tout,tstop,ncoef)
717
        *outterm = tout-outterm;
718
*/
719
        t = term + 1;
26,886✔
720
        while ( t < tstop ) {
53,556✔
721
                if ( *t == SYMBOL ) {
26,670✔
722
                        tstop1 = t + t[1];
26,670✔
723
                        tt = t + 2;
26,670✔
724
                        while ( tt < tstop1 ) {
91,950✔
725
                                if ( ( *tt < MAXVARIABLES - to )
65,280✔
726
                                  || ( *tt >= MAXVARIABLES - from ) ) {
19,974✔
727
                                        tt += 2;
45,306✔
728
                                }
729
                                else {
730
                                        *tout++ = SUBEXPRESSION;
19,974✔
731
                                        *tout++ = SUBEXPSIZE;
19,974✔
732
                                        *tout++ = MAXVARIABLES - *tt++ + offset;
19,974✔
733
                                        *tout++ = *tt++;
19,974✔
734
                                        if ( par ) *tout++ = AT.ebufnum;
19,974✔
735
                                        else       *tout++ = AM.sbufnum;
9,042✔
736
                                        FILLSUB(tout)
737
                                }
738
                        }
739
                        r = tout; t += 2;
26,670✔
740
                        *tout++ = SYMBOL; *tout++ = 0;
26,670✔
741
                        while ( t < tstop1 ) {
91,950✔
742
                                if ( ( *t < MAXVARIABLES - to )
65,280✔
743
                                  || ( *t >= MAXVARIABLES - from ) ) {
19,974✔
744
                                        *tout++ = *t++;
45,306✔
745
                                        *tout++ = *t++;
45,306✔
746
                                }
747
                                else { t += 2; }
19,974✔
748
                        }
749
                        r[1] = tout - r;
26,670✔
750
                        if ( r[1] <= 2 ) tout = r;
26,670✔
751
                }
752
                else {
753
                        i = t[1]; NCOPY(tout,t,i)
×
754
                }
755
        }
756
        NCOPY(tout,tstop,ncoef)
199,740✔
757
        *outterm = tout-outterm;
26,886✔
758
        return(*outterm);
26,886✔
759
}
760

761
/*
762
                 #] ConvertFromPoly : 
763
                 #[ FindSubterm :
764

765
                In this routine we look up a variable.
766
                If we don't find it we will enter it in the subterm compiler buffer
767
                Searching is by tree structure.
768
                Adding changes the tree.
769

770
                Notice that in TFORM we should be in sequential mode.
771
*/
772

773
int FindSubterm(WORD *subterm)
120✔
774
{
775
        WORD old[5], *ss, *term;
120✔
776
        int number;
120✔
777
        CBUF *C = cbuf + AM.sbufnum;
120✔
778
        LONG oldCpointer;
120✔
779
        term = subterm-1;
120✔
780
        ss = subterm+subterm[1];
120✔
781
/*
782
                Convert to proper term
783
*/
784
        old[0] = *term; old[1] = ss[0]; old[2] = ss[1]; old[3] = ss[2]; old[4] = ss[3];
120✔
785
        ss[0] = 1; ss[1] = 1; ss[2] = 3; ss[3] = 0; *term = subterm[1]+4;
120✔
786
/*
787
                We may have to add the term to the compiler
788
                buffer and then to the tree. This cannot be done in parallel and
789
                hence we have to set a lock.
790
*/
791
        LOCK(AM.sbuflock);
120✔
792

793
        oldCpointer = C->Pointer-C->Buffer; /* Offset of course !!!!!*/
120✔
794
        AddRHS(AM.sbufnum,1);
120✔
795
        AddNtoC(AM.sbufnum,*term,term,8);
120✔
796
        AddToCB(C,0)
120✔
797
/*
798
                See whether we have this one already. If not, insert it in the tree.
799
*/
800
        number = InsTree(AM.sbufnum,C->numrhs);
120✔
801
/*
802
                Restore old values and return what is needed.
803
*/
804
        if ( number < (C->numrhs) ) {        /* It existed already */
120✔
805
                C->Pointer = oldCpointer + C->Buffer;
18✔
806
                C->numrhs--;
18✔
807
        }
808
    else {
809
                GETIDENTITY
68✔
810
                WORD dim = DimensionSubterm(subterm);
102✔
811

812
                if ( dim == -MAXPOSITIVE ) {        /* Give error message but continue */
102✔
813
                        WORD *old = AN.currentTerm;
×
814
                        AN.currentTerm = term;
×
815
                        MLOCK(ErrorMessageLock);
×
816
                        MesPrint("Dimension out of range in %t");
×
817
                        MUNLOCK(ErrorMessageLock);
×
818
                        AN.currentTerm = old;
×
819
                }
820
/*
821
                Store the dimension
822
*/
823
                C->dimension[number] = dim;
102✔
824
        }
825
        UNLOCK(AM.sbuflock);
120✔
826

827
        *term = old[0]; ss[0] = old[1]; ss[1] = old[2]; ss[2] = old[3]; ss[3] = old[4];
120✔
828
        return(number);
120✔
829
}
830

831
/*
832
                 #] FindSubterm : 
833
                 #[ FindLocalSubterm :
834

835
                In this routine we look up a variable.
836
                If we don't find it we will enter it in the subterm compiler buffer
837
                Searching is by tree structure.
838
                Adding changes the tree.
839

840
                Notice that in TFORM we should be in sequential mode.
841
*/
842

843
int FindLocalSubterm(PHEAD WORD *subterm, WORD startebuf)
1,878✔
844
{
845
        WORD old[5], *ss, *term, i, j, *t1, *t2;
1,878✔
846
        int number;
1,878✔
847
        CBUF *C = cbuf + AT.ebufnum;
1,878✔
848
        term = subterm-1;
1,878✔
849
        ss = subterm+subterm[1];
1,878✔
850
/*
851
                Convert to proper term
852
*/
853
        old[0] = *term; old[1] = ss[0]; old[2] = ss[1]; old[3] = ss[2]; old[4] = ss[3];
1,878✔
854
        ss[0] = 1; ss[1] = 1; ss[2] = 3; ss[3] = 0; *term = subterm[1]+4;
1,878✔
855
/*
856
                First see whether we have this one already in the global buffer.
857
*/
858
        number = FindTree(AM.sbufnum,term);
1,878✔
859
        if ( number > 0 ) goto wearehappy;
1,878✔
860
/*
861
        Now look whether it is in the ebufnum between startebuf and numrhs
862
        Note however that we need an offset of (numxsymbol-startebuf)
863
*/
864
        for ( i = startebuf+1; i <= C->numrhs; i++ ) {
27,222✔
865
                t1 = C->rhs[i]; t2 = term;
26,826✔
866
                if ( *t1 == *t2 ) {
26,826✔
867
                        j = *t1;
868
                        while ( *t1 == *t2 && j > 0 ) { t1++; t2++; j--; }
166,560✔
869
                        if ( j <= 0 ) {
25,344✔
870
                                number = i-startebuf+numxsymbol;
1,482✔
871
                                goto wearehappy;
1,482✔
872
                        }
873
                }
874
        }
875
/*
876
        Now we have to add it to cbuf[AT.ebufnum]
877
*/
878
        AddRHS(AT.ebufnum,1);
396✔
879
        AddNtoC(AT.ebufnum,*term,term,9);
396✔
880
        AddToCB(C,0)
396✔
881
        number = C->numrhs-startebuf+numxsymbol;
396✔
882
wearehappy:
1,878✔
883
        *term = old[0]; ss[0] = old[1]; ss[1] = old[2]; ss[2] = old[3]; ss[3] = old[4];
1,878✔
884
        return(number);
1,878✔
885
}
886

887
/*
888
                 #] FindLocalSubterm : 
889
                 #[ PrintSubtermList :
890

891
                Prints all the expressions in the subterm compiler buffer.
892
                The format is such that they give definitions of the temporary
893
                variables of which the contents are stored in this buffer.
894
                These variables have the names Z_123 etc.
895
*/
896

897
void PrintSubtermList(int from,int to)
30✔
898
{
899
        UBYTE buffer[80], *out, outbuffer[300];
30✔
900
        int first, i, ii, inc = 1;
30✔
901
        WORD *term;
30✔
902
        CBUF *C = cbuf + AM.sbufnum;
30✔
903
/*
904
        if ( to < from ) inc = -1;
905
        if ( to == from ) inc = 0;
906
*/
907
        if ( from <= to ) {
30✔
908
                inc = 1; to += inc;
30✔
909
        }
910
        else {
911
                inc = -1; to += inc;
×
912
        }
913
        AO.OutFill = AO.OutputLine = outbuffer;
30✔
914
        AO.OutStop = AO.OutputLine+AC.LineLength;
30✔
915
        AO.IsBracket = 0;
30✔
916
        AO.OutSkip = 3;
30✔
917

918
        if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
30✔
919
                TokenToLine((UBYTE *)"      ");
18✔
920
                AO.OutSkip = 7;
18✔
921
        }
922
        else if ( ( AO.Optimize.debugflags & 1 ) == 1 ) {}
12✔
923
        else if ( AO.OutSkip > 0 ) {
924
                for ( i = 0; i < AO.OutSkip; i++ ) TokenToLine((UBYTE *)" ");
48✔
925
        }
926
        i = from;
927
        do {
66✔
928
                if ( ( AO.Optimize.debugflags & 1 ) == 1 ) {
66✔
929
                        TokenToLine((UBYTE *)"id ");
×
930
                        for ( ii = 3; ii < AO.OutSkip; ii++ ) TokenToLine((UBYTE *)" ");
×
931
                }
932
/*
933
                if ( AC.OutputMode == NORMALFORMAT ) {
934
                        TokenToLine((UBYTE *)"id ");
935
                }
936
*/
937
                else if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {}
66✔
938
                else { TokenToLine((UBYTE *)" "); }
18✔
939

940
                out = StrCopy((UBYTE *)AC.extrasym,buffer);
66✔
941
                if ( AC.extrasymbols == 0 ) {
66✔
942
                        out = NumCopy(i,out);
18✔
943
                        out = StrCopy((UBYTE *)"_",out);
18✔
944
                }
945
                else if ( AC.extrasymbols == 1 ) {
48✔
946
                        out = AddArrayIndex(i,out);
48✔
947
                }
948
                out = StrCopy((UBYTE *)"=",out);
66✔
949
                TokenToLine(buffer);
66✔
950
                term = C->rhs[i];
66✔
951
                first = 1;
66✔
952
                if ( *term == 0 ) {
66✔
953
                        out = StrCopy((UBYTE *)"0",buffer);
×
954
                        if ( AC.OutputMode != FORTRANMODE && AC.OutputMode != PFORTRANMODE ) {
×
955
                                out = StrCopy((UBYTE *)";",out);
×
956
                        }
957
                        TokenToLine(buffer);
×
958
                }
959
                else {
960
                        while ( *term ) {
132✔
961
                                if ( WriteInnerTerm(term,first) ) Terminate(-1);
66✔
962
                                term += *term;
66✔
963
                                first = 0;
66✔
964
                        }
965
                        if ( AC.OutputMode != FORTRANMODE && AC.OutputMode != PFORTRANMODE ) {
66✔
966
                                out = StrCopy((UBYTE *)";",buffer);
18✔
967
                                TokenToLine(buffer);
18✔
968
                        }
969
                }
970
/*
971
                There is a problem with FiniLine because it prepares for a
972
                continuation line in fortran mode.
973
                But the next statement should start on a blank line.
974
*/
975
/*
976
                FiniLine();
977
                if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
978
                        AO.OutFill = AO.OutputLine;
979
                        TokenToLine((UBYTE *)"      ");
980
                        AO.OutSkip = 7;
981
                }
982
*/
983
                if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
66✔
984
                        AO.OutSkip = 6;
48✔
985
                        FiniLine();
48✔
986
                        AO.OutSkip = 7;
48✔
987
                }
988
                else {
989
                        FiniLine();
18✔
990
                }
991
                i += inc;
66✔
992
        } while ( i != to );
66✔
993
}
30✔
994

995
/*
996
                 #] PrintSubtermList : 
997
                 #[ PrintExtraSymbol :
998

999
                Prints the definition of extra symbol num as the contents
1000
                of the expression in terms.
1001
                The parameter par has three options:
1002
                        EXTRASYMBOL      num is interpreted as the number of an extra symbol
1003
                        REGULARSYMBOL    num is interpreted as the number of a symbol.
1004
                                         It could still be an extra symbol.
1005
                        EXPRESSIONNUMBER num is the number of an expression.
1006
                terms contains the rhs expression.
1007
*/
1008

1009
void PrintExtraSymbol(int num, WORD *terms,int par)
276✔
1010
{
1011
        UBYTE buffer[80], *out, outbuffer[300];
276✔
1012
        int first, i;
276✔
1013
        WORD *term;
276✔
1014

1015
        AO.OutFill = AO.OutputLine = outbuffer;
276✔
1016
        AO.OutStop = AO.OutputLine+AC.LineLength;
276✔
1017
        AO.IsBracket = 0;
276✔
1018

1019
        if ( AC.OutputMode == FORTRANMODE || AC.OutputMode == PFORTRANMODE ) {
276✔
1020
                TokenToLine((UBYTE *)"      ");
120✔
1021
                AO.OutSkip = 7;
120✔
1022
        }
1023
        else if ( ( AO.Optimize.debugflags & 1 ) == 1 ) {
156✔
1024
                TokenToLine((UBYTE *)"id ");
×
1025
                for ( i = 3; i < AO.OutSkip; i++ ) TokenToLine((UBYTE *)" ");
×
1026
        }
1027
        else if ( AO.OutSkip > 0 ) {
156✔
1028
                for ( i = 0; i < AO.OutSkip; i++ ) TokenToLine((UBYTE *)" ");
696✔
1029
        }
1030
        out = buffer;
276✔
1031
        switch ( par ) {
276✔
1032
                case REGULARSYMBOL:
×
1033
                        if ( num >= MAXVARIABLES-cbuf[AM.sbufnum].numrhs ) {
×
1034
                                num = MAXVARIABLES-num;
×
1035
                        }
1036
                        else {
1037
                                out = StrCopy(FindSymbol(num),out);
×
1038
/*                                out = StrCopy(VARNAME(symbols,num),out); */
1039
                                break;
×
1040
                        }
1041
                        /* fall through */
1042
                case EXTRASYMBOL:
1043
                        out = StrCopy(FindExtraSymbol(num),out);
240✔
1044
/*
1045
                        out = StrCopy((UBYTE *)AC.extrasym,out);
1046
                        if ( AC.extrasymbols == 0 ) {
1047
                                out = NumCopy(num,out);
1048
                                out = StrCopy((UBYTE *)"_",out);
1049
                        }
1050
                        else if ( AC.extrasymbols == 1 ) {
1051
                                out = AddArrayIndex(num,out);
1052
                        }
1053
*/
1054
                        break;
240✔
1055
                case EXPRESSIONNUMBER:
36✔
1056
                        out = StrCopy(EXPRNAME(num),out);
36✔
1057
                        break;
36✔
1058
                default:
×
1059
                        MesPrint("Illegal option in PrintExtraSymbol");
×
1060
                        Terminate(-1);
×
1061
        }
1062
        out = StrCopy((UBYTE *)"=",out);
276✔
1063
        TokenToLine(buffer);
276✔
1064
        term = terms;
276✔
1065
        first = 1;
276✔
1066
        if ( *term == 0 ) {
276✔
1067
                out = StrCopy((UBYTE *)"0",buffer);
×
1068
                TokenToLine(buffer);
×
1069
        }
1070
        else {
1071
                while ( *term ) {
714✔
1072
                        if ( WriteInnerTerm(term,first) ) Terminate(-1);
438✔
1073
                        term += *term;
438✔
1074
                        first = 0;
438✔
1075
                }
1076
        }
1077
        if ( AC.OutputMode != FORTRANMODE && AC.OutputMode != PFORTRANMODE ) {
276✔
1078
                out = StrCopy((UBYTE *)";",buffer);
156✔
1079
                TokenToLine(buffer);
156✔
1080
        }
1081
        FiniLine();
276✔
1082
}
276✔
1083

1084
/*
1085
                 #] PrintExtraSymbol : 
1086
                 #[ FindSubexpression :
1087

1088
                In this routine we look up a subexpression.
1089
                If we don't find it we will enter it in the subterm compiler buffer
1090
                Searching is by tree structure.
1091
                Adding changes the tree.
1092

1093
                Notice that in TFORM we should be in sequential mode.
1094
*/
1095

1096
int FindSubexpression(WORD *subexpr)
9,114✔
1097
{
1098
        WORD *term;
9,114✔
1099
        int number;
9,114✔
1100
        CBUF *C = cbuf + AM.sbufnum;
9,114✔
1101
        LONG oldCpointer;
9,114✔
1102

1103
        term = subexpr;
9,114✔
1104
        while ( *term ) term += *term;
27,234✔
1105
        number = term - subexpr;
9,114✔
1106
/*
1107
                We may have to add the subexpression to the tree.
1108
                This requires a lock.
1109
*/
1110
        LOCK(AM.sbuflock);
9,114✔
1111

1112
        oldCpointer = C->Pointer-C->Buffer; /* Offset of course !!!!!*/
9,114✔
1113
        AddRHS(AM.sbufnum,1);
9,114✔
1114
/*
1115
                Add the terms to the compiler buffer. Paste on a zero.
1116
*/
1117
        AddNtoC(AM.sbufnum,number,subexpr,10);
9,114✔
1118
        AddToCB(C,0)
9,114✔
1119
/*
1120
                See whether we have this one already. If not, insert it in the tree.
1121
*/
1122
        number = InsTree(AM.sbufnum,C->numrhs);
9,114✔
1123
/*
1124
                Restore old values and return what is needed.
1125
*/
1126
        if ( number < (C->numrhs) ) {        /* It existed already */
9,114✔
1127
                C->Pointer = oldCpointer + C->Buffer;
4,800✔
1128
                C->numrhs--;
4,800✔
1129
        }
1130
    else {
1131
                GETIDENTITY
2,876✔
1132
                WORD dim = DimensionExpression(BHEAD subexpr);
4,314✔
1133
/*
1134
                Store the dimension
1135
*/
1136
                C->dimension[number] = dim;
4,314✔
1137
        }
1138

1139
        UNLOCK(AM.sbuflock);
9,114✔
1140

1141
        return(number);
9,114✔
1142
}
1143

1144
/*
1145
                 #] FindSubexpression : 
1146
                 #[ ExtraSymFun :
1147
*/
1148

1149
int ExtraSymFun(PHEAD WORD *term,WORD level)
×
1150
{
1151
        WORD *oldworkpointer = AT.WorkPointer;
×
1152
        WORD *termout, *t1, *t2, *t3, *tstop, *tend, i;
×
1153
        int retval = 0;
×
1154
        tend = termout = term + *term;
×
1155
        tstop = tend - ABS(tend[-1]);
×
1156
        t3 = t1 = term+1; t2 = termout+1;
×
1157
/*
1158
        First refind the function(s). There is at least one.
1159
*/
1160
        while ( t1 < tstop ) {
×
1161
                if ( *t1 == EXTRASYMFUN && t1[1] == FUNHEAD+2 ) {
×
1162
                        if ( t1[FUNHEAD] == -SNUMBER && t1[FUNHEAD+1] <= numxsymbol
×
1163
                                                        && t1[FUNHEAD+1] > 0 ) {
×
1164
                                i = t1[FUNHEAD+1];
×
1165
                        }
1166
                        else if ( t1[FUNHEAD] == -SYMBOL && t1[FUNHEAD+1] < MAXVARIABLES 
×
1167
                                                        && t1[FUNHEAD+1] >= MAXVARIABLES-numxsymbol ) {
×
1168
                                i = MAXVARIABLES - t1[FUNHEAD+1];
×
1169
                        }
1170
                        else goto nocase;
×
1171
                        while ( t3 < t1 ) *t2++ = *t3++;
×
1172
/*
1173
                                Now inset the rhs pointer
1174
*/
1175
                        *t2++ = SUBEXPRESSION;
×
1176
                        *t2++ = SUBEXPSIZE;
×
1177
                        *t2++ = i;
×
1178
                        *t2++ = 1;
×
1179
                        *t2++ = AM.sbufnum;
×
1180
                        FILLSUB(t2)
1181
                        t3 = t1 = t1 + t1[1];
×
1182
                }
1183
                else if ( *t1 == EXTRASYMFUN && t1[1] == FUNHEAD ) {
×
1184
                        while ( t3 < t1 ) *t2++ = *t3++;
×
1185
                        t3 = t1 = t1 + t1[1];
×
1186
                }
1187
                else {
1188
nocase:;
×
1189
                        t1 = t1 + t1[1];
×
1190
                }
1191
        }
1192
        while ( t3 < tend ) *t2++ = *t3++;
×
1193
        *termout = t2 - termout;
×
1194
        AT.WorkPointer = t2;
×
1195
        if ( AT.WorkPointer >= AT.WorkTop ) {
×
1196
                MLOCK(ErrorMessageLock);
×
1197
                MesWork();
×
1198
                MUNLOCK(ErrorMessageLock);
×
1199
                AT.WorkPointer = oldworkpointer;
×
1200
                return(-1);
×
1201
        }
1202
        retval = Generator(BHEAD termout,level);
×
1203
        AT.WorkPointer = oldworkpointer;
×
1204
        if ( retval < 0 ) {
×
1205
                MLOCK(ErrorMessageLock);
×
1206
                MesCall("ExtraSymFun");
×
1207
                MUNLOCK(ErrorMessageLock);
1208
        }
1209
        return(retval);
1210
}
1211

1212
/*
1213
                 #] ExtraSymFun : 
1214
                 #[ PruneExtraSymbols :
1215
*/
1216

1217
int PruneExtraSymbols(WORD downto)
72✔
1218
{
1219
        CBUF *C = cbuf + AM.sbufnum;
72✔
1220
        if ( downto < C->numrhs && downto >= 0 ) {  /* !!!!! */
72✔
1221
                ClearTree(AM.sbufnum);
18✔
1222
                C->numrhs = downto;
18✔
1223
                if ( downto == 0 ) {
18✔
1224
                        C->Pointer = C->Buffer;
18✔
1225
                }
1226
                else {
1227
                        WORD *w = C->rhs[downto], i;
×
1228
                        while ( *w ) w += *w;
×
1229
                        C->Pointer = w+1;
×
1230
                        for ( i = 1; i <= downto; i++ ) {
×
1231
                                InsTree(AM.sbufnum,i);
×
1232
                        }
1233
                }
1234
        }
1235
        return(0);
72✔
1236
}
1237

1238
/*
1239
                 #] PruneExtraSymbols : 
1240
*/
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