]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/debug.c
Clamp pitch values rather than just dumping an error message.
[simgear.git] / simgear / nasal / debug.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "nasal.h"
6 #include "parse.h"
7 #include "code.h"
8
9 // Bytecode operator to string
10 char* opStringDEBUG(int op)
11 {
12     static char buf[256];
13     switch(op) {
14     case OP_AND: return "AND";
15     case OP_OR: return "OR";
16     case OP_NOT: return "NOT";
17     case OP_MUL: return "MUL";
18     case OP_PLUS: return "PLUS";
19     case OP_MINUS: return "MINUS";
20     case OP_DIV: return "DIV";
21     case OP_NEG: return "NEG";
22     case OP_CAT: return "CAT";
23     case OP_LT: return "LT";
24     case OP_LTE: return "LTE";
25     case OP_GT: return "GT";
26     case OP_GTE: return "GTE";
27     case OP_EQ: return "EQ";
28     case OP_NEQ: return "NEQ";
29     case OP_EACH: return "EACH";
30     case OP_JMP: return "JMP";
31     case OP_JIFNOT: return "JIFNOT";
32     case OP_JIFNIL: return "JIFNIL";
33     case OP_FCALL: return "FCALL";
34     case OP_MCALL: return "MCALL";
35     case OP_RETURN: return "RETURN";
36     case OP_PUSHCONST: return "PUSHCONST";
37     case OP_PUSHONE: return "PUSHONE";
38     case OP_PUSHZERO: return "PUSHZERO";
39     case OP_PUSHNIL: return "PUSHNIL";
40     case OP_POP: return "POP";
41     case OP_DUP: return "DUP";
42     case OP_XCHG: return "XCHG";
43     case OP_INSERT: return "INSERT";
44     case OP_EXTRACT: return "EXTRACT";
45     case OP_MEMBER: return "MEMBER";
46     case OP_SETMEMBER: return "SETMEMBER";
47     case OP_LOCAL: return "LOCAL";
48     case OP_SETLOCAL: return "SETLOCAL";
49     case OP_NEWVEC: return "NEWVEC";
50     case OP_VAPPEND: return "VAPPEND";
51     case OP_NEWHASH: return "NEWHASH";
52     case OP_HAPPEND: return "HAPPEND";
53     case OP_LINE: return "LINE";
54     case OP_MARK: return "MARK";
55     case OP_UNMARK: return "UNMARK";
56     case OP_BREAK: return "BREAK";
57     }
58     sprintf(buf, "<bad opcode: %d>\n", op);
59     return buf;
60 }
61
62 // Print a bytecode operator
63 void printOpDEBUG(int ip, int op)
64 {
65     printf("IP: %d OP: %s\n", ip, opStringDEBUG(op));
66 }
67
68 // Print a naRef
69 void printRefDEBUG(naRef r)
70 {
71     int i;
72     if(IS_NUM(r)) {
73         printf("%f\n", r.num);
74     } else if(IS_NIL(r)) {
75         printf("<nil>\n");
76     } else if(IS_STR(r)) {
77         printf("\"");
78         for(i=0; i<r.ref.ptr.str->len; i++)
79             printf("%c", r.ref.ptr.str->data[i]);
80         printf("\"\n");
81     } else if(IS_VEC(r)) {
82         printf("<vec>\n");
83     } else if(IS_HASH(r)) {
84         printf("<hash>\n");
85     } else if(IS_FUNC(r)) {
86         printf("<func>\n");
87     } else if(IS_CLOSURE(r)) {
88         printf("DEBUG: closure object on stack!\n");
89     } else if(IS_CODE(r)) {
90         printf("DEBUG: code object on stack!\n");
91     } else printf("DEBUG ACK\n");
92 }
93
94 // Print the operand stack of the specified context
95 void printStackDEBUG(struct Context* ctx)
96 {
97     int i;
98     printf("\n");
99     for(i=ctx->opTop-1; i>=0; i--) {
100         printf("] ");
101         printRefDEBUG(ctx->opStack[i]);
102     }
103     printf("\n");
104 }
105
106 // Token type to string
107 char* tokString(int tok)
108 {
109     switch(tok) {
110     case TOK_TOP: return "TOK_TOP";
111     case TOK_AND: return "TOK_AND";
112     case TOK_OR: return "TOK_OR";
113     case TOK_NOT: return "TOK_NOT";
114     case TOK_LPAR: return "TOK_LPAR";
115     case TOK_RPAR: return "TOK_RPAR";
116     case TOK_LBRA: return "TOK_LBRA";
117     case TOK_RBRA: return "TOK_RBRA";
118     case TOK_LCURL: return "TOK_LCURL";
119     case TOK_RCURL: return "TOK_RCURL";
120     case TOK_MUL: return "TOK_MUL";
121     case TOK_PLUS: return "TOK_PLUS";
122     case TOK_MINUS: return "TOK_MINUS";
123     case TOK_NEG: return "TOK_NEG";
124     case TOK_DIV: return "TOK_DIV";
125     case TOK_CAT: return "TOK_CAT";
126     case TOK_COLON: return "TOK_COLON";
127     case TOK_DOT: return "TOK_DOT";
128     case TOK_COMMA: return "TOK_COMMA";
129     case TOK_SEMI: return "TOK_SEMI";
130     case TOK_ASSIGN: return "TOK_ASSIGN";
131     case TOK_LT: return "TOK_LT";
132     case TOK_LTE: return "TOK_LTE";
133     case TOK_EQ: return "TOK_EQ";
134     case TOK_NEQ: return "TOK_NEQ";
135     case TOK_GT: return "TOK_GT";
136     case TOK_GTE: return "TOK_GTE";
137     case TOK_IF: return "TOK_IF";
138     case TOK_ELSIF: return "TOK_ELSIF";
139     case TOK_ELSE: return "TOK_ELSE";
140     case TOK_FOR: return "TOK_FOR";
141     case TOK_FOREACH: return "TOK_FOREACH";
142     case TOK_WHILE: return "TOK_WHILE";
143     case TOK_RETURN: return "TOK_RETURN";
144     case TOK_BREAK: return "TOK_BREAK";
145     case TOK_CONTINUE: return "TOK_CONTINUE";
146     case TOK_FUNC: return "TOK_FUNC";
147     case TOK_SYMBOL: return "TOK_SYMBOL";
148     case TOK_LITERAL: return "TOK_LITERAL";
149     case TOK_EMPTY: return "TOK_EMPTY";
150     case TOK_NIL: return "TOK_NIL";
151     }
152     return 0;
153 }
154
155 // Diagnostic: check all list pointers for sanity
156 void ack()
157 {
158     printf("Bad token list!\n");
159     exit(1);
160 }
161 void checkList(struct Token* start, struct Token* end)
162 {
163     struct Token* t = start;
164     while(t) {
165         if(t->next && t->next->prev != t) ack();
166         if(t->next==0 && t != end) ack();
167         t = t->next;
168     }
169     t = end;
170     while(t) {
171         if(t->prev && t->prev->next != t) ack();
172         if(t->prev==0 && t != start) ack();
173         t = t->prev;
174     };
175 }
176
177
178 // Prints a single parser token to stdout
179 void printToken(struct Token* t, char* prefix)
180 {
181     int i;
182     printf("%sline %d %s ", prefix, t->line, tokString(t->type));
183     if(t->type == TOK_LITERAL || t->type == TOK_SYMBOL) {
184         if(t->str) {
185             printf("\"");
186             for(i=0; i<t->strlen; i++) printf("%c", t->str[i]);
187             printf("\" (len: %d)", t->strlen);
188         } else {
189             printf("%f ", t->num);
190         }
191     }
192     printf("\n");
193 }
194
195 // Prints a parse tree to stdout
196 void dumpTokenList(struct Token* t, int prefix)
197 {
198     char prefstr[128];
199     int i;
200
201     prefstr[0] = 0;
202     for(i=0; i<prefix; i++)
203         strcat(prefstr, ". ");
204
205     while(t) {
206         printToken(t, prefstr);
207         dumpTokenList(t->children, prefix+1);
208         t = t->next;
209     }
210 }
211