1 /* $Id: cgenexp.c,v 1.24 1995/12/02 15:24:43 cim Exp $ */
2
3 /* Copyright (C) 1994, 1998 Sverre Hvammen Johansen and Terje Mj�s,
4 * Department of Informatics, University of Oslo.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 #include "config.h"
20 #include "gen.h"
21 #include "extspec.h"
22
23 int stack;
24 static int anttext;
25 int inthunk; /* Brukes i forbindelse med uttrykk i
26 * thunker. Sier at statisk link (sl) m}
27 * f|lges en gang ekstra for variable
28 * som aksesseres ifra thunken. */
29
30
31
32 /******************************************************************************
33 GEN */
34
35 gen (re)
36 struct EXP *re;
37 {
38 genvalue (transcall (re->up, re));
39 gen_sent_marker();
40 genvalue (re);
41 gen_sent_marker();
42 }
43
44 /******************************************************************************
45 GENSL */
46
47 gensl (re, atr, nonetest)
48 struct EXP *re;
49 char atr,
50 nonetest;
51 {
52 if (is_after_dot (re))
53 {
54 if (re->up->left->token == MQUA || re->up->left->token == MQUANOTNONE)
55 nonetest= OFF;
56 if (atr)
57 fprintf (ccode, "((__bs%d *)", re->rd->encl->blno);
58 if (nonetest == ON)
59 fprintf (ccode, "((__bp=");
60 genvalue (re->up->left);
61 if (nonetest == ON)
62 fprintf (ccode,
63 ")==__NULL?(__dhp)__rerror(__errnone):__bp)");
64 if (atr)
65 fprintf (ccode, ")->");
66 }
67 else if (seen_th_insp (re))
68 {
69 if (atr)
70 fprintf (ccode, "((__bs%d *)", re->rd->encl->blno);
71 genchain (re->seenthrough->quant.match->descr, TRUE);
72 fprintf (ccode, "c%d", re->seenthrough->connest);
73 if (atr)
74 fprintf (ccode, ")->");
75 }
76 else
77 {
78 genchain (re->rd->encl, atr);
79 }
80 }
81
82 /******************************************************************************
83 GENCHAIN */
84
85 genchain (rb, atr)
86 struct BLOCK *rb;
87 char atr;
88 {
89 int i;
90 if (rb->stat)
91 if (atr)
92 fprintf (ccode, "(__blokk%d%s).", rb->blno,
93 rb->timestamp?rb->timestamp:timestamp);
94 #if 0
95 else if (rb == sblock && separat_comp)
96 #else
97 else if (rb->blev==EXTERNALGLOBALBLEV && separat_comp)
98 #endif
99 fprintf (ccode, "__NULL");
100 else
101 fprintf (ccode, "((__dhp)&__blokk%d%s)", rb->blno,
102 rb->timestamp?rb->timestamp:timestamp);
103 else
104 {
105 struct BLOCK *rbx;
106 /* rbx = display[rb->blev];*/
107 for (rbx= cblock; rbx->blev != rb->blev; rbx= rbx->quant.encl);
108
109 while (rbx->quant.kind == KFOR || rbx->quant.kind == KINSP
110 || rbx->quant.kind == KCON)
111 rbx = rbx->quant.prefqual->descr;
112 if (rbx->stat)
113 {
114 if (atr)
115 {
116 fprintf (ccode, "((__bs%d *)&__blokk%d%s)->",
117 rb->blno, rbx->blno,
118 rbx->timestamp?rbx->timestamp:timestamp);
119 }
120 else
121 fprintf (ccode, "((__dhp)&__blokk%d%s)",
122 rbx->blno,
123 rbx->timestamp?rbx->timestamp:timestamp);
124 }
125 else
126 {
127 if (atr)
128 fprintf (ccode, "((__bs%d *)__lb", rb->blno);
129 else
130 fprintf (ccode, "__lb", rb->blno);
131 for (i = cblev + (inthunk ? 1 : 0); i > rb->blev; i--)
132 fprintf (ccode, "->sl");
133 if (atr)
134 fprintf (ccode, ")->", rb->blno);
135 }
136 }
137 }
138
139 /******************************************************************************
140 GENTYPE */
141
142 gentype (re)
143 struct EXP *re;
144 {
145 switch (re->type)
146 {
147 case TINTG:
148 fprintf (ccode, "long");
149 break;
150 case TREAL:
151 fprintf (ccode, "double");
152 break;
153 case TBOOL:
154 case TCHAR:
155 fprintf (ccode, "char");
156 break;
157 case TLABEL:
158 fprintf (ccode, "__lab");
159 break;
160 case TTEXT:
161 fprintf (ccode, "__txt");
162 break;
163 case TREF:
164 fprintf (ccode, "__dhp");
165 break;
166 };
167
168 }
169
170 /******************************************************************************
171 GEN_ADR_PROT */
172
gen_adr_prot(code,rd)173 gen_adr_prot (code, rd) FILE *code;
174 struct DECL *rd;
175 {
176 fprintf (code, "&__p%d%s"
177 ,rd->descr->timestamp == 0 ? rd->descr->blno : rd->descr->ptypno
178 ,rd->descr->timestamp == 0 ?
179 (rd->encl->blev == SYSTEMGLOBALBLEV &&
180 rd->encl->quant.plev == 0
181 ? "" :timestamp) : rd->descr->timestamp);
182 }
183
184 /******************************************************************************
185 GENMODULEMARK */
186
genmodulemark(maintimestamp)187 genmodulemark(maintimestamp) char *maintimestamp;
188 {
189 if (maintimestamp)
190 fprintf (ccode, "__m_%s", maintimestamp);
191 else if (separat_comp)
192 fprintf (ccode, "__m_%s", timestamp);
193 else fprintf (ccode, "__NULL");
194 }
195
196 /******************************************************************************
197 GENVALUE */
198
199 void
genvalue(re)200 genvalue (re)
201 struct EXP *re;
202 {
203 struct EXP *rex;
204 static struct EXP *ree;
205
206 if (re == NULL)
207 return;
208
209 ree = re;
210 switch (re->token)
211 {
212 case MARGUMENT:
213 genprocparam (re);
214 break;
215 case MNEWARG:
216 fprintf (ccode, "__sl=");
217 gensl (re, FALSE, ON);
218 fprintf (ccode, ";");
219 if (re->rd->descr->stat)
220 fprintf (ccode, "__sto= (__dhp)&__blokk%d%s;"
221 ,re->rd->descr->blno, timestamp);
222 fprintf (ccode, "__rcp(");
223 gen_adr_prot (ccode, re->rd);
224
225 fprintf (ccode, ",%ldL);",re->value.n_of_stack_elements);
226 genprocparam (re);
227
228 {
229 long l;
230 fprintf (ccode, "__rccb(%d,", l = newlabel ());
231 genmodulemark(NULL);
232 fprintf (ccode, ");");
233 if (separat_comp && re->rd->descr->timestamp)
234 {
235 fprintf (ccode, "return;");
236 typelabel (l);
237 }
238 else
239 {
240 exitlabel (l);
241 }
242 }
243
244 break;
245
246 case MPROCARG:
247 /* Predefinerte prosedyrer, C-prosedyrer eller vanlige
248 * proper-procedures, som er behandlet av transcall. De
249 * predefinerte og C-prosedyrene skal behandles her, mens vanlige
250 * proper-procedures allerede er behandlet i transcall. */
251 if (re->rd->descr->codeclass == CCNO)
252 {
253 /* Statisk link overf|res i den globale variabelen sl.
254 * Genererer kallet p} rcp. */
255
256 if (re->rd->categ != CNAME)
257 {
258 fprintf (ccode, "__sl=");
259 if (re->rd->categ == CDEFLT)
260 {
261 gensl (re, TRUE, ON);
262 fprintf (ccode, "%s.psl;", re->rd->ident);
263 }
264 else
265 {
266 gensl (re, FALSE, ON);
267 }
268 fprintf (ccode, ";");
269 }
270
271 if (re->rd->categ == CVIRT)
272 {
273 /* Kall p} en virtuell prosedyre.
274 * Prosedyrens prototype er gitt i virtuell tabellen.
275 * M} teste at den ikke er NULL, som gir
276 * run-time error. */
277 fprintf (ccode, "if((__pp=");
278 gensl (re, FALSE, OFF);
279 fprintf (ccode, "->pp->virt[%d])==__NULL)__rerror(__errvirt);",
280 re->rd->virtno - 1);
281 }
282
283 if (re->rd->descr->stat)
284 fprintf (ccode, "__sto= (__dhp)&__blokk%d%s;"
285 ,re->rd->descr->blno, timestamp);
286
287 if (re->type == TNOTY)
288 fprintf (ccode, "__rcpp(");
289 else
290 fprintf (ccode, "__rcp(");
291
292 if (re->rd->categ == CNAME || re->rd->categ == CVIRT)
293 fprintf (ccode, "__pp");
294 else if (re->rd->categ == CDEFLT)
295 {
296 gensl (re, TRUE, OFF);
297 fprintf (ccode, "%s.pp", re->rd->ident);
298 }
299 else
300 gen_adr_prot (ccode, re->rd);
301
302 if (re->type == TNOTY)
303 fprintf (ccode, ");");
304 else
305 fprintf (ccode, ",%ldL);",
306 re->value.combined_stack.n_of_stack_elements);
307
308 /* Kaller p} genprocparam som genererer kode for parameter-
309 * overf|ringen. */
310
311 genprocparam (re);
312
313 /* Hvis dette er et dot'et kall s} skal ikke doten ses n}r genvalue
314 * kalles.(Den informasjonen trengs ikke da) */
315
316
317 /* N} er alle parameterene overf}rt,
318 * og prosedyren kan settes i gang. */
319
320 {
321 int l;
322 fprintf (ccode, "__rcpb(%d,", l= newlabel ());
323 genmodulemark(NULL);
324 fprintf (ccode, ");");
325 if (separat_comp && re->rd->descr->timestamp)
326 {
327 fprintf (ccode, "return;");
328 typelabel (l);
329 }
330 else
331 {
332 exitlabel (l);
333 }
334 }
335
336 /* H}ndterer evt. funksjonsverdier. Sjekker om det
337 * er n|dvendig med konvertering av aritm. returverier eller
338 * kvalifikasjonskontroll for type REF Dette gjelder formelle
339 * prosedyrer med categ lik CVAR og CNAME (type = TREF,
340 * TINTG og TREAL)
341 */
342
343 switch (re->type)
344 {
345 case TREF:
346 fprintf (ccode, "__r[%d]=__er;", re->value.combined_stack.entry);
347 if (re->rd->categ == CVAR || re->rd->categ == CNAME)
348 {
349 fprintf (ccode, "__bp=");
350 gensl (re, FALSE, ON);
351 fprintf (ccode, ";if(((__bs%d *)__bp)->%s.conv==__READTEST "
352 "&& !__rin(__er,((__bs%d *)__bp)->%s.q))"
353 "__rerror(__errqual);",
354 re->rd->encl->blno, re->rd->ident,
355 re->rd->encl->blno, re->rd->ident);
356
357 }
358 break;
359 case TTEXT:
360 fprintf (ccode, "__t[%d]=__et;", re->value.combined_stack.entry);
361 break;
362 case TREAL:
363 if (re->rd->categ == CVAR || re->rd->categ == CNAME)
364 { /* Tre muligheter : ingen, int -> real,
365 * real->int->real */
366 fprintf (ccode, "__v[%d].f=((__conv=",
367 re->value.combined_stack.entry);
368 gensl (re, TRUE, ON);
369 fprintf (ccode, "%s.conv)==__NOCONV?__ev.f:__conv==__INTREAL?"
370 "(double)__ev.i:(double)__rintrea(__ev.f));",
371 re->rd->ident);
372 }
373 else
374 fprintf (ccode, "__v[%d].f=__ev.f;",
375 re->value.combined_stack.entry);
376 break;
377 case TINTG:
378 if (re->rd->categ == CNAME || re->rd->categ == CVAR)
379 { /* To muligheter : ingen konvertering eller
380 * real->int */
381 fprintf (ccode, "__v[%d].i=(",
382 re->value.combined_stack.entry);
383 gensl (re, TRUE, ON);
384 fprintf (ccode, "%s.conv==__NOCONV?",
385 re->rd->ident);
386 fprintf (ccode, "__ev.i:__rintrea(__ev.f));");
387 }
388 else
389 fprintf (ccode, "__v[%d].i=__ev.i;",
390 re->value.combined_stack.entry );
391 break;
392 case TNOTY:
393 break;
394 default:
395 fprintf (ccode, "__v[%d].c=__ev.c;",
396 re->value.combined_stack.entry);
397 break;
398 }
399
400 break;
401 }
402
403 if (re->right == NULL)
404 break;
405 /* Det siste tilfelle skal egentlig aldri sl} til. Det ville i s}
406 * fall bety at en predefinert properprocedure ville v{rt spesifisert
407 * som DANGER, noe som ikke er riktig. */
408
409 if (re->rd->categ == CCPROC)
410 if (re->type == TTEXT)
411 {
412 fprintf (ccode, "__ctext= ");
413 gencproccall (re);
414 fprintf (ccode, ";__t[%d]= *__rblanks(%ldL,"
415 "__ctext==__NULL?0:strlen(__ctext));"
416 "(void)strcpy(__t[%d].obj->string,__ctext);",
417 re->value.combined_stack.entry,
418 re->value.combined_stack.n_of_stack_elements,
419 re->value.combined_stack.entry);
420 }
421 else
422 gencproccall (re);
423 else
424 genpredefproccall (re);
425 break;
426
427 case MNOT:
428 fprintf (ccode, "(!");
429 genvalue (re->left);
430 putc (')', ccode);
431 break;
432 case MIMP:
433 fprintf (ccode, "(!");
434 genvalue (re->left);
435 fprintf (ccode, "|");
436 genvalue (re->right);
437 fprintf (ccode, ")");
438 break;
439 case MIS:
440 fprintf (ccode, "__ris(");
441 genvalue (re->left);
442 fprintf (ccode, ",");
443
444 gen_adr_prot (ccode, re->rd);
445 fprintf (ccode, ")");
446 break;
447 case MINS:
448 fprintf (ccode, "__rin(");
449 genvalue (re->left);
450 fprintf (ccode, ",");
451 gen_adr_prot (ccode, re->rd);
452 fprintf (ccode, ")");
453 break;
454 case MEQT:
455 fprintf (ccode, "__reqtext(");
456 genvalue (re->left);
457 fprintf (ccode, ",");
458 genvalue (re->right);
459 fprintf (ccode, ")");
460 break;
461 case MNET:
462 fprintf (ccode, "!__reqtext(");
463 genvalue (re->left);
464 fprintf (ccode, ",");
465 genvalue (re->right);
466 fprintf (ccode, ")");
467 break;
468 case MLTT:
469 fprintf (ccode, "__rlttext(");
470 genvalue (re->left);
471 fprintf (ccode, ",");
472 genvalue (re->right);
473 fprintf (ccode, ")");
474 break;
475 case MLET:
476 fprintf (ccode, "__rletext(");
477 genvalue (re->left);
478 fprintf (ccode, ",");
479 genvalue (re->right);
480 fprintf (ccode, ")");
481 break;
482 case MGTT:
483 fprintf (ccode, "__rlttext(");
484 genvalue (re->right);
485 fprintf (ccode, ",");
486 genvalue (re->left);
487 fprintf (ccode, ")");
488 break;
489 case MGET:
490 fprintf (ccode, "__rletext(");
491 genvalue (re->right);
492 fprintf (ccode, ",");
493 genvalue (re->left);
494 fprintf (ccode, ")");
495 break;
496 case MEQRT:
497 fprintf (ccode, "__reqrtext(");
498 genvalue (re->left);
499 fprintf (ccode, ",");
500 genvalue (re->right);
501 fprintf (ccode, ")");
502 break;
503 case MNERT:
504 fprintf (ccode, "!__reqrtext(");
505 genvalue (re->left);
506 fprintf (ccode, ",");
507 genvalue (re->right);
508 fprintf (ccode, ")");
509 break;
510 case MSIGNDX:
511 fprintf (ccode, "__rsigndx(");
512 genvalue (re->left);
513 fprintf (ccode, ",");
514 genvalue (re->right);
515 fprintf (ccode, ")");
516 break;
517 case MSIGNDI:
518 fprintf (ccode, "__rsigndi(");
519 genvalue (re->left);
520 fprintf (ccode, ",");
521 genvalue (re->right);
522 fprintf (ccode, ")");
523 break;
524 case MSIGNDR:
525 fprintf (ccode, "__rsigndr(");
526 genvalue (re->left);
527 fprintf (ccode, ",");
528 genvalue (re->right);
529 fprintf (ccode, ")");
530 break;
531 case MIFE:
532 if (re->type == TLABEL)
533 {
534 fprintf (ccode, "if(!");
535 genvalue (re->left);
536 fprintf (ccode, ")");
537 gotollabel ((int) (re->right->value.ival = newllabel ()));
538 genvalue (re->right);
539 break;
540 }
541 putc ('(', ccode);
542 genvalue (re->left);
543 fprintf (ccode, "?");
544 genvalue (re->right);
545 putc (')', ccode);
546 break;
547 case MELSEE:
548 if (re->type == TLABEL)
549 {
550 genvalue (re->left);
551 typellabel ((int) re->value.ival);
552 genvalue (re->right);
553 break;
554 }
555 genvalue (re->left);
556 fprintf (ccode, ":");
557 genvalue (re->right);
558 break;
559 case MIF:
560 fprintf (ccode, "if(!");
561 genvalue (re->left);
562 fprintf (ccode, ")");
563 gotollabel (re->right->value.ival= newllabel ());
564 genvalue (re->right);
565 fprintf (ccode, ";");
566 typellabel (re->value.ival);
567 break;
568 case MELSE:
569 genvalue (re->left);
570 fprintf (ccode, ";");
571 gotollabel (re->up->value.ival= newllabel ());
572 typellabel (re->value.ival);
573 genvalue (re->right);
574 break;
575 case MORELSE:
576 case MANDTHEN:
577 fprintf (ccode, "if(");
578 if (re->token == MANDTHEN)
579 fprintf (ccode, "!");
580 genvalue (re->left);
581 fprintf (ccode, ")");
582 gotollabel ((int) (re->value.ival = newllabel ()));
583 genvalue (re->right);
584 fprintf (ccode, ";");
585 typellabel ((int) re->value.ival);
586 break;
587 case MUADD:
588 case MUADDI:
589 genvalue (re->left);
590 break;
591 case MUSUB:
592 case MUSUBI:
593 fprintf (ccode, "(-");
594 genvalue (re->left);
595 fprintf (ccode, ")");
596 break;
597 case MPRIMARY:
598 fprintf (ccode, "__rpow(");
599 genvalue (re->left);
600 fprintf (ccode, ",");
601 genvalue (re->right);
602 fprintf (ccode, ")");
603 break;
604 case MPRIMARYII:
605 fprintf (ccode, "__rpowii(");
606 genvalue (re->left);
607 fprintf (ccode, ",");
608 genvalue (re->right);
609 fprintf (ccode, ")");
610 break;
611 case MPRIMARYRI:
612 fprintf (ccode, "__rpowri(");
613 genvalue (re->left);
614 fprintf (ccode, ",");
615 genvalue (re->right);
616 fprintf (ccode, ")");
617 break;
618 case MREAINT:
619 fprintf (ccode, "(double)");
620 genvalue (re->left);
621 break;
622 case MINTREA:
623 fprintf (ccode, "__rintrea(");
624 genvalue (re->left);
625 fprintf (ccode, ")");
626 break;
627 case MCONC:
628 fprintf (ccode, "__t[%d]= *__rconc(%ldL,",
629 re->value.combined_stack.entry,
630 re->value.combined_stack.n_of_stack_elements);
631 genvalue (re->left);
632 fprintf (ccode, ",");
633 genvalue (re->right);
634 fprintf (ccode, ");");
635
636 break;
637 case MTEXTKONST:
638 fprintf (ccode, "(__txtvp)&__tk%d%s", re->value.tval.id,
639 re->value.tval.id == NOTEXT ? "" : timestamp);
640 break;
641 case MCHARACTERKONST:
642 case MBOOLEANKONST:
643 if (re->value.ival < 0)
644 fprintf (ccode, " ");
645 fprintf (ccode, "%d", (int) re->value.ival);
646 break;
647 case MINTEGERKONST:
648 if (re->value.ival < 0)
649 fprintf (ccode, " ");
650 if (re->value.ival == (-MAX_INT - 1))
651 {
652 fprintf (ccode, "(%ldL-1L)", re->value.ival+1);
653 } else
654 {
655 fprintf (ccode, "%ldL", re->value.ival);
656 }
657 break;
658 case MREALKONST:
659 if (re->value.rval <= 0.0)
660 fprintf (ccode, " ");
661 fprintf (ccode, "%.16le", re->value.rval);
662 break;
663 case MNONE:
664 fprintf (ccode, "__NULL");
665 break;
666 case MSTACK:
667 switch (re->type)
668 {
669 case TREF:
670 fprintf (ccode, "__r[%d]", re->value.entry);
671 break;
672 case TINTG:
673 fprintf (ccode, "__v[%d].i", re->value.entry);
674 break;
675 case TREAL:
676 fprintf (ccode, "__v[%d].f", re->value.entry);
677 break;
678 case TTEXT:
679 fprintf (ccode, "&__t[%d]", re->value.entry);
680 break;
681 case TNOTY:
682 break;
683 default:
684 fprintf (ccode, "__v[%d].c", re->value.entry);
685 break;
686 }
687 break;
688 case MEXITARGUMENT:
689 switch (re->type)
690 {
691 case TREF:
692 fprintf (ccode, "__er");
693 break;
694 case TINTG:
695 fprintf (ccode, "__ev.i");
696 break;
697 case TREAL:
698 fprintf (ccode, "__ev.f");
699 break;
700 case TTEXT:
701 fprintf (ccode, "&__et");
702 break;
703 default:
704 fprintf (ccode, "__ev.c");
705 break;
706 }
707 break;
708 case MIDENTIFIER:
709 if (re->type != TLABEL)
710 {
711 if (re->rd->categ == CVAR || re->rd->categ == CNAME)
712 {
713 if (re->rd->categ == CVAR && re->rd->kind != KARRAY &&
714 (re->type == TREAL || re->type == TINTG) &&
715 (!(re->up->token == MASSIGN && re->up->left == re)))
716 { /* Lese aksess av aritm. var-parameter. For
717 * bare er gjort RT-call for skrive-aksess.
718 */
719 if (re->type == TINTG)
720 { /* To muligheter : ingen eller real -> int */
721 fprintf (ccode, "((__vvp= &(");
722 gensl (re, TRUE, ON);
723 fprintf (ccode, "%s))->conv==__NOCONV?"
724 " *(long *)(((char *)__vvp->bp)+"
725 "__vvp->ofs):__rintrea("
726 " *(double *)(((char *)__vvp->bp)"
727 "+__vvp->ofs)))",
728 re->rd->ident);
729 }
730 else
731 { /* Tre muligheter : ingen, int -> real,
732 * real->int->real */
733 fprintf (ccode, "((__vvp= &(");
734 gensl (re, TRUE, ON);
735 fprintf (ccode, "%s))->conv==__NOCONV?"
736 " *(double *)(((char *)__vvp->bp)+__vvp->ofs):"
737 "(__vvp->conv==__INTREAL?(double)"
738 " *(long *)(((char *)__vvp->bp)+__vvp->ofs):"
739 "(double)__rintrea( *(double *)"
740 "(((char *)__vvp->bp)+__vvp->ofs))))",
741 re->rd->ident);
742 }
743 }
744 else if (re->rd->categ == CNAME
745 && re->up->token == MASSIGN &&
746 re->up->right == re)
747 {
748 /* Lese-aksess av en name-parameter som det nettopp
749 * er gjort skrive-aksess p}. Vanligvis gj|res
750 * konvertering av NAME-parametere av RT-rutiene, men
751 * ikke i tilfelle med multippel assignment. Det gj|res
752 * da her. Noden er omd|pt fra MNAMEADR til
753 * MIDENTIFER i case MASSIGN grenen i genvalue. */
754
755 if (re->type == TINTG)
756 { /* To muligheter : ingen eller real -> int */
757 fprintf (ccode, "((");
758 gensl (re, TRUE, ON);
759 fprintf (ccode, "%s)->conv==__NOCONV?"
760 " *(long *)(((char *)__r[%d])+__v[%d].i):"
761 "__rintrea("
762 " *(double *)(((char *)__r[%d])+__v[%d].i)))",
763 re->rd->ident,
764 re->value.stack.ref_entry, re->value.stack.val_entry,
765 re->value.stack.ref_entry, (int) re->value.stack.val_entry);
766 }
767 else
768 { /* Tre muligheter : ingen,int ->
769 * real,real->int->real */
770 fprintf (ccode, "((__nvp= &(");
771 gensl (re, TRUE, ON);
772 fprintf (ccode, "%s))->conv==__NOCONV?"
773 " *(double *)(((char *)__r[%d])+__v[%d].i):"
774 "(__nvp->conv==__INTREAL?(double)"
775 " *(long *)(((char *)__r[%d])+__v[%d].i):"
776 "(double)__rintrea( *(double *)"
777 "(((char *)__r[%d])+__v[%d].i))))",
778 re->rd->ident,
779 re->value.stack.ref_entry, re->value.stack.val_entry,
780 re->value.stack.ref_entry, re->value.stack.val_entry,
781 re->value.stack.ref_entry, re->value.stack.val_entry);
782 }
783 }
784 else if (re->type == TREF && re->rd->categ == CVAR &&
785 !(re->up->token == MASSIGNR && re->up->left == re))
786 {
787 /* Lese-aksess av referanse var-parametere. Legger inn
788 * kode som sjekker om re er "in" strengeste
789 * kvalifikasjon p} aksessveien. */
790
791 fprintf (ccode, "((((__vrp= &");
792 gensl (re, TRUE, ON);
793 fprintf (ccode, "%s)->conv==__READTEST "
794 "|| __vrp->conv==__READWRITETEST) &&"
795 " !__rin((__bp= *(__dhp *)(((char *)__vrp->bp)+"
796 "__vrp->ofs)),__vrp->q))?(__dhp)__rerror(__errqual)"
797 ":(__bp= *(__dhp *)(((char *)__vrp->bp)+"
798 "__vrp->ofs)))",
799 re->rd->ident);
800 }
801 else
802 {
803 /* For parametere av type Character, Boolean, LESE og
804 * SKRIVE-AKSESS AV B]DE VAR OG NAME- PARAMETERE som
805 * ikke er behandlet lengre oppe */
806
807 if (re->rd->kind == KARRAY)
808 if (re->rd->categ ==CNAME)
809 fprintf (ccode, "(__arrp)__er");
810 else
811 {
812 gensl (re, TRUE, ON);
813 fprintf (ccode, "%s", re->rd->ident);
814 }
815 else
816 {
817 if (re->type == TTEXT)
818 fprintf (ccode, " (");
819 else
820 fprintf (ccode, " *(");
821 gentype (re);
822 fprintf (ccode, " *)(((char *)");
823
824 gensl (re, TRUE, ON);
825 fprintf (ccode, "%s.", re->rd->ident);
826
827 if (re->rd->categ == CVAR)
828 fprintf (ccode,
829 "bp)+");
830 else
831 fprintf (ccode, "bp)+",
832 re->rd->ident);
833
834 gensl (re, TRUE, ON);
835 fprintf (ccode, "%s.", re->rd->ident);
836
837 if (re->rd->categ == CVAR)
838 fprintf (ccode, "ofs)", re->rd->ident);
839 else
840 fprintf (ccode, "v.ofs)",
841 re->rd->ident);
842 }
843 }
844 } /* End Var eller Name-parameter */
845 else
846 {
847 if (re->type == TTEXT && re->rd->kind != KARRAY)
848 fprintf (ccode, "(__txtvp)&");
849 gensl (re, TRUE, ON);
850 fprintf (ccode, "%s", re->rd->ident);
851 }
852 break;
853 }
854 /* Ingen break her */
855 case MARRAYARG:
856 if (re->type == TLABEL)
857 {
858 if (re->token == MARRAYARG)
859 {
860 fprintf (ccode, "__swv=");
861 genvalue (re->right->left);
862 fprintf (ccode, ";");
863 }
864 switch (re->rd->categ)
865 {
866 case CNAME:
867 if (re->token == MIDENTIFIER)
868 {
869 /* Transcall har skrevet ut kallet p} rgetlab, slik at adressen
870 * ligger i modul og ev, og objekt- pekeren ligger i er. */
871 fprintf (ccode, "__rgoto(__er);__goto=__ev.adr;");
872 gotoswitch ();
873 break;
874 }
875 /* Inge break her */
876 case CDEFLT:
877 case CVAR:
878 /* Setter bp, en hjelpevariabel, til } peker p} den aktuelle
879 * parameterens blokk. Dermed blir aksessveien kortere
880 * for de etterf|lgende aksessene */
881 fprintf (ccode, "__bp=");
882 gensl (re, FALSE, ON);
883 fprintf (ccode, ";__rgoto(((__bs%d *)__bp)->%s.ob);"
884 "__goto=((__bs%d *)__bp)->%s.adr;",
885 re->rd->encl->blno, re->rd->ident,
886 re->rd->encl->blno, re->rd->ident);
887 gotoswitch ();
888 break;
889 case CVIRT:
890 if (cblock->blev > re->rd->encl->blev)
891 {
892 fprintf (ccode, "__rgoto(");
893 gensl (re, FALSE, ON);
894 fprintf (ccode, ");");
895 fprintf (ccode, "if((__pp=__lb");
896 }
897 else
898 {
899 fprintf (ccode, "if((__pp=");
900 genchain (re->rd->encl, FALSE);
901 }
902
903 fprintf (ccode, "->pp)->virtlab[%d].ent==0)"
904 "__rerror(__errvirt);__goto=__pp->virtlab[%d];",
905 re->rd->virtno - 1, re->rd->virtno - 1);
906 gotoswitch ();
907 break;
908 case CLOCAL:
909 if (cblock->blev > re->rd->encl->blev)
910 {
911 fprintf (ccode, "__rgoto(");
912 gensl (re, FALSE, ON);
913 fprintf (ccode, ");");
914 }
915 if (re->rd->plev == 0)
916 re->rd->plev = newlabel ();
917 if (re->rd->encl->timestamp != 0)
918 {
919 /* Skal hoppe til en label i en annen modul */
920 fprintf (ccode, "__goto.ent=%d;__goto.ment=",
921 re->rd->plev);
922 genmodulemark(re->rd->encl->timestamp);
923 fprintf (ccode, ";");
924 gotoswitch ();
925 }
926 else
927 gotolabel (re->rd->plev);
928 break;
929 }
930 not_reached = TRUE;
931 }
932 else
933 {
934 int i, dim;
935 /* Legger ut kode som sjekker indeksene og at det antall indekser
936 * stemmer med dimmensjonen */
937
938 if (re->rd->categ != CNAME) /* Name er behandlet ovenfor */
939 {
940 fprintf (ccode, "__r[%d]=(__dhp)", re->value.stack.ref_entry);
941 gensl (re, TRUE, ON);
942 fprintf (ccode, "%s;", re->rd->ident);
943 }
944
945 if (re->rd->dim == 0)
946 {
947 /* Array som parameter.M} legge ut kode som sjekker dimmensjonen
948 * ved Run-time */
949 dim= 0;
950 for (rex = re->right; rex->token != MENDSEP; rex = rex->right)
951 dim++;
952
953 fprintf
954 (ccode, "((__arrp)__r[%d])->h.dim!=%d?__rerror(__errarr):1;",
955 re->value.stack.ref_entry, dim, re->rd->ident);
956 }
957 dim= 0;
958 for (rex = re->right; rex->token != MENDSEP; rex = rex->right)
959 {
960 if (dim == MAX_ARRAY_DIM)
961 gerror (85);
962 fprintf (ccode, "__h[%d]=", dim++);
963 genvalue (rex->left);
964 fprintf (ccode, "-((__arrp)__r[%d])->limits[%d].low;",
965 re->value.stack.ref_entry, dim - 1);
966 }
967 fprintf (ccode, "if(");
968 for (i = 0; i < dim; i++)
969 {
970 fprintf (ccode, "__h[%d]<0 || __h[%d]>=((__arrp)"
971 "__r[%d])->limits[%d].size",
972 i, i, re->value.stack.ref_entry, i);
973 if (i < dim - 1)
974 fprintf (ccode, " || ");
975 }
976 fprintf (ccode, ")__rerror(__errbound);"
977 "__v[%d].i=sizeof(__ah)+sizeof(__arrlimit)*%d+((",
978 re->value.stack.val_entry, dim);
979 for (i = dim - 1; i > 0; i--)
980 {
981 fprintf (ccode, "((__arrp)__r[%d])->limits[%d].size*(",
982 re->value.stack.ref_entry, i);
983 }
984
985 fprintf (ccode, "__h[0])");
986
987 for (i = 1; i < dim; i++)
988 fprintf (ccode, "+__h[%d])", i);
989 fprintf (ccode, "*sizeof(");
990 gentype (re);
991 fprintf (ccode, "));");
992 }
993 break;
994 case MNAMEREADACESS:
995 case MNAMEWRITEACESS:
996 fprintf (ccode, "if(");
997 if (re->rd->kind == KPROC)
998 fprintf (ccode, "__rgetproc(");
999 else if (re->rd->kind == KARRAY)
1000 fprintf (ccode, "__rgeta(");
1001 else if (re->token == MNAMEWRITEACESS)
1002 fprintf (ccode, "__rgetsa(");
1003 else
1004 switch (re->type)
1005 {
1006 case TINTG:
1007 fprintf (ccode, "__rgetav(__TINTG,");
1008 break;
1009 case TREAL:
1010 fprintf (ccode, "__rgetav(__TREAL,");
1011 break;
1012 case TCHAR:
1013 case TBOOL:
1014 fprintf (ccode, "__rgetcbv(");
1015 break;
1016 case TREF:
1017 fprintf (ccode, "__rgetrv(");
1018 break;
1019 case TTEXT:
1020 fprintf (ccode, "__rgetta(");
1021 break;
1022 case TLABEL:
1023 fprintf (ccode, "__rgetlab(");
1024 break;
1025 }
1026 fprintf (ccode, "&");
1027 gensl (re, TRUE, ON);
1028 {
1029 int i;
1030 fprintf (ccode, "%s,%ldL,%d,", re->rd->ident,
1031 re->value.n_of_stack_elements, i = newlabel ());
1032 genmodulemark(NULL);
1033 fprintf (ccode, "))");
1034 exitcondlabel (i);
1035 }
1036 break;
1037 case MNAMEREADTEXT:
1038 fprintf (ccode, "switch (");
1039 gensl (re, TRUE, ON);
1040 fprintf (ccode, "%s.namekind){"
1041 "case __ADDRESS_THUNK: case __ADDRESS_NOTHUNK: "
1042 "__v[%d].i=__ev.i;__r[%d]=__er;"
1043 "break; case __VALUE_THUNK: case __VALUE_NOTHUNK: "
1044 "__t[%d]=__et;__r[%d] = __NULL;"
1045 "__v[%d].i = ((char *)&__t[%d])-((char *) 0);}",
1046 re->rd->ident, re->value.stack.val_entry, re->value.stack.ref_entry,
1047 re->value.stack.txt_entry, re->value.stack.ref_entry,
1048 re->value.stack.val_entry, re->value.stack.txt_entry);
1049 break;
1050 case MPROCASSIGN:
1051 if (re->type == TNOTY)
1052 break;
1053 if (re->type == TTEXT)
1054 fprintf (ccode, "&");
1055 genchain (re->rd->descr, TRUE);
1056 if (re->type == TREF)
1057 fprintf (ccode, "er");
1058 else if (re->type == TTEXT)
1059 fprintf (ccode, "et");
1060 else if (re->type == TREAL)
1061 fprintf (ccode, "ef");
1062 else if (re->type == TINTG)
1063 fprintf (ccode, "ev");
1064 else
1065 fprintf (ccode, "ec");
1066 break;
1067 case MTHIS:
1068 if (seen_th_insp (re))
1069 {
1070 genchain (re->seenthrough->quant.match->descr, TRUE);
1071 fprintf (ccode, "c%d", re->seenthrough->connest);
1072 }
1073 else
1074 genchain (re->qual->descr, FALSE);
1075 break;
1076 case MQUA:
1077 /* Sjekker om det er n\dvendig } utf\re en none-test, eller om den er
1078 * utf\rt lengre ned i treet. */
1079 if (re->left->token != MDOT && re->left->token != MQUA &&
1080 re->left->token != MQUANOTNONE && nonetest == ON)
1081 {
1082 fprintf (ccode, "((__bp=");
1083 genvalue (re->left);
1084 fprintf (ccode, ")==__NULL?(__dhp)__rerror(__errnone):(__bp");
1085 }
1086 else
1087 {
1088 fprintf (ccode, "(((__bp=");
1089 genvalue (re->left);
1090 fprintf (ccode, ")");
1091 }
1092 if (re->qual->plev >= DEF_PLEV_TAB_SIZE)
1093 fprintf (ccode, "->pp->plev<%d || __bp",
1094 re->qual->plev);
1095
1096 fprintf (ccode, "->pp->pref[%d] != ",
1097 re->qual->plev);
1098 gen_adr_prot (ccode, re->qual);
1099 fprintf (ccode, ")?(__dhp)__rerror(__errqual):__bp)");
1100 break;
1101 case MQUANOTNONE:
1102 /* Sjekker om det er n\dvendig } utf\re en none-test, eller om den er
1103 * utf\rt lengre ned i treet. */
1104 if (re->left->token != MDOT && re->left->token != MQUA &&
1105 re->left->token != MQUANOTNONE)
1106 {
1107 if (nonetest == ON)
1108 fprintf (ccode, "((__bp=");
1109 genvalue (re->left);
1110 if (nonetest == ON)
1111 fprintf (ccode,
1112 ")==__NULL?(__dhp)__rerror(__errnone):__bp)");
1113 }
1114 else
1115 genvalue (re->left);
1116 break;
1117 case MQUANONEAND:
1118 if (re->left->token == MNONE)
1119 fprintf (ccode, "__NULL");
1120 else
1121 {
1122 fprintf (ccode, "(((__bp=");
1123 genvalue (re->left);
1124 fprintf (ccode, ")!=__NULL && (");
1125 if (re->qual->plev >= DEF_PLEV_TAB_SIZE)
1126 fprintf (ccode, "__bp->pp->plev<%d || ",
1127 re->qual->plev);
1128 fprintf (ccode, "__bp->pp->pref[%d]!= ",
1129 re->qual->plev);
1130 gen_adr_prot (ccode, re->qual);
1131 fprintf (ccode, "))?(__dhp)__rerror(__errqual):__bp)");
1132 }
1133 break;
1134 case MDOT:
1135 genvalue (re->right);
1136 break;
1137 case MDOTCONST:
1138 if (nonetest == ON)
1139 fprintf (ccode, "((");
1140 if (nonetest == ON)
1141 genvalue (re->left);
1142 if (nonetest == ON)
1143 fprintf (ccode, ")==__NULL?(");
1144 gentype (re);
1145 if (re->type == TTEXT)
1146 fprintf (ccode, " *");
1147 if (nonetest == ON)
1148 fprintf (ccode, ")__rerror(__errnone):");
1149 genvalue (re->right);
1150 if (nonetest == ON)
1151 fprintf (ccode, ")");
1152
1153 break;
1154 case MTEXTADR:
1155 case MNAMEADR:
1156 case MARRAYADR:
1157 if (re->type == TTEXT)
1158 fprintf (ccode, " ((");
1159 else
1160 fprintf (ccode, " (*(");
1161 gentype (re);
1162 fprintf (ccode, " *)(((char *)__r[%d])+__v[%d].i))",
1163 re->value.stack.ref_entry, re->value.stack.val_entry);
1164 break;
1165 case MREFASSIGNT:
1166 fprintf (ccode, "__rtextassign(");
1167 genvalue (re->left);
1168 fprintf (ccode, ",");
1169 genvalue (re->right);
1170 fprintf (ccode, ")");
1171 break;
1172 case MVALASSIGNT:
1173 fprintf (ccode, "__rtextvalassign(");
1174 genvalue (re->left);
1175 fprintf (ccode, ",");
1176 genvalue (re->right);
1177 fprintf (ccode, ")");
1178 break;
1179 case MASSIGND:
1180 genvalue (re->left);
1181 fprintf(ccode, "= ");
1182 genvalue (re->right);
1183 break;
1184 case MASSIGNADD:
1185 genvalue (re->left);
1186 fprintf(ccode, "+= ");
1187 genvalue (re->right);
1188 break;
1189 case MASSIGN:
1190 if (re->right->token == MASSIGN)
1191 {
1192 genvalue (re->right);
1193 fprintf (ccode, ";");
1194 }
1195 fprintf (ccode, "(");
1196
1197 if (re->left->rd!=NULL && re->left->rd->kind == KSIMPLE &&
1198 (re->left->rd->categ == CVAR || re->left->rd->categ == CNAME)
1199 && (re->left->type == TINTG || re->left->type == TREAL))
1200 { /* For aritmetiske, for } h{ndtere
1201 * konvertering. */
1202 if (re->type == TREAL)
1203 fprintf (ccode, "__ev.f");
1204 else if (re->type == TINTG)
1205 fprintf (ccode, "__ev.i");
1206 }
1207 else
1208 genvalue (re->left);
1209 fprintf (ccode, "=");
1210 if (re->left->type == TINTG && re->right->type == TREAL)
1211 fprintf (ccode, "__rintrea");
1212 fprintf (ccode, "(");
1213 if (re->right->token == MASSIGN)
1214 {
1215 if (re->right->left->token == MNAMEADR
1216 || re->right->left->token == MTEXTADR)
1217 {
1218 if (re->right->left->type == TREAL)
1219 fprintf (ccode, "__ev.f");
1220 else if (re->right->left->type == TINTG)
1221 fprintf (ccode, "__ev.i");
1222 else genvalue (re->right->left);
1223 }
1224 else
1225 genvalue (re->right->left);
1226 }
1227 else
1228 genvalue (re->right);
1229 fprintf (ccode, "))");
1230 if (re->left->rd!= NULL && re->left->rd->kind == KSIMPLE)
1231 {
1232 if (re->left->rd->categ == CVAR &&
1233 (re->type == TINTG || re->type == TREAL))
1234
1235 {
1236 /* SKRIVE-AKSESS AV ARIT. VAR-PARAMETER */
1237 fprintf (ccode, ";");
1238
1239 /* M| sjekke ved runtime om det skal gjores
1240 * konvertering. */
1241
1242 if (re->type == TINTG)
1243 {
1244 /* To muligheter : ingen, real -> int */
1245 fprintf (ccode, "if((__vvp= &");
1246 gensl (re->left, TRUE, ON);
1247 fprintf (ccode, "%s)->conv==__NOCONV)"
1248 " *(long *)(((char *)__vvp->bp)+"
1249 "__vvp->ofs)=__ev.i;"
1250 "else *(double *)(((char *)__vvp->bp)+"
1251 "__vvp->ofs)=__ev.i",
1252 re->left->rd->ident);
1253 }
1254 else
1255 { /* Tre muligheter : ingen, int -> real, og
1256 * real ->int ->real */
1257 fprintf (ccode, "if((__vvp= &");
1258 gensl (re->left, TRUE, ON);
1259 fprintf (ccode, "%s)->conv==__NOCONV)"
1260 "if(__vvp->conv==__INTREAL)"
1261 " *(double *)(((char *)__vvp->bp)+"
1262 "__vvp->ofs)=__ev.f;else "
1263 " *(long *)(((char *)__vvp->bp)+"
1264 "__vvp->ofs)=__ev.f;else "
1265 " *(double *)(((char *)__vvp->bp)+"
1266 "__vvp->ofs)=__rintrea(__ev.f)",
1267 re->left->rd->ident);
1268 }
1269 }
1270 else if (re->left->rd->categ == CNAME &&
1271 (re->type == TINTG || re->type == TREAL))
1272 {
1273 /* SKRIVE-AKSESS AV ARIT. NAME-PARAMETER */
1274 fprintf (ccode, ";");
1275
1276 /* M| sjekke ved runtime om det skal gjores konvertering. */
1277
1278 if (re->type == TINTG)
1279 { /* To muligheter : ingen, real -> int */
1280 fprintf (ccode, "if(");
1281 gensl (re->left, TRUE, ON);
1282 fprintf (ccode, "%s.conv==__NOCONV)"
1283 " *(long *)(((char *)__r[%d])+__v[%d].i)=__ev.i;"
1284 "else *(double *)(((char *)__r[%d])+__v[%d].i)="
1285 "__ev.i",
1286 re->left->rd->ident,
1287 re->left->value.stack.ref_entry,
1288 re->left->value.stack.val_entry,
1289 re->left->value.stack.ref_entry,
1290 re->left->value.stack.val_entry);
1291 }
1292 else
1293 { /* Tre muligheter : ingen, int -> real og
1294 * real ->int ->real */
1295 fprintf (ccode, "if((__nvp= &");
1296 gensl (re->left, TRUE, ON);
1297 fprintf (ccode, "%s)->conv==__NOCONV)"
1298 " *(double *)(((char *)__r[%d])+"
1299 "__v[%d].i)=__ev.f;else "
1300 "if(__nvp->conv==__INTREAL)"
1301 " *(long *)(((char *)__r[%d])+"
1302 "__v[%d].i)=__ev.f;else "
1303 " *(double *)(((char *)__r[%d])+"
1304 "__v[%d].i)=__rintrea(__ev.f)",
1305 re->left->rd->ident,
1306 re->left->value.stack.ref_entry,
1307 re->left->value.stack.val_entry,
1308 re->left->value.stack.ref_entry,
1309 re->left->value.stack.val_entry,
1310 re->left->value.stack.ref_entry,
1311 re->left->value.stack.val_entry);
1312 }
1313 }
1314 }
1315 break;
1316 case MINSTRONGEST:
1317 fprintf (ccode, "if(((__nrp= &(");
1318 gensl (re->left, TRUE, ON);
1319 fprintf (ccode, "%s))->conv==__WRITETEST || __nrp->conv=="
1320 "__READWRITETEST) && !__rin(", re->left->rd->ident);
1321 genvalue (re->right);
1322 fprintf (ccode, ",__nrp->q))__rerror(__errqual);");
1323 break;
1324 case MASSIGNR:
1325 genvalue (re->left);
1326 fprintf (ccode, "=");
1327 if ((rex = re->left)->token == MIDENTIFIER && rex->rd->categ == CVAR)
1328 {
1329 /* SKRIVE-AKSESS P} REFERANSE VAR-PARAMETER M} da
1330 * legge inn kode som ,hvis n|dvendig , sjekker om h|yre side er
1331 * 'in' strengeste kvalifikasjon p} aksessveien */
1332
1333 fprintf (ccode, "((((__vrp= &");
1334 gensl (rex, TRUE, ON);
1335 fprintf (ccode, "%s)->conv==__WRITETEST "
1336 "|| __vrp->conv==__READWRITETEST) && !__rin((__bp= ",
1337 rex->rd->ident);
1338 genvalue (re->right);
1339 fprintf
1340 (ccode, "),__vrp->q))?(__dhp)__rerror(__errqual):(__bp=");
1341 genvalue (re->right);
1342 fprintf (ccode, "))");
1343 }
1344 else
1345 genvalue (re->right);
1346 break;
1347 case MNOOP:
1348 if (re->type == TTEXT)
1349 {
1350 /* Parantes i forbindelse med tekster. Venstre-siden skal legges p}
1351 * en anonym tekst-variabel. */
1352 fprintf (ccode, "__rtextassign(&__et,");
1353 genvalue (re->left);
1354 fprintf (ccode, ")");
1355 }
1356 else
1357 genvalue (re->left);
1358 break;
1359 case MSL:
1360
1361 break;
1362 case MSENTCONC:
1363 genvalue (re->left);
1364 fprintf (ccode, ";");
1365 genvalue (re->right);
1366 break;
1367 case MDIV:
1368 case MINTDIV:
1369 putc ('(', ccode);
1370 genvalue (re->left);
1371 fprintf (ccode, "/");
1372
1373 #ifdef DIV0
1374 if (re->token == MINTDIV)
1375 fprintf (ccode, "__ridiv0 (");
1376 else
1377 fprintf (ccode, "__rrdiv0 (");
1378 #endif /* DIV0 */
1379
1380 genvalue (re->right);
1381 putc (')', ccode);
1382
1383 #ifdef DIV0
1384 putc (')', ccode);
1385 #endif /* DIV0 */
1386 break;
1387 default:
1388 putc ('(', ccode);
1389 if (re->left->type == TCHAR)
1390 fprintf (ccode, "(unsigned char)");
1391 genvalue (re->left);
1392 switch (re->token)
1393 {
1394 case MORELSEE:
1395 fprintf (ccode, "||");
1396 break;
1397 case MANDTHENE:
1398 fprintf (ccode, "&&");
1399 break;
1400 case MOR:
1401 fprintf (ccode, "|");
1402 break;
1403 case MAND:
1404 fprintf (ccode, "&");
1405 break;
1406 case MEQV:
1407 case MEQ:
1408 case MEQR:
1409 fprintf (ccode, "==");
1410 break;
1411 case MNE:
1412 case MNER:
1413 fprintf (ccode, "!=");
1414 break;
1415 case MLT:
1416 fprintf (ccode, "<");
1417 break;
1418 case MLE:
1419 fprintf (ccode, "<=");
1420 break;
1421 case MGT:
1422 fprintf (ccode, ">");
1423 break;
1424 case MGE:
1425 fprintf (ccode, ">=");
1426 break;
1427 case MADD:
1428 case MADDI:
1429 fprintf (ccode, "+");
1430 break;
1431 case MSUB:
1432 case MSUBI:
1433 fprintf (ccode, "-");
1434 break;
1435 case MMUL:
1436 case MMULI:
1437 fprintf (ccode, "*");
1438 break;
1439 default:
1440 #ifdef DEBUG
1441 fprintf (stderr, "Illegal token:%s\n"
1442 ,texttoken (re->token));
1443 #else
1444 fprintf (stderr, "Illegal token:%d\n"
1445 ,re->token);
1446 #endif
1447 break;
1448 }
1449 if (re->left->type == TCHAR)
1450 fprintf (ccode, "(unsigned char)");
1451 genvalue (re->right);
1452 putc (')', ccode);
1453 }
1454 }
1455
1456 /*****************************************************************************
1457 GEN_TEXTCONST */
1458
1459 gen_textconst (re) struct EXP *re;
1460 {
1461 if (re->value.tval.id == NOTEXT)
1462 {
1463 char *t;
1464 static int it = 0;
1465 int antchar;
1466 t = re->value.tval.txt;
1467 antchar = sstrlen (t);
1468 if (antchar == 0)
1469 re->value.tval.id = NOTEXT;
1470 else
1471 {
1472 anttext++;
1473 fprintf (ccode, "struct __tt%d {__txt tvar;__th h;"
1474 "char string[%d];}\n__tk%d%s={(__textref)"
1475 "&__tk%d%s.h.pp,%d,1,1,(__pty)__TEXT,"
1476 "(__dhp)&__tk%d%s.h.pp,__CONSTANT,%d,\"%s\"};\n",
1477 anttext, antchar + 1,
1478 anttext, timestamp, anttext, timestamp,
1479 antchar, anttext, timestamp, antchar, t);
1480
1481 re->value.tval.id = anttext;
1482 }
1483 }
1484 }
1485