Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
718 jacekm 1
/*
2
** Small-C Compiler -- Part 3 -- Expression Analyzer.
3
** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
4
** Copyright 1998 H T Walheim
5
** All rights reserved.
6
*/
7
 
8
#include 
9
#include "cc.h"
10
 
11
#define ST 0   /* is[ST] - symbol table address, else 0 */
12
#define TI 1   /* is[TI] - type of indirect obj to fetch, else 0 */
13
#define TA 2   /* is[TA] - type of address, else 0 */
14
#define TC 3   /* is[TC] - type of constant (INT or UINT), else 0 */
15
#define CV 4   /* is[CV] - value of constant (+ auxiliary uses) */
16
#define OP 5   /* is[OP] - code of highest/last binary operator */
17
#define SA 6   /* is[SA] - stage address of "op 0" code, else 0 */
18
 
19
extern char
20
 *litq, *glbptr, *lptr,  ssname[NAMESIZE],  quote[2];
21
extern int
22
  ch,  csp,  litlab,  litptr,  nch,  op[16],  op2[16],
23
  opindex,  opsize, *snext;
24
 
25
/***************** lead-in functions *******************/
26
 
27
constexpr(val) int *val; {
28
  int constant;
29
  int *before, *start;
30
  setstage(&before, &start);
31
  expression(&constant, val);
32
  clearstage(before, 0);     /* scratch generated code */
33
  if(constant == 0) error("must be constant expression");
34
  return constant;
35
  }
36
 
37
null_is (is)
38
int is[7];
39
  {
40
    int i;
41
 
42
    for (i = 0; i < 7; ++i)
43
      {
44
	is[i] = 0;	/* <-- */
45
      }
46
  }
47
 
48
 
49
expression(con, val) int *con, *val;
50
  {
51
    int i;
52
    int is[7];
53
 
54
    null_is (is);
55
 
56
  if(level1(is)) fetch(is);
57
  *con = is[TC];
58
  *val = is[CV];
59
  }
60
 
61
test(label, parens)  int label, parens;  {
62
  int is[7];
63
  int *before, *start;
64
 
65
  null_is (is);
66
 
67
  if(parens) need("(");
68
  while(1) {
69
    setstage(&before, &start);
70
    if(level1(is)) fetch(is);
71
    if(match(",")) clearstage(before, start);
72
    else break;
73
    }
74
  if(parens) need(")");
75
  if(is[TC]) {             /* constant expression */
76
    clearstage(before, 0);
77
    if(is[CV]) return;
78
    gen(JMPm, label);
79
    return;
80
    }
81
  if(is[SA]) {             /* stage address of "oper 0" code */
82
    switch(is[OP]) {       /* operator code */
83
      case EQ12:
84
      case LE12u: zerojump(EQ10f, label, is); break;
85
      case NE12:
86
      case GT12u: zerojump(NE10f, label, is); break;
87
      case GT12:  zerojump(GT10f, label, is); break;
88
      case GE12:  zerojump(GE10f, label, is); break;
89
      case GE12u: clearstage(is[SA], 0);      break;
90
      case LT12:  zerojump(LT10f, label, is); break;
91
      case LT12u: zerojump(JMPm,  label, is); break;
92
      case LE12:  zerojump(LE10f, label, is); break;
93
      default:    gen(NE10f, label);          break;
94
      }
95
    }
96
  else gen(NE10f, label);
97
  clearstage(before, start);
98
  }
99
 
100
/*
101
** test primary register against zero and jump if false
102
*/
103
zerojump(oper, label, is) int oper, label, is[]; {
104
  clearstage(is[SA], 0);       /* purge conventional code */
105
  gen(oper, label);
106
  }
107
 
108
/***************** precedence levels ******************/
109
#ifdef _MSC_VER
110
level2();
111
level3();
112
level4();
113
level5();
114
level6();
115
level7();
116
level8();
117
level9();
118
level10();
119
level11();
120
level12();
121
level13();
122
#endif
123
 
