debugger
This commit is contained in:
parent
a84cbb2a17
commit
84114f0665
15 changed files with 3179 additions and 0 deletions
397
src/cmd/db/expr.c
Normal file
397
src/cmd/db/expr.c
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
/*
|
||||
*
|
||||
* debugger
|
||||
*
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include "fns.h"
|
||||
|
||||
static long dbround(long, long);
|
||||
|
||||
extern ADDR ditto;
|
||||
vlong 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);
|
||||
}
|
||||
|
||||
int
|
||||
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 = dbround(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);
|
||||
}
|
||||
|
||||
int
|
||||
term(int a)
|
||||
{ /* item | monadic item | (expr) | */
|
||||
u32int u;
|
||||
|
||||
switch ((int)readchar()) {
|
||||
|
||||
case '*':
|
||||
term(a|1);
|
||||
if (get4(cormap, (ADDR)expv, &u) < 0)
|
||||
error("%r");
|
||||
expv = u;
|
||||
return(1);
|
||||
|
||||
case '@':
|
||||
term(a|1);
|
||||
if (get4(symmap, (ADDR)expv, &u) < 0)
|
||||
error("%r");
|
||||
expv = u;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
item(int a)
|
||||
{ /* name [ . local ] | number | . | ^ | <register | 'x | | */
|
||||
char *base;
|
||||
char savc;
|
||||
ulong u;
|
||||
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 */
|
||||
if(file2pc(gsym, expv, &u) < 0)
|
||||
error("%r");
|
||||
expv = u;
|
||||
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, correg, gsym, lsym, &u) < 0)
|
||||
error("%r");
|
||||
expv = u;
|
||||
}
|
||||
else {
|
||||
if (lookupsym(0, gsym, &s) < 0)
|
||||
error("symbol not found");
|
||||
if (s.loc.type != LADDR)
|
||||
error("symbol not kept in memory");
|
||||
expv = s.loc.addr;
|
||||
}
|
||||
reread();
|
||||
} else if (getnum(readchar)) {
|
||||
;
|
||||
} else if (lastc=='.') {
|
||||
readchar();
|
||||
if (!symchar(0) && lastc != '.') {
|
||||
expv = dot;
|
||||
} else {
|
||||
if (findsym(locaddr(dbrget(cormap, mach->pc)), CTEXT, &s) < 0)
|
||||
error("no current function");
|
||||
if (lastc == '.') {
|
||||
lsym[0] = '.';
|
||||
readchar();
|
||||
readsym(lsym+1);
|
||||
} else
|
||||
readsym(lsym);
|
||||
if (localaddr(cormap, correg, s.name, lsym, &u) < 0)
|
||||
error("%r");
|
||||
expv = u;
|
||||
}
|
||||
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 = dbrget(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 */
|
||||
int
|
||||
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();
|
||||
}
|
||||
|
||||
int
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
symchar(int dig)
|
||||
{
|
||||
if (lastc=='\\') {
|
||||
readchar();
|
||||
return(TRUE);
|
||||
}
|
||||
return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));
|
||||
}
|
||||
|
||||
static long
|
||||
dbround(long a, long b)
|
||||
{
|
||||
long w;
|
||||
|
||||
w = (a/b)*b;
|
||||
if (a!=w)
|
||||
w += b;
|
||||
return(w);
|
||||
}
|
||||
|
||||
ulong
|
||||
dbrget(Map *map, char *name)
|
||||
{
|
||||
ulong u;
|
||||
|
||||
USED(map);
|
||||
if(rget(correg, name, &u) < 0)
|
||||
return ~(ulong)0;
|
||||
return u;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue