p1output.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990, 1991, 1993, 1994, 1999-2001 by AT&T, Lucent Technologies and Bellcore.
00003 
00004 Permission to use, copy, modify, and distribute this software
00005 and its documentation for any purpose and without fee is hereby
00006 granted, provided that the above copyright notice appear in all
00007 copies and that both that the copyright notice and this
00008 permission notice and warranty disclaimer appear in supporting
00009 documentation, and that the names of AT&T, Bell Laboratories,
00010 Lucent or Bellcore or any of their entities not be used in
00011 advertising or publicity pertaining to distribution of the
00012 software without specific, written prior permission.
00013 
00014 AT&T, Lucent and Bellcore disclaim all warranties with regard to
00015 this software, including all implied warranties of
00016 merchantability and fitness.  In no event shall AT&T, Lucent or
00017 Bellcore be liable for any special, indirect or consequential
00018 damages or any damages whatsoever resulting from loss of use,
00019 data or profits, whether in an action of contract, negligence or
00020 other tortious action, arising out of or in connection with the
00021 use or performance of this software.
00022 ****************************************************************/
00023 
00024 #include "defs.h"
00025 #include "p1defs.h"
00026 #include "output.h"
00027 #include "names.h"
00028 
00029 
00030 static void p1_addr Argdcl((Addrp));
00031 static void p1_big_addr Argdcl((Addrp));
00032 static void p1_binary Argdcl((Exprp));
00033 static void p1_const Argdcl((Constp));
00034 static void p1_list Argdcl((struct Listblock*));
00035 static void p1_literal Argdcl((long int));
00036 static void p1_name Argdcl((Namep));
00037 static void p1_unary Argdcl((Exprp));
00038 static void p1putd Argdcl((int, long int));
00039 static void p1putdd Argdcl((int, int, int));
00040 static void p1putddd Argdcl((int, int, int, int));
00041 static void p1putdds Argdcl((int, int, int, char*));
00042 static void p1putds Argdcl((int, int, char*));
00043 static void p1putn Argdcl((int, int, char*));
00044 
00045 
00046 /* p1_comment -- save the text of a Fortran comment in the intermediate
00047    file.  Make sure that there are no spurious "/ *" or "* /" characters by
00048    mapping them onto "/+" and "+/".   str   is assumed to hold no newlines and be
00049    null terminated; it may be modified by this function. */
00050 
00051  void
00052 #ifdef KR_headers
00053 p1_comment(str)
00054         char *str;
00055 #else
00056 p1_comment(char *str)
00057 #endif
00058 {
00059     register unsigned char *pointer, *ustr;
00060 
00061     if (!str)
00062         return;
00063 
00064 /* Get rid of any open or close comment combinations that may be in the
00065    Fortran input */
00066 
00067         ustr = (unsigned char *)str;
00068         for(pointer = ustr; *pointer; pointer++)
00069                 if (*pointer == '*' && (pointer[1] == '/'
00070                                         || pointer > ustr && pointer[-1] == '/'))
00071                         *pointer = '+';
00072         /* trim trailing white space */
00073 #ifdef isascii
00074         while(--pointer >= ustr && (!isascii(*pointer) || isspace(*pointer)));
00075 #else
00076         while(--pointer >= ustr && isspace(*pointer));
00077 #endif
00078         pointer[1] = 0;
00079         p1puts (P1_COMMENT, str);
00080 } /* p1_comment */
00081 
00082 /* p1_name -- Writes the address of a hash table entry into the
00083    intermediate file */
00084 
00085  static void
00086 #ifdef KR_headers
00087 p1_name(namep)
00088         Namep namep;
00089 #else
00090 p1_name(Namep namep)
00091 #endif
00092 {
00093         p1putd (P1_NAME_POINTER, (long) namep);
00094         namep->visused = 1;
00095 } /* p1_name */
00096 
00097 
00098 
00099  void
00100 #ifdef KR_headers
00101 p1_expr(expr)
00102         expptr expr;
00103 #else
00104 p1_expr(expptr expr)
00105 #endif
00106 {
00107 /* An opcode of 0 means a null entry */
00108 
00109     if (expr == ENULL) {
00110         p1putdd (P1_EXPR, 0, TYUNKNOWN);        /* Should this be TYERROR? */
00111         return;
00112     } /* if (expr == ENULL) */
00113 
00114     switch (expr -> tag) {
00115         case TNAME:
00116                 p1_name ((Namep) expr);
00117                 return;
00118         case TCONST:
00119                 p1_const(&expr->constblock);
00120                 return;
00121         case TEXPR:
00122                 /* Fall through the switch */
00123                 break;
00124         case TADDR:
00125                 p1_addr (&(expr -> addrblock));
00126                 goto freeup;
00127         case TPRIM:
00128                 warn ("p1_expr:  got TPRIM");
00129                 return;
00130         case TLIST:
00131                 p1_list (&(expr->listblock));
00132                 frchain( &(expr->listblock.listp) );
00133                 return;
00134         case TERROR:
00135                 return;
00136         default:
00137                 erri ("p1_expr: bad tag '%d'", (int) (expr -> tag));
00138                 return;
00139         }
00140 
00141 /* Now we know that the tag is TEXPR */
00142 
00143     if (is_unary_op (expr -> exprblock.opcode))
00144         p1_unary (&(expr -> exprblock));
00145     else if (is_binary_op (expr -> exprblock.opcode))
00146         p1_binary (&(expr -> exprblock));
00147     else
00148         erri ("p1_expr:  bad opcode '%d'", (int) expr -> exprblock.opcode);
00149  freeup:
00150     free((char *)expr);
00151 
00152 } /* p1_expr */
00153 
00154 
00155 
00156  static void
00157 #ifdef KR_headers
00158 p1_const(cp)
00159         register Constp cp;
00160 #else
00161 p1_const(register Constp cp)
00162 #endif
00163 {
00164         int type = cp->vtype;
00165         expptr vleng = cp->vleng;
00166         union Constant *c = &cp->Const;
00167         char cdsbuf0[64], cdsbuf1[64];
00168         char *cds0, *cds1;
00169 
00170     switch (type) {
00171         case TYINT1:
00172         case TYSHORT:
00173         case TYLONG:
00174 #ifdef TYQUAD0
00175         case TYQUAD:
00176 #endif
00177         case TYLOGICAL:
00178         case TYLOGICAL1:
00179         case TYLOGICAL2:
00180             fprintf(pass1_file, "%d: %d %ld\n", P1_CONST, type, c->ci);
00181             break;
00182 #ifndef NO_LONG_LONG
00183         case TYQUAD:
00184             fprintf(pass1_file, "%d: %d %llx\n", P1_CONST, type, c->cq);
00185             break;
00186 #endif
00187         case TYREAL:
00188         case TYDREAL:
00189                 fprintf(pass1_file, "%d: %d %s\n", P1_CONST, type,
00190                         cp->vstg ? c->cds[0] : cds(dtos(c->cd[0]), cdsbuf0));
00191             break;
00192         case TYCOMPLEX:
00193         case TYDCOMPLEX:
00194                 if (cp->vstg) {
00195                         cds0 = c->cds[0];
00196                         cds1 = c->cds[1];
00197                         }
00198                 else {
00199                         cds0 = cds(dtos(c->cd[0]), cdsbuf0);
00200                         cds1 = cds(dtos(c->cd[1]), cdsbuf1);
00201                         }
00202                 fprintf(pass1_file, "%d: %d %s %s\n", P1_CONST, type,
00203                         cds0, cds1);
00204             break;
00205         case TYCHAR:
00206             if (vleng && !ISICON (vleng))
00207                 err("p1_const:  bad vleng\n");
00208             else
00209                 fprintf(pass1_file, "%d: %d %lx\n", P1_CONST, type,
00210                         cpexpr((expptr)cp));
00211             break;
00212         default:
00213             erri ("p1_const:  bad constant type '%d'", type);
00214             break;
00215     } /* switch */
00216 } /* p1_const */
00217 
00218 
00219  void
00220 #ifdef KR_headers
00221 p1_asgoto(addrp)
00222         Addrp addrp;
00223 #else
00224 p1_asgoto(Addrp addrp)
00225 #endif
00226 {
00227     p1put (P1_ASGOTO);
00228     p1_addr (addrp);
00229 } /* p1_asgoto */
00230 
00231 
00232  void
00233 #ifdef KR_headers
00234 p1_goto(stateno)
00235         ftnint stateno;
00236 #else
00237 p1_goto(ftnint stateno)
00238 #endif
00239 {
00240     p1putd (P1_GOTO, stateno);
00241 } /* p1_goto */
00242 
00243 
00244  static void
00245 #ifdef KR_headers
00246 p1_addr(addrp)
00247         register struct Addrblock *addrp;
00248 #else
00249 p1_addr(register struct Addrblock *addrp)
00250 #endif
00251 {
00252     int stg;
00253 
00254     if (addrp == (struct Addrblock *) NULL)
00255         return;
00256 
00257     stg = addrp -> vstg;
00258 
00259     if (ONEOF(stg, M(STGINIT)|M(STGREG))
00260         || ONEOF(stg, M(STGCOMMON)|M(STGEQUIV)) &&
00261                 (!ISICON(addrp->memoffset)
00262                 || (addrp->uname_tag == UNAM_NAME
00263                         ? addrp->memoffset->constblock.Const.ci
00264                                 != addrp->user.name->voffset
00265                         : addrp->memoffset->constblock.Const.ci))
00266         || ONEOF(stg, M(STGBSS)|M(STGINIT)|M(STGAUTO)|M(STGARG)) &&
00267                 (!ISICON(addrp->memoffset)
00268                         || addrp->memoffset->constblock.Const.ci)
00269         || addrp->Field || addrp->isarray || addrp->vstg == STGLENG)
00270         {
00271                 p1_big_addr (addrp);
00272                 return;
00273         }
00274 
00275 /* Write out a level of indirection for non-array arguments, which have
00276    addrp -> memoffset   set and are handled by   p1_big_addr().
00277    Lengths are passed by value, so don't check STGLENG
00278    28-Jun-89 (dmg)  Added the check for != TYCHAR
00279  */
00280 
00281     if (oneof_stg ( addrp -> uname_tag == UNAM_NAME ? addrp -> user.name : NULL,
00282             stg, M(STGARG)|M(STGEQUIV)) && addrp->vtype != TYCHAR) {
00283         p1putdd (P1_EXPR, OPWHATSIN, addrp -> vtype);
00284         p1_expr (ENULL);        /* Put dummy   vleng   */
00285     } /* if stg == STGARG */
00286 
00287     switch (addrp -> uname_tag) {
00288         case UNAM_NAME:
00289             p1_name (addrp -> user.name);
00290             break;
00291         case UNAM_IDENT:
00292             p1putdds(P1_IDENT, addrp->vtype, addrp->vstg,
00293                                 addrp->user.ident);
00294             break;
00295         case UNAM_CHARP:
00296                 p1putdds(P1_CHARP, addrp->vtype, addrp->vstg,
00297                                 addrp->user.Charp);
00298                 break;
00299         case UNAM_EXTERN:
00300             p1putd (P1_EXTERN, (long) addrp -> memno);
00301             if (addrp->vclass == CLPROC)
00302                 extsymtab[addrp->memno].extype = addrp->vtype;
00303             break;
00304         case UNAM_CONST:
00305             if (addrp -> memno != BAD_MEMNO)
00306                 p1_literal (addrp -> memno);
00307             else
00308                 p1_const((struct Constblock *)addrp);
00309             break;
00310         case UNAM_UNKNOWN:
00311         default:
00312             erri ("p1_addr:  unknown uname_tag '%d'", addrp -> uname_tag);
00313             break;
00314     } /* switch */
00315 } /* p1_addr */
00316 
00317 
00318  static void
00319 #ifdef KR_headers
00320 p1_list(listp)
00321         struct Listblock *listp;
00322 #else
00323 p1_list(struct Listblock *listp)
00324 #endif
00325 {
00326     chainp lis;
00327     int count = 0;
00328 
00329     if (listp == (struct Listblock *) NULL)
00330         return;
00331 
00332 /* Count the number of parameters in the list */
00333 
00334     for (lis = listp -> listp; lis; lis = lis -> nextp)
00335         count++;
00336 
00337     p1putddd (P1_LIST, listp -> tag, listp -> vtype, count);
00338 
00339     for (lis = listp -> listp; lis; lis = lis -> nextp)
00340         p1_expr ((expptr) lis -> datap);
00341 
00342 } /* p1_list */
00343 
00344 
00345  void
00346 #ifdef KR_headers
00347 p1_label(lab)
00348         long lab;
00349 #else
00350 p1_label(long lab)
00351 #endif
00352 {
00353         if (parstate < INDATA)
00354                 earlylabs = mkchain((char *)lab, earlylabs);
00355         else
00356                 p1putd (P1_LABEL, lab);
00357         }
00358 
00359 
00360 
00361  static void
00362 #ifdef KR_headers
00363 p1_literal(memno)
00364         long memno;
00365 #else
00366 p1_literal(long memno)
00367 #endif
00368 {
00369     p1putd (P1_LITERAL, memno);
00370 } /* p1_literal */
00371 
00372 
00373  void
00374 #ifdef KR_headers
00375 p1_if(expr)
00376         expptr expr;
00377 #else
00378 p1_if(expptr expr)
00379 #endif
00380 {
00381     p1put (P1_IF);
00382     p1_expr (expr);
00383 } /* p1_if */
00384 
00385 
00386 
00387 
00388  void
00389 #ifdef KR_headers
00390 p1_elif(expr)
00391         expptr expr;
00392 #else
00393 p1_elif(expptr expr)
00394 #endif
00395 {
00396     p1put (P1_ELIF);
00397     p1_expr (expr);
00398 } /* p1_elif */
00399 
00400 
00401 
00402 
00403  void
00404 p1_else(Void)
00405 {
00406     p1put (P1_ELSE);
00407 } /* p1_else */
00408 
00409 
00410 
00411 
00412  void
00413 p1_endif(Void)
00414 {
00415     p1put (P1_ENDIF);
00416 } /* p1_endif */
00417 
00418 
00419 
00420 
00421  void
00422 p1else_end(Void)
00423 {
00424     p1put (P1_ENDELSE);
00425 } /* p1else_end */
00426 
00427 
00428  static void
00429 #ifdef KR_headers
00430 p1_big_addr(addrp)
00431         Addrp addrp;
00432 #else
00433 p1_big_addr(Addrp addrp)
00434 #endif
00435 {
00436     if (addrp == (Addrp) NULL)
00437         return;
00438 
00439     p1putn (P1_ADDR, (int)sizeof(struct Addrblock), (char *) addrp);
00440     p1_expr (addrp -> vleng);
00441     p1_expr (addrp -> memoffset);
00442     if (addrp->uname_tag == UNAM_NAME)
00443         addrp->user.name->visused = 1;
00444 } /* p1_big_addr */
00445 
00446 
00447 
00448  static void
00449 #ifdef KR_headers
00450 p1_unary(e)
00451         struct Exprblock *e;
00452 #else
00453 p1_unary(struct Exprblock *e)
00454 #endif
00455 {
00456     if (e == (struct Exprblock *) NULL)
00457         return;
00458 
00459     p1putdd (P1_EXPR, (int) e -> opcode, e -> vtype);
00460     p1_expr (e -> vleng);
00461 
00462     switch (e -> opcode) {
00463         case OPNEG:
00464         case OPNEG1:
00465         case OPNOT:
00466         case OPABS:
00467         case OPBITNOT:
00468         case OPPREINC:
00469         case OPPREDEC:
00470         case OPADDR:
00471         case OPIDENTITY:
00472         case OPCHARCAST:
00473         case OPDABS:
00474             p1_expr(e -> leftp);
00475             break;
00476         default:
00477             erri ("p1_unary: bad opcode '%d'", (int) e -> opcode);
00478             break;
00479     } /* switch */
00480 
00481 } /* p1_unary */
00482 
00483 
00484  static void
00485 #ifdef KR_headers
00486 p1_binary(e)
00487         struct Exprblock *e;
00488 #else
00489 p1_binary(struct Exprblock *e)
00490 #endif
00491 {
00492     if (e == (struct Exprblock *) NULL)
00493         return;
00494 
00495     p1putdd (P1_EXPR, e -> opcode, e -> vtype);
00496     p1_expr (e -> vleng);
00497     p1_expr (e -> leftp);
00498     p1_expr (e -> rightp);
00499 } /* p1_binary */
00500 
00501 
00502  void
00503 #ifdef KR_headers
00504 p1_head(Class, name)
00505         int Class;
00506         char *name;
00507 #else
00508 p1_head(int Class, char *name)
00509 #endif
00510 {
00511     p1putds (P1_HEAD, Class, (char*)(name ? name : ""));
00512 } /* p1_head */
00513 
00514 
00515  void
00516 #ifdef KR_headers
00517 p1_subr_ret(retexp)
00518         expptr retexp;
00519 #else
00520 p1_subr_ret(expptr retexp)
00521 #endif
00522 {
00523 
00524     p1put (P1_SUBR_RET);
00525     p1_expr (cpexpr(retexp));
00526 } /* p1_subr_ret */
00527 
00528 
00529 
00530  void
00531 #ifdef KR_headers
00532 p1comp_goto(index, count, labels)
00533         expptr index;
00534         int count;
00535         struct Labelblock **labels;
00536 #else
00537 p1comp_goto(expptr index, int count, struct Labelblock **labels)
00538 #endif
00539 {
00540     struct Constblock c;
00541     int i;
00542     register struct Labelblock *L;
00543 
00544     p1put (P1_COMP_GOTO);
00545     p1_expr (index);
00546 
00547 /* Write out a P1_LIST directly, to avoid the overhead of allocating a
00548    list before it's needed HACK HACK HACK */
00549 
00550     p1putddd (P1_LIST, TLIST, TYUNKNOWN, count);
00551     c.vtype = TYLONG;
00552     c.vleng = 0;
00553 
00554     for (i = 0; i < count; i++) {
00555         L = labels[i];
00556         L->labused = 1;
00557         c.Const.ci = L->stateno;
00558         p1_const(&c);
00559     } /* for i = 0 */
00560 } /* p1comp_goto */
00561 
00562 
00563 
00564  void
00565 #ifdef KR_headers
00566 p1_for(init, test, inc)
00567         expptr init;
00568         expptr test;
00569         expptr inc;
00570 #else
00571 p1_for(expptr init, expptr test, expptr inc)
00572 #endif
00573 {
00574     p1put (P1_FOR);
00575     p1_expr (init);
00576     p1_expr (test);
00577     p1_expr (inc);
00578 } /* p1_for */
00579 
00580 
00581  void
00582 p1for_end(Void)
00583 {
00584     p1put (P1_ENDFOR);
00585 } /* p1for_end */
00586 
00587 
00588 
00589 
00590 /* ----------------------------------------------------------------------
00591    The intermediate file actually gets written ONLY by the routines below.
00592    To change the format of the file, you need only change these routines.
00593    ----------------------------------------------------------------------
00594 */
00595 
00596 
00597 /* p1puts -- Put a typed string into the Pass 1 intermediate file.  Assumes that
00598    str   contains no newlines and is null-terminated. */
00599 
00600  void
00601 #ifdef KR_headers
00602 p1puts(type, str)
00603         int type;
00604         char *str;
00605 #else
00606 p1puts(int type, char *str)
00607 #endif
00608 {
00609     fprintf (pass1_file, "%d: %s\n", type, str);
00610 } /* p1puts */
00611 
00612 
00613 /* p1putd -- Put a typed integer into the Pass 1 intermediate file. */
00614 
00615  static void
00616 #ifdef KR_headers
00617 p1putd(type, value)
00618         int type;
00619         long value;
00620 #else
00621 p1putd(int type, long value)
00622 #endif
00623 {
00624     fprintf (pass1_file, "%d: %ld\n", type, value);
00625 } /* p1_putd */
00626 
00627 
00628 /* p1putdd -- Put a typed pair of integers into the intermediate file. */
00629 
00630  static void
00631 #ifdef KR_headers
00632 p1putdd(type, v1, v2)
00633         int type;
00634         int v1;
00635         int v2;
00636 #else
00637 p1putdd(int type, int v1, int v2)
00638 #endif
00639 {
00640     fprintf (pass1_file, "%d: %d %d\n", type, v1, v2);
00641 } /* p1putdd */
00642 
00643 
00644 /* p1putddd -- Put a typed triple of integers into the intermediate file. */
00645 
00646  static void
00647 #ifdef KR_headers
00648 p1putddd(type, v1, v2, v3)
00649         int type;
00650         int v1;
00651         int v2;
00652         int v3;
00653 #else
00654 p1putddd(int type, int v1, int v2, int v3)
00655 #endif
00656 {
00657     fprintf (pass1_file, "%d: %d %d %d\n", type, v1, v2, v3);
00658 } /* p1putddd */
00659 
00660  union dL {
00661         double d;
00662         long L[2];
00663         };
00664 
00665  static void
00666 #ifdef KR_headers
00667 p1putn(type, count, str)
00668         int type;
00669         int count;
00670         char *str;
00671 #else
00672 p1putn(int type, int count, char *str)
00673 #endif
00674 {
00675     int i;
00676 
00677     fprintf (pass1_file, "%d: ", type);
00678 
00679     for (i = 0; i < count; i++)
00680         putc (str[i], pass1_file);
00681 
00682     putc ('\n', pass1_file);
00683 } /* p1putn */
00684 
00685 
00686 
00687 /* p1put -- Put a type marker into the intermediate file. */
00688 
00689  void
00690 #ifdef KR_headers
00691 p1put(type)
00692         int type;
00693 #else
00694 p1put(int type)
00695 #endif
00696 {
00697     fprintf (pass1_file, "%d:\n", type);
00698 } /* p1put */
00699 
00700 
00701 
00702  static void
00703 #ifdef KR_headers
00704 p1putds(type, i, str)
00705         int type;
00706         int i;
00707         char *str;
00708 #else
00709 p1putds(int type, int i, char *str)
00710 #endif
00711 {
00712     fprintf (pass1_file, "%d: %d %s\n", type, i, str);
00713 } /* p1putds */
00714 
00715 
00716  static void
00717 #ifdef KR_headers
00718 p1putdds(token, type, stg, str)
00719         int token;
00720         int type;
00721         int stg;
00722         char *str;
00723 #else
00724 p1putdds(int token, int type, int stg, char *str)
00725 #endif
00726 {
00727     fprintf (pass1_file, "%d: %d %d %s\n", token, type, stg, str);
00728 } /* p1putdds */

Generated on Sun Mar 4 15:03:44 2007 for Scilab [trunk] by  doxygen 1.5.1