124
level1(is) int is[];  {
125
  int k, is2[7], is3[2], oper, oper2;
126
 
127
  null_is (is2);
128
  null_is (is3);
129
 
130
  k = down1(level2, is);
131
  if(is[TC])
132
    {
133
#ifdef INT32
134
      gen(GETd1n, is[CV]);
135
#else
136
      gen(GETw1n, is[CV]);
137
#endif
138
    }
139
       if(match("|="))  {oper =        oper2 = OR12;}
140
  else if(match("^="))  {oper =        oper2 = XOR12;}
141
  else if(match("&="))  {oper =        oper2 = AND12;}
142
  else if(match("+="))  {oper =        oper2 = ADD12;}
143
  else if(match("-="))  {oper =        oper2 = SUB12;}
144
  else if(match("*="))  {oper = MUL12; oper2 = MUL12u;}
145
  else if(match("/="))  {oper = DIV12; oper2 = DIV12u;}
146
  else if(match("%="))  {oper = MOD12; oper2 = MOD12u;}
147
  else if(match(">>=")) {oper =        oper2 = ASR12;}
148
  else if(match("<<=")) {oper =        oper2 = ASL12;}
149
  else if(match("="))   {oper =        oper2 = 0;}
150
  else return k;
151
                        /* have an assignment operator */
152
  if(k == 0) {
153
    needlval();
154
    return 0;
155
    }
156
  is3[ST] = is[ST];
157
  is3[TI] = is[TI];
158
  if(is[TI]) {                             /* indirect target */
159
    if(oper) {                             /* ?= */
160
      gen(PUSH1, 0);                       /* save address */
161
      fetch(is);                           /* fetch left side */
162
      }
163
    down2(oper, oper2, level1, is, is2);   /* parse right side */
164
    if(oper) gen(POP2, 0);                 /* retrieve address */
165
    }
166
  else {                                   /* direct target */
167
    if(oper) {                             /* ?= */
168
      fetch(is);                           /* fetch left side */
169
      down2(oper, oper2, level1, is, is2); /* parse right side */
170
      }
171
    else {                                 /*  = */
172
      if(level1(is2)) fetch(is2);          /* parse right side */
173
      }
174
    }
175
  store(is3);                              /* store result */
176
  return 0;
177
  }
178
 
179
level2(is1)  int is1[]; {
180
  int is2[7], is3[7], k, flab, endlab, *before, *after;
181
 
182
  null_is (is2);
183
  null_is (is3);
184
 
185
  k = down1(level3, is1);                   /* expression 1 */
186
  if(match("?") == 0) return k;
187
  dropout(k, NE10f, flab = getlabel(), is1);
188
  if(down1(level2, is2)) fetch(is2);        /* expression 2 */
189
  else if(is2[TC])
190
    {
191
#ifdef INT32
192
      gen(GETd1n, is2[CV]);
193
#else
194
      gen(GETw1n, is2[CV]);
195
#endif
196
    }
197
  need(":");
198
  gen(JMPm, endlab = getlabel());
199
  gen(LABm, flab);
200
  if(down1(level2, is3)) fetch(is3);        /* expression 3 */
201
  else if(is3[TC])
202
    {
203
#ifdef INT32
204
      gen(GETd1n, is3[CV]);
205
#else
206
      gen(GETw1n, is3[CV]);
207
#endif
208
    }
209
  gen(LABm, endlab);
210
 
211
  is1[TC] = is1[CV] = 0;
212
  if(is2[TC] && is3[TC]) {                  /* expr1 ? const2 : const3 */
213
    is1[TA] = is1[TI] = is1[SA] = 0;
214
    }
215
  else if(is3[TC]) {                        /* expr1 ? var2 : const3 */
216
    is1[TA] = is2[TA];
217
    is1[TI] = is2[TI];
218
    is1[SA] = is2[SA];
219
    }
220
  else if((is2[TC])                         /* expr1 ? const2 : var3 */
221
       || (is2[TA] == is3[TA])) {           /* expr1 ? same2 : same3 */
222
    is1[TA] = is3[TA];
223
    is1[TI] = is3[TI];
224
    is1[SA] = is3[SA];
225
    }
226
  else error("mismatched expressions");
227
  return 0;
228
  }
229
 
230
level3 (is) int is[]; {return skim("||", EQ10f, 1, 0, level4,  is);}
231
level4 (is) int is[]; {return skim("&&", NE10f, 0, 1, level5,  is);}
232
level5 (is) int is[]; {return down("|",            0, level6,  is);}
233
level6 (is) int is[]; {return down("^",            1, level7,  is);}
234
level7 (is) int is[]; {return down("&",            2, level8,  is);}
235
level8 (is) int is[]; {return down("== !=",        3, level9,  is);}
236
level9 (is) int is[]; {return down("<= >= < >",    5, level10, is);}
237
level10(is) int is[]; {return down(">> <<",        9, level11, is);}
238
level11(is) int is[]; {return down("+ -",         11, level12, is);}
239
level12(is) int is[]; {return down("* / %",       13, level13, is);}
240
 
