diff options
| author | Byron Rakitzis <byron@archone.tamu.edu> | 1992-05-27 00:00:01 +0100 |
|---|---|---|
| committer | Toby Goodwin <toby@paccrat.org> | 2015-05-16 21:22:04 +0100 |
| commit | 6bb38f6a01dbf4bbd584e038ceace0a00faa27bb (patch) | |
| tree | 589705b2492ce4681760846d9ca45600f0af298d /tree.c | |
release: rc-1.4
Diffstat (limited to 'tree.c')
| -rw-r--r-- | tree.c | 172 |
1 files changed, 172 insertions, 0 deletions
@@ -0,0 +1,172 @@ +/* tree.c: functions for manipulating parse-trees. (create, copy, delete) */ + +#include "rc.h" + +/* make a new node, pass it back to yyparse. Used to generate the parsetree. */ + +extern Node *mk(int /*nodetype*/ t,...) { + va_list ap; + Node *n; + va_start(ap, t); + switch (t) { + default: + panic("unexpected node in mk"); + /* NOTREACHED */ + case nDup: + n = nalloc(offsetof(Node, u[3])); + n->u[0].i = va_arg(ap, int); + n->u[1].i = va_arg(ap, int); + n->u[2].i = va_arg(ap, int); + break; + case nWord: case nQword: + n = nalloc(offsetof(Node, u[2])); + n->u[0].s = va_arg(ap, char *); + n->u[1].s = va_arg(ap, char *); + break; + case nBang: case nNowait: + case nCount: case nFlat: case nRmfn: case nSubshell: + case nVar: case nCase: + n = nalloc(offsetof(Node, u[1])); + n->u[0].p = va_arg(ap, Node *); + break; + case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat: + case nElse: case nEpilog: case nIf: case nNewfn: case nCbody: + case nOrelse: case nPre: case nArgs: case nSwitch: + case nMatch: case nVarsub: case nWhile: case nLappend: + n = nalloc(offsetof(Node, u[2])); + n->u[0].p = va_arg(ap, Node *); + n->u[1].p = va_arg(ap, Node *); + break; + case nForin: + n = nalloc(offsetof(Node, u[3])); + n->u[0].p = va_arg(ap, Node *); + n->u[1].p = va_arg(ap, Node *); + n->u[2].p = va_arg(ap, Node *); + break; + case nPipe: + n = nalloc(offsetof(Node, u[4])); + n->u[0].i = va_arg(ap, int); + n->u[1].i = va_arg(ap, int); + n->u[2].p = va_arg(ap, Node *); + n->u[3].p = va_arg(ap, Node *); + break; + case nRedir: + case nNmpipe: + n = nalloc(offsetof(Node, u[3])); + n->u[0].i = va_arg(ap, int); + n->u[1].i = va_arg(ap, int); + n->u[2].p = va_arg(ap, Node *); + break; + } + n->type = t; + va_end(ap); + return n; +} + +/* copy a tree to malloc space. Used when storing the definition of a function */ + +extern Node *treecpy(Node *s, void *(*alloc)(SIZE_T)) { + Node *n; + if (s == NULL) + return NULL; + switch (s->type) { + default: + panic("unexpected node in treecpy"); + /* NOTREACHED */ + case nDup: + n = (*alloc)(offsetof(Node, u[3])); + n->u[0].i = s->u[0].i; + n->u[1].i = s->u[1].i; + n->u[2].i = s->u[2].i; + break; + case nWord: case nQword: + n = (*alloc)(offsetof(Node, u[2])); + n->u[0].s = strcpy((char *) (*alloc)(strlen(s->u[0].s) + 1), s->u[0].s); + if (s->u[1].s != NULL) { + SIZE_T i = strlen(s->u[0].s); + n->u[1].s = (*alloc)(i); + memcpy(n->u[1].s, s->u[1].s, i); + } else + n->u[1].s = NULL; + break; + case nBang: case nNowait: case nCase: + case nCount: case nFlat: case nRmfn: case nSubshell: case nVar: + n = (*alloc)(offsetof(Node, u[1])); + n->u[0].p = treecpy(s->u[0].p, alloc); + break; + case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat: + case nElse: case nEpilog: case nIf: case nNewfn: case nCbody: + case nOrelse: case nPre: case nArgs: case nSwitch: + case nMatch: case nVarsub: case nWhile: case nLappend: + n = (*alloc)(offsetof(Node, u[2])); + n->u[0].p = treecpy(s->u[0].p, alloc); + n->u[1].p = treecpy(s->u[1].p, alloc); + break; + case nForin: + n = (*alloc)(offsetof(Node, u[3])); + n->u[0].p = treecpy(s->u[0].p, alloc); + n->u[1].p = treecpy(s->u[1].p, alloc); + n->u[2].p = treecpy(s->u[2].p, alloc); + break; + case nPipe: + n = (*alloc)(offsetof(Node, u[4])); + n->u[0].i = s->u[0].i; + n->u[1].i = s->u[1].i; + n->u[2].p = treecpy(s->u[2].p, alloc); + n->u[3].p = treecpy(s->u[3].p, alloc); + break; + case nRedir: + case nNmpipe: + n = (*alloc)(offsetof(Node, u[3])); + n->u[0].i = s->u[0].i; + n->u[1].i = s->u[1].i; + n->u[2].p = treecpy(s->u[2].p, alloc); + break; + } + n->type = s->type; + return n; +} + +/* free a function definition that is no longer needed */ + +extern void treefree(Node *s) { + if (s == NULL) + return; + switch (s->type) { + default: + panic("unexpected node in treefree"); + /* NOTREACHED */ + case nDup: + break; + case nWord: case nQword: + efree(s->u[0].s); + efree(s->u[1].s); + break; + case nBang: case nNowait: + case nCount: case nFlat: case nRmfn: + case nSubshell: case nVar: case nCase: + treefree(s->u[0].p); + break; + case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat: + case nElse: case nEpilog: case nIf: case nNewfn: + case nOrelse: case nPre: case nArgs: case nCbody: + case nSwitch: case nMatch: case nVarsub: case nWhile: + case nLappend: + treefree(s->u[1].p); + treefree(s->u[0].p); + break; + case nForin: + treefree(s->u[2].p); + treefree(s->u[1].p); + treefree(s->u[0].p); + break; + case nPipe: + treefree(s->u[2].p); + treefree(s->u[3].p); + break; + case nRedir: + case nNmpipe: + treefree(s->u[2].p); + } + efree(s); +} |