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