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
widen
defined in line
19; used 5 times
Defined variables
rcsid
defined in line
2;
never used