1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
   2: static char rcsid[] = "$Header: wide.c,v 2.3 84/07/19 12:01:37 guido Exp $";
   3: 
   4: /*
   5:  * B editor -- Commands to make the focus larger and smaller in various ways.
   6:  */
   7: 
   8: #include "b.h"
   9: #include "bobj.h"
  10: #include "node.h"
  11: #include "supr.h"
  12: #include "gram.h"
  13: 
  14: 
  15: /*
  16:  * Widen -- make the focus larger.
  17:  */
  18: 
  19: Visible bool
  20: widen(ep)
  21:     register environ *ep;
  22: {
  23:     register node n;
  24:     register int sym;
  25:     register int ich;
  26: 
  27:     higher(ep);
  28:     grow(ep);
  29: 
  30:     n = tree(ep->focus);
  31:     sym = symbol(n);
  32:     if (ep->mode == VHOLE && (ep->s1&1))
  33:         ep->mode = FHOLE;
  34: 
  35:     switch (ep->mode) {
  36: 
  37:     case ATBEGIN:
  38:     case ATEND:
  39:         /* Shouldn't occur after grow(ep) */
  40:         ep->mode = WHOLE;
  41:         return Yes;
  42: 
  43:     case VHOLE:
  44:         if (ep->s2 >= lenitem(ep))
  45:             --ep->s2;
  46:         ep->mode = SUBRANGE;
  47:         ep->s3 = ep->s2;
  48:         return Yes;
  49: 
  50:     case FHOLE:
  51:         if (ep->s2 >= lenitem(ep)) {
  52:             if (ep->s2 > 0)
  53:                 --ep->s2;
  54:             else {
  55:                 leftvhole(ep);
  56:                 switch (ep->mode) {
  57:                 case ATBEGIN:
  58:                 case ATEND:
  59:                     ep->mode = WHOLE;
  60:                     return Yes;
  61:                 case VHOLE:
  62:                 case FHOLE:
  63:                     if (ep->s2 >= lenitem(ep)) {
  64:                         if (ep->s2 == 0) {
  65: #ifndef NDEBUG
  66:                             debug("[Desperate in widen]");
  67: #endif NDEBUG
  68:                             ep->mode = SUBSET;
  69:                             ep->s2 = ep->s1;
  70:                             return widen(ep);
  71:                         }
  72:                         --ep->s2;
  73:                     }
  74:                     ep->mode = SUBRANGE;
  75:                     ep->s3 = ep->s2;
  76:                     return Yes;
  77:                 }
  78:                 Abort();
  79:             }
  80:         }
  81:         ep->mode = SUBRANGE;
  82:         ep->s3 = ep->s2;
  83:         return Yes;
  84: 
  85:     case SUBRANGE:
  86:         ep->mode = SUBSET;
  87:         ep->s2 = ep->s1;
  88:         return Yes;
  89: 
  90:     case SUBSET:
  91:         if (!issublist(sym) || width(lastchild(n)) == 0) {
  92:             ep->mode = WHOLE;
  93:             return Yes;
  94:         }
  95:         if (ep->s2 < 2*nchildren(n)) {
  96:             ep->mode = SUBLIST;
  97:             ep->s3 = 1;
  98:             return Yes;
  99:         }
 100:         /* Fall through */
 101:     case SUBLIST:
 102:         for (;;) {
 103:             ich = ichild(ep->focus);
 104:             if (!up(&ep->focus)) {
 105:                 ep->mode = WHOLE;
 106:                 return Yes;
 107:             }
 108:             higher(ep);
 109:             n = tree(ep->focus);
 110:             if (ich != nchildren(n) || !samelevel(sym, symbol(n))) {
 111:                 ep->mode = SUBSET;
 112:                 ep->s1 = ep->s2 = 2*ich;
 113:                 return Yes;
 114:             }
 115:         }
 116:         /* Not reached */
 117: 
 118:     case WHOLE:
 119:         ich = ichild(ep->focus);
 120:         if (!up(&ep->focus))
 121:             return No;
 122:         n = tree(ep->focus);
 123:         if (issublist(symbol(n)) && ich < nchildren(n)) {
 124:             ep->mode = SUBLIST;
 125:             ep->s3 = 1;
 126:         }
 127:         return Yes;
 128: 
 129:     default:
 130:         Abort();
 131:         /* NOTREACHED */
 132:     }
 133:     /* Not reached */
 134: }
 135: 
 136: 
 137: /*
 138:  * Narrow -- make the focus smaller.
 139:  */
 140: 
 141: Visible bool
 142: narrow(ep)
 143:     register environ *ep;
 144: {
 145:     register node n;
 146:     register int sym;
 147:     register int nch;
 148:     register string repr;
 149: 
 150:     higher(ep);
 151: 
 152:     shrink(ep);
 153:     n = tree(ep->focus);
 154:     sym = symbol(n);
 155: 
 156:     switch (ep->mode) {
 157: 
 158:     case ATBEGIN:
 159:     case ATEND:
 160:     case VHOLE:
 161:     case FHOLE:
 162:         return No;
 163: 
 164:     case SUBRANGE:
 165:         if (ep->s3 > ep->s2)
 166:             ep->s3 = ep->s2;
 167:         else
 168:             ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
 169:         return Yes;
 170: 
 171:     case SUBSET:
 172:         if (ep->s1 <= 2) {
 173:             nch = nchildren(n);
 174:             if (ep->s2 >= 2*nch && issublist(symbol(n))) {
 175:                 if (ep->s1 <= 1) {
 176:                     ep->s2 = 2*nch - 1;
 177:                     return Yes;
 178:                 }
 179:                 repr = noderepr(n)[0];
 180:                 if (!Fw_positive(repr)) {
 181:                     ep->s2 = 2*nch - 1;
 182:                     return Yes;
 183:                 }
 184:             }
 185:         }
 186:         ep->s2 = ep->s1;
 187:         return Yes;
 188: 
 189:     case SUBLIST:
 190:         Assert(ep->s3 > 1);
 191:         ep->s3 = 1;
 192:         return Yes;
 193: 
 194:     case WHOLE:
 195:         Assert(sym == Hole || sym == Optional);
 196:         return No;
 197: 
 198:     default:
 199:         Abort();
 200:         /* NOTREACHED */
 201:     }
 202: }
 203: 
 204: 
 205: Visible bool
 206: extend(ep)
 207:     register environ *ep;
 208: {
 209:     register node n;
 210:     register int i;
 211:     register int len;
 212:     register int s1save;
 213: 
 214:     grow(ep);
 215:     higher(ep);
 216:     switch (ep->mode) {
 217: 
 218:     case VHOLE:
 219:     case FHOLE:
 220:     case ATBEGIN:
 221:     case ATEND:
 222:         return widen(ep);
 223: 
 224:     case SUBRANGE:
 225:         len = lenitem(ep);
 226:         if (ep->s3 < len-1)
 227:             ++ep->s3;
 228:         else if (ep->s2 > 0)
 229:             --ep->s2;
 230:         else {
 231:             ep->mode = SUBSET;
 232:             ep->s2 = ep->s1;
 233:             return extend(ep); /* Recursion! */
 234:         }
 235:         return Yes;
 236: 
 237:     case SUBSET:
 238:         s1save = ep->s1;
 239:         ep->s1 = ep->s2;
 240:         if (nextnnitem(ep)) {
 241:             ep->s2 = ep->s1;
 242:             ep->s1 = s1save;
 243:         }
 244:         else {
 245:             ep->s1 = s1save;
 246:             prevnnitem(ep) || Abort();
 247:         }
 248:         return Yes;
 249: 
 250:     case WHOLE:
 251:         return up(&ep->focus);
 252: 
 253:     case SUBLIST:
 254:         n = tree(ep->focus);
 255:         for (i = ep->s3; i > 1; --i)
 256:             n = lastchild(n);
 257:         if (samelevel(symbol(n), symbol(lastchild(n)))) {
 258:             ++ep->s3;
 259:             return Yes;
 260:         }
 261:         ep->mode = WHOLE;
 262:         if (symbol(lastchild(n)) != Optional)
 263:             return Yes;
 264:         return extend(ep); /* Recursion! */
 265: 
 266:     default:
 267:         Abort();
 268:         /* NOTREACHED */
 269:     }
 270: }
 271: 
 272: 
 273: /*
 274:  * Right-Narrow -- make the focus smaller, going to the last item of a list.
 275:  */
 276: 
 277: Visible bool
 278: rnarrow(ep)
 279:     register environ *ep;
 280: {
 281:     register node n;
 282:     register int i;
 283:     register int sym;
 284: 
 285:     higher(ep);
 286: 
 287:     shrink(ep);
 288:     n = tree(ep->focus);
 289:     sym = symbol(n);
 290:     if (sym == Optional || sym == Hole)
 291:         return No;
 292: 
 293:     switch (ep->mode) {
 294: 
 295:     case ATBEGIN:
 296:     case ATEND:
 297:     case VHOLE:
 298:     case FHOLE:
 299:         return No;
 300: 
 301:     case SUBRANGE:
 302:         if (ep->s3 > ep->s2)
 303:             ep->s2 = ep->s3;
 304:         else {
 305:             ++ep->s2;
 306:             ep->mode = (ep->s1&1) ? FHOLE : VHOLE;
 307:         }
 308:         return Yes;
 309: 
 310:     case SUBSET:
 311:         if (issublist(sym) && ep->s2 >= 2*nchildren(n)) {
 312:             do {
 313:                 sym = symbol(n);
 314:                 s_downrite(ep);
 315:                 n = tree(ep->focus);
 316:             } while (samelevel(sym, symbol(n))
 317:                 && width(lastchild(n)) != 0);
 318:             ep->mode = WHOLE;
 319:             return Yes;
 320:         }
 321:         ep->s1 = ep->s2;
 322:         return Yes;
 323: 
 324:     case SUBLIST:
 325:         Assert(ep->s3 > 1);
 326:         for (i = ep->s3; i > 1; --i)
 327:             s_downi(ep, nchildren(tree(ep->focus)));
 328:         ep->s3 = 1;
 329:         return Yes;
 330: 
 331:     case WHOLE:
 332:         Assert(sym == Hole || sym == Optional);
 333:         return No;
 334: 
 335:     default:
 336:         Abort();
 337:         /* NOTREACHED */
 338:     }
 339: }

Defined functions

extend defined in line 205; used 3 times
narrow defined in line 141; used 8 times
widen defined in line 19; used 5 times

Defined variables

rcsid defined in line 2; never used
Last modified: 1985-08-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2849
Valid CSS Valid XHTML 1.0 Strict