URI:
       texpr.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       texpr.c (5694B)
       ---
            1 /*
            2  *
            3  *        debugger
            4  *
            5  */
            6 
            7 #include "defs.h"
            8 #include "fns.h"
            9 
           10 static long        dbround(long, long);
           11 
           12 extern        ADDR        ditto;
           13 vlong        expv;
           14 
           15 static WORD
           16 ascval(void)
           17 {
           18         Rune r;
           19 
           20         if (readchar() == 0)
           21                 return (0);
           22         r = lastc;
           23         while(quotchar())        /*discard chars to ending quote */
           24                 ;
           25         return((WORD) r);
           26 }
           27 
           28 /*
           29  * read a floating point number
           30  * the result must fit in a WORD
           31  */
           32 
           33 static WORD
           34 fpin(char *buf)
           35 {
           36         union {
           37                 WORD w;
           38                 float f;
           39         } x;
           40 
           41         x.f = atof(buf);
           42         return (x.w);
           43 }
           44 
           45 WORD
           46 defval(WORD w)
           47 {
           48         if (expr(0))
           49                 return (expv);
           50         else
           51                 return (w);
           52 }
           53 
           54 int
           55 expr(int a)
           56 {        /* term | term dyadic expr |  */
           57         int        rc;
           58         WORD        lhs;
           59 
           60         rdc();
           61         reread();
           62         rc=term(a);
           63         while (rc) {
           64                 lhs = expv;
           65                 switch ((int)readchar()) {
           66 
           67                 case '+':
           68                         term(a|1);
           69                         expv += lhs;
           70                         break;
           71 
           72                 case '-':
           73                         term(a|1);
           74                         expv = lhs - expv;
           75                         break;
           76 
           77                 case '#':
           78                         term(a|1);
           79                         expv = dbround(lhs,expv);
           80                         break;
           81 
           82                 case '*':
           83                         term(a|1);
           84                         expv *= lhs;
           85                         break;
           86 
           87                 case '%':
           88                         term(a|1);
           89                         if(expv != 0)
           90                                 expv = lhs/expv;
           91                         else{
           92                                 if(lhs)
           93                                         expv = 1;
           94                                 else
           95                                         expv = 0;
           96                         }
           97                         break;
           98 
           99                 case '&':
          100                         term(a|1);
          101                         expv &= lhs;
          102                         break;
          103 
          104                 case '|':
          105                         term(a|1);
          106                         expv |= lhs;
          107                         break;
          108 
          109                 case ')':
          110                         if ((a&2)==0)
          111                                 error("unexpected `)'");
          112 
          113                 default:
          114                         reread();
          115                         return(rc);
          116                 }
          117         }
          118         return(rc);
          119 }
          120 
          121 int
          122 term(int a)
          123 {        /* item | monadic item | (expr) | */
          124         u32int u;
          125 
          126         switch ((int)readchar()) {
          127 
          128         case '*':
          129                 term(a|1);
          130                 if (get4(cormap, (ADDR)expv, &u) < 0)
          131                         error("%r");
          132                 expv = u;
          133                 return(1);
          134 
          135         case '@':
          136                 term(a|1);
          137                 if (get4(symmap, (ADDR)expv, &u) < 0)
          138                         error("%r");
          139                 expv = u;
          140                 return(1);
          141 
          142         case '-':
          143                 term(a|1);
          144                 expv = -expv;
          145                 return(1);
          146 
          147         case '~':
          148                 term(a|1);
          149                 expv = ~expv;
          150                 return(1);
          151 
          152         case '(':
          153                 expr(2);
          154                 if (readchar()!=')')
          155                         error("syntax error: `)' expected");
          156                 return(1);
          157 
          158         default:
          159                 reread();
          160                 return(item(a));
          161         }
          162 }
          163 
          164 int
          165 item(int a)
          166 {        /* name [ . local ] | number | . | ^  | <register | 'x | | */
          167         char        *base;
          168         char        savc;
          169         u64int u;
          170         Symbol s;
          171         char gsym[MAXSYM], lsym[MAXSYM];
          172 
          173         readchar();
          174         if (isfileref()) {
          175                 readfname(gsym);
          176                 rdc();                        /* skip white space */
          177                 if (lastc == ':') {        /* it better be */
          178                         rdc();                /* skip white space */
          179                         if (!getnum(readchar))
          180                                 error("bad number");
          181                         if (expv == 0)
          182                                 expv = 1;        /* file begins at line 1 */
          183                         if(file2pc(gsym, expv, &u) < 0)
          184                                 error("%r");
          185                         expv = u;
          186                         return 1;
          187                 }
          188                 error("bad file location");
          189         } else if (symchar(0)) {
          190                 readsym(gsym);
          191                 if (lastc=='.') {
          192                         readchar();        /* ugh */
          193                         if (lastc == '.') {
          194                                 lsym[0] = '.';
          195                                 readchar();
          196                                 readsym(lsym+1);
          197                         } else if (symchar(0)) {
          198                                 readsym(lsym);
          199                         } else
          200                                 lsym[0] = 0;
          201                         if (localaddr(cormap, correg, gsym, lsym, &u) < 0)
          202                                 error("%r");
          203                         expv = u;
          204                 }
          205                 else {
          206                         if (lookupsym(0, gsym, &s) < 0)
          207                                 error("symbol not found");
          208                         if (s.loc.type != LADDR)
          209                                 error("symbol not kept in memory");
          210                         expv = s.loc.addr;
          211                 }
          212                 reread();
          213         } else if (getnum(readchar)) {
          214                 ;
          215         } else if (lastc=='.') {
          216                 readchar();
          217                 if (!symchar(0) && lastc != '.') {
          218                         expv = dot;
          219                 } else {
          220                         if (findsym(locaddr(dbrget(cormap, mach->pc)), CTEXT, &s) < 0)
          221                                 error("no current function");
          222                         if (lastc == '.') {
          223                                 lsym[0] = '.';
          224                                 readchar();
          225                                 readsym(lsym+1);
          226                         } else
          227                                 readsym(lsym);
          228                         if (localaddr(cormap, correg, s.name, lsym, &u) < 0)
          229                                 error("%r");
          230                         expv = u;
          231                 }
          232                 reread();
          233         } else if (lastc=='"') {
          234                 expv=ditto;
          235         } else if (lastc=='+') {
          236                 expv=inkdot(dotinc);
          237         } else if (lastc=='^') {
          238                 expv=inkdot(-dotinc);
          239         } else if (lastc=='<') {
          240                 savc=rdc();
          241                 base = regname(savc);
          242                 expv = dbrget(cormap, base);
          243         }
          244         else if (lastc=='\'')
          245                 expv = ascval();
          246         else if (a)
          247                 error("address expected");
          248         else {
          249                 reread();
          250                 return(0);
          251         }
          252         return(1);
          253 }
          254 
          255 #define        MAXBASE        16
          256 
          257 /* service routines for expression reading */
          258 int
          259 getnum(int (*rdf)(void))
          260 {
          261         char *cp;
          262         int base, d;
          263         BOOL fpnum;
          264         char num[MAXLIN];
          265 
          266         base = 0;
          267         fpnum = FALSE;
          268         if (lastc == '#') {
          269                 base = 16;
          270                 (*rdf)();
          271         }
          272         if (convdig(lastc) >= MAXBASE)
          273                 return (0);
          274         if (lastc == '0')
          275                 switch ((*rdf)()) {
          276                 case 'x':
          277                 case 'X':
          278                         base = 16;
          279                         (*rdf)();
          280                         break;
          281 
          282                 case 't':
          283                 case 'T':
          284                         base = 10;
          285                         (*rdf)();
          286                         break;
          287 
          288                 case 'o':
          289                 case 'O':
          290                         base = 8;
          291                         (*rdf)();
          292                         break;
          293                 default:
          294                         if (base == 0)
          295                                 base = 8;
          296                         break;
          297                 }
          298         if (base == 0)
          299                 base = 10;
          300         expv = 0;
          301         for (cp = num, *cp = lastc; ;(*rdf)()) {
          302                 if ((d = convdig(lastc)) < base) {
          303                         expv *= base;
          304                         expv += d;
          305                         *cp++ = lastc;
          306                 }
          307                 else if (lastc == '.') {
          308                         fpnum = TRUE;
          309                         *cp++ = lastc;
          310                 } else {
          311                         reread();
          312                         break;
          313                 }
          314         }
          315         if (fpnum)
          316                 expv = fpin(num);
          317         return (1);
          318 }
          319 
          320 void
          321 readsym(char *isymbol)
          322 {
          323         char        *p;
          324         Rune r;
          325 
          326         p = isymbol;
          327         do {
          328                 if (p < &isymbol[MAXSYM-UTFmax-1]){
          329                         r = lastc;
          330                         p += runetochar(p, &r);
          331                 }
          332                 readchar();
          333         } while (symchar(1));
          334         *p = 0;
          335 }
          336 
          337 void
          338 readfname(char *filename)
          339 {
          340         char        *p;
          341         Rune        c;
          342 
          343         /* snarf chars until un-escaped char in terminal char set */
          344         p = filename;
          345         do {
          346                 if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1])
          347                         p += runetochar(p, &c);
          348                 readchar();
          349         } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0);
          350         *p = 0;
          351         reread();
          352 }
          353 
          354 int
          355 convdig(int c)
          356 {
          357         if (isdigit(c))
          358                 return(c-'0');
          359         else if (!isxdigit(c))
          360                 return(MAXBASE);
          361         else if (isupper(c))
          362                 return(c-'A'+10);
          363         else
          364                 return(c-'a'+10);
          365 }
          366 
          367 int
          368 symchar(int dig)
          369 {
          370         if (lastc=='\\') {
          371                 readchar();
          372                 return(TRUE);
          373         }
          374         return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));
          375 }
          376 
          377 static long
          378 dbround(long a, long b)
          379 {
          380         long w;
          381 
          382         w = (a/b)*b;
          383         if (a!=w)
          384                 w += b;
          385         return(w);
          386 }
          387 
          388 ulong
          389 dbrget(Map *map, char *name)
          390 {
          391         u64int u;
          392 
          393         USED(map);
          394         if(rget(correg, name, &u) < 0)
          395                 return ~(ulong)0;
          396         return u;
          397 }