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