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