241
level13(is)  int is[];  {
242
  int k;
243
  char *ptr;
244
  if(match("++")) {                 /* ++lval */
245
    if(level13(is) == 0) {
246
      needlval();
247
      return 0;
248
      }
249
    step(rINC1, is, 0);
250
    return 0;
251
    }
252
  else if(match("--")) {            /* --lval */
253
    if(level13(is) == 0) {
254
      needlval();
255
      return 0;
256
      }
257
    step(rDEC1, is, 0);
258
    return 0;
259
    }
260
  else if(match("~")) {             /* ~ */
261
    if(level13(is)) fetch(is);
262
    gen(COM1, 0);
263
    is[CV] = ~ is[CV];
264
    return (is[SA] = 0);
265
    }
266
  else if(match("!")) {             /* ! */
267
    if(level13(is)) fetch(is);
268
    gen(LNEG1, 0);
269
    is[CV] = ! is[CV];
270
    return (is[SA] = 0);
271
    }
272
  else if(match("-")) {             /* unary - */
273
    if(level13(is)) fetch(is);
274
    gen(ANEG1, 0);
275
    is[CV] = -is[CV];
276
    return (is[SA] = 0);
277
    }
278
  else if(match("*")) {             /* unary * */
279
    if(level13(is)) fetch(is);
280
    if(ptr = is[ST]) is[TI] = ptr[TYPE];
281
    else             is[TI] = INT;
282
    is[SA] =       /* no (op 0) stage address */
283
    is[TA] =       /* not an address */
284
    is[TC] = 0;    /* not a constant */
285
    is[CV] = 1;    /* omit fetch() on func call */
286
    return 1;
287
    }
288
  else if(amatch("sizeof", 6)) {    /* sizeof() */
289
    int sz, p;  char *ptr, sname[NAMESIZE];
290
    if(match("(")) p = 1;
291
    else           p = 0;
292
    sz = 0;
293
    if     (amatch("unsigned", 8))  sz = INTSIZE;
294
    if     (amatch("int",      3))  sz = INTSIZE;
295
    else if(amatch("char",     4))  sz = 1;
296
    if(sz) {if(match("*"))          sz = PTRSIZE;}
297
    else if(symname(sname)
298
         && ((ptr = findloc(sname)) ||
299
             (ptr = findglb(sname)))
300
         && ptr[IDENT] != FUNCTION
301
         && ptr[IDENT] != LABEL)    sz = getint(ptr+SIZE, INTSIZE);
302
    else if(sz == 0) error("must be object or type");
303
    if(p) need(")");
304
    is[TC] = INT;
305
    is[CV] = sz;
306
    is[TA] = is[TI] = is[ST] = 0;
307
    return 0;
308
    }
309
  else if(match("&")) {             /* unary & */
310
    if(level13(is) == 0) {
311
      error("illegal address");
312
      return 0;
313
      }
314
    ptr = is[ST];
315
    is[TA] = ptr[TYPE];
316
    if(is[TI]) return 0;
317
    gen(POINT1m, ptr);
318
    is[TI] = ptr[TYPE];
319
    return 0;
320
    }
321
  else {
322
    k = level14(is);
323
    if(match("++")) {               /* lval++ */
324
      if(k == 0) {
325
        needlval();
326
        return 0;
327
        }
328
      step(rINC1, is, rDEC1);
329
      return 0;
330
      }
331
    else if(match("--")) {          /* lval-- */
332
      if(k == 0) {
333
        needlval();
334
        return 0;
335
        }
336
      step(rDEC1, is, rINC1);
337
      return 0;
338
      }
339
    else return k;
340
    }
341
  }
342
 
