home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume23 / abc / part17 < prev    next >
Encoding:
Internet Message Format  |  1991-01-08  |  54.3 KB

  1. Subject:  v23i096:  ABC interactive programming environment, Part17/25
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 1625473c 9c90c416 e7088d59 34948ff1
  5.  
  6. Submitted-by: Steven Pemberton <steven@cwi.nl>
  7. Posting-number: Volume 23, Issue 96
  8. Archive-name: abc/part17
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  abc/bed/e1inse.c abc/bed/e1move.c abc/bed/e1outp.c
  17. #   abc/bint1/i1nui.c abc/bint3/i3gfx.c abc/lin/i1tlt.h
  18. #   abc/stc/i2tce.c
  19. # Wrapped by rsalz@litchi.bbn.com on Mon Dec 17 13:28:12 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 17 (of 25)."'
  23. if test -f 'abc/bed/e1inse.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'abc/bed/e1inse.c'\"
  25. else
  26.   echo shar: Extracting \"'abc/bed/e1inse.c'\" \(7653 characters\)
  27.   sed "s/^X//" >'abc/bed/e1inse.c' <<'END_OF_FILE'
  28. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  29. X
  30. X/*
  31. X * Subroutines (refinements) for ins_string() (see que2.c).
  32. X */
  33. X
  34. X#include "b.h"
  35. X#include "bedi.h"
  36. X#include "etex.h"
  37. X#include "feat.h"
  38. X#include "bobj.h"
  39. X#include "node.h"
  40. X#include "gram.h"
  41. X#include "supr.h"
  42. X#include "tabl.h"
  43. X#include "code.h"
  44. X
  45. X
  46. X/*
  47. X * Try to insert the character c in the focus *pp.
  48. X */
  49. X
  50. XVisible bool
  51. Xinsguess(pp, c, ep)
  52. X    path *pp;
  53. X    char c;
  54. X    environ *ep;
  55. X{
  56. X    path pa = parent(*pp);
  57. X    node n;
  58. X    int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
  59. X    int ich = ichild(*pp);
  60. X    struct classinfo *ci = table[sympa].r_class[ich-1];
  61. X    classptr cp;
  62. X    string *rp;
  63. X    int code = Code(c);
  64. X    int sym;
  65. X    char buf[2];
  66. X
  67. X#ifdef USERSUGG
  68. X    if (isascii(c) && isinclass(Suggestion, ci)
  69. X        && (isalpha(c) || (c == ':' && sympa == Rootsymbol)))
  70. X    {
  71. X        if (setsugg(pp, c, ep, allows_colon(sympa)))
  72. X            return Yes;
  73. X    }
  74. X#endif /* USERSUGG */
  75. X    for (cp = ci->c_insert; *cp; cp += 2) {
  76. X        if (cp[0] == code)
  77. X            break;
  78. X    }
  79. X    if (!*cp)
  80. X        return No;
  81. X    sym = cp[1];
  82. X    if (sym >= LEXICAL) {
  83. X        buf[0] = c;
  84. X        buf[1] = 0;
  85. X        treereplace(pp, (node) mk_etext(buf));
  86. X        ep->mode = VHOLE;
  87. X        ep->s1 = 2*ich;
  88. X        ep->s2 = 1;
  89. X        return Yes;
  90. X    }
  91. X    Assert(sym < TABLEN);
  92. X    rp = table[sym].r_repr;
  93. X    n = table[sym].r_node;
  94. X    if (Fw_zero(rp[0])) {
  95. X        buf[0] = c;
  96. X        buf[1] = 0;
  97. X        setchild(&n, 1, (node) mk_etext(buf));
  98. X        treereplace(pp, n);
  99. X        ep->mode = VHOLE;
  100. X        ep->s1 = 2;
  101. X        ep->s2 = 1;
  102. X        return Yes;
  103. X    }
  104. X    treereplace(pp, n);
  105. X    if (c == '\n' || c == '\r') {
  106. X        ep->mode = SUBSET;
  107. X        ep->s1 = ep->s2 = 2;
  108. X    }
  109. X    else {
  110. X        ep->mode = FHOLE;
  111. X        ep->s1 = 1;
  112. X        ep->s2 = 1;
  113. X    }
  114. X    return Yes;
  115. X}
  116. X
  117. X
  118. X/*
  119. X * Test whether character `c' may be inserted in position `s2' in
  120. X * child `ich' of node `n'; that child must be a Text.
  121. X */
  122. X
  123. XVisible bool
  124. Xmayinsert(n, ich, s2, c)
  125. X    node n;
  126. X    int ich;
  127. X    int s2;
  128. X    register char c;
  129. X{
  130. X    int sympa = symbol(n);
  131. X    struct classinfo *ci;
  132. X    register classptr cp;
  133. X    register value v = (value) child(n, ich);
  134. X    register char c1;
  135. X    bool maycontinue();
  136. X    bool maystart();
  137. X    register bool (*fun1)() = s2 > 0 ? /*&*/maystart : /*&*/maycontinue;
  138. X    register bool (*fun2)() = s2 > 0 ? /*&*/maycontinue : /*&*/maystart;
  139. X
  140. X    Assert(v && v->type == Etex);
  141. X    Assert(sympa > 0 && sympa < TABLEN);
  142. X    ci = table[sympa].r_class[ich-1];
  143. X    Assert(ci && ci->c_class);
  144. X    /* c1 = strval(v)[0]; */
  145. X    c1= e_ncharval(1, v);
  146. X    for (cp = ci->c_class; *cp; ++cp) {
  147. X        if (*cp >= LEXICAL && (*fun1)(c1, *cp)) {
  148. X            if ((*fun2)(c, *cp))
  149. X                return Yes;
  150. X        }
  151. X    }
  152. X    return No;
  153. X}
  154. X
  155. X
  156. X/*
  157. X * Change a Fixed into a Variable node, given a string pointer variable
  158. X * which contains the next characters to be inserted.
  159. X * If the change is not appropriate, No is returned.
  160. X * Otherwise, as many (though maybe zero) characters from the string
  161. X * as possible will have been incorporated in the string node.
  162. X */
  163. X
  164. XVisible bool
  165. Xsoften(ep, pstr, alt_c)
  166. X    environ *ep;
  167. X    string *pstr;
  168. X    int alt_c;
  169. X{
  170. X    path pa = parent(ep->focus);
  171. X    node n;
  172. X    int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
  173. X    struct classinfo *ci;
  174. X    register classptr cp;
  175. X    register int code;
  176. X    string repr;
  177. X    register struct table *tp;
  178. X    char buf[1024];
  179. X
  180. X    if (ep->mode == VHOLE && (ep->s1&1))
  181. X        ep->mode = FHOLE;
  182. X    if (ep->mode != FHOLE || ep->s1 != 1 || ep->s2 <= 0 || !issuggestion(ep))
  183. X        return No;
  184. X    n = tree(ep->focus);
  185. X    repr = noderepr(n)[0];
  186. X    if (!repr || !isupper(repr[0]))
  187. X        return No;
  188. X    if (symbol(n) == Select && repr[ep->s2-1] == ':')
  189. X        return No;
  190. X    if (symbol(n) == Head)
  191. X        return No;
  192. X    code = Code(repr[0]);
  193. X    ci = table[sympa].r_class[ichild(ep->focus) - 1];
  194. X    n = Nnil;
  195. X    for (cp = ci->c_insert; *cp; cp += 2) {
  196. X        if (cp[0] != code)
  197. X            continue;
  198. X        if (cp[1] >= TABLEN)
  199. X            continue;
  200. X        tp = &table[cp[1]];
  201. X        if (Fw_zero(tp->r_repr[0])) {
  202. X            Assert(tp->r_class[0]->c_class[0] >= LEXICAL);
  203. X            n = tp->r_node;
  204. X            break;
  205. X        }
  206. X    }
  207. X    if (!n)
  208. X        return No;
  209. X    strncpy(buf, repr, ep->s2);
  210. X    buf[ep->s2] = 0;
  211. X    setchild(&n, 1, (node) mk_etext(buf));
  212. X    if (!mayinsert(n, 1, ep->s2, repr[ep->s2])) {
  213. X        if (!**pstr || !mayinsert(n, 1, ep->s2, **pstr)
  214. X            && (!alt_c || !mayinsert(n, 1, ep->s2, alt_c))) {
  215. X            noderelease(n); /* Don't forget! */
  216. X            return No;
  217. X        }
  218. X    }
  219. X    if (!ep->spflag && **pstr && mayinsert(n, 1, ep->s2, **pstr)) {
  220. X        do {
  221. X            buf[ep->s2] = **pstr;
  222. X            ++*pstr;
  223. X            ++ep->s2;
  224. X        } while (ep->s2 < sizeof buf - 1 && **pstr
  225. X                && mayinsert(n, 1, ep->s2, **pstr));
  226. X        buf[ep->s2] = 0;
  227. X        setchild(&n, 1, (node) mk_etext(buf));
  228. X    }
  229. X    treereplace(&ep->focus, n);
  230. X    ep->mode = VHOLE;
  231. X    ep->s1 = 2;
  232. X    return Yes;
  233. X}
  234. X
  235. X
  236. X/*
  237. X * Renew suggestion, or advance in old suggestion.
  238. X * Return Yes if *pstr has been advanced.
  239. X */
  240. X
  241. XVisible bool
  242. Xresuggest(ep, pstr, alt_c)
  243. X    environ *ep;
  244. X    string *pstr;
  245. X    int alt_c;
  246. X{
  247. X    struct table *tp;
  248. X    struct classinfo *ci;
  249. X    classptr cp;
  250. X    path pa;
  251. X    node nn;
  252. X    node n = tree(ep->focus);
  253. X    register string *oldrp = noderepr(n);
  254. X    register int ich = ep->s1/2;
  255. X    register string str = oldrp[ich];
  256. X    int oldsym = symbol(n);
  257. X    int childsym[MAXCHILD];
  258. X    string *newrp;
  259. X    int sympa;
  260. X    register int sym;
  261. X    int symfound = -1;
  262. X    register int i;
  263. X    int code;
  264. X    char buf[15]; /* Should be sufficient for all fixed texts */
  265. X    bool ok;
  266. X    bool anyok = No;
  267. X
  268. X    if (!str || !**pstr || !issuggestion(ep))
  269. X        return No;
  270. X    /***** Change this if commands can be prefixes of others! *****/
  271. X    /***** Well, they can!
  272. X    if (!c)
  273. X        return No;
  274. X        *****/
  275. X
  276. X    if (ich > 0 && ifmatch(ep, pstr, str, alt_c))
  277. X        /* Shortcut: sec. keyword, exact match will do just fine */
  278. X        return Yes;
  279. X    if (ep->s2 <= 0 || Fw_zero(oldrp[0]))
  280. X        return No;
  281. X    if (**pstr != ' ' && !isupper(**pstr)
  282. X        && !alt_c && **pstr != '"' && **pstr != '\'' && **pstr != '.')
  283. X        /* Shortcut: not a keyword, must match exactly */
  284. X        return ifmatch(ep, pstr, str, alt_c);
  285. X    for (i = 0; i < ich; ++i) { /* Preset some stuff for main loop */
  286. X        if (!oldrp[i])
  287. X            oldrp[i] = "";
  288. X        childsym[i] = symbol(child(n, i+1));
  289. X    }
  290. X    Assert(ep->s2 + 1 < sizeof buf);
  291. X    strcpy(buf, oldrp[ich]);
  292. X    buf[ep->s2] = alt_c ? alt_c : **pstr;
  293. X    buf[ep->s2 + 1] = 0;
  294. X    pa = parent(ep->focus);
  295. X    sympa = pa ? symbol(tree(pa)) : Rootsymbol;
  296. X    ci = table[sympa].r_class[ichild(ep->focus) - 1];
  297. X    code = Code(oldrp[0][0]);
  298. X
  299. X    for (cp = ci->c_insert; *cp; cp += 2) {
  300. X        if (cp[0] != code)
  301. X            continue;
  302. X        sym = cp[1];
  303. X        if (sym >= TABLEN)
  304. X            continue;
  305. X        if (sym == oldsym) {
  306. X            anyok = Yes;
  307. X            continue;
  308. X        }
  309. X        tp = &table[sym];
  310. X        newrp = tp->r_repr;
  311. X        ok = Yes;
  312. X        for (i = 0; i < ich; ++i) {
  313. X            str = newrp[i];
  314. X            if (!str)
  315. X                str = "";
  316. X            if (strcmp(str, oldrp[i])
  317. X                || childsym[i] != Optional && childsym[i] != Hole
  318. X                    && !isinclass(childsym[i], tp->r_class[i])) {
  319. X                ok = No;
  320. X                break;
  321. X            }
  322. X        }
  323. X        if (!ok)
  324. X            continue;
  325. X        str = newrp[i];
  326. X        if (!str || strncmp(str, buf, ep->s2+1))
  327. X            continue;
  328. X        if (anyok) {
  329. X            if (!strcmp(str, oldrp[ich]))
  330. X                continue; /* Same as it was: no new suggestion */
  331. X            symfound = sym;
  332. X            break;
  333. X        }
  334. X        else if (symfound < 0 && strcmp(str, oldrp[ich]))
  335. X            symfound = sym;
  336. X    }
  337. X
  338. X    if (symfound < 0) {
  339. X        return ifmatch(ep, pstr, oldrp[ich], alt_c);
  340. X    }
  341. X    nn = table[symfound].r_node;
  342. X    for (i = 1; i <= ich; ++i) { /* Copy children to the left of the focus */
  343. X        sym = symbol(child(n, i));
  344. X        if (sym == Optional || sym == Hole)
  345. X            continue;
  346. X        setchild(&nn, i, nodecopy(child(n, i)));
  347. X    }
  348. X    treereplace(&ep->focus, nn);
  349. X    str = newrp[ich];
  350. X    do { /* Find easy continuation */
  351. X        ++ep->s2;
  352. X        ++*pstr;
  353. X    } while (**pstr && **pstr == str[ep->s2]);
  354. X    
  355. X    return Yes;
  356. X}
  357. X
  358. X
  359. X/*
  360. X * Refinement for resuggest(): see if there is a match, and if so, find
  361. X * longest match.
  362. X */
  363. X
  364. XHidden bool
  365. Xifmatch(ep, pstr, str, alt_c)
  366. X    register environ *ep;
  367. X    register string *pstr;
  368. X    register string str;
  369. X    register int alt_c;
  370. X{
  371. X    register int c = str[ep->s2];
  372. X
  373. X    if (c != **pstr && (!alt_c || c != alt_c))
  374. X        return No;
  375. X    do {
  376. X        ++ep->s2;
  377. X        ++*pstr;
  378. X    } while (**pstr && **pstr == str[ep->s2]);
  379. X    
  380. X    return Yes;
  381. X}
  382. END_OF_FILE
  383.   if test 7653 -ne `wc -c <'abc/bed/e1inse.c'`; then
  384.     echo shar: \"'abc/bed/e1inse.c'\" unpacked with wrong size!
  385.   fi
  386.   # end of 'abc/bed/e1inse.c'
  387. fi
  388. if test -f 'abc/bed/e1move.c' -a "${1}" != "-c" ; then 
  389.   echo shar: Will not clobber existing file \"'abc/bed/e1move.c'\"
  390. else
  391.   echo shar: Extracting \"'abc/bed/e1move.c'\" \(7754 characters\)
  392.   sed "s/^X//" >'abc/bed/e1move.c' <<'END_OF_FILE'
  393. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  394. X
  395. X/*
  396. X * B editor -- Process arrow keys in four directions, plus TAB.
  397. X */
  398. X
  399. X#include "b.h"
  400. X#include "feat.h"
  401. X#include "bedi.h"
  402. X#include "etex.h"
  403. X#include "bobj.h"
  404. X#include "node.h"
  405. X#include "supr.h"
  406. X#include "gram.h"
  407. X#include "tabl.h"
  408. X
  409. X#define Left (-1)
  410. X#define Rite 1
  411. X
  412. X
  413. X/*
  414. X * Common code for PREVIOUS and NEXT commands.
  415. X */
  416. X
  417. XHidden bool
  418. Xprevnext(ep, direction)
  419. X    environ *ep;
  420. X{
  421. X    node n;
  422. X    node n1;
  423. X    int nch;
  424. X    int i;
  425. X    int len;
  426. X    int sym;
  427. X    string *rp;
  428. X
  429. X    higher(ep);
  430. X    switch (ep->mode) {
  431. X    case VHOLE:
  432. X    case FHOLE:
  433. X    case ATBEGIN:
  434. X    case ATEND:
  435. X        if (direction == Left)
  436. X            leftvhole(ep);
  437. X        else
  438. X            ritevhole(ep);
  439. X    }
  440. X
  441. X    for (;;) {
  442. X        n = tree(ep->focus);
  443. X        nch = nchildren(n);
  444. X        rp = noderepr(n);
  445. X
  446. X        switch (ep->mode) {
  447. X
  448. X        case ATBEGIN:
  449. X        case ATEND:
  450. X            ep->mode = WHOLE;
  451. X            continue;
  452. X
  453. X        case VHOLE:
  454. X        case FHOLE:
  455. X            if (direction == Rite) {
  456. X                if (ep->s1&1)
  457. X                    len = Fwidth(rp[ep->s1/2]);
  458. X                else {
  459. X                    n1 = child(n, ep->s1/2);
  460. X                    len = nodewidth(n1);
  461. X                }
  462. X            }
  463. X            if (direction == Rite ? ep->s2 >= len : ep->s2 <= 0) {
  464. X                ep->mode = SUBSET;
  465. X                ep->s2 = ep->s1;
  466. X                return nextchar(ep, direction);
  467. X            }
  468. X            ep->s2 += direction;
  469. X            return Yes;
  470. X
  471. X        case SUBRANGE:
  472. X            if (direction == Rite) {
  473. X                if (ep->s1&1)
  474. X                    len = Fwidth(rp[ep->s1/2]);
  475. X                else {
  476. X                    n1 = child(n, ep->s1/2);
  477. X                    len = nodewidth(n1);
  478. X                }
  479. X            }
  480. X            if (direction == Left ? ep->s2 <= 0 : ep->s3 >= len-1) {
  481. X                ep->mode = SUBSET;
  482. X                ep->s2 = ep->s1;
  483. X                return nextchar(ep, direction);
  484. X            }
  485. X            if (direction == Rite)
  486. X                ep->s2 = ++ep->s3;
  487. X            else
  488. X                ep->s3 = --ep->s2;
  489. X            return Yes;
  490. X
  491. X        case SUBSET:
  492. X            if (direction == Rite ? ep->s2 > 2*nch : ep->s1 <= 1) {
  493. X                ep->mode = WHOLE;
  494. X                continue;
  495. X            }
  496. X            if (direction == Rite)
  497. X                ep->s1 = ++ep->s2;
  498. X            else
  499. X                ep->s2 = --ep->s1;
  500. X            if (ep->s1&1) {
  501. X                if (!Fw_positive(rp[ep->s1/2]) || allspaces(rp[ep->s1/2]))
  502. X                    continue;
  503. X            }
  504. X            else {
  505. X                sym = symbol(n);
  506. X                if (downi(&ep->focus, ep->s1/2)) {
  507. X                    n = tree(ep->focus);
  508. X                    if (((value)n)->type == Etex)
  509. X                        s_up(ep);
  510. X                    else {
  511. X                        if (ep->s1 == 2*nch && direction == Rite
  512. X                            && issublist(sym) && samelevel(sym, symbol(n))) {
  513. X                            ep->mode = SUBLIST;
  514. X                            ep->s3 = 1;
  515. X                            return Yes;
  516. X                        }
  517. X                        ep->mode = WHOLE;
  518. X                        if (nodewidth(n) == 0)
  519. X                            continue;
  520. X                    }
  521. X                }
  522. X            }
  523. X            return Yes;
  524. X
  525. X        case SUBLIST:
  526. X            sym = symbol(n);
  527. X            if (direction == Left) {
  528. X                i = ichild(ep->focus);
  529. X                if (!up(&ep->focus))
  530. X                    return No;
  531. X                higher(ep);
  532. X                n = tree(ep->focus);
  533. X                if (i == nchildren(n) && samelevel(sym, symbol(n))) {
  534. X                    ep->s3 = 1;
  535. X                    return Yes;
  536. X                }
  537. X                ep->mode = SUBSET;
  538. X                ep->s1 = ep->s2 = 2*i;
  539. X                continue;
  540. X            }
  541. X            for (i = ep->s3; i > 0; --i)
  542. X                if (!downrite(&ep->focus))
  543. X                    return No; /* Sorry... */
  544. X            if (samelevel(sym, symbol(tree(ep->focus))))
  545. X                ep->s3 = 1;
  546. X            else
  547. X                ep->mode = WHOLE;
  548. X            return Yes;
  549. X
  550. X        case WHOLE:
  551. X            i = ichild(ep->focus);
  552. X            if (!up(&ep->focus))
  553. X                return No;
  554. X            higher(ep);
  555. X            ep->mode = SUBSET;
  556. X            ep->s1 = ep->s2 = 2*i;
  557. X            continue;
  558. X
  559. X        default:
  560. X            Abort();
  561. X        }
  562. X    }
  563. X    /* Not reached */
  564. X}
  565. X
  566. X
  567. XVisible bool
  568. Xprevious(ep)
  569. X    environ *ep;
  570. X{
  571. X    if (!prevnext(ep, Left))
  572. X        return No;
  573. X    return Yes;
  574. X}
  575. X
  576. X
  577. XVisible bool
  578. Xnextarrow(ep)
  579. X    environ *ep;
  580. X{
  581. X    if (!prevnext(ep, Rite))
  582. X        return No;
  583. X    return Yes;
  584. X}
  585. X
  586. XVisible bool
  587. Xleftarrow(ep)
  588. X    environ *ep;
  589. X{
  590. X    int w;
  591. X    bool hole;
  592. X
  593. X    if (narrow(ep)) {
  594. X        while (narrow(ep))
  595. X            ;
  596. X        return Yes;
  597. X    }
  598. X    hole= ep->mode == WHOLE;
  599. X    if (!previous(ep))
  600. X        return No;
  601. X    if (hole) {
  602. X        for (;;) {
  603. X            w= focwidth(ep);
  604. X            if (w >= 0 && w <= 1)
  605. X                break;
  606. X            if (!rnarrow(ep))
  607. X                return No;
  608. X        }
  609. X        VOID narrow(ep);
  610. X    }
  611. X    else {
  612. X        while (rnarrow(ep))
  613. X            ;
  614. X    }
  615. X    return Yes;
  616. X}
  617. X
  618. XVisible bool
  619. Xritearrow(ep)
  620. X    environ *ep;
  621. X{
  622. X    while (narrow(ep))
  623. X        ;
  624. X    if (!nextarrow(ep))
  625. X        return No;
  626. X    while (narrow(ep))
  627. X        ;
  628. X    return Yes;
  629. X}
  630. X
  631. X/*
  632. X * Position focus at next or previous char relative to current position.
  633. X * Assume current position given as SUBSET.
  634. X */
  635. X
  636. XHidden bool
  637. Xnextchar(ep, direction)
  638. X    register environ *ep;
  639. X    register int direction;
  640. X{
  641. X    register int ich;
  642. X    register int nch;
  643. X    register node n;
  644. X    node n1;
  645. X    register int len;
  646. X    string *rp;
  647. X
  648. X    Assert(ep->mode == SUBSET);
  649. X    for (;;) {
  650. X        n = tree(ep->focus);
  651. X        rp = noderepr(n);
  652. X        nch = nchildren(n);
  653. X        if (direction == Left)
  654. X            ep->s2 = --ep->s1;
  655. X        else
  656. X            ep->s1 = ++ep->s2;
  657. X        if (direction == Left ? ep->s1 < 1 : ep->s2 > 2*nch+1) {
  658. X            ich = ichild(ep->focus);
  659. X            if (!up(&ep->focus))
  660. X                return No; /* *ep is garbage now! */
  661. X            higher(ep);
  662. X            ep->s1 = ep->s2 = 2*ich;
  663. X            continue;
  664. X        }
  665. X        if (ep->s1&1) {
  666. X            len = Fwidth(rp[ep->s1/2]);
  667. X            if (len > 0) {
  668. X                ep->mode = SUBRANGE;
  669. X                ep->s2 = ep->s3 = direction == Left ? len-1 : 0;
  670. X                return Yes;
  671. X            }
  672. X            continue;
  673. X        }
  674. X        n1 = child(n, ep->s1/2);
  675. X        len = nodewidth(n1);
  676. X        if (len == 0)
  677. X            continue;
  678. X        if (!downi(&ep->focus, ep->s1/2))
  679. X            return No; /* Sorry... */
  680. X        n = tree(ep->focus);
  681. X        if (((value)n)->type == Etex) {
  682. X            s_up(ep);
  683. X            ep->mode = SUBRANGE;
  684. X            ep->s2 = ep->s3 = direction == Left ? len-1 : 0;
  685. X            return Yes;
  686. X        }
  687. X        if (direction == Left) {
  688. X            nch = nchildren(n);
  689. X            ep->s1 = ep->s2 = 2*(nch+1);
  690. X        }
  691. X        else
  692. X            ep->s1 = ep->s2 = 0;
  693. X    }
  694. X    /* Not reached */
  695. X}
  696. X
  697. X
  698. X/*
  699. X * Up and down arrows.
  700. X */
  701. X
  702. XHidden bool
  703. Xupdownarrow(ep, yincr)
  704. X    environ *ep;
  705. X    int yincr;
  706. X{
  707. X    int y, x;
  708. X
  709. X    while (narrow(ep))
  710. X        ;
  711. X    y= lineno(ep) + yincr;
  712. X    x= colno(ep);
  713. X    if (!gotoyx(ep, y, x))
  714. X        return No;
  715. X    gotofix(ep, y, x);
  716. X    while (narrow(ep))
  717. X        ;
  718. X    return Yes;
  719. X}
  720. X
  721. XVisible bool
  722. Xuparrow(ep)
  723. X    environ *ep;
  724. X{
  725. X    return updownarrow(ep, -1);
  726. X}
  727. X
  728. XVisible bool
  729. Xdownarrow(ep)
  730. X    environ *ep;
  731. X{
  732. X    return updownarrow(ep, 1);
  733. X}
  734. X
  735. XVisible bool
  736. Xupline(ep)
  737. X    register environ *ep;
  738. X{
  739. X    register int y;
  740. X
  741. X    y = lineno(ep);
  742. X    if (y <= 0)
  743. X        return No;
  744. X    if (!gotoyx(ep, y-1, 0))
  745. X        return No;
  746. X    oneline(ep);
  747. X    return Yes;
  748. X}
  749. X
  750. XVisible bool
  751. Xdownline(ep)
  752. X    register environ *ep;
  753. X{
  754. X    register int w;
  755. X
  756. X    if (!parent(ep->focus) && ep->mode == ATEND)
  757. X        return No; /* Superfluous? */
  758. X    w = -focwidth(ep);
  759. X    if (w <= 0)
  760. X        w = 1;
  761. X    if (!gotoyx(ep, lineno(ep) + w, 0))
  762. X        return No;
  763. X    oneline(ep);
  764. X    return Yes;
  765. X}
  766. X
  767. X
  768. X/*
  769. X * ACCEPT command
  770. X * move to next Hole hole or to end of suggestion or to end of line.
  771. X */
  772. X
  773. X
  774. XVisible bool
  775. Xaccept(ep)
  776. X    environ *ep;
  777. X{
  778. X    int i;
  779. X    string repr;
  780. X
  781. X    shrink(ep);
  782. X    switch (ep->mode) {
  783. X    case ATBEGIN:
  784. X    case ATEND:
  785. X    case FHOLE:
  786. X    case VHOLE:
  787. X        ritevhole(ep);
  788. X    }
  789. X#ifdef USERSUGG
  790. X    if (symbol(tree(ep->focus)) == Sugghowname)
  791. X        ackhowsugg(ep);
  792. X#endif
  793. X    if (symbol(tree(ep->focus)) == Hole) {
  794. X        ep->mode = WHOLE;
  795. X        return No;
  796. X    }
  797. X    switch (ep->mode) {
  798. X    case ATBEGIN:
  799. X    case SUBLIST:
  800. X    case WHOLE:
  801. X        i = 1;
  802. X        break;
  803. X    case ATEND:
  804. X        i = 2*nchildren(tree(ep->focus)) + 2;
  805. X        break;
  806. X    case SUBRANGE:
  807. X    case VHOLE:
  808. X    case FHOLE:
  809. X        i = ep->s1;
  810. X        if (ep->s2 > 0 && i > 2*nchildren(tree(ep->focus)))
  811. X            ++i; /* Kludge so after E?LSE: the focus moves to ELSE: ? */
  812. X        break;
  813. X    case SUBSET:
  814. X        i = ep->s1 - 1;
  815. X        break;
  816. X    default:
  817. X        Abort();
  818. X    }
  819. X    ep->mode = WHOLE;
  820. X    for (;;) {
  821. X        if (i/2 == nchildren(tree(ep->focus))) {
  822. X            repr = noderepr(tree(ep->focus))[i/2];
  823. X            if (Fw_positive(repr))
  824. X                break;
  825. X        }
  826. X        if (tabstop(ep, i + 1))
  827. X            return Yes;
  828. X        i = 2*ichild(ep->focus) + 1;
  829. X        if (!up(&ep->focus))
  830. X            break;
  831. X        higher(ep);
  832. X    }
  833. X    ep->mode = ATEND;
  834. X    return Yes;
  835. X}
  836. X
  837. X
  838. X/*
  839. X * Find suitable tab stops for accept.
  840. X */
  841. X
  842. XHidden bool
  843. Xtabstop(ep, i)
  844. X    environ *ep;
  845. X    int i;
  846. X{
  847. X    node n = tree(ep->focus);
  848. X    int nch;
  849. X    string repr;
  850. X
  851. X    if (Is_etext(n))
  852. X        return No;
  853. X    nch = nchildren(n);
  854. X    if (i/2 > nch)
  855. X        return No;
  856. X    if (symbol(n) == Hole) {
  857. X        ep->mode = WHOLE;
  858. X        return Yes;
  859. X    }
  860. X    if (i < 2) {
  861. X        i = 2;
  862. X        if (nodewidth(n) < 0) {
  863. X            repr = noderepr(n)[0];
  864. X            if (Fw_negative(repr)) {
  865. X                ep->mode = ATBEGIN;
  866. X                leftvhole(ep);
  867. X                return Yes;
  868. X            }
  869. X        }
  870. X    }
  871. X    for (i /= 2; i <= nch; ++i) {
  872. X        s_downi(ep, i);
  873. X        if (tabstop(ep, 1))
  874. X            return Yes;
  875. X        s_up(ep);
  876. X    }
  877. X    return No;
  878. X}
  879. END_OF_FILE
  880.   if test 7754 -ne `wc -c <'abc/bed/e1move.c'`; then
  881.     echo shar: \"'abc/bed/e1move.c'\" unpacked with wrong size!
  882.   fi
  883.   # end of 'abc/bed/e1move.c'
  884. fi
  885. if test -f 'abc/bed/e1outp.c' -a "${1}" != "-c" ; then 
  886.   echo shar: Will not clobber existing file \"'abc/bed/e1outp.c'\"
  887. else
  888.   echo shar: Extracting \"'abc/bed/e1outp.c'\" \(7976 characters\)
  889.   sed "s/^X//" >'abc/bed/e1outp.c' <<'END_OF_FILE'
  890. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  891. X
  892. X/*
  893. X * B editor -- Screen management package, lower level output part.
  894. X */
  895. X
  896. X#include "b.h"
  897. X#include "bedi.h"
  898. X#include "etex.h"
  899. X#include "bobj.h"
  900. X#include "bmem.h"
  901. X#include "node.h"
  902. X#include "supr.h"
  903. X#include "gram.h"
  904. X#include "cell.h"
  905. X#include "tabl.h"
  906. X
  907. X#define SOBIT 0200
  908. X#define CHAR 0177
  909. X
  910. X/*
  911. X * Variables used for communication with outfocus.
  912. X */
  913. X
  914. XHidden node thefocus;
  915. XHidden environ wherebuf;
  916. XHidden environ *where = &wherebuf;
  917. XHidden bool realvhole;
  918. XHidden int multiline; /* Height of focus */
  919. XHidden int yfocus;
  920. X
  921. XVisible int focy; /* Where the cursor must go */
  922. XVisible int focx;
  923. X
  924. X
  925. X/*
  926. X * Save position of the focus for use by outnode/outfocus.
  927. X */
  928. X
  929. XVisible Procedure
  930. Xsavefocus(ep)
  931. X    register environ *ep;
  932. X{
  933. X    register int sym;
  934. X    register int w;
  935. X
  936. X    realvhole = No;
  937. X    thefocus = Nnil;
  938. X    multiline = 0;
  939. X    yfocus = Ycoord(ep->focus);
  940. X    w = focoffset(ep);
  941. X    if (w < 0)
  942. X        yfocus += -w;
  943. X    w = focwidth(ep);
  944. X    if (w < 0) {
  945. X        multiline = -w;
  946. X        if (focchar(ep) == '\n')
  947. X            ++yfocus;
  948. X        else
  949. X            ++multiline;
  950. X        return;
  951. X    }
  952. X    if (ep->mode == WHOLE) {
  953. X        sym = symbol(tree(ep->focus));
  954. X        if (sym == Optional)
  955. X            ep->mode = ATBEGIN;
  956. X    }
  957. X    switch(ep->mode) {
  958. X    case VHOLE:
  959. X        if (ep->s1&1)
  960. X            ep->mode = FHOLE;
  961. X    case ATBEGIN:
  962. X    case ATEND:
  963. X    case FHOLE:
  964. X        ritevhole(ep);
  965. X        switch (ep->mode) {
  966. X        case ATBEGIN:
  967. X        case FHOLE:
  968. X            sym = symbol(tree(ep->focus));
  969. X            if (sym == Hole && (ep->mode == ATBEGIN || ep->s2 == 0)) {
  970. X                ep->mode = WHOLE;
  971. X                break;
  972. X            }
  973. X            /* Fall through */
  974. X        case VHOLE:
  975. X        case ATEND:
  976. X            leftvhole(ep);
  977. X            realvhole = 1 + ep->spflag;
  978. X        }
  979. X    }
  980. X    touchpath(&ep->focus); /* Make sure it is a unique pointer */
  981. X    thefocus = tree(ep->focus); /* No copy; used for comparison only! */
  982. X    where->mode = ep->mode;
  983. X    where->s1 = ep->s1;
  984. X    where->s2 = ep->s2;
  985. X    where->s3 = ep->s3;
  986. X    where->spflag = ep->spflag;
  987. X}
  988. X
  989. X
  990. X/*
  991. X * Incorporate the information saved about the focus.
  992. X */
  993. X
  994. XVisible Procedure
  995. Xsetfocus(tops)
  996. X    register cell *tops;
  997. X{
  998. X    register cell *p;
  999. X    register int i;
  1000. X
  1001. X    for (p = tops, i = 0; i < yfocus; ++i, p = p->c_link) {
  1002. X        if (!p) {
  1003. X#ifndef NDEBUG
  1004. X            debug("[Focus lost (setfocus)]");
  1005. X#endif /* NDEBUG */
  1006. X            return;
  1007. X        }
  1008. X    }
  1009. X    p->c_newvhole = realvhole;
  1010. X    i = multiline;
  1011. X    do {
  1012. X        p->c_newfocus = Yes;
  1013. X        p = p->c_link;
  1014. X    } while (--i > 0);
  1015. X}
  1016. X
  1017. X
  1018. X/*
  1019. X * Signal that actual updata is started.
  1020. X */
  1021. X
  1022. XVisible Procedure
  1023. Xstartactupdate(nofocus)
  1024. X    bool nofocus;
  1025. X{
  1026. X    if (nofocus) {
  1027. X        multiline = 0;
  1028. X        thefocus = Nnil;
  1029. X    }
  1030. X}
  1031. X
  1032. X
  1033. X/*
  1034. X * Signal the end of the actual update.
  1035. X */
  1036. X
  1037. XVisible Procedure
  1038. Xendactupdate()
  1039. X{
  1040. X}
  1041. X
  1042. X
  1043. X/*
  1044. X * Output a line of text.
  1045. X */
  1046. X
  1047. XVisible Procedure
  1048. Xoutline(p, lineno)
  1049. X    register cell *p;
  1050. X    register int lineno;
  1051. X{
  1052. X    register node n = p->c_data;
  1053. X    register int w = nodewidth(n);
  1054. X    register int len=  p->c_newindent + 4 + (w < 0 ? linelen(n) : w);
  1055. X            /* some 4 extra for spflag and vhole */
  1056. X    register string buf;
  1057. X    auto string bp;
  1058. X    register int i;
  1059. X    register int endarea = lineno+Space(p)-1;
  1060. X
  1061. X    buf= (string) getmem((unsigned) len);
  1062. X    bp= buf;
  1063. X    if (endarea >= winheight)
  1064. X        endarea = winheight-1;
  1065. X    for (i = p->c_newindent; i-- > 0; )
  1066. X        *bp++ = ' ';
  1067. X    if (!p->c_newfocus) {
  1068. X        smash(&bp, n, 0);
  1069. X        *bp = 0;
  1070. X        Assert(bp-buf < len);
  1071. X    }
  1072. X    else {
  1073. X        if (multiline)
  1074. X            smash(&bp, n, SOBIT);
  1075. X        else if (n == thefocus)
  1076. X            focsmash(&bp, n);
  1077. X        else
  1078. X            smash(&bp, n, 0);
  1079. X        *bp = 0;
  1080. X        Assert(bp-buf < len);
  1081. X        for (bp = buf; *bp && !(*bp&SOBIT); ++bp)
  1082. X            ;
  1083. X        if (*bp&SOBIT) {
  1084. X            if (focy == Nowhere) {
  1085. X                focx = indent + bp-buf;
  1086. X                focy = lineno + focx/llength;
  1087. X                focx %= llength;
  1088. X            }
  1089. X            if (multiline <= 1 && !(bp[1]&SOBIT))
  1090. X                *bp &= ~SOBIT; /* Clear mask if just one char in focus */
  1091. X        }
  1092. X    }
  1093. X    trmputdata(lineno, endarea, indent, buf);
  1094. X    freemem((ptr) buf);
  1095. X}
  1096. X
  1097. X
  1098. X/*
  1099. X * Smash -- produce a linear version of a node in a buffer (which had
  1100. X * better be long enough!).  The buffer pointer is moved to the end of
  1101. X * the resulting string.
  1102. X * Care is taken to represent the focus.
  1103. X * Characters in the focus have their upper bit set.
  1104. X */
  1105. X
  1106. X#define Outvhole() \
  1107. X    (where->spflag && strsmash(pbuf, " ", 0), strsmash(pbuf, "?", SOBIT))
  1108. X
  1109. XHidden Procedure
  1110. Xfocsmash(pbuf, n)
  1111. X    string *pbuf;
  1112. X    node n;
  1113. X{
  1114. X    value v;
  1115. X    string str;
  1116. X    register string *rp;
  1117. X    register int maxs2;
  1118. X    register int i;
  1119. X    register bool ok;
  1120. X    register int j;
  1121. X    register int mask;
  1122. X
  1123. X    switch (where->mode) {
  1124. X
  1125. X    case WHOLE:
  1126. X        smash(pbuf, n, SOBIT);
  1127. X        break;
  1128. X
  1129. X    case ATBEGIN:
  1130. X        Outvhole();
  1131. X        smash(pbuf, n, 0);
  1132. X        break;
  1133. X
  1134. X    case ATEND:
  1135. X        smash(pbuf, n, 0);
  1136. X        Outvhole();
  1137. X        break;
  1138. X
  1139. X    case VHOLE:
  1140. X        if (!(where->s1&1)) {
  1141. X            v = (value) child(n, where->s1/2);
  1142. X            Assert(Is_etext(v));
  1143. X            str= e_sstrval(v);
  1144. X            subsmash(pbuf, str, where->s2, 0);
  1145. X            Outvhole();
  1146. X            j= symbol(n);
  1147. X            i= str[where->s2] == '?' &&
  1148. X             (j == Suggestion || j == Sugghowname);
  1149. X            strsmash(pbuf, str + where->s2 + i, 0);
  1150. X            e_fstrval(str);
  1151. X            break;
  1152. X        }
  1153. X        /* Else, fall through */
  1154. X    case FHOLE:
  1155. X        rp = noderepr(n);
  1156. X        maxs2 = 2*nchildren(n) + 1;
  1157. X        for (ok = Yes, i = 1; ok && i <= maxs2; ++i) {
  1158. X            if (i&1) {
  1159. X                if (i == where->s1) {
  1160. X                    subsmash(pbuf, rp[i/2], where->s2, 0);
  1161. X                    Outvhole();
  1162. X                    if (rp[i/2])
  1163. X                        strsmash(pbuf, rp[i/2] + where->s2, 0);
  1164. X                }
  1165. X                else
  1166. X                    strsmash(pbuf, rp[i/2], 0);
  1167. X            }
  1168. X            else
  1169. X                ok = chismash(pbuf, n, i/2, 0);
  1170. X        }
  1171. X        break;
  1172. X
  1173. X    case SUBRANGE:
  1174. X        rp = noderepr(n);
  1175. X        maxs2 = 2*nchildren(n) + 1;
  1176. X        for (ok = Yes, i = 1; ok && i <= maxs2; ++i) {
  1177. X            if (i&1) {
  1178. X                if (i == where->s1) {
  1179. X                    subsmash(pbuf, rp[i/2], where->s2,0);
  1180. X                    if (rp[i/2])
  1181. X                        subsmash(pbuf, rp[i/2] + where->s2,
  1182. X                            where->s3 - where->s2 + 1, SOBIT);
  1183. X                    if (rp[i/2])
  1184. X                        strsmash(pbuf, rp[i/2] + where->s3 + 1, 0);
  1185. X                }
  1186. X                else
  1187. X                    strsmash(pbuf, rp[i/2], 0);
  1188. X            }
  1189. X            else if (i == where->s1) {
  1190. X                v = (value)child(n, i/2);
  1191. X                Assert(Is_etext(v));
  1192. X                str = e_sstrval(v);
  1193. X                subsmash(pbuf, str, where->s2, 0);
  1194. X                subsmash(pbuf, str + where->s2, where->s3 - where->s2 + 1,
  1195. X                    SOBIT);
  1196. X                strsmash(pbuf, str + where->s3 + 1, 0);
  1197. X                e_fstrval(str);
  1198. X            }
  1199. X            else
  1200. X                ok = chismash(pbuf, n, i/2, 0);
  1201. X        }
  1202. X        break;
  1203. X
  1204. X    case SUBLIST:
  1205. X        for (ok = Yes, j = where->s3; j > 0; --j) {
  1206. X            rp = noderepr(n);
  1207. X            maxs2 = 2*nchildren(n) - 1;
  1208. X            for (i = 1; ok && i <= maxs2; ++i) {
  1209. X                if (i&1)
  1210. X                    strsmash(pbuf, rp[i/2], SOBIT);
  1211. X                else
  1212. X                    ok = chismash(pbuf, n, i/2, SOBIT);
  1213. X            }
  1214. X            if (ok)
  1215. X                n = lastchild(n);
  1216. X        }
  1217. X        if (ok)
  1218. X            smash(pbuf, n, 0);
  1219. X        break;
  1220. X
  1221. X    case SUBSET:
  1222. X        rp = noderepr(n);
  1223. X        maxs2 = 2*nchildren(n) + 1;
  1224. X        mask = 0;
  1225. X        for (ok = Yes, i = 1; ok && i <= maxs2; ++i) {
  1226. X            if (i == where->s1)
  1227. X                mask = SOBIT;
  1228. X            if (i&1)
  1229. X                strsmash(pbuf, rp[i/2], mask);
  1230. X            else
  1231. X                ok = chismash(pbuf, n, i/2, mask);
  1232. X            if (i == where->s2)
  1233. X                mask = 0;
  1234. X        }
  1235. X        break;
  1236. X
  1237. X    default:
  1238. X        Abort();
  1239. X    }
  1240. X}
  1241. X
  1242. XHidden Procedure
  1243. Xsmash(pbuf, n, mask)
  1244. X    register string *pbuf;
  1245. X    register node n;
  1246. X    register int mask;
  1247. X{
  1248. X    register string *rp;
  1249. X    register int i;
  1250. X    register int nch;
  1251. X
  1252. X    rp = noderepr(n);
  1253. X    strsmash(pbuf, rp[0], mask);
  1254. X    nch = nchildren(n);
  1255. X    for (i = 1; i <= nch; ++i) {
  1256. X        if (!chismash(pbuf, n, i, mask))
  1257. X            break;
  1258. X        strsmash(pbuf, rp[i], mask);
  1259. X    }
  1260. X}
  1261. X
  1262. XHidden Procedure
  1263. Xstrsmash(pbuf, str, mask)
  1264. X    register string *pbuf;
  1265. X    register string str;
  1266. X    register int mask;
  1267. X{
  1268. X    if (!str)
  1269. X        return;
  1270. X    for (; *str; ++str) {
  1271. X        if (isprint(*str) || *str == ' ')
  1272. X            **pbuf = *str|mask, ++*pbuf;
  1273. X    }
  1274. X}
  1275. X
  1276. XHidden Procedure
  1277. Xsubsmash(pbuf, str, len, mask)
  1278. X    register string *pbuf;
  1279. X    register string str;
  1280. X    register int len;
  1281. X    register int mask;
  1282. X{
  1283. X    if (!str)
  1284. X        return;
  1285. X    for (; len > 0 && *str; --len, ++str) {
  1286. X        if (isprint(*str) || *str == ' ')
  1287. X            **pbuf = *str|mask, ++*pbuf;
  1288. X    }
  1289. X}
  1290. X
  1291. X
  1292. X/*
  1293. X * Smash a node's child.
  1294. X * Return No if it contained a newline (to stop the parent).
  1295. X */
  1296. X
  1297. XHidden bool
  1298. Xchismash(pbuf, n, i, mask)
  1299. X    register string *pbuf;
  1300. X    register node n;
  1301. X    register int i;
  1302. X{
  1303. X    register node nn = child(n, i);
  1304. X    register int w;
  1305. X
  1306. X    if (Is_etext(nn)) {
  1307. X        strsmash(pbuf, e_strval((value)nn), mask);
  1308. X        return Yes;
  1309. X    }
  1310. X    w = nodewidth(nn);
  1311. X    if (w < 0 && Fw_negative(noderepr(nn)[0]))
  1312. X        return No;
  1313. X    if (nn == thefocus)
  1314. X        focsmash(pbuf, nn);
  1315. X    else
  1316. X        smash(pbuf, nn, mask);
  1317. X    return w >= 0;
  1318. X}
  1319. END_OF_FILE
  1320.   if test 7976 -ne `wc -c <'abc/bed/e1outp.c'`; then
  1321.     echo shar: \"'abc/bed/e1outp.c'\" unpacked with wrong size!
  1322.   fi
  1323.   # end of 'abc/bed/e1outp.c'
  1324. fi
  1325. if test -f 'abc/bint1/i1nui.c' -a "${1}" != "-c" ; then 
  1326.   echo shar: Will not clobber existing file \"'abc/bint1/i1nui.c'\"
  1327. else
  1328.   echo shar: Extracting \"'abc/bint1/i1nui.c'\" \(8077 characters\)
  1329.   sed "s/^X//" >'abc/bint1/i1nui.c' <<'END_OF_FILE'
  1330. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  1331. X
  1332. X/* Multi-precision integer arithmetic */
  1333. X
  1334. X#include "b.h"
  1335. X#include "feat.h"     /* for EXT_RANGE */
  1336. X#include "bobj.h"
  1337. X#include "i1num.h"
  1338. X
  1339. X/*
  1340. X * Number representation:
  1341. X * ======================
  1342. X *
  1343. X * (Think of BASE = 10 for ordinary decimal notation.)
  1344. X * A number is a sequence of N "digits" b1, b2, ..., bN
  1345. X * where each bi is in {0..BASE-1}, except for negative numbers,
  1346. X * where bN = -1.
  1347. X * The number represented by b1, ..., bN is
  1348. X *      b1*BASE**(N-1) + b2*BASE**(N-2) + ... + bN .
  1349. X * The base BASE is chosen so that multiplication of two positive
  1350. X * integers up to BASE-1 can be multiplied exactly using double
  1351. X * precision floating point arithmetic.
  1352. X * Also it must be possible to add two long integers between
  1353. X * -BASE and +BASE (exclusive), giving a result between -2BASE and
  1354. X * +2BASE.
  1355. X * BASE must be even (so we can easily decide whether the whole
  1356. X * number is even), and positive (to avoid all kinds of other trouble).
  1357. X * Presently, it is restricted to a power of 10 by the I/O-conversion
  1358. X * routines (file "i1nuc.c").
  1359. X *
  1360. X * Canonical representation:
  1361. X * bN is never zero (for the number zero itself, N is zero).
  1362. X * If bN is -1, b[N-1] is never BASE-1 .
  1363. X * All operands are assumed to be in canonical representation.
  1364. X * Routine "int_canon" brings a number in canonical representation.
  1365. X *
  1366. X * Mapping to C objects:
  1367. X * A "digit" is an integer of type "digit", probably an "int".
  1368. X * A number is represented as a "B-integer", i.e. something
  1369. X * of type "integer" (which is actually a pointer to some struct).
  1370. X * The number of digits N is extracted through the macro Length(v).
  1371. X * The i-th digit is extracted through the macro Digit(v,N-i).
  1372. X * (So in C, we count in a backwards direction from 0 ... n-1 !)
  1373. X * A number is created through a call to grab_num(N), which sets
  1374. X * N zero digits (thus not in canonical form!).
  1375. X */
  1376. X
  1377. X
  1378. X/*
  1379. X * Bring an integer into canonical form.
  1380. X * Make a SmallInt if at all possible.
  1381. X */
  1382. X
  1383. XVisible integer int_canon(v) integer v; {
  1384. X    register int i;
  1385. X
  1386. X    if (IsSmallInt(v)) return v;
  1387. X
  1388. X    for (i = Length(v) - 1; i >= 0 && Digit(v,i) == 0; --i)
  1389. X        ;
  1390. X
  1391. X    if (i < 0) {
  1392. X        Release(v);
  1393. X        return int_0;
  1394. X    }
  1395. X
  1396. X    if (i == 0) {
  1397. X        digit dig = Digit(v,0);
  1398. X        Release(v);
  1399. X        return (integer) MkSmallInt(dig);
  1400. X    }
  1401. X
  1402. X    /* i > 0 */
  1403. X    if (Digit(v,i) == -1) {
  1404. X        while (i > 0 && Digit(v, i-1) == BASE-1) --i;
  1405. X        if (i == 0) {
  1406. X            Release(v);
  1407. X            return int_min1;
  1408. X        }
  1409. X        if (i == 1) {
  1410. X            digit dig = Digit(v,0) - BASE;
  1411. X            Release(v);
  1412. X            return (integer) MkSmallInt(dig);
  1413. X        }
  1414. X        Digit(v,i) = -1;
  1415. X    }
  1416. X    else if (Digit(v, i) < -1) {
  1417. X        /* e.g. after -100 * 10**7, with BASE == 10**4 */
  1418. X        ++i;
  1419. X        if (i+1 != Length(v))
  1420. X            v = (integer) regrab_num((value) v, i+1);
  1421. X        Digit(v, i) = -1;
  1422. X        Digit(v, i-1) += BASE;
  1423. X        /* note: i>=2 && Digit(v, i-1) != BASE-1 */
  1424. X    }
  1425. X
  1426. X    if (i+1 < Length(v)) return (integer) regrab_num((value) v, i+1);
  1427. X
  1428. X    return v;
  1429. X}
  1430. X
  1431. X
  1432. X/* General add/subtract subroutine */
  1433. X
  1434. XHidden twodigit fmodulo(x) twodigit x; {
  1435. X    /* RETURN x - (BASE * floor(x/BASE)) */
  1436. X    twodigit d= x/BASE;
  1437. X    /* next one remedies if negative x/BASE rounds towards 0 */
  1438. X    if (x < 0 && d*BASE > x) --d;
  1439. X    return x - BASE*d;
  1440. X}
  1441. X
  1442. XHidden Procedure dig_gadd(to, nto, from, nfrom, ffactor)
  1443. X    digit *to, *from; intlet nto, nfrom; digit ffactor; {
  1444. X    twodigit carry= 0;
  1445. X    twodigit factor= ffactor;
  1446. X    digit save;
  1447. X
  1448. X    nto -= nfrom;
  1449. X    if (nto < 0)
  1450. X        syserr(MESS(1000, "dig_gadd: nto < nfrom"));
  1451. X    for (; nfrom > 0; ++to, ++from, --nfrom) {
  1452. X        carry += *to + *from * factor;
  1453. X        *to= save= fmodulo(carry);
  1454. X        carry= (carry-save) / BASE;
  1455. X    }
  1456. X    for (; nto > 0; ++to, --nto) {
  1457. X        if (carry == 0)
  1458. X            return;
  1459. X        carry += *to;
  1460. X        *to= save= fmodulo(carry);
  1461. X        carry= (carry-save) / BASE;
  1462. X    }
  1463. X    if (carry != 0)
  1464. X        to[-1] += carry*BASE;
  1465. X        /* Mostly -1, but it can be <-1,
  1466. X         * e.g. after -100*10**7 with BASE == 10**4
  1467. X         */
  1468. X}
  1469. X
  1470. X
  1471. X/* Sum or difference of two integers */
  1472. X/* Should have its own version of dig-gadd without double precision */
  1473. X
  1474. XVisible integer int_gadd(v, w, factor) integer v, w; intlet factor; {
  1475. X    struct integer vv, ww;
  1476. X    integer s;
  1477. X    int len, lenv, i;
  1478. X
  1479. X    FreezeSmallInt(v, vv);
  1480. X    FreezeSmallInt(w, ww);
  1481. X    lenv= len= Length(v);
  1482. X    if (Length(w) > len)
  1483. X        len= Length(w);
  1484. X    ++len;
  1485. X    s= (integer) grab_num(len);
  1486. X    for (i= 0; i < lenv; ++i)
  1487. X        Digit(s, i)= Digit(v, i);
  1488. X    for (; i < len; ++i)
  1489. X        Digit(s, i)= 0;
  1490. X    dig_gadd(&Digit(s, 0), len, &Digit(w, 0), Length(w), (digit)factor);
  1491. X    return int_canon(s);
  1492. X}
  1493. X
  1494. X/* Sum of two integers */
  1495. X
  1496. XVisible integer int_sum(v, w) integer v, w; {
  1497. X    if (IsSmallInt(v) && IsSmallInt(w))
  1498. X        return mk_int((double)SmallIntVal(v) + (double)SmallIntVal(w));
  1499. X    return int_gadd(v, w, 1);
  1500. X}
  1501. X
  1502. X/* Difference of two integers */
  1503. X
  1504. XVisible integer int_diff(v, w) integer v, w; {
  1505. X    if (IsSmallInt(v) && IsSmallInt(w))
  1506. X        return mk_int((double)SmallIntVal(v) - (double)SmallIntVal(w));
  1507. X    return int_gadd(v, w, -1);
  1508. X}
  1509. X
  1510. X/* Product of two integers */
  1511. X
  1512. XVisible integer int_prod(v, w) integer v, w; {
  1513. X    int i;
  1514. X    integer a;
  1515. X    struct integer vv, ww;
  1516. X
  1517. X    if (v == int_0 || w == int_0) return int_0;
  1518. X    if (v == int_1) return (integer) Copy(w);
  1519. X    if (w == int_1) return (integer) Copy(v);
  1520. X
  1521. X    if (IsSmallInt(v) && IsSmallInt(w))
  1522. X        return mk_int((double)SmallIntVal(v) * (double)SmallIntVal(w));
  1523. X    FreezeSmallInt(v, vv);
  1524. X    FreezeSmallInt(w, ww);
  1525. X
  1526. X    a = (integer) grab_num(Length(v) + Length(w));
  1527. X
  1528. X    for (i= Length(a)-1; i >= 0; --i)
  1529. X        Digit(a, i)= 0;
  1530. X    for (i = 0; i < Length(v) && !Interrupted(); ++i)
  1531. X        dig_gadd(&Digit(a, i), Length(w)+1, &Digit(w, 0), Length(w), 
  1532. X            Digit(v, i));
  1533. X    return int_canon(a);
  1534. X}
  1535. X
  1536. XVisible integer int_neg(u) integer u; {
  1537. X    if (IsSmallInt(u))
  1538. X        return mk_int((double) (-SmallIntVal(u)));
  1539. X    return int_gadd(int_0, u, -1);
  1540. X}
  1541. X
  1542. X/* Compare two integers */
  1543. X
  1544. XVisible relation int_comp(v, w) integer v, w; {
  1545. X    int sv, sw;
  1546. X    register int i;
  1547. X    struct integer vv, ww;
  1548. X
  1549. X    /* 1. Compare pointers and equal SmallInts */
  1550. X    if (v == w) return 0;
  1551. X
  1552. X    /* 1a. Handle SmallInts */
  1553. X    if (IsSmallInt(v) && IsSmallInt(w))
  1554. X        return SmallIntVal(v) - SmallIntVal(w);
  1555. X    FreezeSmallInt(v, vv);
  1556. X    FreezeSmallInt(w, ww);
  1557. X
  1558. X    /* 2. Extract signs */
  1559. X    sv = Length(v)==0 ? 0 : Digit(v,Length(v)-1)<0 ? -1 : 1;
  1560. X    sw = Length(w)==0 ? 0 : Digit(w,Length(w)-1)<0 ? -1 : 1;
  1561. X
  1562. X    /* 3. Compare signs */
  1563. X    if (sv != sw) return (sv>sw) - (sv<sw);
  1564. X
  1565. X    /* 4. Compare sizes */
  1566. X    if (Length(v) != Length(w))
  1567. X        return sv * ( (Length(v)>Length(w)) - (Length(v)<Length(w)) );
  1568. X
  1569. X    /* 5. Compare individual digits */
  1570. X    for (i = Length(v)-1; i >= 0 && Digit(v,i) == Digit(w,i); --i)
  1571. X        ;
  1572. X
  1573. X    /* 6. All digits equal? */
  1574. X    if (i < 0) return 0;  /* Yes */
  1575. X
  1576. X    /* 7. Compare leftmost different digits */
  1577. X    if (Digit(v,i) < Digit(w,i)) return -1;
  1578. X
  1579. X    return 1;
  1580. X}
  1581. X
  1582. X
  1583. X/* Construct an integer out of a floating point number */
  1584. X
  1585. X#define GRAN 8    /* Granularity used when requesting more storage */
  1586. X        /* MOVE TO MEM! */
  1587. XVisible integer mk_int(x) double x; {
  1588. X    register integer a;
  1589. X    integer b;
  1590. X    register int i, j;
  1591. X    int negate;
  1592. X
  1593. X    if (MinSmallInt <= x && x <= MaxSmallInt)
  1594. X        return (integer) MkSmallInt((int)x);
  1595. X
  1596. X    a = (integer) grab_num(1);
  1597. X    negate = x < 0 ? 1 : 0;
  1598. X    if (negate) x = -x;
  1599. X
  1600. X    for (i = 0; x != 0; ++i) {
  1601. X        double z = floor(x/BASE);
  1602. X        double y = z*BASE;
  1603. X        digit save = Modulo((int)(x-y), BASE);
  1604. X        if (i >= Length(a)) {
  1605. X            a = (integer) regrab_num((value) a, Length(a)+GRAN);
  1606. X            for (j = Length(a)-1; j > i; --j)
  1607. X                Digit(a,j) = 0;    /* clear higher digits */
  1608. X        }
  1609. X        Digit(a,i) = save;
  1610. X        x = floor((x-save)/BASE);
  1611. X    }
  1612. X
  1613. X    if (negate) {
  1614. X        b = int_neg(a);
  1615. X        Release(a);
  1616. X        return b;
  1617. X    }
  1618. X
  1619. X    return int_canon(a);
  1620. X}
  1621. X
  1622. X/* Construct an integer out of a C int.  Like mk_int, but optimized. */
  1623. X
  1624. XVisible value mk_integer(x) int x; {
  1625. X    if (MinSmallInt <= x && x <= MaxSmallInt) return MkSmallInt(x);
  1626. X    return (value) mk_int((double)x);
  1627. X}
  1628. X
  1629. X
  1630. X/* Efficiently compute 10**n as a B integer, where n is a C int >= 0 */
  1631. X
  1632. XVisible integer int_tento(n) int n; {
  1633. X    integer i;
  1634. X    digit msd = 1;
  1635. X    if (n < 0) syserr(MESS(1001, "int_tento(-n)"));
  1636. X    if (n < tenlogBASE) {
  1637. X        while (n != 0) msd *= 10, --n;
  1638. X        return (integer) MkSmallInt(msd);
  1639. X    }
  1640. X    i = (integer) grab_num(1 + (int)(n/tenlogBASE));
  1641. X    if (i) {
  1642. X        n %= tenlogBASE;
  1643. X        while (n != 0) msd *= 10, --n;
  1644. X        Digit(i, Length(i)-1) = msd;
  1645. X    }
  1646. X    /* else caveat invocator */
  1647. X    return i;
  1648. X}
  1649. END_OF_FILE
  1650.   if test 8077 -ne `wc -c <'abc/bint1/i1nui.c'`; then
  1651.     echo shar: \"'abc/bint1/i1nui.c'\" unpacked with wrong size!
  1652.   fi
  1653.   # end of 'abc/bint1/i1nui.c'
  1654. fi
  1655. if test -f 'abc/bint3/i3gfx.c' -a "${1}" != "-c" ; then 
  1656.   echo shar: Will not clobber existing file \"'abc/bint3/i3gfx.c'\"
  1657. else
  1658.   echo shar: Extracting \"'abc/bint3/i3gfx.c'\" \(8005 characters\)
  1659.   sed "s/^X//" >'abc/bint3/i3gfx.c' <<'END_OF_FILE'
  1660. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  1661. X
  1662. X/*
  1663. X * Graphics extension to B.
  1664. X *
  1665. X * Three commands have been added:
  1666. X *
  1667. X * SPACE'FROM a, b TO c, d
  1668. X *    Enters graphics mode; (a, b) is the lower left corner, (c, d) the
  1669. X *    upper right corner of screen.  Clears the screen in any case.
  1670. X *    A few lines at the bottom of the screen are still used for
  1671. X *    normal scrolling text.    If a=c or b=d, the corresponding
  1672. X *    scale is taken from the device precision with the origin
  1673. X *    in the middle of the screen.
  1674. X *
  1675. X * LINE'FROM a, b TO c, d
  1676. X *    Draws a line (with clipping) from (a, b) to (c, d).
  1677. X *    If not already in graphics mode, enter it (with unchanged
  1678. X *    coordinate space).
  1679. X *
  1680. X * CLEAR'SCREEN
  1681. X *    If in graphics mode, turns it off.  Clears the screen in any case.
  1682. X *
  1683. X *
  1684. X * Changes have also been made to the editor, parser and interpreter;
  1685. X * these are only compiled if '#ifdef GFX' is true.
  1686. X */
  1687. X
  1688. X#include "b.h"
  1689. X#include "bobj.h"
  1690. X#include "bgfx.h"
  1691. X
  1692. X#ifdef GFX
  1693. X
  1694. X/* Interface for interpreter ----------------------------------------------- */
  1695. X
  1696. Xbool enter_gfx();
  1697. Xdo_space();
  1698. Xdo_line();
  1699. X
  1700. X
  1701. X/*
  1702. X * Enter graphics mode.  Clear the screen.  Set spacing to given values.
  1703. X */
  1704. X
  1705. XVisible Procedure space_to(v, w) value v, w; {
  1706. X    do_gfx(v, w, /*&*/do_space);
  1707. X}
  1708. X
  1709. X
  1710. X/*
  1711. X * Draw a line between given points.
  1712. X * If not already in graphics mode, enter it first.
  1713. X * (Default spacing is the same as used last time, or (0, 0) TO (100, 100)
  1714. X * if no SPACE command was ever issued.)
  1715. X */
  1716. X
  1717. XVisible Procedure line_to(v, w) value v, w; {
  1718. X    do_gfx(v, w, /*&*/do_line);
  1719. X}
  1720. X
  1721. X
  1722. X/*
  1723. X * Exit graphics mode.
  1724. X * Clear the screen.
  1725. X */
  1726. X
  1727. XVisible Procedure clear_screen() {
  1728. X    exit_gfx();
  1729. X}
  1730. X
  1731. X
  1732. X/* Device-independent code ------------------------------------------------- */
  1733. X
  1734. X/*
  1735. X * Graphics mode.
  1736. X */
  1737. X
  1738. XVisible int gfx_mode= TEXT_MODE;
  1739. X
  1740. X
  1741. X/*
  1742. X * Representation of a vector.
  1743. X */
  1744. X
  1745. Xtypedef struct vector {
  1746. X    double x;
  1747. X    double y;
  1748. X} vector;
  1749. X
  1750. X
  1751. X/*
  1752. X * Variables describing the user coordinate space.
  1753. X * (Can be changed by calls to space_to).
  1754. X */
  1755. X
  1756. Xstatic vector origin= {0.0, 0.0};
  1757. Xstatic vector corner= {0.0, 0.0};
  1758. X
  1759. X
  1760. X/*
  1761. X * Scale factor for coordinate transformation.
  1762. X * (Computed from above variables plus device information by space_to.)
  1763. X */
  1764. X
  1765. Xstatic vector scale;
  1766. X
  1767. X
  1768. X/*
  1769. X * Macros to do the transformation from user to device coordinates.
  1770. X */
  1771. X
  1772. X#define XSCALE(a) (((a) - origin.x) * scale.x)
  1773. X#define YSCALE(a) (((a) - origin.y) * scale.y)
  1774. X
  1775. X
  1776. X/*
  1777. X * Check to see if a B value is a valid vector (= pair of numbers).
  1778. X * If so, extract the value into the vector whose address is passed.
  1779. X */
  1780. X
  1781. XHidden bool get_point(v, pv) value v; vector *pv; {
  1782. X    value x, y;
  1783. X
  1784. X    if (!Is_compound(v) || Nfields(v) != 2)
  1785. X        return No;
  1786. X    x= *Field(v, 0);
  1787. X    y= *Field(v, 1);
  1788. X    if (!Is_number(x) || !Is_number(y))
  1789. X        return No;
  1790. X    pv->x= numval(x);
  1791. X    pv->y= numval(y);
  1792. X    return Yes;
  1793. X}
  1794. X
  1795. X
  1796. X/*
  1797. X * Generic code for graphics routines that have two vector parameters.
  1798. X * Check that the arguments are indeed vectors and call the processing code.
  1799. X */
  1800. X
  1801. XHidden Procedure do_gfx(v, w, proc) value v; value w; int (*proc)(); {
  1802. X    vector v1, v2;
  1803. X
  1804. X    if (!get_point(v, &v1) || !get_point(w, &v2)) {
  1805. X        interr(MESS(8000, "argument to graphics command not a vector"));
  1806. X        return;
  1807. X    }
  1808. X    (*proc)(&v1, &v2);
  1809. X}
  1810. X
  1811. X
  1812. X/*
  1813. X * Routine to enter graphics mode and set the spacing as desired.
  1814. X */
  1815. X
  1816. XHidden Procedure do_space(pv1, pv2) vector *pv1, *pv2; {
  1817. X    double tmp;
  1818. X
  1819. X    if (gfx_mode != GFX_MODE) {
  1820. X        if (!enter_gfx()) {
  1821. X            interr(MESS(8001, "no graphics hardware available"));
  1822. X            return;
  1823. X        }
  1824. X    }
  1825. X    clipinit(dev_origin.x, dev_origin.y, dev_corner.x, dev_corner.y);
  1826. X    origin.x= pv1->x;
  1827. X    origin.y= pv1->y;
  1828. X    corner.x= pv2->x;
  1829. X    corner.y= pv2->y;
  1830. X    if (origin.x > corner.x) {
  1831. X        tmp= origin.x;
  1832. X        origin.x= corner.x;
  1833. X        corner.x= tmp;
  1834. X    }
  1835. X    else if (origin.x == corner.x) {
  1836. X        origin.x= dev_origin.x - (dev_corner.x - dev_origin.x) / 2;
  1837. X        corner.x= origin.x + (dev_corner.x - dev_origin.x);
  1838. X    }
  1839. X    if (origin.y > corner.y) {
  1840. X        tmp= origin.y;
  1841. X        origin.y= corner.y;
  1842. X        corner.y= tmp;
  1843. X    }
  1844. X    else if (origin.y == corner.y) {
  1845. X        origin.y= dev_origin.y - (dev_corner.y - dev_origin.y) / 2;
  1846. X        corner.y= origin.y + (dev_corner.y - dev_origin.y);
  1847. X    }
  1848. X    scale.x= (double) (dev_corner.x - dev_origin.x) /
  1849. X            (corner.x - origin.x);
  1850. X    scale.y= (double) (dev_corner.y - dev_origin.y) /
  1851. X            (corner.y - origin.y);
  1852. X}
  1853. X
  1854. X
  1855. X/*
  1856. X * Routine to draw a line.
  1857. X */
  1858. X
  1859. XHidden Procedure do_line(pv1, pv2) vector *pv1, *pv2; {
  1860. X    int x1, y1, x2, y2;
  1861. X
  1862. X    if (gfx_mode != GFX_MODE) {
  1863. X        do_space(&origin, &corner);
  1864. X        if (gfx_mode != GFX_MODE)
  1865. X            return;
  1866. X    }
  1867. X    x1= XSCALE(pv1->x);
  1868. X    x2= XSCALE(pv2->x);
  1869. X    y1= YSCALE(pv1->y);
  1870. X    y2= YSCALE(pv2->y);
  1871. X    if (inview2d(x1, y1, x2, y2) || clip2d(&x1, &y1, &x2, &y2))
  1872. X        draw_line(x1, y1, x2, y2);
  1873. X}
  1874. X
  1875. X/* Clipping ---------------------------------------------------------------- */
  1876. X
  1877. X/* @(#)clip.c    1.2 - 85/10/07 */
  1878. X/*
  1879. X * Fast, 2d, integer clipping plot(3) operations.
  1880. X * Clipping algorithm taken from "A New Concept and Method for Line Clipping,"
  1881. X * Barsky & Liang, ACM Tran. on Graphics Vol 3, #1, Jan 84.
  1882. X * In contrast to the algoritm presented in TOG, this one works
  1883. X * on integers only.  The idea is to only do that which is useful
  1884. X * for my plot(3) based graphics programs.
  1885. X */
  1886. X
  1887. X/* AUTHOR:
  1888. XRob Adams <ima!rob>
  1889. XInteractive Systems, 7th floor, 441 Stuart st, Boston, MA 02116; 617-247-1155
  1890. X*/
  1891. X
  1892. X/*
  1893. X * Interface:
  1894. X *
  1895. X *  clipinit(int xleft, int ybottom, int xright, int ytop)
  1896. X *   Send this guy the same things you would send to space().
  1897. X *   Don't worry if xleft > xright.
  1898. X *
  1899. X *  clip2d(int *x0p, int *y0p, int *x1p, int *y1p)
  1900. X *   By the time this returns, the points referenced will have
  1901. X *   been clipped.  Call this right before line(), with pointers
  1902. X *   to the same arguments.  Returns TRUE is the resulting line
  1903. X *   can be displayed.
  1904. X *
  1905. X *  inview2d(int x0,int y0,int x1,int y1)
  1906. X *   Does a fast check for simple acceptance.  Returns TRUE if
  1907. X *   the segment is intirely in view.  If your program runs too
  1908. X *   slowly, consider making this a macro.
  1909. X *
  1910. X *  Usage of clip2d and inview2d would be something like --
  1911. X *    (inview2d(x0,y0, x1,y1) || clip2d(&x0,&y0, &x1,&y1))
  1912. X *        && line(x0,y0,x1,y1);
  1913. X *  If inview2d says the segment is safe or clip2d says the clipped
  1914. X *  segment is safe, then go ahead and print the line.
  1915. X */
  1916. Xstatic int Xleft, Xright, Ytop, Ybot;
  1917. X
  1918. X#define TRUE    1
  1919. X#define FALSE    0
  1920. X#define bool    int
  1921. X
  1922. X/*------------------------------- clipinit ----------------------------------*/
  1923. Xclipinit(x0,y0,x1,y1) {
  1924. X    if ( x0 > x1 ) {
  1925. X        Xleft  = x1;
  1926. X        Xright = x0;
  1927. X    } else {
  1928. X        Xleft  = x0;
  1929. X        Xright = x1;
  1930. X    }
  1931. X    if ( y0 > y1 ) {
  1932. X        Ytop = y0;
  1933. X        Ybot = y1;
  1934. X    } else {
  1935. X        Ytop = y1;
  1936. X        Ybot = y0;
  1937. X    }
  1938. X}
  1939. X
  1940. X/*------------------------------- inview2d ----------------------------------*/
  1941. Xbool inview2d(x0,y0, x1,y1) register x0,y0, x1,y1; {
  1942. X    return    x0 >= Xleft && x0 <= Xright && x1 >= Xleft && x1 <= Xright &&
  1943. X        y0 >= Ybot  && y0 <= Ytop   && y1 >= Ybot  && y1 <= Ytop;
  1944. X}
  1945. X
  1946. X/*-------------------------------- clip2d -----------------------------------*/
  1947. Xbool clip2d(x0p, y0p, x1p, y1p) int *x0p, *y0p, *x1p, *y1p; {
  1948. X    register int    x0 = *x0p,
  1949. X            y0 = *y0p,
  1950. X            x1 = *x1p,
  1951. X            y1 = *y1p;
  1952. X
  1953. X    register int    dx, dy;
  1954. X         double t0, t1;
  1955. X
  1956. X    t0 = 0.0, t1 = 1.0;             /* init parametic equations */
  1957. X    dx = x1 - x0;
  1958. X    if ( clipt( -dx, x0 - Xleft, &t0, &t1) &&
  1959. X         clipt( dx, Xright - x0, &t0, &t1)) {
  1960. X        dy = y1 - y0;
  1961. X        if ( clipt( -dy, y0 - Ybot, &t0, &t1) &&
  1962. X         clipt( dy, Ytop - y0, &t0, &t1)) {
  1963. X        if ( t1 < 1 ) {
  1964. X            *x1p = x0 + t1 * dx;
  1965. X            *y1p = y0 + t1 * dy;
  1966. X        }
  1967. X        if ( t0 > 0.0 ) {
  1968. X            *x0p = x0 + t0 * dx;
  1969. X            *y0p = y0 + t0 * dy;
  1970. X        }
  1971. X        return TRUE;
  1972. X        }
  1973. X    }
  1974. X    return FALSE;
  1975. X}
  1976. X
  1977. X/*-------------------------------- clipt ------------------------------------*/
  1978. Xstatic bool clipt(p, q, t0p, t1p) register int p, q;
  1979. X        register double *t0p, *t1p; {
  1980. X    register double r;
  1981. X
  1982. X    if ( p < 0 ) {
  1983. X        r = (double)q / p;
  1984. X        if ( r > *t1p )
  1985. X        return FALSE;
  1986. X        if ( r > *t0p )
  1987. X        *t0p = r;
  1988. X    } else if (p > 0) {
  1989. X        r = (double)q / p;
  1990. X        if ( r < *t0p )
  1991. X        return FALSE;
  1992. X        if ( r < *t1p )
  1993. X        *t1p = r;
  1994. X    } else if (q < 0)
  1995. X        return FALSE;
  1996. X    return TRUE;
  1997. X}
  1998. X
  1999. X#endif /* GFX */
  2000. END_OF_FILE
  2001.   if test 8005 -ne `wc -c <'abc/bint3/i3gfx.c'`; then
  2002.     echo shar: \"'abc/bint3/i3gfx.c'\" unpacked with wrong size!
  2003.   fi
  2004.   # end of 'abc/bint3/i3gfx.c'
  2005. fi
  2006. if test -f 'abc/lin/i1tlt.h' -a "${1}" != "-c" ; then 
  2007.   echo shar: Will not clobber existing file \"'abc/lin/i1tlt.h'\"
  2008. else
  2009.   echo shar: Extracting \"'abc/lin/i1tlt.h'\" \(1494 characters\)
  2010.   sed "s/^X//" >'abc/lin/i1tlt.h' <<'END_OF_FILE'
  2011. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  2012. X
  2013. X/************************************************************************/
  2014. X/* Private definitions for small texts, lists and tables module         */
  2015. X/* A text is modelled as a sequence of len characters.                  */
  2016. X/*                                                                      */
  2017. X/* A list is modelled as a sequence of len values,                      */
  2018. X/*         each of which corresponds to a list entry.                   */
  2019. X/*  or, for a numeric range display with more than Minrange entries,    */
  2020. X/*         it is modelled as a sequence of two values, corresponding    */
  2021. X/*         to the lower and upper bounds, respectively.                 */
  2022. X/*                                                                      */
  2023. X/* A table is modelled as a sequence of len values,                     */
  2024. X/*         each of which corresponds to a table entry;                  */
  2025. X/*     table entries are modelled as a compound with two fields.        */
  2026. X/************************************************************************/
  2027. X
  2028. X#define Cts(v) (*Ats(v))
  2029. X#define Dts(v) (*(Ats(v)+1))
  2030. X
  2031. X#define List_elem(l, i) (*(Ats(l)+i)) /*counts from 0; takes no copy*/
  2032. X#define Key(t, i) (Ats(*(Ats(t)+i))) /*Ditto*/
  2033. X#define Assoc(t, i) (Ats(*(Ats(t)+i))+1) /*Ditto*/
  2034. X
  2035. X#define Lwb(l)    (*Ats(l))
  2036. X#define Upb(l)    (*(Ats(l)+1))
  2037. X
  2038. Xvalue rangesize();
  2039. Xrelation range_comp();
  2040. Xbool found();
  2041. Xvalue list_elem();
  2042. Xvalue key_elem();
  2043. END_OF_FILE
  2044.   if test 1494 -ne `wc -c <'abc/lin/i1tlt.h'`; then
  2045.     echo shar: \"'abc/lin/i1tlt.h'\" unpacked with wrong size!
  2046.   fi
  2047.   # end of 'abc/lin/i1tlt.h'
  2048. fi
  2049. if test -f 'abc/stc/i2tce.c' -a "${1}" != "-c" ; then 
  2050.   echo shar: Will not clobber existing file \"'abc/stc/i2tce.c'\"
  2051. else
  2052.   echo shar: Extracting \"'abc/stc/i2tce.c'\" \(7902 characters\)
  2053.   sed "s/^X//" >'abc/stc/i2tce.c' <<'END_OF_FILE'
  2054. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  2055. X
  2056. X/* process type unification errors */
  2057. X
  2058. X#include "b.h"
  2059. X#include "bobj.h"
  2060. X#include "i2stc.h"
  2061. X
  2062. X#define I_FOUND_TYPE    GMESS(2600, "I found type ")
  2063. X#define EG        GMESS(2601, "EG ")
  2064. X#define WHERE_EXPECTED    GMESS(2602, " where I expected ")
  2065. X
  2066. X#define I_THOUGHT    GMESS(2603, "I thought ")
  2067. X#define WAS_OF_TYPE    GMESS(2604, " was of type ")
  2068. X
  2069. X#define LT_OF        GMESS(2605, "list or table of ")
  2070. X#define LT        GMESS(2606, "list or table")
  2071. X#define T_OR_LT_OF_T    GMESS(2607, """, or list or table of """)
  2072. X#define TLT        GMESS(2608, "text or list or table")
  2073. X
  2074. X#define INCOMPATIBLE    GMESS(2609, "incompatible type for ")
  2075. X#define INCOMPATIBLES    GMESS(2610, "incompatible types for ")
  2076. X#define _AND_        GMESS(2611, " and ")
  2077. X
  2078. X/* 
  2079. X * The variables from the users line are inserted in var_list.
  2080. X * This is used to produce the right variable names
  2081. X * in the error message.
  2082. X * Call start_vars() when a new error context is established
  2083. X * with the setting of curline.
  2084. X */
  2085. X
  2086. XHidden value var_list;
  2087. X
  2088. XVisible Procedure start_vars() {
  2089. X    var_list = mk_elt();
  2090. X}
  2091. X
  2092. XVisible Procedure add_var(tvar) polytype tvar; {
  2093. X    insert(tvar, &var_list);
  2094. X}
  2095. X
  2096. XHidden bool in_vars(t) polytype t; {
  2097. X    return in(t, var_list);
  2098. X}
  2099. X
  2100. XVisible Procedure end_vars() {
  2101. X    release(var_list);
  2102. X}
  2103. X
  2104. X/* t_repr(u) is used to print polytypes when an error
  2105. X * has occurred.
  2106. X * Because the errors are printed AFTER unification, the variable 
  2107. X * polytypes in question have changed to the error-type.
  2108. X * To print the real types in error, the table has to be 
  2109. X * saved in reprtable.
  2110. X * The routines are called in unify().
  2111. X */
  2112. X
  2113. XHidden value reprtable;
  2114. Xextern value ptype_of;         /* defined in i2tp.c */
  2115. X
  2116. XVisible Procedure setreprtable() {
  2117. X    reprtable = copy(ptype_of);
  2118. X}
  2119. X
  2120. XVisible Procedure delreprtable() {
  2121. X    release(reprtable);
  2122. X}
  2123. X
  2124. X/* variables whose type is in error are gathered in errvarlist */
  2125. X
  2126. XHidden value errvarlist;
  2127. X
  2128. XVisible Procedure starterrvars() {
  2129. X    errvarlist= mk_elt();
  2130. X}
  2131. X
  2132. XVisible Procedure adderrvar(t) polytype t; {
  2133. X    if (in_vars(t) && !in(t, errvarlist))
  2134. X        insert(t, &errvarlist);
  2135. X}
  2136. X
  2137. XVisible Procedure enderrvars() {
  2138. X    release(errvarlist);
  2139. X}
  2140. X
  2141. X/* miscellaneous procs */
  2142. X
  2143. XVisible value conc(v, w) value v, w; {
  2144. X    value c;
  2145. X    c = concat(v, w);
  2146. X    release(v); release(w);
  2147. X    return c;
  2148. X}
  2149. X
  2150. XHidden bool newvar(u) polytype u; {
  2151. X    value u1;
  2152. X    char ch;
  2153. X    u1 = curtail(ident(u), one);
  2154. X    ch = charval(u1);
  2155. X    release(u1);
  2156. X    return (bool) ('0' <= ch && ch <= '9');
  2157. X}
  2158. X
  2159. X#define Known(tu) (!t_is_var(kind(tu)) && !t_is_error(kind(tu)))
  2160. X
  2161. XHidden polytype oldbottomtype(u) polytype u; {
  2162. X    polytype tu= u;
  2163. X    while (t_is_var(kind(tu)) && in_keys(ident(tu), reprtable))
  2164. X        tu= *adrassoc(reprtable, ident(tu));
  2165. X    return tu; /* not a copy, just a pointer! */
  2166. X}
  2167. X
  2168. XHidden value t_repr(u) polytype u; {
  2169. X    typekind u_kind;
  2170. X    polytype tau;
  2171. X    value c;
  2172. X    
  2173. X    u_kind = kind(u);
  2174. X    if (t_is_number(u_kind)) {
  2175. X        return mk_text("0");
  2176. X    }
  2177. X    else if (t_is_text(u_kind)) {
  2178. X        return mk_text("\"\"");
  2179. X    }
  2180. X    else if (t_is_tn(u_kind)) {
  2181. X        return mk_text("\"\" or 0");
  2182. X    }
  2183. X    else if (t_is_compound(u_kind)) {
  2184. X        intlet k, len = nsubtypes(u);
  2185. X        c = mk_text("(");
  2186. X        for (k = 0; k < len - 1; k++) {
  2187. X            c = conc(c, t_repr(subtype(u, k)));
  2188. X            c = conc(c, mk_text(", "));
  2189. X        }
  2190. X        c = conc(c, t_repr(subtype(u, k)));
  2191. X        return conc(c, mk_text(")"));
  2192. X    }
  2193. X    else if (t_is_error(u_kind)) {
  2194. X        return mk_text("?");
  2195. X    }
  2196. X    else if (t_is_var(u_kind)) {
  2197. X        value tu;
  2198. X        tu = oldbottomtype(u);
  2199. X        if (Known(tu))
  2200. X            return t_repr(tu);
  2201. X        else if (newvar(u))
  2202. X            return mk_text("?");
  2203. X        else
  2204. X            return copy(ident(u));
  2205. X    }
  2206. X    else if (t_is_table(u_kind)) {
  2207. X        c = conc(mk_text("{["),
  2208. X            t_repr(keytype(u)));
  2209. X        c = conc(c, mk_text("]: "));
  2210. X        c = conc(c, t_repr(asctype(u)));
  2211. X        return conc(c, mk_text("}"));
  2212. X    }
  2213. X    else if (t_is_list(u_kind)) {
  2214. X        c = conc(mk_text("{"), t_repr(asctype(u)));
  2215. X        return conc(c, mk_text("}"));
  2216. X    }
  2217. X    else if (t_is_lt(u_kind)) {
  2218. X        tau = oldbottomtype(asctype(u));
  2219. X        if (Known(tau))
  2220. X            return conc(mk_text(LT_OF),
  2221. X                    t_repr(tau));
  2222. X        else
  2223. X            return mk_text(LT);
  2224. X    }
  2225. X    else if (t_is_tlt(u_kind)) {
  2226. X        tau= oldbottomtype(asctype(u));
  2227. X        if (Known(tau)) {
  2228. X            if (t_is_text(kind(tau)))
  2229. X                return mk_text(T_OR_LT_OF_T);
  2230. X            else
  2231. X                return conc(mk_text(LT_OF), t_repr(tau));
  2232. X        }
  2233. X        else
  2234. X            return mk_text(TLT);
  2235. X    }
  2236. X    else {
  2237. X        return mk_text("***"); /* cannot happen */
  2238. X    }
  2239. X}
  2240. X
  2241. X/* now, the real error messages */
  2242. X
  2243. XVisible Procedure badtyperr(a, b) polytype a, b; {
  2244. X    value t;
  2245. X    value nerrs, n, ne_min, m, sep;
  2246. X    polytype te, bte;
  2247. X    
  2248. X    nerrs= size(errvarlist);
  2249. X    
  2250. X    if (compare(nerrs, one) < 0) {
  2251. X        t= mk_text(I_FOUND_TYPE);
  2252. X        if (!has_lt(kind(a)))
  2253. X            t= conc(t, mk_text(EG));
  2254. X        t= conc(t, t_repr(a));
  2255. X        t= conc(t, mk_text(WHERE_EXPECTED));
  2256. X        t= conc(t, t_repr(b));
  2257. X    }
  2258. X    else if (compare(nerrs, one) == 0) {
  2259. X        te= (polytype) item(errvarlist, one);
  2260. X        bte= oldbottomtype(te);
  2261. X        if (Known(bte)) {
  2262. X            t= conc(mk_text(I_THOUGHT),
  2263. X                copy(ident(te)));
  2264. X            t= conc(t, mk_text(WAS_OF_TYPE));
  2265. X            if (!has_lt(kind(bte)))
  2266. X                t= conc(t, mk_text(EG));
  2267. X            t= conc(t, t_repr(bte));
  2268. X        }
  2269. X        else {
  2270. X            t= conc(mk_text(INCOMPATIBLE),
  2271. X                copy(ident(te)));
  2272. X        }
  2273. X    }
  2274. X    else {
  2275. X        n= copy(one);
  2276. X        ne_min= diff(nerrs, one);
  2277. X        t= mk_text(INCOMPATIBLES);
  2278. X        for (;;) {
  2279. X            te= item(errvarlist, n);
  2280. X            t= conc(t, copy(ident(te)));
  2281. X            if (compare(n, nerrs) == 0)
  2282. X                break;
  2283. X            if (compare(n, ne_min) < 0)
  2284. X                sep= mk_text(", ");
  2285. X            else
  2286. X                sep= mk_text(_AND_);
  2287. X            t= conc(t, sep);
  2288. X            n= sum(m=n, one);
  2289. X            release(m); release(te);
  2290. X        }
  2291. X        release(te); release(ne_min); release(n);
  2292. X    }
  2293. X    release(nerrs);
  2294. X
  2295. X    typerrV(MESS(2612, "%s"), t);
  2296. X    release(t);
  2297. X}
  2298. X
  2299. X#ifdef TYPETRACE
  2300. X#include "i2nod.h"
  2301. Xchar *treename[NTYPES] = { /* legible names for debugging */
  2302. X    "HOW TO",
  2303. X    "HOW TO RETURN",
  2304. X    "HOW TO REPORT",
  2305. X    "REFINEMENT",
  2306. X
  2307. X/* Commands */
  2308. X
  2309. X    "SUITE",
  2310. X    "PUT",
  2311. X    "INSERT",
  2312. X    "REMOVE",
  2313. X    "SET RANDOM",
  2314. X    "DELETE",
  2315. X    "CHECK",
  2316. X    "SHARE",
  2317. X    "PASS",
  2318. X
  2319. X    "WRITE",
  2320. X    "WRITE1",
  2321. X    "READ",
  2322. X    "READ_RAW",
  2323. X
  2324. X    "IF",
  2325. X    "WHILE",
  2326. X    "FOR",
  2327. X
  2328. X    "SELECT",
  2329. X    "TEST_SUITE",
  2330. X    "ELSE",
  2331. X
  2332. X    "QUIT",
  2333. X    "RETURN",
  2334. X    "REPORT",
  2335. X    "SUCCEED",
  2336. X    "FAIL",
  2337. X
  2338. X    "USER_COMMAND",
  2339. X    "EXTENDED_COMMAND",
  2340. X
  2341. X/* Expressions, targets, tests */
  2342. X
  2343. X    "TAG",
  2344. X    "COMPOUND",
  2345. X
  2346. X/* Expressions, targets */
  2347. X
  2348. X    "COLLATERAL",
  2349. X    "SELECTION",
  2350. X    "BEHEAD",
  2351. X    "CURTAIL",
  2352. X
  2353. X/* Expressions, tests */
  2354. X
  2355. X    "UNPARSED",
  2356. X
  2357. X/* Expressions */
  2358. X
  2359. X    "MONF",
  2360. X    "DYAF",
  2361. X    "NUMBER",
  2362. X    "TEXT_DIS",
  2363. X    "TEXT_LIT",
  2364. X    "TEXT_CONV",
  2365. X    "ELT_DIS",
  2366. X    "LIST_DIS",
  2367. X    "RANGE_BNDS",
  2368. X    "TAB_DIS",
  2369. X
  2370. X/* Tests */
  2371. X
  2372. X    "AND",
  2373. X    "OR",
  2374. X    "NOT",
  2375. X    "SOME_IN",
  2376. X    "EACH_IN",
  2377. X    "NO_IN",
  2378. X    "MONPRD",
  2379. X    "DYAPRD",
  2380. X    "LESS_THAN",
  2381. X    "AT_MOST",
  2382. X    "GREATER_THAN",
  2383. X    "AT_LEAST",
  2384. X    "EQUAL",
  2385. X    "UNEQUAL",
  2386. X    "Nonode",
  2387. X
  2388. X    "TAGformal",
  2389. X    "TAGlocal",
  2390. X    "TAGglobal",
  2391. X    "TAGrefinement",
  2392. X    "TAGzerfun",
  2393. X    "TAGzerprd",
  2394. X
  2395. X    "ACTUAL",
  2396. X    "FORMAL",
  2397. X
  2398. X#ifdef GFX
  2399. X    "SPACE",
  2400. X    "LINE",
  2401. X    "CLEAR",
  2402. X#endif
  2403. X
  2404. X    "COLON_NODE",
  2405. X
  2406. X};
  2407. X
  2408. Xextern FILE *stc_fp;
  2409. X
  2410. XVisible Procedure t_typecheck(nt, t) int nt; string t; {
  2411. X    if (stc_fp == NULL)
  2412. X        return;
  2413. X    fprintf(stc_fp, "TC NODE %s, CODE %s\n", treename[nt], t);
  2414. X    fflush(stc_fp);
  2415. X}
  2416. X
  2417. XVisible Procedure s_unify(a, b) polytype a, b; {
  2418. X    value t;
  2419. X    
  2420. X    if (stc_fp == NULL)
  2421. X        return;
  2422. X    t= mk_text("START UNIFY ");
  2423. X    if (t_is_var(kind(a))) {
  2424. X        t= conc(t, copy(ident(a)));
  2425. X        t= conc(t, mk_text("="));
  2426. X    }
  2427. X    t= conc(t, convert((value)oldbottomtype(a), No, No));
  2428. X    t= conc(t, mk_text(" WITH "));
  2429. X    if (t_is_var(kind(b))) {
  2430. X        t= conc(t, copy(ident(b)));
  2431. X        t= conc(t, mk_text("="));
  2432. X    }
  2433. X    t= conc(t, convert((value)oldbottomtype(b), No, No));
  2434. X    fprintf(stc_fp, "%s\n", strval(t));
  2435. X    release(t);
  2436. X    t= mk_text("USING ");
  2437. X    t= conc(t, convert(ptype_of, No, No));
  2438. X    fprintf(stc_fp, "%s\n", strval(t));
  2439. X    release(t);
  2440. X    fflush(stc_fp);
  2441. X}
  2442. X
  2443. XVisible Procedure e_unify(a, b, c) polytype a, b, c; {
  2444. X    value t;
  2445. X    
  2446. X    if (stc_fp == NULL)
  2447. X        return;
  2448. X    t= mk_text("GIVING ");
  2449. X    if (t_is_var(kind(c))) {
  2450. X        t= conc(t, copy(ident(c)));
  2451. X        t= conc(t, mk_text("="));
  2452. X    }
  2453. X    t= conc(t, convert((value)oldbottomtype(c), No, No));
  2454. X    fprintf(stc_fp, "%s\n", strval(t));
  2455. X    release(t);
  2456. X    t= mk_text("PRODUCING ");
  2457. X    t= conc(t, convert(ptype_of));
  2458. X    fprintf(stc_fp, "%s\n", strval(t));
  2459. X    release(t);
  2460. X    fflush(stc_fp);
  2461. X}
  2462. X#endif /* TYPETRACE */
  2463. END_OF_FILE
  2464.   if test 7902 -ne `wc -c <'abc/stc/i2tce.c'`; then
  2465.     echo shar: \"'abc/stc/i2tce.c'\" unpacked with wrong size!
  2466.   fi
  2467.   # end of 'abc/stc/i2tce.c'
  2468. fi
  2469. echo shar: End of archive 17 \(of 25\).
  2470. cp /dev/null ark17isdone
  2471. MISSING=""
  2472. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
  2473.     if test ! -f ark${I}isdone ; then
  2474.     MISSING="${MISSING} ${I}"
  2475.     fi
  2476. done
  2477. if test "${MISSING}" = "" ; then
  2478.     echo You have unpacked all 25 archives.
  2479.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2480. else
  2481.     echo You still must unpack the following archives:
  2482.     echo "        " ${MISSING}
  2483. fi
  2484. exit 0 # Just in case...
  2485.