|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.