ba13583433af303e5321870b42686b534cca8945
[fw/altos] / src / lisp / ao_lisp_error.c
1 /*
2  * Copyright © 2016 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  */
14
15 #include "ao_lisp.h"
16 #include <stdarg.h>
17
18 void
19 ao_lisp_error_poly(char *name, ao_poly poly, ao_poly last)
20 {
21         int first = 1;
22         printf("\t\t%s(", name);
23         if (ao_lisp_poly_type(poly) == AO_LISP_CONS) {
24                 if (poly) {
25                         while (poly) {
26                                 struct ao_lisp_cons *cons = ao_lisp_poly_cons(poly);
27                                 if (!first)
28                                         printf("\t\t         ");
29                                 else
30                                         first = 0;
31                                 ao_lisp_poly_write(cons->car);
32                                 printf("\n");
33                                 if (poly == last)
34                                         break;
35                                 poly = cons->cdr;
36                         }
37                         printf("\t\t         )\n");
38                 } else
39                         printf(")\n");
40         } else {
41                 ao_lisp_poly_write(poly);
42                 printf("\n");
43         }
44 }
45
46 static void tabs(int indent)
47 {
48         while (indent--)
49                 printf("\t");
50 }
51
52 void
53 ao_lisp_error_frame(int indent, char *name, struct ao_lisp_frame *frame)
54 {
55         int                     f;
56
57         tabs(indent);
58         printf ("%s{", name);
59         if (frame) {
60                 struct ao_lisp_frame_vals       *vals = ao_lisp_poly_frame_vals(frame->vals);
61                 if (frame->type & AO_LISP_FRAME_PRINT)
62                         printf("recurse...");
63                 else {
64                         frame->type |= AO_LISP_FRAME_PRINT;
65                         for (f = 0; f < frame->num; f++) {
66                                 if (f != 0) {
67                                         tabs(indent);
68                                         printf("         ");
69                                 }
70                                 ao_lisp_poly_write(vals->vals[f].atom);
71                                 printf(" = ");
72                                 ao_lisp_poly_write(vals->vals[f].val);
73                                 printf("\n");
74                         }
75                         if (frame->prev)
76                                 ao_lisp_error_frame(indent + 1, "prev:   ", ao_lisp_poly_frame(frame->prev));
77                         frame->type &= ~AO_LISP_FRAME_PRINT;
78                 }
79                 tabs(indent);
80                 printf("        }\n");
81         } else
82                 printf ("}\n");
83 }
84
85
86 ao_poly
87 ao_lisp_error(int error, char *format, ...)
88 {
89         va_list args;
90
91         ao_lisp_exception |= error;
92         va_start(args, format);
93         vprintf(format, args);
94         va_end(args);
95         printf("\n");
96         printf("Value: "); ao_lisp_poly_write(ao_lisp_v); printf("\n");
97         printf("Stack:\n");
98         ao_lisp_stack_write(ao_lisp_stack_poly(ao_lisp_stack));
99         printf("Globals:\n\t");
100         ao_lisp_frame_write(ao_lisp_frame_poly(ao_lisp_frame_global));
101         printf("\n");
102         return AO_LISP_NIL;
103 }