1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)rmothers.c	5.1 (Berkeley) 6/5/85";
   9: #endif not lint
  10: 
  11: #ifdef RMOTHERS
  12:     /* and the rest of the file */
  13: 
  14: #include "0.h"
  15: #include "tree.h"
  16: 
  17:     /*
  18:      *	translate extended case statements to pascal (for tex).
  19:      *	don knuth should know better.  enough said.
  20:      *		... peter 5/4/83
  21:      *
  22:      *	extended case statements have the form:
  23:      *	    case expresion of
  24:      *		label1,label2,...: statement1;
  25:      *		...
  26:      *		others: otherstatement
  27:      *		end
  28:      *	which i am going to translate to:
  29:      *	    if expression in [ label1,label2,...] then
  30:      *		case expression of
  31:      *		    label1,label2,...: statement1;
  32:      *		    ...
  33:      *		    end
  34:      *	    else otherstatement
  35:      *	which has the effect that the expression will be evaluated twice.
  36:      *	i've looked very briefly at all cases in tex and
  37:      *	they seem to be variables or pure functions.
  38:      *	for simplicity i'm assuming that the others is the last labeled
  39:      *	statement, and that no other labels appear with the label others.
  40:      *	this appears correct from the tex82 documentation.
  41:      */
  42: 
  43:     /*
  44:      *	given a case statement tree and the address of an others pointer,
  45:      *	amputate the others statement from the case statement tree
  46:      *	and hang it on the the others pointer.
  47:      *
  48:      *	Case statement
  49:      *	r	[0]	T_CASE
  50:      *		[1]	lineof "case"
  51:      *		[2]	expression
  52:      *		[3]	list of cased statements:
  53:      *			cstat	[0]	T_CSTAT
  54:      *				[1]	lineof ":"
  55:      *				[2]	list of constant labels
  56:      *				[3]	statement
  57:      */
  58: needscaseguard(r, otherspp)
  59:     int *r;
  60:     int **otherspp;
  61: {
  62:     int *statlistp;
  63:     int *cutpointer;
  64:     int *lstatementp;
  65:     int *lablistp;
  66:     int *label;
  67:     int hasothers;
  68: 
  69:     *otherspp = NIL;
  70:     hasothers = 0;
  71:     if (!rmothers) {
  72:     return hasothers;
  73:     }
  74:     for (cutpointer = &r[3], statlistp = r[3];
  75:      statlistp != NIL;
  76:      cutpointer = &statlistp[2], statlistp = statlistp[2]) {
  77:     lstatementp = statlistp[1];
  78:     if (lstatementp == NIL)
  79:         continue;
  80:     lablistp = lstatementp[2];
  81:     if (lablistp != NIL) {
  82:         label = lablistp[1];
  83:         /* only look at the first label */
  84:         if (label != NIL &&
  85:         label[0] == T_ID && !strcmp(label[1],"others")) {
  86:             hasothers = 1;
  87:             *otherspp = lstatementp[3];
  88:             *cutpointer = NIL;
  89:             if (statlistp[2] != NIL) {
  90:             panic("others not last case");
  91:             }
  92:             if (lablistp[2] != NIL) {
  93:             panic("others not only case label");
  94:             }
  95:         }
  96:     }
  97:     }
  98:     return hasothers;
  99: }
 100: 
 101: precaseguard(r)
 102:     int *r;
 103: {
 104:     int *statlistp;
 105:     int *cutpointer;
 106:     int *lstatementp;
 107:     int *lablistp;
 108:     int *label;
 109:     int hadsome;
 110:     int counter;
 111: 
 112:     if (!rmothers) {
 113:     return;
 114:     }
 115:     ppkw("if");
 116:     ppspac();
 117:     rvalue(r[2], NIL);
 118:     ppspac();
 119:     ppkw("in");
 120:     ppgoin(DECL);
 121:     ppnl();
 122:     indent();
 123:     ppsep("[");
 124:     hadsome = 0;
 125:     counter = 0;
 126:     for (statlistp = r[3]; statlistp != NIL; statlistp = statlistp[2]) {
 127:     lstatementp = statlistp[1];
 128:     if (lstatementp == NIL)
 129:         continue;
 130:     for (lablistp = lstatementp[2];lablistp != NIL;lablistp = lablistp[2]) {
 131:         label = lablistp[1];
 132:         if (hadsome) {
 133:         if (counter < 8) {
 134:             ppsep(", ");
 135:         } else {
 136:             ppsep(",");
 137:             ppnl();
 138:             indent();
 139:             ppspac();
 140:             counter = 0;
 141:         }
 142:         } else {
 143:         hadsome = 1;
 144:         }
 145:         gconst(label);
 146:         counter += 1;
 147:     }
 148:     }
 149:     ppsep("]");
 150:     ppspac();
 151:     ppkw("then");
 152:     ppgoout(DECL);
 153:     ppgoin(STAT);
 154:     ppnl();
 155:     indent();
 156: }
 157: 
 158:     /*
 159:      *	given an others statement, hang it on the else branch of the guard.
 160:      */
 161: postcaseguard(othersp)
 162:     int *othersp;
 163: {
 164:     if (!rmothers) {
 165:     return;
 166:     }
 167:     ppgoout(STAT);
 168:     ppnl();
 169:     indent();
 170:     ppkw("else");
 171:     ppgoin(STAT);
 172:     if (othersp == NIL) {
 173:         /*
 174: 	     *	this will print a call to the routine ``null''.
 175: 	     *	but it has to be checked first, or we will indirect through
 176: 	     *	NIL to check the statement type.
 177: 	     */
 178:     statement(NIL);
 179:     ppgoout(STAT);
 180:     return;
 181:     }
 182:     if (othersp[0] == T_BLOCK) {
 183:     ppnl();
 184:     indent();
 185:     ppstbl1(othersp, STAT);
 186:     ppstbl2();
 187:     } else {
 188:     statement(othersp);
 189:     }
 190:     ppgoout(STAT);
 191: }
 192: #endif RMOTHERS

Defined functions

needscaseguard defined in line 58; used 1 times
postcaseguard defined in line 161; used 1 times
precaseguard defined in line 101; used 1 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3080
Valid CSS Valid XHTML 1.0 Strict