diff --git a/src/cmd/db/expr.c b/src/cmd/db/expr.c
new file mode 100644
index 0000000..8d33e7f
--- /dev/null
+++ b/src/cmd/db/expr.c
@@ -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;
+}