343
level14(is)  int *is; {
344
  int k, consta, val;
345
  char *ptr, *before, *start;
346
  k = primary(is);
347
  ptr = is[ST];
348
  blanks();
349
  if(ch == '[' || ch == '(') {
350
    int is2[7];                     /* allocate only if needed */
351
 
352
    null_is (is2);
353
 
354
    while(1) {
355
      if(match("[")) {              /* [subscript] */
356
        if(ptr == 0) {
357
          error("can't subscript");
358
          skip();
359
          need("]");
360
          return 0;
361
          }
362
        if(is[TA]) {if(k) fetch(is);}
363
        else       {error("can't subscript"); k = 0;}
364
        setstage(&before, &start);
365
        is2[TC] = 0;
366
        down2(0, 0, level1, is2, is2);
367
        need("]");
368
        if(is2[TC]) {
369
          clearstage(before, 0);
370
          if(is2[CV])
371
	    {             /* only add if non-zero */
372
	      if(ptr[TYPE] >> 2 == BPD)
373
		{
374
#ifdef INT32
375
		  gen(GETd2n, is2[CV] << LBPD);
376
#else
377
		  gen(GETw2n, is2[CV] << LBPD);
378
#endif
379
		}
380
	      else if(ptr[TYPE] >> 2 == BPW)
381
		{
382
#ifdef INT32
383
		  gen(GETd2n, is2[CV] << LBPW);
384
#else
385
		  gen(GETw2n, is2[CV] << LBPW);
386
#endif
387
		}
388
	      else
389
		{
390
#ifdef INT32
391
		  gen(GETd2n, is2[CV]);
392
#else
393
		  gen(GETw2n, is2[CV]);
394
#endif
395
		}
396
	      gen(ADD12, 0);
397
            }
398
          }
399
        else
400
	  {
401
	    if(ptr[TYPE] >> 2 == BPD)
402
	      {
403
		gen(DBL1, 0);
404
		gen(DBL1, 0);
405
	      }
406
	    else if(ptr[TYPE] >> 2 == BPW)
407
	      {
408
		gen(DBL1, 0);
409
	      }
410
	    gen(ADD12, 0);
411
          }
412
        is[TA] = 0;
413
        is[TI] = ptr[TYPE];
414
        k = 1;
415
        }
416
      else if(match("(")) {         /* function(...) */
417
        if(ptr == 0) callfunc(0);
418
        else if(ptr[IDENT] != FUNCTION) {
419
          if(k && !is[CV]) fetch(is);
420
          callfunc(0);
421
          }
422
        else callfunc(ptr);
423
        k = is[ST] = is[TC] = is[CV] = 0;
424
        }
425
      else return k;
426
      }
427
    }
428
  if(ptr && ptr[IDENT] == FUNCTION) {
429
    gen(POINT1m, ptr);
430
    is[ST] = 0;
431
    return 0;
432
    }
433
  return k;
434
  }
435
 
436
primary(is)  int *is; {
437
  char *ptr, sname[NAMESIZE];
438
  int k;
439
  if(match("(")) {                  /* (subexpression) */
440
    do k = level1(is); while(match(","));
441
    need(")");
442
    return k;
443
    }
444
  putint(0, is, 7 << LBPW);         /* clear "is" array */
445
  if(symname(sname)) {              /* is legal symbol */
446
    if(ptr = findloc(sname)) {      /* is local */
447
      if(ptr[IDENT] == LABEL) {
448
        experr();
449
        return 0;
450
        }
451
      gen(POINT1s, getint(ptr+OFFSET, INTSIZE));
452
      is[ST] = ptr;
453
      is[TI] = ptr[TYPE];
454
      if(ptr[IDENT] == ARRAY) {
455
        is[TA] = ptr[TYPE];
456
        return 0;
457
        }
458
      if(ptr[IDENT] == POINTER) {
459
        is[TI] = UINT;
460
        is[TA] = ptr[TYPE];
461
        }
462
      return 1;
463
      }
464
    if(ptr = findglb(sname)) {      /* is global */
465
      is[ST] = ptr;
466
      if(ptr[IDENT] != FUNCTION) {
467
        if(ptr[IDENT] == ARRAY) {
468
          gen(POINT1m, ptr);
469
          is[TI] =
470
          is[TA] = ptr[TYPE];
471
          return 0;
472
          }
473
        if(ptr[IDENT] == POINTER)
474
          is[TA] = ptr[TYPE];
475
        return 1;
476
        }
477
      }
478
    else is[ST] = addsym(sname, FUNCTION, INT, 0, 0, &glbptr, AUTOEXT);
479
    return 0;
480
    }
481
  if(constant(is) == 0) experr();
482
  return 0;
483
  }
484
 
485
experr() {
486
  error("invalid expression");
487
#ifdef INT32
488
  gen(GETd1n, 0);
489
#else
490
  gen(GETw1n, 0);
491
#endif
492
  skip();
493
  }
494
 
495
/* attempt at right to left - do it later */
496
#ifdef LATER
497
pushargs (ptr, nargs)
498
char *ptr;
499
int nargs;
500
  {
501
    if (streq(lptr, ")") != 0)
502
      return;
503
 
504
    if(endst())
505
      return;
506
 
507
    if(ptr)
508
      {
509
	expression(&consta, &val);
510
	gen(PUSH1, 0);
511
      }
512
    else
513
      {
514
	gen(PUSH1, 0);
515
	expression(&consta, &val);
516
	gen(SWAP1s, 0);            /* don't push addr */
517
      }
518
    nargs = nargs + INTSIZE;         /* count args*BPW */
519
 
520
    if(match(",") == 0) break;
521
 
522
  }
523
#endif
524
 
