home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume20
/
plum-ansi-macros
< prev
next >
Wrap
Text File
|
1989-10-22
|
27KB
|
1,314 lines
Subject: v20i048: Plum-Hall X3J11 macro explainer
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Eric S. Raymond <eric@snark.uu.net>
Posting-number: Volume 20, Issue 48
Archive-name: plum-ansi-macros
his is a tutorial program which illustrates how the Standard's
macro-expansion algorithm works. First, look at some of the .out files
to see the model of presentation of macro-expansion.
Then, look at the file mac.c for notes on the implementation. This is
not an elegant program. It was designed to illustrate the dynamics in
the minimum amount of C code. Forget about "information-hiding";
everything is a string of chars.
All of this directory is experimental, not intended to be authoritative,
and in no way an official opinion of the ANSI X3J11 committee.
Permissions:
Permission is granted for reproduction and use of this mac program,
provided that its enclosed authorship notice is reproduced entirely.
Tom Plum, Plum Hall Inc, 609-927-3770, uunet!plumhall!plum .
#!/bin/sh
: "This is a shell archive, meaning: "
: "1. Remove everything above the #! /bin/sh line. "
: "2. Save the resulting test in a file. "
: "3. Execute the file with /bin/sh (not csh) to create the files:"
: " READ.ME"
: " Makefile"
: " mac.c"
: " std1.in"
: " std2.in"
: " std3.in"
: " std4.in"
: " test1.in"
: " test2.in"
: " test5.in"
: " test6.in"
: " test7.in"
: " test8.in"
: " std1.out"
: " std2.out"
: " std3.out"
: " std4.out"
: " test1.out"
: " test2.out"
: " test5.out"
: " test6.out"
: " test7.out"
: " test8.out"
echo file: READ.ME
sed 's/^X//' >READ.ME << 'END-of-READ.ME'
XThe MAC demonstration program
X
XThis is a tutorial program which illustrates how the Standard's
Xmacro-expansion algorithm works. First, look at some of the .out files
Xto see the model of presentation of macro-expansion.
X
XThen, look at the file mac.c for notes on the implementation. This is
Xnot an elegant program. It was designed to illustrate the dynamics in
Xthe minimum amount of C code. Forget about "information-hiding";
Xeverything is a string of chars.
X
XAll of this directory is experimental, not intended to be authoritative,
Xand in no way an official opinion of the ANSI X3J11 committee.
X
X-----------------------
XPermissions:
X
X Permission is granted for reproduction and use of this mac program,
X provided that its enclosed authorship notice is reproduced entirely.
X
X
X Tom Plum, Plum Hall Inc, 609-927-3770, uunet!plumhall!plum .
END-of-READ.ME
echo file: Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
X#
X# Makefile for the Plum-Hall X3J11 macro untangler
X#
XSRC = Makefile mac.c
XIN = std[1234].in test[12345678].in
XOUT = std[1234].out test[12345678].out
X
Xmac: mac.c
X cc -g -o mac mac.c
X
XSUFFIXES: .out .in
X
X.in.out: mac
X mac <$*.in >$*.out
X
Xshar: READ.ME $(SRC) $(IN) $(OUT)
X shar READ.ME $(SRC) $(IN) $(OUT) >mac.shar
X
Xclean:
X rm -f mac mac.shar *~
END-of-Makefile
echo file: mac.c
sed 's/^X//' >mac.c << 'END-of-mac.c'
X/* macros - skeleton of macro expansion algorithm
X * Each token is one char (letter a-z).
X * Token-buffers are modeled by plain old char strings.
X * Each such buffer has another same-size buffer printed just under it,
X * which shows the "hide-set" associated with the token above it.
X * (The "hide-set" contains all the tokens that are non-replaceable.)
X * #define is #d (no space before or after #).
X * No attempt to model details of whitespace handling.
X * Two tokens, when catenated, produce "second token plus one".
X * "Stringize" is crudely stubbed; two quotes "" replace the string.
X * Does not handle empty actuals gracefully.
X * Does not span newlines in matching actuals.
X * Revisions:
X * 88/10/01: Identify the "replacement" buffer as "R".
X * 88/10/03: Handle the hide-set of actuals properly.
X * 88/10/03: Indicate where to refine for the exact (unspecified)
X * semantics of interactions of hide-sets in catenation
X */
X/*
X * First version written by Thomas Plum, Plum Hall Inc.
X * Subsequently revised by members of X3J11, the
X * ANSI C Standards Committee.
X * Permission is granted to reproduce and use this program,
X * for all purposes, provided that this notice is included.
X */
X
X/* First, 300+ lines of inelegant support routines, to about 363 ... */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#define TRACE(x) 0 /* or, printf x , if needed for debugging */
X#define OUT(x) printf x
X#define cpy_nam(p, q) (p[0] = *(q), p[1] = '\0', ++(q))
X#define eobuf(p) (*(p) == '\0')
X#define next(p, s) (strncmp(p, s, (length_matched = strlen(s))) == 0)
X#define advance(p) (p += length_matched)
X#define is_obj(p) in_set(obj.nam, *(p))
X#define is_fn(p) in_set(fn.nam, *(p))
X#define obj_def(p) obj.def[obj_num(p)][0]
X#define obj_num(p) (strchr(obj.nam, *(p)) - obj.nam)
X#define fn_def(p) fn.def[fn_num(p)][0]
X#define fn_num(p) (strchr(fn.nam, *(p)) - fn.nam)
X#define fn_parm_count(p) strlen(fn.parms[fn_num(p)])
X#define fn_parm_index(p, q) \
X (strchr(fn.parms[fn_num(p)], *(q)) - fn.parms[fn_num(p)])
X#define is_parm_name(p, q) in_set(fn.parms[fn_num(p)], *(q))
X#define in_set(p, c) (strchr(p, c) != 0)
X#define hide_set(p) *((char*)p + L)
X#define A 9 /* max # of macro args */
X#define D 26 /* max # of macro defs */
X#define L 100 /* max length of an input line or of a macro def */
Xint length_matched;
Xvoid diagram(), expand(), expand_fn(), set_hide(), listcpy();
Xvoid add_hide(), lower_case();
Xchar *h_set();
Xchar arg_patterns[10][24] =
X {
X "()",
X "(_)",
X "(_,_)",
X "(_,_,_)",
X "(_,_,_,_)",
X "(_,_,_,_,_)",
X "(_,_,_,_,_,_)",
X "(_,_,_,_,_,_,_)",
X "(_,_,_,_,_,_,_,_)",
X "(_,_,_,_,_,_,_,_,_)",
X };
Xchar next_token(p) char *p;
X {
X length_matched = 0;
X ++p;
X for (;;)
X {
X if (*p == ' ')
X ++p, ++length_matched;
X else if (*p == '\0')
X {
X printf("treating end-of-buffer as end-of-file\n");
X return *p;
X }
X else
X return *p;
X }
X }
X
Xvoid strip_blanks(p) char *p;
X {
X char *q = p;
X
X while (*p == ' ')
X ++p;
X /* now at first non-blank in p */
X while (*p != '\0') /* can't use strcpy because overlap */
X hide_set(q) = hide_set(p), *q++ = *p++;
X while (*--q == ' ')
X ;
X *++q = '\0', hide_set(q) = '\0';
X }
X
Xstruct obj { int n; char nam[D]; char def[D][2][L]; }
X obj = {0};
Xstruct fn { int n; char nam[D]; char def[D][2][L]; char parms[D][A]; }
X fn = {0};
X
Xvoid install_obj(nam, def) char *nam; char *def;
X {
X obj.nam[obj.n] = nam[0];
X strcpy(obj.def[obj.n][0], def);
X strip_blanks(obj.def[obj.n][0]);
X set_hide(obj.def[obj.n][0], nam);
X printf("obj: nam=<%s> def=<%s>\n", nam, obj.def[obj.n][0]);
X printf(" <%s>\n", obj.def[obj.n][1]);
X ++obj.n;
X }
X
Xvoid install_fn(nam, def, parms) char *nam; char *def; char *parms;
X {
X fn.nam[fn.n] = nam[0];
X strcpy(fn.def[fn.n][0], def);
X strcpy(fn.parms[fn.n], parms);
X strip_blanks(fn.def[fn.n][0]);
X set_hide(fn.def[fn.n][0], nam);
X printf("fn: nam=<%s> parms=<%s> def=<%s>\n", nam, parms, fn.def[fn.n][0]);
X printf(" %*s <%s>\n",
X strlen(parms), "", fn.def[fn.n][1]);
X ++fn.n;
X }
X
Xchar *parse_parms(p, parms) char *p; char *parms;
X {
X int i = 0;
X
X while (*p != ')')
X {
X if (*p != ' ' && *p != ',')
X parms[i++] = *p;
X ++p;
X }
X ++p;
X parms[i] = '\0';
X return p;
X }
X
X
X
Xvoid replace(level, suf, buf, p, p2, def) char *level, *suf, *buf, *p, *p2, *def;
X {
X char hold[2][L];
X char old_hide[2];
X
X listcpy(hold[0], p2);
X old_hide[0] = hide_set(p), old_hide[1] = '\0';
X listcpy(p, def);
X add_hide(p, old_hide);
X listcpy(p + strlen(def), hold[0]);
X diagram(level, buf, suf);
X }
Xchar *match_actuals(p, actual, n) char *p; char actual[A][2][L]; int n;
X {
X int parens = 1;
X int i = 0;
X int j = 0;
X
X TRACE(("match_actuals(<%s>, actual)\n", p));
X p += 1;
X /* past the '(' */
X
X for ( ;; )
X {
X if (*p == '(')
X {
X ++parens;
X actual[i][1][j] = p[L];
X actual[i][0][j++] = *p++;
X }
X else if (*p == ')')
X {
X --parens;
X if (parens == 0)
X break;
X actual[i][1][j] = p[L];
X actual[i][0][j++] = *p++;
X }
X else if (*p == ',' && parens == 1)
X {
X actual[i][1][j] = '\0';
X actual[i][0][j] = '\0';
X j = 0;
X ++i;
X ++p;
X }
X else
X {
X actual[i][1][j] = p[L];
X actual[i][0][j++] = *p++;
X }
X }
X actual[i][1][j] = '\0';
X actual[i][0][j] = '\0';
X /* should strip blanks on each actual, to be sure non-empty */
X if (i == 0 && n == 0)
X ; /* ok, no args */
X else if (i != n-1)
X {
X printf("wrong number of actuals\n");
X exit(2);
X }
X for (i = 0; i < n; ++i)
X TRACE(("actual[%d] = <%s>\n", i, actual[i][0]));
X return p+1;
X }
X
Xchar *stringize(s) char *s;
X {
X static char string_buf[2][L] = {"\"\"", " "};
X
X printf("string \"%s\" --> \"\"\n", s);
X return string_buf[0];
X }
X
Xchar *catenate(p, q) char *p, *q;
X {
X static char cat_buf[2][L];
X char old_hide[2];
X
X cat_buf[0][0] = q[0] + 1;
X cat_buf[0][1] = '\0';
X set_hide(cat_buf[0], " ");
X old_hide[0] = hide_set(p), old_hide[1] = '\0';
X add_hide(cat_buf[0], old_hide);
X old_hide[0] = hide_set(q), old_hide[1] = '\0';
X add_hide(cat_buf[0], old_hide); /* NOTE: The other "unspecified" */
X /* choice is to intersect(!) the */
X /* two hide-sets, as in Prosser */
X /* 86-196. */
X printf("catenate %c%c --> %c\n", p[0], q[0], cat_buf[0][0]);
X return cat_buf[0];
X }
X
Xvoid listcpy(p, q) char *p, *q;
X {
X strcpy(p, q);
X strcpy(&hide_set(p), &hide_set(q));
X }
X
Xvoid diagram(level, s, suf) char *level, *s, *suf;
X {
X char prefix[L];
X
X if (level[0] == '\0')
X strcpy(prefix, "0");
X else
X strcpy(prefix, level+1);
X printf("%s%s: %s\n", prefix, suf, s);
X printf("%*s%.*s\n", strlen(prefix)+strlen(suf)+2, ": ",
X strlen(s), &hide_set(s));
X }
X
Xint charcmp(s, t) char *s, *t;
X {
X return *s - *t;
X }
X
Xvoid set_hide(def, nam) char *def, *nam;
X {
X memset(&hide_set(def), nam[0], strlen(def));
X def[L+strlen(def)] = '\0';
X }
Xchar hide_sets[10][10] = {0};
Xint n_hide_sets = 0;
Xvoid add_hide(p, h) char *p, *h;
X {
X int i, lim;
X
X lim = strlen(p);
X for (i = 0; i < lim; ++i)
X {
X char c = p[L+i];
X char old_h[2];
X
X old_h[0] = c, old_h[1] = '\0';
X TRACE(("c=<%c>, h=<%c>\n", c, h[0]));
X if (h[0] == ' ')
X ;
X else if (c == ' ')
X p[L+i] = h[0];
X else if (h[0] == c)
X ;
X else if (in_set(h_set(old_h), h[0]))
X ;
X else
X {
X char new_hide[10];
X int n = n_hide_sets;
X int j;
X int found = 0;
X
X strcpy(new_hide, h_set(old_h));
X strcat(new_hide, h_set(h));
X qsort(new_hide, strlen(new_hide), 1, charcmp);
X TRACE(("new_hide=<%s>\n", new_hide));
X for (j = 0; j < n_hide_sets; ++j)
X {
X if (strcmp(new_hide, hide_sets[j]) == 0)
X {
X p[L+i] = j + '0';
X found = 1;
X }
X }
X if (!found)
X {
X if (n > 9)
X {
X printf("too many hide-sets\n");
X exit(2);
X }
X strcpy(hide_sets[n], new_hide);
X p[L+i] = n + '0';
X qsort(hide_sets[n], strlen(hide_sets[n]), 1, charcmp);
X printf("hide-set #%d = {%s}\n", n, hide_sets[n]);
X ++n_hide_sets;
X }
X }
X }
X }
X
Xchar *h_set(s) char *s;
X {
X char c = s[0];
X
X if (isdigit(c))
X return hide_sets[c - '0'];
X else
X return s;
X }
X
Xint is_hidden(p) char *p;
X {
X if (!islower(*p))
X return 0;
X else if (*p == p[L])
X return 1;
X else if (isdigit(p[L]) && strchr(hide_sets[p[L] - '0'], *p) != 0)
X return 1;
X else
X return 0;
X }
X
Xvoid mark_non_replace(p) char *p;
X {
X *p = toupper(*p);
X }
X
Xvoid lower_case(p) char *p;
X {
X for ( ; *p != '\0'; ++p)
X *p = tolower(*p);
X }
X
X
X/* Now: Here's the actual macro algorithm ... */
X
Xvoid preproc(p) char *p;
X {
X char nam[2];
X char parms[A];
X
X if (next(p, "#d "))
X { /* starting a #define */
X advance(p);
X TRACE(("p=<%s>\n", p));
X cpy_nam(nam, p);
X if (next(p, "(")) /* a fn-like macro */
X {
X advance(p);
X p = parse_parms(p, parms);
X install_fn(nam, p, parms);
X }
X else /* an object-like macro */
X install_obj(nam, p);
X } /* end of #define */
X else if (next(p, "#u "))
X { /* starting a #undef */
X } /* stub */
X else
X {
X expand(p, "");
X lower_case(p);
X set_hide(p, " ");
X diagram("", p, "");
X }
X }
Xvoid expand(buf, level) char *buf; char *level;
X {
X char *p = buf;
X
X TRACE(("expand(<%s>, %s)\n", buf, level));
X diagram(level, buf, "");
X while (!eobuf(p))
X {
X if (is_hidden(p))
X {
X mark_non_replace(p);
X ++p;
X diagram(level, buf, "");
X }
X else if (is_obj(p)) /* instance of object-like macro */
X replace(level, "", buf, p, p+1, obj_def(p));
X else if (is_fn(p) && next_token(p) == '(')
X expand_fn(buf, p, level); /* instance of fn-like macro */
X else
X ++p; /* ordinary token */
X } /* end while !eobuf */
X } /* end expand() */
X
X
X
X
X
X
Xvoid expand_fn(buf, p, level) char *buf, *p, *level;
X {
X char actual[A][2][L], expandeds[A][2][L];
X char repl[2][L];
X char nlevel[20];
X char fn_nam[2];
X char invocation[2][L];
X char *start_invok, *q;
X int i_parm, num_parms;
X
X start_invok = p;
X cpy_nam(fn_nam, p);
X advance(p); /* past any blanks skipped in next_token */
X num_parms = fn_parm_count(fn_nam);
X p = match_actuals(p, actual, num_parms);
X for (i_parm = 0; i_parm < num_parms; ++i_parm)
X {
X listcpy(expandeds[i_parm][0], actual[i_parm][0]);
X sprintf(nlevel, "%s.%d", level, i_parm+1);
X expand(expandeds[i_parm][0], nlevel);
X }
X sprintf(invocation[0], "%s%s", fn_nam, arg_patterns[num_parms]);
X set_hide(invocation[0], " ");
X diagram(level, invocation[0], "R");
X listcpy(repl[0], fn_def(fn_nam));
X diagram(level, repl[0], "R");
X TRACE(("subst parms in repl:<%s>\n", repl));
X for (q = repl[0]; !eobuf(q); )
X {
X TRACE(("repl-token <%c>\n", *q));
X if (q[1] == '#' && q[2] == '#' && !eobuf(q+3))
X {
X replace(level, "R", repl[0], q, q+4,
X catenate(q, q+3));
X q += 1; /* advance past new "token" */
X }
X else if (q[0] == '#' && is_parm_name(fn_nam, q+1))
X {
X i_parm = fn_parm_index(fn_nam, q+1);
X replace(level, "R", repl[0], q, q+2,
X stringize(actual[i_parm][0]));
X q += 2; /* advance past "" */
X }
X else if (is_parm_name(fn_nam, q))
X {
X i_parm = fn_parm_index(fn_nam, q);
X replace(level, "R", repl[0], q, q+1,
X expandeds[i_parm][0]);
X q += strlen(expandeds[i_parm][0]); /* advance past expansion */
X }
X else /* ordinary token */
X ++q;
X }
X replace(level, "", buf, start_invok, p, repl[0]);
X }
X
X
X
X
Xmain()
X {
X char line[BUFSIZ];
X
X while (gets(line))
X {
X set_hide(line, " ");
X preproc(line);
X }
X } /* end main */
END-of-mac.c
echo file: std1.in
sed 's/^X//' >std1.in << 'END-of-std1.in'
X#d f(a) f( x * (a))
X#d z z[0]
X#d x 2
Xf(y+1) + f(f(z)) %
END-of-std1.in
echo file: std2.in
sed 's/^X//' >std2.in << 'END-of-std2.in'
X#d f(a) f( x * (a))
X#d x 2
X#d g f
X#d t(a) a
Xt(t(g)(0) + t)(1);
END-of-std2.in
echo file: std3.in
sed 's/^X//' >std3.in << 'END-of-std3.in'
X#d f(a) f( x * (a))
X#d x 2
X#d g f
X#d w 0,1
X#d h g(~
X
Xg(x+(3,4)-w) | h 5)
END-of-std3.in
echo file: std4.in
sed 's/^X//' >std4.in << 'END-of-std4.in'
X#d f(a) f( x * (a))
X#d x 2
X#d m(a) a(w)
X#d w 0,1
X
Xm (f)^m(m) ;
END-of-std4.in
echo file: test1.in
sed 's/^X//' >test1.in << 'END-of-test1.in'
X#d x(c) (y(c,3))
X#d y(a, b) x(a+b)
Xy(x(2),1)
END-of-test1.in
echo file: test2.in
sed 's/^X//' >test2.in << 'END-of-test2.in'
X#d f(a) i(x*(a))
X#d j(a) k(x*(a))
X#d z y[0]
X#d x 2
Xf(j(z)) 3 4 z
X
X#d h(g) g
X#d a() 0
X#d b ()
X#d c a b
Xh(c)
X
X#d m(a) <<#a>>
X#d n(a) m(a)
Xm(1 2 3)
Xm(z)
Xn(z)
X
X#d e(a, b) [[a##b]]
Xe(x,y)
END-of-test2.in
echo file: test5.in
sed 's/^X//' >test5.in << 'END-of-test5.in'
X#d h(g) g
X#d a() 0
X#d b ()
X#d c a b
Xh(c)
END-of-test5.in
echo file: test6.in
sed 's/^X//' >test6.in << 'END-of-test6.in'
X#d m(a) <<#a>>
X#d n(a) m(a)
Xm(1 2 3)
Xm(z)
Xn(z)
END-of-test6.in
echo file: test7.in
sed 's/^X//' >test7.in << 'END-of-test7.in'
X#d e(a, b) [[a##b]]
Xe(x,y)
END-of-test7.in
echo file: test8.in
sed 's/^X//' >test8.in << 'END-of-test8.in'
X#d f(a) a * g
X#d g(a) f(a)
X
Xf(2)(9)
END-of-test8.in
echo file: std1.out
sed 's/^X//' >std1.out << 'END-of-std1.out'
Xfn: nam=<f> parms=<a> def=<f( x * (a))>
X <fffffffffff>
Xobj: nam=<z> def=<z[0]>
X <zzzz>
Xobj: nam=<x> def=<2>
X <x>
X0: f(y+1) + f(f(z)) %
X :
X1: y+1
X :
X0R: f(_)
X :
X0R: f( x * (a))
X : fffffffffff
X0R: f( x * (y+1))
X : fffffffffffff
X0: f( x * (y+1)) + f(f(z)) %
X : fffffffffffff
X0: F( x * (y+1)) + f(f(z)) %
X : fffffffffffff
Xhide-set #0 = {fx}
X0: F( 2 * (y+1)) + f(f(z)) %
X : fff0fffffffff
X1: f(z)
X :
X1.1: z
X :
X1.1: z[0]
X : zzzz
X1.1: Z[0]
X : zzzz
X1R: f(_)
X :
X1R: f( x * (a))
X : fffffffffff
Xhide-set #1 = {fz}
X1R: f( x * (Z[0]))
X : ffffffff1111ff
X1: f( x * (Z[0]))
X : ffffffff1111ff
X1: F( x * (Z[0]))
X : ffffffff1111ff
X1: F( 2 * (Z[0]))
X : fff0ffff1111ff
X0R: f(_)
X :
X0R: f( x * (a))
X : fffffffffff
X0R: f( x * (F( 2 * (Z[0]))))
X : fffffffffff0ffff1111ffff
X0: F( 2 * (y+1)) + f( x * (F( 2 * (Z[0])))) %
X : fff0fffffffff fffffffffff0ffff1111ffff
X0: F( 2 * (y+1)) + F( x * (F( 2 * (Z[0])))) %
X : fff0fffffffff fffffffffff0ffff1111ffff
X0: F( 2 * (y+1)) + F( 2 * (F( 2 * (Z[0])))) %
X : fff0fffffffff fff0fffffff0ffff1111ffff
X0: f( 2 * (y+1)) + f( 2 * (f( 2 * (z[0])))) %
X :
END-of-std1.out
echo file: std2.out
sed 's/^X//' >std2.out << 'END-of-std2.out'
Xfn: nam=<f> parms=<a> def=<f( x * (a))>
X <fffffffffff>
Xobj: nam=<x> def=<2>
X <x>
Xobj: nam=<g> def=<f>
X <g>
Xfn: nam=<t> parms=<a> def=<a>
X <t>
X0: t(t(g)(0) + t)(1);
X :
X1: t(g)(0) + t
X :
X1.1: g
X :
X1.1: f
X : g
Xtreating end-of-buffer as end-of-file
X1R: t(_)
X :
X1R: a
X : t
Xhide-set #0 = {gt}
X1R: f
X : 0
X1: f(0) + t
X : 0
X1.1: 0
X :
X1R: f(_)
X :
X1R: f( x * (a))
X : fffffffffff
X1R: f( x * (0))
X : fffffffffff
Xhide-set #1 = {fgt}
X1: f( x * (0)) + t
X : 11111111111
X1: F( x * (0)) + t
X : 11111111111
Xhide-set #2 = {fgtx}
X1: F( 2 * (0)) + t
X : 11121111111
Xtreating end-of-buffer as end-of-file
X0R: t(_)
X :
X0R: a
X : t
X0R: F( 2 * (0)) + t
X : 11121111111tttt
X0: F( 2 * (0)) + t(1);
X : 11121111111tttt
X0: F( 2 * (0)) + T(1);
X : 11121111111tttt
X0: f( 2 * (0)) + t(1);
X :
END-of-std2.out
echo file: std3.out
sed 's/^X//' >std3.out << 'END-of-std3.out'
Xfn: nam=<f> parms=<a> def=<f( x * (a))>
X <fffffffffff>
Xobj: nam=<x> def=<2>
X <x>
Xobj: nam=<g> def=<f>
X <g>
Xobj: nam=<w> def=<0,1>
X <www>
Xobj: nam=<h> def=<g(~>
X <hhh>
X0:
X :
X0:
X :
X0: g(x+(3,4)-w) | h 5)
X :
X0: f(x+(3,4)-w) | h 5)
X : g
X1: x+(3,4)-w
X :
X1: 2+(3,4)-w
X : x
X1: 2+(3,4)-0,1
X : x www
X0R: f(_)
X :
X0R: f( x * (a))
X : fffffffffff
Xhide-set #0 = {fx}
Xhide-set #1 = {fw}
X0R: f( x * (2+(3,4)-0,1))
X : ffffffff0fffffff111ff
Xhide-set #2 = {fg}
Xhide-set #3 = {fgx}
Xhide-set #4 = {fgw}
X0: f( x * (2+(3,4)-0,1)) | h 5)
X : 222222223222222244422
X0: F( x * (2+(3,4)-0,1)) | h 5)
X : 222222223222222244422
X0: F( 2 * (2+(3,4)-0,1)) | h 5)
X : 222322223222222244422
X0: F( 2 * (2+(3,4)-0,1)) | g(~ 5)
X : 222322223222222244422 hhh
Xhide-set #5 = {gh}
X0: F( 2 * (2+(3,4)-0,1)) | f(~ 5)
X : 222322223222222244422 5hh
X1: ~ 5
X : h
X0R: f(_)
X :
X0R: f( x * (a))
X : fffffffffff
Xhide-set #6 = {fh}
X0R: f( x * (~ 5))
X : ffffffff6ffff
Xhide-set #7 = {fgh}
Xhide-set #8 = {fghh}
X0: F( 2 * (2+(3,4)-0,1)) | f( x * (~ 5))
X : 222322223222222244422 7777777787777
X0: F( 2 * (2+(3,4)-0,1)) | F( x * (~ 5))
X : 222322223222222244422 7777777787777
Xhide-set #9 = {fghx}
X0: F( 2 * (2+(3,4)-0,1)) | F( 2 * (~ 5))
X : 222322223222222244422 7779777787777
X0: f( 2 * (2+(3,4)-0,1)) | f( 2 * (~ 5))
X :
END-of-std3.out
echo file: std4.out
sed 's/^X//' >std4.out << 'END-of-std4.out'
Xfn: nam=<f> parms=<a> def=<f( x * (a))>
X <fffffffffff>
Xobj: nam=<x> def=<2>
X <x>
Xfn: nam=<m> parms=<a> def=<a(w)>
X <mmmm>
Xobj: nam=<w> def=<0,1>
X <www>
X0:
X :
X0:
X :
X0: m (f)^m(m) ;
X :
X1: f
X :
Xtreating end-of-buffer as end-of-file
X0R: m(_)
X :
X0R: a(w)
X : mmmm
X0R: f(w)
X : mmmm
X0: f(w)^m(m) ;
X : mmmm
X1: w
X : m
Xhide-set #0 = {mw}
X1: 0,1
X : 000
X0R: f(_)
X :
X0R: f( x * (a))
X : fffffffffff
Xhide-set #1 = {fmw}
X0R: f( x * (0,1))
X : ffffffff111ff
Xhide-set #2 = {fm}
X0: f( x * (0,1))^m(m) ;
X : 2222222211122
X0: F( x * (0,1))^m(m) ;
X : 2222222211122
Xhide-set #3 = {fmx}
X0: F( 2 * (0,1))^m(m) ;
X : 2223222211122
X1: m
X :
Xtreating end-of-buffer as end-of-file
X0R: m(_)
X :
X0R: a(w)
X : mmmm
X0R: m(w)
X : mmmm
X0: F( 2 * (0,1))^m(w) ;
X : 2223222211122 mmmm
X0: F( 2 * (0,1))^M(w) ;
X : 2223222211122 mmmm
X0: F( 2 * (0,1))^M(0,1) ;
X : 2223222211122 mm000m
X0: f( 2 * (0,1))^m(0,1) ;
X :
END-of-std4.out
echo file: test1.out
sed 's/^X//' >test1.out << 'END-of-test1.out'
Xfn: nam=<x> parms=<c> def=<(y(c,3))>
X <xxxxxxxx>
Xfn: nam=<y> parms=<ab> def=<x(a+b)>
X <yyyyyy>
X0: y(x(2),1)
X :
X1: x(2)
X :
X1.1: 2
X :
X1R: x(_)
X :
X1R: (y(c,3))
X : xxxxxxxx
X1R: (y(2,3))
X : xxxxxxxx
X1: (y(2,3))
X : xxxxxxxx
X1.1: 2
X : x
X1.2: 3
X : x
X1R: y(_,_)
X :
X1R: x(a+b)
X : yyyyyy
Xhide-set #0 = {xy}
X1R: x(2+b)
X : yy0yyy
X1R: x(2+3)
X : yy0y0y
X1: (x(2+3))
X : x000000x
X1: (X(2+3))
X : x000000x
X2: 1
X :
X0R: y(_,_)
X :
X0R: x(a+b)
X : yyyyyy
X0R: x((X(2+3))+b)
X : yy00000000yyy
X0R: x((X(2+3))+1)
X : yy00000000yyy
X0: x((X(2+3))+1)
X : yy00000000yyy
X1: (X(2+3))+1
X : 00000000yy
X0R: x(_)
X :
X0R: (y(c,3))
X : xxxxxxxx
X0R: (y((X(2+3))+1,3))
X : xxx0000000000xxxx
X0: (y((X(2+3))+1,3))
X : 00000000000000000
X0: (Y((X(2+3))+1,3))
X : 00000000000000000
X0: (y((x(2+3))+1,3))
X :
END-of-test1.out
echo file: test2.out
sed 's/^X//' >test2.out << 'END-of-test2.out'
Xfn: nam=<f> parms=<a> def=<i(x*(a))>
X <ffffffff>
Xfn: nam=<j> parms=<a> def=<k(x*(a))>
X <jjjjjjjj>
Xobj: nam=<z> def=<y[0]>
X <zzzz>
Xobj: nam=<x> def=<2>
X <x>
X0: f(j(z)) 3 4 z
X :
X1: j(z)
X :
X1.1: z
X :
X1.1: y[0]
X : zzzz
X1R: j(_)
X :
X1R: k(x*(a))
X : jjjjjjjj
Xhide-set #0 = {jz}
X1R: k(x*(y[0]))
X : jjjjj0000jj
X1: k(x*(y[0]))
X : jjjjj0000jj
Xhide-set #1 = {jx}
X1: k(2*(y[0]))
X : jj1jj0000jj
X0R: f(_)
X :
X0R: i(x*(a))
X : ffffffff
Xhide-set #2 = {fj}
Xhide-set #3 = {fjx}
Xhide-set #4 = {fjz}
X0R: i(x*(k(2*(y[0]))))
X : fffff22322444422ff
X0: i(x*(k(2*(y[0])))) 3 4 z
X : fffff22322444422ff
Xhide-set #5 = {fx}
X0: i(2*(k(2*(y[0])))) 3 4 z
X : ff5ff22322444422ff
X0: i(2*(k(2*(y[0])))) 3 4 y[0]
X : ff5ff22322444422ff zzzz
X0: i(2*(k(2*(y[0])))) 3 4 y[0]
X :
X0:
X :
X0:
X :
Xfn: nam=<h> parms=<g> def=<g>
X <h>
Xfn: nam=<a> parms=<> def=<0>
X <a>
Xobj: nam=<b> def=<()>
X <bb>
Xobj: nam=<c> def=<a b>
X <ccc>
X0: h(c)
X :
X1: c
X :
X1: a b
X : ccc
Xhide-set #6 = {bc}
X1: a ()
X : cc66
X0R: h(_)
X :
X0R: g
X : h
Xhide-set #7 = {ch}
Xhide-set #8 = {bch}
X0R: a ()
X : 7788
X0: a ()
X : 7788
X0R: a()
X :
X0R: 0
X : a
Xhide-set #9 = {ach}
X0: 0
X : 9
X0: 0
X :
X0:
X :
X0:
X :
Xfn: nam=<m> parms=<a> def=<<<#a>>>
X <mmmmmm>
Xfn: nam=<n> parms=<a> def=<m(a)>
X <nnnn>
X0: m(1 2 3)
X :
X1: 1 2 3
X :
X0R: m(_)
X :
X0R: <<#a>>
X : mmmmmm
Xstring "1 2 3" --> ""
X0R: <<"">>
X : mmmmmm
X0: <<"">>
X : mmmmmm
X0: <<"">>
X :
X0: m(z)
X :
X1: z
X :
X1: y[0]
X : zzzz
X0R: m(_)
X :
X0R: <<#a>>
X : mmmmmm
Xstring "z" --> ""
X0R: <<"">>
X : mmmmmm
X0: <<"">>
X : mmmmmm
X0: <<"">>
X :
X0: n(z)
X :
X1: z
X :
X1: y[0]
X : zzzz
X0R: n(_)
X :
X0R: m(a)
X : nnnn
Xtoo many hide-sets
END-of-test2.out
echo file: test5.out
sed 's/^X//' >test5.out << 'END-of-test5.out'
Xfn: nam=<h> parms=<g> def=<g>
X <h>
Xfn: nam=<a> parms=<> def=<0>
X <a>
Xobj: nam=<b> def=<()>
X <bb>
Xobj: nam=<c> def=<a b>
X <ccc>
X0: h(c)
X :
X1: c
X :
X1: a b
X : ccc
Xhide-set #0 = {bc}
X1: a ()
X : cc00
X0R: h(_)
X :
X0R: g
X : h
Xhide-set #1 = {ch}
Xhide-set #2 = {bch}
X0R: a ()
X : 1122
X0: a ()
X : 1122
X0R: a()
X :
X0R: 0
X : a
Xhide-set #3 = {ach}
X0: 0
X : 3
X0: 0
X :
END-of-test5.out
echo file: test6.out
sed 's/^X//' >test6.out << 'END-of-test6.out'
Xfn: nam=<m> parms=<a> def=<<<#a>>>
X <mmmmmm>
Xfn: nam=<n> parms=<a> def=<m(a)>
X <nnnn>
X0: m(1 2 3)
X :
X1: 1 2 3
X :
X0R: m(_)
X :
X0R: <<#a>>
X : mmmmmm
Xstring "1 2 3" --> ""
X0R: <<"">>
X : mmmmmm
X0: <<"">>
X : mmmmmm
X0: <<"">>
X :
X0: m(z)
X :
X1: z
X :
X0R: m(_)
X :
X0R: <<#a>>
X : mmmmmm
Xstring "z" --> ""
X0R: <<"">>
X : mmmmmm
X0: <<"">>
X : mmmmmm
X0: <<"">>
X :
X0: n(z)
X :
X1: z
X :
X0R: n(_)
X :
X0R: m(a)
X : nnnn
X0R: m(z)
X : nnnn
X0: m(z)
X : nnnn
X1: z
X : n
X0R: m(_)
X :
X0R: <<#a>>
X : mmmmmm
Xstring "z" --> ""
X0R: <<"">>
X : mmmmmm
Xhide-set #0 = {mn}
X0: <<"">>
X : 000000
X0: <<"">>
X :
END-of-test6.out
echo file: test7.out
sed 's/^X//' >test7.out << 'END-of-test7.out'
Xfn: nam=<e> parms=<ab> def=<[[a##b]]>
X <eeeeeeee>
X0: e(x,y)
X :
X1: x
X :
X2: y
X :
X0R: e(_,_)
X :
X0R: [[a##b]]
X : eeeeeeee
Xcatenate ab --> c
X0R: [[c]]
X : eeeee
X0: [[c]]
X : eeeee
X0: [[c]]
X :
END-of-test7.out
echo file: test8.out
sed 's/^X//' >test8.out << 'END-of-test8.out'
Xfn: nam=<f> parms=<a> def=<a * g>
X <fffff>
Xfn: nam=<g> parms=<a> def=<f(a)>
X <gggg>
X0:
X :
X0:
X :
X0: f(2)(9)
X :
X1: 2
X :
X0R: f(_)
X :
X0R: a * g
X : fffff
X0R: 2 * g
X : fffff
X0: 2 * g(9)
X : fffff
X1: 9
X :
X0R: g(_)
X :
X0R: f(a)
X : gggg
X0R: f(9)
X : gggg
Xhide-set #0 = {fg}
X0: 2 * f(9)
X : ffff0000
X0: 2 * F(9)
X : ffff0000
X0: 2 * f(9)
X :
END-of-test8.out
exit
--
Eric S. Raymond = eric@snark.uu.net (mad mastermind of TMN-Netnews)