123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /*
- *
- * debugger
- *
- */
- #include "defs.h"
- #include "fns.h"
- static long round(long, long);
- extern ADDR ditto;
- uvlong expv;
- static WORD
- ascval(void)
- {
- Rune r;
- if (readchar() == 0)
- return (0);
- r = lastc;
- while(quotchar()) /*discard chars to ending quote */
- ;
- return((WORD) r);
- }
- /*
- * read a floating point number
- * the result must fit in a WORD
- */
- static WORD
- fpin(char *buf)
- {
- union {
- WORD w;
- float f;
- } x;
- x.f = atof(buf);
- return (x.w);
- }
- WORD
- defval(WORD w)
- {
- if (expr(0))
- return (expv);
- else
- return (w);
- }
- expr(int a)
- { /* term | term dyadic expr | */
- int rc;
- WORD lhs;
- rdc();
- reread();
- rc=term(a);
- while (rc) {
- lhs = expv;
- switch ((int)readchar()) {
- case '+':
- term(a|1);
- expv += lhs;
- break;
- case '-':
- term(a|1);
- expv = lhs - expv;
- break;
- case '#':
- term(a|1);
- expv = round(lhs,expv);
- break;
- case '*':
- term(a|1);
- expv *= lhs;
- break;
- case '%':
- term(a|1);
- if(expv != 0)
- expv = lhs/expv;
- else{
- if(lhs)
- expv = 1;
- else
- expv = 0;
- }
- break;
- case '&':
- term(a|1);
- expv &= lhs;
- break;
- case '|':
- term(a|1);
- expv |= lhs;
- break;
- case ')':
- if ((a&2)==0)
- error("unexpected `)'");
- default:
- reread();
- return(rc);
- }
- }
- return(rc);
- }
- term(int a)
- { /* item | monadic item | (expr) | */
- ADDR e;
- switch ((int)readchar()) {
- case '*':
- term(a|1);
- if (geta(cormap, expv, &e) < 0)
- error("%r");
- expv = e;
- return(1);
- case '@':
- term(a|1);
- if (geta(symmap, expv, &e) < 0)
- error("%r");
- expv = e;
- return(1);
- case '-':
- term(a|1);
- expv = -expv;
- return(1);
- case '~':
- term(a|1);
- expv = ~expv;
- return(1);
- case '(':
- expr(2);
- if (readchar()!=')')
- error("syntax error: `)' expected");
- return(1);
- default:
- reread();
- return(item(a));
- }
- }
- item(int a)
- { /* name [ . local ] | number | . | ^ | <register | 'x | | */
- char *base;
- char savc;
- uvlong e;
- Symbol s;
- char gsym[MAXSYM], lsym[MAXSYM];
- readchar();
- if (isfileref()) {
- readfname(gsym);
- rdc(); /* skip white space */
- if (lastc == ':') { /* it better be */
- rdc(); /* skip white space */
- if (!getnum(readchar))
- error("bad number");
- if (expv == 0)
- expv = 1; /* file begins at line 1 */
- expv = file2pc(gsym, expv);
- if (expv == -1)
- error("%r");
- return 1;
- }
- error("bad file location");
- } else if (symchar(0)) {
- readsym(gsym);
- if (lastc=='.') {
- readchar(); /* ugh */
- if (lastc == '.') {
- lsym[0] = '.';
- readchar();
- readsym(lsym+1);
- } else if (symchar(0)) {
- readsym(lsym);
- } else
- lsym[0] = 0;
- if (localaddr(cormap, gsym, lsym, &e, rget) < 0)
- error("%r");
- expv = e;
- }
- else {
- if (lookup(0, gsym, &s) == 0)
- error("symbol not found");
- expv = s.value;
- }
- reread();
- } else if (getnum(readchar)) {
- ;
- } else if (lastc=='.') {
- readchar();
- if (!symchar(0) && lastc != '.') {
- expv = dot;
- } else {
- if (findsym(rget(cormap, mach->pc), CTEXT, &s) == 0)
- error("no current function");
- if (lastc == '.') {
- lsym[0] = '.';
- readchar();
- readsym(lsym+1);
- } else
- readsym(lsym);
- if (localaddr(cormap, s.name, lsym, &e, rget) < 0)
- error("%r");
- expv = e;
- }
- reread();
- } else if (lastc=='"') {
- expv=ditto;
- } else if (lastc=='+') {
- expv=inkdot(dotinc);
- } else if (lastc=='^') {
- expv=inkdot(-dotinc);
- } else if (lastc=='<') {
- savc=rdc();
- base = regname(savc);
- expv = rget(cormap, base);
- }
- else if (lastc=='\'')
- expv = ascval();
- else if (a)
- error("address expected");
- else {
- reread();
- return(0);
- }
- return(1);
- }
- #define MAXBASE 16
- /* service routines for expression reading */
- getnum(int (*rdf)(void))
- {
- char *cp;
- int base, d;
- BOOL fpnum;
- char num[MAXLIN];
- base = 0;
- fpnum = FALSE;
- if (lastc == '#') {
- base = 16;
- (*rdf)();
- }
- if (convdig(lastc) >= MAXBASE)
- return (0);
- if (lastc == '0')
- switch ((*rdf)()) {
- case 'x':
- case 'X':
- base = 16;
- (*rdf)();
- break;
- case 't':
- case 'T':
- base = 10;
- (*rdf)();
- break;
- case 'o':
- case 'O':
- base = 8;
- (*rdf)();
- break;
- default:
- if (base == 0)
- base = 8;
- break;
- }
- if (base == 0)
- base = 10;
- expv = 0;
- for (cp = num, *cp = lastc; ;(*rdf)()) {
- if ((d = convdig(lastc)) < base) {
- expv *= base;
- expv += d;
- *cp++ = lastc;
- }
- else if (lastc == '.') {
- fpnum = TRUE;
- *cp++ = lastc;
- } else {
- reread();
- break;
- }
- }
- if (fpnum)
- expv = fpin(num);
- return (1);
- }
- void
- readsym(char *isymbol)
- {
- char *p;
- Rune r;
- p = isymbol;
- do {
- if (p < &isymbol[MAXSYM-UTFmax-1]){
- r = lastc;
- p += runetochar(p, &r);
- }
- readchar();
- } while (symchar(1));
- *p = 0;
- }
- void
- readfname(char *filename)
- {
- char *p;
- Rune c;
- /* snarf chars until un-escaped char in terminal char set */
- p = filename;
- do {
- if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1])
- p += runetochar(p, &c);
- readchar();
- } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0);
- *p = 0;
- reread();
- }
- convdig(int c)
- {
- if (isdigit(c))
- return(c-'0');
- else if (!isxdigit(c))
- return(MAXBASE);
- else if (isupper(c))
- return(c-'A'+10);
- else
- return(c-'a'+10);
- }
- symchar(int dig)
- {
- if (lastc=='\\') {
- readchar();
- return(TRUE);
- }
- return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));
- }
- static long
- round(long a, long b)
- {
- long w;
- w = (a/b)*b;
- if (a!=w)
- w += b;
- return(w);
- }
|