├── 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 |
  1. freeing or reallocing memory that wasn’t allocated by malloc, realloc, or calloc;
  2. 13 |
  3. freeing or reallocing free memory; and
  4. 14 |
  5. failing to free memory.
  6. 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 | --------------------------------------------------------------------------------