1*5542Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*5542Slinton 3*5542Slinton static char sccsid[] = "@(#)build.c 1.1 01/18/82"; 4*5542Slinton 5*5542Slinton /* 6*5542Slinton * parse tree building routines 7*5542Slinton * 8*5542Slinton * Semantics is not checked here, this is done by the "treetype" routine 9*5542Slinton * in the SYM directory which returns the type of the newly built tree. 10*5542Slinton */ 11*5542Slinton 12*5542Slinton #include "defs.h" 13*5542Slinton #include "tree.h" 14*5542Slinton #include "sym.h" 15*5542Slinton #include "source.h" 16*5542Slinton #include "tree.rep" 17*5542Slinton 18*5542Slinton /* 19*5542Slinton * header for using routines with unknown number and types of arguments 20*5542Slinton * I didn't like the looks of the standard varargs.h. 21*5542Slinton */ 22*5542Slinton 23*5542Slinton typedef char *ARGLIST; 24*5542Slinton 25*5542Slinton #define nextarg(arglist, type) ((type *) (arglist += sizeof(type)))[-1] 26*5542Slinton 27*5542Slinton /* 28*5542Slinton * build a tree 29*5542Slinton */ 30*5542Slinton 31*5542Slinton /*VARARGS1*/ 32*5542Slinton NODE *build(op, args) 33*5542Slinton OP op; 34*5542Slinton { 35*5542Slinton register NODE *p; 36*5542Slinton NODE *p1, *p2; 37*5542Slinton register ARGLIST ap; 38*5542Slinton SYM *s; 39*5542Slinton 40*5542Slinton p = alloc(1, NODE); 41*5542Slinton p->op = op; 42*5542Slinton ap = (ARGLIST) &args; 43*5542Slinton switch(degree(op)) { 44*5542Slinton case BINARY: 45*5542Slinton p->left = p1 = nextarg(ap, NODE *); 46*5542Slinton p->right = p2 = nextarg(ap, NODE *); 47*5542Slinton break; 48*5542Slinton 49*5542Slinton case UNARY: 50*5542Slinton p->left = p1 = nextarg(ap, NODE *); 51*5542Slinton p->right = NIL; 52*5542Slinton break; 53*5542Slinton 54*5542Slinton } 55*5542Slinton switch(op) { 56*5542Slinton case O_NAME: 57*5542Slinton case O_WHICH: 58*5542Slinton p->nameval = nextarg(ap, SYM *); 59*5542Slinton break; 60*5542Slinton 61*5542Slinton case O_LCON: 62*5542Slinton p->lconval = nextarg(ap, long); 63*5542Slinton break; 64*5542Slinton 65*5542Slinton case O_FCON: 66*5542Slinton p->fconval = nextarg(ap, double); 67*5542Slinton break; 68*5542Slinton 69*5542Slinton case O_SCON: 70*5542Slinton p->sconval = nextarg(ap, char *); 71*5542Slinton break; 72*5542Slinton 73*5542Slinton case O_CALL: 74*5542Slinton p->left = nextarg(ap, NODE *); 75*5542Slinton p->right = nextarg(ap, NODE *); 76*5542Slinton break; 77*5542Slinton 78*5542Slinton case O_CHFILE: 79*5542Slinton p->sconval = nextarg(ap, char *); 80*5542Slinton break; 81*5542Slinton 82*5542Slinton case O_EDIT: 83*5542Slinton p->sconval = nextarg(ap, char *); 84*5542Slinton if (p->sconval == NIL) { 85*5542Slinton p->sconval = cursource; 86*5542Slinton } 87*5542Slinton break; 88*5542Slinton 89*5542Slinton case O_SOURCE: 90*5542Slinton p->sconval = nextarg(ap, char *); 91*5542Slinton break; 92*5542Slinton 93*5542Slinton case O_PRINT: 94*5542Slinton case O_WHATIS: 95*5542Slinton case O_LIST: 96*5542Slinton case O_XI: 97*5542Slinton case O_XD: 98*5542Slinton p->left = nextarg(ap, NODE *); 99*5542Slinton break; 100*5542Slinton 101*5542Slinton case O_TRACE: 102*5542Slinton case O_TRACEI: 103*5542Slinton case O_STOP: 104*5542Slinton case O_STOPI: 105*5542Slinton p->what = nextarg(ap, NODE *); 106*5542Slinton p->where = nextarg(ap, NODE *); 107*5542Slinton p->cond = nextarg(ap, NODE *); 108*5542Slinton break; 109*5542Slinton 110*5542Slinton case O_DELETE: 111*5542Slinton p->left = build(O_LCON, nextarg(ap, long)); 112*5542Slinton break; 113*5542Slinton 114*5542Slinton case O_QLINE: { 115*5542Slinton char *s; 116*5542Slinton 117*5542Slinton s = nextarg(ap, char *); 118*5542Slinton p->left = alloc(1, NODE); 119*5542Slinton p->left->op = O_SCON; 120*5542Slinton if (s != cursource) { 121*5542Slinton p->left->sconval = s; 122*5542Slinton s[strlen(s) - 1] = '\0'; 123*5542Slinton } else { 124*5542Slinton p->left->sconval = strdup(s); 125*5542Slinton } 126*5542Slinton p->right = nextarg(ap, NODE *); 127*5542Slinton break; 128*5542Slinton } 129*5542Slinton 130*5542Slinton case O_ALIAS: 131*5542Slinton p->left = alloc(1, NODE); 132*5542Slinton p->left->op = O_SCON; 133*5542Slinton p->left->sconval = nextarg(ap, char *); 134*5542Slinton p->right = alloc(1, NODE); 135*5542Slinton p->right->op = O_SCON; 136*5542Slinton p->right->sconval = nextarg(ap, char *); 137*5542Slinton break; 138*5542Slinton 139*5542Slinton default: 140*5542Slinton if (op < O_NOP || op > O_LASTOP) { 141*5542Slinton panic("build: bad op %d", op); 142*5542Slinton } 143*5542Slinton break; 144*5542Slinton } 145*5542Slinton p->nodetype = treetype(p, (ARGLIST) &args); 146*5542Slinton return(p); 147*5542Slinton } 148