Skip to content

Commit 0135d12

Browse files
committed
Merge branch 'master' of https://github.com/yesco/esp-lisp
2 parents 9796dd9 + 72de03a commit 0135d12

File tree

1 file changed

+113
-28
lines changed

1 file changed

+113
-28
lines changed

lisp.c

Lines changed: 113 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,12 @@
167167
void gc_conses();
168168
int kbhit();
169169
static inline lisp callfunc(lisp f, lisp args, lisp* envp, lisp e, int noeval);
170+
int lispreadchar(char *chp);
171+
172+
PRIM breakpoint();
170173
void error(char* msg);
174+
static inline int tracep(lisp f);
175+
171176
void run(char* s, lisp* envp);
172177

173178
PRIM fundef(lisp f);
@@ -1024,13 +1029,19 @@ PRIM evallist(lisp e, lisp* envp) {
10241029
return r;
10251030
}
10261031

1027-
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+
10281039

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

10321043
PRIM primapply(lisp ff, lisp args, lisp* envp, lisp all, int noeval) {
1033-
//printf("PRIMAPPLY "); princ(ff); princ(args); terpri();
1044+
//printf("PRIMAPPLY "); princ(ff); putchar(' '); princ(args); putchar(' '); princ(*envp); terpri();
10341045
int n = GETPRIMNUM(ff);
10351046
lisp (*e)(lisp x, lisp* envp) = (noeval && n > 0) ? noEval : evalGC;
10361047
int an = abs(n);
@@ -1799,7 +1810,7 @@ PRIM with_putc(lisp* envp, lisp args) {
17991810
int myputc(int c) {
18001811
recurse++;
18011812
if (recurse > 1) error("with-putc called with function that calls putc - prohibited!");
1802-
lisp r= callfunc(fn, cons(mkint(c), nil), envp, nil, 1);
1813+
lisp r = callfunc(fn, cons(mkint(c), nil), envp, nil, 1);
18031814
recurse--;
18041815
return getint(r);
18051816
}
@@ -2118,7 +2129,12 @@ static inline lisp eval_hlp(lisp e, lisp* envp) {
21182129
}
21192130

21202131
// This may return a immediate, this allows tail recursion evalGC will reduce it.
2132+
2133+
stack[level].e = f;
2134+
stack[level].envp = envp;
21212135
lisp r = callfunc(f, cdr(e), envp, e, 0);
2136+
stack[level].e = nil;
2137+
stack[level].envp = nil;
21222138

21232139
// we replace it after as no error was generated...
21242140
if (f != orig) {
@@ -2203,25 +2219,20 @@ int needGC();
22032219
// #772 0x08052d58 in readeval ()
22042220
// #773 0x08048b57 in main ()
22052221

2206-
#define MAX_STACK 80
2207-
2208-
static struct stack {
2209-
lisp e;
2210-
lisp* envp;
2211-
} stack[MAX_STACK];
2212-
22132222
// TODO: because of tail call optimization, we can't tell where the error occurred as it's not relevant on the stack???
2214-
PRIM print_detailed_stack() {
2223+
PRIM print_detailed_stack(int curr) {
22152224
int l;
22162225
// TODO: DONE but too much: using fargs of f can use .envp to print actual arguments!
22172226
for(l = 0; l < level + 5; l++) {
22182227
if (!stack[l].e && !stack[l].envp) break;
22192228

22202229
if (!l) terpri();
2230+
if (curr && l == curr-1) printf("==>");
22212231
printf("%4d : ", l);
2222-
prin1(stack[l].e); printf(" ==> ");
2232+
prin1(stack[l].e); printf(" ENV: ");
22232233

22242234
lisp f = car(stack[l].e);
2235+
if (!f) f = stack[l].e;
22252236
lisp* envp = stack[l].envp;
22262237
lisp env = envp ? *envp : nil; // env before
22272238
while (f && IS(f, symboll) && !IS(f, func) && !IS(f, thunk) && !IS(f, prim) && !IS(f, immediate)) {
@@ -2250,7 +2261,7 @@ PRIM print_detailed_stack() {
22502261
printf(" ... ] ");
22512262
} else {
22522263
printf(" ... ] ");
2253-
printf(" ...car did not evaluate to a function... (it's an %s)\n", f ? tag_name[TAG(f)] : "nil");
2264+
printf(" ...car did not evaluate to a function... (it's %s)\n", f ? tag_name[TAG(f)] : "nil");
22542265
break;
22552266
}
22562267
terpri();
@@ -2597,7 +2608,7 @@ PRIM load(lisp* envp, lisp name, lisp verbosity) {
25972608

25982609
// no gcc style innner functions with outer variables.. .:-(
25992610
int evalIt(void* p, char* s, char* filename, int startno, int endno, int v) {
2600-
if (!s || !s[0] || s[0] == ';') return;
2611+
if (!s || !s[0] || s[0] == ';') return 0;
26012612
if (v > 1) printf("\n========================= %s :%d-%d>\n%s\n", filename, startno, endno, s);
26022613
lisp* envp = p;
26032614
jmp_buf saved;
@@ -3422,7 +3433,21 @@ lisp lisp_init() {
34223433
// http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-user/Command_002dLine-Debugger.html#Command_002dLine-Debugger
34233434
// TODO: set-trace! set-break! http://www.lilypond.org/doc/v2.19/Documentation/contributor/debugging-scheme-code
34243435
DEFPRIM(pstack, 0, print_detailed_stack);
3425-
3436+
DEFPRIM(break, 0, breakpoint);
3437+
// unbound: foo
3438+
// (restart 3) ask and return other value
3439+
// (restart 2) ask for value and set it
3440+
// (restart 1) return to top-level
3441+
// (bkpt datum arg...) breakpoint
3442+
// (pa) print actual arguments
3443+
// (apropos "str") list matching functions
3444+
// (where) one letter command loop
3445+
// u(p) d(own) g(o)N
3446+
// (continue)
3447+
// (break) (break func)
3448+
// *proc* *args* *result*
3449+
// Single stepping: e(val), RETURN, d(ebug)
3450+
34263451
// flash stuff - experimental
34273452
DEFPRIM(flash, 2, flash);
34283453
DEFPRIM(flashit, 1, flashit);
@@ -3474,6 +3499,10 @@ void help(lisp* envp) {
34743499
printf("Type 'help' to get this message again\n");
34753500
}
34763501

3502+
PRIM breakpoint() {
3503+
error(NULL);
3504+
return nil;
3505+
}
34773506
// TODO: make it take one lisp parameter?
34783507
// TODO: https://groups.csail.mit.edu/mac/ftpdir/scheme-7.4/doc-html/scheme_17.html#SEC153
34793508
void error(char* msg) {
@@ -3482,29 +3511,80 @@ void error(char* msg) {
34823511

34833512
// restore output to stdout, if error inside print function we're screwed otherwise!
34843513
writeputc = origputc;
3485-
34863514
terpri();
3515+
3516+
// make sure that we don't blow the stack if we get error in the error function!
34873517
if (error_level == 0) {
34883518
error_level++;
3489-
if (level) { printf("%%%s\nBacktrace: ", msg); print_stack(); terpri(); }
3490-
print_detailed_stack();
3491-
printf("%s -- see above!\n", msg);
3519+
if (!msg) { // breakpoint
3520+
int elsave = error_level; error_level = 0;
3521+
print_stack(); terpri();
3522+
int l = level > 0 ? level : 0;
3523+
void print_env(int d) {
3524+
l += d;
3525+
if (l < 0) l = 0;
3526+
if (!stack[l].envp) l -= d;
3527+
printf(" STACK: "); print_stack(); terpri();
3528+
printf("CURRENT: "); prin1(stack[l].e); terpri();
3529+
if (stack[l].envp) {
3530+
printf(" ENV: ");
3531+
prin1(_env(stack[l].envp, nil)); terpri();
3532+
}
3533+
}
3534+
print(stack[l].e); terpri();
3535+
char* ln = NULL;
3536+
while (1) {
3537+
if (ln) free(ln);
3538+
printf("debug %d] ", l-1); fflush(stdout);
3539+
char* ln = readline_int("", READLINE_MAXLEN, lispreadchar);
3540+
printf("---------\n");
3541+
if (!ln) break;
3542+
if (!strcmp(ln, "q")) break;
3543+
if (!strcmp(ln, "h") || !strcmp(ln, "?")) {
3544+
printf("Debug help: q(uit) h(elp) p(rint env) u(p) d(own) b(ack)t(race) EXPR\n");
3545+
continue;
3546+
}
3547+
if (!strcmp(ln, "p")) { print_env(0); continue; }
3548+
if (!strcmp(ln, "u")) { print_env(-1); continue; }
3549+
if (!strcmp(ln, "d")) { print_env(+1); continue; }
3550+
if (!strcmp(ln, "bt")) { print_detailed_stack(l); continue; }
3551+
lisp r = reads(ln);
3552+
jmp_buf save;
3553+
memcpy(save, lisp_break, sizeof(save));
3554+
if (setjmp(lisp_break) == 0) {
3555+
// continue deeper on the stack
3556+
level++;
3557+
prin1(evalGC(r, stack[l].envp)); terpri();
3558+
level--;
3559+
} else {
3560+
// TODO() if any error above (like aslfkjasdf) it'll mess up the stack?
3561+
printf("\n%%back....from error/break\n");
3562+
memcpy(lisp_break, save, sizeof(save));
3563+
}
3564+
}
3565+
if (ln) free(ln);
3566+
error_level = elsave;
3567+
} else {
3568+
if (level) { printf("%%%s\nBacktrace: ", msg); print_stack(); terpri(); }
3569+
print_detailed_stack(0);
3570+
printf("%s!\n", msg);
3571+
}
34923572
error_level--;
34933573
} else {
34943574
error_level = 0;
34953575
printf("%% error(): error inside error... recovering...\n");
34963576
}
34973577

34983578
if (memcmp(lisp_break, empty, sizeof(empty))) { // contains valid value
3499-
// reset stack
3500-
level = 0;
3501-
stack[0].e = nil;
3502-
stack[0].envp = NULL;
3503-
3579+
// Don't reset stack here, where we return could possibly where
3580+
// TODO: reset stack - cleanup? this doesn't handle recursive errors/debug
3581+
// level = 0;
3582+
// stack[0].e = nil;
3583+
// stack[0].envp = NULL;
35043584
longjmp(lisp_break, 1);
35053585
// does not continue!
35063586
} else {
3507-
printf("%%%% error(): NOT inside setjmp, continuing, ...possibly bad\n");
3587+
//printf("%% At toplevel\n");
35083588
// exit(77);
35093589
}
35103590
}
@@ -3522,7 +3602,9 @@ void run(char* s, lisp* envp) {
35223602
blockGC = 0;
35233603
level = 0;
35243604
trace_level = 0;
3525-
printf("%%%% type 'help' to get help\n");
3605+
stack[0].e = nil;
3606+
stack[0].envp = NULL;
3607+
printf("\n%%%% type 'help' to get help\n");
35263608
}
35273609
// disable longjmp
35283610
memset(lisp_break, 0, sizeof(lisp_break));
@@ -3612,7 +3694,7 @@ int kbhit() {
36123694

36133695
int ms = clock_ms();
36143696
int update = 0;
3615-
// update every s
3697+
// update every s for printing status
36163698
if (ms - last_ms > 1000) {
36173699
int tms = (lisp_ticks - last_ticks) / (ms - last_ms);
36183700
if (tms > max_ticks_per_ms) max_ticks_per_ms = tms;
@@ -3632,6 +3714,8 @@ int kbhit() {
36323714
if (thechar == 'C'-64) {
36333715
int c = thechar;
36343716
thechar = 0;
3717+
printf("^C\n");
3718+
// This will longjmp back if there is is a stack
36353719
error("CTRL-C");
36363720
// error only returns if couln't longjmp to setjmp position, so keep the ctrl-c
36373721
thechar = c;
@@ -3668,6 +3752,7 @@ void readeval(lisp* envp) {
36683752
char* ln = readline_int("lisp> ", READLINE_MAXLEN, lispreadchar);
36693753
global_envp = NULL;
36703754

3755+
// TODO: get rid of special unquoted commands at toplevel?
36713756
if (!ln) {
36723757
break;
36733758
} else if (strncmp(ln, ";", 1) == 0) {
@@ -3726,7 +3811,7 @@ void readeval(lisp* envp) {
37263811
free(ln);
37273812
}
37283813

3729-
printf("OK, bye!\n");
3814+
printf("^D\nOK, bye!\n");
37303815
}
37313816

37323817
void treads(char* s) {

0 commit comments

Comments
 (0)