1 # 2 /* 3 * 4 * UNIX debugger 5 * 6 */ 7 8 #include "defs.h" 9 static char sccsid[] = "@(#)expr.c 4.6 05/03/83"; 10 11 MSG BADSYM; 12 MSG BADVAR; 13 MSG BADKET; 14 MSG BADSYN; 15 MSG NOCFN; 16 MSG NOADR; 17 MSG BADLOC; 18 19 ADDR lastframe; 20 ADDR savlastf; 21 ADDR savframe; 22 ADDR savpc; 23 ADDR callpc; 24 25 26 27 CHAR *lp; 28 INT radix; 29 STRING errflg; 30 L_INT localval; 31 CHAR isymbol[1024]; 32 33 CHAR lastc,peekc; 34 35 L_INT dot; 36 L_INT ditto; 37 INT dotinc; 38 L_INT var[]; 39 L_INT expv; 40 41 42 43 44 expr(a) 45 { /* term | term dyadic expr | */ 46 INT rc; 47 L_INT lhs; 48 49 rdc(); lp--; rc=term(a); 50 51 WHILE rc 52 DO lhs = expv; 53 54 switch ((int)readchar()) { 55 56 case '+': 57 term(a|1); expv += lhs; break; 58 59 case '-': 60 term(a|1); expv = lhs - expv; break; 61 62 case '#': 63 term(a|1); expv = round(lhs,expv); break; 64 65 case '*': 66 term(a|1); expv *= lhs; break; 67 68 case '%': 69 term(a|1); expv = lhs/expv; break; 70 71 case '&': 72 term(a|1); expv &= lhs; break; 73 74 case '|': 75 term(a|1); expv |= lhs; break; 76 77 case ')': 78 IF (a&2)==0 THEN error(BADKET); FI 79 80 default: 81 lp--; 82 return(rc); 83 } 84 OD 85 return(rc); 86 } 87 88 term(a) 89 { /* item | monadic item | (expr) | */ 90 91 switch ((int)readchar()) { 92 93 case '*': 94 term(a|1); expv=chkget(expv,DSP); return(1); 95 96 case '@': 97 term(a|1); expv=chkget(expv,ISP); return(1); 98 99 case '-': 100 term(a|1); expv = -expv; return(1); 101 102 case '~': 103 104 ELIF getnum(readchar) 105 THEN ; 106 ELIF lastc=='.' 107 THEN readchar(); 108 IF symchar(0) 109 THEN lastframe=savlastf; callpc=savpc; 110 chkloc(savframe); 111 ELSE expv=dot; 112 FI 113 lp--; 114 115 ELIF lastc=='"' 116 THEN expv=ditto; 117 118 ELIF lastc=='+' 119 THEN expv=inkdot(dotinc); 120 121 ELIF lastc=='^' 122 THEN expv=inkdot(-dotinc); 123 124 ELIF lastc=='<' 125 THEN savc=rdc(); 126 IF regptr=getreg(savc) 127 THEN IF kcore THEN expv = *(int *)regptr; 128 ELSE expv= * (ADDR *)(((ADDR)&u)+regptr); FI 129 ELIF (base=varchk(savc)) != -1 130 THEN expv=var[base]; 131 ELSE error(BADVAR); 132 FI 133 134 ELIF lastc=='\'' 135 THEN d=4; expv=0; 136 WHILE quotchar() 137 DO IF d-- 138 THEN expv = (expv << 8) | lastc; 139 ELSE error(BADSYN); 140 FI 141 OD 142 143 ELIF a 144 THEN error(NOADR); 145 ELSE lp--; return(0); 146 FI 147 return(1); 148 } 149 150 /* service routines for expression reading */ 151 getnum(rdf) int (*rdf)(); 152 { 153 INT base,d,frpt; 154 BOOL hex; 155 UNION{REAL r; L_INT i;} real; 156 IF isdigit(lastc) ORF (hex=TRUE, lastc=='#' ANDF isxdigit((*rdf)())) 157 THEN expv = 0; 158 base = (hex ? 16 : radix); 159 WHILE (base>10 ? isxdigit(lastc) : isdigit(lastc)) 160 DO expv = (base==16 ? expv<<4 : expv*base); 161 IF (d=convdig(lastc))>=base THEN error(BADSYN); FI 162 expv += d; (*rdf)(); 163 IF expv==0 164 THEN IF (lastc=='x' ORF lastc=='X') 165 THEN hex=TRUE; base=16; (*rdf)(); 166 ELIF (lastc=='t' ORF lastc=='T') 167 THEN hex=FALSE; base=10; (*rdf)(); 168 ELIF (lastc=='o' ORF lastc=='O') 169 THEN hex=FALSE; base=8; (*rdf)(); 170 FI 171 FI 172 OD 173 IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex 174 THEN real.r=expv; frpt=0; base=10; 175 WHILE isdigit((*rdf)()) 176 DO real.r *= base; frpt++; 177 real.r += lastc-'0'; 178 OD 179 WHILE frpt-- 180 DO real.r /= base; OD 181 expv = real.i; 182 FI 183 peekc=lastc; 184 /* lp--; */ 185 return(1); 186 ELSE return(0); 187 FI 188 } 189 190 readsym() 191 { 192 REG char *p; 193 194 p = isymbol; 195 REP IF p < &isymbol[sizeof(isymbol)-1] 196 THEN *p++ = lastc; 197 FI 198 readchar(); 199 PER symchar(1) DONE 200 *p++ = 0; 201 } 202 203 convdig(c) 204 CHAR c; 205 { 206 IF isdigit(c) 207 THEN return(c-'0'); 208 ELIF isxdigit(c) 209 THEN return(c-'a'+10); 210 ELSE return(17); 211 FI 212 } 213 214 symchar(dig) 215 { 216 IF lastc=='\\' THEN readchar(); return(TRUE); FI 217 return( isalpha(lastc) ORF lastc=='_' ORF dig ANDF isdigit(lastc) ); 218 } 219 220 varchk(name) 221 { 222 IF isdigit(name) THEN return(name-'0'); FI 223 IF isalpha(name) THEN return((name&037)-1+10); FI 224 return(-1); 225 } 226 227 chkloc(frame) 228 L_INT frame; 229 { 230 readsym(); 231 REP IF localsym(frame)==0 THEN error(BADLOC); FI 232 expv=localval; 233 PER !eqsym(cursym->n_un.n_name,isymbol,'~') DONE 234 } 235 236 eqsym(s1, s2, c) 237 register char *s1, *s2; 238 { 239 240 if (!strcmp(s1,s2)) 241 return (1); 242 if (*s1 == c && !strcmp(s1+1, s2)) 243 return (1); 244 return (0); 245 } 246