home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / abc / part11 < prev    next >
Text File  |  1991-01-08  |  56KB  |  2,243 lines

  1. Subject:  v23i090:  ABC interactive programming environment, Part11/25
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: c6309c96 cdc316ee 7100378f 8bf5ed3b
  5.  
  6. Submitted-by: Steven Pemberton <steven@cwi.nl>
  7. Posting-number: Volume 23, Issue 90
  8. Archive-name: abc/part11
  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/Problems abc/bed/e1deco.c abc/bint2/i2syn.c
  17. #   abc/boot/read.c
  18. # Wrapped by rsalz@litchi.bbn.com on Mon Dec 17 13:28:02 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. echo If this archive is complete, you will see the following message:
  21. echo '          "shar: End of archive 11 (of 25)."'
  22. if test -f 'abc/Problems' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'abc/Problems'\"
  24. else
  25.   echo shar: Extracting \"'abc/Problems'\" \(8788 characters\)
  26.   sed "s/^X//" >'abc/Problems' <<'END_OF_FILE'
  27. XCopyright (c) Stichting Mathematisch Centrum, Amsterdam, 1988.
  28. X
  29. XHOW TO TACKLE PROBLEMS DURING ABC INSTALLATION
  30. X
  31. XThis file contains some detailed advice in case you run into problems while
  32. Xinstalling the ABC system.
  33. X
  34. XTHE SETUP PROCEDURE
  35. X
  36. XYour best bet if the "Setup" script fails is to read it, locate the
  37. Xproblem, change it and run it again.  You can always shorten its runtime by
  38. Xchanging long pieces into the simple setting of a shell variable.  For
  39. Xinstance, once you are sure your floating point is allright, you might
  40. Xreplace the whole section titled "Floating point arithmetic ok?" by a
  41. Xsimple "fflag=".
  42. X
  43. XNormally you should not edit the files that Setup creates (./Makefile,
  44. X./uhdrs/os.h ./unix/abc.sh and ./scripts/mkdep) directly, but their
  45. Xancestors (./Makefile.unix, ./uhdrs/os.h.gen, ./unix/abc.sh.gen and
  46. X./scripts/mkdep.gen, respectively) and run Setup to incorporate your
  47. Xchanges.  If you really want to change them directly, also change Setup to
  48. Xwork on them or remove Setup completely.
  49. X
  50. XWHEN "MAKE MAKEFILES" OR "MAKE DEPEND" FAIL
  51. X
  52. XWhen "make makefiles" fails to create the makefiles */Mf in the relevant
  53. Xsubdirectories, first try to edit the shell commands in Makefile.unix (and
  54. Xrun Setup again; see above).
  55. X
  56. XLikewise, if "make depend" fails to create the */Dep files in the
  57. Xsubdirectories, try to fix ./scripts/mkdep (and incorporate the changes in
  58. X./scripts/mkdep.gen before running Setup again).
  59. X
  60. XHowever, if either of these is not succesful, you can use the already
  61. Xconstructed makefiles */MF and */DEP.  To do this, redefine "MF=Mf" to
  62. X"MF=MF" and "DEP=Dep" to "DEP=DEP" in Makefile.unix.  You can then call
  63. X"make all" immediately, without "make makefiles" and "make depend".
  64. X
  65. XThe makefiles */MF and */DEP were created on a machine running 4.3 BSD
  66. XUNIX.  The dependencies in the */DEP files on system include files
  67. X(embedded in <>) were stripped to make them more portable.  On a different
  68. Xsystem the real dependencies may differ in some details, however.  This may
  69. Xcause a second "make" after some editing to not see all dependencies on
  70. Xinclude files properly.  You can always use "make clean all" to force all
  71. Xobjects to be recompiled if you suspect you ran into this.
  72. X
  73. XMACHINE CONFIGURATION
  74. X
  75. XThe file ./uhdrs/config.h is created by compiling "mkconfig.c" and running
  76. X"mkconfig" on your target machine, since it tries to establish some facts
  77. Xabout the hardware configuration.  (If you are cross-compiling you should
  78. Xdo that before "make depend" since that would run mkconfig on the local
  79. X(compiling) machine.  If Setup went alright, DESTROOT will be set in the
  80. XMakefile and you will be warned accordingly.)
  81. X
  82. XIf you really have to edit uhdrs/config.h, you should edit the Makefile (or
  83. XMakefile.unix) so that it will not overwrite it anymore.
  84. X
  85. XThe problem most encountered with mkconfig is "unexpected over/underflow".
  86. XThis is usually caused by a bug in "printf", where it can't print very
  87. Xlarge or very small numbers.  Look at the last line produced by mkconfig
  88. Xbefore it failed, and then locate the printf after the one that printed
  89. Xthat line.  If it is trying to print a comment (rather than a #define),
  90. Xyou can safely comment out the printf and try again.  (You might also want
  91. Xto report the bug to your UNIX supplier.)
  92. X
  93. XOTHER UNIX's
  94. X
  95. XThe installation of the ABC system has been tested under 4.3 BSD UNIX on
  96. XTahoe, Vax and Sun machines, under ATT System V Release 3.0 UNIX on an
  97. XIntel 80386, and under MINIX, which is supposed to be VERSION 7 UNIX
  98. Xcompatible.  The Setup script tries to find out whether your UNIX is one of
  99. Xthese, and creates ./uhdrs/os.h from ./uhdrs/os.h.gen accordingly.  We
  100. Xexpect you will have no problems compiling the ABC system in this case.
  101. X
  102. XIf your UNIX is different, the Setup script will create a file ./uhdrs/os.h
  103. Xwith most defaults setup for a VERSION 7 UNIX system, since that makes a
  104. Xminimum number of assumptions.  Examine the resulting file, and change the
  105. Xnames of system include files if they are different on your system.  Also
  106. Xcheck the definitions and UNIX specific flags in this file.  See the
  107. Xcomments, and use your systems manual to find out how to set them.  Don't
  108. Xforget that this file is created by running Setup; change Setup if you want
  109. Xto edit uhdrs/os.h directly, or edit uhdrs/os.h.gen and run Setup again.
  110. X
  111. XIf your machine's memory is not that big, you might examine ./uhdrs/feat.h
  112. Xto turn off some features in an attempt to make the ABC editor-interpreter
  113. Xsmaller.
  114. X
  115. XWe have tried to gather the operating system dependent parts in ./unix/*.c
  116. Xand ./uhdrs/*.h.  Examine these if any problems in compilation remain.
  117. X
  118. XEDITOR PROBLEMS
  119. X
  120. XOnce the ABC system is compiled, you may encounter problems when you use
  121. Xthe ABC editor.  Our experience is that most of these problems are caused
  122. Xby erroneous or insufficiently detailed termcap entries, which decribe your
  123. Xterminal's capabilities; so first check the "termcap(5)" manual entry (or
  124. X"terminfo(4)" for terminfo systems).  Ask your system's guru to give you a
  125. Xhand if you are not familiar with these.
  126. X
  127. XWe use the following entries from the termcap database if they are defined
  128. Xfor your terminal:
  129. X
  130. X       Name   Type   Description
  131. X
  132. X       AL     str    add n new blank lines
  133. X       CM     str    screen-relative cursor motion
  134. X       DL     str    delete n lines
  135. X       al     str    add new blank line
  136. X       am     bool   has automatic margins
  137. X       bc     str    backspace character
  138. X       bs     bool   terminal can backspace
  139. X       cd     str    clear to end of display
  140. X       ce     str    clear to end of line
  141. X       cl     str    cursor home and clear screen
  142. X       cm     str    cursor motion
  143. X       co     num    number of columns in a line
  144. X       cp     str    cursor position sense reply
  145. X       cr     str    carriage return
  146. X       cs     str    change scrolling region
  147. X       da     bool   display may be retained above screen
  148. X       db     bool   display may be retained below screen
  149. X       dc     str    delete character
  150. X       dl     str    delete line
  151. X       dm     str    enter delete mode
  152. X       do     str    cursor down one line
  153. X       ed     str    end delete mode
  154. X       ei     str    end insert mode
  155. X       hc     bool   hardcopy terminal
  156. X       ho     str    cursor home
  157. X       ic     str    insert character (if necessary; may pad)
  158. X       im     str    enter insert mode
  159. X       in     bool   not save to have null chars on the screen
  160. X       ke     str    keypad mode end
  161. X       ks     str    keypad mode start
  162. X       le     str    cursor left
  163. X       li     num    number of lines on screen
  164. X       mi     bool   move safely in insert (and delete?) mode
  165. X       ms     bool   move safely in standout mode
  166. X       nd     str    cursor right (non-destructive space)
  167. X       nl     str    newline
  168. X       pc     str    pad character
  169. X       se     str    end standout mode
  170. X       sf     str    scroll text up (from bottom of region)
  171. X       sg     num    number of garbage characters left by so or se (default 0)
  172. X       so     str    begin standout mode
  173. X       sp     str    sense cursor position
  174. X       sr     str    scroll text down (from top of region)
  175. X       te     str    end termcap
  176. X       ti     str    start termcap
  177. X       ue     str    end underscore mode
  178. X       up     str    cursor up
  179. X       us     str    start underscore mode
  180. X       vb     str    visible bell
  181. X       ve     str    make cursor visible again
  182. X       vi     str    make cursor invisible
  183. X       xn     bool   newline ignored after 80 cols (VT100 / Concept glitch)
  184. X       xs     bool   standout not erased by overwriting
  185. X
  186. XOf these your termcap entry should at least define the following:
  187. X
  188. X       le OR bc OR bs
  189. X       up
  190. X       cm OR CM OR (ho AND do AND nd)
  191. X       (al AND dl) OR (cs AND sr)
  192. X       ce
  193. X       (so AND se AND sg = 0 [or not defined]) OR (us AND ue)
  194. X
  195. XIf either of these requirements is not fulfilled, the ABC editor will
  196. Xcomplain that your terminal is too dumb.
  197. X
  198. XOne common problem on terminals with resizeable windows is that the ABC
  199. Xprompt shows up like
  200. X
  201. X       >>>
  202. X           ?
  203. X
  204. Xon two lines instead of one.  This means that the "li#" entry in your
  205. XTERMCAP does not accurately reflect the number of lines actually in the
  206. Xwindow.  This can be remedied by changing the setting of your TERMCAP
  207. Xenvironment variable, using the output of "stty size" (see stty(1)).  (On
  208. Xsystems that have the TIOCGWINSZ ioctl, we use it to get the proper window
  209. Xsize; see tty(4) on BSD UNIX systems).
  210. X
  211. XERROR MESSAGES
  212. X
  213. XThe error messages that ABC displays are all gathered in a file and only
  214. Xread when necessary.  This was done to diminish the store used for all
  215. Xthese strings and to enhance the adaptability of ABC to another natural
  216. Xlanguage.
  217. X
  218. XIf you want the error messages in another language, for example French, you
  219. Xonly have to replace the file ./abc.msg by a French version.
  220. END_OF_FILE
  221.   if test 8788 -ne `wc -c <'abc/Problems'`; then
  222.     echo shar: \"'abc/Problems'\" unpacked with wrong size!
  223.   fi
  224.   # end of 'abc/Problems'
  225. fi
  226. if test -f 'abc/bed/e1deco.c' -a "${1}" != "-c" ; then 
  227.   echo shar: Will not clobber existing file \"'abc/bed/e1deco.c'\"
  228. else
  229.   echo shar: Extracting \"'abc/bed/e1deco.c'\" \(15039 characters\)
  230.   sed "s/^X//" >'abc/bed/e1deco.c' <<'END_OF_FILE'
  231. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  232. X
  233. X/*
  234. X * B editor -- Delete and copy commands.
  235. X */
  236. X
  237. X#include "b.h"
  238. X#include "bedi.h"
  239. X#include "etex.h"
  240. X#include "bobj.h"
  241. X#include "feat.h"
  242. X#include "erro.h"
  243. X#include "node.h"
  244. X#include "gram.h"
  245. X#include "supr.h"
  246. X#include "queu.h"
  247. X#include "tabl.h"
  248. X
  249. Xvalue copyout(); /* Forward */
  250. Xextern bool lefttorite;
  251. X/*
  252. X * DELETE and COPY currently share a buffer, called the copy buffer.
  253. X * (Physically, there is one such a buffer in each environment.)
  254. X * In ordinary use, the copy buffer receives the text deleted by the
  255. X * last DELETE command (unless it just removed a hole); the COPY command
  256. X * can then be used (with the focus on a hole) to copy it back.
  257. X * When some portion of text must be held while other text is deleted,
  258. X * the COPY command again, but now with the focus on the text to be held,
  259. X * copies it to the buffer and deleted text won't overwrite the buffer
  260. X * until it is copied back at least once.
  261. X * If the buffer holds text that was explicitly copied out but not yet
  262. X * copied back in, it is saved on a file when the editor exits, so it can
  263. X * be used in the next session; but this is not true for text implicitly
  264. X * placed in the buffer through DELETE.
  265. X */
  266. X
  267. X/*
  268. X * Delete command -- delete the text in the focus, or delete the hole
  269. X * if it is only a hole.
  270. X */
  271. X
  272. XVisible bool
  273. Xdeltext(ep)
  274. X    register environ *ep;
  275. X{
  276. X    higher(ep);
  277. X    shrink(ep);
  278. X    if (ishole(ep))
  279. X        return delhole(ep);
  280. X    if (!ep->copyflag) {
  281. X        release(ep->copybuffer);
  282. X        ep->copybuffer = copyout(ep);
  283. X    }
  284. X    return delbody(ep);
  285. X}
  286. X
  287. X
  288. X/*
  289. X * Delete the focus under the assumption that it contains some text.
  290. X */
  291. X
  292. XVisible bool
  293. Xdelbody(ep)
  294. X    register environ *ep;
  295. X{
  296. X    ep->changed = Yes;
  297. X
  298. X    subgrow(ep, No, Yes); /* Don't ignore spaces */
  299. X    switch (ep->mode) {
  300. X
  301. X    case SUBRANGE:
  302. X        if (ep->s1&1)
  303. X            return delfixed(ep);
  304. X        return delvarying(ep);
  305. X
  306. X    case SUBSET:
  307. X        return delsubset(ep, Yes);
  308. X
  309. X    case SUBLIST:
  310. X        return delsublist(ep);
  311. X
  312. X    case WHOLE:
  313. X        return delwhole(ep);
  314. X
  315. X    default:
  316. X        Abort();
  317. X        /* NOTREACHED */
  318. X    }
  319. X}
  320. X
  321. X
  322. X/*
  323. X * Delete portion (ep->mode == SUBRANGE) of varying text ((ep->s1&1) == 0).
  324. X */
  325. X
  326. XHidden bool
  327. Xdelvarying(ep)
  328. X    register environ *ep;
  329. X{
  330. X    auto queue q = Qnil;
  331. X    register node n = tree(ep->focus);
  332. X    auto value v;
  333. X    value t1, t2;
  334. X
  335. X    v = (value) child(n, ep->s1/2);
  336. X    Assert(ep->mode == SUBRANGE && !(ep->s1&1)); /* Wrong call */
  337. X    Assert(Is_etext(v)); /* Inconsistent parse tree */
  338. X    if (ep->s2 == 0) {
  339. X        /* strval(v)[ep->s3 + 1] */
  340. X        if (!mayinsert(tree(ep->focus), ep->s1/2, 0, e_ncharval(ep->s3 + 2, v))) {
  341. X            /* Cannot do simple substring deletion. */
  342. X/*            stringtoqueue(strval(v) + ep->s3 + 1, &q); */
  343. X            t1= e_ibehead(v, ep->s3 + 2);
  344. X            preptoqueue((node) t1, &q);
  345. X            release(t1);
  346. X            delfocus(&ep->focus);
  347. X            ep->mode = WHOLE;
  348. X            return app_queue(ep, &q);
  349. X        }
  350. X    }
  351. X    v = copy(v);
  352. X    /* putintrim(&v, ep->s2, len - ep->s3 - 1, ""); */
  353. X    t1= e_icurtail(v, ep->s2);
  354. X    t2= e_ibehead(v, ep->s3 + 2);
  355. X    release(v);
  356. X    v= e_concat(t1, t2);
  357. X    release(t1); release(t2);
  358. X    s_downi(ep, ep->s1/2);
  359. X    treereplace(&ep->focus, (node) v);
  360. X    s_up(ep);
  361. X    ep->mode = VHOLE;
  362. X    return Yes;
  363. X}
  364. X
  365. X
  366. X/*
  367. X * Delete portion (ep->mode == SUBRANGE) of fixed text ((ep->s1&1) == 1).
  368. X */
  369. X
  370. XHidden bool
  371. Xdelfixed(ep)
  372. X    register environ *ep;
  373. X{
  374. X    register node n = tree(ep->focus);
  375. X    char buf[15]; /* Long enough for all fixed texts */
  376. X    string *nr= noderepr(n);
  377. X    register string repr = nr[ep->s1/2];
  378. X    register int len;
  379. X    queue q = Qnil;
  380. X    bool ok;
  381. X
  382. X    Assert(ep->mode == SUBRANGE && (ep->s1&1));
  383. X    if (ep->s1 > 1) {
  384. X        ep->mode = FHOLE;
  385. X        return Yes;
  386. X    }
  387. X    else if (symbol(n) == Select && ep->s2 == 0 && repr[ep->s3+1] == ':') {
  388. X        /* hack to prevent asserr in app_queue below */
  389. X        ep->s3++;
  390. X    }
  391. X    Assert(fwidth(repr) < sizeof buf - 1);
  392. X    len = ep->s2;
  393. X    ep->s2 = ep->s3 + 1;
  394. X    ep->mode = FHOLE;
  395. X    nosuggtoqueue(ep, &q);
  396. X    strcpy(buf, repr);
  397. X    if (nchildren(tree(ep->focus)) > 0)
  398. X        buf[len] = 0;
  399. X    else
  400. X        strcpy(buf+len, buf+ep->s2);
  401. X    delfocus(&ep->focus);
  402. X    ep->mode = WHOLE;
  403. X    markpath(&ep->focus, 1);
  404. X    ok = ins_string(ep, buf, &q, 0);
  405. X    if (!ok) {
  406. X        qrelease(q);
  407. X        return No;
  408. X    }
  409. X    if (!firstmarked(&ep->focus, 1)) Abort();
  410. X    unmkpath(&ep->focus, 1);
  411. X    fixfocus(ep, len);
  412. X    return app_queue(ep, &q);
  413. X}
  414. X
  415. X/*
  416. X * refinement for delsubset and delsublist
  417. X * to delete an initial KEYWORDS part before an expression
  418. X * (the latter being sent to qq)
  419. X */
  420. X
  421. XHidden bool hole_ify_keywords(ep, qq)
  422. X    register environ *ep;
  423. X    queue *qq;
  424. X{
  425. X    treereplace(&ep->focus, gram(Kw_plus));
  426. X    ep->mode= VHOLE;
  427. X    ep->s1= 4;
  428. X    ep->s2= 0;
  429. X    if (app_queue(ep, qq)) {
  430. X        ep->mode= FHOLE;
  431. X        ep->s1= 1;
  432. X        ep->s2= 0;
  433. X        return Yes;
  434. X    }
  435. X    return No;
  436. X}
  437. X
  438. X/*
  439. X * Delete focus if ep->mode == SUBSET.
  440. X */
  441. X
  442. XHidden bool
  443. Xdelsubset(ep, hack)
  444. X    register environ *ep;
  445. X    bool hack;
  446. X{
  447. X    auto queue q = Qnil;
  448. X    auto queue q2 = Qnil;
  449. X    register node n = tree(ep->focus);
  450. X    register node nn;
  451. X    register string *rp = noderepr(n);
  452. X    register int nch = nchildren(n);
  453. X    register int i;
  454. X    bool res;
  455. X    int sym= symbol(n);
  456. X    
  457. X    if (hack) {
  458. X        shrsubset(ep);
  459. X        if (ep->s1 == ep->s2 && !(ep->s1&1)) {
  460. X            nn = child(tree(ep->focus), ep->s1/2);
  461. X            if (fwidth(noderepr(nn)[0]) < 0) {
  462. X                /* It starts with a newline, leave the newline */
  463. X                s_downi(ep, ep->s1/2);
  464. X                ep->mode = SUBSET;
  465. X                ep->s1 = 2;
  466. X                ep->s2 = 2*nchildren(nn) + 1;
  467. X                return delsubset(ep, hack);
  468. X            }
  469. X        }
  470. X        subgrsubset(ep, No); /* Undo shrsubset */
  471. X        if (ep->s2 == 3 && rp[1] && !strcmp(rp[1], "\t"))
  472. X            --ep->s2; /* Hack for deletion of unit-head or if/for/wh. head */
  473. X    }
  474. X    if (ep->s1 == 1 && Fw_negative(rp[0]))
  475. X        ++ep->s1; /* Hack for deletion of test-suite or refinement head */
  476. X
  477. X    if (Fw_zero(rp[0]) ? (ep->s2 < 3 || ep->s1 > 3) : ep->s1 > 1) {
  478. X        /* No deep structural change */
  479. X        for (i = (ep->s1+1)/2; i <= ep->s2/2; ++i) {
  480. X            s_downi(ep, i);
  481. X            delfocus(&ep->focus);
  482. X            s_up(ep);
  483. X        }
  484. X        if (ep->s1&1) {
  485. X            ep->mode = FHOLE;
  486. X            ep->s2 = 0;
  487. X        }
  488. X        else if (Is_etext(child(tree(ep->focus), ep->s1/2))) {
  489. X            ep->mode = VHOLE;
  490. X            ep->s2 = 0;
  491. X        }
  492. X        else {
  493. X            s_downi(ep, ep->s1/2);
  494. X            ep->mode = ATBEGIN;
  495. X        }
  496. X        return Yes;
  497. X    }
  498. X
  499. X    balance(ep); /* Make balanced \t - \b pairs */
  500. X    subsettoqueue(n, 1, ep->s1-1, &q);
  501. X    subsettoqueue(n, ep->s2+1, 2*nch+1, &q2);
  502. X    nonewline(&q2); /* Wonder what will happen...? */
  503. X    
  504. X    if (ep->s1 == 1 && Fw_positive(rp[0]) && allowed(ep->focus, Kw_plus)
  505. X        && (sym != If && sym != While && sym != For && sym != Select))
  506. X    {
  507. X        Assert(emptyqueue(q));
  508. X        return hole_ify_keywords(ep, &q2);
  509. X    }
  510. X    delfocus(&ep->focus);
  511. X    ep->mode = ATBEGIN;
  512. X    leftvhole(ep);
  513. X    if (!ins_queue(ep, &q, &q2)) {
  514. X        qrelease(q2);
  515. X        return No;
  516. X    }
  517. X    res= app_queue(ep, &q2);
  518. X#ifdef USERSUGG
  519. X    if (symbol(tree(ep->focus)) == Suggestion)
  520. X        killsugg(ep, (string*)NULL);
  521. X#endif
  522. X    return res;
  523. X}
  524. X
  525. X
  526. X/*
  527. X * Delete the focus if ep->mode == SUBLIST.
  528. X */
  529. X
  530. Xdelsublist(ep)
  531. X    register environ *ep;
  532. X{
  533. X    register node n;
  534. X    register int i;
  535. X    register int sym;
  536. X    queue q = Qnil;
  537. X    bool flag;
  538. X
  539. X    Assert(ep->mode == SUBLIST);
  540. X    n = tree(ep->focus);
  541. X    flag = fwidth(noderepr(n)[0]) < 0;
  542. X    for (i = ep->s3; i > 0; --i) {
  543. X        n = lastchild(n);
  544. X        Assert(n);
  545. X    }
  546. X    if (flag) {
  547. X        n = nodecopy(n);
  548. X        s_down(ep);
  549. X        do {
  550. X            delfocus(&ep->focus);
  551. X        } while (rite(&ep->focus));
  552. X        if (!allowed(ep->focus, symbol(n))) {
  553. X            ederr(0); /* The remains wouldn't fit */
  554. X            noderelease(n);
  555. X            return No;
  556. X        }
  557. X        treereplace(&ep->focus, n);
  558. X        s_up(ep);
  559. X        s_down(ep); /* I.e., to leftmost sibling */
  560. X        ep->mode = WHOLE;
  561. X        return Yes;
  562. X    }
  563. X    sym = symbol(n);
  564. X    if (sym == Optional || sym == Hole) {
  565. X        delfocus(&ep->focus);
  566. X        ep->mode = WHOLE;
  567. X    }
  568. X    else if (!allowed(ep->focus, sym)) {
  569. X        preptoqueue(n, &q);
  570. X        if (symbol(tree(ep->focus)) == Kw_plus) {
  571. X            return hole_ify_keywords(ep, &q);
  572. X        }
  573. X        delfocus(&ep->focus);
  574. X        ep->mode = WHOLE;
  575. X        return app_queue(ep, &q);
  576. X    }
  577. X    else {
  578. X        treereplace(&ep->focus, nodecopy(n));
  579. X        ep->mode = ATBEGIN;
  580. X    }
  581. X    return Yes;
  582. X}
  583. X
  584. X
  585. X/*
  586. X * Delete the focus if ep->mode == WHOLE.
  587. X */
  588. X
  589. XHidden bool
  590. Xdelwhole(ep)
  591. X    register environ *ep;
  592. X{
  593. X    register int sym = symbol(tree(ep->focus));
  594. X
  595. X    Assert(ep->mode == WHOLE);
  596. X    if (sym == Optional || sym == Hole)
  597. X        return No;
  598. X    delfocus(&ep->focus);
  599. X    return Yes;
  600. X}
  601. X
  602. X
  603. X/*
  604. X * Delete the focus if it is only a hole.
  605. X * Assume shrink() has been called before!
  606. X */
  607. X
  608. XHidden bool
  609. Xdelhole(ep)
  610. X    register environ *ep;
  611. X{
  612. X    node n;
  613. X    int sym;
  614. X    bool flag = No;
  615. X
  616. X    switch (ep->mode) {
  617. X    
  618. X    case ATBEGIN:
  619. X    case VHOLE:
  620. X    case FHOLE:
  621. X    case ATEND:
  622. X        return widen(ep, Yes);
  623. X
  624. X    case WHOLE:
  625. X        Assert((sym = symbol(tree(ep->focus))) == Optional || sym == Hole);
  626. X        if (ichild(ep->focus) != 1)
  627. X            break;
  628. X        if (!up(&ep->focus))
  629. X            return No;
  630. X        higher(ep);
  631. X        ep->mode = SUBSET;
  632. X        ep->s1 = 2;
  633. X        ep->s2 = 2;
  634. X        if (fwidth(noderepr(tree(ep->focus))[0]) < 0) {
  635. X            flag = Yes;
  636. X            ep->s2 = 3; /* Extend to rest of line */
  637. X        }
  638. X    }
  639. X
  640. X    ep->changed = Yes;
  641. X    grow(ep, Yes);
  642. X    
  643. X    if (!parent(ep->focus) && colonhack(ep, Yes))
  644. X        ep->mode= WHOLE; /* to delete a sequence of hole's below */
  645. X    
  646. X    switch (ep->mode) {
  647. X
  648. X    case SUBSET:
  649. X        if (!delsubset(ep, No))
  650. X            return No;
  651. X        if (!flag)
  652. X            return widen(ep, Yes);
  653. X        leftvhole(ep);
  654. X        oneline(ep);
  655. X        return Yes;
  656. X
  657. X    case SUBLIST:
  658. X        n = tree(ep->focus);
  659. X        n = lastchild(n);
  660. X        sym = symbol(n);
  661. X        if (!allowed(ep->focus, sym) 
  662. X            && sym != Exp_plus && symbol(tree(ep->focus)) != Kw_plus) {
  663. X            /* previous line enables deletion of emptied KEYWORD */
  664. X            ederr(0); /* The remains wouldn't fit */
  665. X            return No;
  666. X        }
  667. X        flag = samelevel(sym, symbol(tree(ep->focus)));
  668. X        treereplace(&ep->focus, nodecopy(n));
  669. X        if (flag) {
  670. X            ep->mode = SUBLIST;
  671. X            ep->s3 = 1;
  672. X        }
  673. X        else
  674. X            ep->mode = WHOLE;
  675. X        return Yes;
  676. X
  677. X    case WHOLE:
  678. X        Assert(!parent(ep->focus)); /* Must be at root! */
  679. X        sym= symbol(tree(ep->focus));
  680. X        if (sym != Optional && sym != Hole) {
  681. X            /* delete sequence of Hole's */
  682. X            delfocus(&ep->focus);
  683. X            return Yes;
  684. X        }
  685. X        return No;
  686. X
  687. X    default:
  688. X        Abort();
  689. X        /* NOTREACHED */
  690. X
  691. X    }
  692. X}
  693. X
  694. X
  695. X/*
  696. X * Subroutine to delete the focus.
  697. X */
  698. X
  699. XVisible Procedure
  700. Xdelfocus(pp)
  701. X    register path *pp;
  702. X{
  703. X    register path pa = parent(*pp);
  704. X    register int sympa = pa ? symbol(tree(pa)) : Rootsymbol;
  705. X
  706. X    treereplace(pp, child(gram(sympa), ichild(*pp)));
  707. X}
  708. X
  709. X
  710. X/*
  711. X * Copy command -- copy the focus to the copy buffer if it contains
  712. X * some text, copy the copy buffer into the focus if the focus is
  713. X * empty (just a hole).
  714. X */
  715. X
  716. XVisible bool
  717. Xcopyinout(ep)
  718. X    register environ *ep;
  719. X{
  720. X    shrink(ep);
  721. X    if (!ishole(ep)) {
  722. X        release(ep->copybuffer);
  723. X        ep->copybuffer = copyout(ep);
  724. X        ep->copyflag = !!ep->copybuffer;
  725. X        return ep->copyflag;
  726. X    }
  727. X    else {
  728. X        fixit(ep); /* Make sure it looks like a hole now */
  729. X        if (!copyin(ep, (queue) ep->copybuffer))
  730. X            return No;
  731. X        ep->copyflag = No;
  732. X        return Yes;
  733. X    }
  734. X}
  735. X
  736. X
  737. X/*
  738. X * Copy the focus to the copy buffer.
  739. X */
  740. X
  741. XVisible value
  742. Xcopyout(ep)
  743. X    register environ *ep;
  744. X{
  745. X    auto queue q = Qnil;
  746. X    auto path p;
  747. X    register node n;
  748. X    register value v;
  749. X    char buf[15];
  750. X    register string *rp;
  751. X    register int i;
  752. X    value w;
  753. X
  754. X    switch (ep->mode) {
  755. X    case WHOLE:
  756. X        preptoqueue(tree(ep->focus), &q);
  757. X        break;
  758. X    case SUBLIST:
  759. X        p = pathcopy(ep->focus);
  760. X        for (i = ep->s3; i > 0; --i)
  761. X            if (!downrite(&p)) Abort();
  762. X        for (i = ep->s3; i > 0; --i) {
  763. X            if (!up(&p)) Abort();
  764. X            n = tree(p);
  765. X            subsettoqueue(n, 1, 2*nchildren(n) - 1, &q);
  766. X        }
  767. X        pathrelease(p);
  768. X        break;
  769. X    case SUBSET:
  770. X        balance(ep);
  771. X        subsettoqueue(tree(ep->focus), ep->s1, ep->s2, &q);
  772. X        break;
  773. X    case SUBRANGE:
  774. X        Assert(ep->s3 >= ep->s2);
  775. X        if (ep->s1&1) { /* Fixed text */
  776. X            Assert(ep->s3 - ep->s2 + 1 < sizeof buf);
  777. X            rp = noderepr(tree(ep->focus));
  778. X            Assert(ep->s2 < Fwidth(rp[ep->s1/2]));
  779. X            strncpy(buf, rp[ep->s1/2] + ep->s2, ep->s3 - ep->s2 + 1);
  780. X            buf[ep->s3 - ep->s2 + 1] = 0;
  781. X            stringtoqueue(buf, &q);
  782. X        }
  783. X        else { /* Varying text */
  784. X            v = (value) child(tree(ep->focus), ep->s1/2);
  785. X            Assert(Is_etext(v));
  786. X/*            v = trim(v, ep->s2, Length(v) - ep->s3 - 1); */
  787. X            w= e_icurtail(v, ep->s3 + 1);
  788. X            v= e_ibehead(w, ep->s2 + 1);
  789. X            release(w);
  790. X            preptoqueue((node)v, &q);
  791. X            release(v);
  792. X        }
  793. X        break;
  794. X    default:
  795. X        Abort();
  796. X    }
  797. X    nonewline(&q);
  798. X    return (value)q;
  799. X}
  800. X
  801. X
  802. X/*
  803. X * Subroutine to ensure the copy buffer doesn't start with a newline.
  804. X */
  805. X
  806. XHidden Procedure
  807. Xnonewline(pq)
  808. X    register queue *pq;
  809. X{
  810. X    register node n;
  811. X    register int c;
  812. X
  813. X    if (!emptyqueue(*pq)) {
  814. X        for (;;) {
  815. X            n = queuebehead(pq);
  816. X            if (Is_etext(n)) {
  817. X                if (e_ncharval(1, (value)n) != '\n')
  818. X                    preptoqueue(n, pq);
  819. X                noderelease(n);
  820. X                break;
  821. X            }
  822. X            else {
  823. X                c = nodechar(n);
  824. X                if (c != '\n')
  825. X                    preptoqueue(n, pq);
  826. X                else
  827. X                    splitnode(n, pq);
  828. X                noderelease(n);
  829. X                if (c != '\n')
  830. X                    break;
  831. X            }
  832. X        }
  833. X    }
  834. X}
  835. X
  836. X
  837. X/*
  838. X * Refinement for copyout, case SUBSET: make sure that \t is balanced with \b.
  839. X * Actually it can only handle the case where a \t is in the subset and the
  840. X * matching \b is immediately following.
  841. X */
  842. X
  843. XHidden Procedure
  844. Xbalance(ep)
  845. X    environ *ep;
  846. X{
  847. X    string *rp = noderepr(tree(ep->focus));
  848. X    int i;
  849. X    int level = 0;
  850. X
  851. X    Assert(ep->mode == SUBSET);
  852. X    for (i = ep->s1/2; i*2 < ep->s2; ++i) {
  853. X        if (rp[i]) {
  854. X            if (strchr(rp[i], '\t'))
  855. X                ++level;
  856. X            else if (strchr(rp[i], '\b'))
  857. X                --level;
  858. X        }
  859. X    }
  860. X    if (level > 0 && i*2 == ep->s2 && rp[i] && strchr(rp[i], '\b'))
  861. X        ep->s2 = 2*i + 1;
  862. X}
  863. X
  864. X
  865. X/*
  866. X * Copy the copy buffer to the focus.
  867. X */
  868. X
  869. XHidden bool
  870. Xcopyin(ep, q)
  871. X    register environ *ep;
  872. X    /*auto*/ queue q;
  873. X{
  874. X    auto queue q2 = Qnil;
  875. X    bool res;
  876. X    
  877. X    if (!q) {
  878. X        ederr(COPY_EMPTY); /* Empty copy buffer */
  879. X        return No;
  880. X    }
  881. X    ep->changed = Yes;
  882. X    q = qcopy(q);
  883. X    lefttorite= Yes;
  884. X    if (!ins_queue(ep, &q, &q2)) {
  885. X        qrelease(q2);
  886. X        lefttorite= No;
  887. X        return No;
  888. X    }
  889. X    res= app_queue(ep, &q2);
  890. X    lefttorite= No;
  891. X#ifdef USERSUGG
  892. X    if (symbol(tree(ep->focus)) == Suggestion)
  893. X        killsugg(ep, (string*)NULL);
  894. X#endif
  895. X    return res;
  896. X}
  897. X
  898. X
  899. X/*
  900. X * Find out whether the focus looks like a hole or if it has some real
  901. X * text in it.
  902. X * Assumes shrink(ep) has already been performed.
  903. X */
  904. X
  905. XVisible bool
  906. Xishole(ep)
  907. X    register environ *ep;
  908. X{
  909. X    register int sym;
  910. X
  911. X    switch (ep->mode) {
  912. X    
  913. X    case ATBEGIN:
  914. X    case ATEND:
  915. X    case VHOLE:
  916. X    case FHOLE:
  917. X        return Yes;
  918. X
  919. X    case SUBLIST:
  920. X    case SUBRANGE:
  921. X        return No;
  922. X
  923. X    case SUBSET:
  924. X        return colonhack(ep, No);
  925. X
  926. X    case WHOLE:
  927. X        sym = symbol(tree(ep->focus));
  928. X        return sym == Optional || sym == Hole;
  929. X
  930. X    default:
  931. X        Abort();
  932. X        /* NOTREACHED */
  933. X    }
  934. X}
  935. X
  936. X
  937. X/*
  938. X * Amendment to ishole so that it categorizes '?: ?' as a hole.
  939. X * This makes deletion of empty refinements / alternative-suites
  940. X * easier (Steven).
  941. X * Hacked to enable deletion of sequence of hole's at outer level.
  942. X */
  943. X
  944. XHidden bool
  945. Xcolonhack(ep, all)
  946. X    environ *ep;
  947. X{
  948. X    node n = tree(ep->focus);
  949. X    node n1;
  950. X    string *rp = noderepr(n);
  951. X    int i0, ii, i;
  952. X    int sym;
  953. X    
  954. X    if (all) {
  955. X        /* hack to delete sequence of hole's on outer level */
  956. X        i0= 1; ii= 2*nchildren(n) + 1;
  957. X    }
  958. X    else {
  959. X        /* original code: */
  960. X        i0= ep->s1; ii= ep->s2;
  961. X    }
  962. X    for (i = i0; i <= ii; ++i) {
  963. X        if (i&1) {
  964. X            if (!allright(rp[i/2]))
  965. X                return No;
  966. X        }
  967. X        else {
  968. X            n1 = child(n, i/2);
  969. X            if (Is_etext(n1))
  970. X                return No;
  971. X            sym = symbol(n1);
  972. X            if (sym != Hole && sym != Optional)
  973. X                return No;
  974. X        }
  975. X    }
  976. X    return Yes;
  977. X}
  978. X
  979. X
  980. X/*
  981. X * Refinement for colonhack.  Recognize strings that are almost blank
  982. X * (i.e. containing only spaces, colons and the allowed control characters).
  983. X */
  984. X
  985. XHidden bool
  986. Xallright(repr)
  987. X    string repr;
  988. X{
  989. X    if (repr) {
  990. X        for (; *repr; ++repr) {
  991. X            if (!strchr(": \t\b\n\r", *repr))
  992. X                return No;
  993. X        }
  994. X    }
  995. X    return Yes;
  996. X}
  997. END_OF_FILE
  998.   if test 15039 -ne `wc -c <'abc/bed/e1deco.c'`; then
  999.     echo shar: \"'abc/bed/e1deco.c'\" unpacked with wrong size!
  1000.   fi
  1001.   # end of 'abc/bed/e1deco.c'
  1002. fi
  1003. if test -f 'abc/bint2/i2syn.c' -a "${1}" != "-c" ; then 
  1004.   echo shar: Will not clobber existing file \"'abc/bint2/i2syn.c'\"
  1005. else
  1006.   echo shar: Extracting \"'abc/bint2/i2syn.c'\" \(13202 characters\)
  1007.   sed "s/^X//" >'abc/bint2/i2syn.c' <<'END_OF_FILE'
  1008. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */
  1009. X
  1010. X#include "b.h"
  1011. X#include "bint.h"
  1012. X#include "feat.h"
  1013. X#include "bmem.h"
  1014. X#include "bobj.h"
  1015. X#include "b0lan.h"
  1016. X#include "i2par.h"
  1017. X#include "i3scr.h"
  1018. X#include "i3env.h"
  1019. X
  1020. X#define TABSIZE 8 /* Number of spaces assumed for a tab on a file.
  1021. X             (Some editors insist on emitting tabs wherever
  1022. X             they can, and always assume 8 spaces for a tab.
  1023. X             Even when the editor can be instructed not to
  1024. X             do this, beginning users won't know about this,
  1025. X             so we'll always assume the default tab size.
  1026. X             Advanced users who used to instruct their editor
  1027. X             to set tab stops every 4 spaces will have to
  1028. X             unlearn this habit.  But that's the price for
  1029. X             over-cleverness :-)
  1030. X             The indent increment is still 4 spaces!
  1031. X             When the B interpreter outputs text, it never uses
  1032. X             tabs but always emits 4 spaces for each indent level.
  1033. X             Note that the B editor also has a #defined constant
  1034. X             which sets the number of spaces for a tab on a file.
  1035. X             Finally the B editor *displays* indents as 3 spaces,
  1036. X             but *writes* them to the file as 4, so a neat
  1037. X             lay-out on the screen may look a bit garbled
  1038. X             when the file is printed.  Sorry.  */
  1039. X
  1040. XVisible txptr tx, ceol;
  1041. X
  1042. XVisible Procedure skipsp(tx0) txptr *tx0; {
  1043. X    while(Space(Char(*tx0))) (*tx0)++;
  1044. X}
  1045. X
  1046. X#define Keyletmark(c) \
  1047. X    (Cap(c) || Dig(c) || (c) == C_APOSTROPHE || (c) == C_QUOTE)
  1048. X
  1049. XHidden bool keymark(tx) txptr tx; {
  1050. X    if (Keyletmark(Char(tx)))
  1051. X        return Yes;
  1052. X    else if (Char(tx) == C_POINT &&
  1053. X             Keyletmark(Char(tx-1)) && Keyletmark(Char(tx+1)))
  1054. X        return Yes;
  1055. X    return No;
  1056. X}
  1057. X
  1058. X/* ******************************************************************** */
  1059. X/*        cr_text                            */
  1060. X/* ******************************************************************** */
  1061. X
  1062. XVisible value cr_text(p, q) txptr p, q; {
  1063. X    /* Messes with the input line, which is a bit nasty,
  1064. X       but considered preferable to copying to a separate buffer */
  1065. X    value t;
  1066. X    char save= Char(q);
  1067. X    Char(q)= '\0';
  1068. X    t= mk_text(p);
  1069. X    Char(q)= save;
  1070. X    return t;
  1071. X}
  1072. X
  1073. X/* ******************************************************************** */
  1074. X/*        find, findceol, req, findrel                */
  1075. X/* ******************************************************************** */
  1076. X
  1077. X#define Txnil    ((txptr) NULL)
  1078. X
  1079. XHidden bool search(find_kw, s, q, ftx, ttx) bool find_kw; string s;
  1080. X        txptr q, *ftx, *ttx; {
  1081. X    intlet parcnt= 0; bool outs= Yes, kw= No; char aq;
  1082. X    txptr lctx= Txnil;
  1083. X    
  1084. X    while (*ftx < q) {
  1085. X        if (outs) {
  1086. X            if (parcnt == 0) {
  1087. X                if (find_kw) {
  1088. X                    if (Cap(Char(*ftx)))
  1089. X                        return Yes;
  1090. X                }
  1091. X                else if (Char(*ftx) == *s) {
  1092. X                    string t= s+1;
  1093. X                    *ttx= (*ftx)+1;
  1094. X                    while (*t && *ttx < q) {
  1095. X                        if (*t != Char(*ttx)) break;
  1096. X                        else { t++; (*ttx)++; }
  1097. X                    }
  1098. X                    if (*t);
  1099. X                    else if (Cap(*s) &&
  1100. X                         (kw || keymark(*ttx) ));
  1101. X                    else return Yes;
  1102. X                }
  1103. X            }
  1104. X            switch (Char(*ftx)) {
  1105. X                case C_OPEN: 
  1106. X                case C_CUROPEN:
  1107. X                case C_SUB:
  1108. X                    parcnt++; break;
  1109. X                case C_CLOSE:
  1110. X                case C_CURCLOSE:
  1111. X                case C_BUS:    
  1112. X                    if (parcnt > 0) parcnt--; break;
  1113. X                case C_APOSTROPHE:
  1114. X                case C_QUOTE:
  1115. X                    if (lctx == Txnil || !Keytagmark(lctx)) {
  1116. X                        outs= No; aq= Char(*ftx);
  1117. X                    }
  1118. X                    break;
  1119. X                default:
  1120. X                    break;
  1121. X            }
  1122. X            lctx= *ftx;
  1123. X            if (kw)
  1124. X                kw= keymark(*ftx);
  1125. X            else
  1126. X                kw= Cap(Char(lctx));
  1127. X        }
  1128. X        else {
  1129. X            if (Char(*ftx) == aq)
  1130. X                { outs= Yes; kw= No; lctx= Txnil; }
  1131. X            else if (Char(*ftx) == C_CONVERT) {
  1132. X                (*ftx)++;
  1133. X                if (!search(No, S_CONVERT, q, ftx, ttx)) 
  1134. X                    return No;
  1135. X            }
  1136. X        }
  1137. X        (*ftx)++;
  1138. X    }
  1139. X    return No;
  1140. X}
  1141. X
  1142. X/* ********************************************************************    */
  1143. X
  1144. XVisible bool find(s, q, ftx, ttx) string s; txptr q, *ftx, *ttx; {
  1145. X    return search(No, s, q, (*ftx= tx, ftx), ttx);
  1146. X}
  1147. X
  1148. XForward txptr lcol();
  1149. X
  1150. XVisible Procedure findceol() {
  1151. X    txptr q= lcol(), ttx;
  1152. X    if (!find(S_COMMENT, q, &ceol, &ttx)) ceol= q;
  1153. X}
  1154. X
  1155. XVisible Procedure req(s, q, ftx, ttx) string s; txptr q, *ftx, *ttx; {
  1156. X    if (!find(s, q, ftx, ttx)) {
  1157. X        value v= mk_text(s);
  1158. X        parerrV(MESS(2400, "cannot find expected %s"), v);
  1159. X        release(v);
  1160. X        *ftx= tx; *ttx= q;
  1161. X    }
  1162. X}
  1163. X
  1164. XHidden bool relsearch(s, q, ftx) string s; txptr q, *ftx; {
  1165. X    txptr ttx;
  1166. X    *ftx= tx;
  1167. X    while (search(No, s, q, ftx, &ttx))
  1168. X        switch (Char(*ftx)) {
  1169. X            case C_LESS:
  1170. X                if (Char(*ftx+1) == C_LESS)
  1171. X                    *ftx= ++ttx;
  1172. X                else if (Char((*ftx)-1) == C_GREATER) 
  1173. X                    *ftx= ttx;
  1174. X                else return Yes;
  1175. X                break;
  1176. X            case C_GREATER:
  1177. X                if (Char((*ftx)+1) == C_LESS) 
  1178. X                    *ftx= ++ttx;
  1179. X                else if (Char((*ftx)+1) == C_GREATER) 
  1180. X                    *ftx= ++ttx;
  1181. X                else return Yes;
  1182. X                break;
  1183. X            case C_EQUAL:
  1184. X                return Yes;
  1185. X            default:
  1186. X                return No;
  1187. X        }
  1188. X    return No;
  1189. X}
  1190. X
  1191. XVisible bool findrel(q, ftx) txptr q, *ftx; {
  1192. X    txptr ttx;
  1193. X    *ftx= q;
  1194. X    if (relsearch(S_LESS, *ftx, &ttx)) *ftx= ttx;
  1195. X    if (relsearch(S_GREATER, *ftx, &ttx)) *ftx= ttx;
  1196. X    if (relsearch(S_EQUAL, *ftx, &ttx)) *ftx= ttx;
  1197. X    return *ftx < q;
  1198. X}
  1199. X
  1200. XVisible bool findtrim(q, first) txptr q, *first; {
  1201. X    txptr ftx, ttx;
  1202. X    *first= q;
  1203. X    if (find(S_BEHEAD, *first, &ftx, &ttx)) *first= ftx;
  1204. X    if (find(S_CURTAIL, *first, &ftx, &ttx)) *first= ftx;
  1205. X    return *first < q;
  1206. X}
  1207. X
  1208. X/* ******************************************************************** */
  1209. X/*        tag, keyword, findkw                    */
  1210. X/* ******************************************************************** */
  1211. X
  1212. XHidden value tag() {
  1213. X    txptr tx0= tx;
  1214. X    if (!Letter(Char(tx))) parerr(MESS(2401, "no name where expected"));
  1215. X    else while (Tagmark(tx)) tx++;
  1216. X    return cr_text(tx0, tx);
  1217. X}
  1218. X
  1219. XVisible bool is_tag(v) value *v; {
  1220. X    if (!Letter(Char(tx))) return No;
  1221. X    *v= tag();
  1222. X    return Yes;
  1223. X}
  1224. X
  1225. XVisible bool is_abcname(name) value name; {
  1226. X    string s= strval(name);
  1227. X    
  1228. X    if (!Letter(*s))
  1229. X        return No;
  1230. X    for (; *s != '\0'; ++s) {
  1231. X        if (!Tagmark(s))
  1232. X            return No;
  1233. X    }
  1234. X    return Yes;
  1235. X}
  1236. X
  1237. XVisible char *keyword() {
  1238. X    txptr tx0= tx;
  1239. X    static char *kwbuf;
  1240. X    int len;
  1241. X
  1242. X    if (!Cap(Char(tx))) parerr(MESS(2402, "no keyword where expected"));
  1243. X    else while (keymark(tx)) tx++;
  1244. X    len= tx-tx0;
  1245. X    if (kwbuf) freemem((ptr) kwbuf);
  1246. X    kwbuf= (char *) getmem((unsigned) (len+1));
  1247. X    strncpy(kwbuf, tx0, len);
  1248. X    kwbuf[len]= '\0';
  1249. X    return kwbuf;
  1250. X}
  1251. X
  1252. XVisible bool is_keyword(kw) char **kw; {
  1253. X    if (!Cap(Char(tx))) return No;
  1254. X    *kw= keyword();
  1255. X    return Yes;
  1256. X}
  1257. X
  1258. XVisible bool is_cmdname(q, name) txptr q; char **name; {
  1259. X    static char *cmdbuf;
  1260. X    char *kw;
  1261. X    int len;
  1262. X
  1263. X    if (!is_keyword(&kw)) return No;
  1264. X    if (cmdbuf) freemem((ptr) cmdbuf);
  1265. X    cmdbuf= (char *) savestr(kw);
  1266. X    if (!spec_firstkeyword(kw)) {
  1267. X        while (NEXT_keyword(q, &kw)) {
  1268. X            len= strlen(cmdbuf) + 1 + strlen(kw);
  1269. X            regetmem((ptr *) &cmdbuf, (unsigned) (len+1));
  1270. X            strcat(cmdbuf, " ");
  1271. X            strcat(cmdbuf, kw);
  1272. X        }
  1273. X    }
  1274. X    *name= cmdbuf;
  1275. X    return Yes;
  1276. X}
  1277. X
  1278. X/* only those immediately following the FIRST keyword */
  1279. X
  1280. XHidden bool NEXT_keyword(q, kw) txptr q; char **kw; {
  1281. X    txptr ftx;
  1282. X    skipsp(&tx);
  1283. X    if (!findkw(q, &ftx))
  1284. X        return No;
  1285. X    if (Text(ftx)) /* there is a parameter */
  1286. X        return No;
  1287. X    return is_keyword(kw);
  1288. X}
  1289. X
  1290. X/* The reserved keywords that a user command may not begin with:
  1291. X * e.g. HOW TO HOW ARE YOU isn't allowed
  1292. X */
  1293. X
  1294. XHidden char *firstkw[] = {
  1295. X    K_IF, K_WHILE, K_CHECK, K_HOW, K_RETURN, K_REPORT,
  1296. X    ""
  1297. X};
  1298. X
  1299. XHidden bool spec_firstkeyword(fkw) char *fkw; {
  1300. X    char **kw;
  1301. X    for (kw= firstkw; **kw != '\0'; kw++) {
  1302. X        if (strcmp(fkw, *kw) == 0)
  1303. X            return Yes;
  1304. X    }
  1305. X    return No;
  1306. X}
  1307. X
  1308. XVisible bool findkw(q, ftx) txptr q, *ftx; {
  1309. X    txptr ttx;
  1310. X    *ftx= tx;
  1311. X    return search(Yes, "", q, ftx, &ttx);
  1312. X}
  1313. X
  1314. X/* ******************************************************************** */
  1315. X/*        upto, nothing, ateol, need                */
  1316. X/* ******************************************************************** */
  1317. X
  1318. XVisible Procedure upto(q, s) txptr q; string s; {
  1319. X    skipsp(&tx);
  1320. X    if (Text(q)) {
  1321. X        value v= mk_text(s);
  1322. X        parerrV(MESS(2403, "something unexpected following %s"), v);
  1323. X        release(v);
  1324. X        tx= q;
  1325. X    }
  1326. X}
  1327. X
  1328. XVisible Procedure upto1(q, m) txptr q; int m; {
  1329. X    skipsp(&tx);
  1330. X    if (Text(q)) {
  1331. X        parerr(m);
  1332. X        tx= q;
  1333. X    }
  1334. X}
  1335. X
  1336. XVisible bool nothing(q, m) txptr q; int m; {
  1337. X    if (!Text(q)) {
  1338. X        if (Char(tx-1) == ' ') tx--;
  1339. X        parerr(m);
  1340. X        return Yes;
  1341. X    }
  1342. X    return No;
  1343. X}
  1344. X
  1345. XVisible bool i_looked_ahead= No;
  1346. XHidden  bool o_looked_ahead= No;
  1347. X
  1348. XVisible intlet cur_ilev;
  1349. X
  1350. XVisible bool ateol() {
  1351. X    if ((ifile == sv_ifile && i_looked_ahead)
  1352. X        || (ifile != sv_ifile && o_looked_ahead)) return Yes;
  1353. X    skipsp(&tx);
  1354. X    return Eol(tx);
  1355. X}
  1356. X
  1357. XVisible Procedure need(s) string s; {
  1358. X    string t= s;
  1359. X    skipsp(&tx);
  1360. X    while (*t)
  1361. X        if (*t++ != Char(tx++)) {
  1362. X            value v= mk_text(s);
  1363. X            tx--;
  1364. X        parerrV(MESS(2404, "according to the syntax I expected %s"), v);
  1365. X            release(v);
  1366. X            return;
  1367. X        }
  1368. X}
  1369. X
  1370. X/* ******************************************************************** */
  1371. X/*        buffer handling                        */
  1372. X/* ******************************************************************** */
  1373. X
  1374. XVisible txptr first_col;
  1375. X
  1376. XVisible txptr fcol() { /* the first position of the current line */
  1377. X    return first_col;
  1378. X}
  1379. X
  1380. XHidden txptr lcol() { /* the position beyond the last character of the line */
  1381. X    txptr ax= tx;
  1382. X    while (!Eol(ax)) ax++;
  1383. X    return ax;
  1384. X}
  1385. X
  1386. XVisible intlet ilev() {
  1387. X    intlet i;
  1388. X    if (ifile == sv_ifile && i_looked_ahead) {
  1389. X        if (!interactive && ifile == sv_ifile) 
  1390. X            f_lino++;
  1391. X        i_looked_ahead= No;
  1392. X        return cur_ilev;
  1393. X    }
  1394. X    else if (ifile != sv_ifile && o_looked_ahead) {
  1395. X        o_looked_ahead= No;
  1396. X        return cur_ilev;
  1397. X    }
  1398. X    else {
  1399. X        first_col= tx= getline();
  1400. X        if (ifile == sv_ifile)
  1401. X            i_looked_ahead= No;
  1402. X        else
  1403. X            o_looked_ahead= No;
  1404. X        lino++;
  1405. X        if (!interactive && ifile == sv_ifile)
  1406. X            f_lino++;
  1407. X        i= 0;
  1408. X        while (Space(Char(tx))) {
  1409. X            if (Char(tx++) == ' ') i++;
  1410. X            else i= (i/TABSIZE+1)*TABSIZE;
  1411. X        }
  1412. X        if (Char(tx) == C_COMMENT) return cur_ilev= 0;
  1413. X        if (Char(tx) == '\n') return cur_ilev= 0;
  1414. X        return cur_ilev= i;
  1415. X    }
  1416. X}
  1417. X
  1418. XVisible Procedure veli() { /* After a look-ahead call of ilev */
  1419. X    if (!interactive && ifile == sv_ifile)
  1420. X        f_lino--;
  1421. X    if (ifile == sv_ifile)
  1422. X        i_looked_ahead= Yes;
  1423. X    else
  1424. X        o_looked_ahead= Yes;
  1425. X}
  1426. X
  1427. XVisible Procedure first_ilev() { /* initialise read buffer for new input */
  1428. X    o_looked_ahead= No;
  1429. X    VOID ilev();
  1430. X    findceol();
  1431. X}
  1432. X
  1433. X/* ********************************************************************    */
  1434. X
  1435. XVisible value res_cmdnames;
  1436. X
  1437. X/* The reserved command names;
  1438. X * e.g. HOW TO PUT IN x is allowed, but HOW TO PUT x OUT isn't
  1439. X */
  1440. X
  1441. XHidden string reserved[] = {
  1442. X    K_SHARE, K_CHECK, K_DELETE, K_FAIL, K_FOR,
  1443. X    K_HOW, K_IF, K_INSERT, K_PASS, K_PUT, K_QUIT, K_READ, K_REMOVE,
  1444. X    K_REPORT, K_RETURN, K_SELECT, K_SETRANDOM, K_SUCCEED,
  1445. X    K_WHILE, K_WRITE,
  1446. X#ifdef GFX
  1447. X    K_SPACEFROM, K_LINEFROM, K_CLEARSCREEN,
  1448. X#endif
  1449. X    ""
  1450. X};
  1451. X
  1452. XVisible Procedure initsyn() {
  1453. X    value v;
  1454. X    string *kw;
  1455. X    
  1456. X    res_cmdnames= mk_elt();
  1457. X    for (kw= reserved; **kw != '\0'; kw++) {
  1458. X        insert(v= mk_text(*kw), &res_cmdnames);
  1459. X        release(v);
  1460. X    }
  1461. X}
  1462. X
  1463. XVisible Procedure endsyn() {
  1464. X    release(res_cmdnames); res_cmdnames= Vnil;
  1465. X}
  1466. X
  1467. X/* ******************************************************************** */
  1468. X/*        signs                            */
  1469. X/* ********************************************************************    */
  1470. X
  1471. XHidden bool la_denum(tx0) txptr tx0; {
  1472. X    char l, r;
  1473. X    switch (l= Char(++tx0)) {
  1474. X        case C_OVER:    r= C_TIMES; break;
  1475. X        case C_TIMES:    r= C_OVER; break;
  1476. X        default:    return Yes;
  1477. X    }
  1478. X    do if (Char(++tx0) != r) return No; while (Char(++tx0) == l);
  1479. X    return Yes;
  1480. X}
  1481. X
  1482. XVisible bool _nwl_sign() {
  1483. X    if (_sign_is(C_NEWLINE))
  1484. X        return !la_denum(tx-2) ? Yes : (tx--, No);
  1485. X    return No;
  1486. X}
  1487. X
  1488. XVisible bool _times_sign() {
  1489. X    if (_sign_is(C_TIMES))
  1490. X        return la_denum(tx-1) ? Yes : (tx--, No);
  1491. X    return No;
  1492. X}
  1493. X
  1494. XVisible bool _over_sign() {
  1495. X    if (_sign_is(C_OVER))
  1496. X        return la_denum(tx-1) ? Yes : (tx--, No);
  1497. X    return No;
  1498. X}
  1499. X
  1500. XVisible bool _power_sign() {
  1501. X    if (_sign2_is(S_POWER))
  1502. X        return la_denum(tx-1) ? Yes : (tx-= 2, No);
  1503. X    return No;
  1504. X}
  1505. X
  1506. XVisible bool _numtor_sign() {
  1507. X    if (_sign2_is(S_NUMERATOR))
  1508. X        return la_denum(tx-1) ? Yes : (tx-= 2, No);
  1509. X    return No;
  1510. X}
  1511. X
  1512. XVisible bool _denomtor_sign() {
  1513. X    if (_sign2_is(S_DENOMINATOR))
  1514. X        return la_denum(tx-1) ? Yes : (tx-= 2, No);
  1515. X    return No;
  1516. X}
  1517. X
  1518. XVisible bool _join_sign() {
  1519. X    if (_sign_is(C_JOIN))
  1520. X        return !_sign_is(C_JOIN) ? Yes : (tx-= 2, No);
  1521. X    return No;
  1522. X}
  1523. X
  1524. XVisible bool _less_than_sign() {
  1525. X    if (_sign_is(C_LESS))
  1526. X        return !_sign_is(C_LESS) && !_sign_is(C_EQUAL)
  1527. X            && !_sign_is(C_GREATER) ? Yes : (tx--, No);
  1528. X    return No;
  1529. X}
  1530. X
  1531. XVisible bool _greater_than_sign() {
  1532. X    if (_sign_is(C_GREATER))
  1533. X        return !_sign_is(C_LESS) && !_sign_is(C_EQUAL)
  1534. X            && !_sign_is(C_GREATER)  ? Yes : (tx--, No);
  1535. X    return No;
  1536. X}
  1537. X
  1538. XVisible bool dyamon_sign(v) value *v; {
  1539. X    string s;
  1540. X    if (plus_sign) s= S_PLUS;
  1541. X    else if (minus_sign) s= S_MINUS;
  1542. X    else if (number_sign) s= S_NUMBER;
  1543. X    else return No;
  1544. X    *v= mk_text(s);
  1545. X    return Yes;
  1546. X}
  1547. X
  1548. XVisible bool dya_sign(v) value *v; {
  1549. X    string s;
  1550. X    if (times_sign) s= S_TIMES;
  1551. X    else if (over_sign) s= S_OVER;
  1552. X    else if (power_sign) s= S_POWER;
  1553. X    else if (behead_sign) s= S_BEHEAD;
  1554. X    else if (curtl_sign) s= S_CURTAIL;
  1555. X    else if (join_sign) s= S_JOIN;
  1556. X    else if (reptext_sign) s= S_REPEAT;
  1557. X    else if (leftadj_sign) s= S_LEFT_ADJUST;
  1558. X    else if (center_sign) s= S_CENTER;
  1559. X    else if (rightadj_sign) s= S_RIGHT_ADJUST;
  1560. X    else return No;
  1561. X    *v= mk_text(s);
  1562. X    return Yes;
  1563. X}
  1564. X
  1565. XVisible bool mon_sign(v) value *v; {
  1566. X    string s;
  1567. X    if (about_sign) s= S_ABOUT;
  1568. X    else if (numtor_sign) s= S_NUMERATOR;
  1569. X    else if (denomtor_sign) s= S_DENOMINATOR;
  1570. X    else return No;
  1571. X    *v= mk_text(s);
  1572. X    return Yes;
  1573. X}
  1574. X
  1575. XVisible bool texdis_sign(v) value *v; {
  1576. X    string s;
  1577. X    if (apostrophe_sign) s= S_APOSTROPHE;
  1578. X    else if (quote_sign) s= S_QUOTE;
  1579. X    else return No;
  1580. X    *v= mk_text(s);
  1581. X    return Yes;
  1582. X}
  1583. END_OF_FILE
  1584.   if test 13202 -ne `wc -c <'abc/bint2/i2syn.c'`; then
  1585.     echo shar: \"'abc/bint2/i2syn.c'\" unpacked with wrong size!
  1586.   fi
  1587.   # end of 'abc/bint2/i2syn.c'
  1588. fi
  1589. if test -f 'abc/boot/read.c' -a "${1}" != "-c" ; then 
  1590.   echo shar: Will not clobber existing file \"'abc/boot/read.c'\"
  1591. else
  1592.   echo shar: Extracting \"'abc/boot/read.c'\" \(13315 characters\)
  1593.   sed "s/^X//" >'abc/boot/read.c' <<'END_OF_FILE'
  1594. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1988. */
  1595. X
  1596. X/*
  1597. X * read grammar from file into tables.
  1598. X *
  1599. X * There's a little parser here, to read the grammar from the file.
  1600. X * See the file "grammar.abc" for the possible formats.
  1601. X *
  1602. X * We use namelist[] to store all names. At the end of the reading process
  1603. X * the cross-references between classdef[] and symdef[] will be in terms
  1604. X * of indices in namelist[]. In fill.c they will be replaced by indices
  1605. X * directly into the other one.
  1606. X * This organisation is necessary to keep the order of the Symbol-definitions
  1607. X * the same as in the input file.
  1608. X *
  1609. X * Definitions for "Suggestion", "Sugghowname", "Optional" and "Hole" are
  1610. X * added at the end; see comment below.
  1611. X */
  1612. X
  1613. X#include "b.h"
  1614. X#include "main.h"
  1615. X
  1616. X#define COMMENT '#' /* Not ABC-like but very UNIX-like, and we used cpp ... */
  1617. X#define QUOTE '"'
  1618. X
  1619. XHidden char nextc; /* Next character to be analyzed */
  1620. XHidden bool eof; /* EOF seen? */
  1621. XHidden int lcount; /* Current line number */
  1622. XHidden int errcount; /* Number of errors detected */
  1623. X
  1624. XHidden string dname= NULL; /* name currently being defined (at linestart) */
  1625. X/* VARARGS 1 */
  1626. XHidden Procedure error(format, arg1, arg2, arg3, arg4, arg5)
  1627. X    char *format;
  1628. X    char *arg1, *arg2, *arg3, *arg4, *arg5;
  1629. X{
  1630. X    fprintf(stderr, 
  1631. X        "%s: error in grammar file %s, line %d, defining name %s\n\t",
  1632. X        progname, gfile, lcount, (dname==NULL ? "???" : dname));
  1633. X    fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5);
  1634. X    putc('\n', stderr);
  1635. X    errcount++;
  1636. X}
  1637. X
  1638. XVisible Procedure read_grammar_into_tables() {
  1639. X    errcount= 0;
  1640. X    lcount= 1;
  1641. X    eof= No;
  1642. X    do {
  1643. X        adv();
  1644. X        skipspace();
  1645. X        if (nextc != COMMENT && nextc != '\n')
  1646. X            getdefinition();
  1647. X        while (nextc != '\n')
  1648. X            adv();
  1649. X        lcount++;
  1650. X    } while (!eof);
  1651. X    
  1652. X    if (errcount > 0) {
  1653. X        fatal("You 'd better fix that grammar description first");
  1654. X    }
  1655. X    
  1656. X    add_special_definitions();
  1657. X}
  1658. X
  1659. XHidden Procedure adv()
  1660. X{
  1661. X    int c;
  1662. X
  1663. X    if (eof)
  1664. X        return;
  1665. X    c= getc(gfp);
  1666. X    if (c == EOF) {
  1667. X        nextc= '\n';
  1668. X        eof= Yes;
  1669. X    }
  1670. X    else {
  1671. X        nextc= c;
  1672. X    }
  1673. X}
  1674. X
  1675. XHidden Procedure skipspace()
  1676. X{
  1677. X    while (nextc == ' ' || nextc == '\t')
  1678. X        adv();
  1679. X}
  1680. X
  1681. XHidden Procedure skipwhite()
  1682. X{
  1683. X    while (nextc == ' ' || nextc == '\t' || nextc == '\n') {
  1684. X        if (nextc == '\n')
  1685. X            lcount++;
  1686. X        adv();
  1687. X    }
  1688. X}
  1689. X
  1690. XHidden Procedure skipdef()    /* to synchronize after error in def */
  1691. X{                /* assumes at least points are allright */
  1692. X    while (nextc != '.') {
  1693. X        adv();
  1694. X    }
  1695. X}
  1696. X
  1697. XHidden Procedure skipstring()    /* idem for string, must end with '"' */
  1698. X{
  1699. X    while (nextc != '\"') {
  1700. X        adv();
  1701. X    }
  1702. X}
  1703. X
  1704. XHidden string getname() {
  1705. X    char buffer[NAMELEN];
  1706. X    string bp;
  1707. X    
  1708. X    if (!isascii(nextc) || !isalpha(nextc)) {
  1709. X        if (!isascii(nextc) || (!isprint(nextc) && nextc != ' '))
  1710. X            sprintf(buffer, "\\%03o", nextc);
  1711. X        else
  1712. X            sprintf(buffer, "'%c'", nextc);
  1713. X        error("illegal character at start of name: %s", buffer);
  1714. X        return NULL;
  1715. X    }
  1716. X    bp= buffer;
  1717. X    *bp++= nextc;
  1718. X    adv();
  1719. X    while (isascii(nextc)
  1720. X        &&
  1721. X           (isalnum(nextc) || nextc == '_')
  1722. X          ) {
  1723. X        if (bp < buffer + sizeof buffer - 1)
  1724. X            *bp++= nextc;
  1725. X        adv();
  1726. X    }
  1727. X    *bp= '\0';
  1728. X    return savestr((string)buffer);
  1729. X}
  1730. X
  1731. XHidden string getstring()
  1732. X{
  1733. X    char buf[STRINGLEN]; /* Arbitrary limit */
  1734. X    char c;
  1735. X    int len= 0;
  1736. X
  1737. X    if (nextc != QUOTE) {
  1738. X        return NULL;
  1739. X    }
  1740. X    adv();
  1741. X    while (nextc != QUOTE) {
  1742. X        if (nextc == '\n') {
  1743. X            error("end of line in string");
  1744. X            skipstring();
  1745. X            break;
  1746. X        }
  1747. X        if (nextc != '\\') {
  1748. X            c= nextc;
  1749. X            adv();
  1750. X        }
  1751. X        else {
  1752. X            adv();
  1753. X            switch (nextc) {
  1754. X
  1755. X            case 'r': c= '\r'; adv(); break;
  1756. X            case 'n': c= '\n'; adv(); break;
  1757. X            case 'b': c= '\b'; adv(); break;
  1758. X            case 't': c= '\t'; adv(); break;
  1759. X            case 'f': c= '\f'; adv(); break;
  1760. X            case 'v': c= '\v'; adv(); break;
  1761. X            /* '\\', '\'' and '\"' handled by default below */
  1762. X
  1763. X            case '0': case '1': case '2': case '3':
  1764. X            case '4': case '5': case '6': case '7':
  1765. X                c= nextc-'0';
  1766. X                adv();
  1767. X                if (nextc >= '0' && nextc < '8') {
  1768. X                    c= 8*c + nextc-'0';
  1769. X                    adv();
  1770. X                    if (nextc >= '0' && nextc < '8') {
  1771. X                        c= 8*c + nextc-'0';
  1772. X                        adv();
  1773. X                    }
  1774. X                }
  1775. X                break;
  1776. X
  1777. X            default: c=nextc; adv(); break;
  1778. X
  1779. X            }
  1780. X        }
  1781. X        if (len >= (sizeof(buf)-1)) {
  1782. X            error("string too long");
  1783. X            skipstring();
  1784. X            len= sizeof(buf)-1;
  1785. X            break;
  1786. X        }
  1787. X        buf[len++]= c;
  1788. X    }
  1789. X    adv();
  1790. X    buf[len]= '\0';
  1791. X    return savestr((string)buf);
  1792. X}
  1793. X
  1794. XHidden Procedure storename(name, pi, pt) string name; item *pi; char *pt; {
  1795. X    int iname;
  1796. X    struct nameinfo *pname;
  1797. X    char *pc;
  1798. X    char type;
  1799. X    
  1800. X    for (iname= 0; iname < nname; iname++) {
  1801. X        pname= &namelist[iname];
  1802. X        if (strcmp(name, pname->n_name) == 0) {
  1803. X            /* stored already */
  1804. X            *pi= (item) iname;
  1805. X            *pt= pname->n_type;
  1806. X            return;
  1807. X        }
  1808. X    }
  1809. X    /* not stored yet; reserve entry and check type */
  1810. X    Assert(nname < maxname);
  1811. X    type= Errtype;
  1812. X    if (isupper(name[0]) && isupper(name[1])) {
  1813. X        for (pc= &name[2]; *pc != '\0'; pc++)
  1814. X            if (isalpha(*pc) && !isupper(*pc))
  1815. X                break;
  1816. X        if (*pc == '\0')
  1817. X            type= Lex;
  1818. X    }
  1819. X    if (isupper(name[0]) && islower(name[1])) {
  1820. X        for (pc= &name[2]; *pc != '\0'; pc++)
  1821. X            if (isalpha(*pc) && !islower(*pc))
  1822. X                break;
  1823. X        if (*pc == '\0')
  1824. X            type= Sym;
  1825. X    }
  1826. X    if (islower(name[0])) {
  1827. X        for (pc= &name[1]; *pc != '\0'; pc++)
  1828. X            if (isalpha(*pc) && !islower(*pc))
  1829. X                break;
  1830. X        if (*pc == '\0')
  1831. X            type= Class;
  1832. X    }
  1833. X    *pt= type;
  1834. X    if (type == Errtype)
  1835. X        error("cannot determine type of name '%s'", name);
  1836. X    pname= &namelist[nname];
  1837. X    pname->n_name= name;
  1838. X    pname->n_type= type;
  1839. X    pname->n_index= Nilitem;    /* filled in iff definition found */
  1840. X    *pi= (item) nname;
  1841. X    nname++;
  1842. X}
  1843. X
  1844. XHidden Procedure getdefinition()
  1845. X{
  1846. X    string defname;
  1847. X    item defitem;
  1848. X    char deftype;
  1849. X    
  1850. X    defname= getname();
  1851. X    if (defname == NULL)
  1852. X        return;
  1853. X    dname= defname;
  1854. X    
  1855. X    storename(defname, &defitem, &deftype);
  1856. X    
  1857. X    skipwhite();
  1858. X    if (nextc != ':') {
  1859. X        error("defined name not followed by ':'");
  1860. X        dname= NULL;
  1861. X        return;
  1862. X    }
  1863. X    adv();
  1864. X    skipwhite();
  1865. X    
  1866. X    switch (deftype) {
  1867. X    case Class:
  1868. X        getclassdef(defname, defitem);
  1869. X        break;
  1870. X    case Sym:
  1871. X        getsymdef(defname, defitem);
  1872. X        break;
  1873. X    case Lex:
  1874. X        getlexdef(defname, defitem);
  1875. X        break;
  1876. X    case Errtype:
  1877. X    default:
  1878. X        error("skipping definition");
  1879. X        break;
  1880. X    }
  1881. X    
  1882. X    dname= NULL;
  1883. X}
  1884. X
  1885. XHidden Procedure getclassdef(defname, defitem) string defname; item defitem; {
  1886. X    int iclass;
  1887. X    string sname;
  1888. X    item sitem;
  1889. X    char stype;
  1890. X    item symarray[SYMLEN];
  1891. X    int s;
  1892. X    
  1893. X    iclass= nclass++;
  1894. X    namelist[defitem].n_index= iclass;
  1895. X    classdef[iclass].c_name= defname;
  1896. X    
  1897. X    for (s= 0; s < SYMLEN-1; s++) {
  1898. X        sname= getname(); 
  1899. X        if (sname == NULL) {
  1900. X            error("giving up this definition");
  1901. X            skipdef();
  1902. X            break;
  1903. X        }
  1904. X        storename(sname, &sitem, &stype);
  1905. X        if (stype == Sym || stype == Lex) {
  1906. X            symarray[s]= sitem;
  1907. X        }
  1908. X        else if (stype == Class) {
  1909. X            error("class '%s' used in class definition", sname);
  1910. X        }
  1911. X        
  1912. X        skipwhite();
  1913. X        if (nextc == '.') {
  1914. X            break;
  1915. X        }
  1916. X        else if (nextc != ';') {
  1917. X            error("missing ';'");
  1918. X        }
  1919. X        else {
  1920. X            adv();
  1921. X        }
  1922. X        skipwhite();
  1923. X    }
  1924. X    if (s == SYMLEN-1 && nextc != '.') {
  1925. X error("too many alternatives in rule; skipping tail of definition");
  1926. X         skipdef();
  1927. X    }
  1928. X    else {
  1929. X        s++;
  1930. X    }
  1931. X    adv();    /* skip '.' */
  1932. X    symarray[s]= Nilitem;
  1933. X    classdef[iclass].c_syms= savearray(symarray, s+1);
  1934. X    classdef[iclass].c_insert= NULL;
  1935. X    classdef[iclass].c_append= NULL;
  1936. X    classdef[iclass].c_join= NULL;
  1937. X}
  1938. X
  1939. XHidden Procedure getsymdef(defname, defitem) string defname; item defitem; {
  1940. X    int isym;
  1941. X    struct syminfo *psym;
  1942. X    string str;
  1943. X    string cname;
  1944. X    item citem;
  1945. X    char ctype;
  1946. X    int ich;
  1947. X    
  1948. X    isym= nsym++;
  1949. X    namelist[defitem].n_index= isym;
  1950. X    
  1951. X    psym= &symdef[isym];
  1952. X    psym->s_name= defname;
  1953. X    
  1954. X    for (ich= 0; ich <= MAXCHILD; ich++) {
  1955. X        str= getstring();
  1956. X        psym->s_repr[ich]= str;
  1957. X        
  1958. X        if (str != NULL) {
  1959. X            skipwhite();
  1960. X            if (nextc == '.')
  1961. X                break;    /* for ich */
  1962. X            else if (nextc == ',') {
  1963. X                adv();
  1964. X                skipwhite();
  1965. X            }
  1966. X            else {
  1967. X                error("missing ','");
  1968. X            }
  1969. X        }
  1970. X        
  1971. X        if (ich == MAXCHILD) {
  1972. X            error("too many children in Symbol definition");
  1973. X            skipdef();
  1974. X            break;
  1975. X        }
  1976. X        
  1977. X        cname= getname(); 
  1978. X        if (cname == NULL) {
  1979. X            error("missing class name");
  1980. X            skipdef();
  1981. X            break;
  1982. X        }
  1983. X        storename(cname, &citem, &ctype);
  1984. X        if (ctype == Class || ctype == Lex) {
  1985. X            psym->s_class[ich]= citem;
  1986. X        }
  1987. X        else if (ctype == Sym) {
  1988. X            error("Symbol '%s' used in Symbol definition", cname);
  1989. X        }
  1990. X        
  1991. X        skipwhite();
  1992. X        if (nextc == '.') {
  1993. X            /* ich < MAXCHILD */
  1994. X            ich++;
  1995. X            psym->s_repr[ich]= NULL;
  1996. X            break;
  1997. X        }
  1998. X        else if (nextc != ',') {
  1999. X            error("missing ','");
  2000. X        }
  2001. X        else {
  2002. X            adv();
  2003. X            skipwhite();
  2004. X        }
  2005. X    }
  2006. X    
  2007. X    if (nextc == '.') {
  2008. X        adv();
  2009. X    }
  2010. X    while (ich < MAXCHILD) {
  2011. X        psym->s_class[ich]= Nilitem;
  2012. X        ich++;
  2013. X        psym->s_repr[ich]= NULL;
  2014. X    }
  2015. X}
  2016. X
  2017. XHidden item nilarray[]= {Nilitem, Nilitem};
  2018. X
  2019. XForward string bodyname();
  2020. X
  2021. XHidden Procedure getlexdef(defname, defitem) string defname; item defitem; {
  2022. X    int ilex;
  2023. X    struct lexinfo *plex;
  2024. X    string str1;
  2025. X    string str2;
  2026. X    struct classinfo *pclass;
  2027. X    struct syminfo *psym;
  2028. X    int ich;
  2029. X
  2030. X    ilex= nlex++;
  2031. X    namelist[defitem].n_index= ilex;
  2032. X    
  2033. X    plex= &lexdef[ilex];
  2034. X    plex->l_name= defname;
  2035. X    
  2036. X    str1= getstring();
  2037. X    if (str1 == NULL) {
  2038. X        error("no string of start chars in lexical definition");
  2039. X        skipdef();
  2040. X        return;
  2041. X    }
  2042. X    plex->l_start= str1;
  2043. X    skipwhite();
  2044. X    if (nextc != ',') {
  2045. X        error("missing ',' between start and continuation string");
  2046. X    }
  2047. X    else {
  2048. X        adv();
  2049. X        skipwhite();
  2050. X    }
  2051. X    str2= getstring();
  2052. X    if (str2 == NULL) {
  2053. X        error("no string of continuation chars in lexical definition");
  2054. X        skipdef();
  2055. X        return;
  2056. X    }
  2057. X    plex->l_cont= str2;
  2058. X    skipwhite();
  2059. X    if (nextc != '.') {
  2060. X        error("missing '.' after lexical definition");
  2061. X    }
  2062. X    else {
  2063. X        adv();
  2064. X    }
  2065. X    /* And now the tricky part:
  2066. X     * the lexical will be enveloped in the following definitions:
  2067. X     *    l_body: LEXICAL.
  2068. X     *    L_sym: l_body.
  2069. X     *    l_class: L_sym.
  2070. X     * Wherever the lexical is used in a class or symbol definition
  2071. X     * the latter two definitions will be used.
  2072. X     * The first is only referenced indirectly.
  2073. X     * Even Guido forgot why this was necessary for the ABC editor.
  2074. X     *
  2075. X     * Here we only reserve the space, and keep the indexes.
  2076. X     * The names must be converted into legal C identifiers
  2077. X     * differing from the original one. (they will show up
  2078. X     * in a generated headerfile as debugging info).
  2079. X     * The definitions must be filled with Nil's to prevent them
  2080. X     * from being interpreted as namelist-indices in the replacement
  2081. X     * process in fill.c. There the correct definitions will be filled in.
  2082. X     *
  2083. X     * For "SUGGESTION" we only do the first step; an entry for
  2084. X     *    Suggestion: suggestion_body.
  2085. X     * will be added below in add_special_definitions().
  2086. X     * Idem for "SUGGHOWNAME".
  2087. X     */
  2088. X    pclass= &classdef[nclass];
  2089. X    pclass->c_name= bodyname(defname);
  2090. X    pclass->c_syms= savearray(nilarray, 2);
  2091. X    pclass->c_insert= NULL;
  2092. X    pclass->c_append= NULL;
  2093. X    pclass->c_join= NULL;
  2094. X    plex->l_body= nclass++;
  2095. X    
  2096. X    if (strcmp(defname, "SUGGESTION") == 0) {
  2097. X        lsuggestion= ilex;    /* later needed for filling in */
  2098. X        nsuggstnbody= nclass-1;    /* also used to check presence */
  2099. X        return;
  2100. X    }
  2101. X    if (strcmp(defname, "SUGGHOWNAME") == 0) {
  2102. X        lsugghowname= ilex;    /* later needed for filling in */
  2103. X        nsugghowbody= nclass-1;    /* also used to check presence */
  2104. X        return;
  2105. X    }
  2106. X    
  2107. X    psym= &symdef[nsym];
  2108. X    psym->s_name= savestr(defname);
  2109. X    symname(psym->s_name);
  2110. X    for (ich= 0; ; ich++) {
  2111. X        psym->s_repr[ich]= NULL;
  2112. X        if (ich == MAXCHILD)
  2113. X            break;
  2114. X        psym->s_class[ich]= Nilitem;
  2115. X    }
  2116. X    plex->l_sym= nsym++;
  2117. X    
  2118. X    pclass= &classdef[nclass];
  2119. X    pclass->c_name= savestr(defname);
  2120. X    classname(pclass->c_name);
  2121. X    pclass->c_syms= savearray(nilarray, 2);
  2122. X    pclass->c_insert= NULL;
  2123. X    pclass->c_append= NULL;
  2124. X    pclass->c_join= NULL;
  2125. X    plex->l_class= nclass++;
  2126. X}
  2127. X
  2128. XHidden string bodyname(s) string s; {
  2129. X    char lexbuffer[NAMELEN];
  2130. X    
  2131. X    strcpy(lexbuffer, s);
  2132. X    classname(lexbuffer);
  2133. X    strcat(lexbuffer, "-body");
  2134. X    return savestr((string)lexbuffer);
  2135. X}
  2136. X
  2137. XHidden Procedure symname(s) string s; {    
  2138. X    string t= s+1;
  2139. X    char c;
  2140. X    
  2141. X    while (*t) {
  2142. X        if (isupper(*t)) {
  2143. X            c= tolower(*t);
  2144. X            *t= c;
  2145. X        }
  2146. X        t++;
  2147. X    }
  2148. X}
  2149. X
  2150. XHidden Procedure classname(s) string s; {    
  2151. X    string t= s;
  2152. X    char c;
  2153. X    
  2154. X    while (*t) {
  2155. X        if (isupper(*t)) {
  2156. X            c= tolower(*t);
  2157. X            *t= c;
  2158. X        }
  2159. X        t++;
  2160. X    }
  2161. X}
  2162. X
  2163. X/* At the end we must add two Symbol definitions
  2164. X * that could not be entered in the grammar:
  2165. X *    Optional: .
  2166. X *    Hole: "?".
  2167. X * The ABC editor expects these to be at the end of the symdef[] table.
  2168. X *
  2169. X * Just before that entries for:
  2170. X *     Suggestion: suggestion_body.
  2171. X *    Sugghowname: sugghowname_body.
  2172. X * will be defined iff the corresponding lexical symbol has
  2173. X * been defined in the grammar.
  2174. X *
  2175. X * 'Suggestion', 'Sugghowname' and 'Optional' are already in the namelist[],
  2176. X * but still undefined.
  2177. X * To replace the references made to them (later, in fill_and_check_tables())
  2178. X * we must add their definitions here first, mimicking the reading procedure.
  2179. X *
  2180. X * 'Hole' should not be used, only by the ABC editor, so we don't
  2181. X * bother about any links to it. (check_defined() will fail if this
  2182. X * is violated).
  2183. X */
  2184. X
  2185. XHidden Procedure add_special_definitions() {
  2186. X    
  2187. X    if (lsuggestion >= 0) {    /* SUGGESTION defined */
  2188. X        add_symbol("Suggestion", &nsuggestion, Yes);
  2189. X    }
  2190. X    if (lsugghowname >= 0) { /* SUGGHOWNAME defined */
  2191. X        add_symbol("Sugghowname", &nsugghowname, Yes);
  2192. X    }
  2193. X    
  2194. X    add_symbol("Optional", &noptional, Yes);
  2195. X    add_symbol("Hole", &nhole, No);
  2196. X    symdef[nhole].s_repr[0]= "?";
  2197. X}
  2198. X
  2199. XHidden Procedure add_symbol(name, pn, referenced)
  2200. Xstring name; int *pn; bool referenced;
  2201. X{
  2202. X    struct syminfo *psym;
  2203. X    item i;
  2204. X    char t;
  2205. X    int ich;
  2206. X    
  2207. X    *pn= nsym++;
  2208. X    if (referenced) {
  2209. X        storename(name, &i, &t);
  2210. X        namelist[i].n_index= *pn;
  2211. X    }
  2212. X    psym= &symdef[*pn];
  2213. X    psym->s_name= name;
  2214. X    for (ich= 0; ; ich++) {
  2215. X        psym->s_repr[ich]= NULL;
  2216. X        if (ich == MAXCHILD)
  2217. X            break;
  2218. X        psym->s_class[ich]= Nilitem;
  2219. X    }
  2220. X}
  2221. END_OF_FILE
  2222.   if test 13315 -ne `wc -c <'abc/boot/read.c'`; then
  2223.     echo shar: \"'abc/boot/read.c'\" unpacked with wrong size!
  2224.   fi
  2225.   # end of 'abc/boot/read.c'
  2226. fi
  2227. echo shar: End of archive 11 \(of 25\).
  2228. cp /dev/null ark11isdone
  2229. MISSING=""
  2230. 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
  2231.     if test ! -f ark${I}isdone ; then
  2232.     MISSING="${MISSING} ${I}"
  2233.     fi
  2234. done
  2235. if test "${MISSING}" = "" ; then
  2236.     echo You have unpacked all 25 archives.
  2237.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2238. else
  2239.     echo You still must unpack the following archives:
  2240.     echo "        " ${MISSING}
  2241. fi
  2242. exit 0 # Just in case...
  2243.