525
callfunc(ptr)
526
char *ptr;      /* symbol table entry or 0 */
527
  {
528
    int nargs, consta, val;
529
 
530
    nargs = 0;
531
    blanks();                      /* already saw open paren */
532
 
533
    while(streq(lptr, ")") == 0)
534
      {
535
	if(endst())
536
	  break;
537
	if(ptr)
538
	  {
539
	    expression(&consta, &val);
540
	    gen(PUSH1, 0);
541
	  }
542
	else
543
	  {
544
	    gen(PUSH1, 0);
545
	    expression(&consta, &val);
546
	    gen(SWAP1s, 0);            /* don't push addr */
547
	  }
548
	nargs = nargs + INTSIZE;         /* count args*BPW */
549
 
550
	if(match(",") == 0) break;
551
      }
552
    need(")");
553
    if(ptr && (streq(ptr + NAME, "CCARGC") == 0))	/* accessing ... like va_args */
554
#ifdef INT32
555
      gen(ARGCNTn, nargs >> LBPD);		/* to get start of frame */
556
#else
557
      gen(ARGCNTn, nargs >> LBPW);		/* to get start of frame */
558
#endif
559
 
560
    if(ptr)
561
      gen(CALLm, ptr);
562
    else
563
      gen(CALL1, 0);
564
    gen(ADDSP, csp + nargs);
565
  }
566
 
567
/*
568
** true if is2's operand should be doubled
569
*/
570
fdouble (oper, is1, is2)
571
int oper, is1[], is2[];
572
{
573
  //////////////////////////////////////////////////////
574
  // This is a 'magic' function, its usage and function
575
  // are not so obvious
576
  //
577
  // Purpose:  when indexing an address we must know
578
  // what we are pointing at so that the indexsize is
579
  // proper, e,g,
580
  // charptr++,  should multiply index by a 1
581
  // shortptr++, should multiply index by a 2
582
  // intptr++,   should multiply index by a 4
583
  //
584
  // Algorithm:
585
  // IF
586
  // operation is ADD12 or SUB12
587
  // AND
588
  // is1 is an address (pointer, array or via & operator
589
  // AND
590
  // is2 is NOT an address (pointer, array or via & operator
591
  // THEN
592
  // return the multiplication factor based on s1 (or true)
593
  // ELSE
594
  // return 0 (or false)
595
  //
596
  // Usage: The return value is used as a 'boolean'
597
  // for nonconstant values, indicating that runtime code
598
  // is necessary to do the necessary multiplication
599
  // For contant value the return value is used to do a compile-time
600
  // multiplication (shift actually)
601
  //
602
 
603
  if ((oper == ADD12 || oper == SUB12)
604
      && (is2[TA] == 0))
605
    {
606
      switch (is1[TA]>>2)
607
	{
608
	  default:
609
	  case 1:		// char
610
	    return (0);
611
	  case 2:		// short
612
	    return (1);
613
	  case 4:		// int
614
	    return (2);
615
	}
616
    }
617
 
618
  return (0);
619
 
620
 
621
 
622
/*
623
  - original code -
624
  if((oper != ADD12 && oper != SUB12)
625
     || (is1[TA] >> 2 != BPW)
626
     || (is2[TA]))
627
 
628
    return 0;
629
 
630
 
631
  return 1;
632
*/
633
}
634
 
635
 
636
step (oper, is, oper2) int oper, is[], oper2; {
637
  fetch(is);
638
  gen(oper, is[TA] ? (is[TA] >> 2) : 1);
639
  store(is);
640
  if(oper2) gen(oper2, is[TA] ? (is[TA] >> 2) : 1);
641
  }
642
 
643
store(is)
644
int is[];
645
  {
646
    char *ptr;
647
 
648
    if(is[TI])
649
      {                     /* putstk */
650
	if(is[TI] >> 2 == 1)
651
	  {
652
	    gen(PUTbp1, 0);
653
	  }
654
	else if(is[TI] >> 2 == 2)
655
	  {
656
	    gen(PUTwp1, 0);
657
	  }
658
	else
659
	  {
660
	    gen(PUTdp1, 0);
661
	  }
662
      }
663
    else
664
      {                          /* putmem */
665
	ptr = is[ST];
666
	if(ptr[IDENT] == POINTER)
667
	  {
668
#ifdef INT32	/* int and ptr-size are ALWAYS the same */
669
	  gen(PUTdm1, ptr);
670
#else
671
	  gen(PUTwm1, ptr);
672
#endif
673
	  }
674
	else if (ptr[TYPE] >> 2 == 1)
675
	  {
676
	    gen(PUTbm1, ptr);
677
	  }
678
	else if (ptr[TYPE] >> 2 == BPW)
679
	  {
680
	    gen(PUTwm1, ptr);
681
	  }
682
	else
683
	  {
684
	    gen(PUTdm1, ptr);
685
	  }
686
      }
687
  }
