home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume20 / plumansm.crs < prev    next >
Encoding:
Internet Message Format  |  1989-10-23  |  26.8 KB

  1. Path: wuarchive!cs.utexas.edu!uunet!bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v20i048:  Plum-Hall X3J11 macro explainer
  5. Message-ID: <2055@papaya.bbn.com>
  6. Date: 24 Oct 89 00:25:20 GMT
  7. Lines: 1311
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: Eric S. Raymond <eric@snark.uu.net>
  11. Posting-number: Volume 20, Issue 48
  12. Archive-name: plum-ansi-macros
  13.  
  14. his is a tutorial program which illustrates how the Standard's
  15. macro-expansion algorithm works.  First, look at some of the  .out  files
  16. to see the model of presentation of macro-expansion.
  17.  
  18. Then, look at the file  mac.c  for notes on the implementation.  This is
  19. not an elegant program.  It was designed to illustrate the dynamics in
  20. the minimum amount of C code.  Forget about "information-hiding";
  21. everything is a string of chars.
  22.  
  23. All of this directory is experimental, not intended to be authoritative,
  24. and in no way an official opinion of the ANSI X3J11 committee.
  25.  
  26. Permissions:
  27.  Permission is granted for reproduction and use of this  mac  program,
  28.  provided that its enclosed authorship notice is reproduced entirely.
  29.  
  30.  
  31.  Tom Plum, Plum Hall Inc, 609-927-3770,  uunet!plumhall!plum .
  32.  
  33. #!/bin/sh
  34. : "This is a shell archive, meaning:                              "
  35. : "1. Remove everything above the #! /bin/sh line.                "
  36. : "2. Save the resulting test in a file.                          "
  37. : "3. Execute the file with /bin/sh (not csh) to create the files:"
  38. : "    READ.ME"
  39. : "    Makefile"
  40. : "    mac.c"
  41. : "    std1.in"
  42. : "    std2.in"
  43. : "    std3.in"
  44. : "    std4.in"
  45. : "    test1.in"
  46. : "    test2.in"
  47. : "    test5.in"
  48. : "    test6.in"
  49. : "    test7.in"
  50. : "    test8.in"
  51. : "    std1.out"
  52. : "    std2.out"
  53. : "    std3.out"
  54. : "    std4.out"
  55. : "    test1.out"
  56. : "    test2.out"
  57. : "    test5.out"
  58. : "    test6.out"
  59. : "    test7.out"
  60. : "    test8.out"
  61. echo file: READ.ME
  62. sed 's/^X//' >READ.ME << 'END-of-READ.ME'
  63. XThe MAC demonstration program
  64. X
  65. XThis is a tutorial program which illustrates how the Standard's
  66. Xmacro-expansion algorithm works.  First, look at some of the  .out  files
  67. Xto see the model of presentation of macro-expansion.
  68. X
  69. XThen, look at the file  mac.c  for notes on the implementation.  This is
  70. Xnot an elegant program.  It was designed to illustrate the dynamics in
  71. Xthe minimum amount of C code.  Forget about "information-hiding";
  72. Xeverything is a string of chars.
  73. X
  74. XAll of this directory is experimental, not intended to be authoritative,
  75. Xand in no way an official opinion of the ANSI X3J11 committee.
  76. X
  77. X-----------------------
  78. XPermissions:
  79. X
  80. X Permission is granted for reproduction and use of this  mac  program,
  81. X provided that its enclosed authorship notice is reproduced entirely.
  82. X
  83. X
  84. X Tom Plum, Plum Hall Inc, 609-927-3770,  uunet!plumhall!plum .
  85. END-of-READ.ME
  86. echo file: Makefile
  87. sed 's/^X//' >Makefile << 'END-of-Makefile'
  88. X#
  89. X# Makefile for the Plum-Hall X3J11 macro untangler
  90. X#
  91. XSRC = Makefile mac.c
  92. XIN = std[1234].in test[12345678].in
  93. XOUT = std[1234].out test[12345678].out
  94. X
  95. Xmac: mac.c 
  96. X    cc -g -o mac mac.c
  97. X
  98. XSUFFIXES: .out .in
  99. X
  100. X.in.out: mac
  101. X    mac <$*.in >$*.out
  102. X
  103. Xshar: READ.ME $(SRC) $(IN) $(OUT)
  104. X    shar READ.ME $(SRC) $(IN) $(OUT) >mac.shar
  105. X
  106. Xclean:
  107. X    rm -f mac mac.shar *~
  108. END-of-Makefile
  109. echo file: mac.c
  110. sed 's/^X//' >mac.c << 'END-of-mac.c'
  111. X/* macros - skeleton of macro expansion algorithm
  112. X * Each token is one char (letter a-z).
  113. X * Token-buffers are modeled by plain old char strings.
  114. X * Each such buffer has another same-size buffer printed just under it,
  115. X * which shows the "hide-set" associated with the token above it.
  116. X * (The "hide-set" contains all the tokens that are non-replaceable.)
  117. X * #define  is  #d (no space before or after #).
  118. X * No attempt to model details of whitespace handling.
  119. X * Two tokens, when catenated, produce "second token plus one".
  120. X * "Stringize" is crudely stubbed; two quotes "" replace the string.
  121. X * Does not handle empty actuals gracefully.
  122. X * Does not span newlines in matching actuals.
  123. X * Revisions:
  124. X * 88/10/01: Identify the "replacement" buffer as "R".
  125. X * 88/10/03: Handle the hide-set of actuals properly.
  126. X * 88/10/03: Indicate where to refine for the exact (unspecified)
  127. X *        semantics of interactions of hide-sets in catenation 
  128. X */
  129. X/*
  130. X * First version written by Thomas Plum, Plum Hall Inc.
  131. X * Subsequently revised by members of X3J11, the
  132. X * ANSI C Standards Committee.
  133. X * Permission is granted to reproduce and use this program,
  134. X * for all purposes, provided that this notice is included.
  135. X */
  136. X
  137. X/* First, 300+ lines of inelegant support routines, to about 363  ... */
  138. X
  139. X#include <stdio.h>
  140. X#include <ctype.h>
  141. X#include <string.h>
  142. X#define TRACE(x) 0    /* or,  printf x , if needed for debugging */
  143. X#define OUT(x) printf x
  144. X#define cpy_nam(p, q) (p[0] = *(q), p[1] = '\0', ++(q))
  145. X#define eobuf(p) (*(p) == '\0')
  146. X#define next(p, s) (strncmp(p, s, (length_matched = strlen(s))) == 0)
  147. X#define advance(p) (p += length_matched)
  148. X#define is_obj(p) in_set(obj.nam, *(p))
  149. X#define is_fn(p) in_set(fn.nam, *(p))
  150. X#define obj_def(p) obj.def[obj_num(p)][0]
  151. X#define obj_num(p) (strchr(obj.nam, *(p)) - obj.nam)
  152. X#define fn_def(p) fn.def[fn_num(p)][0]
  153. X#define fn_num(p) (strchr(fn.nam, *(p)) - fn.nam)
  154. X#define fn_parm_count(p) strlen(fn.parms[fn_num(p)])
  155. X#define fn_parm_index(p, q) \
  156. X    (strchr(fn.parms[fn_num(p)], *(q)) - fn.parms[fn_num(p)])
  157. X#define is_parm_name(p, q) in_set(fn.parms[fn_num(p)], *(q))
  158. X#define in_set(p, c) (strchr(p, c) != 0)
  159. X#define hide_set(p) *((char*)p + L)
  160. X#define A 9   /* max # of macro args */
  161. X#define D 26  /* max # of macro defs */
  162. X#define L 100 /* max length of an input line  or of a macro def */
  163. Xint length_matched;
  164. Xvoid diagram(), expand(), expand_fn(), set_hide(), listcpy();
  165. Xvoid add_hide(), lower_case();
  166. Xchar *h_set();
  167. Xchar arg_patterns[10][24] =
  168. X    {
  169. X    "()",
  170. X    "(_)",
  171. X    "(_,_)",
  172. X    "(_,_,_)",
  173. X    "(_,_,_,_)",
  174. X    "(_,_,_,_,_)",
  175. X    "(_,_,_,_,_,_)",
  176. X    "(_,_,_,_,_,_,_)",
  177. X    "(_,_,_,_,_,_,_,_)",
  178. X    "(_,_,_,_,_,_,_,_,_)",
  179. X    };
  180. Xchar next_token(p) char *p;
  181. X    {
  182. X    length_matched = 0;
  183. X    ++p;
  184. X    for (;;)
  185. X        {
  186. X        if (*p == ' ')
  187. X            ++p, ++length_matched;
  188. X        else if (*p == '\0')
  189. X            {
  190. X            printf("treating end-of-buffer as end-of-file\n");
  191. X            return *p;
  192. X            }
  193. X        else
  194. X            return *p;
  195. X        }
  196. X    }
  197. X
  198. Xvoid strip_blanks(p) char *p;
  199. X    {
  200. X    char *q = p;
  201. X
  202. X    while (*p == ' ')
  203. X        ++p;
  204. X    /* now at first non-blank in p */
  205. X    while (*p != '\0')    /* can't use strcpy because overlap */
  206. X        hide_set(q) = hide_set(p), *q++ = *p++;
  207. X    while (*--q == ' ')
  208. X        ;
  209. X    *++q = '\0', hide_set(q) = '\0';
  210. X    }
  211. X
  212. Xstruct obj { int n; char nam[D]; char def[D][2][L]; }
  213. X    obj = {0};
  214. Xstruct fn  { int n; char nam[D]; char def[D][2][L]; char parms[D][A]; }
  215. X    fn = {0};
  216. X
  217. Xvoid install_obj(nam, def) char *nam; char *def;
  218. X    {
  219. X    obj.nam[obj.n] = nam[0];
  220. X    strcpy(obj.def[obj.n][0], def);
  221. X    strip_blanks(obj.def[obj.n][0]);
  222. X    set_hide(obj.def[obj.n][0], nam);
  223. X    printf("obj: nam=<%s> def=<%s>\n", nam, obj.def[obj.n][0]);
  224. X    printf("                 <%s>\n", obj.def[obj.n][1]);
  225. X    ++obj.n;
  226. X    }
  227. X
  228. Xvoid install_fn(nam, def, parms) char *nam; char *def; char *parms;
  229. X    {
  230. X    fn.nam[fn.n] = nam[0];
  231. X    strcpy(fn.def[fn.n][0], def);
  232. X    strcpy(fn.parms[fn.n], parms);
  233. X    strip_blanks(fn.def[fn.n][0]);
  234. X    set_hide(fn.def[fn.n][0], nam);
  235. X    printf("fn:  nam=<%s> parms=<%s> def=<%s>\n", nam, parms, fn.def[fn.n][0]);
  236. X    printf("                    %*s      <%s>\n", 
  237. X        strlen(parms), "", fn.def[fn.n][1]);
  238. X    ++fn.n;
  239. X    }
  240. X
  241. Xchar *parse_parms(p, parms) char *p; char *parms;
  242. X    {
  243. X    int i = 0;
  244. X
  245. X    while (*p != ')')
  246. X        {
  247. X        if (*p != ' ' && *p != ',')
  248. X            parms[i++] = *p;
  249. X        ++p;
  250. X        }
  251. X    ++p;
  252. X    parms[i] = '\0';
  253. X    return p;
  254. X    }
  255. X
  256. X
  257. X
  258. Xvoid replace(level, suf, buf, p, p2, def) char *level, *suf, *buf, *p, *p2, *def;
  259. X    {
  260. X    char hold[2][L];
  261. X    char old_hide[2];
  262. X
  263. X    listcpy(hold[0], p2);
  264. X    old_hide[0] = hide_set(p), old_hide[1] = '\0';
  265. X    listcpy(p, def);
  266. X    add_hide(p, old_hide);
  267. X    listcpy(p + strlen(def), hold[0]);
  268. X    diagram(level, buf, suf);
  269. X    }
  270. Xchar *match_actuals(p, actual, n) char *p; char actual[A][2][L]; int n;
  271. X    {
  272. X    int parens = 1;
  273. X    int i = 0;
  274. X    int j = 0;
  275. X
  276. X    TRACE(("match_actuals(<%s>, actual)\n", p));
  277. X    p += 1;
  278. X    /* past the '(' */
  279. X
  280. X    for ( ;; )
  281. X        {
  282. X        if (*p == '(')
  283. X            {
  284. X            ++parens;
  285. X            actual[i][1][j] = p[L];
  286. X            actual[i][0][j++] = *p++;
  287. X            }
  288. X        else if (*p == ')')
  289. X            {
  290. X            --parens;
  291. X            if (parens == 0)
  292. X                break;
  293. X            actual[i][1][j] = p[L];
  294. X            actual[i][0][j++] = *p++;
  295. X            }
  296. X        else if (*p == ',' && parens == 1)
  297. X            {
  298. X            actual[i][1][j] = '\0';
  299. X            actual[i][0][j] = '\0';
  300. X            j = 0;
  301. X            ++i;
  302. X            ++p;
  303. X            }
  304. X        else
  305. X            {
  306. X            actual[i][1][j] = p[L];
  307. X            actual[i][0][j++] = *p++;
  308. X            }
  309. X        }
  310. X    actual[i][1][j] = '\0';
  311. X    actual[i][0][j] = '\0';
  312. X    /* should strip blanks on each actual, to be sure non-empty */
  313. X    if (i == 0 && n == 0)
  314. X        ;    /* ok, no args */
  315. X    else if (i != n-1)
  316. X        {
  317. X        printf("wrong number of actuals\n");
  318. X        exit(2);
  319. X        }
  320. X    for (i = 0; i < n; ++i)
  321. X        TRACE(("actual[%d] = <%s>\n", i, actual[i][0]));
  322. X    return p+1;
  323. X    }
  324. X
  325. Xchar *stringize(s) char *s;
  326. X    {
  327. X    static char string_buf[2][L] = {"\"\"", "  "};
  328. X
  329. X    printf("string \"%s\" --> \"\"\n", s);
  330. X    return string_buf[0];
  331. X    }
  332. X
  333. Xchar *catenate(p, q) char *p, *q;
  334. X    {
  335. X    static char cat_buf[2][L];
  336. X    char old_hide[2];
  337. X
  338. X    cat_buf[0][0] = q[0] + 1;
  339. X    cat_buf[0][1] = '\0';
  340. X    set_hide(cat_buf[0], " ");
  341. X    old_hide[0] = hide_set(p), old_hide[1] = '\0';
  342. X    add_hide(cat_buf[0], old_hide);
  343. X    old_hide[0] = hide_set(q), old_hide[1] = '\0';
  344. X    add_hide(cat_buf[0], old_hide);    /* NOTE: The other "unspecified" */
  345. X                                    /* choice is to intersect(!) the */
  346. X                                    /* two hide-sets, as in Prosser  */
  347. X                                    /* 86-196.                       */
  348. X    printf("catenate %c%c --> %c\n", p[0], q[0], cat_buf[0][0]);
  349. X    return cat_buf[0];
  350. X    }
  351. X
  352. Xvoid listcpy(p, q) char *p, *q;
  353. X    {
  354. X    strcpy(p, q);
  355. X    strcpy(&hide_set(p), &hide_set(q));
  356. X    }
  357. X
  358. Xvoid diagram(level, s, suf) char *level, *s, *suf;
  359. X    {
  360. X    char prefix[L];
  361. X
  362. X    if (level[0] == '\0')
  363. X        strcpy(prefix, "0");
  364. X    else
  365. X        strcpy(prefix, level+1);
  366. X    printf("%s%s: %s\n", prefix, suf, s);
  367. X    printf("%*s%.*s\n", strlen(prefix)+strlen(suf)+2, ": ",
  368. X        strlen(s), &hide_set(s));
  369. X    }
  370. X
  371. Xint charcmp(s, t) char *s, *t;
  372. X    {
  373. X    return *s - *t;
  374. X    }
  375. X
  376. Xvoid set_hide(def, nam) char *def, *nam;
  377. X    {
  378. X    memset(&hide_set(def), nam[0], strlen(def));
  379. X    def[L+strlen(def)] = '\0';
  380. X    }
  381. Xchar hide_sets[10][10] = {0};
  382. Xint n_hide_sets = 0;
  383. Xvoid add_hide(p, h) char *p, *h;
  384. X    {
  385. X    int i, lim;
  386. X
  387. X    lim = strlen(p);
  388. X    for (i = 0; i < lim; ++i)
  389. X        {
  390. X        char c = p[L+i];
  391. X        char old_h[2];
  392. X
  393. X        old_h[0] = c, old_h[1] = '\0';
  394. X        TRACE(("c=<%c>, h=<%c>\n", c, h[0]));
  395. X        if (h[0] == ' ')
  396. X            ;
  397. X        else if (c == ' ')
  398. X            p[L+i] = h[0];
  399. X        else if (h[0] == c)
  400. X            ;
  401. X        else if (in_set(h_set(old_h), h[0]))
  402. X            ;
  403. X        else
  404. X            {
  405. X            char new_hide[10];
  406. X            int n = n_hide_sets;
  407. X            int j;
  408. X            int found = 0;
  409. X
  410. X            strcpy(new_hide, h_set(old_h));
  411. X            strcat(new_hide, h_set(h));
  412. X            qsort(new_hide, strlen(new_hide), 1, charcmp);
  413. X            TRACE(("new_hide=<%s>\n", new_hide));
  414. X            for (j = 0; j < n_hide_sets; ++j)
  415. X                {
  416. X                if (strcmp(new_hide, hide_sets[j]) == 0)
  417. X                    {
  418. X                    p[L+i] = j + '0';
  419. X                    found = 1;
  420. X                    }
  421. X                }
  422. X            if (!found)
  423. X                {
  424. X                if (n > 9)
  425. X                    {
  426. X                    printf("too many hide-sets\n");
  427. X                    exit(2);
  428. X                    }
  429. X                strcpy(hide_sets[n], new_hide);
  430. X                p[L+i] = n + '0';
  431. X                qsort(hide_sets[n], strlen(hide_sets[n]), 1, charcmp);
  432. X                printf("hide-set #%d = {%s}\n", n, hide_sets[n]);
  433. X                ++n_hide_sets;
  434. X                }
  435. X            }
  436. X        }
  437. X    }
  438. X
  439. Xchar *h_set(s) char *s;
  440. X    {
  441. X    char c = s[0];
  442. X
  443. X    if (isdigit(c))
  444. X        return hide_sets[c - '0'];
  445. X    else
  446. X        return s;
  447. X    }
  448. X
  449. Xint is_hidden(p) char *p;
  450. X    {
  451. X    if (!islower(*p))
  452. X        return 0;
  453. X    else if (*p == p[L])
  454. X        return 1;
  455. X    else if (isdigit(p[L]) && strchr(hide_sets[p[L] - '0'], *p) != 0)
  456. X        return 1;
  457. X    else
  458. X        return 0;
  459. X    }
  460. X
  461. Xvoid mark_non_replace(p) char *p;
  462. X    {
  463. X    *p = toupper(*p);
  464. X    }
  465. X
  466. Xvoid lower_case(p) char *p;
  467. X    {
  468. X    for ( ; *p != '\0'; ++p)
  469. X        *p = tolower(*p);
  470. X    }
  471. X
  472. X
  473. X/* Now: Here's the actual macro algorithm ... */
  474. X
  475. Xvoid preproc(p) char *p;
  476. X    {
  477. X    char nam[2];
  478. X    char parms[A];
  479. X
  480. X    if (next(p, "#d "))
  481. X        {             /* starting a #define */
  482. X        advance(p);
  483. X        TRACE(("p=<%s>\n", p));
  484. X        cpy_nam(nam, p);
  485. X        if (next(p, "("))    /* a fn-like macro */
  486. X            {
  487. X            advance(p);
  488. X            p = parse_parms(p, parms);
  489. X            install_fn(nam, p, parms);
  490. X            }
  491. X        else        /* an object-like macro */
  492. X            install_obj(nam, p);
  493. X        }    /* end of #define */
  494. X    else if (next(p, "#u "))
  495. X        {            /* starting a #undef */
  496. X        } /* stub */
  497. X    else
  498. X        {
  499. X        expand(p, "");
  500. X        lower_case(p);
  501. X        set_hide(p, " ");
  502. X        diagram("", p, "");
  503. X        }
  504. X    }
  505. Xvoid expand(buf, level) char *buf; char *level;
  506. X    {
  507. X    char *p = buf;
  508. X
  509. X    TRACE(("expand(<%s>, %s)\n", buf, level));
  510. X    diagram(level, buf, "");
  511. X    while (!eobuf(p))
  512. X        {
  513. X        if (is_hidden(p))
  514. X            {
  515. X            mark_non_replace(p);
  516. X            ++p;
  517. X            diagram(level, buf, "");
  518. X            }
  519. X        else if (is_obj(p))    /* instance of object-like macro */
  520. X            replace(level, "", buf, p, p+1, obj_def(p));
  521. X        else if (is_fn(p) && next_token(p) == '(') 
  522. X            expand_fn(buf, p, level); /* instance of fn-like macro */
  523. X        else
  524. X            ++p;    /* ordinary token */
  525. X        }    /* end while !eobuf */
  526. X    }    /* end expand() */
  527. X
  528. X
  529. X
  530. X
  531. X
  532. X
  533. Xvoid expand_fn(buf, p, level) char *buf, *p, *level;
  534. X    {
  535. X    char actual[A][2][L], expandeds[A][2][L];
  536. X    char repl[2][L];
  537. X    char nlevel[20];
  538. X    char fn_nam[2];
  539. X    char invocation[2][L];
  540. X    char *start_invok, *q;
  541. X    int i_parm, num_parms;
  542. X
  543. X    start_invok = p;
  544. X    cpy_nam(fn_nam, p);
  545. X    advance(p);    /* past any blanks skipped in next_token */
  546. X    num_parms = fn_parm_count(fn_nam);
  547. X    p = match_actuals(p, actual, num_parms);
  548. X    for (i_parm = 0; i_parm < num_parms; ++i_parm)
  549. X        {
  550. X        listcpy(expandeds[i_parm][0], actual[i_parm][0]);
  551. X        sprintf(nlevel, "%s.%d", level, i_parm+1);
  552. X        expand(expandeds[i_parm][0], nlevel);
  553. X        }
  554. X    sprintf(invocation[0], "%s%s", fn_nam, arg_patterns[num_parms]);
  555. X    set_hide(invocation[0], " ");
  556. X    diagram(level, invocation[0], "R");
  557. X    listcpy(repl[0], fn_def(fn_nam));
  558. X    diagram(level, repl[0], "R");
  559. X    TRACE(("subst parms in repl:<%s>\n", repl));
  560. X    for (q = repl[0]; !eobuf(q); )
  561. X        {
  562. X        TRACE(("repl-token <%c>\n", *q));
  563. X        if (q[1] == '#' && q[2] == '#' && !eobuf(q+3))
  564. X            {
  565. X            replace(level, "R", repl[0], q, q+4,
  566. X                catenate(q, q+3));
  567. X            q += 1;    /* advance past new "token" */
  568. X            }
  569. X        else if (q[0] == '#' && is_parm_name(fn_nam, q+1))
  570. X            {
  571. X            i_parm = fn_parm_index(fn_nam, q+1);
  572. X            replace(level, "R", repl[0], q, q+2,
  573. X                stringize(actual[i_parm][0]));
  574. X            q += 2;    /* advance past "" */
  575. X            }
  576. X        else if (is_parm_name(fn_nam, q))
  577. X            {
  578. X            i_parm = fn_parm_index(fn_nam, q);
  579. X            replace(level, "R", repl[0], q, q+1,
  580. X                expandeds[i_parm][0]);
  581. X            q += strlen(expandeds[i_parm][0]);    /* advance past expansion */
  582. X            }
  583. X        else        /* ordinary token */
  584. X            ++q;
  585. X        }
  586. X    replace(level, "", buf, start_invok, p, repl[0]);
  587. X    }
  588. X
  589. X
  590. X
  591. X
  592. Xmain()
  593. X    {
  594. X    char line[BUFSIZ];
  595. X
  596. X    while (gets(line))
  597. X        {
  598. X        set_hide(line, " ");
  599. X        preproc(line);
  600. X        }
  601. X    } /* end main */
  602. END-of-mac.c
  603. echo file: std1.in
  604. sed 's/^X//' >std1.in << 'END-of-std1.in'
  605. X#d f(a) f( x * (a))
  606. X#d z z[0]
  607. X#d x 2
  608. Xf(y+1) + f(f(z)) %
  609. END-of-std1.in
  610. echo file: std2.in
  611. sed 's/^X//' >std2.in << 'END-of-std2.in'
  612. X#d f(a) f( x * (a))
  613. X#d x    2
  614. X#d g    f
  615. X#d t(a) a
  616. Xt(t(g)(0) + t)(1);
  617. END-of-std2.in
  618. echo file: std3.in
  619. sed 's/^X//' >std3.in << 'END-of-std3.in'
  620. X#d f(a) f( x * (a))
  621. X#d x    2
  622. X#d g    f
  623. X#d w    0,1
  624. X#d h    g(~
  625. X
  626. Xg(x+(3,4)-w) | h 5)
  627. END-of-std3.in
  628. echo file: std4.in
  629. sed 's/^X//' >std4.in << 'END-of-std4.in'
  630. X#d f(a) f( x * (a))
  631. X#d x    2
  632. X#d m(a) a(w)
  633. X#d w    0,1
  634. X
  635. Xm (f)^m(m) ;
  636. END-of-std4.in
  637. echo file: test1.in
  638. sed 's/^X//' >test1.in << 'END-of-test1.in'
  639. X#d x(c) (y(c,3))
  640. X#d y(a, b) x(a+b)
  641. Xy(x(2),1)
  642. END-of-test1.in
  643. echo file: test2.in
  644. sed 's/^X//' >test2.in << 'END-of-test2.in'
  645. X#d f(a) i(x*(a))
  646. X#d j(a) k(x*(a))
  647. X#d z y[0]
  648. X#d x 2
  649. Xf(j(z)) 3 4 z
  650. X
  651. X#d h(g) g
  652. X#d a()  0
  653. X#d b    ()
  654. X#d c    a b
  655. Xh(c)
  656. X
  657. X#d m(a) <<#a>>
  658. X#d n(a) m(a)
  659. Xm(1 2 3)
  660. Xm(z)
  661. Xn(z)
  662. X
  663. X#d e(a, b) [[a##b]]
  664. Xe(x,y)
  665. END-of-test2.in
  666. echo file: test5.in
  667. sed 's/^X//' >test5.in << 'END-of-test5.in'
  668. X#d h(g) g
  669. X#d a()  0
  670. X#d b    ()
  671. X#d c    a b
  672. Xh(c)
  673. END-of-test5.in
  674. echo file: test6.in
  675. sed 's/^X//' >test6.in << 'END-of-test6.in'
  676. X#d m(a) <<#a>>
  677. X#d n(a) m(a)
  678. Xm(1 2 3)
  679. Xm(z)
  680. Xn(z)
  681. END-of-test6.in
  682. echo file: test7.in
  683. sed 's/^X//' >test7.in << 'END-of-test7.in'
  684. X#d e(a, b) [[a##b]]
  685. Xe(x,y)
  686. END-of-test7.in
  687. echo file: test8.in
  688. sed 's/^X//' >test8.in << 'END-of-test8.in'
  689. X#d f(a) a * g
  690. X#d g(a) f(a)
  691. X
  692. Xf(2)(9)
  693. END-of-test8.in
  694. echo file: std1.out
  695. sed 's/^X//' >std1.out << 'END-of-std1.out'
  696. Xfn:  nam=<f> parms=<a> def=<f( x * (a))>
  697. X                           <fffffffffff>
  698. Xobj: nam=<z> def=<z[0]>
  699. X                 <zzzz>
  700. Xobj: nam=<x> def=<2>
  701. X                 <x>
  702. X0: f(y+1) + f(f(z)) %
  703. X :                   
  704. X1: y+1
  705. X :    
  706. X0R: f(_)
  707. X  :     
  708. X0R: f( x * (a))
  709. X  : fffffffffff
  710. X0R: f( x * (y+1))
  711. X  : fffffffffffff
  712. X0: f( x * (y+1)) + f(f(z)) %
  713. X : fffffffffffff            
  714. X0: F( x * (y+1)) + f(f(z)) %
  715. X : fffffffffffff            
  716. Xhide-set #0 = {fx}
  717. X0: F( 2 * (y+1)) + f(f(z)) %
  718. X : fff0fffffffff            
  719. X1: f(z)
  720. X :     
  721. X1.1: z
  722. X   :  
  723. X1.1: z[0]
  724. X   : zzzz
  725. X1.1: Z[0]
  726. X   : zzzz
  727. X1R: f(_)
  728. X  :     
  729. X1R: f( x * (a))
  730. X  : fffffffffff
  731. Xhide-set #1 = {fz}
  732. X1R: f( x * (Z[0]))
  733. X  : ffffffff1111ff
  734. X1: f( x * (Z[0]))
  735. X : ffffffff1111ff
  736. X1: F( x * (Z[0]))
  737. X : ffffffff1111ff
  738. X1: F( 2 * (Z[0]))
  739. X : fff0ffff1111ff
  740. X0R: f(_)
  741. X  :     
  742. X0R: f( x * (a))
  743. X  : fffffffffff
  744. X0R: f( x * (F( 2 * (Z[0]))))
  745. X  : fffffffffff0ffff1111ffff
  746. X0: F( 2 * (y+1)) + f( x * (F( 2 * (Z[0])))) %
  747. X : fff0fffffffff   fffffffffff0ffff1111ffff  
  748. X0: F( 2 * (y+1)) + F( x * (F( 2 * (Z[0])))) %
  749. X : fff0fffffffff   fffffffffff0ffff1111ffff  
  750. X0: F( 2 * (y+1)) + F( 2 * (F( 2 * (Z[0])))) %
  751. X : fff0fffffffff   fff0fffffff0ffff1111ffff  
  752. X0: f( 2 * (y+1)) + f( 2 * (f( 2 * (z[0])))) %
  753. X :                                           
  754. END-of-std1.out
  755. echo file: std2.out
  756. sed 's/^X//' >std2.out << 'END-of-std2.out'
  757. Xfn:  nam=<f> parms=<a> def=<f( x * (a))>
  758. X                           <fffffffffff>
  759. Xobj: nam=<x> def=<2>
  760. X                 <x>
  761. Xobj: nam=<g> def=<f>
  762. X                 <g>
  763. Xfn:  nam=<t> parms=<a> def=<a>
  764. X                           <t>
  765. X0: t(t(g)(0) + t)(1);
  766. X :                   
  767. X1: t(g)(0) + t
  768. X :            
  769. X1.1: g
  770. X   :  
  771. X1.1: f
  772. X   : g
  773. Xtreating end-of-buffer as end-of-file
  774. X1R: t(_)
  775. X  :     
  776. X1R: a
  777. X  : t
  778. Xhide-set #0 = {gt}
  779. X1R: f
  780. X  : 0
  781. X1: f(0) + t
  782. X : 0       
  783. X1.1: 0
  784. X   :  
  785. X1R: f(_)
  786. X  :     
  787. X1R: f( x * (a))
  788. X  : fffffffffff
  789. X1R: f( x * (0))
  790. X  : fffffffffff
  791. Xhide-set #1 = {fgt}
  792. X1: f( x * (0)) + t
  793. X : 11111111111    
  794. X1: F( x * (0)) + t
  795. X : 11111111111    
  796. Xhide-set #2 = {fgtx}
  797. X1: F( 2 * (0)) + t
  798. X : 11121111111    
  799. Xtreating end-of-buffer as end-of-file
  800. X0R: t(_)
  801. X  :     
  802. X0R: a
  803. X  : t
  804. X0R: F( 2 * (0)) + t
  805. X  : 11121111111tttt
  806. X0: F( 2 * (0)) + t(1);
  807. X : 11121111111tttt    
  808. X0: F( 2 * (0)) + T(1);
  809. X : 11121111111tttt    
  810. X0: f( 2 * (0)) + t(1);
  811. X :                    
  812. END-of-std2.out
  813. echo file: std3.out
  814. sed 's/^X//' >std3.out << 'END-of-std3.out'
  815. Xfn:  nam=<f> parms=<a> def=<f( x * (a))>
  816. X                           <fffffffffff>
  817. Xobj: nam=<x> def=<2>
  818. X                 <x>
  819. Xobj: nam=<g> def=<f>
  820. X                 <g>
  821. Xobj: nam=<w> def=<0,1>
  822. X                 <www>
  823. Xobj: nam=<h> def=<g(~>
  824. X                 <hhh>
  825. X0: 
  826. X : 
  827. X0: 
  828. X : 
  829. X0: g(x+(3,4)-w) | h 5)
  830. X :                    
  831. X0: f(x+(3,4)-w) | h 5)
  832. X : g                  
  833. X1: x+(3,4)-w
  834. X :          
  835. X1: 2+(3,4)-w
  836. X : x        
  837. X1: 2+(3,4)-0,1
  838. X : x       www
  839. X0R: f(_)
  840. X  :     
  841. X0R: f( x * (a))
  842. X  : fffffffffff
  843. Xhide-set #0 = {fx}
  844. Xhide-set #1 = {fw}
  845. X0R: f( x * (2+(3,4)-0,1))
  846. X  : ffffffff0fffffff111ff
  847. Xhide-set #2 = {fg}
  848. Xhide-set #3 = {fgx}
  849. Xhide-set #4 = {fgw}
  850. X0: f( x * (2+(3,4)-0,1)) | h 5)
  851. X : 222222223222222244422       
  852. X0: F( x * (2+(3,4)-0,1)) | h 5)
  853. X : 222222223222222244422       
  854. X0: F( 2 * (2+(3,4)-0,1)) | h 5)
  855. X : 222322223222222244422       
  856. X0: F( 2 * (2+(3,4)-0,1)) | g(~ 5)
  857. X : 222322223222222244422   hhh   
  858. Xhide-set #5 = {gh}
  859. X0: F( 2 * (2+(3,4)-0,1)) | f(~ 5)
  860. X : 222322223222222244422   5hh   
  861. X1: ~ 5
  862. X : h  
  863. X0R: f(_)
  864. X  :     
  865. X0R: f( x * (a))
  866. X  : fffffffffff
  867. Xhide-set #6 = {fh}
  868. X0R: f( x * (~ 5))
  869. X  : ffffffff6ffff
  870. Xhide-set #7 = {fgh}
  871. Xhide-set #8 = {fghh}
  872. X0: F( 2 * (2+(3,4)-0,1)) | f( x * (~ 5))
  873. X : 222322223222222244422   7777777787777
  874. X0: F( 2 * (2+(3,4)-0,1)) | F( x * (~ 5))
  875. X : 222322223222222244422   7777777787777
  876. Xhide-set #9 = {fghx}
  877. X0: F( 2 * (2+(3,4)-0,1)) | F( 2 * (~ 5))
  878. X : 222322223222222244422   7779777787777
  879. X0: f( 2 * (2+(3,4)-0,1)) | f( 2 * (~ 5))
  880. X :                                      
  881. END-of-std3.out
  882. echo file: std4.out
  883. sed 's/^X//' >std4.out << 'END-of-std4.out'
  884. Xfn:  nam=<f> parms=<a> def=<f( x * (a))>
  885. X                           <fffffffffff>
  886. Xobj: nam=<x> def=<2>
  887. X                 <x>
  888. Xfn:  nam=<m> parms=<a> def=<a(w)>
  889. X                           <mmmm>
  890. Xobj: nam=<w> def=<0,1>
  891. X                 <www>
  892. X0: 
  893. X : 
  894. X0: 
  895. X : 
  896. X0: m (f)^m(m) ;
  897. X :             
  898. X1: f
  899. X :  
  900. Xtreating end-of-buffer as end-of-file
  901. X0R: m(_)
  902. X  :     
  903. X0R: a(w)
  904. X  : mmmm
  905. X0R: f(w)
  906. X  : mmmm
  907. X0: f(w)^m(m) ;
  908. X : mmmm       
  909. X1: w
  910. X : m
  911. Xhide-set #0 = {mw}
  912. X1: 0,1
  913. X : 000
  914. X0R: f(_)
  915. X  :     
  916. X0R: f( x * (a))
  917. X  : fffffffffff
  918. Xhide-set #1 = {fmw}
  919. X0R: f( x * (0,1))
  920. X  : ffffffff111ff
  921. Xhide-set #2 = {fm}
  922. X0: f( x * (0,1))^m(m) ;
  923. X : 2222222211122       
  924. X0: F( x * (0,1))^m(m) ;
  925. X : 2222222211122       
  926. Xhide-set #3 = {fmx}
  927. X0: F( 2 * (0,1))^m(m) ;
  928. X : 2223222211122       
  929. X1: m
  930. X :  
  931. Xtreating end-of-buffer as end-of-file
  932. X0R: m(_)
  933. X  :     
  934. X0R: a(w)
  935. X  : mmmm
  936. X0R: m(w)
  937. X  : mmmm
  938. X0: F( 2 * (0,1))^m(w) ;
  939. X : 2223222211122 mmmm  
  940. X0: F( 2 * (0,1))^M(w) ;
  941. X : 2223222211122 mmmm  
  942. X0: F( 2 * (0,1))^M(0,1) ;
  943. X : 2223222211122 mm000m  
  944. X0: f( 2 * (0,1))^m(0,1) ;
  945. X :                       
  946. END-of-std4.out
  947. echo file: test1.out
  948. sed 's/^X//' >test1.out << 'END-of-test1.out'
  949. Xfn:  nam=<x> parms=<c> def=<(y(c,3))>
  950. X                           <xxxxxxxx>
  951. Xfn:  nam=<y> parms=<ab> def=<x(a+b)>
  952. X                            <yyyyyy>
  953. X0: y(x(2),1)
  954. X :          
  955. X1: x(2)
  956. X :     
  957. X1.1: 2
  958. X   :  
  959. X1R: x(_)
  960. X  :     
  961. X1R: (y(c,3))
  962. X  : xxxxxxxx
  963. X1R: (y(2,3))
  964. X  : xxxxxxxx
  965. X1: (y(2,3))
  966. X : xxxxxxxx
  967. X1.1: 2
  968. X   : x
  969. X1.2: 3
  970. X   : x
  971. X1R: y(_,_)
  972. X  :       
  973. X1R: x(a+b)
  974. X  : yyyyyy
  975. Xhide-set #0 = {xy}
  976. X1R: x(2+b)
  977. X  : yy0yyy
  978. X1R: x(2+3)
  979. X  : yy0y0y
  980. X1: (x(2+3))
  981. X : x000000x
  982. X1: (X(2+3))
  983. X : x000000x
  984. X2: 1
  985. X :  
  986. X0R: y(_,_)
  987. X  :       
  988. X0R: x(a+b)
  989. X  : yyyyyy
  990. X0R: x((X(2+3))+b)
  991. X  : yy00000000yyy
  992. X0R: x((X(2+3))+1)
  993. X  : yy00000000yyy
  994. X0: x((X(2+3))+1)
  995. X : yy00000000yyy
  996. X1: (X(2+3))+1
  997. X : 00000000yy
  998. X0R: x(_)
  999. X  :     
  1000. X0R: (y(c,3))
  1001. X  : xxxxxxxx
  1002. X0R: (y((X(2+3))+1,3))
  1003. X  : xxx0000000000xxxx
  1004. X0: (y((X(2+3))+1,3))
  1005. X : 00000000000000000
  1006. X0: (Y((X(2+3))+1,3))
  1007. X : 00000000000000000
  1008. X0: (y((x(2+3))+1,3))
  1009. X :                  
  1010. END-of-test1.out
  1011. echo file: test2.out
  1012. sed 's/^X//' >test2.out << 'END-of-test2.out'
  1013. Xfn:  nam=<f> parms=<a> def=<i(x*(a))>
  1014. X                           <ffffffff>
  1015. Xfn:  nam=<j> parms=<a> def=<k(x*(a))>
  1016. X                           <jjjjjjjj>
  1017. Xobj: nam=<z> def=<y[0]>
  1018. X                 <zzzz>
  1019. Xobj: nam=<x> def=<2>
  1020. X                 <x>
  1021. X0: f(j(z)) 3 4 z
  1022. X :              
  1023. X1: j(z)
  1024. X :     
  1025. X1.1: z
  1026. X   :  
  1027. X1.1: y[0]
  1028. X   : zzzz
  1029. X1R: j(_)
  1030. X  :     
  1031. X1R: k(x*(a))
  1032. X  : jjjjjjjj
  1033. Xhide-set #0 = {jz}
  1034. X1R: k(x*(y[0]))
  1035. X  : jjjjj0000jj
  1036. X1: k(x*(y[0]))
  1037. X : jjjjj0000jj
  1038. Xhide-set #1 = {jx}
  1039. X1: k(2*(y[0]))
  1040. X : jj1jj0000jj
  1041. X0R: f(_)
  1042. X  :     
  1043. X0R: i(x*(a))
  1044. X  : ffffffff
  1045. Xhide-set #2 = {fj}
  1046. Xhide-set #3 = {fjx}
  1047. Xhide-set #4 = {fjz}
  1048. X0R: i(x*(k(2*(y[0]))))
  1049. X  : fffff22322444422ff
  1050. X0: i(x*(k(2*(y[0])))) 3 4 z
  1051. X : fffff22322444422ff      
  1052. Xhide-set #5 = {fx}
  1053. X0: i(2*(k(2*(y[0])))) 3 4 z
  1054. X : ff5ff22322444422ff      
  1055. X0: i(2*(k(2*(y[0])))) 3 4 y[0]
  1056. X : ff5ff22322444422ff     zzzz
  1057. X0: i(2*(k(2*(y[0])))) 3 4 y[0]
  1058. X :                            
  1059. X0: 
  1060. X : 
  1061. X0: 
  1062. X : 
  1063. Xfn:  nam=<h> parms=<g> def=<g>
  1064. X                           <h>
  1065. Xfn:  nam=<a> parms=<> def=<0>
  1066. X                          <a>
  1067. Xobj: nam=<b> def=<()>
  1068. X                 <bb>
  1069. Xobj: nam=<c> def=<a b>
  1070. X                 <ccc>
  1071. X0: h(c)
  1072. X :     
  1073. X1: c
  1074. X :  
  1075. X1: a b
  1076. X : ccc
  1077. Xhide-set #6 = {bc}
  1078. X1: a ()
  1079. X : cc66
  1080. X0R: h(_)
  1081. X  :     
  1082. X0R: g
  1083. X  : h
  1084. Xhide-set #7 = {ch}
  1085. Xhide-set #8 = {bch}
  1086. X0R: a ()
  1087. X  : 7788
  1088. X0: a ()
  1089. X : 7788
  1090. X0R: a()
  1091. X  :    
  1092. X0R: 0
  1093. X  : a
  1094. Xhide-set #9 = {ach}
  1095. X0: 0
  1096. X : 9
  1097. X0: 0
  1098. X :  
  1099. X0: 
  1100. X : 
  1101. X0: 
  1102. X : 
  1103. Xfn:  nam=<m> parms=<a> def=<<<#a>>>
  1104. X                           <mmmmmm>
  1105. Xfn:  nam=<n> parms=<a> def=<m(a)>
  1106. X                           <nnnn>
  1107. X0: m(1 2 3)
  1108. X :         
  1109. X1: 1 2 3
  1110. X :      
  1111. X0R: m(_)
  1112. X  :     
  1113. X0R: <<#a>>
  1114. X  : mmmmmm
  1115. Xstring "1 2 3" --> ""
  1116. X0R: <<"">>
  1117. X  : mmmmmm
  1118. X0: <<"">>
  1119. X : mmmmmm
  1120. X0: <<"">>
  1121. X :       
  1122. X0: m(z)
  1123. X :     
  1124. X1: z
  1125. X :  
  1126. X1: y[0]
  1127. X : zzzz
  1128. X0R: m(_)
  1129. X  :     
  1130. X0R: <<#a>>
  1131. X  : mmmmmm
  1132. Xstring "z" --> ""
  1133. X0R: <<"">>
  1134. X  : mmmmmm
  1135. X0: <<"">>
  1136. X : mmmmmm
  1137. X0: <<"">>
  1138. X :       
  1139. X0: n(z)
  1140. X :     
  1141. X1: z
  1142. X :  
  1143. X1: y[0]
  1144. X : zzzz
  1145. X0R: n(_)
  1146. X  :     
  1147. X0R: m(a)
  1148. X  : nnnn
  1149. Xtoo many hide-sets
  1150. END-of-test2.out
  1151. echo file: test5.out
  1152. sed 's/^X//' >test5.out << 'END-of-test5.out'
  1153. Xfn:  nam=<h> parms=<g> def=<g>
  1154. X                           <h>
  1155. Xfn:  nam=<a> parms=<> def=<0>
  1156. X                          <a>
  1157. Xobj: nam=<b> def=<()>
  1158. X                 <bb>
  1159. Xobj: nam=<c> def=<a b>
  1160. X                 <ccc>
  1161. X0: h(c)
  1162. X :     
  1163. X1: c
  1164. X :  
  1165. X1: a b
  1166. X : ccc
  1167. Xhide-set #0 = {bc}
  1168. X1: a ()
  1169. X : cc00
  1170. X0R: h(_)
  1171. X  :     
  1172. X0R: g
  1173. X  : h
  1174. Xhide-set #1 = {ch}
  1175. Xhide-set #2 = {bch}
  1176. X0R: a ()
  1177. X  : 1122
  1178. X0: a ()
  1179. X : 1122
  1180. X0R: a()
  1181. X  :    
  1182. X0R: 0
  1183. X  : a
  1184. Xhide-set #3 = {ach}
  1185. X0: 0
  1186. X : 3
  1187. X0: 0
  1188. X :  
  1189. END-of-test5.out
  1190. echo file: test6.out
  1191. sed 's/^X//' >test6.out << 'END-of-test6.out'
  1192. Xfn:  nam=<m> parms=<a> def=<<<#a>>>
  1193. X                           <mmmmmm>
  1194. Xfn:  nam=<n> parms=<a> def=<m(a)>
  1195. X                           <nnnn>
  1196. X0: m(1 2 3)
  1197. X :         
  1198. X1: 1 2 3
  1199. X :      
  1200. X0R: m(_)
  1201. X  :     
  1202. X0R: <<#a>>
  1203. X  : mmmmmm
  1204. Xstring "1 2 3" --> ""
  1205. X0R: <<"">>
  1206. X  : mmmmmm
  1207. X0: <<"">>
  1208. X : mmmmmm
  1209. X0: <<"">>
  1210. X :       
  1211. X0: m(z)
  1212. X :     
  1213. X1: z
  1214. X :  
  1215. X0R: m(_)
  1216. X  :     
  1217. X0R: <<#a>>
  1218. X  : mmmmmm
  1219. Xstring "z" --> ""
  1220. X0R: <<"">>
  1221. X  : mmmmmm
  1222. X0: <<"">>
  1223. X : mmmmmm
  1224. X0: <<"">>
  1225. X :       
  1226. X0: n(z)
  1227. X :     
  1228. X1: z
  1229. X :  
  1230. X0R: n(_)
  1231. X  :     
  1232. X0R: m(a)
  1233. X  : nnnn
  1234. X0R: m(z)
  1235. X  : nnnn
  1236. X0: m(z)
  1237. X : nnnn
  1238. X1: z
  1239. X : n
  1240. X0R: m(_)
  1241. X  :     
  1242. X0R: <<#a>>
  1243. X  : mmmmmm
  1244. Xstring "z" --> ""
  1245. X0R: <<"">>
  1246. X  : mmmmmm
  1247. Xhide-set #0 = {mn}
  1248. X0: <<"">>
  1249. X : 000000
  1250. X0: <<"">>
  1251. X :       
  1252. END-of-test6.out
  1253. echo file: test7.out
  1254. sed 's/^X//' >test7.out << 'END-of-test7.out'
  1255. Xfn:  nam=<e> parms=<ab> def=<[[a##b]]>
  1256. X                            <eeeeeeee>
  1257. X0: e(x,y)
  1258. X :       
  1259. X1: x
  1260. X :  
  1261. X2: y
  1262. X :  
  1263. X0R: e(_,_)
  1264. X  :       
  1265. X0R: [[a##b]]
  1266. X  : eeeeeeee
  1267. Xcatenate ab --> c
  1268. X0R: [[c]]
  1269. X  : eeeee
  1270. X0: [[c]]
  1271. X : eeeee
  1272. X0: [[c]]
  1273. X :      
  1274. END-of-test7.out
  1275. echo file: test8.out
  1276. sed 's/^X//' >test8.out << 'END-of-test8.out'
  1277. Xfn:  nam=<f> parms=<a> def=<a * g>
  1278. X                           <fffff>
  1279. Xfn:  nam=<g> parms=<a> def=<f(a)>
  1280. X                           <gggg>
  1281. X0: 
  1282. X : 
  1283. X0: 
  1284. X : 
  1285. X0: f(2)(9)
  1286. X :        
  1287. X1: 2
  1288. X :  
  1289. X0R: f(_)
  1290. X  :     
  1291. X0R: a * g
  1292. X  : fffff
  1293. X0R: 2 * g
  1294. X  : fffff
  1295. X0: 2 * g(9)
  1296. X : fffff   
  1297. X1: 9
  1298. X :  
  1299. X0R: g(_)
  1300. X  :     
  1301. X0R: f(a)
  1302. X  : gggg
  1303. X0R: f(9)
  1304. X  : gggg
  1305. Xhide-set #0 = {fg}
  1306. X0: 2 * f(9)
  1307. X : ffff0000
  1308. X0: 2 * F(9)
  1309. X : ffff0000
  1310. X0: 2 * f(9)
  1311. X :         
  1312. END-of-test8.out
  1313. exit
  1314. -- 
  1315.       Eric S. Raymond = eric@snark.uu.net    (mad mastermind of TMN-Netnews)
  1316.  
  1317.  
  1318. -- 
  1319. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1320. Use a domain-based address or give alternate paths, or you may lose out.
  1321.