Skip to content

Commit 72de03a

Browse files
committed
improve debugger
- when executing update the stack with current expression - it'll show better in the stack where you are when break - show position in stacktrace - print current state using 'p' - inc level before evalGC... - can handle break inside break - clean stack after longjmp
1 parent 7560e84 commit 72de03a

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

lisp.c

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ int lispreadchar(char *chp);
171171

172172
PRIM breakpoint();
173173
void error(char* msg);
174+
static inline int tracep(lisp f);
174175

175176
void run(char* s, lisp* envp);
176177

@@ -1028,13 +1029,19 @@ PRIM evallist(lisp e, lisp* envp) {
10281029
return r;
10291030
}
10301031

1031-
static inline int tracep(lisp f);
1032+
#define MAX_STACK 80
1033+
1034+
static struct stack {
1035+
lisp e;
1036+
lisp* envp;
1037+
} stack[MAX_STACK];
1038+
10321039

10331040
// dummy function that doesn't eval, used instead of eval
10341041
static PRIM noEval(lisp x, lisp* envp) { return x; }
10351042

10361043
PRIM primapply(lisp ff, lisp args, lisp* envp, lisp all, int noeval) {
1037-
//printf("PRIMAPPLY "); princ(ff); princ(args); terpri();
1044+
//printf("PRIMAPPLY "); princ(ff); putchar(' '); princ(args); putchar(' '); princ(*envp); terpri();
10381045
int n = GETPRIMNUM(ff);
10391046
lisp (*e)(lisp x, lisp* envp) = (noeval && n > 0) ? noEval : evalGC;
10401047
int an = abs(n);
@@ -2123,7 +2130,12 @@ static inline lisp eval_hlp(lisp e, lisp* envp) {
21232130
}
21242131

21252132
// This may return a immediate, this allows tail recursion evalGC will reduce it.
2133+
2134+
stack[level].e = f;
2135+
stack[level].envp = envp;
21262136
lisp r = callfunc(f, cdr(e), envp, e, 0);
2137+
stack[level].e = nil;
2138+
stack[level].envp = nil;
21272139

21282140
// we replace it after as no error was generated...
21292141
if (f != orig) {
@@ -2208,25 +2220,20 @@ int needGC();
22082220
// #772 0x08052d58 in readeval ()
22092221
// #773 0x08048b57 in main ()
22102222

2211-
#define MAX_STACK 80
2212-
2213-
static struct stack {
2214-
lisp e;
2215-
lisp* envp;
2216-
} stack[MAX_STACK];
2217-
22182223
// TODO: because of tail call optimization, we can't tell where the error occurred as it's not relevant on the stack???
2219-
PRIM print_detailed_stack() {
2224+
PRIM print_detailed_stack(int curr) {
22202225
int l;
22212226
// TODO: DONE but too much: using fargs of f can use .envp to print actual arguments!
22222227
for(l = 0; l < level + 5; l++) {
22232228
if (!stack[l].e && !stack[l].envp) break;
22242229

22252230
if (!l) terpri();
2231+
if (curr && l == curr-1) printf("==>");
22262232
printf("%4d : ", l);
2227-
prin1(stack[l].e); printf(" ==> ");
2233+
prin1(stack[l].e); printf(" ENV: ");
22282234

22292235
lisp f = car(stack[l].e);
2236+
if (!f) f = stack[l].e;
22302237
lisp* envp = stack[l].envp;
22312238
lisp env = envp ? *envp : nil; // env before
22322239
while (f && IS(f, symboll) && !IS(f, func) && !IS(f, thunk) && !IS(f, prim) && !IS(f, immediate)) {
@@ -2255,7 +2262,7 @@ PRIM print_detailed_stack() {
22552262
printf(" ... ] ");
22562263
} else {
22572264
printf(" ... ] ");
2258-
printf(" ...car did not evaluate to a function... (it's an %s)\n", f ? tag_name[TAG(f)] : "nil");
2265+
printf(" ...car did not evaluate to a function... (it's %s)\n", f ? tag_name[TAG(f)] : "nil");
22592266
break;
22602267
}
22612268
terpri();
@@ -3513,31 +3520,43 @@ void error(char* msg) {
35133520
if (!msg) { // breakpoint
35143521
int elsave = error_level; error_level = 0;
35153522
print_stack(); terpri();
3516-
int l = level > 0 ? level - 1 : 0;
3523+
int l = level > 0 ? level : 0;
35173524
void print_env(int d) {
35183525
l += d;
35193526
if (l < 0) l = 0;
35203527
if (!stack[l].envp) l -= d;
3521-
if (stack[l].envp) print(_env(stack[l].envp, nil)); terpri();
3528+
printf(" STACK: "); print_stack(); terpri();
3529+
printf("CURRENT: "); prin1(stack[l].e); terpri();
3530+
if (stack[l].envp) {
3531+
printf(" ENV: ");
3532+
prin1(_env(stack[l].envp, nil)); terpri();
3533+
}
35223534
}
35233535
print(stack[l].e); terpri();
35243536
char* ln = NULL;
35253537
while (1) {
35263538
if (ln) free(ln);
3527-
printf("debug %d] ", l - 1); fflush(stdout);
3539+
printf("debug %d] ", l-1); fflush(stdout);
35283540
char* ln = readline_int("", READLINE_MAXLEN, lispreadchar);
3541+
printf("---------\n");
35293542
if (!ln) break;
35303543
if (!strcmp(ln, "q")) break;
3531-
if (!strcmp(ln, "e")) { print_env(0); continue; }
3544+
if (!strcmp(ln, "h") || !strcmp(ln, "?")) {
3545+
printf("Debug help: q(uit) h(elp) p(rint env) u(p) d(own) b(ack)t(race) EXPR\n");
3546+
continue;
3547+
}
3548+
if (!strcmp(ln, "p")) { print_env(0); continue; }
35323549
if (!strcmp(ln, "u")) { print_env(-1); continue; }
35333550
if (!strcmp(ln, "d")) { print_env(+1); continue; }
3534-
if (!strcmp(ln, "bt")) { print_detailed_stack(); continue; }
3551+
if (!strcmp(ln, "bt")) { print_detailed_stack(l); continue; }
35353552
lisp r = reads(ln);
35363553
jmp_buf save;
35373554
memcpy(save, lisp_break, sizeof(save));
35383555
if (setjmp(lisp_break) == 0) {
3539-
// TODO(jsk): this zeroes level/trace_level
3556+
// continue deeper on the stack
3557+
level++;
35403558
prin1(evalGC(r, stack[l].envp)); terpri();
3559+
level--;
35413560
} else {
35423561
// TODO() if any error above (like aslfkjasdf) it'll mess up the stack?
35433562
printf("\n%%back....from error/break\n");
@@ -3548,7 +3567,7 @@ void error(char* msg) {
35483567
error_level = elsave;
35493568
} else {
35503569
if (level) { printf("%%%s\nBacktrace: ", msg); print_stack(); terpri(); }
3551-
print_detailed_stack();
3570+
print_detailed_stack(0);
35523571
printf("%s!\n", msg);
35533572
}
35543573
error_level--;
@@ -3584,6 +3603,8 @@ void run(char* s, lisp* envp) {
35843603
blockGC = 0;
35853604
level = 0;
35863605
trace_level = 0;
3606+
stack[0].e = nil;
3607+
stack[0].envp = NULL;
35873608
printf("\n%%%% type 'help' to get help\n");
35883609
}
35893610
// disable longjmp

0 commit comments

Comments
 (0)