688
 
689
fetch(is)
690
int is[];
691
  {
692
    char *ptr;
693
 
694
    ptr = is[ST];
695
    if(is[TI])                          /* indirect */
696
      {
697
	if(is[TI] >> 2 == BPD)		/* pointer to DWORD */
698
	  {
699
	    gen(GETd1p,  0);
700
	  }
701
	else if(is[TI] >> 2 == BPW)	/* pointer to WORD */
702
	  {
703
	    /* if INT32 must make distinction between signed/unsigned <-- */
704
	    gen(GETw1p,  0);
705
	  }
706
	else
707
	  {
708
	    if(ptr[TYPE] & UNSIGNED)
709
	      gen(GETb1pu, 0);
710
	    else
711
	      gen(GETb1p,  0);
712
	  }
713
      }
714
    else
715
      {					/* direct */
716
 
717
	if(ptr[IDENT] == POINTER)
718
	  {
719
#ifdef INT32
720
	    gen(GETd1m,  ptr);
721
#else
722
	    gen(GETw1m,  ptr);
723
#endif
724
	  }
725
	else if (ptr[TYPE] >> 2 == BPD)
726
	  {
727
	    gen(GETd1m,  ptr);
728
	  }
729
	else if (ptr[TYPE] >> 2 == BPW)
730
	  {
731
	    gen(GETw1m,  ptr);
732
	  }
733
	else
734
	  {
735
	    if(ptr[TYPE] & UNSIGNED)
736
	      gen(GETb1mu, ptr);
737
	    else
738
	      gen(GETb1m,  ptr);
739
	  }
740
      }
741
  }
742
 
743
constant(is)
744
int is[];
745
  {
746
    int offset;
747
 
748
    if (is[TC] = number(is + CV))
749
      {
750
#ifdef INT32
751
	gen(GETd1n,  is[CV]);
752
#else
753
	gen(GETw1n,  is[CV]);
754
#endif
755
      }
756
    else if(is[TC] = chrcon(is + CV))
757
      {
758
#ifdef INT32
759
	gen(GETd1n,  is[CV]);
760
#else
761
	gen(GETw1n,  is[CV]);
762
#endif
763
      }
764
    else if(string(&offset))
765
      {
766
	gen(POINT1l, offset);
767
      }
768
    else
769
      {
770
	return 0;
771
      }
772
    return 1;
773
  }
774
 
775
number(value)  int *value; {
776
  int k, minus;
777
  k = minus = 0;
778
  while(1) {
779
    if(match("+")) ;
780
    else if(match("-")) minus = 1;
781
    else break;
782
    }
783
  if(isdigit(ch) == 0) return 0;
784
  if(ch == '0') {
785
    while(ch == '0') inbyte();
786
    if(toupper(ch) == 'X') {
787
      inbyte();
788
      while(isxdigit(ch)) {
789
        if(isdigit(ch))
790
             k = k*16 + (inbyte() - '0');
791
        else k = k*16 + 10 + (toupper(inbyte()) - 'A');
792
        }
793
      }
794
    else while (ch >= '0' && ch <= '7')
795
      k = k*8 + (inbyte() - '0');
796
    }
797
  else while (isdigit(ch)) k = k*10 + (inbyte() - '0');
798
  if(minus) {
799
    *value = -k;
800
    return (INT);
801
    }
802
  if((*value = k) < 0) return (UINT);
803
  else                 return (INT);
804
  }
805
 
806
chrcon(value)
807
int *value;
808
  {
809
    int k;
810
 
811
    k = 0;
812
    if(match("'") == 0)
813
      return 0;
814
    while(ch != '\'')
815
      k = (k << 8) + (litchar() & 255);
816
    gch();
817
    *value = k;
818
    return (INT);
819
  }
820
 
821
string(offset) int *offset; {
822
  char c;
823
  if(match(quote) == 0) return 0;
824
  *offset = litptr;
825
  while (ch != '"') {
826
    if(ch == 0) break;
827
    stowlit(litchar(), 1);
828
    }
829
  gch();
830
  litq[litptr++] = 0;
831
  return 1;
832
  }
833
 
834
stowlit(value, size) int value, size; {
835
  if((litptr+size) >= LITMAX) {
836
    error("literal queue overflow");
837
    exit(ERRCODE);
838
    }
839
  putint(value, litq+litptr, size);
840
  litptr += size;
841
  }
