```   1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2:
3: /*
4:   \$Header: b2exp.c,v 1.4 85/08/22 16:54:36 timo Exp \$
5: */
6:
7: #include "b.h"
8: #include "b1obj.h"
9: #include "b2par.h"
10: #include "b2syn.h"
11: #include "b2nod.h"
12: #include "b2exp.h"
13: #include "b3err.h"
14:
15: /* ******************************************************************** */
16: /*		expression						*/
17: /* ******************************************************************** */
18:
19: Visible parsetree expr(q) txptr q; {
20:     return collateral(q, singexpr);
21: }
22:
23: Forward parsetree rsingexpr();
24:
25: Visible parsetree singexpr(q) txptr q; {
26:     if (nothing(q, "expression")) return NilTree;
27:     else {
31:     }
32: }
33:
38:     dya_proposition= No;
39: }
40:
41: Hidden bool expr_opr() {
42:     return reptext_sign() || center_sign() || leftadj_sign() ||
44: }
45:
46: Forward parsetree term(), factor(), primary(), base(), unp_expr();
47: Forward bool element();
48:
50:     parsetree v; value w; txptr tx0= tx;
52:     skipsp(&tx);
53:     if (Parsed(adm) && Text(q) && expr_opr()) {
54:         if (nodetype(v) == DYAF) pprerr(Prio);
55:         dya_formula(q, adm, &v, mk_text(textsign), L_expr, base);
56:     }
57:     skipsp(&tx);
59:         if (Text(q) && (nodetype(v) == DYAF || Level(adm) < L_expr))
60:             /* predicate must follow */
61:             return v;
62:         else if (Text(q) && tag_operator(q, &w))
63:             dya_formula(q, adm, &v, w, L_expr, unp_expr);
64:         else
65:             parerr(MESS(2100, "no test where expected"));
66:     }
67:     if (Parsed(adm) && Text(q) && tag_operator(q, &w)) {
68:         if (nodetype(v) == DYAF) pprerr(Prio);
69:         dya_formula(q, adm, &v, w, L_expr, base);
70:     }
71:     if (!Parsed(adm)) /* v is an UNPARSED node */
72:         *Branch(v, UNP_TEXT)= cr_text(tx0, tx);
73:     upto_expr(q);
74:     return v;
75: }
76:
77: Hidden Procedure dya_formula(q, adm, v, name, lev, fct)
78:     txptr q; expadm *adm; parsetree *v, (*fct)(); value name; intlet lev; {
79:
80:     parsetree w;
81:     if (Level(adm) < lev) pprerr(Prio);
88:         else
89:             *v= node5(DYAF, *v, name, w, Vnil);
90:     } else {
93:         *v= w;
94:     }
95: }
96:
97: /* ******************************************************************** */
98: /*		term							*/
99: /* ******************************************************************** */
100:
101: Hidden bool term_opr() {
102:     return plus_sign() || minus_sign() || join_sign();
103: }
104:
107:     skipsp(&tx);
108:     while (Parsed(adm) && Text(q) && term_opr()) {
109:         dya_formula(q, adm, &v, mk_text(textsign), L_term, factor);
110:         skipsp(&tx);
111:     }
112:     return v;
113: }
114:
115: /* ******************************************************************** */
116: /*		factor							*/
117: /* ******************************************************************** */
118:
121:     skipsp(&tx);
122:     while (Parsed(adm) && Text(q) && times_sign()) {
123:         dya_formula(q, adm, &v, mk_text(textsign), L_factor, primary);
124:         skipsp(&tx);
125:     }
126:     if (Parsed(adm) && Text(q) && over_sign())
127:         dya_formula(q, adm, &v, mk_text(textsign), L_factor, primary);
128:     return v;
129: }
130:
131: /* ******************************************************************** */
132: /*		primary							*/
133: /* ******************************************************************** */
134:
136:     parsetree v;
138:     skipsp(&tx);
139:     if (Parsed(adm) && Text(q) && number_sign())
140:         dya_formula(q, adm, &v, mk_text(textsign), L_number, base);
141:     skipsp(&tx);
142:     if (Parsed(adm) && Text(q) && power_sign())
143:         dya_formula(q, adm, &v, mk_text(textsign), L_power, base);
144:     return v;
145: }
146:
147: /* ******************************************************************** */
148: /*		base							*/
149: /* ******************************************************************** */
150:
151: Forward parsetree rbase();
152:
158: }
159:
161:     if (State(adm) == S_t) {
162:         if (b_plus(v) || b_minus(v))
164:         if (b_number(v))
166:     }
167:     return No;
168: }
169:
170: Hidden parsetree mon_formula(q, adm, w, fct)
172:
173:     parsetree v;
178:         return v == NilTree ? node2(TAG, w) : node4(MONF, w, v, Vnil);
179:     } else {
181:         return v;
182:     }
183: }
184:
187: }
188:
190:     parsetree v; value name;
191:     skipsp(&tx);
192:     if (Text(q) && tag_operator(q, &name)) {
194:             return mon_formula(q, adm, name, unp_expr);
195:         if (State(adm) == S_t) {
199:         v= mon_formula(q, adm, name, rbase);
202:         return v;
203:     } else if (Text(q) && (dyamon_sign() || mon_sign())) {
204:         name= mk_text(textsign);
206:             return mon_formula(q, adm, name, unp_expr);
211:             else if (b_numtor(name) || b_denomtor(name))
213:         }
215:         if (!Trim(adm) && b_minus(name)) {
217:             v= mon_formula(q, adm, name, primary);
219:             return v;
220:         } else
221:             return mon_formula(q, adm, name, rbase);
222:     } else if (Text(q) && element(q, &v)) {
224:             return mon_formula(q, adm, v, unp_expr);
226:         return v;
227:     } else {
229:             parerr(MESS(2101, "no expression where expected"));
230:         return NilTree;
231:     }
232: }
233:
234: /* ******************************************************************** */
235: /*		element							*/
236: /* ******************************************************************** */
237:
238: Forward bool closed_expr(), constant(), text_dis(), tlr_dis(), seltrim_tag();
239:
240: Hidden bool element(q, v) txptr q; parsetree *v; {
241:     if (seltrim_tag(q, v) || closed_expr(q, v) || constant(q, v) ||
242:         text_dis(q, v) || tlr_dis(q, v)
243:        ) {
244:         selection(q, v);
245:         return Yes;
246:     }
247:     return No;
248: }
249:
250: /* ******************************************************************** */
251: /*		(seltrim_tag)						*/
252: /* ******************************************************************** */
253:
254: Hidden bool seltrim_tag(q, v) txptr q; parsetree *v; {
255:     value name; txptr tx0= tx;
256:     if (Text(q) && is_tag(&name)) {
257:         txptr tx1= tx;
258:         skipsp(&tx);
259:         if (Text(q) && (sub_sign() || trim_sign())) {
260:             tx= tx1;
261:             *v= node2(TAG, name);
262:             return Yes;
263:         } else {
264:             release(name);
265:             tx= tx0;
266:         }
267:     }
268:     return No;
269: }
270:
271: /* ******************************************************************** */
272: /*		(expression)						*/
273: /* ******************************************************************** */
274:
275: Hidden bool closed_expr(q, v) txptr q; parsetree *v; {
276:     return open_sign() ? (*v= compound(q, expr), Yes) : No;
277: }
278:
279: /* ******************************************************************** */
280: /*		constant						*/
281: /*									*/
282: /* note: stand_alone E<number> not allowed				*/
283: /* ******************************************************************** */
284:
285: Forward bool digits();
286:
287: Hidden bool constant(q, v) txptr q; parsetree *v; {
288:     if (Dig(Char(tx)) || Char(tx) == '.') {
289:         txptr tx0= tx;
290:         bool d= digits(q);
291:         if (Text(q) && point_sign() && !digits(q) && !d)
292:             pprerr(MESS(2102, "point without digits"));
293:         if (Text(q) && Char(tx) == 'E' &&
294:             (Dig(Char(tx+1)) || !keymark(Char(tx+1)))
295:            ) {
296:             tx++;
297:             if (Text(q) && (plus_sign() || minus_sign()));
298:             if (!digits(q)) pprerr(MESS(2103, "E not followed by exponent"));
299:         }
300:         *v= node3(NUMBER, numconst(tx0, tx), cr_text(tx0, tx));
301:         return Yes;
302:     }
303:     return No;
304: }
305:
306: Hidden bool digits(q) txptr q; {
307:     txptr tx0= tx;
308:     while (Text(q) && Dig(Char(tx))) tx++;
309:     return tx > tx0;
310: }
311:
312: /* ******************************************************************** */
313: /*		textual_display						*/
314: /* ******************************************************************** */
315:
316: Forward parsetree text_body();
317:
318: Hidden bool text_dis(q, v) txptr q; parsetree *v; {
319:     if (apostrophe_sign() || quote_sign()) {
320:         parsetree w; value aq= mk_text(textsign);
321:         w= text_body(q, textsign);
322:         if (w == NilTree) w= node3(TEXT_LIT, mk_text(""), NilTree);
323:         *v= node3(TEXT_DIS, aq, w);
324:         return Yes;
325:     }
326:     return No;
327: }
328:
329: Forward bool is_conversion();
330:
331: Hidden parsetree text_body(q, aq) txptr q; string aq; {
333:     txptr tx0= tx;
334:     while (Text(q)) {
335:         if (Char(tx) == *aq || Char(tx) == '`') {
336:             head= tx0 < tx ? cr_text(tx0, tx) : Vnil;
337:             if (Char(tx) == Char(tx+1)) {
338:                 value spec= cr_text(tx, tx+1);
339:                 tx+= 2;
340:                 tail= text_body(q, aq);
341:                 tail= node3(TEXT_LIT, spec, tail);
342:             } else {
343:                 parsetree e;
344:                 if (is_conversion(q, &e)) {
345:                     tail= text_body(q, aq);
346:                     tail= node3(TEXT_CONV, e, tail);
347:                 } else {
348:                     tx++;
349:                     tail= NilTree;
350:                 }
351:             }
352:             if (head == Vnil) return tail;
353:             else return node3(TEXT_LIT, head, tail);
354:         } else
355:             tx++;
356:     }
357:     parerr2(MESS(2104, "cannot find matching "), MESSMAKE(aq));
358:     return NilTree;
359: }
360:
361: Hidden bool is_conversion(q, v) txptr q; parsetree *v; {
362:     if (conv_sign()) {
363:         txptr ftx, ttx;
364:         req("`", q, &ftx, &ttx);
365:         *v= expr(ftx); tx= ttx;
366:         return Yes;
367:     }
368:     return No;
369: }
370:
371: /* ******************************************************************** */
372: /*		table_display; list_display; range_display;		*/
373: /* ******************************************************************** */
374:
375: Hidden bool elt_dis(v) parsetree *v; {
376:     if (curlyclose_sign()) {
377:         *v= node1(ELT_DIS);
378:         return Yes;
379:     }
380:     return No;
381: }
382:
383: Hidden bool range_dis(q, v) txptr q; parsetree *v; {
384:     txptr ftx, ttx;
385:     if (find("..", q, &ftx, &ttx)) {
386:         parsetree w;
387:         if (Char(ttx) == '.') { ftx++; ttx++; }
388:         w= singexpr(ftx); tx= ttx;
389:         *v= node3(RANGE_DIS, w, singexpr(q));
390:         return Yes;
391:     }
392:     return No;
393: }
394:
395: Forward value tab_comp();
396:
397: Hidden bool tab_dis(q, v) txptr q; parsetree *v; {
398:     if (Char(tx) == '[') {
399:         *v= node2(TAB_DIS, tab_comp(q, 1));
400:         return Yes;
401:     }
402:     return No;
403: }
404:
405: Hidden value tab_comp(q, n) txptr q; intlet n; {
406:     value v; parsetree key, assoc; txptr ftx, ttx;
407:     if (find(";", q, &ftx, &ttx)) {
408:         tab_elem(ftx, &key, &assoc); tx= ttx;
409:         v= tab_comp(q, n+2);
410:     } else {
411:         tab_elem(q, &key, &assoc);
412:         v= mk_compound(n+1);
413:     }
414:     *Field(v, n-1)= key;
415:     *Field(v, n)= assoc;
416:     return v;
417: }
418:
419: Hidden Procedure tab_elem(q, key, assoc) txptr q; parsetree *key, *assoc; {
420:     txptr ftx, ttx;
421:     need("[");
422:     req("]", q, &ftx, &ttx);
423:     *key= expr(ftx); tx= ttx;
424:     need(":");
425:     *assoc= singexpr(q);
426: }
427:
428: Forward value list_comp();
429:
430: Hidden Procedure list_dis(q, v) txptr q; parsetree *v; {
431:     *v= node2(LIST_DIS, list_comp(q, 1));
432: }
433:
434: Hidden value list_comp(q, n) txptr q; intlet n; {
435:     value v; parsetree w; txptr ftx, ttx;
436:     if (find(";", q, &ftx, &ttx)) {
437:         w= singexpr(ftx); tx= ttx;
438:         v= list_comp(q, n+1);
439:     } else {
440:         w= singexpr(q);
441:         v= mk_compound(n);
442:     }
443:     *Field(v, n-1)= w;
444:     return v;
445: }
446:
447: Hidden bool tlr_dis(q, v) txptr q; parsetree *v; {
448:     if (curlyopen_sign()) {
449:         skipsp(&tx);
450:         if (!elt_dis(v)) {
451:             txptr ftx, ttx;
452:             req("}", q, &ftx, &ttx);
453:             if (!range_dis(ftx, v)) {
454:                 skipsp(&tx);
455:                 if (!tab_dis(ftx, v)) list_dis(ftx, v);
456:             }
457:             tx= ttx;
458:         }
459:         return Yes;
460:     }
461:     return No;
462: }
463:
464: /* ******************************************************************** */
465: /*		selection						*/
466: /* ******************************************************************** */
467:
468: Visible Procedure selection(q, v) txptr q; parsetree *v; {
469:     txptr ftx, ttx;
470:     skipsp(&tx);
471:     while (Text(q) && sub_sign()) {
472:         req("]", q, &ftx, &ttx);
473:         *v= node3(SELECTION, *v, expr(ftx)); tx= ttx;
474:         skipsp(&tx);
475:     }
476: }
477:
478: /* ******************************************************************** */
479: /*		trimmed_text						*/
480: /* ******************************************************************** */
481:
482: Hidden bool is_trimmed_text(q) txptr q; {
483:     txptr tx0= tx; bool b;
484:     skipsp(&tx);
485:     b= Text(q) && trim_sign();
486:     tx= tx0;
487:     return b;
488: }
489:
492:     while (Parsed(adm) && Text(q) && trim_sign()) {
494:         dya_formula(q, adm, v, mk_text(textsign), L_bottom, rbase);
495:         skipsp(&tx);
496:     }
498: }
499:
500: Visible Procedure tar_trimmed_text(q, v) txptr q; parsetree *v; {
501:     if (is_trimmed_text(q)) {
506:     }
507: }
508:
509: Hidden Procedure exp_trimmed_text(q, adm, v)
511:
512:     if (!Trim(adm) && is_trimmed_text(q)) {
513:         intlet s= State(adm); /* save */
516:         State(adm)= s; /* restore */
517:     }
518: }
519:
520: /* ******************************************************************** */
521: /*		unp_expr, unp_test 					*/
522: /* ******************************************************************** */
523:
524: Forward bool item();
525:
527:     value v;
528:     skipsp(&tx);
529:     if (Text(q) && item(q, &v)) {
530:         return mon_formula(q, adm, v, unp_expr);
531:     } else {
535:     }
536: }
537:
538: Visible parsetree unp_test(q) txptr q; {
542:     *Branch(v, UNP_TEXT)= cr_text(tx0, tx);
543:     return v;
544: }
545:
546: Visible bool tag_operator(q, v) txptr q; value *v; {
547:     txptr tx0= tx;
548:     if (Text(q) && is_tag(v)) {
549:         skipsp(&tx);
550:         if (!(Text(q) && (sub_sign() || trim_sign()))) return Yes;
551:         else {
552:             release(*v);
553:             tx= tx0;
554:         }
555:     }
556:     return No;
557: }
558:
559: Hidden bool dm_operator(q, v) txptr q; value *v; {
560:     return dyamon_sign() ? (*v= mk_text(textsign), Yes) : tag_operator(q, v);
561: }
562:
563: Hidden bool d_operator(q, v) txptr q; value *v; {
564:     return dya_sign() ? (*v= mk_text(textsign), Yes) : dm_operator(q, v);
565: }
566:
567: Hidden bool m_operator(q, v) txptr q; value *v; {
568:     return mon_sign() ? (*v= mk_text(textsign), Yes) : dm_operator(q, v);
569: }
570:
571: Hidden bool trim_operator(q, v) txptr q; value *v; {
572:     return trim_sign() ? (*v= mk_text(textsign), Yes) : No;
573: }
574:
575: Hidden bool item(q, v) txptr q; value *v; {
576:     return  tag_operator(q, v) || trim_operator(q, v) ||
577:         d_operator(q, v) || m_operator(q, v) ||
578:         element(q, v);
579: }
580:
581: /* ********************************************************************	*/
582: /*		upto_expr						*/
583: /* ********************************************************************	*/
584:
585: Hidden Procedure upto_expr(q) txptr q; {
586:     skipsp(&tx);
587:     if (Text(q)) {
588:         value dum;
589:         if (d_operator(q, &dum)) {
590:             release(dum);
591:             pprerr(Prio);
592:         } else parerr(MESS(2105, "something unexpected following expression"));
593:         tx= q;
594:     }
595: }
596:
597: /* ********************************************************************	*/
598:
599: Hidden bool is_opr(v, s) value v; string s; {
600:     value t= Vnil;
601:     bool is= Is_text(v) && compare(v, t= mk_text(s)) == 0;
602:     release(t);
603:     return is;
604: }
605:
606: Visible bool b_about(v) value v;    { return is_opr(v, "~"); }
607: Visible bool b_numtor(v) value v;   { return is_opr(v, "*/"); }
608: Visible bool b_denomtor(v) value v;     { return is_opr(v, "/*"); }
609: Visible bool b_plus(v) value v;     { return is_opr(v, "+"); }
610: Visible bool b_minus(v) value v;    { return is_opr(v, "-"); }
611: Visible bool b_number(v) value v;   { return is_opr(v, "#"); }
612: Visible bool b_behead(v) value v;   { return is_opr(v, "@"); }
613: Visible bool b_curtail(v) value v;  { return is_opr(v, "|"); }
614: #ifdef NOT_USED
615: Visible bool b_times(v) value v;    { return is_opr(v, "*"); }
616: Visible bool b_over(v) value v;     { return is_opr(v, "/"); }
617: Visible bool b_power(v) value v;    { return is_opr(v, "**"); }
618: Visible bool b_join(v) value v;     { return is_opr(v, "^"); }
619: Visible bool b_reptext(v) value v;  { return is_opr(v, "^^"); }
620: Visible bool b_center(v) value v;   { return is_opr(v, "><"); }
621: Visible bool b_leftadj(v) value v;  { return is_opr(v, "<<"); }
622: Visible bool b_rightadj(v) value v;     { return is_opr(v, ">>"); }
623: #endif
```

#### Defined functions

adjust_level defined in line 185; used 8 times
b_about defined in line 606; used 2 times
b_behead defined in line 612; used 4 times
b_center defined in line 620; used 1 times
b_denomtor defined in line 608; used 2 times
b_join defined in line 618; used 1 times
b_leftadj defined in line 621; used 1 times
b_minus defined in line 610; used 6 times
b_number defined in line 611; used 4 times
b_numtor defined in line 607; used 2 times
b_over defined in line 616; used 1 times
b_plus defined in line 609; used 3 times
b_power defined in line 617; used 1 times
b_reptext defined in line 619; used 1 times
b_rightadj defined in line 622; used 1 times
b_times defined in line 615; used 1 times
base defined in line 153; used 6 times
closed_expr defined in line 275; used 2 times
constant defined in line 287; used 2 times
critical defined in line 160; used 1 times
d_operator defined in line 563; used 2 times
digits defined in line 306; used 4 times
dm_operator defined in line 559; used 2 times
dya_formula defined in line 77; used 9 times
element defined in line 240; used 3 times
elt_dis defined in line 375; used 1 times
exp_trimmed_text defined in line 509; used 1 times
expr_opr defined in line 41; used 1 times
• in line 53
factor defined in line 119; used 3 times
initexp defined in line 34; used 3 times
is_conversion defined in line 361; used 2 times
is_opr defined in line 599; used 16 times
is_trimmed_text defined in line 482; used 2 times
item defined in line 575; used 2 times
list_comp defined in line 434; used 3 times
list_dis defined in line 430; used 1 times
m_operator defined in line 567; used 1 times
mon_formula defined in line 170; used 7 times
primary defined in line 135; used 5 times
range_dis defined in line 383; used 1 times
rbase defined in line 189; used 5 times
rsingexpr defined in line 49; used 2 times
selection defined in line 468; used 2 times
seltrim_tag defined in line 254; used 2 times
singexpr defined in line 25; used 11 times
tab_comp defined in line 405; used 3 times
tab_dis defined in line 397; used 1 times
tab_elem defined in line 419; used 2 times
tag_operator defined in line 546; used 9 times
tar_trimmed_text defined in line 500; used 1 times
term defined in line 105; used 2 times
term_opr defined in line 101; used 1 times
text_body defined in line 331; used 4 times
text_dis defined in line 318; used 2 times
tlr_dis defined in line 447; used 2 times
trim_operator defined in line 571; used 1 times
trimmed_text defined in line 490; used 2 times
unp_expr defined in line 526; used 7 times
unp_test defined in line 538; used 3 times
upto_expr defined in line 585; used 1 times
• in line 73

#### Defined variables

Forward defined in line 46; never used
Hidden defined in line 105; never used
 Last modified: 1985-08-27 Generated: 2016-12-26 Generated by src2html V0.67 page hit count: 2595