├── calc
├── tags
│ └── original
│ │ ├── calc.h
│ │ ├── calc.y
│ │ ├── code.c
│ │ ├── depend.c
│ │ ├── func.c
│ │ ├── gen.c
│ │ ├── main.c
│ │ ├── makefile
│ │ └── sym.c
└── trunk
│ ├── calc.h
│ ├── calc.y
│ ├── code.c
│ ├── depend.c
│ ├── func.c
│ ├── gen.c
│ ├── main.c
│ ├── makefile
│ └── sym.c
├── ez
├── tags
│ ├── old
│ │ ├── 8q.S
│ │ ├── BUGS
│ │ ├── TODO
│ │ ├── alloc.c
│ │ ├── bug.S
│ │ ├── bug11.S
│ │ ├── bug9.S
│ │ ├── cbook.S
│ │ ├── checkbook
│ │ ├── code.c
│ │ ├── ed.in
│ │ ├── ed.script
│ │ ├── editor.S
│ │ ├── editor1.S
│ │ ├── g.h
│ │ ├── hanoi.S
│ │ ├── init.c
│ │ ├── lc.S
│ │ ├── lex.c
│ │ ├── libf.c
│ │ ├── libutil.c
│ │ ├── main.c
│ │ ├── makefile
│ │ ├── s.g
│ │ ├── s.h
│ │ ├── s.y
│ │ ├── sem.c
│ │ ├── ssh
│ │ ├── sym.c
│ │ ├── table.c
│ │ ├── util.c
│ │ ├── wc.S
│ │ ├── wf.S
│ │ └── y.tab.h
│ └── original
│ │ ├── doc
│ │ ├── abstract
│ │ ├── cwfslides.tex
│ │ ├── ez.1
│ │ ├── makefile
│ │ ├── paper
│ │ ├── popl
│ │ ├── poplslides.tex
│ │ ├── popltalk.tex
│ │ ├── refman
│ │ ├── refman.1
│ │ ├── refman.2
│ │ ├── refman.3
│ │ ├── refman.4
│ │ ├── refman.5
│ │ ├── refman.a
│ │ ├── slides
│ │ ├── slides.tex
│ │ ├── slides1.tex
│ │ ├── slides2
│ │ ├── talk.tex
│ │ ├── texttalk
│ │ ├── tr81-13
│ │ └── tr84-2
│ │ ├── lib
│ │ ├── 8q.ez
│ │ ├── acker.ez
│ │ ├── array.ez
│ │ ├── box.ez
│ │ ├── cd.ez
│ │ ├── decode.ez
│ │ ├── directory.ez
│ │ ├── ed.ez
│ │ ├── edit.ez
│ │ ├── hanoi.ez
│ │ ├── init.ez
│ │ ├── lib.ez
│ │ ├── list.ez
│ │ ├── map.ez
│ │ ├── out.ez
│ │ ├── random.ez
│ │ ├── rpoints.ez
│ │ ├── sort.ez
│ │ ├── string.ez
│ │ ├── table.ez
│ │ ├── wc.ez
│ │ ├── wf.ez
│ │ └── z19.ez
│ │ └── src
│ │ ├── BUGS
│ │ ├── TODO
│ │ ├── cache.c
│ │ ├── code.c
│ │ ├── collect.c
│ │ ├── contents
│ │ ├── cvt.c
│ │ ├── expr.c
│ │ ├── ez.h
│ │ ├── func.c
│ │ ├── gen.c
│ │ ├── lex.c
│ │ ├── main.c
│ │ ├── makefile
│ │ ├── parse.c
│ │ ├── proc.c
│ │ ├── stmt.c
│ │ ├── table.c
│ │ ├── tokens.h
│ │ └── util.c
└── trunk
│ ├── doc
│ └── ez.1
│ ├── lib
│ ├── 8q.ez
│ ├── acker.ez
│ ├── array.ez
│ ├── box.ez
│ ├── cd.ez
│ ├── decode.ez
│ ├── directory.ez
│ ├── ed.ez
│ ├── edit.ez
│ ├── hanoi.ez
│ ├── init.ez
│ ├── lib.ez
│ ├── list.ez
│ ├── map.ez
│ ├── out.ez
│ ├── random.ez
│ ├── rpoints.ez
│ ├── sort.ez
│ ├── string.ez
│ ├── table.ez
│ ├── wc.ez
│ ├── wf.ez
│ └── z19.ez
│ └── src
│ ├── BUGS
│ ├── TODO
│ ├── cache.c
│ ├── code.c
│ ├── collect.c
│ ├── cvt.c
│ ├── expr.c
│ ├── ez.h
│ ├── func.c
│ ├── gen.c
│ ├── lex.c
│ ├── main.c
│ ├── makefile
│ ├── parse.c
│ ├── proc.c
│ ├── stmt.c
│ ├── table.c
│ ├── tokens.h
│ └── util.c
├── loom
├── tags
│ └── original
│ │ ├── README
│ │ ├── alloc.c
│ │ ├── common.c
│ │ ├── common.tex
│ │ ├── error.c
│ │ ├── index.tex
│ │ ├── loom.1
│ │ ├── loom.c
│ │ └── makefile
└── trunk
│ ├── README
│ ├── common.c
│ ├── common.tex
│ ├── index.tex
│ ├── loom.1
│ ├── loom.c
│ └── makefile
├── malloc
├── tags
│ └── original
│ │ ├── README
│ │ ├── flush.s
│ │ ├── index.ps
│ │ ├── makefile
│ │ ├── malloc.c
│ │ ├── memmon.1
│ │ ├── memmon.c
│ │ ├── memmon.h
│ │ ├── sym.c
│ │ ├── sym.h
│ │ └── trace.c
└── trunk
│ ├── README
│ ├── bug1.c
│ ├── bug2.c
│ ├── bug3.c
│ ├── index.html
│ ├── makefile
│ ├── malloc.c
│ ├── memmon.1
│ ├── memmon.c
│ ├── memmon.h
│ ├── sym.c
│ ├── sym.h
│ └── trace.c
├── tex
├── tags
│ └── original
│ │ ├── figplace.tex
│ │ ├── fontbl.tex
│ │ ├── fonts.tex
│ │ ├── letter.tex
│ │ ├── letterformat.tex
│ │ ├── listing.tex
│ │ ├── loommac.tex
│ │ ├── macros.tex
│ │ ├── psfonts.tex
│ │ └── spesample.tex
└── trunk
│ ├── figplace.tex
│ ├── fontbl.tex
│ ├── fonts.tex
│ ├── letter.tex
│ ├── letterformat.tex
│ ├── listing.tex
│ ├── loommac.tex
│ ├── macros.tex
│ ├── psfonts.tex
│ └── spesample.tex
└── treeIR
├── tags
└── original
│ ├── doc.tex
│ ├── tree.c
│ └── tree.h
└── trunk
├── doc.tex
├── makefile
├── tree.c
└── tree.h
/calc/tags/original/calc.h:
--------------------------------------------------------------------------------
1 | /* calc: definitions */
2 |
3 | /* limits */
4 | #define TOKSIZE 120 /* size of token string */
5 | #define HASHSIZE 119 /* hash table size */
6 |
7 | /* types */
8 | #define T_VOID 0 /* void */
9 | #define T_REAL 1 /* real */
10 | #define T_VAR 2 /* variable */
11 | #define T_STRING 3 /* string */
12 | #define T_TABLE 4 /* table */
13 |
14 | /* data structures */
15 | struct value {
16 | char type; /* datatype */
17 | union u_info { /* associated information */
18 | double u_double; /* real value */
19 | char *u_str; /* string */
20 | struct value *u_var; /* variable */
21 | struct table *u_tbl; /* table */
22 | unsigned u_other; /* everything else */
23 | } u_info;
24 | };
25 |
26 | #define real u_info.u_double /* abbreviations */
27 | #define string u_info.u_str
28 | #define var u_info.u_var
29 | #define tbl u_info.u_tbl
30 | #define other u_info.u_other
31 |
32 | struct table { /* tables (associative arrays) */
33 | int size; /* number of elements in the table */
34 | struct tnode *htab[37]; /* hash headers */
35 | };
36 | struct tnode { /* table entry */
37 | struct value index; /* index */
38 | struct value value; /* associated value */
39 | struct tnode *link; /* next entry on chain */
40 | };
41 |
42 | struct symbol { /* symbol table entries */
43 | char *name; /* entry name */
44 | struct value val; /* current value */
45 | struct dnode *depen; /* dependents */
46 | struct dnode *succ; /* successors */
47 | int count; /* predecessor count */
48 | union inst *code; /* pointer to code */
49 | struct value (*f)(); /* builtin function */
50 | union inst *fcode; /* pointer to function code */
51 | short amin; /* minimum number of arguments */
52 | short amax; /* maximum number of arguments */
53 | short offset; /* activation frame offset */
54 | short flags; /* flags (see below) */
55 | struct symbol *class; /* link to next entry in same class */
56 | struct symbol *link; /* link to next table entry */
57 | };
58 |
59 | struct dnode { /* dependency nodes */
60 | struct symbol *sym; /* depends on */
61 | struct dnode *link; /* next dnode */
62 | };
63 |
64 | union inst { /* "machine" instruction */
65 | int (*op)(); /* operator function */
66 | union inst *addr; /* link in backpatch list */
67 | int offset; /* jump offset */
68 | struct value *val; /* pointer to a constant */
69 | struct symbol *sym; /* pointer to symbol entry */
70 | };
71 |
72 | struct operator { /* operator information */
73 | int argc; /* expected number of arguments */
74 | int (*op)(); /* function */
75 | char *name; /* print name */
76 | };
77 |
78 | /* symbol table entry flags */
79 | #define CONST 01 /* symbol is a constant */
80 | #define FUNC 02 /* symbol is a function */
81 | #define BUILTIN 04 /* symbol is a builtin */
82 | #define DEFERRED 010 /* computation of symbol is deferred */
83 | #define GLOBAL 020 /* symbol is a global */
84 | #define LOCAL 040 /* symbol is a parameter or local */
85 | #define ARB 121 /* in amax, denotes arbitrary number of args */
86 |
87 | /* globals */
88 | struct value cvr();
89 | struct value cvs();
90 | struct value deref();
91 | struct value newvalue();
92 | double rnd();
93 | struct tnode *tindex();
94 | #undef atof
95 | double atof();
96 | char *alloc();
97 | struct symbol *lookup();
98 | struct symbol *install();
99 | struct symbol *new();
100 | char *strsave();
101 | struct dnode *add();
102 | struct dnode *append();
103 | struct dnode *dlist();
104 | struct dnode *tsort();
105 | union inst *dumpinst();
106 | union inst *savecode();
107 |
108 | extern int nerrors; /* error count */
109 | extern FILE *infp; /* input file */
110 | extern char *infile; /* input file name */
111 | extern int lineno; /* input line number */
112 | extern union inst *pc; /* location counter */
113 | extern union inst code[]; /* program code */
114 | extern char *progname; /* program name */
115 |
116 | /* built-in variables */
117 | #define trace Trace.real /* trace flag */
118 | extern struct value Trace;
119 |
--------------------------------------------------------------------------------
/calc/tags/original/depend.c:
--------------------------------------------------------------------------------
1 | /* calc: dependency analysis */
2 |
3 | #include
4 | #include "calc.h"
5 |
6 | static struct dnode *freelist = NULL; /* list of free dnodes */
7 | struct dnode *queue = NULL; /* computation order */
8 | struct symbol *current = NULL; /* current computation entry */
9 |
10 | extern struct value TraceCompute;
11 |
12 | /* add - add a to d if not already present, return new list */
13 | struct dnode *add(a, d)
14 | struct symbol *a;
15 | struct dnode *d;
16 | {
17 | struct dnode *dp;
18 |
19 | if ((dp = d) == NULL)
20 | return (dlist(a));
21 | do {
22 | dp = dp->link;
23 | if (dp->sym == a)
24 | return (d);
25 | } while (dp != d);
26 | return (append(d, dlist(a)));
27 | }
28 |
29 | /* append - append d2 to d1, return d2 */
30 | struct dnode *append(d1, d2)
31 | struct dnode *d1, *d2;
32 | {
33 | struct dnode *dp;
34 |
35 | if (d2 == NULL)
36 | return (d1);
37 | if (d1 == NULL)
38 | return (d2);
39 | dp = d2->link;
40 | d2->link = d1->link;
41 | d1->link = dp;
42 | return (d2);
43 | }
44 |
45 | /* compute - compute values for all variables on d */
46 | compute(d)
47 | struct dnode *d;
48 | {
49 | struct dnode *dp;
50 |
51 | if (dp = d)
52 | do {
53 | dp = dp->link;
54 | current = dp->sym;
55 | if (TraceCompute.real)
56 | fprintf(stderr, "computing %s = ",
57 | current->name);
58 | execute(current->code);
59 | if (TraceCompute.real) {
60 | image(current->val, "\n", stderr);
61 | TraceCompute.real--;
62 | }
63 | } while (dp != d);
64 | current = NULL;
65 | }
66 |
67 | /* dlist - create a 1-element dlist for p */
68 | struct dnode *dlist(p)
69 | struct symbol *p;
70 | {
71 | struct dnode *dp;
72 |
73 | if (dp = freelist)
74 | freelist = dp->link;
75 | else
76 | dp = (struct dnode *) alloc(sizeof(struct dnode));
77 | dp->sym = p;
78 | dp->link = dp;
79 | return (dp);
80 | }
81 |
82 | /* enter - enter relation a < b */
83 | enter(a, b)
84 | struct symbol *a, *b;
85 | {
86 | if ((a->flags&DEFERRED) == 0)
87 | return;
88 | b->count++;
89 | a->succ = add(b, a->succ);
90 | }
91 |
92 | /* printd - print dependency list d followed by s on fp (default stderr) */
93 | printd(d, s, fp)
94 | struct dnode *d;
95 | char *s;
96 | FILE *fp;
97 | {
98 | struct dnode *dp;
99 | int i;
100 |
101 | if (fp == NULL)
102 | fp = stderr;
103 | if (d) {
104 | dp = d;
105 | i = 0;
106 | do {
107 | dp = dp->link;
108 | if (dp == d)
109 | fprintf(fp, "%s", i >= 1 ? " and " : "");
110 | else if (i)
111 | fprintf(fp, ", ");
112 | fprintf(fp, "%s", dp->sym->name);
113 | i++;
114 | } while (dp != d);
115 | }
116 | if (s)
117 | fprintf(fp, "%s", s);
118 | }
119 |
120 | /* release - release dlist d */
121 | release(d)
122 | struct dnode *d;
123 | {
124 | struct dnode *dp;
125 |
126 | if (d) {
127 | dp = d->link;
128 | d->link = freelist;
129 | freelist = dp;
130 | }
131 | }
132 |
133 | /* tsort - topologically sort those symbols with flags and return list */
134 | struct dnode *tsort(flags)
135 | int flags;
136 | {
137 | int i, n;
138 | extern struct symbol *htab[];
139 | struct symbol *p;
140 | struct dnode *dp, *dp1, *q, *new;
141 |
142 | n = 0;
143 | for (i = 0; i < HASHSIZE; i++) /* create successor lists and counts */
144 | for (p = htab[i]; p; p = p->link)
145 | if (p->flags&flags) {
146 | if (dp1 = p->depen)
147 | do {
148 | dp1 = dp1->link;
149 | enter(dp1->sym, p);
150 | } while (dp1 != p->depen);
151 | n++;
152 | }
153 | if (n == 0)
154 | return (NULL);
155 | if (TraceCompute.real) {
156 | fprintf(stderr, "sorting\n");
157 | TraceCompute.real--;
158 | }
159 | q = NULL;
160 | for (i = 0; i < HASHSIZE; i++) /* find zero counts, build queue */
161 | for (p = htab[i]; p; p = p->link)
162 | if ((p->flags&flags) && p->count == 0)
163 | q = append(q, dlist(p));
164 | new = NULL;
165 | while (q) { /* build new list in topogical order */
166 | dp = q->link;
167 | if (dp == q)
168 | q = NULL;
169 | else
170 | q->link = dp->link;
171 | new = append(new, dlist(dp->sym));
172 | n--;
173 | if (dp1 = dp->sym->succ)
174 | do {
175 | dp1 = dp1->link;
176 | if (--dp1->sym->count == 0)
177 | q = append(q, dlist(dp1->sym));
178 | } while (dp1 != dp->sym->succ);
179 | release(dp->sym->succ);
180 | dp->sym->succ = NULL;
181 | dp->link = freelist;
182 | freelist = dp;
183 | }
184 | if (n) {
185 | for (i = 0; i < HASHSIZE; i++) /* clean counts & lists */
186 | for (p = htab[i]; p; p = p->link)
187 | if (p->flags&flags) {
188 | p->count == 0;
189 | release(p->succ);
190 | p->succ = NULL;
191 | }
192 | fprintf(stderr, "partial list is ");
193 | printd(new, "\n", stderr);
194 | release(new);
195 | runtimeError("circular dependencies", "", NULL);
196 | }
197 | return (new);
198 | }
199 |
200 |
--------------------------------------------------------------------------------
/calc/tags/original/gen.c:
--------------------------------------------------------------------------------
1 | /* calc: code generation */
2 |
3 | #include
4 | #include "calc.h"
5 | #include "y.tab.h"
6 |
7 | union inst *pc; /* location counter */
8 | union inst code[1000]; /* program code */
9 |
10 | /* backpatch - fill in offsets to pc starting at p */
11 | backpatch(p, pc)
12 | union inst *p, *pc;
13 | {
14 | union inst *q;
15 |
16 | for ( ; p; p = q) {
17 | q = p->addr;
18 | p->offset = pc - p;
19 | }
20 | }
21 |
22 | /* copycode - copy n code elements */
23 | copycode(n, from, to)
24 | int n;
25 | union inst *from, *to;
26 | {
27 | while (n--)
28 | *to++ = *from++;
29 | }
30 |
31 | /* dumpcode - print code beginning at pc to fp, default stderr */
32 | dumpcode(pc, fp)
33 | union inst *pc;
34 | FILE *fp;
35 | {
36 | extern End();
37 | union inst *base, *p, *dumpinst();
38 |
39 | if (fp == NULL)
40 | fp = stderr;
41 | for (base = pc; pc && pc->offset; pc = p) {
42 | p = dumpinst(pc, base, fp);
43 | if (pc->op == End)
44 | break;
45 | }
46 | }
47 |
48 | /* dumpinst - print instruction at pc on fp, default stderr, return new pc */
49 | union inst *dumpinst(pc, base, fp)
50 | union inst *pc, *base;
51 | FILE *fp;
52 | {
53 | extern struct operator opnames[];
54 | int i;
55 |
56 | if (fp == NULL)
57 | fp = stderr;
58 | fprintf(fp, "%d:\t", pc - base);
59 | for (i = 0; opnames[i].op; i++)
60 | if (pc->op == opnames[i].op)
61 | break;
62 | if (opnames[i].op) {
63 | fprintf(fp, "%s", opnames[i].name);
64 | if (opnames[i].argc >= 1)
65 | if ((++pc)->sym->flags&CONST) {
66 | fprintf(fp, " ");
67 | image(pc->sym->val, "", fp);
68 | }
69 | else
70 | fprintf(fp, " %s", pc->sym->name);
71 | if (opnames[i].argc >= 2)
72 | fprintf(fp, " %d", (++pc)->op);
73 | if (opnames[i].argc < 0)
74 | for (i = opnames[i].argc; i < 0; i++) {
75 | pc++;
76 | fprintf(fp, " %d", pc+pc->offset - base);
77 | }
78 | fprintf(fp, "\n");
79 | }
80 | else
81 | fprintf(fp, "%0o\n", pc->op);
82 | return (++pc);
83 | }
84 |
85 | /* emit - emit x into code */
86 | emit(x)
87 | union inst x;
88 | {
89 | if (pc >= &code[sizeof(code)/sizeof(union inst)])
90 | error("system error", " in emit: code overflow");
91 | *pc++ = x;
92 | }
93 |
94 | /* savecode - save code generated up to pc */
95 | union inst *savecode(pc)
96 | union inst *pc;
97 | {
98 | union inst *new;
99 |
100 | new = (union inst *) alloc((pc-code)*sizeof(union inst));
101 | copycode(pc - code, code, new);
102 | return (new);
103 | }
104 |
--------------------------------------------------------------------------------
/calc/tags/original/main.c:
--------------------------------------------------------------------------------
1 | /* calc: main program */
2 |
3 | #include
4 | #include
5 | #include "calc.h"
6 | #include
7 | #include
8 |
9 | jmp_buf restart; /* to restart after runtime errors */
10 | int debug; /* debugging bits */
11 | char *progname = "";
12 | extern struct value Trace, Tracecode, TraceCompute;
13 | static void onintr();
14 |
15 | /* main program - parse expressions */
16 | main(argc, argv)
17 | int argc;
18 | char *argv[];
19 | {
20 | #ifdef __LCC__
21 | void (*isig)();
22 | #else
23 | int (*isig)();
24 | #endif
25 | int nf;
26 |
27 | progname = *argv;
28 | isig = signal(SIGINT, SIG_IGN);
29 | debug = 0;
30 | setjmp(restart);
31 | if (isig != SIG_IGN)
32 | signal(SIGINT, onintr);
33 | init();
34 | for (nf = 0; --argc > 0; )
35 | if (strcmp(*++argv, "-d") == 0)
36 | debug++;
37 | else if (strcmp(*argv, "-trace") == 0)
38 | trace = -1.0;
39 | else if (strcmp(*argv, "-tracecode") == 0)
40 | Tracecode.real = -1.0;
41 | else if (strcmp(*argv, "-tracecompute") == 0)
42 | TraceCompute.real = -1.0;
43 | else if (strcmp(*argv, "-traceexecute") == 0)
44 | TraceCompute.real = -1.0;
45 | else
46 | run(*argv), nf++;
47 | if (nf == 0)
48 | run("-");
49 | return (0);
50 | }
51 |
52 | /* init - initialize */
53 | init()
54 | {
55 | extern struct symbol *Show, *Table;
56 |
57 | initsym();
58 | initbuiltin(); /* built-in functions */
59 | Show = lookup(strsave("show"), GLOBAL);
60 | Table = lookup(strsave("table"), GLOBAL);
61 | }
62 |
63 | /* onintr - called on Interrupt signal */
64 | static void onintr()
65 | {
66 | fprintf(stderr, "\nInterrupt\n");
67 | longjmp(restart, 1);
68 | }
69 |
70 | /* run - execute file s */
71 | run(s)
72 | char *s;
73 | {
74 | infile = s;
75 | lineno = 1;
76 | nerrors = 0;
77 | if (strcmp(s, "-") == 0) {
78 | infp = stdin;
79 | infile = NULL;
80 | }
81 | else if ((infp = fopen(s, "r")) == NULL) {
82 | fprintf(stderr, "%s: can't open %s\n", progname, s);
83 | return;
84 | }
85 | setjmp(restart);
86 | pc = code;
87 | while (yyparse()) {
88 | if (Tracecode.real) {
89 | dumpcode(code, stderr);
90 | Tracecode.real--;
91 | }
92 | execute(pc = code);
93 | }
94 | if (infp != stdin)
95 | fclose(infp);
96 | }
97 |
--------------------------------------------------------------------------------
/calc/tags/original/makefile:
--------------------------------------------------------------------------------
1 | CC=lcc
2 | CFLAGS=-g
3 | YFLAGS=-d
4 | FILES=calc.h calc.y code.c depend.c func.c gen.c main.c sym.c
5 | OBJECTS=calc.o code.o func.o depend.o gen.o main.o sym.o
6 |
7 | a.out: $(OBJECTS) makefile
8 | $(CC) -g $(OBJECTS) -lm
9 |
10 | $(OBJECTS): calc.h
11 |
12 | code.o gen.o: x.tab.h
13 |
14 | x.tab.h: y.tab.h
15 | -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
16 | clean:
17 | rm -f $(OBJECTS) a.out *.CKP y.output [xy].tab.*
18 |
19 | list: $(FILES) makefile
20 | @enscript -2r $(FILES) makefile
21 |
--------------------------------------------------------------------------------
/calc/trunk/calc.h:
--------------------------------------------------------------------------------
1 | /* calc: definitions */
2 |
3 | /* limits */
4 | #define TOKSIZE 120 /* size of token string */
5 | #define HASHSIZE 119 /* hash table size */
6 |
7 | /* types */
8 | #define T_VOID 0 /* void */
9 | #define T_REAL 1 /* real */
10 | #define T_VAR 2 /* variable */
11 | #define T_STRING 3 /* string */
12 | #define T_TABLE 4 /* table */
13 |
14 | /* data structures */
15 | struct value {
16 | char type; /* datatype */
17 | union u_info { /* associated information */
18 | double u_double; /* real value */
19 | char *u_str; /* string */
20 | struct value *u_var; /* variable */
21 | struct table *u_tbl; /* table */
22 | unsigned u_other; /* everything else */
23 | } u_info;
24 | };
25 |
26 | #define real u_info.u_double /* abbreviations */
27 | #define string u_info.u_str
28 | #define var u_info.u_var
29 | #define tbl u_info.u_tbl
30 | #define other u_info.u_other
31 |
32 | struct table { /* tables (associative arrays) */
33 | int size; /* number of elements in the table */
34 | struct tnode *htab[37]; /* hash headers */
35 | };
36 | struct tnode { /* table entry */
37 | struct value index; /* index */
38 | struct value value; /* associated value */
39 | struct tnode *link; /* next entry on chain */
40 | };
41 |
42 | struct symbol { /* symbol table entries */
43 | char *name; /* entry name */
44 | struct value val; /* current value */
45 | struct dnode *depen; /* dependents */
46 | struct dnode *succ; /* successors */
47 | int count; /* predecessor count */
48 | union inst *code; /* pointer to code */
49 | struct value (*f)(); /* builtin function */
50 | union inst *fcode; /* pointer to function code */
51 | short amin; /* minimum number of arguments */
52 | short amax; /* maximum number of arguments */
53 | short offset; /* activation frame offset */
54 | short flags; /* flags (see below) */
55 | struct symbol *class; /* link to next entry in same class */
56 | struct symbol *link; /* link to next table entry */
57 | };
58 |
59 | struct dnode { /* dependency nodes */
60 | struct symbol *sym; /* depends on */
61 | struct dnode *link; /* next dnode */
62 | };
63 |
64 | union inst { /* "machine" instruction */
65 | int (*op)(); /* operator function */
66 | union inst *addr; /* link in backpatch list */
67 | int offset; /* jump offset */
68 | struct value *val; /* pointer to a constant */
69 | struct symbol *sym; /* pointer to symbol entry */
70 | };
71 |
72 | struct operator { /* operator information */
73 | int argc; /* expected number of arguments */
74 | int (*op)(); /* function */
75 | char *name; /* print name */
76 | };
77 |
78 | /* symbol table entry flags */
79 | #define CONST 01 /* symbol is a constant */
80 | #define FUNC 02 /* symbol is a function */
81 | #define BUILTIN 04 /* symbol is a builtin */
82 | #define DEFERRED 010 /* computation of symbol is deferred */
83 | #define GLOBAL 020 /* symbol is a global */
84 | #define LOCAL 040 /* symbol is a parameter or local */
85 | #define ARB 121 /* in amax, denotes arbitrary number of args */
86 |
87 | /* globals */
88 | struct value cvr();
89 | struct value cvs();
90 | struct value deref();
91 | struct value newvalue();
92 | double rnd();
93 | struct tnode *tindex();
94 | #undef atof
95 | double atof();
96 | void *alloc();
97 | struct symbol *lookup();
98 | struct symbol *install();
99 | struct symbol *new();
100 | char *strsave();
101 | struct dnode *add();
102 | struct dnode *append();
103 | struct dnode *dlist();
104 | struct dnode *tsort();
105 | union inst *dumpinst();
106 | union inst *savecode();
107 |
108 | extern int nerrors; /* error count */
109 | extern FILE *infp; /* input file */
110 | extern char *infile; /* input file name */
111 | extern int lineno; /* input line number */
112 | extern union inst *pc; /* location counter */
113 | extern union inst code[]; /* program code */
114 | extern char *progname; /* program name */
115 |
116 | /* built-in variables */
117 | #define trace Trace.real /* trace flag */
118 | extern struct value Trace;
119 |
--------------------------------------------------------------------------------
/calc/trunk/depend.c:
--------------------------------------------------------------------------------
1 | /* calc: dependency analysis */
2 |
3 | #include
4 | #include "calc.h"
5 |
6 | static struct dnode *freelist = NULL; /* list of free dnodes */
7 | struct dnode *queue = NULL; /* computation order */
8 | struct symbol *current = NULL; /* current computation entry */
9 |
10 | extern struct value TraceCompute;
11 |
12 | /* add - add a to d if not already present, return new list */
13 | struct dnode *add(a, d)
14 | struct symbol *a;
15 | struct dnode *d;
16 | {
17 | struct dnode *dp;
18 |
19 | if ((dp = d) == NULL)
20 | return (dlist(a));
21 | do {
22 | dp = dp->link;
23 | if (dp->sym == a)
24 | return (d);
25 | } while (dp != d);
26 | return (append(d, dlist(a)));
27 | }
28 |
29 | /* append - append d2 to d1, return d2 */
30 | struct dnode *append(d1, d2)
31 | struct dnode *d1, *d2;
32 | {
33 | struct dnode *dp;
34 |
35 | if (d2 == NULL)
36 | return (d1);
37 | if (d1 == NULL)
38 | return (d2);
39 | dp = d2->link;
40 | d2->link = d1->link;
41 | d1->link = dp;
42 | return (d2);
43 | }
44 |
45 | /* compute - compute values for all variables on d */
46 | compute(d)
47 | struct dnode *d;
48 | {
49 | struct dnode *dp;
50 |
51 | if (dp = d)
52 | do {
53 | dp = dp->link;
54 | current = dp->sym;
55 | if (TraceCompute.real)
56 | fprintf(stderr, "computing %s = ",
57 | current->name);
58 | execute(current->code);
59 | if (TraceCompute.real) {
60 | image(current->val, "\n", stderr);
61 | TraceCompute.real--;
62 | }
63 | } while (dp != d);
64 | current = NULL;
65 | }
66 |
67 | /* dlist - create a 1-element dlist for p */
68 | struct dnode *dlist(p)
69 | struct symbol *p;
70 | {
71 | struct dnode *dp;
72 |
73 | if (dp = freelist)
74 | freelist = dp->link;
75 | else
76 | dp = alloc(sizeof(struct dnode));
77 | dp->sym = p;
78 | dp->link = dp;
79 | return (dp);
80 | }
81 |
82 | /* enter - enter relation a < b */
83 | enter(a, b)
84 | struct symbol *a, *b;
85 | {
86 | if ((a->flags&DEFERRED) == 0)
87 | return;
88 | b->count++;
89 | a->succ = add(b, a->succ);
90 | }
91 |
92 | /* printd - print dependency list d followed by s on fp (default stderr) */
93 | printd(d, s, fp)
94 | struct dnode *d;
95 | char *s;
96 | FILE *fp;
97 | {
98 | struct dnode *dp;
99 | int i;
100 |
101 | if (fp == NULL)
102 | fp = stderr;
103 | if (d) {
104 | dp = d;
105 | i = 0;
106 | do {
107 | dp = dp->link;
108 | if (dp == d)
109 | fprintf(fp, "%s", i >= 1 ? " and " : "");
110 | else if (i)
111 | fprintf(fp, ", ");
112 | fprintf(fp, "%s", dp->sym->name);
113 | i++;
114 | } while (dp != d);
115 | }
116 | if (s)
117 | fprintf(fp, "%s", s);
118 | }
119 |
120 | /* release - release dlist d */
121 | release(d)
122 | struct dnode *d;
123 | {
124 | struct dnode *dp;
125 |
126 | if (d) {
127 | dp = d->link;
128 | d->link = freelist;
129 | freelist = dp;
130 | }
131 | }
132 |
133 | /* tsort - topologically sort those symbols with flags and return list */
134 | struct dnode *tsort(flags)
135 | int flags;
136 | {
137 | int i, n;
138 | extern struct symbol *htab[];
139 | struct symbol *p;
140 | struct dnode *dp, *dp1, *q, *new;
141 |
142 | n = 0;
143 | for (i = 0; i < HASHSIZE; i++) /* create successor lists and counts */
144 | for (p = htab[i]; p; p = p->link)
145 | if (p->flags&flags) {
146 | if (dp1 = p->depen)
147 | do {
148 | dp1 = dp1->link;
149 | enter(dp1->sym, p);
150 | } while (dp1 != p->depen);
151 | n++;
152 | }
153 | if (n == 0)
154 | return (NULL);
155 | if (TraceCompute.real) {
156 | fprintf(stderr, "sorting\n");
157 | TraceCompute.real--;
158 | }
159 | q = NULL;
160 | for (i = 0; i < HASHSIZE; i++) /* find zero counts, build queue */
161 | for (p = htab[i]; p; p = p->link)
162 | if ((p->flags&flags) && p->count == 0)
163 | q = append(q, dlist(p));
164 | new = NULL;
165 | while (q) { /* build new list in topogical order */
166 | dp = q->link;
167 | if (dp == q)
168 | q = NULL;
169 | else
170 | q->link = dp->link;
171 | new = append(new, dlist(dp->sym));
172 | n--;
173 | if (dp1 = dp->sym->succ)
174 | do {
175 | dp1 = dp1->link;
176 | if (--dp1->sym->count == 0)
177 | q = append(q, dlist(dp1->sym));
178 | } while (dp1 != dp->sym->succ);
179 | release(dp->sym->succ);
180 | dp->sym->succ = NULL;
181 | dp->link = freelist;
182 | freelist = dp;
183 | }
184 | if (n) {
185 | for (i = 0; i < HASHSIZE; i++) /* clean counts & lists */
186 | for (p = htab[i]; p; p = p->link)
187 | if (p->flags&flags) {
188 | p->count == 0;
189 | release(p->succ);
190 | p->succ = NULL;
191 | }
192 | fprintf(stderr, "partial list is ");
193 | printd(new, "\n", stderr);
194 | release(new);
195 | runtimeError("circular dependencies", "", NULL);
196 | }
197 | return (new);
198 | }
199 |
200 |
--------------------------------------------------------------------------------
/calc/trunk/gen.c:
--------------------------------------------------------------------------------
1 | /* calc: code generation */
2 |
3 | #include
4 | #include "calc.h"
5 | #include "y.tab.h"
6 |
7 | union inst *pc; /* location counter */
8 | union inst code[1000]; /* program code */
9 |
10 | /* backpatch - fill in offsets to pc starting at p */
11 | backpatch(p, pc)
12 | union inst *p, *pc;
13 | {
14 | union inst *q;
15 |
16 | for ( ; p; p = q) {
17 | q = p->addr;
18 | p->offset = pc - p;
19 | }
20 | }
21 |
22 | /* copycode - copy n code elements */
23 | copycode(n, from, to)
24 | int n;
25 | union inst *from, *to;
26 | {
27 | while (n--)
28 | *to++ = *from++;
29 | }
30 |
31 | /* dumpcode - print code beginning at pc to fp, default stderr */
32 | dumpcode(pc, fp)
33 | union inst *pc;
34 | FILE *fp;
35 | {
36 | extern End();
37 | union inst *base, *p, *dumpinst();
38 |
39 | if (fp == NULL)
40 | fp = stderr;
41 | for (base = pc; pc && pc->offset; pc = p) {
42 | p = dumpinst(pc, base, fp);
43 | if (pc->op == End)
44 | break;
45 | }
46 | }
47 |
48 | /* dumpinst - print instruction at pc on fp, default stderr, return new pc */
49 | union inst *dumpinst(pc, base, fp)
50 | union inst *pc, *base;
51 | FILE *fp;
52 | {
53 | extern struct operator opnames[];
54 | int i;
55 |
56 | if (fp == NULL)
57 | fp = stderr;
58 | fprintf(fp, "%d:\t", pc - base);
59 | for (i = 0; opnames[i].op; i++)
60 | if (pc->op == opnames[i].op)
61 | break;
62 | if (opnames[i].op) {
63 | fprintf(fp, "%s", opnames[i].name);
64 | if (opnames[i].argc >= 1)
65 | if ((++pc)->sym->flags&CONST) {
66 | fprintf(fp, " ");
67 | image(pc->sym->val, "", fp);
68 | }
69 | else
70 | fprintf(fp, " %s", pc->sym->name);
71 | if (opnames[i].argc >= 2)
72 | fprintf(fp, " %d", (++pc)->op);
73 | if (opnames[i].argc < 0)
74 | for (i = opnames[i].argc; i < 0; i++) {
75 | pc++;
76 | fprintf(fp, " %d", pc+pc->offset - base);
77 | }
78 | fprintf(fp, "\n");
79 | }
80 | else
81 | fprintf(fp, "%0o\n", pc->op);
82 | return (++pc);
83 | }
84 |
85 | /* emit - emit x into code */
86 | emit(x)
87 | union inst x;
88 | {
89 | if (pc >= &code[sizeof(code)/sizeof(union inst)])
90 | error("system error", " in emit: code overflow");
91 | *pc++ = x;
92 | }
93 |
94 | /* savecode - save code generated up to pc */
95 | union inst *savecode(pc)
96 | union inst *pc;
97 | {
98 | union inst *new;
99 |
100 | new = alloc((pc-code)*sizeof(union inst));
101 | copycode(pc - code, code, new);
102 | return (new);
103 | }
104 |
--------------------------------------------------------------------------------
/calc/trunk/main.c:
--------------------------------------------------------------------------------
1 | /* calc: main program */
2 |
3 | #include
4 | #include
5 | #include "calc.h"
6 | #include
7 | #include
8 |
9 | jmp_buf restart; /* to restart after runtime errors */
10 | int debug; /* debugging bits */
11 | char *progname = "";
12 | extern struct value Trace, Tracecode, TraceCompute;
13 | static void onintr();
14 |
15 | /* main program - parse expressions */
16 | main(argc, argv)
17 | int argc;
18 | char *argv[];
19 | {
20 | void (*isig)();
21 | int nf;
22 |
23 | progname = *argv;
24 | isig = signal(SIGINT, SIG_IGN);
25 | debug = 0;
26 | setjmp(restart);
27 | if (isig != SIG_IGN)
28 | signal(SIGINT, onintr);
29 | init();
30 | for (nf = 0; --argc > 0; )
31 | if (strcmp(*++argv, "-d") == 0)
32 | debug++;
33 | else if (strcmp(*argv, "-trace") == 0)
34 | trace = -1.0;
35 | else if (strcmp(*argv, "-tracecode") == 0)
36 | Tracecode.real = -1.0;
37 | else if (strcmp(*argv, "-tracecompute") == 0)
38 | TraceCompute.real = -1.0;
39 | else if (strcmp(*argv, "-traceexecute") == 0)
40 | TraceCompute.real = -1.0;
41 | else
42 | run(*argv), nf++;
43 | if (nf == 0)
44 | run("-");
45 | return (0);
46 | }
47 |
48 | /* init - initialize */
49 | init()
50 | {
51 | extern struct symbol *Show, *Table;
52 |
53 | initsym();
54 | initbuiltin(); /* built-in functions */
55 | Show = lookup(strsave("show"), GLOBAL);
56 | Table = lookup(strsave("table"), GLOBAL);
57 | }
58 |
59 | /* onintr - called on Interrupt signal */
60 | static void onintr()
61 | {
62 | fprintf(stderr, "\nInterrupt\n");
63 | longjmp(restart, 1);
64 | }
65 |
66 | /* run - execute file s */
67 | run(s)
68 | char *s;
69 | {
70 | infile = s;
71 | lineno = 1;
72 | nerrors = 0;
73 | if (strcmp(s, "-") == 0) {
74 | infp = stdin;
75 | infile = NULL;
76 | }
77 | else if ((infp = fopen(s, "r")) == NULL) {
78 | fprintf(stderr, "%s: can't open %s\n", progname, s);
79 | return;
80 | }
81 | setjmp(restart);
82 | pc = code;
83 | while (yyparse()) {
84 | if (Tracecode.real) {
85 | dumpcode(code, stderr);
86 | Tracecode.real--;
87 | }
88 | execute(pc = code);
89 | }
90 | if (infp != stdin)
91 | fclose(infp);
92 | }
93 |
--------------------------------------------------------------------------------
/calc/trunk/makefile:
--------------------------------------------------------------------------------
1 | CC=cc
2 | CFLAGS=-g
3 | YFLAGS=-d
4 | FILES=calc.h calc.y code.c depend.c func.c gen.c main.c sym.c
5 | OBJECTS=calc.o code.o func.o depend.o gen.o main.o sym.o
6 |
7 | a.out: $(OBJECTS) makefile
8 | $(CC) -g $(OBJECTS) -lm
9 |
10 | $(OBJECTS): calc.h
11 |
12 | code.o gen.o: x.tab.h
13 |
14 | x.tab.h: y.tab.h
15 | -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
16 | clean:
17 | rm -f $(OBJECTS) a.out *.CKP y.output [xy].tab.*
18 |
--------------------------------------------------------------------------------
/ez/tags/old/8q.S:
--------------------------------------------------------------------------------
1 | procedure queens(c)
2 | local r
3 |
4 | for (r = 1; r <= 8; r = r + 1)
5 | if (rows[r] == up[r-c+8] == down[r+c-1] == 1) {
6 | rows[r] = up[r-c+8] = down[r+c-1] = 0
7 | x[c] = r
8 | if (c == 8)
9 | write(x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], "\n")
10 | else queens(c + 1)
11 | rows[r] = up[r-c+8] = down[r+c-1] = 1
12 | }
13 | end
14 | for (i = 1; i <= 15; i = i + 1)
15 | up[i] = down[i] = 1
16 | for (i = 1; i <= 8; i = i + 1)
17 | rows[i] = 1
18 | queens(1)
19 |
--------------------------------------------------------------------------------
/ez/tags/old/BUGS:
--------------------------------------------------------------------------------
1 | (lines beginning with `-' indicate the bug is fixed.)
2 |
3 | -1. Two for in loops in editor.S don't work.
4 |
5 | 2. t[2][3] = 4 gives an error, and doesn't set t[2] or t[3]. It works
6 | if t[2] already exists.
7 |
8 | -3. the program "if (x) y = 3" assigns 3 to y even is x is void.
9 |
10 | -4. the program "while (1) write(1)" gets evaluation stack overflow.
11 |
12 | -5. the program "for(;;)write(1)" loops.
13 |
14 | -6. the expression 6 < 5 < 7 returns 7!
15 |
16 | -7. the program "for(;;)write(1)" gives evaluation stack overflow (after
17 | bug #5 was fixed).
18 |
19 | 8. need "not" operator to avoid "if(expr)0 else break" kludge
20 |
21 | 9. bug9.S gets a bus error
22 |
23 | 10. type(1<0) is not "void", the manual notwithstanding
24 |
25 | 11. bug11.S responds to input line "cd" with "12error 107...".
26 | yet the stmt is correct, and worse, it should not be executed.
27 |
28 | 12. Fixing bugs 4, 5, and 7 introduced another bug -- values
29 | of expressions outside procedures are not printed. Problem
30 | is indiscriminate use of o_base.
31 |
--------------------------------------------------------------------------------
/ez/tags/old/TODO:
--------------------------------------------------------------------------------
1 | - swap
2 | ! remove semicolons
3 | ! make include work
4 | ! sequencing thru tables (for x in y...)
5 | ! files
6 | syntax errors
7 | ! write 'The S Programming Language'
8 | ! builtin values:
9 | ! input
10 | ! output
11 | builtin functions:
12 | ! many(s1,s2)
13 | ! read(f,n)
14 | ! write(f,x)
15 | ! display(n)
16 | ! size(x)
17 | ! map(s1, s2, s3)
18 | ! open(name, mode)
19 | - create(name, mode)
20 | ! close(f)
21 | ! integer(x)
22 | ! real(x)
23 | ! type(x)
24 | ! seek(f, n, type)
25 | ! string(x)
26 | ! numeric(x)
27 | ! reverse(s)
28 | ! image(x)
29 | compile(s)
30 | ! allocate/deallocate backpatch lists
31 | ! tracing
32 | ! trace(n)
33 | ! unify error handling and messages
34 |
--------------------------------------------------------------------------------
/ez/tags/old/alloc.c:
--------------------------------------------------------------------------------
1 | /* storage allocation */
2 |
3 | #include "s.h"
4 | #include "g.h"
5 |
6 | struct block *freelist; /* ptr to head of freelist */
7 | struct bheap *blocklist; /* ptr to head of list of all blocks */
8 |
9 |
10 | /* initialize storage allocator */
11 | initalloc()
12 | {
13 | blocklist = NULL;
14 | freelist = NULL;
15 | }
16 |
17 | /* return a free block - garbage collect & allocate more blks if neccessary */
18 | struct block *balloc(type)
19 | int type;
20 | {
21 | struct block *b, *t;
22 | char *malloc();
23 | struct bheap *p;
24 | int i;
25 |
26 | if (freelist == NULL && blocklist != NULL && gcoff != 1)
27 | gc();
28 | if (freelist == NULL) {
29 | p = (struct bheap *) malloc(sizeof(struct bheap));
30 | p->h_list = blocklist;
31 | blocklist = p;
32 | freelist = t = b = (((int)p->h_slot+CHUNKMASK)&(~CHUNKMASK));
33 | for (i=0; bb_type = B_FREE;
36 | t->b_ints[0] = (int) b;
37 | b->b_ints[0] = NULL;
38 | t = b;
39 | }
40 | p->h_size = i;
41 | }
42 | b = freelist;
43 | freelist = (struct block *) b->b_ints[0];
44 | b->b_type = type;
45 | b->b_ints[0] = NULL;
46 | return(b);
47 | }
48 |
49 | /* garbage collector */
50 | gc()
51 | {
52 | int i;
53 | struct symbol *p;
54 | struct bheap *b;
55 | struct block *blk;
56 |
57 | for (i=0; i<=xsp; i++)
58 | vmark(val[i]);
59 | for (i=0; islink) {
61 | vmark(p->y_val);
62 | bmark(BLKTOP(p->y_name));
63 | }
64 | for (i=0; islink) {
66 | vmark(p->y_val);
67 | bmark(BLKTOP(p->y_name));
68 | }
69 | bmark(BLKTOP(istr));
70 | bmark(fstblk);
71 | bmark(curblk);
72 | for (i=0; ih_list) {
75 | blk = (struct block *) (((int)b->h_slot+CHUNKMASK)&(~CHUNKMASK));
76 | for (i=1; i<=b->h_size; i++) {
77 | if (BTYPE(blk) != B_FREE)
78 | if (MARK(blk) == 0) {
79 | blk->b_type = B_FREE;
80 | blk->b_ints[0] = (int) freelist;
81 | freelist = blk;
82 | }
83 | else
84 | blk->b_type = UNMARK(blk);
85 | blk++;
86 | }
87 | }
88 | }
89 |
90 | bmark(p)
91 | struct block *p;
92 | {
93 | int i;
94 | struct value *v;
95 |
96 | if (p == NULL)
97 | return;
98 | if (MARK(p) != B_MARK) {
99 | p->b_type += B_MARK;
100 | switch (BTYPE(p)) {
101 | case B_STRING:
102 | case B_CODE:
103 | case B_PROC:
104 | bmark(p->p_next);
105 | break;
106 | case B_TABLE:
107 | case B_ARRAY:
108 | case B_INDIR:
109 | for (i=0; i<=CHUNKSIZE-2; i++)
110 | if (p->b_ints[i] != 0)
111 | bmark((struct block *)p->b_ints[i]);
112 | break;
113 | case B_TELEM:
114 | if (p->b_ints[0] != 0)
115 | bmark((struct block *)p->b_ints[0]);
116 | for (v=(&p->b_ints[1]); TYPE((*v)) != T_VOID; v+=2) {
117 | vmark(*v);
118 | vmark(*(v+1));
119 | }
120 | break;
121 | case B_DATA:
122 | for (i=0; i<=CHUNKSIZE-2; i+=2) {
123 | v = &p->b_ints[i];
124 | if (TYPE((*v)) != T_VOID)
125 | vmark(*v);
126 | }
127 | break;
128 | }
129 | }
130 | }
131 |
132 | /* mark values if necessary */
133 | vmark(v)
134 | struct value v;
135 | {
136 | if (TYPE(v) == T_STRING || (TYPE(v) == T_PROC &&
137 | XFIELD(v) == 0) || TYPE(v) == T_TABLE)
138 | bmark(BLKTOP(v.v_addr));
139 | }
140 |
--------------------------------------------------------------------------------
/ez/tags/old/bug.S:
--------------------------------------------------------------------------------
1 | procedure insert(pos)
2 | local line, tbuf, i;
3 |
4 | for (i in buf)
5 | if (i > pos)
6 | tbuf[i] = buf[i];
7 | while (line = read(script))
8 | if (line ~= ".")
9 | buf[pos = pos + 1] = line
10 | else
11 | break;
12 | # dump(buf);
13 | for (i in tbuf)
14 | buf[pos = pos + 1] = tbuf[i]
15 | end;
16 |
--------------------------------------------------------------------------------
/ez/tags/old/bug11.S:
--------------------------------------------------------------------------------
1 | procedure sh(cd)
2 | local args, i, lin;
3 |
4 | for (write("% "); lin = read(); write("% ")) {
5 | if (args = getargs(lin)) 0 else next;
6 | if (args[0] == "c")
7 | cd[args[1]] = read() || "\n"
8 | else if (args[0] == "d")
9 | cd[args[1]] = ""
10 | else if (args[0] == "p")
11 | write(cd[args[1]])
12 | else if (args[0] == "ls") {
13 | for (i in cd)
14 | if (type(cd[i]) ~= "string" | cd[i] ~= "") write(i, "\n")
15 | }
16 | else if (args[0] == "cd") {
17 | dump(args); dump(cd);
18 | if (args[1]) 0 else args[1] = "";
19 | if (type(cd[args[1]]) ~= "table") {
20 | write("1");
21 | cd[args[1]] = "";
22 | write("2");
23 | cd[args[1]][""] = root;
24 | write("3");
25 | cd[args[1]]["."] = cd[args[1]];
26 | write("4");
27 | cd[args[1]][".."] = cd;
28 | write("5");
29 | };
30 | cd = cd[args[1]];
31 | };
32 | };
33 | end;
34 |
35 | procedure getargs(lin)
36 | local args, i, p1, p2;
37 |
38 | p2 = 1;
39 | lin = " " || lin || " ";
40 | for (i = 0; p2 = upto(" ", lin, p1 = many(" ", lin, p2)); i = i + 1)
41 | args[i] = lin[p1:p2];
42 | return (args);
43 | end;
44 |
45 | sh(root[""] = root["."] = root[".."] = root);
46 |
--------------------------------------------------------------------------------
/ez/tags/old/bug9.S:
--------------------------------------------------------------------------------
1 | procedure sh(cd)
2 | local args, i;
3 |
4 | for (write("% "); args = getargs(read()); write("% "))
5 | if (args[0] == "c")
6 | cd[args[1]] = read() || "\n"
7 | else if (args[0] == "d")
8 | cd[args[1]] = ""
9 | else if (args[0] == "p")
10 | write(cd[args[1]])
11 | else if (args[0] == "ls")
12 | for (i in cd) write(i, "\n")
13 | else if (args[0] == "cd") {
14 | if (type(cd[args[1]]) ~= "table") {
15 | cd[args[1]] = "";
16 | cd[args[1]]["."] = cd[args[1]];
17 | cd[args[1]][".."] = cd;
18 | };
19 | cd = cd[args[1]];
20 | };
21 | end;
22 |
23 | procedure getargs(lin)
24 | local args, i, p1, p2;
25 |
26 | if (lin == "") return("");
27 | p2 = 1;
28 | lin = " " || lin || " ";
29 | for (i = 0; p2 = upto(" ", lin, p1 = many(" ", lin, p2)); i = i + 1)
30 | args[i] = lin[p1:p2];
31 | return (args);
32 | end;
33 |
34 | sh(root["."] = root);
35 |
--------------------------------------------------------------------------------
/ez/tags/old/cbook.S:
--------------------------------------------------------------------------------
1 | f = open("checkbook");
2 | while (line = read(f))
3 | cbook[integer(line[1:upto(":", line, 1)])] = line;
4 | balance = 545.45;
5 | write("num\tdate\tamt\tdep\tbalance\twho\n");
6 | for (num in cbook) {
7 | i = upto(":", cbook[num], 1);
8 | date = cbook[num][i+1:j = upto(":", cbook[num], i + 1)];
9 | who = cbook[num][j+1:i = upto(":", cbook[num], j + 1)];
10 | amt = cbook[num][i+1:j = upto(":", cbook[num], i + 1)];
11 | dep = cbook[num][j+1:i = upto(":", cbook[num], j + 1)];
12 | balance = balance + dep - amt;
13 | write(num, "\t", date, "\t", amt, "\t", dep, "\t", balance, "\t", who, "\n")
14 | }
15 |
--------------------------------------------------------------------------------
/ez/tags/old/checkbook:
--------------------------------------------------------------------------------
1 | 171:8/20:Diamond's:4.37::
2 | 172:8/29:Oracle Rd. Rental:8.48::
3 | 173:8/31:Indus. Chem. of Arizona:14.77:609.35:
4 |
--------------------------------------------------------------------------------
/ez/tags/old/ed.in:
--------------------------------------------------------------------------------
1 | line 1
2 | line 2
3 | line 3
4 | line 4
5 | line 5
6 | line 6
7 | line 7
8 | line 8
9 | line 9
10 | line 10
11 |
--------------------------------------------------------------------------------
/ez/tags/old/ed.script:
--------------------------------------------------------------------------------
1 | 5i
2 | inserted line 1
3 | inserted line 2
4 | .
5 | 2d
6 | 1,5p
7 | 7,9d
8 | w foo
9 |
--------------------------------------------------------------------------------
/ez/tags/old/editor.S:
--------------------------------------------------------------------------------
1 | procedure insert(pos)
2 | local line, tbuf, i;
3 |
4 | for (i in buf)
5 | if (i > pos)
6 | tbuf[i] = buf[i];
7 | while (line = read(script))
8 | if (line ~= ".")
9 | buf[pos = pos + 1] = line
10 | else
11 | break;
12 | for (i in tbuf)
13 | buf[pos = pos + 1] = tbuf[i]
14 | end;
15 |
16 | procedure delete(pos1, pos2)
17 | local n, i;
18 |
19 | n = pos2 - pos1 + 1;
20 | for (i = pos1; i <= size(buf) - n; i = i + 1)
21 | buf[i] = buf[i + n];
22 | for (; i <= size(buf); i = i + 1)
23 | buf[i] = ""
24 | end;
25 |
26 | procedure print(pos1, pos2)
27 | for (; pos1 <= pos2; pos1 = pos1 + 1)
28 | write(buf[pos1], "\n");
29 | end;
30 |
31 | procedure fwrite(f)
32 | local out, i;
33 |
34 | outp = open(f, "w");
35 | for (i in buf)
36 | if (buf[i] ~= "")
37 | write(outp, buf[i], "\n");
38 | close(outp);
39 | end;
40 |
41 | inp = open("ed.in");
42 | for (i = 1; line = read(inp); i = i + 1)
43 | buf[i] = line;
44 | close(inp);
45 | script = open("ed.script");
46 | digits = "0123456789";
47 | while (line = read(script)) {
48 | low = integer(line[1:many(digits, line)]);
49 | if (i = many(",", line))
50 | high = integer(line[i:many(digits, line, i)])
51 | else
52 | high = low;
53 | if (find("i", line))
54 | insert(low)
55 | else if (find("d", line))
56 | delete(low, high)
57 | else if (find("p", line))
58 | print(low, high)
59 | else if (i=match("w", line))
60 | fwrite(line[upto(ascii[34:0],line,i):0])
61 | };
62 |
--------------------------------------------------------------------------------
/ez/tags/old/editor1.S:
--------------------------------------------------------------------------------
1 | procedure insert(pos)
2 | local line, tbuf, i;
3 |
4 | for (i in buf)
5 | if (i > pos)
6 | tbuf[i] = buf[i];
7 | while (line = read(script))
8 | if (line ~= ".")
9 | buf[pos = pos + 1] = line
10 | else
11 | break;
12 | # dump(buf);
13 | for (i in tbuf)
14 | buf[pos = pos + 1] = tbuf[i]
15 | end;
16 |
17 | procedure delete(pos1, pos2)
18 | local n, i;
19 |
20 | n = pos2 - pos1 + 1;
21 | for (i = pos1; i <= size(buf) - n; i = i + 1)
22 | buf[i] = buf[i + n];
23 | for (; i <= size(buf); i = i + 1)
24 | buf[i] = ""
25 | end;
26 |
27 | procedure print(pos1, pos2)
28 | for (; pos1 <= pos2; pos1 = pos1 + 1)
29 | write(buf[pos1], "\n");
30 | end;
31 |
32 | procedure fwrite(f)
33 | local out, i;
34 |
35 | outp = open(f, "w");
36 | for (i in buf)
37 | if (buf[i] ~= "")
38 | write(outp, buf[i], "\n");
39 | close(outp);
40 | end;
41 |
42 | inp = open("ed.in");
43 | for (i = 1; line = read(inp); i = i + 1)
44 | buf[i] = line;
45 | close(inp);
46 | script = open("ed.script");
47 | digits = "0123456789";
48 | while (line = read(script)) {
49 | low = integer(line[1:many(digits, line)]);
50 | if (i = many(",", line))
51 | high = integer(line[i:many(digits, line, i)])
52 | else
53 | high = low;
54 | if (find("i", line))
55 | insert(low)
56 | else if (find("d", line))
57 | delete(low, high)
58 | else if (find("p", line))
59 | print(low, high)
60 | else if (i=match("w", line))
61 | fwrite(line[upto(ascii[34:0],line,i):0])
62 | };
63 |
--------------------------------------------------------------------------------
/ez/tags/old/g.h:
--------------------------------------------------------------------------------
1 | /* globals */
2 |
3 | struct value val[MAXVAL]; /* value stack for interp */
4 | int xsp; /* value stack pointer */
5 | int xap; /* store stack argument pointer */
6 | int xlp; /* store stack local pointer */
7 | struct value void; /* void value */
8 | struct code *curblk; /* pointer to current block */
9 | struct code *fstblk; /* pointer to first code block */
10 | char *ident1; /* variable name in current for in */
11 | int **cp; /* code pointer */
12 | int loff; /* current local offset index */
13 | int aoff; /* current argument offset index */
14 | int level; /* procedure nesting level */
15 | int slevel; /* statement nesting level */
16 | int trace; /* trace flag */
17 | int ntrace; /* execution trace counter */
18 | int pnlevel; /* execution time proc nesting level */
19 | int debug; /* debug flag */
20 | int gcoff; /* garbage collector flag */
21 | jmp_buf env; /* stack state for errors */
22 | int eofflag; /* input eof flag */
23 | int doflag; /* DO flag, turns ) into DO */
24 | int ctype; /* type of last constant */
25 | int lensav; /* length of last constant */
26 | struct symbol *symtab[SYMSIZE]; /* symbol table hash headers */
27 | struct symbol *constab[SYMSIZE]; /* constant table hash headers */
28 | char *istr; /* tmporary string storage */
29 | int sp; /* stack pointer */
30 | int **cpstor[LEVMAX]; /* previous cp */
31 | struct code *blkstor[LEVMAX]; /* previous curblk */
32 |
--------------------------------------------------------------------------------
/ez/tags/old/hanoi.S:
--------------------------------------------------------------------------------
1 | procedure hanoi(n, src, dst, tmp)
2 | if (n > 0) {
3 | hanoi(n - 1, src, tmp, dst)
4 | write("move a disk from ", src, " to ", dst, "\n")
5 | hanoi(n - 1, tmp, dst, src)
6 | }
7 | end
8 | hanoi(3, "a", "b", "c")
9 |
--------------------------------------------------------------------------------
/ez/tags/old/init.c:
--------------------------------------------------------------------------------
1 | /* initialize arrays */
2 |
3 | #include "s.h"
4 | #include "g.h"
5 |
6 | struct tlvars lvars[] = { &o_avar, 1,
7 | &o_avar, 2,
8 | &o_avar, 3,
9 | &o_avar, 4,
10 | &o_avar, 5,
11 | &o_avar, 6,
12 | &o_avar, 7,
13 | &o_avar, 8,
14 | &o_avar, 9,
15 | &o_avar, 10,
16 | &o_lvar, 1,
17 | &o_lvar, 2,
18 | &o_lvar, 3,
19 | &o_lvar, 4,
20 | &o_lvar, 5,
21 | &o_lvar, 6,
22 | &o_lvar, 7,
23 | &o_lvar, 8,
24 | &o_lvar, 9,
25 | &o_lvar, 10
26 | };
27 |
28 | int (*(op[]))() = { &o_add,
29 | &o_sub,
30 | &o_mul,
31 | &o_div,
32 | &o_mod,
33 | &o_cat,
34 | &o_sstr,
35 | &o_idx,
36 | &o_call,
37 | &o_gvar,
38 | &o_gval,
39 | &o_lvar,
40 | &o_avar,
41 | &o_jump,
42 | &o_link,
43 | &o_lt,
44 | &o_le,
45 | &o_eq,
46 | &o_ne,
47 | &o_ge,
48 | &o_gt,
49 | &o_jev,
50 | &o_asgn,
51 | &o_ret,
52 | &o_neg,
53 | &o_binit,
54 | &o_bnext,
55 | &o_ssasn,
56 | &o_idxl,
57 | &o_base,
58 | 0
59 | };
60 |
61 | char *opname[] = { "add",
62 | "sub",
63 | "mul",
64 | "div",
65 | "mod",
66 | "cat",
67 | "sstr",
68 | "idx",
69 | "call",
70 | "gvar",
71 | "gval",
72 | "lvar",
73 | "avar",
74 | "jump",
75 | "link",
76 | "lt",
77 | "le",
78 | "eq",
79 | "ne",
80 | "ge",
81 | "gt",
82 | "jev",
83 | "asgn",
84 | "ret",
85 | "neg",
86 | "binit",
87 | "bnext",
88 | "ssasn",
89 | "idxl",
90 | "base"
91 | };
92 |
93 | char *bfname[] = { "null",
94 | "close",
95 | "compile",
96 | "display",
97 | "dump",
98 | "find",
99 | "image",
100 | "integer",
101 | "many",
102 | "map",
103 | "match",
104 | "numeric",
105 | "open",
106 | "read",
107 | "real",
108 | "reverse",
109 | "seek",
110 | "size",
111 | "string",
112 | "trace",
113 | "type",
114 | "upto",
115 | "write"
116 | };
117 |
--------------------------------------------------------------------------------
/ez/tags/old/lc.S:
--------------------------------------------------------------------------------
1 | procedure lc(f)
2 | local n;
3 | for (n = 0; read(f); n = n + 1)
4 | ;
5 | write (n,"\n")
6 | end;
7 | lc(open("lc.S"));
8 |
--------------------------------------------------------------------------------
/ez/tags/old/main.c:
--------------------------------------------------------------------------------
1 | #include "s.h"
2 | #include "y.tab.h"
3 | #include "g.h"
4 |
5 | /* main program - parse and execute statements */
6 | main(argc, argv)
7 | int argc;
8 | char *argv[];
9 | {
10 | FILE *fopen(), *f;
11 | int i;
12 |
13 | gcoff = debug = trace = ntrace = 0;
14 | f = stdin;
15 | for (i=1; ic_code);
45 | valprnt();
46 | }
47 | else if (i == 2)
48 | valprnt();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/ez/tags/old/makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-c -O
2 | YFLAGS=-d
3 |
4 | a.out: y.tab.o lex.o sem.o sym.o init.o util.o code.o alloc.o \
5 | table.o libf.o libutil.o main.o
6 | cc -i y.tab.o lex.o sem.o sym.o init.c util.o code.o \
7 | alloc.o table.o libf.o libutil.o main.o -ly
8 |
9 | y.tab.o: y.tab.c s.h
10 | cc $(CFLAGS) y.tab.c
11 | lex.o: lex.c s.h y.tab.h y.tab.c
12 | cc $(CFLAGS) lex.c
13 | sem.o: sem.c s.h
14 | cc $(CFLAGS) sem.c
15 | sym.o: sym.c s.h
16 | cc $(CFLAGS) sym.c
17 | code.o: code.c s.h
18 | cc $(CFLAGS) code.c
19 | y.tab.c: s.g s.h
20 | yacc $(YFLAGS) s.g
21 | alloc.o: alloc.c s.h
22 | cc $(CFLAGS) alloc.c
23 | util.o: util.c s.h
24 | cc $(CFLAGS) util.c
25 | table.o: table.c s.h
26 | cc $(CFLAGS) table.c
27 | libf.o: libf.c s.h
28 | cc $(CFLAGS) libf.c
29 | libutil.o: libutil.c s.h
30 | cc $(CFLAGS) libutil.c
31 | main.o: main.c s.h y.tab.h y.tab.c
32 | cc $(CFLAGS) main.c
33 | init.o: init.c s.h
34 | cc $(CFLAGS) init.c
35 |
36 | list: .printdate
37 | .printdate: s.h \
38 | s.g \
39 | g.h \
40 | alloc.c \
41 | code.c \
42 | lex.c \
43 | libf.c \
44 | libutil.c \
45 | init.c \
46 | main.c \
47 | sem.c \
48 | sym.c \
49 | table.c \
50 | util.c
51 | pr $? | lpr &
52 |
--------------------------------------------------------------------------------
/ez/tags/old/ssh:
--------------------------------------------------------------------------------
1 | procedure sh()
2 | local arg, cd, cmd, i;
3 |
4 | root["."] = "";
5 | root["."] = root[".."] = root;
6 | cd = root;
7 | for (write("% "); lin = read(); write("% ")) {
8 | if (lin == "") next;
9 | arg = ".";
10 | lin = lin || " ";
11 | cmd = lin[i=1:j=upto(" ",lin,i)];
12 | i=many(" ",lin,j);
13 | arg = lin[i:j=upto(" ",lin,i)];
14 | display(1);
15 | write(image(cmd), "\n");
16 | write(image(arg), "\n");
17 | write(image(cd), "\n");
18 | write(image(cd[arg]), "\n");
19 | };
20 | end;
21 |
--------------------------------------------------------------------------------
/ez/tags/old/sym.c:
--------------------------------------------------------------------------------
1 | /* symbol table management */
2 |
3 | #include "s.h"
4 | #include "g.h"
5 |
6 | #define SSIZE 119
7 | struct sentry *stab[SSIZE];
8 |
9 | /* initialize string and symbol table arrays to null, set initial values */
10 | initsym()
11 | {
12 | int i;
13 | char *slookup(), *s, *stralloc();
14 | struct symbol *install(), *p;
15 | struct value mkfile(), mkstr();
16 |
17 | for (i=0; iy_val = mkfile(stdin);
26 | p = install(slookup("output"), S_GLOBAL);
27 | p->y_val = mkfile(stdout);
28 | p = install(slookup("errout"), S_GLOBAL);
29 | p->y_val = mkfile(stderr);
30 | p = install(slookup("lcase"), S_GLOBAL);
31 | p->y_val = mkstr(stralloc("abcdefghijklmnopqrstuvwxyz", 26, 1), 26);
32 | p = install(slookup("ucase"), S_GLOBAL);
33 | p->y_val = mkstr(stralloc("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26, 1), 26);
34 | p = install(slookup("ascii"), S_GLOBAL);
35 | s = "\0\01\02\03\04\05\07\b\t\n\013\014\r\016\017\020\021\022\023\024\
36 | \025\026\027\030\031\032\033\034\035\036\037\040!\"#$%&\'()*+,-./\
37 | 0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop\
38 | qrstuvwxyz{|}~\177";
39 | p->y_val = mkstr(stralloc(s, 128, 1), 128);
40 | level = 0;
41 | cp = istr = NULL;
42 | void.v_type = T_VOID;
43 | void.v_addr = 0;
44 | }
45 |
46 | /* look for str in string table, install if neccessary, return ptr to entry */
47 | char *slookup(str)
48 | char *str;
49 | {
50 | int hashval;
51 | char *malloc(), *hstr, *stralloc();
52 | struct sentry *p;
53 |
54 | hstr = str;
55 | for (hashval=0; *str!='\0';)
56 | hashval += *str++;
57 | for (p=stab[hashval=hashval%SSIZE]; p!=NULL; p=p->snext)
58 | if (tstreq(hstr,p->schar) > 0)
59 | return(p->schar);
60 | p = (struct sentry *) malloc(sizeof(struct sentry));
61 | p->snext = stab[hashval];
62 | stab[hashval] = p;
63 | return(p->schar=stralloc(hstr,strlen(hstr),1));
64 | }
65 |
66 | /* lookup and install in constant table */
67 | struct symbol *clookup(id, ctype, lensav)
68 | char *id;
69 | int ctype, lensav;
70 | {
71 | double atof();
72 | struct value mkint(), mkreal(), mkstr();
73 | struct symbol *p;
74 | char *malloc();
75 | int hash;
76 |
77 | for (p=constab[hash=((unsigned) id)%SYMSIZE]; p!=NULL; p=p->slink)
78 | if (id == p->y_name && ctype == TYPE(p->y_val))
79 | return(p);
80 | p = (struct symbol *) malloc(sizeof(struct symbol));
81 | p->y_name = id;
82 | p->y_loff = p->y_scope = 0;
83 | p->y_fcn = op[O_GVAL];
84 | p->slink = constab[hash];
85 | constab[hash] = p;
86 | if (ctype == T_INT)
87 | p->y_val = mkint(atoi(id));
88 | else if (ctype == T_REAL)
89 | p->y_val = mkreal(atof(id));
90 | else if (ctype == T_STRING)
91 | p->y_val = mkstr(id, lensav);
92 | return(p);
93 | }
94 |
95 | /* lookup id in symbol table and return ptr into the symbol table if found */
96 | struct symbol *lookup(id)
97 | char *id;
98 | {
99 | struct symbol *p;
100 |
101 | for (p=symtab[((unsigned) id)%SYMSIZE]; p!=NULL; p=p->slink)
102 | if (id==p->y_name && (p->y_scope==level || p->y_scope<=S_GLOBAL))
103 | return(p);
104 | return(NULL);
105 | }
106 |
107 | /* install id as global or local and return ptr into the symbol table */
108 | struct symbol *install(id, scope)
109 | char *id;
110 | int scope;
111 | {
112 | struct symbol *p, *h, *t;
113 | char *malloc();
114 | int hash;
115 |
116 | p = (struct symbol *) malloc(sizeof(struct symbol));
117 | p->y_name = id;
118 | if (scope == S_GLOBAL) {
119 | p->y_loff = 0;
120 | p->y_scope = 0;
121 | p->y_fcn = op[O_GVAR];
122 | }
123 | else {
124 | p->y_loff = loff;
125 | p->y_scope = level;
126 | p->y_fcn = NULL;
127 | }
128 | if (scope == S_PARAM)
129 | p->y_loff = aoff;
130 | for (h=symtab[hash=((unsigned) id)%SYMSIZE]; h!=NULL; h=h->slink) {
131 | if (p->y_scope >= h->y_scope)
132 | break;
133 | t = h;
134 | }
135 | p->slink = h;
136 | if (h == symtab[hash])
137 | symtab[hash] = p;
138 | else
139 | t->slink = p;
140 | p->y_val.v_type = T_VOID;
141 | p->y_val.v_addr = 0;
142 | return(p);
143 | }
144 |
145 | char *stralloc(s, l, tokstr)
146 | char *s;
147 | int l, tokstr;
148 | {
149 | char *h;
150 | struct string *p;
151 | struct block *balloc();
152 |
153 | if (istr == NULL) {
154 | p = balloc(B_STRING);
155 | istr = p->s_chars;
156 | }
157 | mstrcpy((h=istr), s, l, tokstr);
158 | return(h);
159 | }
160 |
161 | /* remove - remove symbols with scope == lev from symbol table */
162 | remove(lev)
163 | int lev;
164 | {
165 | int i;
166 | struct symbol *p, *t;
167 |
168 | for (i=0; iy_scope >= lev; p=p->slink)
170 | if (p->y_scope == lev) {
171 | if (p == symtab[i])
172 | symtab[i] = p->slink;
173 | else
174 | t->slink = p->slink;
175 | bfree((char *) p);
176 | }
177 | else
178 | t = p;
179 | }
180 |
--------------------------------------------------------------------------------
/ez/tags/old/wc.S:
--------------------------------------------------------------------------------
1 | procedure wc(file)
2 | local nl, nc, nw, s, i, f;
3 |
4 | f = open(file);
5 | nc = nw = 0;
6 | for (nl = 0; s = read(f); nl = nl + 1) {
7 | s = s || " ";
8 | for (i = upto(ascii[34:0], s, 1); i = many(" \t", s, i);)
9 | nw = nw + 1;
10 | nc = nc + size(s)
11 | };
12 | write (nl, " ", nw, " ", nc, "\n")
13 | end;
14 | "wc.S:\t";
15 | wc("wc.S");
16 | "wf.S:\t";
17 | wc("wf.S");
18 |
--------------------------------------------------------------------------------
/ez/tags/old/wf.S:
--------------------------------------------------------------------------------
1 | procedure wf(file)
2 | local t, line, i, j, f
3 |
4 | f = open(file, "r")
5 | while (line = map(read(f), ucase, lcase))
6 | for (i = 1; i = upto(lcase, line, i); i = j) {
7 | j = many(lcase, line, i)
8 | t[line[i:j]] = t[line[i:j]] + 1
9 | }
10 | for (i in t)
11 | write(t[i], "\t", i, "\n")
12 | close(f)
13 | end
14 | wf("wf.S")
15 |
--------------------------------------------------------------------------------
/ez/tags/old/y.tab.h:
--------------------------------------------------------------------------------
1 |
2 | typedef union {
3 | int ival;
4 | int **cpval;
5 | char *cval;
6 | struct string *strval;
7 | struct bplist *bpval;
8 | struct stlist *stval;
9 | struct symbol *smval;
10 | } YYSTYPE;
11 | extern YYSTYPE yylval;
12 | # define RELOP 257
13 | # define UMINUS 258
14 | # define IDENTIFIER 259
15 | # define CONSTANT 260
16 | # define IF 261
17 | # define ELSE 262
18 | # define NEXT 263
19 | # define LOCAL 264
20 | # define BREAK 265
21 | # define CAT 266
22 | # define WHILE 267
23 | # define RETURN 268
24 | # define FOR 269
25 | # define END 270
26 | # define DO 271
27 | # define EQ 272
28 | # define NE 273
29 | # define LE 274
30 | # define GE 275
31 | # define PROCEDURE 276
32 | # define IN 277
33 | # define INCLUDE 278
34 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/abstract:
--------------------------------------------------------------------------------
1 | The EZ Environment
2 |
3 | David R. Hanson
4 | Department of Computer Science, The University of Arizona
5 | Tucson, Arizona 85721
6 |
7 | EZ is a language-based programming environment that offers the services
8 | provided separately by programming languages and operating systems in
9 | traditional environments. These services are provided as facilities of
10 | a high-level string processing language with a `persistent' memory in
11 | which values exist indefinitely or until changed. In EZ, strings and
12 | associative tables provide traditional file and directory services.
13 | This talk describes the use of EZ procedures and their activations,
14 | which, like other values, have indefinite lifetimes. In EZ, the
15 | low-level aspects of procedure execution, such as activation record
16 | creation, references to local variables, and access to state
17 | information, are accessible via high-level language constructs. As a
18 | result, traditionally distinct services can be provided by a single
19 | service in the EZ environment, and such services are written in EZ. An
20 | editor/debugger that illustrates the details of this approach is
21 | described.
22 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/ez.1:
--------------------------------------------------------------------------------
1 | .TH EZ 1 "local \- 1/4/84"
2 | .ds EZ \fI\s-2EZ\s0\fP
3 | .SH NAME
4 | ez \- \*(EZ interpreter and support utilities
5 | .SH SYNOPSIS
6 | .B ez
7 | [ file \(br option ]...
8 | .br
9 | .B collect
10 | [ file \(br option ]...
11 | .SH DESCRIPTION
12 | .I ez
13 | is an interpreter for the \*(EZ command and programming language.
14 | By default,
15 | the `read-evaluate'
16 | loop reads \*(EZ statements from the standard input and executes them,
17 | printing values for statements consisting of expressions.
18 | A statement is assumed to fit on one line unless
19 | the first token is a left brace ({) or the keyword
20 | .B procedure ,
21 | which is the beginning of a procedure specification.
22 | In these cases, input is read until the matching right brace (})
23 | or keyword
24 | .B end
25 | is encountered.
26 | Execution of the input is accomplished by compiling it as if it were the body
27 | of a procedure and then invoking that procedure.
28 | Assuming
29 | .B s
30 | is assigned a string containing the input, execution is equivalent to
31 | the \*(EX expression
32 | .BR s() .
33 | Compilation errors are recorded in a string that is assigned to
34 | .BR errors ,
35 | which is printed if compilation failed.
36 | .PP
37 | The
38 | .I file
39 | argument is used as the \*(EZ virtual address space
40 | and is created and initialized, if necessary.
41 | If the
42 | .I file
43 | argument is missing, the file
44 | .I ez.sys
45 | in the current directory is used.
46 | If more than one
47 | .I file
48 | argument is given,
49 | the rightmost argument is used.
50 | .PP
51 | .I ez
52 | accepts the following options.
53 | Options are executed when in encountered during the left to right
54 | processing of the arguments.
55 | Thus, their placement is significant.
56 | .IP \fB\-t\fIn\fR
57 | Set the trace counter to
58 | .I n
59 | or to -1 if
60 | .I n
61 | is omitted.
62 | Setting the trace counter is equivalent to calling the \*(EZ built-in
63 | procedure
64 | .BR trace ,
65 | which causes diagnostic messages to be issued for the next
66 | .I n
67 | procedure calls and returns.
68 | .IP "\fB\-D\fIn\fR"
69 | Turn on debugging bit
70 | .I n .
71 | The debugging bits cause various system information to
72 | be written to the standard error during execution.
73 | If
74 | .I n
75 | is omitted, the debugging bits are set to 0.
76 | .IP "\fB\-C\fIn\fR"
77 | Set the limit on the cache to
78 | .I n
79 | or to 100 if
80 | .I n
81 | is omitted.
82 | .I ez
83 | uses an \s-2LRU\s0 cache to access its virtual memory.
84 | Increasing the size of this cache may improve performance for large
85 | programs.
86 | .PP
87 | .I collect
88 | is the off-line garbage collector.
89 | .I ez
90 | allocates virtual memory upon demand;
91 | .I collect
92 | reclaims inaccessible memory for reuse.
93 | Typically,
94 | .I collect
95 | is run periodically, such as during the night,
96 | on \*(EZ virtual memory files.
97 | .I collect
98 | reclaims inaccessible memory in each of its
99 | .I file
100 | arguments, or in
101 | .I ez.sys
102 | if no
103 | .I file
104 | arguments are given, and rewrites those files.
105 | In addition to the
106 | .B \-C
107 | and
108 | .B \-D
109 | flags described above,
110 | .I collect
111 | accepts the following options.
112 | .IP "\fB\-s\fR"
113 | A one-line summary of the collection, indicating the number of
114 | free and busy pages, is printed on the standard output for each
115 | .I file
116 | argument.
117 | .IP "\fB\-S\fR"
118 | A detailed map of the free and busy pages is printed on the standard output
119 | in addition to the one-line summary for each
120 | .I file
121 | argument.
122 | .IP "\fB\-c\fR"
123 | Normally, inaccessible pages are placed on a free list for later use.
124 | The
125 | .B \-c
126 | option causes the busy pages to be compacted and each
127 | .I file
128 | argument is rewritten with the compacted virtual memory.
129 | .SH FILES
130 | .ta \w'ez\fInnnnnn\fR\ \ 'u
131 | ez.sys default virtual memory file
132 | .br
133 | ez\fInnnnnn\fP temporary file used by \fIcollect\fP
134 | .SH "SEE ALSO"
135 | C. W. Fraser and D. R. Hanson,
136 | The \*(EZ Reference Manual,
137 | Tech. Rep. 84-1,
138 | Dept. of Computer Science, Univ. of Arizona, Tucson,
139 | Jan. 1984.
140 | .PP
141 | C. W. Fraser and D. R. Hanson,
142 | Integrating Operating Systems and Languages,
143 | Tech. Rep. 84-2,
144 | Dept. of Computer Science, Univ. of Arizona, Tucson,
145 | Jan. 1984.
146 | .PP
147 | C. W. Fraser and D. R. Hanson,
148 | A High-Level Programming and Command Language,
149 | \fIProc. SIGPLAN '83 Symp. on Programming Lang. Issues in Software Systems\fP,
150 | 212-219, San Francisco, June 1983.
151 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/makefile:
--------------------------------------------------------------------------------
1 | TROFF=ditroff
2 | TFLAGS=
3 | Refman:
4 | bib -p /u/drh/refs/INDEX refman* | tbl | $(TROFF) -mtr $(TFLAGS)
5 |
6 | TR84-2:
7 | bib -p /u/drh/refs/INDEX tr84-2 | tbl | $(TROFF) -mtr $(TFLAGS)
8 |
9 | Popl:
10 | bib -p /u/drh/refs/INDEX popl | $(TROFF) -mtr $(TFLAGS)
11 |
12 | ez:
13 | $(TROFF) -man ez.1
14 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/refman:
--------------------------------------------------------------------------------
1 | .ds V# 3.0
2 | .de M
3 | .nr PQ \\n(.f
4 | .if !"\\$1"" \\$3\\fM\\$1\\f\\n(PQ\\$2
5 | .if "\\$1"" .ft M
6 | ..
7 | .de PS
8 | .DS I 3n
9 | .M
10 | .if !'\\$1'' .ta \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
11 | .if '\\$1'' .ta 3n +3n +3n +3n +3n +3n +3n +3n
12 | ..
13 | .de PE
14 | .R
15 | .DE
16 | ..
17 | .ds Y \s-2Y\s0
18 | .ds EZ \fI\s-2EZ\s0\fP
19 | .ds Un \s-2UNIX\s0
20 | .ds UN \s-2UNIX\s0
21 | .ds t
22 | .ds || \(br\(br
23 | .if \nd=2 .ds || \(br\|\|\(br
24 | .de SS
25 | .ps \\$1
26 | .nr PS \\$1
27 | .vs \\$2p
28 | .nr VS \\$2
29 | ..
30 | .de DL
31 | .DS \\$1 3n
32 | .ft I
33 | .ta 3n 6n 9n 12n 15n
34 | ..
35 | .TR 84-1
36 | .GP MCS-8102298 MCS-8302398
37 | .DA "January 1984"
38 | .TL
39 | The \*(EZ Reference Manual
40 | .AU
41 | Christopher W. Fraser
42 | David R. Hanson
43 | .AB
44 | \*(EZ is an interactive programming and command language
45 | that is semantically between
46 | high-level string processing languages like SNOBOL4
47 | and low-level Algol-like languages like Pascal.
48 | It is similar in spirit to SNOBOL4 and Icon
49 | and has many of their attributes, such as
50 | run-time flexibility,
51 | untyped variables, and heterogeneous structures.
52 | \*(EZ operates in a `persistent' environment in which
53 | variables retain their values until changed.
54 | As such, many of the services provided by traditional
55 | operating systems, such as a file system,
56 | are provided by \*(EZ language features.
57 | This report is a reference manual for Version \*(V# of \*(EZ.
58 | .AE
59 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/refman.1:
--------------------------------------------------------------------------------
1 | .NH
2 | Introduction
3 | .PP
4 | \*(EZ is designed to provide high-level language features
5 | that subsume facilities traditionally
6 | provided by operating systems.
7 | This goal is accomplished by using late binding times,
8 | execution-time scope rules,
9 | and a type system in which conventionally distinct types are
10 | treated as single types.
11 | The result is a system in which objects
12 | that are manipulated by utilities in traditional operating systems
13 | are manipulated by operators and control structures in \*(EZ.
14 | .PP
15 | As a programming language,
16 | \*(EZ is a high-level string-processing language
17 | derived from SNOBOL4, SL5,[.sl5 procedure mechanism.] and Icon .[.iconref.]
18 | It has most of the basic attributes of those languages,
19 | such as concise, expressive constructs, run-time flexibility,
20 | untyped variables, heterogeneous structures, and automatic type conversion.
21 | Strings are treated as scalars, and there are
22 | numerous `mid-level' string operations similar to those in Icon,
23 | but pattern-matching operations are not provided.
24 | With a few exceptions,
25 | \*(EZ's control structures are identical to those
26 | found in traditional languages.
27 | .PP
28 | The \*(EZ language resides in a `persistent' environment
29 | much like an APL workspace in which
30 | values exist until changed.
31 | Unlike systems that access workspaces explicitly,[.persistent heap.]
32 | the persistence in \*(EZ is implicit and a part of the language,
33 | much as in the Gem system.[.irons graphics software 1976.]
34 | This is one characteristic that distinguishes \*(EZ from
35 | various LISP environments, which access traditional operating system
36 | services through functions or other explicit mechanisms.[.sandewall lisp.]
37 | .PP
38 | The remainder of this report describes the syntax and semantics
39 | of Version \*(V# of \*(EZ.
40 | .NH 2
41 | Syntax Notation
42 | .PP
43 | The syntax of \*(EZ is described informally
44 | using English prose and formally using a metalanguage in which
45 | syntactic classes are denoted by
46 | .I italic
47 | type and literal characters and symbols are denoted by
48 | .B bold
49 | type.
50 | Alternatives are separated by vertical bars ( \(br ) or are
51 | listed on separate lines.
52 | Brackets ( [ ] ) enclose optional items,
53 | and ellipses (...) indicate indefinite
54 | repetition of the item they immediately follow.
55 | In cases where the literal use of the metasymbols
56 | is unclear in context or conflicts with their
57 | metalinguistic use, they are enclosed in quotes.
58 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/refman.2:
--------------------------------------------------------------------------------
1 | .NH
2 | Lexical Structure
3 | .PP
4 | \*(EZ programs are composed of identifiers, reserved words,
5 | constants, operators, and other separators.
6 | The `official' character set of \*(EZ is \s-2ASCII\s0.
7 | Blanks and tabs are ignored but
8 | are required to separate some lexical elements
9 | such as identifiers and reserved words.
10 | .PP
11 | Most language constructs are terminated by the end of the line on which
12 | they appear much as in Ratfor, \*Y, and Icon.
13 | Within a construct, however, newlines
14 | may be used as desired to improve
15 | readability where it is clear that the construct is
16 | continued on the next line.\(dg
17 | .FN
18 | \(dgTechnically, newlines are treated as white space except
19 | in contexts where they are in the
20 | .I follow
21 | set.[.aho ullman compiler.]
22 | .FE
23 | .PP
24 | Reserved words introduce language constructs and may
25 | not be used for other purposes (e.g. as variable names).
26 | Reserved words must be given in lower-case.
27 | The reserved words are
28 | .TS
29 | center ;
30 | lb lb lb .
31 | break for procedure
32 | continue if return
33 | else in while
34 | end local
35 | .TE
36 | .PP
37 | An identifier is a sequence of letters, digits, or underscores
38 | that begins with a letter.
39 | Corresponding upper- and lower-case letters are treated as different.
40 | Identifiers may be of any length.
41 | .PP
42 | Integer literals are specified by sequences of digits in the usual manner.
43 | Real literals are specified in the standard fashion,
44 | but exponential notation (like
45 | .M 3.45e10 )
46 | is not supported.
47 | For magnitudes less than 1, a leading 0 is required.
48 | .PP
49 | String literals are specified by delimiting the
50 | sequence of characters by single (') or double quotes (").
51 | Some characters, such as newline,
52 | cannot be entered directly because of their special function.
53 | The following escape convention may be used to enter these kinds of characters.
54 | .TS
55 | center ;
56 | li li
57 | lr l .
58 | character code
59 | .sp .2v
60 | newline \en
61 | single quote \e'
62 | double quote \e"
63 | backslash \e\e
64 | tab \et
65 | any character \e\fIddd\fP
66 | .TE
67 | The specification \e\fIddd\fP represents the character with
68 | \s-2ASCII\s0 code octal
69 | .I ddd ;
70 | only enough digits to specify the code need be given.
71 | String literals can be continued across line boundaries by preceding
72 | the newline with a backslash;
73 | the newline is ignored.
74 | .PP
75 | Literals for built-in values, such as the built-in procedures (see \(sc4.8),
76 | are specified by enclosing the name of the built-in value in
77 | accent graves, like
78 | .M `lcase` .
79 | .PP
80 | The sharp character (#) causes
81 | the rest of the line on which it appears to be
82 | ignored and serves to introduce comments.
83 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/refman.3:
--------------------------------------------------------------------------------
1 | .NH
2 | Types
3 | .PP
4 | \*(EZ supports four types of data:
5 | numeric,
6 | string,
7 | table, and
8 | procedure.
9 | Numerics (integers and reals)
10 | serve their conventional purposes.
11 | Strings are sequences of characters.
12 | Tables are heterogeneous one-dimensional
13 | arrays that can be indexed by arbitrary values much like SNOBOL4 tables.
14 | Procedures serve their conventional purpose, but are data objects.
15 | Procedures are created by a procedure specification and
16 | tables are created by subscripting a variable or by
17 | a table expression (see \(sc4.1).
18 | .PP
19 | The type of a variable varies during execution and is
20 | the type of the value assigned to it.
21 | Values are converted to the appropriate types automatically
22 | as necessary for most operations.
23 | For arithmetic operations,
24 | both operands are converted to numeric types if possible.
25 | Only strings that conform to the
26 | syntax described in \(sc2 for numeric constants
27 | can be converted to numeric.
28 | Integer arithmetic is performed if both of the resulting
29 | operands are integers.
30 | Otherwise, the operands are
31 | converted to real, if necessary, and real arithmetic is performed.
32 | Reals are converted to integers by truncation.
33 | .PP
34 | For string operations,
35 | operands are converted to string if possible.
36 | Integers and reals are converted to the
37 | appropriate string representation.
38 | Tables are converted to strings by converting their
39 | contents to strings and concatenating the results.
40 | Procedures are converted to string by returning the source
41 | code presented to the compiler when they were compiled.
42 | .PP
43 | For procedure operations, values other than procedures
44 | are converted to string, if necessary, and then compiled
45 | as if the string were the body of a procedure.
46 | .PP
47 | The specific action of some operations depends on the types of the operands.
48 | In comparisons, for example, lexical comparison is performed
49 | if both operands are strings,
50 | arithmetic comparison is performed if either operand is numeric,
51 | and an arbitrary, but well defined, comparison operation
52 | is performed otherwise.
53 | .PP
54 | Failure of any automatic conversion results in a run-time error.
55 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/refman.a:
--------------------------------------------------------------------------------
1 | .[]
2 | .bp
3 | .SH
4 | Appendix A. Run-Time Error Messages
5 | .PP
6 | Execution errors result in an error message
7 | being printed on the standard error output.
8 | If a type error occurs, the offending value is also printed.
9 | Error messages that may occur during program execution are listed below.
10 | .DS
11 | .ft R
12 | stack overflow
13 | division by zero
14 | residue by zero
15 | second and third arguments to map of unequal length
16 | numeric expected
17 | real expected
18 | string expected
19 | integer expected
20 | procedure expected
21 | variable expected
22 | .DE
23 | A trace of the call stack at the time of the error is also printed.
24 | .PP
25 | System errors result in a message describing the location of the error.
26 | These errors, which should be reported to the authors,
27 | cause immediate termination of \*(EZ.
28 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/slides:
--------------------------------------------------------------------------------
1 | .ds CM
2 | .ds HM 2i
3 | .ds LF \s8Foil %\s0
4 | .ds CF
5 | .ds RF \s8\*(DY\s0
6 | .nr PS 20
7 | .ps 20
8 | .nr VS 24
9 | .vs 24
10 | .nr fg 0
11 | .de SL
12 | .if \\n(fg>0 .bp
13 | .nr fg 1
14 | .ce 1
15 | \s24\\$1\s0
16 | .sp .5i
17 | .nf
18 | ..
19 | .de BU
20 | .sp .5i
21 | \(bu \\$1
22 | .ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
23 | ..
24 | .de PS
25 | .DS I .5i
26 | .ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
27 | .ft B
28 | ..
29 | .de PE
30 | .ft R
31 | .DE
32 | ..
33 | .SL "\fIEZ\fP"
34 | .DS C
35 | A High-Level Programming
36 | and Command Language
37 | .sp 2
38 | Christopher W. Fraser
39 | David R. Hanson
40 | .sp 2
41 | Department of Computer Science
42 | University of Arizona
43 | Tucson, Arizona
44 | .DE
45 | .SL Design
46 | .DS L
47 | .ta \w'\(bu 'u +\w'\(bu 'u
48 | \(bu An environment like APL, Lisp, Smalltalk.
49 | String-processing like SNOBOL4, SL5, Icon.
50 | .DE
51 | .BU "A programming \fIand\fP command language."
52 | .TS
53 | center;
54 | l l.
55 | \fIProgramming\fP \fICommand\fP
56 | \fIlanguages\fP \fIlanguages\fP
57 |
58 | e.g., Pascal e.g., UNIX Shell
59 | Usual control Same, coroutines
60 | Early binding Late binding
61 | Low-level types High-level types
62 | .TE
63 | .SL "Fuse Types"
64 | .BU "\fIEZ\fP provides general types:"
65 | .TS
66 | center;
67 | l l.
68 | \fIEZ type\fP \fITraditional types\fP
69 | number integer
70 | real
71 | string string
72 | text file
73 | procedure procedure
74 | program
75 | object file
76 | executable file
77 | table array
78 | record
79 | associative table
80 | directory
81 | .TE
82 | .BU "Implementation manages representation."
83 | .DE
84 | .SL "Appearance"
85 | .BU "Like C, Icon"
86 | .PS
87 | alphas = lcase || ucase || "0123456789"
88 |
89 | max = max < a
90 |
91 | procedure lc(s)
92 | local linecount
93 |
94 | linecount = 0
95 | while (s = s[upto("\en", s)+1:0])
96 | linecount = linecount + 1
97 | return (linecount)
98 | end
99 |
100 | doc[lc] = "lc(s) counts the lines in s."
101 | .PE
102 | .SL "Make Everything Do Something"
103 | .BU "Conversions between numbers and strings:"
104 | .PS
105 | s = "Back in 5 minutes."
106 | s[9:10] = s[9:10] + 20
107 | .PE
108 | .BU "Automatic table creation:"
109 | .PS
110 | paper["title"] = "EZ Programming"
111 | .PE
112 | .BU "Convert tables to strings:"
113 | .PS
114 | find("fix me", paper)
115 | .PE
116 | .BU "Convert functions to strings:"
117 | .PS
118 | find("fix me", lc)
119 | .PE
120 | .BU "Convert strings to functions:"
121 | .PS
122 | while (read()())
123 | ;
124 | .PE
125 | .SL "Avoid Duplication"
126 | .BU "\fIEZ\fP's symbol table is an \fIEZ\fP table."
127 | .PS
128 | x == root["x"]
129 | .PE
130 | .sp .5i
131 | \(bu Compiler searches \fBroot\fP, \fBroot[".."]\fP, ...
132 | .ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
133 | .DS L
134 | .ta \w'\(bu Like 'u
135 | \(bu Like nested scope,
136 | Smalltalk inheritance,
137 | UNIX search lists.
138 | .DE
139 | .BU "UNIX \fBchdir\fP analog:"
140 | .PS
141 | procedure ChDir(dir)
142 | root[dir][".back"] = root
143 | root = root[dir]
144 | end
145 | .PE
146 | .SL "Editing ``Directories''"
147 | .BU "Listing contents:"
148 | .PS
149 | for (i in root)
150 | write(i)
151 | .PE
152 | .BU "Interactive removal:"
153 | .PS
154 | for (i in root) {
155 | write(i)
156 | if (read() == "y")
157 | remove(root, i)
158 | }
159 | .PE
160 | .BU "Changing the hierarchy:"
161 | .PS
162 | root["old.."] = root[".."]
163 | root[".."] = NoviceFunctions
164 | ...
165 | root[".."] = root["old.."]
166 | .PE
167 | .SL "Editing ``Files''"
168 | .BU "Delete a table entry:"
169 | .PS
170 | procedure Delete(n)
171 | if (integer(n))
172 | for (; n < size(root); n = n + 1)
173 | root[n] = root[n+1]
174 | remove(root, n)
175 | end
176 |
177 | Insert(3, root[1])
178 | Delete(1)
179 |
180 | Insert("new", root["old"])
181 | Delete("old")
182 | .PE
183 | .SL "Editing Documents"
184 | .DS L
185 | .ta \w'\(bu 'u
186 | \(bu A paper is a table of sections.
187 | A section is a table of paragraphs.
188 | A paragraph is a table of sentences.
189 | .DE
190 | .BU "Delete introduction:"
191 | .PS
192 | Delete("Introduction")
193 | .PE
194 | .BU "Delete just its first paragraph:"
195 | .PS
196 | ChDir("Introduction")
197 | Delete(1)
198 | .PE
199 | .BU "Delete just its second sentence:"
200 | .PS
201 | ChDir("Introduction")
202 | ChDir(1)
203 | Delete(2)
204 | .PE
205 | .SL Implementation
206 | .BU "Generate and execute interpretive code."
207 | .BU "Fixed-size descriptors represent all values."
208 | .BU "Descriptors may point to pages."
209 | .BU "Implementation handles paging, caching."
210 | .BU "Implementation picks table representation."
211 | .BU "Paging out \fBroot\f saves state."
212 | .BU "Garbage collected off-line."
213 |
--------------------------------------------------------------------------------
/ez/tags/original/doc/slides1.tex:
--------------------------------------------------------------------------------
1 | \input macros
2 | \magnification=\magstep4
3 | \voffset=1 true in
4 | \font\bigrm=amr10 at 12 pt %\font\eightit=ami10 at 8pt
5 | \font\footrm=amr8 at 8 true pt \font\pt=amtt10
6 | \newif\ifLong
7 | \footline={\footrm Slide \folio\ifLong\hfill Long Version\fi\hfill\today}
8 | \def\Bullet{\bigskip$\bullet$\enspace\enspace}
9 | \def\NewPage{\vfill\eject\Longfalse}
10 | \def\EZ{{\sl EZ\/}}
11 | \catcode`\^^I=\active
12 | \def^^I{\hskip .4 true in}
13 | \parindent=0pt \catcode`\~=12
14 | \def\center{\leftskip=0pt plus 1fil \rightskip=\leftskip \parfillskip=0pt}
15 | \def\program{\begingroup\medskip\pt\catcode`\{=12 \catcode`\}=12}
16 | \def\endprogram{\endgroup}
17 | {\obeylines\center
18 | {\bigrm The \EZ\ System}
19 | \vskip 1 true in
20 | Christopher W. Fraser and David R. Hanson
21 |
22 | Department of Computer Science
23 | The University of Arizona
24 | }
25 | \bye
26 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/8q.ez:
--------------------------------------------------------------------------------
1 | procedure eightQ()
2 | local i
3 |
4 | for (i = 1; i <= 15; i = i + 1)
5 | up[i] = down[i] = 1
6 | for (i = 1; i <= 8; i = i + 1)
7 | rows[i] = 1
8 | procedure queens(c)
9 | local r
10 |
11 | for (r = 1; r <= 8; r = r + 1)
12 | if (rows[r] == up[r-c+8] == down[r+c-1] == 1) {
13 | rows[r] = up[r-c+8] = down[r+c-1] = 0
14 | x[c] = r
15 | if (c == 8) {
16 | write(x, "\n")
17 | burp()
18 | }
19 | else
20 | queens(c + 1)
21 | rows[r] = up[r-c+8] = down[r+c-1] = 1
22 | }
23 | end
24 | queens(1)
25 | end
26 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/acker.ez:
--------------------------------------------------------------------------------
1 | procedure acker(a,b)
2 | if (a == 0) return (b+1)
3 | if (b == 0) return (acker(a-1, 1))
4 | return (acker(a-1, acker(a, b-1)))
5 | end
6 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/array.ez:
--------------------------------------------------------------------------------
1 | name = "array"
2 |
3 | carray = ""
4 |
5 | procedure edappd(n, new)
6 | carray = carray[1:n+2] || carray[n+1:size(carray)+1]
7 | carray[n+1] = new
8 | end
9 |
10 | procedure edchng(n, new)
11 | carray[n] = new
12 | end
13 |
14 | procedure eddel(n)
15 | carray = carray[1:n] || carray[n+1:size(carray)+1]
16 | end
17 |
18 | procedure edgetl(n)
19 | return (carray[n])
20 | end
21 |
22 | procedure edinit(v)
23 | if (v)
24 | carray = copy(v)
25 | end
26 |
27 | procedure edquit()
28 | return (carray)
29 | end
30 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/box.ez:
--------------------------------------------------------------------------------
1 | procedure main()
2 | while (1) {
3 | write ("---------------------\n")
4 | write ("| Main Menu |\n")
5 | write ("| |\n")
6 | write ("|b: box |\n")
7 | write ("|q: quit |\n")
8 | write ("| |\n")
9 | write ("---------------------\n")
10 | write("\nEnter a letter: ")
11 | cmd = read()
12 | if (cmd == "b")
13 | box()
14 | if (cmd == "q")
15 | break
16 | }
17 | end
18 |
19 | procedure box()
20 | write("Draw a Box\nenter length of side: ")
21 | n = read()
22 | for(i = 1; i <= n; i = i + 1)
23 | write("-")
24 | write("\n")
25 | for(j = 1; j <= n; j = j + 1) {
26 | write("|")
27 | for(i = 1; i < n-1; i = i + 1)
28 | write(" ")
29 | write("|\n")
30 | }
31 | for(i = 1; i <= n; i = i + 1)
32 | write("-")
33 | write("\n")
34 | end
35 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/cd.ez:
--------------------------------------------------------------------------------
1 | procedure cd(dir)
2 | root[dir]["last"] = root
3 | root = root[dir]
4 | end
5 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/decode.ez:
--------------------------------------------------------------------------------
1 | procedure decode(cmd, keymap)
2 | local c, s, t
3 |
4 | s = ""
5 | t = keymap
6 | while (c = cmd[1!1]) {
7 | s = s || c
8 | cmd = cmd[2:0]
9 | if (type(t[c]) == "procedure") {
10 | t[c](s)
11 | return (1)
12 | }
13 | else if (type(t[c]) ~= "table")
14 | return
15 | t = t[c]
16 | }
17 | end
18 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/directory.ez:
--------------------------------------------------------------------------------
1 | name = "directory"
2 |
3 | carray = cdirectory = ""
4 |
5 | procedure edappd(n, new)
6 | cdirectory[new] = ""
7 | carray = keys(cdirectory)
8 | end
9 |
10 | procedure edchng(n, new) local old
11 | old = carray[n]
12 | cdirectory[new] = cdirectory[old]
13 | if (old ~= new)
14 | remove(cdirectory, old)
15 | carray = keys(cdirectory)
16 | end
17 |
18 | procedure eddel(n)
19 | remove(cdirectory, carray[n])
20 | carray = keys(cdirectory)
21 | end
22 |
23 | procedure edexec(n) local sarray, sdirectory
24 | sarray = carray
25 | sdirectory = cdirectory
26 | edit(cdirectory[carray[n]])
27 | carray = sarray
28 | cdirectory = sdirectory
29 | end
30 |
31 | procedure edgetl(n)
32 | return (carray[n])
33 | end
34 |
35 | procedure edinit(v)
36 | if (v)
37 | carray = keys(cdirectory = copy(v))
38 | end
39 |
40 | procedure edquit()
41 | return (cdirectory)
42 | end
43 |
44 | procedure keys(t) local i, k, l
45 | i = 0
46 | for (k in t)
47 | l[i=i+1] = k
48 | return (sort(l))
49 | end
50 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/ed.ez:
--------------------------------------------------------------------------------
1 | procedure ed(s)
2 | if (s = string(s)) {
3 | system("echo >/tmp/ezTmp '"||s||"'; ed /tmp/ezTmp");
4 | s = read("/tmp/ezTmp")
5 | system("rm /tmp/ezTmp")
6 | return (s)
7 | }
8 | end
9 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/hanoi.ez:
--------------------------------------------------------------------------------
1 | procedure hanoi(n, src, dst, tmp)
2 | if (n > 0) {
3 | hanoi(n - 1, src, tmp, dst)
4 | write("move a disk from ", src, " to ", dst, "\n")
5 | hanoi(n - 1, tmp, dst, src)
6 | }
7 | end
8 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/init.ez:
--------------------------------------------------------------------------------
1 | root = ["..":root]
2 |
3 | read("lib.ez")()
4 |
5 | mkdir(".edit")
6 | cd(".edit")
7 | load("edit")
8 |
9 | mkdir(".string")
10 | cd(".string")
11 | load("string")
12 | cd()
13 |
14 | mkdir(".table")
15 | cd(".table")
16 | load("table")
17 | cd()
18 |
19 | mkdir("term")
20 | cd("term")
21 | load("z19")
22 | cd()
23 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/lib.ez:
--------------------------------------------------------------------------------
1 | procedure cd(x)
2 | if (type(x) == "string")
3 | root = root[x]
4 | else if (type(x) == "table")
5 | root = x
6 | else
7 | cd("..")
8 | end
9 |
10 | procedure copy(t) local c, i
11 | if (type(t) ~= "table")
12 | return (t)
13 | else if (size(t) == 0)
14 | return (table())
15 | else {
16 | for (i in t)
17 | c[i] = t[i]
18 | return (c)
19 | }
20 | end
21 |
22 | procedure dupl(s, n)
23 | if (n <= 0)
24 | return ("")
25 | else if (n%2 == 0)
26 | return (dupl(s||s, n/2))
27 | else
28 | return (s||dupl(s||s, n/2))
29 | end
30 |
31 | procedure getfile(x)
32 | if (x)
33 | savefile = x
34 | return (savefile)
35 | end
36 |
37 | procedure itoc(n, b)
38 | if (n < 0)
39 | return ("-" || itoc(-n, b))
40 | else if (n < b)
41 | return (string(n%b))
42 | else
43 | return (itoc(n/b, b) || n%b)
44 | end
45 |
46 | procedure load(x)
47 | read(getfile(x) || ".ez")()
48 | end
49 |
50 | procedure ls(x) local i, s
51 | if (type(x) == "string")
52 | return (ls(root[x]))
53 | if (~x)
54 | return (ls(root))
55 | s = ""
56 | for (i in x)
57 | s = s || string(i) || "\n"
58 | return (s)
59 | end
60 |
61 | procedure max(x, y)
62 | if (x > y)
63 | return (x)
64 | else
65 | return (y)
66 | end
67 |
68 | procedure mkdir(s)
69 | root[s][".."] = root
70 | end
71 |
72 | procedure min(x, y)
73 | if (x < y)
74 | return (x)
75 | else
76 | return (y)
77 | end
78 |
79 | procedure pad(s, l)
80 | return (s||dupl(" ",l-size(s)))
81 | end
82 |
83 | procedure rm(x)
84 | remove(root, x)
85 | end
86 |
87 | procedure qsort(a, l, r) local v, t, i, j
88 | if (r > l) {
89 | v = a[r]; i = l - 1; j = r
90 | for (;;) {
91 | while (a[i=i+1]l & a[j=j-1]>v)
94 | ;
95 | t = a[i]; a[i] = a[j]; a[j] = t
96 | if (j <= i)
97 | break
98 | }
99 | a[j] = a[i]; a[i] = a[r]; a[r] = t
100 | qsort(a, l, i-1)
101 | qsort(a, i+1, r)
102 | }
103 | return (a)
104 | end
105 |
106 | procedure reset()
107 | system("stty -raw echo")
108 | end
109 |
110 | procedure sort(a)
111 | return (qsort(copy(a), 1, size(a)))
112 | end
113 |
114 | # stot - convert string to table
115 | procedure stot(s) local i, n, t
116 | n = 0
117 | t = table()
118 | while (i = upto("\n", s)) {
119 | t[n=n+1] = s[1:i]
120 | s = s[i+1:0]
121 | }
122 | if (s ~= "")
123 | t[n=n+1] = s
124 | return (t)
125 | end
126 |
127 | # ttos - convert table to string
128 | procedure ttos(t) local i, s
129 | s = ""
130 | for (i in t)
131 | s = s || string(t[i]) || "\n"
132 | if (size(t) == 1)
133 | return (s[1:-1])
134 | else
135 | return (s)
136 | end
137 |
138 | procedure vi(x)
139 | x = getfile(x)
140 | system("vi "||x||".ez")
141 | load(x)
142 | end
143 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/list.ez:
--------------------------------------------------------------------------------
1 | for (i = 1; i <= 10; i = i + 1) test[i] = "line " || i
2 |
3 | cx = cy = 1
4 | xmax = 80
5 | ymax = 10
6 |
7 | # home, down, up, right, left, enter commands
8 | keymap["h"] = procedure() curmov(1, 1) end
9 | keymap["d"] = procedure() curmov(cx, cy+1) end
10 | keymap["u"] = procedure() curmov(cx, cy-1) end
11 | keymap["r"] = procedure() curmov(cx+1, cy) end
12 | keymap["l"] = procedure() curmov(cx-1, cy) end
13 | keymap["e"] = procedure() edit(ctable[cy]) end
14 |
15 | # insert/delete character/line commands
16 | keymap["ic"] = procedure()
17 | if (check() & cx <= size(ctable[cy]))
18 | ctable[cy][cx!0] = " "
19 | end
20 | keymap["dc"] = procedure()
21 | if (check() & cx <= size(ctable[cy]))
22 | ctable[cy][cx!1] = ""
23 | end
24 | keymap["il"] = procedure()
25 | if (check()) {
26 | ctable[cy] = pad(ctable[cy], cx)
27 | ctable = ctable[1:cy] || ctable[cy:size(ctable)]
28 | ctable[cy][cx:0] = ""
29 | ctable[cy+1][1:cx] = ""
30 | }
31 | end
32 | keymap["dl"] = procedure foo()
33 | if (check()) {
34 | ctable[cy] = pad(ctable[cy], cx)[1:cx] || ctable[cy+1]
35 | ctable = ctable[1:cy] || ctable[cy+2:size(ctable)]
36 | }
37 | end
38 |
39 | # overstrike commands
40 | keymap["x"] = procedure(c)
41 | if (check()) {
42 | ctable[cy] = pad(ctable[cy], cx)
43 | ctable[cy][cx!1] = c
44 | curmov(cx+1, cy)
45 | }
46 | end
47 |
48 | # check - check that current line is a string
49 | procedure check()
50 | if (type(ctable[cy]) == "table") {
51 | error()
52 | return
53 | }
54 | return (1)
55 | end
56 |
57 | # curmov - move the cursor to (cx,cy)
58 | procedure curmov(x, y)
59 | if (x <= xmax) cx = x
60 | if (y <= ymax) cy = y
61 | end
62 |
63 | # estring - convert v to string of at most xmax characters
64 | procedure estring(v)
65 | local s
66 |
67 | if (size(s = string(v)) > xmax) s[xmax-3:0] = "..."
68 | return (s)
69 | end
70 |
71 | # error - signal illegal editing command
72 | procedure error()
73 | write(ascii[8!1]) # ring bell
74 | end
75 |
76 | # pad - pad s to length l
77 | procedure pad(s, l)
78 | if (l > size(s))
79 | return (pad(s||" ", l-1))
80 | return (s)
81 | end
82 |
83 | # refresh - redraw screen to reflect current state
84 | procedure refresh()
85 | for (i = 1; i <= ymax; i = i + 1)
86 | write(estring(ctable[i]), "\n")
87 | write("(", cx, ",", cy, ")")
88 | end
89 |
90 | procedure edit(v) local s
91 | ctable = v
92 | refresh()
93 | while (s = read())
94 | if (keymap[s]) {
95 | keymap[s](s)
96 | refresh()
97 | }
98 | end
99 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/map.ez:
--------------------------------------------------------------------------------
1 | kludge = 0
2 |
3 | procedure addmap(s, v, t)
4 | if (size(s) == 0)
5 | return
6 | else if (type(t[s[1!1]]) == "table")
7 | return (addmap(s[2:0], v, t[s[1!1]]))
8 | else if (t[s[1!1]])
9 | return
10 | else {
11 | t[s[1!1]] = mkmap(s[2:0], v)
12 | return (t)
13 | }
14 | end
15 |
16 | procedure mkmap(s, v) local t
17 | if (size(s) == 0)
18 | return (v)
19 | else {
20 | t[s[1!1]] = mkmap(s[2:0], v)
21 | return (t)
22 | }
23 | end
24 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/random.ez:
--------------------------------------------------------------------------------
1 | s = 0
2 | p = 12621
3 | c = 21131
4 | m = 100000
5 | procedure random(n)
6 | s = (s*p + c)%m
7 | return (s*n/m + 1)
8 | end
9 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/rpoints.ez:
--------------------------------------------------------------------------------
1 | procedure rpoints(p)
2 | if (type(p) == "procedure")
3 | for (i in p)
4 | write(i, ":\t", p[i], "\n")
5 | end
6 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/sort.ez:
--------------------------------------------------------------------------------
1 | From rebecca Tue May 3 11:24:58 1983
2 | To: drh
3 |
4 | Subject: EZ
5 |
6 | We have been working on this program (for too long now)
7 | and have the problem narrowed down to lines with Rvalues of the
8 | string s. Concatenation of s to some random string got
9 | rid of the syntax errors, but doesn't do much for quicksort.
10 | Confused,
11 | Ron and Becky
12 | procedure qsort(s)
13 | procedure sort(lb,ub)
14 | local i,j,p,t
15 | i = lb
16 | j = ub
17 | t = (lb + ub)/2
18 | p = s[t!1]
19 | while (1) {
20 | while (s[i!1] < p)
21 | i = i + 1
22 | while (p < s[j!1])
23 | j = j - 1
24 | if (i <= j) {
25 | t = s[i!1]
26 | s[i!1] = s[j!1]
27 | s[j!1] = t
28 | i = i + 1
29 | j = j - 1
30 | }
31 | if (i > j)
32 | break
33 | }
34 | if (lb < j)
35 | sort(lb,j)
36 | if (i < ub)
37 | sort(i,ub)
38 | end;
39 | sort(1,size(s))
40 | end
41 |
42 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/string.ez:
--------------------------------------------------------------------------------
1 | procedure edappd(n, new)
2 | while (n > size(carray))
3 | carray[size(carray)+1] = ""
4 | carray = carray[1:n+1] || table(new) || carray[n+1:size(carray)+1]
5 | end
6 |
7 | procedure edchng(n, new)
8 | if (n > size(carray))
9 | edappd(n-1, new)
10 | else
11 | carray[n] = new
12 | end
13 |
14 | procedure eddel(n)
15 | carray = carray[1:n] || carray[n+1:size(carray)+1]
16 | end
17 |
18 | procedure edesc()
19 | end
20 |
21 | procedure edgetl(n)
22 | return (carray[n])
23 | end
24 |
25 | procedure edinit(v)
26 | carray = stot(v)
27 | end
28 |
29 | procedure edlast()
30 | return (size(carray))
31 | end
32 |
33 | procedure edquit()
34 | return (ttos(carray))
35 | end
36 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/table.ez:
--------------------------------------------------------------------------------
1 | procedure edappd(n, new)
2 | ctable[new] = ""
3 | while (n > size(carray))
4 | carray[size(carray)+1] = ""
5 | carray = carray[1:n+1] || table(new) || carray[n+1:size(carray)+1]
6 | end
7 |
8 | procedure edchng(n, new) local old
9 | if (n > size(carray))
10 | edappd(n-1, new)
11 | else {
12 | old = carray[n]
13 | ctable[new] = ctable[old]
14 | if (old ~= new)
15 | remove(ctable, old)
16 | carray[n] = new
17 | }
18 | end
19 |
20 | procedure eddel(n)
21 | remove(ctable, carray[n])
22 | carray = carray[1:n] || carray[n+1:size(carray)+1]
23 | end
24 |
25 | procedure edesc(n) local sarray, stable
26 | sarray = carray
27 | stable = ctable
28 | ctable[carray[n]] = edit(ctable[carray[n]])
29 | carray = sarray
30 | ctable = stable
31 | end
32 |
33 | procedure edgetl(n)
34 | return (carray[n])
35 | end
36 |
37 | procedure edinit(v) local i, k
38 | if (v) {
39 | ctable = v
40 | i = 0
41 | carray = table()
42 | for (k in ctable)
43 | carray[i=i+1] = k
44 | }
45 | end
46 |
47 | procedure edlast()
48 | return (size(carray))
49 | end
50 |
51 | procedure edquit()
52 | return (ctable)
53 | end
54 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/wc.ez:
--------------------------------------------------------------------------------
1 | procedure wc(s)
2 | local nl, nw, i
3 |
4 | wordchars = ascii[upto(" ", ascii)+1:-1]
5 | nl = nw = 0
6 | while (i = upto(wordchars||"\n", s))
7 | if (s[i:i+1] == "\n") {
8 | nl = nl + 1
9 | s = s[i+1:0]
10 | }
11 | else {
12 | nw = nw + 1
13 | s = s[many(wordchars, s, i):0]
14 | }
15 | return (nl || " " || nw)
16 | end
17 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/wf.ez:
--------------------------------------------------------------------------------
1 | procedure table(s)
2 | local i, j, t
3 |
4 | s = string(s)
5 | i = 0
6 | while (j = upto("\n", s)) {
7 | t[i = i + 1] = s[1:j+1]
8 | s = s[j+2:0]
9 | }
10 | if (size(s) > 0)
11 | t[i+1] = s
12 | return (t)
13 | end
14 |
15 | procedure wf(s)
16 | local t, i, j
17 |
18 | for (i = 1; i = upto(lcase, s, i); i = j) {
19 | j = many(lcase, s, i)
20 | if (t[s[i:j]])
21 | t[s[i:j]] = t[s[i:j]] + 1
22 | else
23 | t[s[i:j]] = 1
24 | }
25 | for (i in t)
26 | write(t[i], "\t", i, "\n")
27 | end
28 |
--------------------------------------------------------------------------------
/ez/tags/original/lib/z19.ez:
--------------------------------------------------------------------------------
1 | xmax = 80
2 | ymax = 24
3 |
4 | keymap = table()
5 | addmap("\b", procedure() curmov(cx-1, cy); delchr() end, keymap) # backspace
6 | addmap("\012", procedure() escape() end, keymap) # escape
7 | addmap("\015", procedure() curmov(1, cy+1) end, keymap) # return
8 | addmap("\033A", procedure() curmov(cx, cy-1) end, keymap) # up
9 | addmap("\033B", procedure() curmov(cx, cy+1) end, keymap) # down
10 | addmap("\033C", procedure() curmov(cx+1, cy) end, keymap) # right
11 | addmap("\033D", procedure() curmov(cx-1, cy) end, keymap) # left
12 | addmap("\033H", procedure() curmov(1, 1) end, keymap) # home
13 | addmap("\033J", procedure() touch(1, ymax) end, keymap) # refresh
14 | addmap("\033L", procedure() inslin() end, keymap) # insert line
15 | addmap("\033@", procedure() inschr() end, keymap) # insert char
16 | addmap("\033M", procedure() dellin() end, keymap) # delete line
17 | addmap("\033N", procedure() delchr() end, keymap) # delete char
18 | addmap("\033P", procedure() mark() end, keymap) # mark
19 | addmap("\033Q", procedure() pick() end, keymap) # pick
20 | addmap("\033R", procedure() put() end, keymap) # put
21 | addmap("\033S", procedure() scnmov( 7) end, keymap) # +lines
22 | addmap("\033T", procedure() scnmov(-7) end, keymap) # -lines
23 | addmap("\033U", procedure() scnmov( ymax) end, keymap) # +pages
24 | addmap("\033V", procedure() scnmov(-ymax) end, keymap) # -pages
25 | addmap("\033W", procedure() mode = 1 - mode end, keymap) # insert mode
26 | addmap("\033/", procedure() search(+1) end, keymap) # +search
27 | addmap("\033?", procedure() search(-1) end, keymap) # -search
28 | addmap("\177", procedure() exec() end, keymap) # exec
29 |
30 | for (i = 32; i < 128; i = i + 1)
31 | addmap(ascii[i+1!1], procedure(c) overstrike(c) end, keymap) # overstrike
32 | remove(root, "i")
33 |
34 | procedure error(s)
35 | write(ascii[8!1])
36 | end
37 |
38 | procedure init(s)
39 | write("\033x6")
40 | end
41 |
--------------------------------------------------------------------------------
/ez/tags/original/src/TODO:
--------------------------------------------------------------------------------
1 | - make a copy of initial root
2 | - implement t(), where t is a table
3 | - implement f[...], where f is a function
4 | - implement initial values for locals
5 | - rearrange assignment code.
6 | - not all operators handle VOID correctly (e.g. ||)
7 | - implement position-independent procedure parameters (foo(arg=exp))
8 | - fix O_QUIT code so it's emitted only if necessary
9 |
--------------------------------------------------------------------------------
/ez/tags/original/src/contents:
--------------------------------------------------------------------------------
1 | trap "rm -f /tmp/c$$" 1 15
2 | for i
3 | do
4 | echo -n "$i:+"
5 | sed -e '2,$d' -e 's/\/\*[ ]*//' -e 's/[ ]*\*\///' \
6 | -e 's/ez: //' -e 's/ez //' $i
7 | done | awk -F+ '{ printf "%-15s%s\n", $1, $2 }' | enscript -h Files
8 | grep -n ')$' $* | sed -e '/[ ]if/d' -e '/[ ]for/d' -e '/[ ]while/d' \
9 | -e '/[ ]else/d' -e '/#define/d' -e '/[=+><-]/d' \
10 | -e 's/^"\(.*\)".*line \([0-9]*\):[ ]*\(.*\)$/\1:\2:\3/' >/tmp/c$$
11 | awk -F: ' { printf "%s, %d %s\n", $1, $2, $3 }'
4 | #include
5 | #include "ez.h"
6 | #include "tokens.h"
7 | #include
8 | #include
9 |
10 | int execute; /* set to execute input */
11 | jmp_buf restart; /* to restart after runtime errors */
12 | int debug; /* debugging bits */
13 | char *progname = "";
14 | char *fsysname = FILESYS;/* ez file system name */
15 | extern int cachelimit; /* cache size limit */
16 | extern int trace; /* trace counter */
17 | extern int slength; /* source code length */
18 | extern char *source; /* source code */
19 | extern struct root *rp; /* pointer to root block */
20 |
21 | /* main program - parse and execute statements */
22 | main(argc, argv)
23 | int argc;
24 | char *argv[];
25 | {
26 | FILE *f;
27 | int i, (*isig)(), onintr();
28 | extern struct value errors;
29 | struct value v, getline();
30 |
31 | progname = *argv;
32 | isig = signal(SIGINT, SIG_IGN);
33 | debug = trace = 0;
34 | cachelimit = 100;
35 | for (i = 1; i < argc; i++)
36 | if (strncmp(argv[i], "-D", 2) == 0)
37 | if (isdigit(argv[i][2]))
38 | debug |= 1<<(atoi(&argv[i][2])-1);
39 | else
40 | debug = 0;
41 | else if (strncmp(argv[i], "-C", 2) == 0)
42 | if (argv[i][2])
43 | cachelimit = atoi(&argv[i][2]);
44 | else
45 | cachelimit = 100;
46 | else if (strncmp(argv[i], "-t", 2) == 0)
47 | if (argv[i][2])
48 | trace = atoi(&argv[i][2]);
49 | else
50 | trace = -1;
51 | else
52 | fsysname = argv[i];
53 | initialize(fsysname);
54 | for (;;) {
55 | setjmp(restart);
56 | if (isig != SIG_IGN)
57 | signal(SIGINT, onintr);
58 | v = getline(stdin);
59 | if (TYPE(v) == T_VOID)
60 | break;
61 | if (debug&DBINPUT) {
62 | image(v, stderr, 1);
63 | putc('\n', stderr);
64 | }
65 | v = excvproc(v);
66 | if (nerrors)
67 | excvstr(errors, stdout);
68 | else if (execute) {
69 | v = apply(v);
70 | excvstr(v, stdout);
71 | if (TYPE(v) != T_VOID)
72 | putchar('\n');
73 | }
74 | }
75 | putblk(rp, 1);
76 | savecache();
77 | }
78 |
79 | /* getline - get next input source item */
80 | struct value getline(f)
81 | FILE *f;
82 | {
83 | struct value v;
84 | char *s;
85 | int t, va, n, c1, c2;
86 |
87 | execute = 0;
88 | initlex(f, NULL, stderr);
89 | va = salloc();
90 | source = SOPENW(va);
91 | n = 0;
92 | switch (c1 = t = gtok('\n')) {
93 | case EOF:
94 | c2 = EOF;
95 | break;
96 | case '{':
97 | execute++;
98 | c2 = '}';
99 | break;
100 | case PROCEDURE:
101 | execute++;
102 | c2 = END;
103 | break;
104 | default:
105 | execute++;
106 | c1 = 0;
107 | c2 = '\n';
108 | break;
109 | }
110 | do {
111 | if (t == c2 && --n < 0)
112 | break;
113 | t = gtok(0);
114 | if (t == c1)
115 | n++;
116 | } while (t > 0);
117 | SCLOSEW(source);
118 | source = NULL;
119 | if (c2 == -1)
120 | return (VOID);
121 | return (mkstr(va, slength));
122 | }
123 |
124 | /* initialize - initialize ez file system in fname */
125 | initialize(fname)
126 | char *fname;
127 | {
128 | struct value *vp;
129 | struct table *bp;
130 | int fd, i;
131 | extern int filesize, cnstp, strp, level;
132 |
133 | if (access(fname, 2)) {
134 | if ((fd = creat(fname, 0666)) == -1) {
135 | fprintf(stderr, "%s: can't create\n", fname);
136 | exit(1);
137 | }
138 | close(fd);
139 | }
140 | initcache(fname);
141 | rp = (struct root *) getblk(0);
142 | if (filesize > sizeof(struct block) && rp->r_major != MAJOR) {
143 | fprintf(stderr, "%s: version mismatch; %s version is %d.%d, \
144 | system version is %d.%d\n", progname, fname, rp->r_major, rp->r_minor,
145 | MAJOR, MINOR);
146 | exit(1);
147 | }
148 | touch(rp);
149 | *builtin("root") = rp->r_globals;
150 | cnstp = strp = level = 0;
151 | Procedure = stralloc("Procedure", -1);
152 | Resumption = stralloc("Resumption", -1);
153 | if (rp->r_major == MAJOR)
154 | return;
155 | rp->r_type = B_DATA;
156 | rp->r_major = MAJOR;
157 | rp->r_minor = MINOR;
158 | rp->r_freelist = 0;
159 | bp = (struct table *) balloc(B_TABLE);
160 | rp->r_globals = mkval(T_TABLE, 0, virtaddr(bp));
161 | rp->r_wglobals = rp->r_globals;
162 | putblk(bp, 0);
163 | rp->r_dotdot = stralloc("..", -1);
164 | VOID = mkval(T_VOID, 0, 0);
165 | *builtin("root") = rp->r_globals;
166 | for (i = 0; bivalues[i].bi_name; i++) {
167 | vp = tindex(rp->r_globals,stralloc(bivalues[i].bi_name,-1),1);
168 | *vp = *builtin(bivalues[i].bi_name);
169 | putblk(vp, 1);
170 | }
171 | }
172 |
173 | /* onintr - called on Interrupt signal */
174 | onintr()
175 | {
176 | fprintf(stderr, "\nInterrupt\n");
177 | longjmp(restart, 1);
178 | }
179 |
180 |
--------------------------------------------------------------------------------
/ez/tags/original/src/makefile:
--------------------------------------------------------------------------------
1 | DESTDIR=/usr/local
2 | CFLAGS=-g
3 | FILES=ez.h tokens.h cache.c code.c cvt.c expr.c func.c gen.c lex.c \
4 | main.c parse.c proc.c stmt.c table.c util.c collect.c
5 | OBJECTS=cache.o code.o cvt.o expr.o func.o gen.o \
6 | lex.o main.o parse.o proc.o stmt.o table.o util.o
7 |
8 | a.out: $(OBJECTS) makefile
9 | cc -g $(OBJECTS) -lcurses -ltermcap
10 |
11 | $(OBJECTS) collect.o: ez.h
12 |
13 | main.o lex.o gen.o parse.o expr.o stmt.o: tokens.h
14 |
15 | ez: a.out
16 | cp a.out ez
17 |
18 | collect: collect.o cache.o
19 | cc -w -g -o collect collect.o cache.o
20 |
21 | install: ez collect
22 | cp ez collect $(DESTDIR)
23 |
24 | clean:
25 | rm -f $(OBJECTS) a.out collect.o
26 |
27 | list: .printdate
28 | .printdate: $(FILES) makefile
29 | @imprint $?
30 | @touch .printdate
31 |
32 | toc:
33 | @contents $(FILES)
34 |
--------------------------------------------------------------------------------
/ez/tags/original/src/parse.c:
--------------------------------------------------------------------------------
1 | /* ez compiler: top-level parsing */
2 |
3 | #include
4 | #include "ez.h"
5 | #include "tokens.h"
6 |
7 | static int follow[] = {END, 0}; /* follow set for procedures */
8 | struct value errors = {T_VOID, 0}; /* current value of `errors' */
9 | static struct value err = {T_VOID, 0}; /* string "errors" */
10 | static int errp = 0; /* virtual address of error string */
11 | extern char *errs;
12 | extern int elength;
13 |
14 | /* prog : { stmt }
15 | *
16 | * ezparse - parse ez program in string v
17 | */
18 | struct value ezparse(v)
19 | struct value v;
20 | {
21 | struct proc *p, *procbeg();
22 |
23 | initlex(NULL, &v, NULL);
24 | errs = SOPENW(errp = salloc());
25 | t = gtok('\n');
26 | p = procbeg(NULL);
27 | endpoint(begpoint());
28 | stmtlist(0);
29 | endpoint(begpoint());
30 | emit1(O_RET);
31 | emit(2, O_ERR, 1);
32 | p->p_source = v;
33 | v = mkval(T_PROC, 0, procend(p));
34 | newline();
35 | if (t != EOF)
36 | error("syntax error", "");
37 | geterrors();
38 | if (nerrors)
39 | v = VOID;
40 | return (v);
41 | }
42 |
43 | /* func : procedure [ id ] `(' [ id { , id } ] `)' { dcl } { stmt } end
44 | *
45 | * parse procedure definition
46 | */
47 | int func()
48 | {
49 | struct compile csav;
50 | extern int cursor, tcursor;
51 | extern struct value src;
52 | int n, a, bpos, epos;
53 | struct proc *p;
54 |
55 | csav = c;
56 | bpos = tcursor;
57 | t = gtok('\n');
58 | if (t == ID) {
59 | p = procbeg(lexval.l_str);
60 | t = gtok('\n');
61 | }
62 | else
63 | p = procbeg(NULL);
64 | c.offset = bpos - 1;
65 | endpoint(begpoint());
66 | newline();
67 | mustbe('(', '\n');
68 | while (t == ID) {
69 | dcl(lexval.l_str, p, 0);
70 | t = gtok('\n');
71 | if (t != ',')
72 | break;
73 | t = gtok('\n');
74 | }
75 | mustbe(')', '\n');
76 | while (t == LOCAL) {
77 | t = gtok('\n');
78 | while (t == ID) {
79 | dcl(lexval.l_str, p, LOCAL);
80 | t = gtok(0);
81 | if (t != ',')
82 | break;
83 | t = gtok('\n');
84 | }
85 | newline();
86 | }
87 | stmtlist(0);
88 | endpoint(begpoint());
89 | emit(2, O_GVAL, const(VOID));
90 | emit1(O_RET);
91 | emit(2, O_ERR, 1);
92 | epos = cursor - 1;
93 | if (t == END)
94 | t = gtok(0);
95 | else {
96 | error("missing end", "");
97 | skipto(follow, 0);
98 | }
99 | if (t == EOF)
100 | epos++;
101 | p->p_source = substr(src, bpos, epos);
102 | a = procend(p);
103 | c = csav;
104 | return (a);
105 | }
106 |
107 | /* dcl - declaration of formal parameter or local in p */
108 | dcl(id, p, lflag)
109 | char *id;
110 | struct proc *p;
111 | int lflag;
112 | {
113 | struct value *vp;
114 |
115 | vp = tindex(p->p_sym, stralloc(id, -1), 1);
116 | if (TYPE(*vp) != T_VOID)
117 | error("parameter or local previously declared: ", id);
118 | else if (lflag == LOCAL)
119 | *vp = mkval(T_VAR, 0, ++p->p_nlocals);
120 | else
121 | *vp = mkval(T_VAR, 0, -++p->p_nargs);
122 | putblk(vp, 1);
123 | bfree(id);
124 | }
125 |
126 | /* geterrors - assign compilation error string to `errors' */
127 | geterrors()
128 | {
129 | struct value *vp;
130 | extern struct root *rp;
131 |
132 | if (errs)
133 | SCLOSEW(errs);
134 | if (nerrors) {
135 | if (TYPE(err) != T_STRING)
136 | err = stralloc("errors", -1);
137 | vp = tindex(rp->r_wglobals, err, 1);
138 | *vp = errors = mkstr(errp, elength);
139 | putblk(vp, 1);
140 | }
141 | }
142 |
143 | /* inset - return t if it is in set, return 0 otherwise */
144 | int inset(t, set)
145 | int t, *set;
146 | {
147 | while (*set)
148 | if (t == *set++)
149 | return (t);
150 | return (0);
151 | }
152 |
153 | /* recompile - recompile source for procedure p */
154 | int recompile(p)
155 | struct proc *p;
156 | {
157 | int a;
158 | struct proc *p1;
159 |
160 | initlex(NULL, &p->p_source, NULL);
161 | errs = SOPENW(errp = salloc());
162 | t = gtok('\n');
163 | if (t == PROCEDURE)
164 | a = func();
165 | else {
166 | p1 = procbeg(NULL);
167 | endpoint(begpoint());
168 | stmtlist(0);
169 | endpoint(begpoint());
170 | emit1(O_RET);
171 | emit(2, O_ERR, 1);
172 | p1->p_source = p->p_source;
173 | a = procend(p1);
174 | newline();
175 | if (t != EOF)
176 | error("syntax error", "");
177 | }
178 | geterrors();
179 | if (nerrors == 0) { /* overwrite previous procedure block */
180 | p1 = (struct proc *) getblk(a);
181 | *p = *p1;
182 | putblk(p1, 0);
183 | touch(p);
184 | }
185 | return (nerrors);
186 | }
187 |
188 | /* skipto - discard input upto next occurrence of character in set or EOF */
189 | skipto(set, ic)
190 | int *set, ic;
191 | {
192 | while (t != EOF && inset(t, set) == 0)
193 | t = gtok(ic);
194 | }
195 |
--------------------------------------------------------------------------------
/ez/tags/original/src/tokens.h:
--------------------------------------------------------------------------------
1 | /* ez tokens (other than single characters) */
2 |
3 | #define EQ 256 /* == */
4 | #define NE 257 /* != */
5 | #define LE 258 /* <= */
6 | #define GE 259 /* >= */
7 | #define CAT 260 /* || */
8 | #define CON 261 /* integer constant */
9 | #define FCON 262 /* floating constant */
10 | #define SCON 263 /* string constant */
11 | #define BCON 264 /* built-in value constant */
12 | #define ID 265 /* identifier */
13 | #define IF 266 /* if */
14 | #define ELSE 267 /* else */
15 | #define WHILE 268 /* while */
16 | #define FOR 269 /* for */
17 | #define RETURN 270 /* return */
18 | #define BREAK 271 /* break */
19 | #define CONTINUE 272 /* continue */
20 | #define PROCEDURE 273 /* procedure */
21 | #define IN 274 /* in */
22 | #define LOCAL 275 /* local */
23 | #define END 276 /* end */
24 |
25 | #define emit1(x) emit(1,x)
26 | #define UNARY 01000| /* unary operator indicator */
27 | #define SUFFIX 02000| /* suffix operator indicator */
28 | #define BINARY 04000| /* binary operator indicator */
29 |
30 | struct node { /* expression nodes */
31 | int ex_op; /* operator */
32 | int ex_type; /* type of result */
33 | struct node *ex_l; /* operands */
34 | struct node *ex_r;
35 | int ex_result; /* result flag */
36 | int ex_count; /* reference count */
37 | };
38 |
39 | struct bpnode { /* backpatch list node */
40 | int addr; /* virtual address to patch */
41 | struct bpnode *next; /* next node */
42 | };
43 |
44 | struct label { /* label definitions */
45 | int addr; /* virtual address of label */
46 | struct bpnode *bplist; /* backpatch list until defined */
47 | };
48 |
49 | struct compile { /* compilation variables */
50 | struct proc *proc; /* current procedure */
51 | int offset; /* offset into input of beginning of proc */
52 | int loop; /* current loop handle */
53 | int forlevel; /* nesting depth for for (x in e) loops */
54 | int label; /* next generated label */
55 | struct code *cblock; /* current code block */
56 | int *pc; /* pointer to next word in cblock->c_code */
57 | struct label labels[200];/* labels */
58 | int point; /* next resumption point */
59 | struct point points[100];/* resumption points */
60 | };
61 |
62 | struct lexval { /* values set by gtok */
63 | char *l_str; /* string and name token */
64 | int l_length; /* length of string constant */
65 | int l_ival; /* integer and character constant */
66 | };
67 |
68 | /* global variables */
69 | extern int t; /* current token */
70 | extern struct lexval lexval; /* associated value */
71 | extern int nerrors; /* error count */
72 | extern struct compile c; /* current compilation record */
73 |
--------------------------------------------------------------------------------
/ez/trunk/doc/ez.1:
--------------------------------------------------------------------------------
1 | .TH EZ 1 "local \- 1/4/84"
2 | .ds EZ \fI\s-2EZ\s0\fP
3 | .SH NAME
4 | ez \- \*(EZ interpreter and support utilities
5 | .SH SYNOPSIS
6 | .B ez
7 | [ file \(br option ]...
8 | .br
9 | .B collect
10 | [ file \(br option ]...
11 | .SH DESCRIPTION
12 | .I ez
13 | is an interpreter for the \*(EZ command and programming language.
14 | By default,
15 | the `read-evaluate'
16 | loop reads \*(EZ statements from the standard input and executes them,
17 | printing values for statements consisting of expressions.
18 | A statement is assumed to fit on one line unless
19 | the first token is a left brace ({) or the keyword
20 | .B procedure ,
21 | which is the beginning of a procedure specification.
22 | In these cases, input is read until the matching right brace (})
23 | or keyword
24 | .B end
25 | is encountered.
26 | Execution of the input is accomplished by compiling it as if it were the body
27 | of a procedure and then invoking that procedure.
28 | Assuming
29 | .B s
30 | is assigned a string containing the input, execution is equivalent to
31 | the \*(EX expression
32 | .BR s() .
33 | Compilation errors are recorded in a string that is assigned to
34 | .BR errors ,
35 | which is printed if compilation failed.
36 | .PP
37 | The
38 | .I file
39 | argument is used as the \*(EZ virtual address space
40 | and is created and initialized, if necessary.
41 | If the
42 | .I file
43 | argument is missing, the file
44 | .I ez.sys
45 | in the current directory is used.
46 | If more than one
47 | .I file
48 | argument is given,
49 | the rightmost argument is used.
50 | .PP
51 | .I ez
52 | accepts the following options.
53 | Options are executed when in encountered during the left to right
54 | processing of the arguments.
55 | Thus, their placement is significant.
56 | .IP \fB\-t\fIn\fR
57 | Set the trace counter to
58 | .I n
59 | or to -1 if
60 | .I n
61 | is omitted.
62 | Setting the trace counter is equivalent to calling the \*(EZ built-in
63 | procedure
64 | .BR trace ,
65 | which causes diagnostic messages to be issued for the next
66 | .I n
67 | procedure calls and returns.
68 | .IP "\fB\-D\fIn\fR"
69 | Turn on debugging bit
70 | .I n .
71 | The debugging bits cause various system information to
72 | be written to the standard error during execution.
73 | If
74 | .I n
75 | is omitted, the debugging bits are set to 0.
76 | .IP "\fB\-C\fIn\fR"
77 | Set the limit on the cache to
78 | .I n
79 | or to 100 if
80 | .I n
81 | is omitted.
82 | .I ez
83 | uses an \s-2LRU\s0 cache to access its virtual memory.
84 | Increasing the size of this cache may improve performance for large
85 | programs.
86 | .PP
87 | .I collect
88 | is the off-line garbage collector.
89 | .I ez
90 | allocates virtual memory upon demand;
91 | .I collect
92 | reclaims inaccessible memory for reuse.
93 | Typically,
94 | .I collect
95 | is run periodically, such as during the night,
96 | on \*(EZ virtual memory files.
97 | .I collect
98 | reclaims inaccessible memory in each of its
99 | .I file
100 | arguments, or in
101 | .I ez.sys
102 | if no
103 | .I file
104 | arguments are given, and rewrites those files.
105 | In addition to the
106 | .B \-C
107 | and
108 | .B \-D
109 | flags described above,
110 | .I collect
111 | accepts the following options.
112 | .IP "\fB\-s\fR"
113 | A one-line summary of the collection, indicating the number of
114 | free and busy pages, is printed on the standard output for each
115 | .I file
116 | argument.
117 | .IP "\fB\-S\fR"
118 | A detailed map of the free and busy pages is printed on the standard output
119 | in addition to the one-line summary for each
120 | .I file
121 | argument.
122 | .IP "\fB\-c\fR"
123 | Normally, inaccessible pages are placed on a free list for later use.
124 | The
125 | .B \-c
126 | option causes the busy pages to be compacted and each
127 | .I file
128 | argument is rewritten with the compacted virtual memory.
129 | .SH FILES
130 | .ta \w'ez\fInnnnnn\fR\ \ 'u
131 | ez.sys default virtual memory file
132 | .br
133 | ez\fInnnnnn\fP temporary file used by \fIcollect\fP
134 | .SH "SEE ALSO"
135 | C. W. Fraser and D. R. Hanson,
136 | The \*(EZ Reference Manual,
137 | Tech. Rep. 84-1,
138 | Dept. of Computer Science, Univ. of Arizona, Tucson,
139 | Jan. 1984.
140 | .PP
141 | C. W. Fraser and D. R. Hanson,
142 | Integrating Operating Systems and Languages,
143 | Tech. Rep. 84-2,
144 | Dept. of Computer Science, Univ. of Arizona, Tucson,
145 | Jan. 1984.
146 | .PP
147 | C. W. Fraser and D. R. Hanson,
148 | A High-Level Programming and Command Language,
149 | \fIProc. SIGPLAN '83 Symp. on Programming Lang. Issues in Software Systems\fP,
150 | 212-219, San Francisco, June 1983.
151 |
--------------------------------------------------------------------------------
/ez/trunk/lib/8q.ez:
--------------------------------------------------------------------------------
1 | procedure eightQ()
2 | local i
3 |
4 | for (i = 1; i <= 15; i = i + 1)
5 | up[i] = down[i] = 1
6 | for (i = 1; i <= 8; i = i + 1)
7 | rows[i] = 1
8 | procedure queens(c)
9 | local r
10 |
11 | for (r = 1; r <= 8; r = r + 1)
12 | if (rows[r] == up[r-c+8] == down[r+c-1] == 1) {
13 | rows[r] = up[r-c+8] = down[r+c-1] = 0
14 | x[c] = r
15 | if (c == 8) {
16 | write(x, "\n")
17 | burp()
18 | }
19 | else
20 | queens(c + 1)
21 | rows[r] = up[r-c+8] = down[r+c-1] = 1
22 | }
23 | end
24 | queens(1)
25 | end
26 |
--------------------------------------------------------------------------------
/ez/trunk/lib/acker.ez:
--------------------------------------------------------------------------------
1 | procedure acker(a,b)
2 | if (a == 0) return (b+1)
3 | if (b == 0) return (acker(a-1, 1))
4 | return (acker(a-1, acker(a, b-1)))
5 | end
6 |
--------------------------------------------------------------------------------
/ez/trunk/lib/array.ez:
--------------------------------------------------------------------------------
1 | name = "array"
2 |
3 | carray = ""
4 |
5 | procedure edappd(n, new)
6 | carray = carray[1:n+2] || carray[n+1:size(carray)+1]
7 | carray[n+1] = new
8 | end
9 |
10 | procedure edchng(n, new)
11 | carray[n] = new
12 | end
13 |
14 | procedure eddel(n)
15 | carray = carray[1:n] || carray[n+1:size(carray)+1]
16 | end
17 |
18 | procedure edgetl(n)
19 | return (carray[n])
20 | end
21 |
22 | procedure edinit(v)
23 | if (v)
24 | carray = copy(v)
25 | end
26 |
27 | procedure edquit()
28 | return (carray)
29 | end
30 |
--------------------------------------------------------------------------------
/ez/trunk/lib/box.ez:
--------------------------------------------------------------------------------
1 | procedure main()
2 | while (1) {
3 | write ("---------------------\n")
4 | write ("| Main Menu |\n")
5 | write ("| |\n")
6 | write ("|b: box |\n")
7 | write ("|q: quit |\n")
8 | write ("| |\n")
9 | write ("---------------------\n")
10 | write("\nEnter a letter: ")
11 | cmd = read()
12 | if (cmd == "b")
13 | box()
14 | if (cmd == "q")
15 | break
16 | }
17 | end
18 |
19 | procedure box()
20 | write("Draw a Box\nenter length of side: ")
21 | n = read()
22 | for(i = 1; i <= n; i = i + 1)
23 | write("-")
24 | write("\n")
25 | for(j = 1; j <= n; j = j + 1) {
26 | write("|")
27 | for(i = 1; i < n-1; i = i + 1)
28 | write(" ")
29 | write("|\n")
30 | }
31 | for(i = 1; i <= n; i = i + 1)
32 | write("-")
33 | write("\n")
34 | end
35 |
--------------------------------------------------------------------------------
/ez/trunk/lib/cd.ez:
--------------------------------------------------------------------------------
1 | procedure cd(dir)
2 | root[dir]["last"] = root
3 | root = root[dir]
4 | end
5 |
--------------------------------------------------------------------------------
/ez/trunk/lib/decode.ez:
--------------------------------------------------------------------------------
1 | procedure decode(cmd, keymap)
2 | local c, s, t
3 |
4 | s = ""
5 | t = keymap
6 | while (c = cmd[1!1]) {
7 | s = s || c
8 | cmd = cmd[2:0]
9 | if (type(t[c]) == "procedure") {
10 | t[c](s)
11 | return (1)
12 | }
13 | else if (type(t[c]) ~= "table")
14 | return
15 | t = t[c]
16 | }
17 | end
18 |
--------------------------------------------------------------------------------
/ez/trunk/lib/directory.ez:
--------------------------------------------------------------------------------
1 | name = "directory"
2 |
3 | carray = cdirectory = ""
4 |
5 | procedure edappd(n, new)
6 | cdirectory[new] = ""
7 | carray = keys(cdirectory)
8 | end
9 |
10 | procedure edchng(n, new) local old
11 | old = carray[n]
12 | cdirectory[new] = cdirectory[old]
13 | if (old ~= new)
14 | remove(cdirectory, old)
15 | carray = keys(cdirectory)
16 | end
17 |
18 | procedure eddel(n)
19 | remove(cdirectory, carray[n])
20 | carray = keys(cdirectory)
21 | end
22 |
23 | procedure edexec(n) local sarray, sdirectory
24 | sarray = carray
25 | sdirectory = cdirectory
26 | edit(cdirectory[carray[n]])
27 | carray = sarray
28 | cdirectory = sdirectory
29 | end
30 |
31 | procedure edgetl(n)
32 | return (carray[n])
33 | end
34 |
35 | procedure edinit(v)
36 | if (v)
37 | carray = keys(cdirectory = copy(v))
38 | end
39 |
40 | procedure edquit()
41 | return (cdirectory)
42 | end
43 |
44 | procedure keys(t) local i, k, l
45 | i = 0
46 | for (k in t)
47 | l[i=i+1] = k
48 | return (sort(l))
49 | end
50 |
--------------------------------------------------------------------------------
/ez/trunk/lib/ed.ez:
--------------------------------------------------------------------------------
1 | procedure ed(s)
2 | if (s = string(s)) {
3 | system("echo >/tmp/ezTmp '"||s||"'; ed /tmp/ezTmp");
4 | s = read("/tmp/ezTmp")
5 | system("rm /tmp/ezTmp")
6 | return (s)
7 | }
8 | end
9 |
--------------------------------------------------------------------------------
/ez/trunk/lib/hanoi.ez:
--------------------------------------------------------------------------------
1 | procedure hanoi(n, src, dst, tmp)
2 | if (n > 0) {
3 | hanoi(n - 1, src, tmp, dst)
4 | write("move a disk from ", src, " to ", dst, "\n")
5 | hanoi(n - 1, tmp, dst, src)
6 | }
7 | end
8 |
--------------------------------------------------------------------------------
/ez/trunk/lib/init.ez:
--------------------------------------------------------------------------------
1 | root = ["..":root]
2 |
3 | read("lib.ez")()
4 |
5 | mkdir(".edit")
6 | cd(".edit")
7 | load("edit")
8 |
9 | mkdir(".string")
10 | cd(".string")
11 | load("string")
12 | cd()
13 |
14 | mkdir(".table")
15 | cd(".table")
16 | load("table")
17 | cd()
18 |
19 | mkdir("term")
20 | cd("term")
21 | load("z19")
22 | cd()
23 |
--------------------------------------------------------------------------------
/ez/trunk/lib/lib.ez:
--------------------------------------------------------------------------------
1 | procedure cd(x)
2 | if (type(x) == "string")
3 | root = root[x]
4 | else if (type(x) == "table")
5 | root = x
6 | else
7 | cd("..")
8 | end
9 |
10 | procedure copy(t) local c, i
11 | if (type(t) ~= "table")
12 | return (t)
13 | else if (size(t) == 0)
14 | return (table())
15 | else {
16 | for (i in t)
17 | c[i] = t[i]
18 | return (c)
19 | }
20 | end
21 |
22 | procedure dupl(s, n)
23 | if (n <= 0)
24 | return ("")
25 | else if (n%2 == 0)
26 | return (dupl(s||s, n/2))
27 | else
28 | return (s||dupl(s||s, n/2))
29 | end
30 |
31 | procedure getfile(x)
32 | if (x)
33 | savefile = x
34 | return (savefile)
35 | end
36 |
37 | procedure itoc(n, b)
38 | if (n < 0)
39 | return ("-" || itoc(-n, b))
40 | else if (n < b)
41 | return (string(n%b))
42 | else
43 | return (itoc(n/b, b) || n%b)
44 | end
45 |
46 | procedure load(x)
47 | read(getfile(x) || ".ez")()
48 | end
49 |
50 | procedure ls(x) local i, s
51 | if (type(x) == "string")
52 | return (ls(root[x]))
53 | if (~x)
54 | return (ls(root))
55 | s = ""
56 | for (i in x)
57 | s = s || string(i) || "\n"
58 | return (s)
59 | end
60 |
61 | procedure max(x, y)
62 | if (x > y)
63 | return (x)
64 | else
65 | return (y)
66 | end
67 |
68 | procedure mkdir(s)
69 | root[s][".."] = root
70 | end
71 |
72 | procedure min(x, y)
73 | if (x < y)
74 | return (x)
75 | else
76 | return (y)
77 | end
78 |
79 | procedure pad(s, l)
80 | return (s||dupl(" ",l-size(s)))
81 | end
82 |
83 | procedure rm(x)
84 | remove(root, x)
85 | end
86 |
87 | procedure qsort(a, l, r) local v, t, i, j
88 | if (r > l) {
89 | v = a[r]; i = l - 1; j = r
90 | for (;;) {
91 | while (a[i=i+1]l & a[j=j-1]>v)
94 | ;
95 | t = a[i]; a[i] = a[j]; a[j] = t
96 | if (j <= i)
97 | break
98 | }
99 | a[j] = a[i]; a[i] = a[r]; a[r] = t
100 | qsort(a, l, i-1)
101 | qsort(a, i+1, r)
102 | }
103 | return (a)
104 | end
105 |
106 | procedure reset()
107 | system("stty -raw echo")
108 | end
109 |
110 | procedure sort(a)
111 | return (qsort(copy(a), 1, size(a)))
112 | end
113 |
114 | # stot - convert string to table
115 | procedure stot(s) local i, n, t
116 | n = 0
117 | t = table()
118 | while (i = upto("\n", s)) {
119 | t[n=n+1] = s[1:i]
120 | s = s[i+1:0]
121 | }
122 | if (s ~= "")
123 | t[n=n+1] = s
124 | return (t)
125 | end
126 |
127 | # ttos - convert table to string
128 | procedure ttos(t) local i, s
129 | s = ""
130 | for (i in t)
131 | s = s || string(t[i]) || "\n"
132 | if (size(t) == 1)
133 | return (s[1:-1])
134 | else
135 | return (s)
136 | end
137 |
138 | procedure vi(x)
139 | x = getfile(x)
140 | system("vi "||x||".ez")
141 | load(x)
142 | end
143 |
--------------------------------------------------------------------------------
/ez/trunk/lib/list.ez:
--------------------------------------------------------------------------------
1 | for (i = 1; i <= 10; i = i + 1) test[i] = "line " || i
2 |
3 | cx = cy = 1
4 | xmax = 80
5 | ymax = 10
6 |
7 | # home, down, up, right, left, enter commands
8 | keymap["h"] = procedure() curmov(1, 1) end
9 | keymap["d"] = procedure() curmov(cx, cy+1) end
10 | keymap["u"] = procedure() curmov(cx, cy-1) end
11 | keymap["r"] = procedure() curmov(cx+1, cy) end
12 | keymap["l"] = procedure() curmov(cx-1, cy) end
13 | keymap["e"] = procedure() edit(ctable[cy]) end
14 |
15 | # insert/delete character/line commands
16 | keymap["ic"] = procedure()
17 | if (check() & cx <= size(ctable[cy]))
18 | ctable[cy][cx!0] = " "
19 | end
20 | keymap["dc"] = procedure()
21 | if (check() & cx <= size(ctable[cy]))
22 | ctable[cy][cx!1] = ""
23 | end
24 | keymap["il"] = procedure()
25 | if (check()) {
26 | ctable[cy] = pad(ctable[cy], cx)
27 | ctable = ctable[1:cy] || ctable[cy:size(ctable)]
28 | ctable[cy][cx:0] = ""
29 | ctable[cy+1][1:cx] = ""
30 | }
31 | end
32 | keymap["dl"] = procedure foo()
33 | if (check()) {
34 | ctable[cy] = pad(ctable[cy], cx)[1:cx] || ctable[cy+1]
35 | ctable = ctable[1:cy] || ctable[cy+2:size(ctable)]
36 | }
37 | end
38 |
39 | # overstrike commands
40 | keymap["x"] = procedure(c)
41 | if (check()) {
42 | ctable[cy] = pad(ctable[cy], cx)
43 | ctable[cy][cx!1] = c
44 | curmov(cx+1, cy)
45 | }
46 | end
47 |
48 | # check - check that current line is a string
49 | procedure check()
50 | if (type(ctable[cy]) == "table") {
51 | error()
52 | return
53 | }
54 | return (1)
55 | end
56 |
57 | # curmov - move the cursor to (cx,cy)
58 | procedure curmov(x, y)
59 | if (x <= xmax) cx = x
60 | if (y <= ymax) cy = y
61 | end
62 |
63 | # estring - convert v to string of at most xmax characters
64 | procedure estring(v)
65 | local s
66 |
67 | if (size(s = string(v)) > xmax) s[xmax-3:0] = "..."
68 | return (s)
69 | end
70 |
71 | # error - signal illegal editing command
72 | procedure error()
73 | write(ascii[8!1]) # ring bell
74 | end
75 |
76 | # pad - pad s to length l
77 | procedure pad(s, l)
78 | if (l > size(s))
79 | return (pad(s||" ", l-1))
80 | return (s)
81 | end
82 |
83 | # refresh - redraw screen to reflect current state
84 | procedure refresh()
85 | for (i = 1; i <= ymax; i = i + 1)
86 | write(estring(ctable[i]), "\n")
87 | write("(", cx, ",", cy, ")")
88 | end
89 |
90 | procedure edit(v) local s
91 | ctable = v
92 | refresh()
93 | while (s = read())
94 | if (keymap[s]) {
95 | keymap[s](s)
96 | refresh()
97 | }
98 | end
99 |
--------------------------------------------------------------------------------
/ez/trunk/lib/map.ez:
--------------------------------------------------------------------------------
1 | kludge = 0
2 |
3 | procedure addmap(s, v, t)
4 | if (size(s) == 0)
5 | return
6 | else if (type(t[s[1!1]]) == "table")
7 | return (addmap(s[2:0], v, t[s[1!1]]))
8 | else if (t[s[1!1]])
9 | return
10 | else {
11 | t[s[1!1]] = mkmap(s[2:0], v)
12 | return (t)
13 | }
14 | end
15 |
16 | procedure mkmap(s, v) local t
17 | if (size(s) == 0)
18 | return (v)
19 | else {
20 | t[s[1!1]] = mkmap(s[2:0], v)
21 | return (t)
22 | }
23 | end
24 |
--------------------------------------------------------------------------------
/ez/trunk/lib/random.ez:
--------------------------------------------------------------------------------
1 | s = 0
2 | p = 12621
3 | c = 21131
4 | m = 100000
5 | procedure random(n)
6 | s = (s*p + c)%m
7 | return (s*n/m + 1)
8 | end
9 |
--------------------------------------------------------------------------------
/ez/trunk/lib/rpoints.ez:
--------------------------------------------------------------------------------
1 | procedure rpoints(p)
2 | if (type(p) == "procedure")
3 | for (i in p)
4 | write(i, ":\t", p[i], "\n")
5 | end
6 |
--------------------------------------------------------------------------------
/ez/trunk/lib/sort.ez:
--------------------------------------------------------------------------------
1 | From rebecca Tue May 3 11:24:58 1983
2 | To: drh
3 |
4 | Subject: EZ
5 |
6 | We have been working on this program (for too long now)
7 | and have the problem narrowed down to lines with Rvalues of the
8 | string s. Concatenation of s to some random string got
9 | rid of the syntax errors, but doesn't do much for quicksort.
10 | Confused,
11 | Ron and Becky
12 | procedure qsort(s)
13 | procedure sort(lb,ub)
14 | local i,j,p,t
15 | i = lb
16 | j = ub
17 | t = (lb + ub)/2
18 | p = s[t!1]
19 | while (1) {
20 | while (s[i!1] < p)
21 | i = i + 1
22 | while (p < s[j!1])
23 | j = j - 1
24 | if (i <= j) {
25 | t = s[i!1]
26 | s[i!1] = s[j!1]
27 | s[j!1] = t
28 | i = i + 1
29 | j = j - 1
30 | }
31 | if (i > j)
32 | break
33 | }
34 | if (lb < j)
35 | sort(lb,j)
36 | if (i < ub)
37 | sort(i,ub)
38 | end;
39 | sort(1,size(s))
40 | end
41 |
42 |
--------------------------------------------------------------------------------
/ez/trunk/lib/string.ez:
--------------------------------------------------------------------------------
1 | procedure edappd(n, new)
2 | while (n > size(carray))
3 | carray[size(carray)+1] = ""
4 | carray = carray[1:n+1] || table(new) || carray[n+1:size(carray)+1]
5 | end
6 |
7 | procedure edchng(n, new)
8 | if (n > size(carray))
9 | edappd(n-1, new)
10 | else
11 | carray[n] = new
12 | end
13 |
14 | procedure eddel(n)
15 | carray = carray[1:n] || carray[n+1:size(carray)+1]
16 | end
17 |
18 | procedure edesc()
19 | end
20 |
21 | procedure edgetl(n)
22 | return (carray[n])
23 | end
24 |
25 | procedure edinit(v)
26 | carray = stot(v)
27 | end
28 |
29 | procedure edlast()
30 | return (size(carray))
31 | end
32 |
33 | procedure edquit()
34 | return (ttos(carray))
35 | end
36 |
--------------------------------------------------------------------------------
/ez/trunk/lib/table.ez:
--------------------------------------------------------------------------------
1 | procedure edappd(n, new)
2 | ctable[new] = ""
3 | while (n > size(carray))
4 | carray[size(carray)+1] = ""
5 | carray = carray[1:n+1] || table(new) || carray[n+1:size(carray)+1]
6 | end
7 |
8 | procedure edchng(n, new) local old
9 | if (n > size(carray))
10 | edappd(n-1, new)
11 | else {
12 | old = carray[n]
13 | ctable[new] = ctable[old]
14 | if (old ~= new)
15 | remove(ctable, old)
16 | carray[n] = new
17 | }
18 | end
19 |
20 | procedure eddel(n)
21 | remove(ctable, carray[n])
22 | carray = carray[1:n] || carray[n+1:size(carray)+1]
23 | end
24 |
25 | procedure edesc(n) local sarray, stable
26 | sarray = carray
27 | stable = ctable
28 | ctable[carray[n]] = edit(ctable[carray[n]])
29 | carray = sarray
30 | ctable = stable
31 | end
32 |
33 | procedure edgetl(n)
34 | return (carray[n])
35 | end
36 |
37 | procedure edinit(v) local i, k
38 | if (v) {
39 | ctable = v
40 | i = 0
41 | carray = table()
42 | for (k in ctable)
43 | carray[i=i+1] = k
44 | }
45 | end
46 |
47 | procedure edlast()
48 | return (size(carray))
49 | end
50 |
51 | procedure edquit()
52 | return (ctable)
53 | end
54 |
--------------------------------------------------------------------------------
/ez/trunk/lib/wc.ez:
--------------------------------------------------------------------------------
1 | procedure wc(s)
2 | local nl, nw, i
3 |
4 | wordchars = ascii[upto(" ", ascii)+1:-1]
5 | nl = nw = 0
6 | while (i = upto(wordchars||"\n", s))
7 | if (s[i:i+1] == "\n") {
8 | nl = nl + 1
9 | s = s[i+1:0]
10 | }
11 | else {
12 | nw = nw + 1
13 | s = s[many(wordchars, s, i):0]
14 | }
15 | return (nl || " " || nw)
16 | end
17 |
--------------------------------------------------------------------------------
/ez/trunk/lib/wf.ez:
--------------------------------------------------------------------------------
1 | procedure table(s)
2 | local i, j, t
3 |
4 | s = string(s)
5 | i = 0
6 | while (j = upto("\n", s)) {
7 | t[i = i + 1] = s[1:j+1]
8 | s = s[j+2:0]
9 | }
10 | if (size(s) > 0)
11 | t[i+1] = s
12 | return (t)
13 | end
14 |
15 | procedure wf(s)
16 | local t, i, j
17 |
18 | for (i = 1; i = upto(lcase, s, i); i = j) {
19 | j = many(lcase, s, i)
20 | if (t[s[i:j]])
21 | t[s[i:j]] = t[s[i:j]] + 1
22 | else
23 | t[s[i:j]] = 1
24 | }
25 | for (i in t)
26 | write(t[i], "\t", i, "\n")
27 | end
28 |
--------------------------------------------------------------------------------
/ez/trunk/lib/z19.ez:
--------------------------------------------------------------------------------
1 | xmax = 80
2 | ymax = 24
3 |
4 | keymap = table()
5 | addmap("\b", procedure() curmov(cx-1, cy); delchr() end, keymap) # backspace
6 | addmap("\012", procedure() escape() end, keymap) # escape
7 | addmap("\015", procedure() curmov(1, cy+1) end, keymap) # return
8 | addmap("\033A", procedure() curmov(cx, cy-1) end, keymap) # up
9 | addmap("\033B", procedure() curmov(cx, cy+1) end, keymap) # down
10 | addmap("\033C", procedure() curmov(cx+1, cy) end, keymap) # right
11 | addmap("\033D", procedure() curmov(cx-1, cy) end, keymap) # left
12 | addmap("\033H", procedure() curmov(1, 1) end, keymap) # home
13 | addmap("\033J", procedure() touch(1, ymax) end, keymap) # refresh
14 | addmap("\033L", procedure() inslin() end, keymap) # insert line
15 | addmap("\033@", procedure() inschr() end, keymap) # insert char
16 | addmap("\033M", procedure() dellin() end, keymap) # delete line
17 | addmap("\033N", procedure() delchr() end, keymap) # delete char
18 | addmap("\033P", procedure() mark() end, keymap) # mark
19 | addmap("\033Q", procedure() pick() end, keymap) # pick
20 | addmap("\033R", procedure() put() end, keymap) # put
21 | addmap("\033S", procedure() scnmov( 7) end, keymap) # +lines
22 | addmap("\033T", procedure() scnmov(-7) end, keymap) # -lines
23 | addmap("\033U", procedure() scnmov( ymax) end, keymap) # +pages
24 | addmap("\033V", procedure() scnmov(-ymax) end, keymap) # -pages
25 | addmap("\033W", procedure() mode = 1 - mode end, keymap) # insert mode
26 | addmap("\033/", procedure() search(+1) end, keymap) # +search
27 | addmap("\033?", procedure() search(-1) end, keymap) # -search
28 | addmap("\177", procedure() exec() end, keymap) # exec
29 |
30 | for (i = 32; i < 128; i = i + 1)
31 | addmap(ascii[i+1!1], procedure(c) overstrike(c) end, keymap) # overstrike
32 | remove(root, "i")
33 |
34 | procedure error(s)
35 | write(ascii[8!1])
36 | end
37 |
38 | procedure init(s)
39 | write("\033x6")
40 | end
41 |
--------------------------------------------------------------------------------
/ez/trunk/src/TODO:
--------------------------------------------------------------------------------
1 | - make a copy of initial root
2 | - implement t(), where t is a table
3 | - implement f[...], where f is a function
4 | - implement initial values for locals
5 | - rearrange assignment code.
6 | - not all operators handle VOID correctly (e.g. ||)
7 | - implement position-independent procedure parameters (foo(arg=exp))
8 | - fix O_QUIT code so it's emitted only if necessary
9 |
--------------------------------------------------------------------------------
/ez/trunk/src/main.c:
--------------------------------------------------------------------------------
1 | /* ez: main program */
2 |
3 | #include
4 | #include
5 | #include
6 | #include "ez.h"
7 | #include "tokens.h"
8 | #include
9 | #include
10 |
11 | int execute; /* set to execute input */
12 | jmp_buf restart; /* to restart after runtime errors */
13 | int debug; /* debugging bits */
14 | char *progname = "";
15 | char *fsysname = FILESYS;/* ez file system name */
16 | extern int cachelimit; /* cache size limit */
17 | extern int trace; /* trace counter */
18 | extern int slength; /* source code length */
19 | extern char *source; /* source code */
20 | extern struct root *rp; /* pointer to root block */
21 |
22 | /* main program - parse and execute statements */
23 | main(argc, argv)
24 | int argc;
25 | char *argv[];
26 | {
27 | FILE *f;
28 | int i;
29 | sig_t isig, onintr;
30 | extern struct value errors;
31 | struct value v, getline();
32 |
33 | progname = *argv;
34 | isig = signal(SIGINT, SIG_IGN);
35 | debug = trace = 0;
36 | cachelimit = 100;
37 | for (i = 1; i < argc; i++)
38 | if (strncmp(argv[i], "-D", 2) == 0)
39 | if (isdigit(argv[i][2]))
40 | debug |= 1<<(atoi(&argv[i][2])-1);
41 | else
42 | debug = 0;
43 | else if (strncmp(argv[i], "-C", 2) == 0)
44 | if (argv[i][2])
45 | cachelimit = atoi(&argv[i][2]);
46 | else
47 | cachelimit = 100;
48 | else if (strncmp(argv[i], "-t", 2) == 0)
49 | if (argv[i][2])
50 | trace = atoi(&argv[i][2]);
51 | else
52 | trace = -1;
53 | else
54 | fsysname = argv[i];
55 | initialize(fsysname);
56 | for (;;) {
57 | setjmp(restart);
58 | if (isig != SIG_IGN)
59 | signal(SIGINT, onintr);
60 | v = getline(stdin);
61 | if (TYPE(v) == T_VOID)
62 | break;
63 | if (debug&DBINPUT) {
64 | image(v, stderr, 1);
65 | putc('\n', stderr);
66 | }
67 | v = excvproc(v);
68 | if (nerrors)
69 | excvstr(errors, stdout);
70 | else if (execute) {
71 | v = apply(v);
72 | excvstr(v, stdout);
73 | if (TYPE(v) != T_VOID)
74 | putchar('\n');
75 | }
76 | }
77 | putblk(rp, 1);
78 | savecache();
79 | }
80 |
81 | /* getline - get next input source item */
82 | struct value getline(f)
83 | FILE *f;
84 | {
85 | struct value v;
86 | char *s;
87 | int t, va, n, c1, c2;
88 |
89 | execute = 0;
90 | initlex(f, NULL, stderr);
91 | va = salloc();
92 | source = SOPENW(va);
93 | n = 0;
94 | switch (c1 = t = gtok('\n')) {
95 | case EOF:
96 | c2 = EOF;
97 | break;
98 | case '{':
99 | execute++;
100 | c2 = '}';
101 | break;
102 | case PROCEDURE:
103 | execute++;
104 | c2 = END;
105 | break;
106 | default:
107 | execute++;
108 | c1 = 0;
109 | c2 = '\n';
110 | break;
111 | }
112 | do {
113 | if (t == c2 && --n < 0)
114 | break;
115 | t = gtok(0);
116 | if (t == c1)
117 | n++;
118 | } while (t > 0);
119 | SCLOSEW(source);
120 | source = NULL;
121 | if (c2 == -1)
122 | return (VOID);
123 | return (mkstr(va, slength));
124 | }
125 |
126 | /* initialize - initialize ez file system in fname */
127 | initialize(fname)
128 | char *fname;
129 | {
130 | struct value *vp;
131 | struct table *bp;
132 | int fd, i;
133 | extern int filesize, cnstp, strp, level;
134 |
135 | if (access(fname, 2)) {
136 | if ((fd = creat(fname, 0666)) == -1) {
137 | fprintf(stderr, "%s: can't create\n", fname);
138 | exit(1);
139 | }
140 | close(fd);
141 | }
142 | initcache(fname);
143 | rp = (struct root *) getblk(0);
144 | if (filesize > sizeof(struct block) && rp->r_major != MAJOR) {
145 | fprintf(stderr, "%s: version mismatch; %s version is %d.%d, \
146 | system version is %d.%d\n", progname, fname, rp->r_major, rp->r_minor,
147 | MAJOR, MINOR);
148 | exit(1);
149 | }
150 | touch(rp);
151 | *builtin("root") = rp->r_globals;
152 | cnstp = strp = level = 0;
153 | Procedure = stralloc("Procedure", -1);
154 | Resumption = stralloc("Resumption", -1);
155 | if (rp->r_major == MAJOR)
156 | return;
157 | rp->r_type = B_DATA;
158 | rp->r_major = MAJOR;
159 | rp->r_minor = MINOR;
160 | rp->r_freelist = 0;
161 | bp = (struct table *) balloc(B_TABLE);
162 | rp->r_globals = mkval(T_TABLE, 0, virtaddr(bp));
163 | rp->r_wglobals = rp->r_globals;
164 | putblk(bp, 0);
165 | rp->r_dotdot = stralloc("..", -1);
166 | VOID = mkval(T_VOID, 0, 0);
167 | *builtin("root") = rp->r_globals;
168 | for (i = 0; bivalues[i].bi_name; i++) {
169 | vp = tindex(rp->r_globals,stralloc(bivalues[i].bi_name,-1),1);
170 | *vp = *builtin(bivalues[i].bi_name);
171 | putblk(vp, 1);
172 | }
173 | }
174 |
175 | /* onintr - called on Interrupt signal */
176 | onintr()
177 | {
178 | fprintf(stderr, "\nInterrupt\n");
179 | longjmp(restart, 1);
180 | }
181 |
182 |
--------------------------------------------------------------------------------
/ez/trunk/src/makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-g
2 | FILES=ez.h tokens.h cache.c code.c cvt.c expr.c func.c gen.c lex.c \
3 | main.c parse.c proc.c stmt.c table.c util.c collect.c
4 | OBJECTS=cache.o code.o cvt.o expr.o func.o gen.o \
5 | lex.o main.o parse.o proc.o stmt.o table.o util.o
6 |
7 | a.out: $(OBJECTS) makefile
8 | cc -g $(OBJECTS)
9 |
10 | $(OBJECTS) collect.o: ez.h
11 |
12 | main.o lex.o gen.o parse.o expr.o stmt.o: tokens.h
13 |
14 | ez: a.out
15 | cp a.out ez
16 |
17 | collect: collect.o cache.o
18 | cc -w -g -o collect collect.o cache.o
19 |
20 | install: ez collect
21 | cp ez collect $(DESTDIR)
22 |
23 | clean:
24 | -rm -f $(OBJECTS) a.out collect.o
25 |
26 | clobber: clean
27 | -rm -f ez collect
28 |
29 |
--------------------------------------------------------------------------------
/ez/trunk/src/parse.c:
--------------------------------------------------------------------------------
1 | /* ez compiler: top-level parsing */
2 |
3 | #include
4 | #include "ez.h"
5 | #include "tokens.h"
6 |
7 | static int follow[] = {END, 0}; /* follow set for procedures */
8 | struct value errors = {T_VOID, 0}; /* current value of `errors' */
9 | static struct value err = {T_VOID, 0}; /* string "errors" */
10 | static int errp = 0; /* virtual address of error string */
11 | extern char *errs;
12 | extern int elength;
13 |
14 | /* prog : { stmt }
15 | *
16 | * ezparse - parse ez program in string v
17 | */
18 | struct value ezparse(v)
19 | struct value v;
20 | {
21 | struct proc *p;
22 |
23 | initlex(NULL, &v, NULL);
24 | errs = SOPENW(errp = salloc());
25 | t = gtok('\n');
26 | p = procbeg(NULL);
27 | endpoint(begpoint());
28 | stmtlist(0);
29 | endpoint(begpoint());
30 | emit1(O_RET);
31 | emit(2, O_ERR, 1);
32 | p->p_source = v;
33 | v = mkval(T_PROC, 0, procend(p));
34 | newline();
35 | if (t != EOF)
36 | error("syntax error", "");
37 | geterrors();
38 | if (nerrors)
39 | v = VOID;
40 | return (v);
41 | }
42 |
43 | /* func : procedure [ id ] `(' [ id { , id } ] `)' { dcl } { stmt } end
44 | *
45 | * parse procedure definition
46 | */
47 | int func()
48 | {
49 | struct compile csav;
50 | extern int cursor, tcursor;
51 | extern struct value src;
52 | int n, a, bpos, epos;
53 | struct proc *p;
54 |
55 | csav = c;
56 | bpos = tcursor;
57 | t = gtok('\n');
58 | if (t == ID) {
59 | p = procbeg(lexval.l_str);
60 | t = gtok('\n');
61 | }
62 | else
63 | p = procbeg(NULL);
64 | c.offset = bpos - 1;
65 | endpoint(begpoint());
66 | newline();
67 | mustbe('(', '\n');
68 | while (t == ID) {
69 | dcl(lexval.l_str, p, 0);
70 | t = gtok('\n');
71 | if (t != ',')
72 | break;
73 | t = gtok('\n');
74 | }
75 | mustbe(')', '\n');
76 | while (t == LOCAL) {
77 | t = gtok('\n');
78 | while (t == ID) {
79 | dcl(lexval.l_str, p, LOCAL);
80 | t = gtok(0);
81 | if (t != ',')
82 | break;
83 | t = gtok('\n');
84 | }
85 | newline();
86 | }
87 | stmtlist(0);
88 | endpoint(begpoint());
89 | emit(2, O_GVAL, constant(VOID));
90 | emit1(O_RET);
91 | emit(2, O_ERR, 1);
92 | epos = cursor - 1;
93 | if (t == END)
94 | t = gtok(0);
95 | else {
96 | error("missing end", "");
97 | skipto(follow, 0);
98 | }
99 | if (t == EOF)
100 | epos++;
101 | p->p_source = substr(src, bpos, epos);
102 | a = procend(p);
103 | c = csav;
104 | return (a);
105 | }
106 |
107 | /* dcl - declaration of formal parameter or local in p */
108 | dcl(id, p, lflag)
109 | char *id;
110 | struct proc *p;
111 | int lflag;
112 | {
113 | struct value *vp;
114 |
115 | vp = tindex(p->p_sym, stralloc(id, -1), 1);
116 | if (TYPE(*vp) != T_VOID)
117 | error("parameter or local previously declared: ", id);
118 | else if (lflag == LOCAL)
119 | *vp = mkval(T_VAR, 0, ++p->p_nlocals);
120 | else
121 | *vp = mkval(T_VAR, 0, -++p->p_nargs);
122 | putblk(vp, 1);
123 | bfree(id);
124 | }
125 |
126 | /* geterrors - assign compilation error string to `errors' */
127 | geterrors()
128 | {
129 | struct value *vp;
130 | extern struct root *rp;
131 |
132 | if (errs)
133 | SCLOSEW(errs);
134 | if (nerrors) {
135 | if (TYPE(err) != T_STRING)
136 | err = stralloc("errors", -1);
137 | vp = tindex(rp->r_wglobals, err, 1);
138 | *vp = errors = mkstr(errp, elength);
139 | putblk(vp, 1);
140 | }
141 | }
142 |
143 | /* inset - return t if it is in set, return 0 otherwise */
144 | int inset(t, set)
145 | int t, *set;
146 | {
147 | while (*set)
148 | if (t == *set++)
149 | return (t);
150 | return (0);
151 | }
152 |
153 | /* recompile - recompile source for procedure p */
154 | int recompile(p)
155 | struct proc *p;
156 | {
157 | int a;
158 | struct proc *p1;
159 |
160 | initlex(NULL, &p->p_source, NULL);
161 | errs = SOPENW(errp = salloc());
162 | t = gtok('\n');
163 | if (t == PROCEDURE)
164 | a = func();
165 | else {
166 | p1 = procbeg(NULL);
167 | endpoint(begpoint());
168 | stmtlist(0);
169 | endpoint(begpoint());
170 | emit1(O_RET);
171 | emit(2, O_ERR, 1);
172 | p1->p_source = p->p_source;
173 | a = procend(p1);
174 | newline();
175 | if (t != EOF)
176 | error("syntax error", "");
177 | }
178 | geterrors();
179 | if (nerrors == 0) { /* overwrite previous procedure block */
180 | p1 = (struct proc *) getblk(a);
181 | *p = *p1;
182 | putblk(p1, 0);
183 | touch(p);
184 | }
185 | return (nerrors);
186 | }
187 |
188 | /* skipto - discard input upto next occurrence of character in set or EOF */
189 | skipto(set, ic)
190 | int *set, ic;
191 | {
192 | while (t != EOF && inset(t, set) == 0)
193 | t = gtok(ic);
194 | }
195 |
--------------------------------------------------------------------------------
/ez/trunk/src/tokens.h:
--------------------------------------------------------------------------------
1 | /* ez tokens (other than single characters) */
2 |
3 | #define EQ 256 /* == */
4 | #define NE 257 /* != */
5 | #define LE 258 /* <= */
6 | #define GE 259 /* >= */
7 | #define CAT 260 /* || */
8 | #define CON 261 /* integer constant */
9 | #define FCON 262 /* floating constant */
10 | #define SCON 263 /* string constant */
11 | #define BCON 264 /* built-in value constant */
12 | #define ID 265 /* identifier */
13 | #define IF 266 /* if */
14 | #define ELSE 267 /* else */
15 | #define WHILE 268 /* while */
16 | #define FOR 269 /* for */
17 | #define RETURN 270 /* return */
18 | #define BREAK 271 /* break */
19 | #define CONTINUE 272 /* continue */
20 | #define PROCEDURE 273 /* procedure */
21 | #define IN 274 /* in */
22 | #define LOCAL 275 /* local */
23 | #define END 276 /* end */
24 |
25 | #define emit1(x) emit(1,x)
26 | #define UNARY 01000| /* unary operator indicator */
27 | #define SUFFIX 02000| /* suffix operator indicator */
28 | #define BINARY 04000| /* binary operator indicator */
29 |
30 | struct node { /* expression nodes */
31 | int ex_op; /* operator */
32 | int ex_type; /* type of result */
33 | struct node *ex_l; /* operands */
34 | struct node *ex_r;
35 | int ex_result; /* result flag */
36 | int ex_count; /* reference count */
37 | };
38 |
39 | struct bpnode { /* backpatch list node */
40 | int addr; /* virtual address to patch */
41 | struct bpnode *next; /* next node */
42 | };
43 |
44 | struct label { /* label definitions */
45 | int addr; /* virtual address of label */
46 | struct bpnode *bplist; /* backpatch list until defined */
47 | };
48 |
49 | struct compile { /* compilation variables */
50 | struct proc *proc; /* current procedure */
51 | int offset; /* offset into input of beginning of proc */
52 | int loop; /* current loop handle */
53 | int forlevel; /* nesting depth for for (x in e) loops */
54 | int label; /* next generated label */
55 | struct code *cblock; /* current code block */
56 | int *pc; /* pointer to next word in cblock->c_code */
57 | struct label labels[200];/* labels */
58 | int point; /* next resumption point */
59 | struct point points[100];/* resumption points */
60 | };
61 |
62 | struct lexval { /* values set by gtok */
63 | char *l_str; /* string and name token */
64 | int l_length; /* length of string constant */
65 | int l_ival; /* integer and character constant */
66 | };
67 |
68 | /* global variables */
69 | extern int t; /* current token */
70 | extern struct lexval lexval; /* associated value */
71 | extern int nerrors; /* error count */
72 | extern struct compile c; /* current compilation record */
73 |
--------------------------------------------------------------------------------
/loom/tags/original/README:
--------------------------------------------------------------------------------
1 | This directory contains the `old' version of loom, which is distributed
2 | for personal use only. Please do not distribute it further. This
3 | version of loom is intended C programs and contains some C dependencies.
4 |
5 | The makefile details how to build loom. A manual page is in loom.1.
6 |
7 | common.c is the common words program from which the program described
8 | in the `Literate Programming' column in the Communications of the ACM,
9 | vol. 30, no. 7, 594-599, July 1987 was derived. common.c also contains
10 | the documentation, which is an expanded version of the CACM paper. This
11 | documentation appeared in D. R. Hanson, `Printing Common Words', Tech.
12 | Report 86-18, Dept. of Computer Science, Univ. of Arizona, May 1986.
13 |
14 | Several readers found an error in the common words program presented in
15 | the CACM paper and others suggested improvements. This version of
16 | common.c incorporates changes made in response to their comments.
17 |
18 | The makefile also contains entries for making common, the executable
19 | version of the common words program, and common.dvi, it's TeX
20 | documentation. Both are constructed from common.c.
21 |
22 | common.c is included as an example of loom usage. Since it uses several
23 | unavailable filters and programs (e.g., prog, xref, and makeindex), it
24 | is not possible to construct common.tex from common.c as shown in the
25 | makefile. These filters (and others) will be available in the next
26 | version of loom.
27 |
28 | In addition, common.tex depends on the TeX macro packages loommac.tex
29 | and macros.tex, which are not included. loommac.tex and macros.tex are
30 | used to typeset loom documents in a style similar to Don Knuth's WEB
31 | system. Other styles can be generated by using other macros.
32 |
33 | David R. Hanson
34 | Dept. of Computer Science
35 | Princeton University
36 | Princeton, NJ 08544
37 | 609 452-5598
38 | drh@princeton.edu
39 |
40 | 9/19/87
41 |
--------------------------------------------------------------------------------
/loom/tags/original/alloc.c:
--------------------------------------------------------------------------------
1 |
2 | /* alloc - allocate space of n objects of size bytes or issue error message */
3 | char *alloc(n, size)
4 | int n, size;
5 | {
6 | char *p, *calloc();
7 |
8 | if (p = calloc(n, size))
9 | return p;
10 | error("storage overflow", (char *)0);
11 | return 0;
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/loom/tags/original/error.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | error(s1, s2, s3) /* print error message and die */
4 | char *s1, *s2, *s3;
5 | {
6 | warn(s1, s2, s3);
7 | exit(1);
8 | }
9 |
10 | warn(s1, s2, s3) /* print error message */
11 | char *s1, *s2, *s3;
12 | {
13 | extern int errno, sys_nerr;
14 | extern char *sys_errlist[], *progname;
15 |
16 | fprintf(stderr, "%s: ", progname);
17 | fprintf(stderr, s1, s2, s3);
18 | if (errno > 0 && errno < sys_nerr)
19 | fprintf(stderr, "; %s", sys_errlist[errno]);
20 | fprintf(stderr, "\n");
21 | }
22 |
--------------------------------------------------------------------------------
/loom/tags/original/index.tex:
--------------------------------------------------------------------------------
1 | \beginindex
2 | \newletter
3 | |addword|, 3, 8, 14.\par
4 | |alloc|, 8--10, 14.\par
5 | |argc|, 4.\par
6 | |argv|, 4.\par
7 | |atoi|, 4.\par
8 | \newletter
9 | |break|, 8.\par
10 | |buf|, 3--5, 8, 13--14.\par
11 | \newletter
12 | |calloc|, 9.\par
13 | |char|, 4--6, 8--9, 14.\par
14 | |count|, 6, 8, 10, 13--14.\par
15 | \newletter
16 | |define|, 5--6.\par
17 | \newletter
18 | |else|, 4.\par
19 | |error|, 9.\par
20 | \newletter
21 | |getchar|, 5.\par
22 | |getenv|, 4.\par
23 | |getword|, 3, 5.\par
24 | \newletter
25 | |HASHSIZE|, 6--8, 10, 14.\par
26 | |hashtable|, 6--8, 10, 14.\par
27 | \newletter
28 | |isletter|, 5.\par
29 | \newletter
30 | |k|, 3--4.\par
31 | \newletter
32 | |list|, 10.\par
33 | \newletter
34 | |main|, 4.\par
35 | |MAXWORD|, 3--4.\par
36 | \newletter
37 | |next|, 6, 8, 10, 14.\par
38 | |NULL|, 7--8.\par
39 | \newletter
40 | |printf|, 10.\par
41 | |printwords|, 3, 10.\par
42 | |progname|, 4, 9.\par
43 | \newletter
44 | |return|, 5, 9, 14.\par
45 | \newletter
46 | |scatter|, 8, 14.\par
47 | |size|, 5, 9.\par
48 | |sizeof|, 8, 10, 14.\par
49 | |strcmp|, 8.\par
50 | |strcpy|, 8, 14.\par
51 | |struct|, 6, 8, 10, 14.\par
52 | \newletter
53 | |unsigned|, 8, 14.\par
54 | \newletter
55 | |while|, 3, 5.\par
56 | |word|, 6, 8, 10, 13--14.\par
57 | \endindex
58 |
--------------------------------------------------------------------------------
/loom/tags/original/loom.1:
--------------------------------------------------------------------------------
1 | .TH LOOM 1 "local \- 2/25/87"
2 | .SH NAME
3 | loom \- weave fragments together
4 | .SH SYNOPSIS
5 | .B loom
6 | [ file \(br option ]...
7 | .br
8 | .SH DESCRIPTION
9 | .PP
10 | .I loom
11 | copies the named files, or the standard input if no files are given,
12 | to the standard output replacing occurrences of lines of the form
13 | .IP ""
14 | %include
15 | .IR file \ [
16 | .IR section \ ]\ [
17 | .IR cmd \ ]
18 | .PP
19 | by the fragment named
20 | .I section
21 | in file
22 | .IR file .
23 | If
24 | .I cmd
25 | is given, it is executed with the text of the specified fragment
26 | as its standard input, and the standard output replaces
27 | the %include line, i.e. the fragment is ``filtered'' through
28 | .IR cmd .
29 | .I cmd
30 | may be preceeded by a vertical bar (|).
31 | If
32 | .I section
33 | is omitted, the entire file is filtered through
34 | .IR cmd ,
35 | and
36 | .I cmd
37 | .I must
38 | be preceeded by a vertical bar.
39 | The section name \fB-\fP can also be used to refer to the entire file.
40 | .PP
41 | Fragments are identified by named sections of the form:
42 | .IP ""
43 | .nf
44 | /* include section */
45 | ...body of fragment...
46 | /* end section */
47 | .fi
48 | .PP
49 | or by
50 | .IP ""
51 | .nf
52 | {include section}
53 | ...body of fragment...
54 | {end section}
55 | .fi
56 | .PP
57 | Entire functions are also identified as fragments if they
58 | have the form:
59 | .IP ""
60 | .nf
61 | /* name - comments */
62 | ... name(...)
63 | {
64 | ...
65 | }
66 | .fi
67 | .PP
68 | Spacing, etc. must be
69 | .I exactly
70 | as given.
71 | The section delimiters are
72 | .I not
73 | included in the fragment.
74 | .PP
75 | .I loom
76 | accepts the following options.
77 | Options take effect when they are encountered during the left-to-right
78 | processing of the arguments.
79 | Thus, their placement is significant.
80 | .TP
81 | \fB\-I \fIdirectory\fR
82 | Add
83 | .I directory
84 | to the list of directories examined when searching for a
85 | file given in a %include line.
86 | The directories are examined in the order given by \fB-I\fR options.
87 | .TP
88 | \fB\-f\fI cmd\fR
89 | Use
90 | .I cmd
91 | as the `default filter' for %include lines on which filters are omitted.
92 | .PP
93 | The primary use of
94 | .I loom
95 | is to include program fragments in
96 | .I troff
97 | or TeX documents.
98 | .SH "SEE ALSO"
99 | troff(1)
100 | .SH DIAGNOSTICS
101 | Mostly self-explanatory messages.
102 | .SH BUGS
103 | Erroneous %include lines and section delimiters are handled ungracefully.
104 |
--------------------------------------------------------------------------------
/loom/tags/original/makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-g -DFAST
2 |
3 | loom: loom.o
4 | cc $(CFLAGS) -o loom loom.o
5 |
6 | common: common.o
7 | cc $(CFLAGS) -o common common.o
8 |
9 | common.o: alloc.c error.c
10 |
11 | common.dvi: common.tex index.tex
12 | tex common
13 |
14 | index.tex: common.tex
15 | rm -f index.dat index.tex
16 | tex common
17 | makeindex index.dat >index.tex
18 | rm common.dvi
19 |
20 | common.tex: common.c
21 | cc -E -C -DTeXinput common.c | sed '/^#/d' | \
22 | loom -I /u/drh/src -f "prog|xref +buf +k -t" >common.tex
23 |
24 | clean:
25 | rm -f common common.dvi a.out loom *.o index.dat *.log
26 |
--------------------------------------------------------------------------------
/loom/trunk/README:
--------------------------------------------------------------------------------
1 | This directory contains the 'old' version of loom. This version of loom is
2 | intended for C programs and contains some C dependencies.
3 |
4 | The makefile details how to build loom. A manual page is in loom.1.
5 |
6 | common.c is the common words program from which the program described
7 | in the 'Literate Programming' column in the Communications of the ACM,
8 | vol. 30, no. 7, 594-599, July 1987 was derived. common.c also contains
9 | the documentation, which is an expanded version of the CACM paper. This
10 | documentation appeared in D. R. Hanson, 'Printing Common Words', Tech.
11 | Report 86-18, Dept. of Computer Science, Univ. of Arizona, May 1986.
12 |
13 | Several readers found an error in the common words program presented in
14 | the CACM paper and others suggested improvements. This version of
15 | common.c incorporates changes made in response to their comments.
16 |
17 | The makefile also contains entries for making common, the executable
18 | version of the common words program, and common.dvi, its TeX
19 | documentation. Both are constructed from common.c.
20 |
21 | common.c is an example of loom usage. Since it uses several unavailable filters
22 | and programs (e.g., prog, xref, and makeindex), it is not possible to construct
23 | common.tex from common.c as shown in the makefile.
24 |
25 | In addition, common.tex depends on the TeX macro packages loommac.tex and
26 | macros.tex, which are not included here, but are available at
27 | http://drhanson.googlecode.com/svn/tex/trunk. loommac.tex and macros.tex are
28 | used to typeset loom documents in a style similar to Don Knuth's WEB system.
29 | Other styles can be generated by using other macros.
30 |
31 | David R. Hanson
32 | drh at drhanson dot net
33 |
34 | 9/19/87
35 |
--------------------------------------------------------------------------------
/loom/trunk/index.tex:
--------------------------------------------------------------------------------
1 | \beginindex
2 | \newletter
3 | |addword|, 3, 8, 14.\par
4 | |alloc|, 8--10, 14.\par
5 | |argc|, 4.\par
6 | |argv|, 4.\par
7 | |atoi|, 4.\par
8 | \newletter
9 | |break|, 8.\par
10 | |buf|, 3--5, 8, 13--14.\par
11 | \newletter
12 | |calloc|, 9.\par
13 | |char|, 4--6, 8--9, 14.\par
14 | |count|, 6, 8, 10, 13--14.\par
15 | \newletter
16 | |define|, 5--6.\par
17 | \newletter
18 | |else|, 4.\par
19 | |error|, 9.\par
20 | \newletter
21 | |getchar|, 5.\par
22 | |getenv|, 4.\par
23 | |getword|, 3, 5.\par
24 | \newletter
25 | |HASHSIZE|, 6--8, 10, 14.\par
26 | |hashtable|, 6--8, 10, 14.\par
27 | \newletter
28 | |isletter|, 5.\par
29 | \newletter
30 | |k|, 3--4.\par
31 | \newletter
32 | |list|, 10.\par
33 | \newletter
34 | |main|, 4.\par
35 | |MAXWORD|, 3--4.\par
36 | \newletter
37 | |next|, 6, 8, 10, 14.\par
38 | |NULL|, 7--8.\par
39 | \newletter
40 | |printf|, 10.\par
41 | |printwords|, 3, 10.\par
42 | |progname|, 4, 9.\par
43 | \newletter
44 | |return|, 5, 9, 14.\par
45 | \newletter
46 | |scatter|, 8, 14.\par
47 | |size|, 5, 9.\par
48 | |sizeof|, 8, 10, 14.\par
49 | |strcmp|, 8.\par
50 | |strcpy|, 8, 14.\par
51 | |struct|, 6, 8, 10, 14.\par
52 | \newletter
53 | |unsigned|, 8, 14.\par
54 | \newletter
55 | |while|, 3, 5.\par
56 | |word|, 6, 8, 10, 13--14.\par
57 | \endindex
58 |
--------------------------------------------------------------------------------
/loom/trunk/loom.1:
--------------------------------------------------------------------------------
1 | .TH LOOM 1 "local \- 2/25/87"
2 | .SH NAME
3 | loom \- weave fragments together
4 | .SH SYNOPSIS
5 | .B loom
6 | [ file \(br option ]...
7 | .br
8 | .SH DESCRIPTION
9 | .PP
10 | .I loom
11 | copies the named files, or the standard input if no files are given,
12 | to the standard output replacing occurrences of lines of the form
13 | .IP ""
14 | %include
15 | .IR file \ [
16 | .IR section \ ]\ [
17 | .IR cmd \ ]
18 | .PP
19 | by the fragment named
20 | .I section
21 | in file
22 | .IR file .
23 | If
24 | .I cmd
25 | is given, it is executed with the text of the specified fragment
26 | as its standard input, and the standard output replaces
27 | the %include line, i.e. the fragment is ``filtered'' through
28 | .IR cmd .
29 | .I cmd
30 | may be preceeded by a vertical bar (|).
31 | If
32 | .I section
33 | is omitted, the entire file is filtered through
34 | .IR cmd ,
35 | and
36 | .I cmd
37 | .I must
38 | be preceeded by a vertical bar.
39 | The section name \fB-\fP can also be used to refer to the entire file.
40 | .PP
41 | Fragments are identified by named sections of the form:
42 | .IP ""
43 | .nf
44 | /* include section */
45 | ...body of fragment...
46 | /* end section */
47 | .fi
48 | .PP
49 | or by
50 | .IP ""
51 | .nf
52 | {include section}
53 | ...body of fragment...
54 | {end section}
55 | .fi
56 | .PP
57 | Entire functions are also identified as fragments if they
58 | have the form:
59 | .IP ""
60 | .nf
61 | /* name - comments */
62 | ... name(...)
63 | {
64 | ...
65 | }
66 | .fi
67 | .PP
68 | Spacing, etc. must be
69 | .I exactly
70 | as given.
71 | The section delimiters are
72 | .I not
73 | included in the fragment.
74 | .PP
75 | .I loom
76 | accepts the following options.
77 | Options take effect when they are encountered during the left-to-right
78 | processing of the arguments.
79 | Thus, their placement is significant.
80 | .TP
81 | \fB\-I \fIdirectory\fR
82 | Add
83 | .I directory
84 | to the list of directories examined when searching for a
85 | file given in a %include line.
86 | The directories are examined in the order given by \fB-I\fR options.
87 | .TP
88 | \fB\-f\fI cmd\fR
89 | Use
90 | .I cmd
91 | as the `default filter' for %include lines on which filters are omitted.
92 | .PP
93 | The primary use of
94 | .I loom
95 | is to include program fragments in
96 | .I troff
97 | or TeX documents.
98 | .SH "SEE ALSO"
99 | troff(1)
100 | .SH DIAGNOSTICS
101 | Mostly self-explanatory messages.
102 | .SH BUGS
103 | Erroneous %include lines and section delimiters are handled ungracefully.
104 |
--------------------------------------------------------------------------------
/loom/trunk/makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-g -DFAST
2 |
3 | loom: loom.o
4 | cc $(CFLAGS) -o loom loom.o
5 |
6 | common: common.o
7 | cc $(CFLAGS) -o common common.o
8 |
9 | common.dvi: common.tex index.tex
10 | tex common
11 |
12 | index.tex: common.tex
13 | rm -f index.dat index.tex
14 | tex common
15 | makeindex index.dat >index.tex
16 | rm common.dvi
17 |
18 | common.tex: common.c
19 | cc -E -C -DTeXinput common.c | sed '/^#/d' | \
20 | loom -I . -f "prog|xref +buf +k -t" >common.tex
21 |
22 | clean:
23 | rm -f common common.dvi a.out loom *.o index.dat *.log
24 |
--------------------------------------------------------------------------------
/malloc/tags/original/README:
--------------------------------------------------------------------------------
1 | This archive contains versions of malloc, calloc, realloc, and free
2 | that detect usage errors. This package was part of an assignment in the
3 | Fall 1994 offering of Princeton's COS 217, Introduction to Systems
4 | Programming.
5 |
6 | The important files are
7 |
8 | index.ps
9 | PostScript or the assignment handout and explains the semantics of the
10 | allocation functions and their interaction with memmon, the program
11 | that actually detects the errors and prints the diagnostics.
12 |
13 | memmon.1
14 | a man page for memmon; it explains the format of the messages sent from
15 | the allocation functions to memmon.
16 |
17 | This version of the library and of memmon run only on the SPARC.
18 |
19 | Installation involves 2 files: build memmon first with the commands
20 |
21 | gmake memmon
22 | mv memmon /usr/local/lib/memmon
23 | cp memmon.1 /usr/local/man/man1
24 |
25 | where "/usr/local/lib/memmon" is the local path for memmon. Then build
26 | and install libmalloc.a:
27 |
28 | gmake MEMMON=/usr/local/lib/memmon libmalloc.a
29 | mv libmalloc.a /usr/local/lib
30 | ranlib /usr/local/lib/libmalloc.a
31 |
32 | where the value assigned to MEMMON is the same path you used above to
33 | install memmon.
34 |
35 | Send email about problems/bugs to drh@cs.princeton.edu
36 |
37 | modified Mon May 1 10:40:51 EDT 1995 by drh
38 | created Mon Apr 10 10:00:01 EDT 1995 by drh
39 |
--------------------------------------------------------------------------------
/malloc/tags/original/flush.s:
--------------------------------------------------------------------------------
1 | ! void *_flush()
2 | !
3 | ! flushes the register windows to the stack, returns sp
4 |
5 | .seg "text"
6 | .global __flush
7 | __flush:ta 3 ! flush windows to the stack
8 | retl; mov %sp,%o0
9 |
--------------------------------------------------------------------------------
/malloc/tags/original/makefile:
--------------------------------------------------------------------------------
1 | CC=lcc -A
2 | MEMMON=
3 | CFLAGS=-g -DMEMMON='"$(MEMMON)"'
4 | LDFLAGS=-g
5 | OBJS=malloc.o flush.o
6 | FILES=makefile malloc.c trace.c flush.s memmon.c memmon.h sym.h sym.c
7 |
8 | libmalloc.a: $(OBJS)
9 | ar r $@ $?
10 | ranlib $@
11 |
12 | malloc.o: memmon.h trace.c
13 |
14 | flush.o: flush.s
15 | $(CC) -c flush.s
16 |
17 | lint: malloc.c trace.c memmon.c sym.c sym.h
18 | -lint -I. -u -w2 -e534 malloc.c
19 | -lint -I. -w2 '-esym(526,read,sbrk,unlink)' memmon.c sym.c
20 |
21 | memmon: memmon.o sym.o
22 | $(CC) -o $@ $(LDFLAGS) memmon.o sym.o
23 |
24 | sym.o: sym.h
25 | memmon.o: sym.h memmon.h
26 |
27 | malloc.tar.gz:
28 | tar cf - README $(FILES) memmon.1 index.ps | gzip -c >$@
29 |
30 | clean:
31 | rm -f *.o *.out core a.out *.sym
32 |
33 | clobber: clean
34 | rm -f libmalloc.a memmon
35 |
--------------------------------------------------------------------------------
/malloc/tags/original/malloc.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "memmon.h"
6 |
7 | static struct block { /* block descriptor: */
8 | struct block *free; /* next block on the free list */
9 | struct block *link; /* next block on the hash chain */
10 | void *ptr; /* pointer to the allocated/free block */
11 | size_t size; /* size of the block in bytes */
12 | } *htab[1024];
13 | #define hash(a) ((unsigned)a>>3)
14 | #define NELEMS(a) ((int)(sizeof (a)/sizeof ((a)[0])))
15 | #define NALLOC 4096 /* minimum #bytes to request from system */
16 |
17 | static struct block freelist = { &freelist }; /* list of free blocks */
18 | static union align { void (*f)(void); double d; long l; } align; /*lint -e551 */
19 |
20 | extern void *sbrk(int);
21 | #include "trace.c"
22 |
23 | /* find - find the block descriptor for the block at address ptr */
24 | static struct block *find(void *ptr) {
25 | struct block *bp = htab[hash(ptr)%NELEMS(htab)];
26 |
27 | while (bp && bp->ptr != ptr)
28 | bp = bp->link;
29 | return bp;
30 | }
31 |
32 | /* _free - internal version of free */
33 | static void _free(void *ptr) {
34 | struct block *bp;
35 |
36 | if (((unsigned)ptr&(sizeof align - 1)) == 0
37 | && (bp = find(ptr)) != NULL /* free'ing unallocated memory? */
38 | && bp->free == NULL) { /* free'ing free memory? */
39 | bp->free = freelist.free; /* free a valid block */
40 | freelist.free = bp;
41 | }
42 | }
43 |
44 | /* free - free block at address ptr */
45 | void free(void *ptr) {
46 | Memmon_T msg = { Memmon_free };
47 |
48 | if ((msg.ptr[0] = ptr) != NULL)
49 | _free(ptr);
50 | msg.opcode = Memmon_free;
51 | send(&msg, _flush());
52 | }
53 |
54 | /* block - allocate and initialize a block descriptor */
55 | static struct block *block(void *ptr, unsigned size) {
56 | static struct block *avail;
57 | static int nleft = 0;
58 |
59 | if (nleft <= 0) {
60 | if ((avail = sbrk(512*sizeof *avail)) == (void *)-1)
61 | return NULL;
62 | nleft = 512;
63 | }
64 | avail->ptr = ptr;
65 | avail->size = size;
66 | avail->free = avail->link = NULL;
67 | nleft--;
68 | return avail++;
69 | }
70 |
71 | /* _malloc - internal version of malloc */
72 | void *_malloc(size_t size) {
73 | struct block *bp, *new;
74 | void *ptr;
75 |
76 | if (size > INT_MAX - NALLOC)
77 | return NULL;
78 | if (size == 0)
79 | size = 1;
80 | if (size%sizeof align)
81 | size += sizeof align - size%sizeof align;
82 | for (bp = freelist.free; bp; bp = bp->free) {
83 | if (bp->size > size) { /* big enough? */
84 | bp->size -= size; /* allocate tail end */
85 | ptr = (char *)bp->ptr + bp->size;
86 | if ((bp = block(ptr, size)) != NULL) {
87 | unsigned h = hash(ptr)%NELEMS(htab);
88 | bp->link = htab[h];
89 | htab[h] = bp;
90 | return ptr;
91 | } else
92 | return NULL;
93 | }
94 | if (bp == &freelist) {
95 | if ((ptr = sbrk(size + NALLOC)) == (void *)-1)
96 | return NULL;
97 | if ((new = block(ptr, size + NALLOC)) == NULL)
98 | return NULL;
99 | new->free = freelist.free;
100 | freelist.free = new;
101 | }
102 | }
103 | /*lint -e506 */ assert(0);
104 | return NULL;
105 | }
106 |
107 | void *malloc(size_t size) {
108 | Memmon_T msg = { Memmon_malloc };
109 |
110 | msg.size[0] = size;
111 | msg.ptr[1] = _malloc(size);
112 | send(&msg, _flush());
113 | return msg.ptr[1];
114 | }
115 |
116 | void *calloc(size_t nobj, size_t size) {
117 | Memmon_T msg = { Memmon_calloc };
118 |
119 | if (nobj > 0 && size > UINT_MAX/nobj)
120 | msg.ptr[1] = NULL;
121 | else if ((msg.ptr[1] = _malloc(nobj*size)) != NULL)
122 | memset(msg.ptr[1], 0, nobj*size);
123 | msg.size[1] = nobj;
124 | msg.size[0] = size;
125 | send(&msg, _flush());
126 | return msg.ptr[1];
127 | }
128 |
129 | /* realloc - reallocate the block at ptr to be size bytes */
130 | void *realloc(void *ptr, size_t size) {
131 | struct block *bp;
132 | void *new = NULL;
133 | Memmon_T msg = { Memmon_realloc };
134 |
135 | msg.ptr[0] = ptr;
136 | msg.size[0] = size;
137 | if (ptr == NULL)
138 | new = _malloc(size);
139 | else if (ptr && size == 0)
140 | _free(ptr);
141 | else if ((new = _malloc(size)) != NULL
142 | && (bp = find(ptr)) != NULL && bp->free == NULL) {
143 | memcpy(new, ptr, size < bp->size ? size : bp->size);
144 | _free(ptr);
145 | }
146 | msg.ptr[1] = new;
147 | send(&msg, _flush());
148 | return new;
149 | }
150 |
--------------------------------------------------------------------------------
/malloc/tags/original/memmon.1:
--------------------------------------------------------------------------------
1 | .TH WF 1 "local - 9/21/94"
2 | .SH NAME
3 | memmon - detect allocation errors
4 | .SH SYNOPSIS
5 | .B memmon
6 | [
7 | .I option
8 | ]...
9 | .SH DESCRIPTION
10 | .I memmon
11 | helps detect illegal uses of the standard allocation functions
12 | .IR malloc ,
13 | .IR calloc ,
14 | .IR realloc ,
15 | and
16 | .IR free .
17 | .I memmon
18 | reads allocation messages from the standard input that describe
19 | the calls to these functions made by a program
20 | and prints, on the standard error, illegal uses.
21 | .PP
22 | It detects calls to
23 | .I free
24 | or to
25 | .I realloc
26 | that attempt to free memory that wasn't allocated
27 | by a previous call to
28 | .IR malloc ,
29 | .IR calloc ,
30 | or
31 | .IR realloc ;
32 | and calls to
33 | .I free
34 | or to
35 | .I realloc
36 | that attempt to free memory that is already free.
37 | When after reading its input,
38 | .I memmon
39 | can also lists the memory that is still allocated, which helps
40 | detect storage leaks; that is, memory that should have been
41 | freed, but that is still allocated.
42 | .PP
43 | .I memmon
44 | accepts the following options. It reads its program arguments first,
45 | then it reads options from the environment variable
46 | .IR MEMMONOPTIONS .
47 | .TP
48 | .B \-show-all-calls[=yes|=no]
49 | Prints a message describing
50 | .I every
51 | call to one of the allocation functions when
52 | .B yes
53 | is specified or when there is no value.
54 | The default is
55 | .BR \-show-all-calls=no .
56 | .TP
57 | .BR \-inuse-at-exit[=yes|=no]
58 | Prints the memory that is still allocated at program
59 | termination when
60 | .B yes
61 | is specified or when there is no value.
62 | The default is
63 | .BR \-inuse-at-exit=yes .
64 | .TP
65 | .BR \-a.out= \fIfile\fP
66 | Specifies that
67 | .I file
68 | is the program whose execution is described by the input messages.
69 | The default is
70 | .BR \-a.out=a.out .
71 | .TP
72 | .BR \-log-file= \fIfile\fP
73 | Write the diagnostic output to
74 | .I file
75 | instead of to the standard error, which is the default.
76 | .TP
77 | .BR \-temp-file= \fIfile\fP
78 | Write the
79 | .B a.out
80 | symbol table to
81 | .I file
82 | instead of to a temporary file, which is the default.
83 | .PP
84 | .I memmon
85 | reads binary messages whose format is defined by
86 | .PP
87 | .ta 8 16 24 32 40 48 56 64
88 | .ft B
89 | .nf
90 | #define T Memmon_T
91 | typedef struct T { /* memmon messages: */
92 | enum {
93 | Memmon_free,
94 | Memmon_malloc,
95 | Memmon_calloc,
96 | Memmon_realloc
97 | } opcode; /* allocation function code */
98 | void *ptr[2]; /* input address, output address */
99 | unsigned size[2]; /* input sizes in bytes */
100 | void *calls[10]; /* associated call stack */
101 | } T;
102 | .fi
103 | .PP
104 | The
105 | .I opcode
106 | field identifies the function.
107 | For all functions, the
108 | .I calls
109 | field holds up to 10 return address from the point
110 | of call to the allocation function.
111 | .PP
112 | For
113 | .IR Memmon_free ,
114 | .I ptr[0]
115 | gives the argument to
116 | .IR free .
117 | .PP
118 | For
119 | .IR Memmon_malloc ,
120 | .I size[0]
121 | gives the value of the argument to
122 | .IR malloc ,
123 | and
124 | .I ptr[1]
125 | gives the value returned.
126 | .PP
127 | For
128 | .IR Memmon_calloc ,
129 | .I size[0]
130 | and
131 | .I size[1]
132 | gives the values of the second argument and first arguments,
133 | respectively (note the order), and
134 | .I ptr[1]
135 | gives the value returned.
136 | .PP
137 | For
138 | .IR Memmon_realloc ,
139 | .I ptr[0]
140 | and
141 | .I size[0]
142 | gives the values of the arguments to
143 | .BR realloc , and
144 | .I ptr[1]
145 | gives the value returned.
146 | .SH FILES
147 | .PP
148 | .RS
149 | .ta \w'/usr/tmp/aadddddd---'u
150 | .nf
151 | a.out program file
152 | /usr/tmp/aa? temporary file
153 | .fi
154 | .RE
155 | .PP
156 | .SH "SEE ALSO"
157 | .IR purify (1)
158 |
--------------------------------------------------------------------------------
/malloc/tags/original/memmon.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMMON_INCLUDED
2 | #define MEMMON_INCLUDED
3 |
4 | #define T Memmon_T
5 |
6 | typedef struct T { /* memmon messages: */
7 | enum {
8 | Memmon_free,
9 | Memmon_malloc,
10 | Memmon_calloc,
11 | Memmon_realloc
12 | } opcode; /* allocation function code */
13 | void *ptr[2]; /* input address, output address */
14 | unsigned size[2]; /* input sizes in bytes */
15 | void *calls[10]; /* associated call stack */
16 | } T;
17 |
18 | /*
19 | The fields hold the following values. Omitted values must be transmitted,
20 | but memmon ignores them.
21 |
22 | client's call opcode ptr[0] ptr[1] size[0] size[1]
23 | free(ptr) Memmon_free ptr
24 | ptr=malloc(n) Memmon_malloc ptr n
25 | ptr=calloc(m,n) Memmon_calloc ptr n m
26 | new=realloc(ptr,n) Memmon_realloc ptr new n
27 |
28 | calls[] always holds up to 10 return addresses from the point
29 | of call to the allocation function.
30 | */
31 | #undef T
32 | #endif
33 |
--------------------------------------------------------------------------------
/malloc/tags/original/sym.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "sym.h"
5 | #define T Sym_T
6 |
7 | struct T {
8 | int nsyms; /* number of elements in syms used */
9 | int size; /* number of elements in syms */
10 | struct symbol { /* symbol: */
11 | unsigned addr; /* address */
12 | char name[16]; /* name */
13 | } stab[512]; /* an array of symbols */
14 | };
15 |
16 | static T expand(T stab) {
17 | static struct symbol *last;
18 | extern void *sbrk(int);
19 |
20 | if (stab) {
21 | struct symbol *new = sbrk(stab->size*sizeof *new);
22 | if (new == (void *)-1 || last != new)
23 | return 0;
24 | assert(last);
25 | } else {
26 | stab = sbrk(sizeof *stab);
27 | if (stab == (void *)-1)
28 | return 0;
29 | stab->nsyms = 0;
30 | }
31 | last = sbrk(0);
32 | stab->size = last - stab->stab;
33 | return stab;
34 | }
35 |
36 | T Sym_init(const char *file) {
37 | FILE *f;
38 | struct symbol *sp;
39 | T stab;
40 |
41 | assert(file);
42 | if ((f = fopen(file, "r")) == 0)
43 | return 0;
44 | if ((stab = expand(NULL)) == NULL)
45 | goto error;
46 | sp = stab->stab;
47 | while (!feof(f)) {
48 | unsigned addr;
49 | char junk[4], name[100];
50 | if (fscanf(f, "%x %[tT] _%s\n", (unsigned *)&addr, junk, name) != 3)
51 | goto error;
52 | if (stab->nsyms >= stab->size && !expand(stab))
53 | goto error;
54 | sp->addr = addr;
55 | strncpy(sp->name, name, sizeof sp->name);
56 | sp->name[sizeof(sp->name) - 1] = 0;
57 | sp++;
58 | stab->nsyms++;
59 | }
60 | fclose(f);
61 | return stab;
62 |
63 | error: fclose(f);
64 | return NULL;
65 | }
66 |
67 | char *Sym_find(T stab, void *addr) {
68 | int k = 0, lb = 0, ub;
69 | unsigned adr = (unsigned)addr;
70 |
71 | assert(stab);
72 | ub = stab->nsyms - 1;
73 | while (lb <= ub) {
74 | k = (lb + ub)/2;
75 | if (stab->stab[k].addr < adr) {
76 | if (k+1 == stab->nsyms || adr < stab->stab[k+1].addr)
77 | return stab->stab[k].name;
78 | lb = k + 1;
79 | } else if (stab->stab[k].addr > adr)
80 | ub = k - 1;
81 | else
82 | break;
83 | }
84 | return NULL;
85 | }
86 |
--------------------------------------------------------------------------------
/malloc/tags/original/sym.h:
--------------------------------------------------------------------------------
1 | #ifndef SYM_INCLUDED
2 | #define SYM_INCLUDED
3 |
4 | #define T Sym_T
5 | typedef struct T *T;
6 |
7 | /*
8 | * Sym maintains a map of addresses to function names.
9 | */
10 |
11 | extern T Sym_init(const char *file);
12 | /*
13 | * Sym_init specifies the name of the file from which to extract the symbol
14 | * table of an executable program. The file must be created by a command like
15 | *
16 | * nm -n a.out | grep '[tT] _' >file
17 | *
18 | * where a.out is executable file of interest.
19 | *
20 | * Sym_init returns a handle to the symbol table if the file can be read and
21 | * it's in the proper format. Otherwise, Sym_init returns NULL. Sym_init
22 | * allocates space for the symbol table by making system calls; it does not
23 | * call malloc. It is a checked runtime error to pass a NULL file to Sym_init.
24 | */
25 |
26 | extern char *Sym_find(T stab, void *addr);
27 | /*
28 | * Sym_find searches the symbol table stab and returns a pointer to the name of
29 | * the function whose body includes the location at addr, or NULL if no
30 | * function's body in stab includes addr. The name is at most 16 characters long
31 | * including the terminating null byte. Clients must make a copy of the name
32 | * before modifying it.
33 | */
34 |
35 | /*
36 | * It is a checked runtime error to pass a NULL T to any function in this
37 | * interface.
38 | */
39 |
40 | #undef T
41 | #endif
42 |
--------------------------------------------------------------------------------
/malloc/tags/original/trace.c:
--------------------------------------------------------------------------------
1 | /* #included in malloc.c */
2 | #ifndef MEMMON
3 | #define MEMMON "/u/cs217/7/memmon"
4 | #endif
5 |
6 | extern int close(int);
7 | extern int dup2(int, int);
8 | extern int execl(char *, ...);
9 | extern int fork(void);
10 | extern int pipe(int[]);
11 | extern int write(int, char *, int);
12 | extern struct frame { void *lreg[8], *ireg[8]; } *_flush(void);
13 |
14 | /* trace - insert call trace from sp into pc[0..ncalls-1]; SPARC version */
15 | static void trace(struct frame *sp, void *pc[], int ncalls) {
16 | int i;
17 |
18 | for (i = 0; sp && i < ncalls; i++) {
19 | pc[i] = sp->ireg[7]; /* return address */
20 | sp = sp->ireg[6];
21 | }
22 | if (sp == 0 && i > 1)
23 | i -= 2;
24 | else if (sp && sp->ireg[6] == 0 && i > 0)
25 | i -= 1;
26 | while (i < ncalls)
27 | pc[i++] = NULL;
28 | }
29 |
30 | /* send - send *msg to memmon, starting it if necessary; sp is caller's sp */
31 | static void send(Memmon_T *msg, struct frame *sp) {
32 | static int inited = 0, fd[2];
33 |
34 | if (inited == 0) {
35 | inited = -1;
36 | if (pipe(fd) < 0)
37 | return;
38 | switch (fork()) {
39 | case -1:
40 | return;
41 | default: /* parent: close fd[0], and write *msg */
42 | close(fd[0]);
43 | inited = 1;
44 | break;
45 | case 0: /* child: rearrange i/o, and run memmon */
46 | close(fd[1]);
47 | if (dup2(fd[0], 0) >= 0) {
48 | close(fd[0]);
49 | execl(MEMMON, "memmon", NULL);
50 | }
51 | exit(EXIT_FAILURE);
52 | }
53 | }
54 | trace(sp, msg->calls, sizeof msg->calls/sizeof msg->calls[0]);
55 | if (inited > 0
56 | && write(fd[1], (char *)msg, sizeof *msg) != (int)sizeof *msg)
57 | inited = -1;
58 | }
59 |
--------------------------------------------------------------------------------
/malloc/trunk/README:
--------------------------------------------------------------------------------
1 | This directory contains versions of malloc, calloc, realloc, and free
2 | that detect usage errors. This package was part of an assignment in the
3 | Fall 1994 offering of Princeton's COS 217, Introduction to Systems
4 | Programming.
5 |
6 | The important files are
7 |
8 | index.html
9 | Explains the semantics of the allocation functions and their interaction with
10 | memmon, the program that actually detects the errors and prints the diagnostics.
11 |
12 | memmon.1
13 | a man page for memmon; it explains the format of the messages sent from
14 | the allocation functions to memmon.
15 |
16 | This version of the library and of memmon run on the SPARC (Unix) and Intel
17 | (Linux, OS X 10.4.9).
18 |
19 | Installation involves 2 files: build memmon first with the commands
20 |
21 | make memmon
22 | mv memmon /usr/local/lib/memmon
23 | cp memmon.1 /usr/local/man/man1
24 |
25 | where "/usr/local/lib/memmon" is the local path for memmon. Then build
26 | and install libmalloc.a:
27 |
28 | make CFLAGS='-g -DMEMMON="/usr/local/lib/memmon"' libmalloc.a
29 | mv libmalloc.a /usr/local/lib
30 | ranlib /usr/local/lib/libmalloc.a
31 |
32 | where the value assigned to MEMMON is the same path you used above to
33 | install memmon.
34 |
35 | Send email about problems/bugs to drh at drhanson dot net.
36 |
--------------------------------------------------------------------------------
/malloc/trunk/bug1.c:
--------------------------------------------------------------------------------
1 | #include
2 | void g(int n) { malloc(n); }
3 | void f(int i) { i > 0 ? f(i - 1) : g(16); }
4 | main(void) { f(7); }
5 |
--------------------------------------------------------------------------------
/malloc/trunk/bug2.c:
--------------------------------------------------------------------------------
1 | #include
2 | void *f(int i) { return i > 0 ? f(i - 1) : malloc(10); }
3 | main() {
4 | void *p = f(3);
5 | double d;
6 |
7 | free(p);
8 | free(p);
9 | free(0);
10 | free((void*)1);
11 | free(&d);
12 | f(2);
13 | }
14 |
--------------------------------------------------------------------------------
/malloc/trunk/bug3.c:
--------------------------------------------------------------------------------
1 | #include
2 | main() {
3 | void *p;
4 |
5 | p = realloc(NULL, 100);
6 | p = realloc(p, 200);
7 | free(p);
8 | p = realloc(p, 50);
9 | p = realloc(&p, 200);
10 | p = malloc(0);
11 | p = realloc(NULL, 0);
12 | p = malloc(-1);
13 | p = calloc(2, 2147483648);
14 | }
15 |
--------------------------------------------------------------------------------
/malloc/trunk/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Detecting Memory Usage Errors and Leaks
5 |
6 |
7 | Detecting Memory Usage Errors and Leaks
8 |
9 | Memory usage errors are so common in C programs that special tools,
10 | like purify, are available to help detect these kinds of errors. Three common errors are:
11 |
12 | - freeing or reallocing memory that wasn’t allocated by malloc, realloc, or calloc;
13 | - freeing or reallocing free memory; and
14 | - failing to free memory.
15 |
16 |
17 |
18 | These versions of malloc, calloc, realloc, and free collaborate to detect the usage errors
19 | listed above and to report potential leaks, i.e., allocated memory that isn’t freed.
20 | These functions are packaged in the library libmalloc.a.
21 |
22 | These special versions of the allocation functions manage storage
23 | as detailed in their specifications (see page 252 in K&R and the man page for malloc),
24 | and they write messages about their actions to memmon.
25 | The program memmon analyzes these messages and prints warnings about illegal usage and about leaks.
26 | For example, the program below, bug2.c, has 3 usage errors and 1 leak.
27 | void *f(int i) { return i > 0 ? f(i - 1) : malloc(10); }
28 | main() {
29 | void *p = f(3);
30 | double d;
31 |
32 | free(p);
33 | free(p);
34 | free(0);
35 | free((void*)1);
36 | free(&d);
37 | f(2);
38 | }
39 |
40 | The call to free at line 7 frees memory that has already been freed,
41 | the calls to free at lines 9 and 10 pass pointers that were not returned by malloc.
42 | The call to f in line 11 creates a leak.
43 | When bug2.c is compiled, loaded with libmalloc.a, and run, memmon reports these errors:
44 |
45 | % cc bug2.c libmalloc.a
46 | % ./a.out
47 | memmon $Revision: 4 $
48 | Options: a.out=a.out -inuse-at-exit=yes -show-all-calls=no -log-file=stderr -temp-file=/usr/tmp/aaaa03384
49 |
50 | ** free'ing free memory
51 | free(0x1009000) called from:
52 | main [pc=0x1774]
53 | This block is 10 bytes long and was malloc'd from:
54 | f [pc=0x1741]
55 | f [pc=0x1730]
56 | f [pc=0x1730]
57 | f [pc=0x1730]
58 | main [pc=0x175b]
59 |
60 | ** free'ing unallocated memory
61 | free(0x1) called from:
62 | main [pc=0x178c]
63 |
64 | ** free'ing unallocated memory
65 | free(0xbffff280) called from:
66 | main [pc=0x1797]
67 |
68 | ** Memory in use at 0x1008ff0
69 | This block is 10 bytes long and was malloc'd from:
70 | f [pc=0x1741]
71 | f [pc=0x1730]
72 | f [pc=0x1730]
73 | main [pc=0x17a3]
74 |
75 | memmon’s diagnostics include the top portion of the call stack
76 | at the point the error occurred.
77 | For some errors, the call stack at the point of allocation is also printed.
78 |
79 | Several other test cases are available in bug?.c.
80 |
81 | Implementation Details
82 |
83 | Each call to malloc, calloc, realloc, and free causes a message to be written to memmon.
84 | The format of these binary messages is described in
85 | memmon.h and in the memmon man page.
86 |
87 | The first message causes a pipe to be created between the current process and a new process running memmon.
88 | The system calls pipe creates the pipe, fork creates a new process,
89 | and execl runs memmon in the new process; close and dup2 rearrange the file descriptors so that the messages are written to memmon’s standard input.
90 | write writes the messages.
91 |
92 | Each message includes the top 10 return addresses in the call stack that led to the call.
93 | If there are fewer than 10 return addresses, 0s are passed for the missing ones.
94 | The return addresses are found by traversing the stack.
95 | Given an appropriate starting point (e.g., the current value of the frame point)
96 | this traversal can be written entirely in C.
97 | The “bottom” frame is the one with a 0 return address and a 0 frame pointer.
98 | Also, the second-to-bottom frame is for the C start-up code that calls main;
99 | these bottom two frames are not included in memmon messages.
100 |
101 | memmon detects errors in the use of the allocation functions, and it prints diagnostics like those shown above.
102 | The implementations of the allocation functions are robust—they do not fail when used incorrectly.
103 | For example, free copes with the errors illustrated in bug2.c above.
104 | So, the allocation functions detect the same errors that memmon does and take evasive action,
105 | which usually means ignoring the offending calls.
106 | They must also cope gracefully with other error conditions, like errors in launching memmon.
107 |
108 | —David R. Hanson; drh at drhanson dot net; Fall 1994.
109 |
110 |
111 |
--------------------------------------------------------------------------------
/malloc/trunk/makefile:
--------------------------------------------------------------------------------
1 | CFLAGS=-g
2 | LDFLAGS=-g
3 | OBJS=malloc.o
4 |
5 | libmalloc.a: $(OBJS)
6 | ar r $@ $?
7 | ranlib $@
8 |
9 | malloc.o: memmon.h trace.c
10 |
11 | memmon: memmon.o sym.o
12 | $(CC) -o $@ $(LDFLAGS) memmon.o sym.o
13 |
14 | sym.o: sym.h
15 | memmon.o: sym.h memmon.h
16 |
17 | clean:
18 | -rm -f *.o *.out core a.out *.sym
19 |
20 | clobber: clean
21 | -rm -f libmalloc.a memmon
22 |
--------------------------------------------------------------------------------
/malloc/trunk/malloc.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "memmon.h"
6 |
7 | static struct block { /* block descriptor: */
8 | struct block *free; /* next block on the free list */
9 | struct block *link; /* next block on the hash chain */
10 | void *ptr; /* pointer to the allocated/free block */
11 | size_t size; /* size of the block in bytes */
12 | } *htab[1543];
13 | #define hash(a) ((unsigned long)a>>3)
14 | #define NELEMS(a) ((int)(sizeof (a)/sizeof ((a)[0])))
15 | #define NALLOC 4096 /* minimum #bytes to request from system */
16 |
17 | static struct block freelist = { &freelist }; /* list of free blocks */
18 | static union align { void (*f)(void); double d; long l; } align;
19 |
20 | extern void *sbrk(int);
21 | #include "trace.c"
22 |
23 | /* find - find the block descriptor for the block at address ptr */
24 | static struct block *find(void *ptr) {
25 | struct block *bp = htab[hash(ptr)%NELEMS(htab)];
26 |
27 | while (bp && bp->ptr != ptr)
28 | bp = bp->link;
29 | return bp;
30 | }
31 |
32 | /* _free - internal version of free */
33 | static void _free(void *ptr) {
34 | struct block *bp;
35 |
36 | if (((unsigned)ptr&(sizeof align - 1)) == 0
37 | && (bp = find(ptr)) != NULL /* free'ing unallocated memory? */
38 | && bp->free == NULL) { /* free'ing free memory? */
39 | bp->free = freelist.free; /* free a valid block */
40 | freelist.free = bp;
41 | }
42 | }
43 |
44 | /* free - free block at address ptr */
45 | void free(void *ptr) {
46 | Memmon_T msg = { Memmon_free };
47 |
48 | if ((msg.ptr[0] = ptr) != NULL)
49 | _free(ptr);
50 | msg.opcode = Memmon_free;
51 | send(&msg, _framepointer());
52 | }
53 |
54 | /* block - allocate and initialize a block descriptor */
55 | static struct block *block(void *ptr, unsigned size) {
56 | static struct block *avail;
57 | static int nleft = 0;
58 |
59 | if (nleft <= 0) {
60 | if ((avail = sbrk(512*sizeof *avail)) == (void *)-1)
61 | return NULL;
62 | nleft = 512;
63 | }
64 | avail->ptr = ptr;
65 | avail->size = size;
66 | avail->free = avail->link = NULL;
67 | nleft--;
68 | return avail++;
69 | }
70 |
71 | /* _malloc - internal version of malloc */
72 | void *_malloc(size_t size) {
73 | struct block *bp, *new;
74 | void *ptr;
75 |
76 | if (size > INT_MAX - NALLOC)
77 | return NULL;
78 | if (size == 0)
79 | size = 1;
80 | if (size%sizeof align)
81 | size += sizeof align - size%sizeof align;
82 | for (bp = freelist.free; bp; bp = bp->free) {
83 | if (bp->size > size) { /* big enough? */
84 | bp->size -= size; /* allocate tail end */
85 | ptr = (char *)bp->ptr + bp->size;
86 | if ((bp = block(ptr, size)) != NULL) {
87 | unsigned h = hash(ptr)%NELEMS(htab);
88 | bp->link = htab[h];
89 | htab[h] = bp;
90 | return ptr;
91 | } else
92 | return NULL;
93 | }
94 | if (bp == &freelist) {
95 | if ((ptr = sbrk(size + NALLOC)) == (void *)-1)
96 | return NULL;
97 | if ((new = block(ptr, size + NALLOC)) == NULL)
98 | return NULL;
99 | new->free = freelist.free;
100 | freelist.free = new;
101 | }
102 | }
103 | assert(0);
104 | return NULL;
105 | }
106 |
107 | /* __libc_memalign - allocate nbytes aligned to alignment */
108 | void *__libc_memalign(size_t alignment, size_t nbytes) {
109 | return _malloc(nbytes);
110 | }
111 |
112 | void *malloc(size_t size) {
113 | Memmon_T msg = { Memmon_malloc };
114 |
115 | msg.size[0] = size;
116 | msg.ptr[1] = _malloc(size);
117 | send(&msg, _framepointer());
118 | return msg.ptr[1];
119 | }
120 |
121 | void *calloc(size_t nobj, size_t size) {
122 | Memmon_T msg = { Memmon_calloc };
123 |
124 | if (nobj > 0 && size > UINT_MAX/nobj)
125 | msg.ptr[1] = NULL;
126 | else if ((msg.ptr[1] = _malloc(nobj*size)) != NULL)
127 | memset(msg.ptr[1], 0, nobj*size);
128 | msg.size[1] = nobj;
129 | msg.size[0] = size;
130 | send(&msg, _framepointer());
131 | return msg.ptr[1];
132 | }
133 |
134 | /* realloc - reallocate the block at ptr to be size bytes */
135 | void *realloc(void *ptr, size_t size) {
136 | struct block *bp;
137 | void *new = NULL;
138 | Memmon_T msg = { Memmon_realloc };
139 |
140 | msg.ptr[0] = ptr;
141 | msg.size[0] = size;
142 | if (ptr == NULL)
143 | new = _malloc(size);
144 | else if (ptr && size == 0)
145 | _free(ptr);
146 | else if ((new = _malloc(size)) != NULL
147 | && (bp = find(ptr)) != NULL && bp->free == NULL) {
148 | memcpy(new, ptr, size < bp->size ? size : bp->size);
149 | _free(ptr);
150 | }
151 | msg.ptr[1] = new;
152 | send(&msg, _framepointer());
153 | return new;
154 | }
155 |
--------------------------------------------------------------------------------
/malloc/trunk/memmon.1:
--------------------------------------------------------------------------------
1 | .TH MEMMON 1 "local - 9/21/94"
2 | .SH NAME
3 | memmon - detect allocation errors
4 | .SH SYNOPSIS
5 | .B memmon
6 | [
7 | .I option
8 | ]...
9 | .SH DESCRIPTION
10 | .I memmon
11 | helps detect illegal uses of the standard allocation functions
12 | .IR malloc ,
13 | .IR calloc ,
14 | .IR realloc ,
15 | and
16 | .IR free .
17 | .I memmon
18 | reads allocation messages from the standard input that describe
19 | the calls to these functions made by a program
20 | and prints, on the standard error, illegal uses.
21 | .PP
22 | It detects calls to
23 | .I free
24 | or to
25 | .I realloc
26 | that attempt to free memory that wasn't allocated
27 | by a previous call to
28 | .IR malloc ,
29 | .IR calloc ,
30 | or
31 | .IR realloc ;
32 | and calls to
33 | .I free
34 | or to
35 | .I realloc
36 | that attempt to free memory that is already free.
37 | When after reading its input,
38 | .I memmon
39 | can also lists the memory that is still allocated, which helps
40 | detect storage leaks; that is, memory that should have been
41 | freed, but that is still allocated.
42 | .PP
43 | .I memmon
44 | accepts the following options. It reads its program arguments first,
45 | then it reads options from the environment variable
46 | .IR MEMMONOPTIONS .
47 | .TP
48 | .B \-show-all-calls[=yes|=no]
49 | Prints a message describing
50 | .I every
51 | call to one of the allocation functions when
52 | .B yes
53 | is specified or when there is no value.
54 | The default is
55 | .BR \-show-all-calls=no .
56 | .TP
57 | .BR \-inuse-at-exit[=yes|=no]
58 | Prints the memory that is still allocated at program
59 | termination when
60 | .B yes
61 | is specified or when there is no value.
62 | The default is
63 | .BR \-inuse-at-exit=yes .
64 | .TP
65 | .BR \-a.out= \fIfile\fP
66 | Specifies that
67 | .I file
68 | is the program whose execution is described by the input messages.
69 | The default is
70 | .BR \-a.out=a.out .
71 | .TP
72 | .BR \-log-file= \fIfile\fP
73 | Write the diagnostic output to
74 | .I file
75 | instead of to the standard error, which is the default.
76 | .TP
77 | .BR \-temp-file= \fIfile\fP
78 | Write the
79 | .B a.out
80 | symbol table to
81 | .I file
82 | instead of to a temporary file, which is the default.
83 | .PP
84 | .I memmon
85 | reads binary messages whose format is defined by
86 | .PP
87 | .ta 8 16 24 32 40 48 56 64
88 | .ft B
89 | .nf
90 | #define T Memmon_T
91 | typedef struct T { /* memmon messages: */
92 | enum {
93 | Memmon_free,
94 | Memmon_malloc,
95 | Memmon_calloc,
96 | Memmon_realloc
97 | } opcode; /* allocation function code */
98 | void *ptr[2]; /* input address, output address */
99 | unsigned size[2]; /* input sizes in bytes */
100 | void *calls[10]; /* associated call stack */
101 | } T;
102 | .fi
103 | .PP
104 | The
105 | .I opcode
106 | field identifies the function.
107 | For all functions, the
108 | .I calls
109 | field holds up to 10 return address from the point
110 | of call to the allocation function.
111 | .PP
112 | For
113 | .IR Memmon_free ,
114 | .I ptr[0]
115 | gives the argument to
116 | .IR free .
117 | .PP
118 | For
119 | .IR Memmon_malloc ,
120 | .I size[0]
121 | gives the value of the argument to
122 | .IR malloc ,
123 | and
124 | .I ptr[1]
125 | gives the value returned.
126 | .PP
127 | For
128 | .IR Memmon_calloc ,
129 | .I size[0]
130 | and
131 | .I size[1]
132 | gives the values of the second argument and first arguments,
133 | respectively (note the order), and
134 | .I ptr[1]
135 | gives the value returned.
136 | .PP
137 | For
138 | .IR Memmon_realloc ,
139 | .I ptr[0]
140 | and
141 | .I size[0]
142 | gives the values of the arguments to
143 | .BR realloc , and
144 | .I ptr[1]
145 | gives the value returned.
146 | .SH FILES
147 | .PP
148 | .RS
149 | .ta \w'/usr/tmp/aadddddd---'u
150 | .nf
151 | a.out program file
152 | /usr/tmp/aa? temporary file
153 | .fi
154 | .RE
155 | .PP
156 | .SH "SEE ALSO"
157 | .IR purify (1)
158 |
--------------------------------------------------------------------------------
/malloc/trunk/memmon.h:
--------------------------------------------------------------------------------
1 | #ifndef MEMMON_INCLUDED
2 | #define MEMMON_INCLUDED
3 |
4 | #define T Memmon_T
5 |
6 | typedef struct T { /* memmon messages: */
7 | enum {
8 | Memmon_free,
9 | Memmon_malloc,
10 | Memmon_calloc,
11 | Memmon_realloc
12 | } opcode; /* allocation function code */
13 | void *ptr[2]; /* input address, output address */
14 | unsigned size[2]; /* input sizes in bytes */
15 | void *calls[10]; /* associated call stack */
16 | } T;
17 |
18 | /*
19 | The fields hold the following values. Omitted values must be transmitted,
20 | but memmon ignores them.
21 |
22 | client's call opcode ptr[0] ptr[1] size[0] size[1]
23 | free(ptr) Memmon_free ptr
24 | ptr=malloc(n) Memmon_malloc ptr n
25 | ptr=calloc(m,n) Memmon_calloc ptr n m
26 | new=realloc(ptr,n) Memmon_realloc ptr new n
27 |
28 | calls[] always holds up to 10 return addresses from the point
29 | of call to the allocation function.
30 | */
31 | #undef T
32 | #endif
33 |
--------------------------------------------------------------------------------
/malloc/trunk/sym.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "sym.h"
5 | #define T Sym_T
6 |
7 | struct T {
8 | int nsyms; /* number of elements in syms used */
9 | int size; /* number of elements in syms */
10 | struct symbol { /* symbol: */
11 | unsigned addr; /* address */
12 | char name[32]; /* name */
13 | } stab[512]; /* an array of symbols */
14 | };
15 |
16 | static T expand(T stab) {
17 | static struct symbol *last;
18 | extern void *sbrk(int);
19 |
20 | if (stab) {
21 | struct symbol *new = sbrk(stab->size*sizeof *new);
22 | if (new == (void *)-1 || last != new)
23 | return 0;
24 | assert(last);
25 | } else {
26 | stab = sbrk(sizeof *stab);
27 | if (stab == (void *)-1)
28 | return 0;
29 | stab->nsyms = 0;
30 | }
31 | last = sbrk(0);
32 | stab->size = last - stab->stab;
33 | return stab;
34 | }
35 |
36 | T Sym_init(const char *file) {
37 | FILE *f;
38 | struct symbol *sp;
39 | T stab;
40 |
41 | assert(file);
42 | if ((f = fopen(file, "r")) == 0)
43 | return 0;
44 | if ((stab = expand(NULL)) == NULL)
45 | goto error;
46 | sp = stab->stab;
47 | while (!feof(f)) {
48 | unsigned addr;
49 | char junk[4], name[100];
50 | if (fscanf(f, "%x %[tT] %s\n", (unsigned *)&addr, junk, name) != 3)
51 | goto error;
52 | if (stab->nsyms >= stab->size && !expand(stab))
53 | goto error;
54 | sp->addr = addr;
55 | #if __APPLE__
56 | if (name[0] == '_')
57 | strncpy(sp->name, &name[1], sizeof sp->name);
58 | else
59 | #endif
60 | strncpy(sp->name, name, sizeof sp->name);
61 | sp->name[sizeof(sp->name) - 1] = 0;
62 | sp++;
63 | stab->nsyms++;
64 | }
65 | fclose(f);
66 | return stab;
67 |
68 | error: fclose(f);
69 | return NULL;
70 | }
71 |
72 | char *Sym_find(T stab, void *addr) {
73 | int k = 0, lb = 0, ub;
74 | unsigned adr = (unsigned)addr;
75 |
76 | assert(stab);
77 | ub = stab->nsyms - 1;
78 | while (lb <= ub) {
79 | k = (lb + ub)/2;
80 | if (stab->stab[k].addr < adr) {
81 | if (k+1 == stab->nsyms || adr < stab->stab[k+1].addr)
82 | return stab->stab[k].name;
83 | lb = k + 1;
84 | } else if (stab->stab[k].addr > adr)
85 | ub = k - 1;
86 | else
87 | break;
88 | }
89 | return NULL;
90 | }
91 |
--------------------------------------------------------------------------------
/malloc/trunk/sym.h:
--------------------------------------------------------------------------------
1 | #ifndef SYM_INCLUDED
2 | #define SYM_INCLUDED
3 |
4 | #define T Sym_T
5 | typedef struct T *T;
6 |
7 | /*
8 | * Sym maintains a map of addresses to function names.
9 | */
10 |
11 | extern T Sym_init(const char *file);
12 | /*
13 | * Sym_init specifies the name of the file from which to extract the symbol
14 | * table of an executable program. The file must be created by a command like
15 | *
16 | * nm -n a.out | grep '[tT] _' >file
17 | *
18 | * where a.out is executable file of interest.
19 | *
20 | * Sym_init returns a handle to the symbol table if the file can be read and
21 | * it's in the proper format. Otherwise, Sym_init returns NULL. Sym_init
22 | * allocates space for the symbol table by making system calls; it does not
23 | * call malloc. It is a checked runtime error to pass a NULL file to Sym_init.
24 | */
25 |
26 | extern char *Sym_find(T stab, void *addr);
27 | /*
28 | * Sym_find searches the symbol table stab and returns a pointer to the name of
29 | * the function whose body includes the location at addr, or NULL if no
30 | * function's body in stab includes addr. The name is at most 16 characters long
31 | * including the terminating null byte. Clients must make a copy of the name
32 | * before modifying it.
33 | */
34 |
35 | /*
36 | * It is a checked runtime error to pass a NULL T to any function in this
37 | * interface.
38 | */
39 |
40 | #undef T
41 | #endif
42 |
--------------------------------------------------------------------------------
/malloc/trunk/trace.c:
--------------------------------------------------------------------------------
1 | /* #included in malloc.c */
2 | #ifndef MEMMON
3 | #define MEMMON "./memmon"
4 | #endif
5 |
6 | extern int close(int);
7 | extern int dup2(int, int);
8 | extern int execl(const char *, const char *, ...);
9 | extern int fork(void);
10 | extern int pipe(int[]);
11 | extern int write(int, char *, int);
12 | #if sparc
13 | extern struct frame { void *lreg[8], *ireg[8]; } *_framepointer(void);
14 | asm(
15 | ".seg \"text\"\n"
16 | ".global _framepointer\n"
17 | "_framepointer: ta 3\n"
18 | "retl; mov %sp,%o0\n");
19 | #elif i386
20 | extern struct frame { void *savedbp, *retaddr; } *_framepointer(void);
21 | asm(
22 | ".text\n"
23 | ".globl __framepointer, _framepointer\n"
24 | "__framepointer:\n"
25 | "_framepointer: mov %ebp,%eax\n"
26 | "ret\n");
27 | #else
28 | Unsupported platform
29 | #endif
30 |
31 | /* trace - insert call trace from sp into pc[0..ncalls-1] */
32 | static void trace(struct frame *fp, void *pc[], int ncalls) {
33 | int i;
34 |
35 | #if sparc
36 | for (i = 0; fp && i < ncalls; i++) {
37 | pc[i] = fp->ireg[7]; /* return address */
38 | fp = fp->ireg[6];
39 | }
40 | if (fp == 0 && i > 1)
41 | i -= 2;
42 | else if (fp && fp->ireg[6] == 0 && i > 0)
43 | i -= 1;
44 | #elif i386
45 | for (i = 0; fp && i < ncalls; i++) {
46 | pc[i] = fp->retaddr;
47 | fp = fp->savedbp;
48 | }
49 | #if __APPLE__
50 | if (fp == 0 && i > 2)
51 | i -= 3;
52 | else
53 | #endif
54 | if (fp == 0 && i > 1)
55 | i -= 2;
56 | else if (fp == 0 && i > 0)
57 | i -= 1;
58 | #endif
59 | while (i < ncalls)
60 | pc[i++] = NULL;
61 | }
62 |
63 | /* send - send *msg to memmon, starting it if necessary; sp is caller's sp */
64 | static void send(Memmon_T *msg, struct frame *sp) {
65 | static int inited = 0, fd[2];
66 |
67 | if (inited == 0) {
68 | inited = -1;
69 | if (pipe(fd) < 0)
70 | return;
71 | switch (fork()) {
72 | case -1:
73 | return;
74 | default: /* parent: close fd[0], and write *msg */
75 | close(fd[0]);
76 | inited = 1;
77 | break;
78 | case 0: /* child: rearrange i/o, and run memmon */
79 | close(fd[1]);
80 | if (dup2(fd[0], 0) >= 0) {
81 | close(fd[0]);
82 | execl(MEMMON, "memmon", NULL);
83 | }
84 | exit(EXIT_FAILURE);
85 | }
86 | }
87 | trace(sp, msg->calls, sizeof msg->calls/sizeof msg->calls[0]);
88 | if (inited > 0
89 | && write(fd[1], (char *)msg, sizeof *msg) != (int)sizeof *msg)
90 | inited = -1;
91 | }
92 |
--------------------------------------------------------------------------------
/tex/tags/original/letterformat.tex:
--------------------------------------------------------------------------------
1 | % letter macros; see Appendix E of the TeXBook
2 |
3 | \def\today{\ifcase\month\or
4 | January\or February\or March\or April\or May\or June\or
5 | July\or August\or September\or October\or November\or December\fi
6 | \space\number\day, \number\year}
7 | \raggedbottom
8 | \interlinepenalty=1000
9 | \hsize=6.5truein
10 | \voffset=1truein % for princeton letterhead
11 | \parindent=0pt
12 | \parskip=0pt
13 | \nopagenumbers
14 | \headline={\ifnum\pageno>1
15 | \tenrm To \addressee\hfil\today\hfil Page \folio
16 | \else\hfil\fi}
17 | \def\beginlinemode{\endmode
18 | \begingroup\obeylines\def\endmode{\par\endgroup}}
19 | \def\beginparmode{\endmode
20 | \begingroup\parskip=\medskipamount \def\endmode{\par\endgroup}}
21 | \let\endmode=\par
22 | \def\endletter{\endmode\vfill\supereject}
23 | \newdimen\longindentation \longindentation=4truein
24 | \newbox\theaddress
25 | \def\address{\beginlinemode\getaddress}
26 | {\obeylines\gdef\getaddress #1
27 | #2
28 | {#1\gdef\addressee{#2}%
29 | \global\setbox\theaddress=\vbox\bgroup\raggedright%
30 | \hsize=\longindentation \everypar{\hangindent2em}#2
31 | \def\endmode{\egroup\endgroup \copy\theaddress \bigskip}}}
32 | \def\body{\beginparmode}
33 | \def\closing{\beginlinemode\getclosing}
34 | {\obeylines\gdef\getclosing #1
35 | #2
36 | {#1\nobreak\bigskip\bigskip \leftskip=\longindentation #2
37 | \nobreak\bigskip\bigskip\bigskip % space for signature
38 | \def
39 | {\endgraf\nobreak}}}
40 | \def\annotations{\beginlinemode\def\par{\endgraf\nobreak}\obeylines\par}
41 | \def\ps{\beginparmode\nobreak
42 | \interlinepenalty5000\def\par{\endgraf\penalty5000}}
43 |
44 | \def\letterhead{\pageno=1 \def\addressee{}
45 | {\leftskip=\longindentation\bigskip\today\par}\bigskip\bigskip}
46 | \def\makelabel{\endletter\copy\theaddress
47 | \pageno=0\vfill\eject}
48 |
--------------------------------------------------------------------------------
/tex/tags/original/loommac.tex:
--------------------------------------------------------------------------------
1 | % macros for use with loom'ed program documentation
2 |
3 | \input macros
4 | \newcount\secno \secno=0
5 | \def\section#1\par{\advance\secno by1\bigskip
6 | \message{#1}\noindent{\bf\the\secno.\enspace#1}}
7 | \displayindent=2em
8 | \newwrite\inx
9 | \immediate\closeout\inx
10 | \immediate\openout\inx=index.dat
11 | \def\index(#1,#2,#3){\immediate\write\inx{#1:#2:#3:\the\secno}}
12 | \def\beginprogram{\program\catcode`\%=14\parindent=2em\displayindent=2em}
13 | \def\beginindex{\par\section Index. \par
14 | The numbers in this index refer to the section numbers
15 | in which the indexed identifiers appear.\par\nobreak\bigskip\nobreak
16 | \begindoublecolumns
17 | \parindent=0pt \parskip=0pt plus.5pt \everypar={\hangindent=1em}
18 | \exhyphenpenalty=10000 \rightskip=0pt plus2em \catcode`\_=\other}
19 | \def\endindex{\enddoublecolumns}
20 | \def\newletter{\medbreak\hangindent=1em}
21 |
--------------------------------------------------------------------------------
/tex/trunk/letterformat.tex:
--------------------------------------------------------------------------------
1 | % letter macros; see Appendix E of the TeXBook
2 |
3 | \def\today{\ifcase\month\or
4 | January\or February\or March\or April\or May\or June\or
5 | July\or August\or September\or October\or November\or December\fi
6 | \space\number\day, \number\year}
7 | \raggedbottom
8 | \interlinepenalty=1000
9 | \hsize=6.5truein
10 | \voffset=1truein % for princeton letterhead
11 | \parindent=0pt
12 | \parskip=0pt
13 | \nopagenumbers
14 | \headline={\ifnum\pageno>1
15 | \tenrm To \addressee\hfil\today\hfil Page \folio
16 | \else\hfil\fi}
17 | \def\beginlinemode{\endmode
18 | \begingroup\obeylines\def\endmode{\par\endgroup}}
19 | \def\beginparmode{\endmode
20 | \begingroup\parskip=\medskipamount \def\endmode{\par\endgroup}}
21 | \let\endmode=\par
22 | \def\endletter{\endmode\vfill\supereject}
23 | \newdimen\longindentation \longindentation=4truein
24 | \newbox\theaddress
25 | \def\address{\beginlinemode\getaddress}
26 | {\obeylines\gdef\getaddress #1
27 | #2
28 | {#1\gdef\addressee{#2}%
29 | \global\setbox\theaddress=\vbox\bgroup\raggedright%
30 | \hsize=\longindentation \everypar{\hangindent2em}#2
31 | \def\endmode{\egroup\endgroup \copy\theaddress \bigskip}}}
32 | \def\body{\beginparmode}
33 | \def\closing{\beginlinemode\getclosing}
34 | {\obeylines\gdef\getclosing #1
35 | #2
36 | {#1\nobreak\bigskip\bigskip \leftskip=\longindentation #2
37 | \nobreak\bigskip\bigskip\bigskip % space for signature
38 | \def
39 | {\endgraf\nobreak}}}
40 | \def\annotations{\beginlinemode\def\par{\endgraf\nobreak}\obeylines\par}
41 | \def\ps{\beginparmode\nobreak
42 | \interlinepenalty5000\def\par{\endgraf\penalty5000}}
43 |
44 | \def\letterhead{\pageno=1 \def\addressee{}
45 | {\leftskip=\longindentation\bigskip\today\par}\bigskip\bigskip}
46 | \def\makelabel{\endletter\copy\theaddress
47 | \pageno=0\vfill\eject}
48 |
--------------------------------------------------------------------------------
/tex/trunk/loommac.tex:
--------------------------------------------------------------------------------
1 | % macros for use with loom'ed program documentation
2 |
3 | \input macros
4 | \newcount\secno \secno=0
5 | \def\section#1\par{\advance\secno by1\bigskip
6 | \message{#1}\noindent{\bf\the\secno.\enspace#1}}
7 | \displayindent=2em
8 | \newwrite\inx
9 | \immediate\closeout\inx
10 | \immediate\openout\inx=index.dat
11 | \def\index(#1,#2,#3){\immediate\write\inx{#1:#2:#3:\the\secno}}
12 | \def\beginprogram{\program\catcode`\%=14\parindent=2em\displayindent=2em}
13 | \def\beginindex{\par\section Index. \par
14 | The numbers in this index refer to the section numbers
15 | in which the indexed identifiers appear.\par\nobreak\bigskip\nobreak
16 | \begindoublecolumns
17 | \parindent=0pt \parskip=0pt plus.5pt \everypar={\hangindent=1em}
18 | \exhyphenpenalty=10000 \rightskip=0pt plus2em \catcode`\_=\other}
19 | \def\endindex{\enddoublecolumns}
20 | \def\newletter{\medbreak\hangindent=1em}
21 |
--------------------------------------------------------------------------------
/treeIR/tags/original/tree.h:
--------------------------------------------------------------------------------
1 | /* Tree IR definitions */
2 |
3 | #ifndef _TREE_H
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | typedef enum Opcode {
11 | oZERO,
12 | #define xx(a,b,c) o##a,
13 | #endif
14 |
15 | /* name arity attributes */
16 | xx(SEQ, 2, ATTstm|ATTchild)
17 | xx(LABEL, 0, ATTstm|ATTlabel)
18 | xx(JUMP, 1, ATTstm|ATTchild)
19 | xx(CJUMP, 2, ATTstm|ATTchild)
20 | xx(MEM, 1, ATTexp|ATTchild|ATTsize)
21 | xx(MOVE, 2, ATTexp|ATTchild|ATTsize)
22 | xx(ESEQ, 2, ATTexp|ATTchild)
23 | xx(NAME, 0, ATTexp|ATTlabel|ATTsize)
24 | xx(CONST, 0, ATTexp|ATTivalue|ATTsize)
25 | xx(CONSTF, 0, ATTexp|ATTfvalue|ATTsize)
26 | xx(ALLOC, 2, ATTexp|ATTchild|ATTsize)
27 | xx(TEMP, 0, ATTexp|ATTtemp|ATTsize)
28 | xx(CALL, 2, ATTexp|ATTchild|ATTsize)
29 | xx(ARG, 2, ATTargs|ATTchild|ATTsize)
30 | xx(NOARGS, 0, ATTargs)
31 | xx(FPLUS, 2, ATTbinop|ATTsize|ATTchild)
32 | xx(FMINUS, 2, ATTbinop|ATTsize|ATTchild)
33 | xx(FMUL, 2, ATTbinop|ATTsize|ATTchild)
34 | xx(FDIV, 2, ATTbinop|ATTsize|ATTchild)
35 | xx(FNEG, 1, ATTunop|ATTsize|ATTchild)
36 | xx(CVTSU, 1, ATTcvtop|ATTsize|ATTchild)
37 | xx(CVTSS, 1, ATTcvtop|ATTsize|ATTchild)
38 | xx(CVTSF, 1, ATTcvtop|ATTsize|ATTchild)
39 | xx(CVTUU, 1, ATTcvtop|ATTsize|ATTchild)
40 | xx(CVTUS, 1, ATTcvtop|ATTsize|ATTchild)
41 | xx(CVTFS, 1, ATTcvtop|ATTsize|ATTchild)
42 | xx(CVTFF, 1, ATTcvtop|ATTsize|ATTchild)
43 | xx(PLUS, 2, ATTbinop|ATTsize|ATTchild)
44 | xx(MINUS, 2, ATTbinop|ATTsize|ATTchild)
45 | xx(MUL, 2, ATTbinop|ATTsize|ATTchild)
46 | xx(DIV, 2, ATTbinop|ATTsize|ATTchild)
47 | xx(MOD, 2, ATTbinop|ATTsize|ATTchild)
48 | xx(AND, 2, ATTbinop|ATTsize|ATTchild)
49 | xx(OR, 2, ATTbinop|ATTsize|ATTchild)
50 | xx(LSHIFT, 2, ATTbinop|ATTsize|ATTchild)
51 | xx(RSHIFT, 2, ATTbinop|ATTsize|ATTchild)
52 | xx(XOR, 2, ATTbinop|ATTsize|ATTchild)
53 | xx(NEG, 1, ATTunop|ATTsize|ATTchild)
54 | xx(COMP, 1, ATTunop|ATTsize|ATTchild)
55 | xx(EQ, 2, ATTrelop|ATTchild)
56 | xx(NE, 2, ATTrelop|ATTchild)
57 | xx(LT, 2, ATTrelop|ATTchild)
58 | xx(GE, 2, ATTrelop|ATTchild)
59 | xx(GT, 2, ATTrelop|ATTchild)
60 | xx(LE, 2, ATTrelop|ATTchild)
61 | xx(ULT, 2, ATTrelop|ATTchild)
62 | xx(UGE, 2, ATTrelop|ATTchild)
63 | xx(UGT, 2, ATTrelop|ATTchild)
64 | xx(ULE, 2, ATTrelop|ATTchild)
65 | xx(FEQ, 2, ATTrelop|ATTchild)
66 | xx(FNE, 2, ATTrelop|ATTchild)
67 | xx(FLT, 2, ATTrelop|ATTchild)
68 | xx(FLE, 2, ATTrelop|ATTchild)
69 | xx(FGT, 2, ATTrelop|ATTchild)
70 | xx(FGE, 2, ATTrelop|ATTchild)
71 | #undef xx
72 |
73 | #ifndef _TREE_H
74 | #define _TREE_H
75 | oLAST
76 | } Opcode;
77 |
78 | #define bit(n) (1<<(n))
79 | typedef enum Attribute {
80 | ATTsize=bit(0),
81 | ATTchild=bit(1),
82 | ATTlabel=bit(2),
83 | ATTivalue=bit(3),
84 | ATTfvalue=bit(4),
85 | ATTtemp=bit(5),
86 | ATTexp=bit(6),
87 | ATTtest=bit(7),
88 | ATTstm=bit(8),
89 | ATTargs=bit(9),
90 | ATTbinop=bit(10)|ATTexp,
91 | ATTrelop=bit(11)|ATTtest,
92 | ATTunop=bit(12)|ATTexp,
93 | ATTcvtop=bit(13)|ATTexp
94 | } Attribute;
95 | #undef bit
96 |
97 | #define Attr(op) ((op)>0 && (op)op)&(a))
99 |
100 | extern struct nodeinfo {
101 | char *s;
102 | int attributes;
103 | } nodeops[];
104 |
105 | typedef char *Label;
106 | typedef struct temp {
107 | int number;
108 | int size;
109 | } *Temp;
110 |
111 | typedef struct tree *Tree;
112 | struct tree {
113 | Opcode op;
114 | int size;
115 | union {
116 | Tree child[2];
117 | Label label;
118 | int ivalue;
119 | double fvalue;
120 | Temp temp;
121 | } u;
122 | #ifdef YYTREE
123 | YYTREE x;
124 | #endif
125 | };
126 |
127 | void freeTree(Tree t),
128 | printTree(Tree t, FILE *fp);
129 | Label newLabel(void);
130 | Temp newTemp(int size);
131 | Tree tSEQ(Tree stm1, Tree stm2),
132 | tLABEL(Label label),
133 | tJUMP(Tree exp),
134 | tCJUMP(Tree test, Tree exp),
135 | tOP(int size, Opcode binop, Tree exp1, Tree exp2),
136 | tUNOP(int size, Opcode unop, Tree exp),
137 | tCONVERT(int size, Opcode cvtop, Tree exp),
138 | tREL(Opcode relop, Tree exp1, Tree exp2),
139 | tMEM(int size, Tree exp),
140 | tMOVE(Tree exp1, Tree exp2),
141 | tESEQ(Tree stm, Tree exp),
142 | tNAME(int size, Label label),
143 | tCONST(int size, int val),
144 | tCONSTF(int size, double val),
145 | tALLOC(Temp temp, Tree exp),
146 | tTEMP(Temp temp),
147 | tCALL(int size, Tree exp, Tree args),
148 | tARG(Tree exp, Tree args),
149 | tNOARGS(void);
150 |
151 | #endif
152 |
--------------------------------------------------------------------------------
/treeIR/trunk/makefile:
--------------------------------------------------------------------------------
1 | CC=cc
2 | CFLAGS=-g
3 | AR=ar
4 | OBJS=tree.o
5 |
6 | libtree.a: $(OBJS) makefile
7 | $(AR) -r $@ $(OBJS)
8 |
9 | clean:
10 | -rm $(OBJS)
11 |
12 | clobber: clean
13 | -rm libtree.a
14 |
15 |
--------------------------------------------------------------------------------
/treeIR/trunk/tree.h:
--------------------------------------------------------------------------------
1 | /* Tree IR definitions */
2 |
3 | #ifndef _TREE_H
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | typedef enum Opcode {
11 | oZERO,
12 | #define xx(a,b,c) o##a,
13 | #endif
14 |
15 | /* name arity attributes */
16 | xx(SEQ, 2, ATTstm|ATTchild)
17 | xx(LABEL, 0, ATTstm|ATTlabel)
18 | xx(JUMP, 1, ATTstm|ATTchild)
19 | xx(CJUMP, 2, ATTstm|ATTchild)
20 | xx(MEM, 1, ATTexp|ATTchild|ATTsize)
21 | xx(MOVE, 2, ATTexp|ATTchild|ATTsize)
22 | xx(ESEQ, 2, ATTexp|ATTchild)
23 | xx(NAME, 0, ATTexp|ATTlabel|ATTsize)
24 | xx(CONST, 0, ATTexp|ATTivalue|ATTsize)
25 | xx(CONSTF, 0, ATTexp|ATTfvalue|ATTsize)
26 | xx(ALLOC, 2, ATTexp|ATTchild|ATTsize)
27 | xx(TEMP, 0, ATTexp|ATTtemp|ATTsize)
28 | xx(CALL, 2, ATTexp|ATTchild|ATTsize)
29 | xx(ARG, 2, ATTargs|ATTchild|ATTsize)
30 | xx(NOARGS, 0, ATTargs)
31 | xx(FPLUS, 2, ATTbinop|ATTsize|ATTchild)
32 | xx(FMINUS, 2, ATTbinop|ATTsize|ATTchild)
33 | xx(FMUL, 2, ATTbinop|ATTsize|ATTchild)
34 | xx(FDIV, 2, ATTbinop|ATTsize|ATTchild)
35 | xx(FNEG, 1, ATTunop|ATTsize|ATTchild)
36 | xx(CVTSU, 1, ATTcvtop|ATTsize|ATTchild)
37 | xx(CVTSS, 1, ATTcvtop|ATTsize|ATTchild)
38 | xx(CVTSF, 1, ATTcvtop|ATTsize|ATTchild)
39 | xx(CVTUU, 1, ATTcvtop|ATTsize|ATTchild)
40 | xx(CVTUS, 1, ATTcvtop|ATTsize|ATTchild)
41 | xx(CVTFS, 1, ATTcvtop|ATTsize|ATTchild)
42 | xx(CVTFF, 1, ATTcvtop|ATTsize|ATTchild)
43 | xx(PLUS, 2, ATTbinop|ATTsize|ATTchild)
44 | xx(MINUS, 2, ATTbinop|ATTsize|ATTchild)
45 | xx(MUL, 2, ATTbinop|ATTsize|ATTchild)
46 | xx(DIV, 2, ATTbinop|ATTsize|ATTchild)
47 | xx(MOD, 2, ATTbinop|ATTsize|ATTchild)
48 | xx(AND, 2, ATTbinop|ATTsize|ATTchild)
49 | xx(OR, 2, ATTbinop|ATTsize|ATTchild)
50 | xx(LSHIFT, 2, ATTbinop|ATTsize|ATTchild)
51 | xx(RSHIFT, 2, ATTbinop|ATTsize|ATTchild)
52 | xx(XOR, 2, ATTbinop|ATTsize|ATTchild)
53 | xx(NEG, 1, ATTunop|ATTsize|ATTchild)
54 | xx(COMP, 1, ATTunop|ATTsize|ATTchild)
55 | xx(EQ, 2, ATTrelop|ATTchild)
56 | xx(NE, 2, ATTrelop|ATTchild)
57 | xx(LT, 2, ATTrelop|ATTchild)
58 | xx(GE, 2, ATTrelop|ATTchild)
59 | xx(GT, 2, ATTrelop|ATTchild)
60 | xx(LE, 2, ATTrelop|ATTchild)
61 | xx(ULT, 2, ATTrelop|ATTchild)
62 | xx(UGE, 2, ATTrelop|ATTchild)
63 | xx(UGT, 2, ATTrelop|ATTchild)
64 | xx(ULE, 2, ATTrelop|ATTchild)
65 | xx(FEQ, 2, ATTrelop|ATTchild)
66 | xx(FNE, 2, ATTrelop|ATTchild)
67 | xx(FLT, 2, ATTrelop|ATTchild)
68 | xx(FLE, 2, ATTrelop|ATTchild)
69 | xx(FGT, 2, ATTrelop|ATTchild)
70 | xx(FGE, 2, ATTrelop|ATTchild)
71 | #undef xx
72 |
73 | #ifndef _TREE_H
74 | #define _TREE_H
75 | oLAST
76 | } Opcode;
77 |
78 | #define bit(n) (1<<(n))
79 | typedef enum Attribute {
80 | ATTsize=bit(0),
81 | ATTchild=bit(1),
82 | ATTlabel=bit(2),
83 | ATTivalue=bit(3),
84 | ATTfvalue=bit(4),
85 | ATTtemp=bit(5),
86 | ATTexp=bit(6),
87 | ATTtest=bit(7),
88 | ATTstm=bit(8),
89 | ATTargs=bit(9),
90 | ATTbinop=bit(10)|ATTexp,
91 | ATTrelop=bit(11)|ATTtest,
92 | ATTunop=bit(12)|ATTexp,
93 | ATTcvtop=bit(13)|ATTexp
94 | } Attribute;
95 | #undef bit
96 |
97 | #define Attr(op) ((op)>0 && (op)op)&(a))
99 |
100 | extern struct nodeinfo {
101 | char *s;
102 | int attributes;
103 | } nodeops[];
104 |
105 | typedef char *Label;
106 | typedef struct temp {
107 | int number;
108 | int size;
109 | } *Temp;
110 |
111 | typedef struct tree *Tree;
112 | struct tree {
113 | Opcode op;
114 | int size;
115 | union {
116 | Tree child[2];
117 | Label label;
118 | int ivalue;
119 | double fvalue;
120 | Temp temp;
121 | } u;
122 | #ifdef YYTREE
123 | YYTREE x;
124 | #endif
125 | };
126 |
127 | void freeTree(Tree t),
128 | printTree(Tree t, FILE *fp);
129 | Label newLabel(void);
130 | Temp newTemp(int size);
131 | Tree tSEQ(Tree stm1, Tree stm2),
132 | tLABEL(Label label),
133 | tJUMP(Tree exp),
134 | tCJUMP(Tree test, Tree exp),
135 | tOP(int size, Opcode binop, Tree exp1, Tree exp2),
136 | tUNOP(int size, Opcode unop, Tree exp),
137 | tCONVERT(int size, Opcode cvtop, Tree exp),
138 | tREL(Opcode relop, Tree exp1, Tree exp2),
139 | tMEM(int size, Tree exp),
140 | tMOVE(Tree exp1, Tree exp2),
141 | tESEQ(Tree stm, Tree exp),
142 | tNAME(int size, Label label),
143 | tCONST(int size, int val),
144 | tCONSTF(int size, double val),
145 | tALLOC(Temp temp, Tree exp),
146 | tTEMP(Temp temp),
147 | tCALL(int size, Tree exp, Tree args),
148 | tARG(Tree exp, Tree args),
149 | tNOARGS(void);
150 |
151 | #endif
152 |
--------------------------------------------------------------------------------