842
 
843
litchar() {
844
  int i, oct;
845
  if(ch != '\\' || nch == 0) return gch();
846
  gch();
847
  switch(ch) {
848
    case 'n': gch(); return NEWLINE;
849
    case 't': gch(); return  9;  /* HT */
850
    case 'b': gch(); return  8;  /* BS */
851
    case 'f': gch(); return 12;  /* FF */
852
    }
853
  i = 3;
854
  oct = 0;
855
  while((i--) > 0 && ch >= '0' && ch <= '7')
856
    oct = (oct << 3) + gch() - '0';
857
  if(i == 2) return gch();
858
  else       return oct;
859
  }
860
 
861
/***************** pipeline functions ******************/
862
 
863
/*
864
** skim over terms adjoining || and && operators
865
*/
866
skim(opstr, tcode, dropval, endval, level, is)
867
  char *opstr;
868
  int tcode, dropval, endval, (*level)(), is[]; {
869
  int k, droplab, endlab;
870
  droplab = 0;
871
  while(1) {
872
    k = down1(level, is);
873
    if(nextop(opstr)) {
874
      bump(opsize);
875
      if(droplab == 0) droplab = getlabel();
876
      dropout(k, tcode, droplab, is);
877
      }
878
    else if(droplab) {
879
      dropout(k, tcode, droplab, is);
880
#ifdef INT32
881
      gen(GETd1n, endval);
882
#else
883
      gen(GETw1n, endval);
884
#endif
885
      gen(JMPm, endlab = getlabel());
886
      gen(LABm, droplab);
887
#ifdef INT32
888
      gen(GETd1n, dropval);
889
#else
890
      gen(GETw1n, dropval);
891
#endif
892
      gen(LABm, endlab);
893
      is[TI] = is[TA] = is[TC] = is[CV] = is[SA] = 0;
894
      return 0;
895
      }
896
    else return k;
897
    }
898
  }
899
 
900
/*
901
** test for early dropout from || or && sequences
902
*/
903
dropout(k, tcode, exit1, is)
904
  int k, tcode, exit1, is[]; {
905
  if(k) fetch(is);
906
  else if(is[TC])
907
    {
908
#ifdef INT32
909
      gen(GETd1n, is[CV]);
910
#else
911
      gen(GETw1n, is[CV]);
912
#endif
913
    }
914
  gen(tcode, exit1);          /* jumps on false */
915
  }
916
 
917
/*
918
** drop to a lower level
919
*/
920
down(opstr, opoff, level, is)
921
  char *opstr;  int opoff, (*level)(), is[]; {
922
  int k;
923
  k = down1(level, is);
924
  if(nextop(opstr) == 0) return k;
925
  if(k) fetch(is);
926
  while(1) {
927
    if(nextop(opstr)) {
928
      int is2[7];     /* allocate only if needed */
929
 
930
      null_is (is2);
931
 
932
      bump(opsize);
933
      opindex += opoff;
934
      down2(op[opindex], op2[opindex], level, is, is2);
935
      }
936
    else return 0;
937
    }
938
  }
939
 
940
/*
941
** unary drop to a lower level
942
*/
943
down1(level, is) int (*level)(), is[]; {
944
  int k, *before, *start;
945
  setstage(&before, &start);
946
  k = (*level)(is);
947
  if(is[TC]) clearstage(before, 0);  /* load constant later */
948
  return k;
949
  }
950
 
