1 /****************************************************************
2 Copyright 1990, 1991 by AT&T Bell Laboratories and Bellcore.
4 Permission to use, copy, modify, and distribute this software
5 and its documentation for any purpose and without fee is hereby
6 granted, provided that the above copyright notice appear in all
7 copies and that both that the copyright notice and this
8 permission notice and warranty disclaimer appear in supporting
9 documentation, and that the names of AT&T Bell Laboratories or
10 Bellcore or any of their entities not be used in advertising or
11 publicity pertaining to distribution of the software without
12 specific, written prior permission.
14 AT&T and Bellcore disclaim all warranties with regard to this
15 software, including all implied warranties of merchantability
16 and fitness. In no event shall AT&T or Bellcore be liable for
17 any special, indirect or consequential damages or any damages
18 whatsoever resulting from loss of use, data or profits, whether
19 in an action of contract, negligence or other tortious action,
20 arising out of or in connection with the use or performance of
22 ****************************************************************/
30 static void p1_addr(), p1_big_addr(), p1_binary(), p1_const(), p1_list(),
31 p1_literal(), p1_name(), p1_unary(), p1putn();
32 static void p1putd (/* int, int */);
33 static void p1putds (/* int, int, char * */);
34 static void p1putdds (/* int, int, int, char * */);
35 static void p1putdd (/* int, int, int */);
36 static void p1putddd (/* int, int, int, int */);
39 /* p1_comment -- save the text of a Fortran comment in the intermediate
40 file. Make sure that there are no spurious "/ *" or "* /" characters by
41 mapping them onto "/+" and "+/". str is assumed to hold no newlines and be
42 null terminated; it may be modified by this function. */
47 register unsigned char *pointer, *ustr;
52 /* Get rid of any open or close comment combinations that may be in the
55 ustr = (unsigned char *)str;
56 for(pointer = ustr; *pointer; pointer++)
57 if (*pointer == '*' && (pointer[1] == '/'
58 || pointer > ustr && pointer[-1] == '/'))
60 /* trim trailing white space */
62 while(--pointer >= ustr && (!isascii(*pointer) || isspace(*pointer)));
64 while(--pointer >= ustr && isspace(*pointer));
67 p1puts (P1_COMMENT, str);
70 void p1_line_number (line_number)
74 p1putd (P1_SET_LINE, line_number);
75 } /* p1_line_number */
77 /* p1_name -- Writes the address of a hash table entry into the
80 static void p1_name (namep)
83 p1putd (P1_NAME_POINTER, (long) namep);
92 /* An opcode of 0 means a null entry */
95 p1putdd (P1_EXPR, 0, TYUNKNOWN); /* Should this be TYERROR? */
97 } /* if (expr == ENULL) */
99 switch (expr -> tag) {
101 p1_name ((Namep) expr);
104 p1_const(&expr->constblock);
107 /* Fall through the switch */
110 p1_addr (&(expr -> addrblock));
113 warn ("p1_expr: got TPRIM");
116 p1_list (&(expr->listblock));
117 frchain( &(expr->listblock.listp) );
122 erri ("p1_expr: bad tag '%d'", (int) (expr -> tag));
126 /* Now we know that the tag is TEXPR */
128 if (is_unary_op (expr -> exprblock.opcode))
129 p1_unary (&(expr -> exprblock));
130 else if (is_binary_op (expr -> exprblock.opcode))
131 p1_binary (&(expr -> exprblock));
133 erri ("p1_expr: bad opcode '%d'", (int) expr -> exprblock.opcode);
141 static void p1_const(cp)
144 int type = cp->vtype;
145 expptr vleng = cp->vleng;
146 union Constant *c = &cp->Const;
147 char cdsbuf0[64], cdsbuf1[64];
154 fprintf(pass1_file, "%d: %d %ld\n", P1_CONST, type, c->ci);
158 fprintf(pass1_file, "%d: %d %s\n", P1_CONST, type,
159 cp->vstg ? c->cds[0] : cds(dtos(c->cd[0]), cdsbuf0));
168 cds0 = cds(dtos(c->cd[0]), cdsbuf0);
169 cds1 = cds(dtos(c->cd[1]), cdsbuf1);
171 fprintf(pass1_file, "%d: %d %s %s\n", P1_CONST, type,
175 if (vleng && !ISICON (vleng))
176 erri("p1_const: bad vleng '%d'\n", (int) vleng);
178 fprintf(pass1_file, "%d: %d %lx\n", P1_CONST, type,
182 erri ("p1_const: bad constant type '%d'", type);
188 void p1_asgoto (addrp)
196 void p1_goto (stateno)
199 p1putd (P1_GOTO, stateno);
203 static void p1_addr (addrp)
204 register struct Addrblock *addrp;
208 if (addrp == (struct Addrblock *) NULL)
213 if (ONEOF(stg, M(STGINIT)|M(STGREG))
214 || ONEOF(stg, M(STGCOMMON)|M(STGEQUIV)) &&
215 (!ISICON(addrp->memoffset)
216 || (addrp->uname_tag == UNAM_NAME
217 ? addrp->memoffset->constblock.Const.ci
218 != addrp->user.name->voffset
219 : addrp->memoffset->constblock.Const.ci))
220 || ONEOF(stg, M(STGBSS)|M(STGINIT)|M(STGAUTO)|M(STGARG)) &&
221 (!ISICON(addrp->memoffset)
222 || addrp->memoffset->constblock.Const.ci)
223 || addrp->Field || addrp->isarray || addrp->vstg == STGLENG)
229 /* Write out a level of indirection for non-array arguments, which have
230 addrp -> memoffset set and are handled by p1_big_addr().
231 Lengths are passed by value, so don't check STGLENG
232 28-Jun-89 (dmg) Added the check for != TYCHAR
235 if (oneof_stg ( addrp -> uname_tag == UNAM_NAME ? addrp -> user.name : NULL,
236 stg, M(STGARG)|M(STGEQUIV)) && addrp->vtype != TYCHAR) {
237 p1putdd (P1_EXPR, OPWHATSIN, addrp -> vtype);
238 p1_expr (ENULL); /* Put dummy vleng */
239 } /* if stg == STGARG */
241 switch (addrp -> uname_tag) {
243 p1_name (addrp -> user.name);
246 p1putdds(P1_IDENT, addrp->vtype, addrp->vstg,
250 p1putdds(P1_CHARP, addrp->vtype, addrp->vstg,
254 p1putd (P1_EXTERN, (long) addrp -> memno);
255 if (addrp->vclass == CLPROC)
256 extsymtab[addrp->memno].extype = addrp->vtype;
259 if (addrp -> memno != BAD_MEMNO)
260 p1_literal (addrp -> memno);
262 p1_const((struct Constblock *)addrp);
266 erri ("p1_addr: unknown uname_tag '%d'", addrp -> uname_tag);
272 static void p1_list (listp)
273 struct Listblock *listp;
278 if (listp == (struct Listblock *) NULL)
281 /* Count the number of parameters in the list */
283 for (lis = listp -> listp; lis; lis = lis -> nextp)
286 p1putddd (P1_LIST, listp -> tag, listp -> vtype, count);
288 for (lis = listp -> listp; lis; lis = lis -> nextp)
289 p1_expr ((expptr) lis -> datap);
297 if (parstate < INDATA)
298 earlylabs = mkchain((char *)lab, earlylabs);
300 p1putd (P1_LABEL, lab);
305 static void p1_literal (memno)
308 p1putd (P1_LITERAL, memno);
354 static void p1_big_addr (addrp)
357 if (addrp == (Addrp) NULL)
360 p1putn (P1_ADDR, sizeof (struct Addrblock), (char *) addrp);
361 p1_expr (addrp -> vleng);
362 p1_expr (addrp -> memoffset);
363 if (addrp->uname_tag == UNAM_NAME)
364 addrp->user.name->visused = 1;
369 static void p1_unary (e)
372 if (e == (struct Exprblock *) NULL)
375 p1putdd (P1_EXPR, (int) e -> opcode, e -> vtype);
376 p1_expr (e -> vleng);
378 switch (e -> opcode) {
393 erri ("p1_unary: bad opcode '%d'", (int) e -> opcode);
400 static void p1_binary (e)
403 if (e == (struct Exprblock *) NULL)
406 p1putdd (P1_EXPR, e -> opcode, e -> vtype);
407 p1_expr (e -> vleng);
408 p1_expr (e -> leftp);
409 p1_expr (e -> rightp);
413 void p1_head (class, name)
417 p1putds (P1_HEAD, class, name ? name : "");
421 void p1_subr_ret (retexp)
426 p1_expr (cpexpr(retexp));
431 void p1comp_goto (index, count, labels)
434 struct Labelblock *labels[];
438 register struct Labelblock *L;
440 p1put (P1_COMP_GOTO);
443 /* Write out a P1_LIST directly, to avoid the overhead of allocating a
444 list before it's needed HACK HACK HACK */
446 p1putddd (P1_LIST, TLIST, TYUNKNOWN, count);
450 for (i = 0; i < count; i++) {
453 c.Const.ci = L->stateno;
460 void p1_for (init, test, inc)
461 expptr init, test, inc;
478 /* ----------------------------------------------------------------------
479 The intermediate file actually gets written ONLY by the routines below.
480 To change the format of the file, you need only change these routines.
481 ----------------------------------------------------------------------
485 /* p1puts -- Put a typed string into the Pass 1 intermediate file. Assumes that
486 str contains no newlines and is null-terminated. */
488 void p1puts (type, str)
492 fprintf (pass1_file, "%d: %s\n", type, str);
496 /* p1putd -- Put a typed integer into the Pass 1 intermediate file. */
498 static void p1putd (type, value)
502 fprintf (pass1_file, "%d: %ld\n", type, value);
506 /* p1putdd -- Put a typed pair of integers into the intermediate file. */
508 static void p1putdd (type, v1, v2)
511 fprintf (pass1_file, "%d: %d %d\n", type, v1, v2);
515 /* p1putddd -- Put a typed triple of integers into the intermediate file. */
517 static void p1putddd (type, v1, v2, v3)
518 int type, v1, v2, v3;
520 fprintf (pass1_file, "%d: %d %d %d\n", type, v1, v2, v3);
528 static void p1putn (type, count, str)
534 fprintf (pass1_file, "%d: ", type);
536 for (i = 0; i < count; i++)
537 putc (str[i], pass1_file);
539 putc ('\n', pass1_file);
544 /* p1put -- Put a type marker into the intermediate file. */
549 fprintf (pass1_file, "%d:\n", type);
554 static void p1putds (type, i, str)
559 fprintf (pass1_file, "%d: %d %s\n", type, i, str);
563 static void p1putdds (token, type, stg, str)
564 int token, type, stg;
567 fprintf (pass1_file, "%d: %d %d %s\n", token, type, stg, str);