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