951
/*
952
** binary drop to a lower level
953
*/
954
down2(oper, oper2, level, is, is2)
955
  int oper, oper2, (*level)(), is[], is2[]; {
956
  int *before, *start;
957
  char *ptr;
958
  int value;
959
  setstage(&before, &start);
960
  is[SA] = 0;                     /* not "... op 0" syntax */
961
  if(is[TC]) {                    /* consant op unknown */
962
    if(down1(level, is2)) fetch(is2);
963
    if(is[CV] == 0) is[SA] = snext;
964
    gen(GETw2n, is[CV] << fdouble(oper, is2, is));
965
    }
966
  else {                          /* variable op unknown */
967
    gen(PUSH1, 0);                /* at start in the buffer */
968
    if(down1(level, is2)) fetch(is2);
969
    if(is2[TC]) {                 /* variable op constant */
970
      if(is2[CV] == 0) is[SA] = start;
971
#ifdef INT32
972
      csp += BPD;                 /* adjust stack and */
973
#else
974
      csp += BPW;                 /* adjust stack and */
975
#endif
976
      clearstage(before, 0);      /* discard the PUSH */
977
      if(oper == ADD12) {         /* commutative */
978
#ifdef INT32
979
        gen(GETd2n, is2[CV] << fdouble(oper, is, is2));
980
#else
981
        gen(GETw2n, is2[CV] << fdouble(oper, is, is2));
982
#endif
983
        }
984
      else {                      /* non-commutative */
985
        gen(MOVE21, 0);
986
#ifdef INT32
987
        gen(GETd1n, is2[CV] << fdouble(oper, is, is2));
988
#else
989
        gen(GETw1n, is2[CV] << fdouble(oper, is, is2));
990
#endif
991
        }
992
      }
993
    else {                        /* variable op variable */
994
      gen(POP2, 0);
995
      if(value = fdouble(oper, is, is2))
996
	{
997
	  gen(DBL1, 0);		// index size 2
998
	  if (value > 1)
999
	    gen(DBL1, 0);	// .. or even 4
1000
	}
1001
      if(value = fdouble(oper, is2, is))
1002
	{
1003
	  gen(DBL2, 0);
1004
	  if (value > 1)
1005
	    gen(DBL2, 0);
1006
	}
1007
      }
1008
    }
1009
  if(oper) {
1010
    if(nosign(is) || nosign(is2)) oper = oper2;
1011
    if(is[TC] = is[TC] & is2[TC]) {               /* constant result */
1012
      is[CV] = calc(is[CV], oper, is2[CV]);
1013
      clearstage(before, 0);
1014
      if(is2[TC] == UINT) is[TC] = UINT;
1015
      }
1016
    else {                                        /* variable result */
1017
      gen(oper, 0);
1018
      if(oper == SUB12
1019
      && is [TA] >> 2 == BPW
1020
      && is2[TA] >> 2 == BPW) { /* difference of two word addresses */
1021
        gen(SWAP12, 0);
1022
        gen(GETw1n, 1);
1023
        gen(ASR12, 0);          /* div by 2 */
1024
        }
1025
      is[OP] = oper;            /* identify the operator */
1026
      }
1027
    if(oper == SUB12 || oper == ADD12) {
1028
      if(is[TA] && is2[TA])     /*  addr +/- addr */
1029
        is[TA] = 0;
1030
      else if(is2[TA]) {        /* value +/- addr */
1031
        is[ST] = is2[ST];
1032
        is[TI] = is2[TI];
1033
        is[TA] = is2[TA];
1034
        }
1035
      }
1036
    if(is[ST] == 0 || ((ptr = is2[ST]) && (ptr[TYPE] & UNSIGNED)))
1037
      is[ST] = is2[ST];
1038
    }
1039
  }
1040
 
1041
/*
1042
** unsigned operand?
1043
*/
1044
nosign(is) int is[]; {
1045
  char *ptr;
1046
  if(is[TA]
1047
  || is[TC] == UINT
1048
  || ((ptr = is[ST]) && (ptr[TYPE] & UNSIGNED))
1049
    ) return 1;
1050
  return 0;
1051
  }
1052
 
1053
/*
1054
** calcualte signed constant result
1055
*/
1056
calc(left, oper, right) int left, oper, right; {
1057
  switch(oper) {
1058
    case ADD12: return (left  +  right);
1059
    case SUB12: return (left  -  right);
1060
    case MUL12: return (left  *  right);
1061
    case DIV12: return (left  /  right);
1062
    case MOD12: return (left  %  right);
1063
    case EQ12:  return (left  == right);
1064
    case NE12:  return (left  != right);
1065
    case LE12:  return (left  <= right);
1066
    case GE12:  return (left  >= right);
1067
    case LT12:  return (left  <  right);
1068
    case GT12:  return (left  >  right);
1069
    case AND12: return (left  &  right);
1070
    case OR12:  return (left  |  right);
1071
    case XOR12: return (left  ^  right);
1072
    case ASR12: return (left  >> right);
1073
    case ASL12: return (left  << right);
1074
    }
1075
  return (calc2(left, oper, right));
1076
  }
1077
 
1078
/*
1079
** calcualte unsigned constant result
1080
*/
1081
calc2(left, oper, right) unsigned left, right; int oper; {
1082
  switch(oper) {
1083
    case MUL12u: return (left  *  right);
1084
    case DIV12u: return (left  /  right);
1085
    case MOD12u: return (left  %  right);
1086
    case LE12u:  return (left  <= right);
1087
    case GE12u:  return (left  >= right);
1088
    case LT12u:  return (left  <  right);
1089
    case GT12u:  return (left  >  right);
1090
    }
1091
  return (0);
1092
  }
1093