Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / lang / LangSource / DumpParseNode.cpp
blobaabffba58452b84ce13c39c49403180a75ea55af
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "SCBase.h"
22 #include "PyrParseNode.h"
23 #include "PyrLexer.h"
24 #include "PyrKernel.h"
25 #include "Opcodes.h"
26 #include "PyrPrimitive.h"
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <ctype.h>
32 #ifdef _WIN32
33 # define snprintf _snprintf
34 # define PATH_MAX _MAX_PATH
35 #endif
38 extern int textpos;
40 void dumpNodeList(PyrParseNode *node)
42 for (; node; node = node->mNext) {
43 DUMPNODE(node, 0);
47 void PyrCurryArgNode::dump(int level)
49 postfl("%2d CurryArg %d\n", level, mArgNum);
52 void PyrSlotNode::dump(int level)
54 if (mClassno == pn_PushLitNode)
55 dumpPushLit(level);
56 else if (mClassno == pn_PushNameNode)
57 postfl("%2d PushName '%s'\n", level, slotRawSymbol(&mSlot)->name);
58 else if (mClassno == pn_LiteralNode)
59 dumpLiteral(level);
60 else {
61 postfl("%2d SlotNode\n", level);
62 dumpPyrSlot(&mSlot);
64 DUMPNODE(mNext, level);
67 void PyrPushKeyArgNode::dump(int level)
69 postfl("%2d PushKeyArgNode\n", level);
70 DUMPNODE(mSelector, level+1);
71 DUMPNODE(mExpr, level+1);
72 DUMPNODE(mNext, level);
75 void PyrClassExtNode::dump(int level)
77 postfl("%2d ClassExt '%s'\n", level, slotRawSymbol(&mClassName->mSlot)->name);
78 DUMPNODE(mMethods, level+1);
79 DUMPNODE(mNext, level);
82 void PyrClassNode::dump(int level)
84 postfl("%2d Class '%s'\n", level, slotRawSymbol(&mClassName->mSlot)->name);
85 DUMPNODE(mSuperClassName, level+1);
86 DUMPNODE(mVarlists, level+1);
87 DUMPNODE(mMethods, level+1);
88 DUMPNODE(mNext, level);
91 void PyrMethodNode::dump(int level)
93 postfl("%2d MethodNode '%s' %s\n", level, slotRawSymbol(&mMethodName->mSlot)->name,
94 mPrimitiveName ? slotRawSymbol(&mPrimitiveName->mSlot)->name:"");
95 DUMPNODE(mArglist, level+1);
96 DUMPNODE(mBody, level+1);
97 DUMPNODE(mNext, level);
100 void PyrArgListNode::dump(int level)
102 postfl("%2d ArgList\n", level);
103 DUMPNODE(mVarDefs, level+1);
104 DUMPNODE(mRest, level+1);
105 DUMPNODE(mNext, level);
108 void PyrVarListNode::dump(int level)
110 postfl("%2d VarList\n", level);
111 DUMPNODE(mVarDefs, level+1);
112 DUMPNODE(mNext, level);
115 void PyrVarDefNode::dump(int level)
117 postfl("%2d VarDef '%s'\n", level, slotRawSymbol(&mVarName->mSlot)->name);
118 DUMPNODE(mDefVal, level);
119 DUMPNODE(mNext, level);
122 void PyrCallNode::dump(int level)
124 postfl("%2d Call '%s'\n", level, slotRawSymbol(&mSelector->mSlot)->name);
125 DUMPNODE(mArglist, level+1);
126 DUMPNODE(mKeyarglist, level+1);
127 DUMPNODE(mNext, level);
130 void PyrBinopCallNode::dump(int level)
132 postfl("%2d BinopCall '%s'\n", level, slotRawSymbol(&mSelector->mSlot)->name);
133 DUMPNODE(mArglist, level+1);
134 DUMPNODE(mNext, level);
137 void PyrDropNode::dump(int level)
139 postfl("%2d Drop (\n", level);
140 DUMPNODE(mExpr1, level+1);
141 postfl(" -> %2d Drop\n", level);
142 DUMPNODE(mExpr2, level+1);
143 postfl(") %2d Drop\n", level);
144 DUMPNODE(mNext, level);
147 void PyrSlotNode::dumpPushLit(int level)
149 postfl("%2d PushLit\n", level);
150 if (!IsPtr(&mSlot)) dumpPyrSlot(&mSlot);
151 else {
152 DUMPNODE((PyrParseNode*)slotRawObject(&mSlot), level);
156 void PyrSlotNode::dumpLiteral(int level)
158 postfl("%2d Literal\n", level);
159 if (!IsPtr(&mSlot)) dumpPyrSlot(&mSlot);
160 else {
161 DUMPNODE((PyrParseNode*)slotRawObject(&mSlot), level);
165 void PyrReturnNode::dump(int level)
167 postfl("%2d Return (\n", level);
168 DUMPNODE(mExpr, level+1);
169 postfl(") %2d Return \n", level);
170 DUMPNODE(mNext, level);
173 void PyrBlockReturnNode::dump(int level)
175 postfl("%2d FuncReturn\n", level);
176 DUMPNODE(mNext, level);
179 void PyrAssignNode::dump(int level)
181 postfl("%2d Assign '%s'\n", level, slotRawSymbol(&mVarName->mSlot)->name);
182 DUMPNODE(mVarName, level+1);
183 DUMPNODE(mExpr, level+1);
184 DUMPNODE(mNext, level);
187 void PyrSetterNode::dump(int level)
189 //postfl("%2d Assign '%s'\n", level, slotRawSymbol(&mVarName->mSlot)->name);
190 DUMPNODE(mSelector, level+1);
191 DUMPNODE(mExpr1, level+1);
192 DUMPNODE(mExpr2, level+1);
195 void PyrMultiAssignNode::dump(int level)
197 postfl("%2d MultiAssign\n", level);
198 DUMPNODE(mVarList, level+1);
199 DUMPNODE(mExpr, level+1);
200 DUMPNODE(mNext, level);
203 void PyrMultiAssignVarListNode::dump(int level)
205 postfl("%2d MultiAssignVarList\n", level);
206 DUMPNODE(mVarNames, level+1);
207 DUMPNODE(mRest, level+1);
208 DUMPNODE(mNext, level);
211 void PyrDynDictNode::dump(int level)
213 postfl("%2d DynDict\n", level);
214 DUMPNODE(mElems, level+1);
215 DUMPNODE(mNext, level);
218 void PyrDynListNode::dump(int level)
220 postfl("%2d DynList\n", level);
221 DUMPNODE(mElems, level+1);
222 DUMPNODE(mNext, level);
225 void PyrLitListNode::dump(int level)
227 postfl("%2d LitList\n", level);
228 postfl(" %2d mElems\n", level);
229 DUMPNODE(mElems, level+1);
230 postfl(" %2d mNext\n", level);
231 DUMPNODE(mNext, level);
234 void PyrBlockNode::dump(int level)
236 postfl("%2d Func\n", level);
237 DUMPNODE(mArglist, level+1);
238 DUMPNODE(mBody, level+1);
239 DUMPNODE(mNext, level);
242 void dumpPyrSlot(PyrSlot* slot)
244 char str[128];
245 slotString(slot, str);
246 post(" %s\n", str);
249 void slotString(PyrSlot *slot, char *str)
251 switch (GetTag(slot)) {
252 case tagInt :
253 sprintf(str, "Integer %d", slotRawInt(slot));
254 break;
255 case tagChar :
256 sprintf(str, "Character %d '%c'", static_cast<int>(slotRawChar(slot)), static_cast<int>(slotRawChar(slot)));
257 break;
258 case tagSym :
259 if (strlen(slotRawSymbol(slot)->name) > 240) {
260 char str2[256];
261 memcpy(str2, slotRawSymbol(slot)->name, 240);
262 str2[240] = 0;
263 snprintf(str, 256, "Symbol '%s...'", str2);
264 } else {
265 snprintf(str, 256, "Symbol '%s'", slotRawSymbol(slot)->name);
267 break;
268 case tagObj :
269 if (slotRawObject(slot)) {
270 PyrClass * classptr = slotRawObject(slot)->classptr;
271 if (classptr == class_class) {
272 sprintf(str, "class %s (%p)",
273 slotRawSymbol(&((PyrClass*)slotRawObject(slot))->name)->name, slotRawObject(slot));
274 } else if (classptr == class_string) {
275 char str2[48];
276 int len;
277 if (slotRawObject(slot)->size > 47) {
278 memcpy(str2, (char*)slotRawObject(slot)->slots, 44);
279 str2[44] = '.';
280 str2[45] = '.';
281 str2[46] = '.';
282 str2[47] = 0;
283 } else {
284 len = sc_min(47, slotRawObject(slot)->size);
285 memcpy(str2, (char*)slotRawObject(slot)->slots, len);
286 str2[len] = 0;
288 sprintf(str, "\"%s\"", str2);
289 } else if (classptr == class_method) {
290 sprintf(str, "instance of Method %s:%s (%p)",
291 slotRawSymbol(&slotRawClass(&slotRawMethod(slot)->ownerclass)->name)->name,
292 slotRawSymbol(&slotRawMethod(slot)->name)->name, slotRawMethod(slot));
293 } else if (classptr == class_fundef) {
294 PyrSlot *context, *nextcontext;
295 // find function's method
296 nextcontext = &slotRawBlock(slot)->contextDef;
297 if (NotNil(nextcontext)) {
298 do {
299 context = nextcontext;
300 nextcontext = &slotRawBlock(context)->contextDef;
301 } while (NotNil(nextcontext));
302 if (isKindOf(slotRawObject(context), class_method)) {
303 sprintf(str, "instance of FunctionDef in Method %s:%s",
304 slotRawSymbol(&slotRawClass(&slotRawMethod(context)->ownerclass)->name)->name,
305 slotRawSymbol(&slotRawMethod(context)->name)->name);
306 } else {
307 sprintf(str, "instance of FunctionDef in closed FunctionDef");
309 } else {
310 sprintf(str, "instance of FunctionDef - closed");
312 } else if (classptr == class_frame) {
313 if (!slotRawFrame(slot)) {
314 sprintf(str, "Frame (%0X)", slotRawInt(slot));
315 } else if (slotRawBlock(&slotRawFrame(slot)->method)->classptr == class_method) {
316 sprintf(str, "Frame (%p) of %s:%s", slotRawObject(slot),
317 slotRawSymbol(&slotRawClass(&slotRawMethod(&slotRawFrame(slot)->method)->ownerclass)->name)->name,
318 slotRawSymbol(&slotRawMethod(&slotRawFrame(slot)->method)->name)->name);
319 } else {
320 sprintf(str, "Frame (%p) of Function", slotRawFrame(slot));
322 } else {
323 sprintf(str, "instance of %s (%p, size=%d, set=%d)",
324 slotRawSymbol(&classptr->name)->name,
325 slotRawObject(slot), slotRawObject(slot)->size,
326 slotRawObject(slot)->obj_sizeclass);
328 } else {
329 sprintf(str, "NULL Object Pointer");
331 break;
332 case tagNil :
333 sprintf(str, "nil");
334 break;
335 case tagFalse :
336 sprintf(str, "false");
337 break;
338 case tagTrue :
339 sprintf(str, "true");
340 break;
341 case tagPtr :
342 sprintf(str, "RawPointer %p", slotRawPtr(slot));
343 break;
344 default :
346 union {
347 int32 i[2];
348 double f;
349 } u;
350 u.f = slotRawFloat(slot);
351 sprintf(str, "Float %f %08X %08X", u.f, u.i[0], u.i[1]);
352 break;
357 static void printObject(PyrSlot * slot, PyrObject * obj, char *str)
359 assert(obj);
360 PyrClass * classptr = obj->classptr;
361 if (classptr == class_class) {
362 sprintf(str, "class %s", slotRawSymbol(&((PyrClass*)obj)->name)->name);
363 } else if (classptr == class_string) {
364 char str2[32];
365 int len;
366 if (obj->size > 31) {
367 memcpy(str2, (char*)obj->slots, 28);
368 str2[28] = '.';
369 str2[29] = '.';
370 str2[30] = '.';
371 str2[31] = 0;
372 } else {
373 len = sc_min(31, obj->size);
374 memcpy(str2, (char*)obj->slots, len);
375 str2[len] = 0;
377 sprintf(str, "\"%s\"", str2);
378 } else if (classptr == class_method) {
379 sprintf(str, "%s:%s",
380 slotRawSymbol(&slotRawClass(&slotRawMethod(slot)->ownerclass)->name)->name,
381 slotRawSymbol(&slotRawMethod(slot)->name)->name);
382 } else if (classptr == class_fundef) {
383 PyrSlot *context, *nextcontext;
384 // find function's method
385 nextcontext = &slotRawBlock(slot)->contextDef;
386 if (NotNil(nextcontext)) {
387 do {
388 context = nextcontext;
389 nextcontext = &slotRawBlock(context)->contextDef;
390 } while (NotNil(nextcontext));
391 if (isKindOf(slotRawObject(context), class_method)) {
392 sprintf(str, "< FunctionDef in Method %s:%s >",
393 slotRawSymbol(&slotRawClass(&slotRawMethod(context)->ownerclass)->name)->name,
394 slotRawSymbol(&slotRawMethod(context)->name)->name);
395 } else {
396 sprintf(str, "< FunctionDef in closed FunctionDef >");
398 } else {
399 sprintf(str, "< closed FunctionDef >");
401 } else if (classptr == class_frame) {
402 if (!slotRawFrame(slot)) {
403 sprintf(str, "Frame (null)");
404 } else if (!slotRawBlock(&slotRawFrame(slot)->method)) {
405 sprintf(str, "Frame (null method)");
406 } else if (slotRawBlock(&slotRawFrame(slot)->method)->classptr == class_method) {
407 sprintf(str, "Frame (%p) of %s:%s", obj,
408 slotRawSymbol(&slotRawClass(&slotRawMethod(&slotRawFrame(slot)->method)->ownerclass)->name)->name,
409 slotRawSymbol(&slotRawMethod(&slotRawFrame(slot)->method)->name)->name);
410 } else {
411 sprintf(str, "Frame (%p) of Function", obj);
413 } else if (classptr == class_array) {
414 sprintf(str, "[*%d]", obj->size);
415 } else {
416 sprintf(str, "<instance of %s>", slotRawSymbol(&classptr->name)->name);
420 void slotOneWord(PyrSlot *slot, char *str)
422 str[0] = 0;
423 switch (GetTag(slot)) {
424 case tagInt :
425 sprintf(str, "%d", slotRawInt(slot));
426 break;
427 case tagChar :
428 sprintf(str, "$%c", static_cast<int>(slotRawChar(slot)));
429 break;
430 case tagSym :
431 if (strlen(slotRawSymbol(slot)->name) > 240) {
432 char str2[256];
433 memcpy(str2, slotRawSymbol(slot)->name, 240);
434 str2[240] = 0;
435 snprintf(str, 256, "'%s...'", str2);
436 } else {
437 snprintf(str, 256, "'%s'", slotRawSymbol(slot)->name);
439 break;
440 case tagObj :
442 PyrObject * slotObj = slotRawObject(slot);
443 if (slotObj)
444 printObject(slot, slotObj, str);
445 else
446 sprintf(str, "NULL Object Pointer");
447 break;
449 case tagNil :
450 sprintf(str, "nil");
451 break;
452 case tagFalse :
453 sprintf(str, "false");
454 break;
455 case tagTrue :
456 sprintf(str, "true");
457 break;
458 case tagPtr :
459 sprintf(str, "ptr%p", slotRawPtr(slot));
460 break;
461 default :
462 sprintf(str, "%.14g", slotRawFloat(slot));
463 break;
467 bool postString(PyrSlot *slot, char *str)
469 bool res = true;
470 switch (GetTag(slot)) {
471 case tagInt :
472 sprintf(str, "%d", slotRawInt(slot));
473 break;
474 case tagChar :
475 sprintf(str, "%c", slotRawChar(slot));
476 break;
477 case tagSym :
478 str[0] = 0;
479 res = false;
480 break;
481 case tagObj :
483 PyrObject * slotObj = slotRawObject(slot);
484 if (slotObj) {
485 PyrClass * classptr = slotRawObject(slot)->classptr;
486 if (classptr == class_class || classptr == class_method || classptr == class_fundef || classptr == class_frame)
487 printObject(slot, slotObj, str);
488 else {
489 str[0] = 0;
490 res = false;
493 else
494 sprintf(str, "NULL Object Pointer");
495 break;
497 case tagNil :
498 sprintf(str, "nil");
499 break;
500 case tagFalse :
501 sprintf(str, "false");
502 break;
503 case tagTrue :
504 sprintf(str, "true");
505 break;
506 case tagPtr :
507 sprintf(str, "%p", slotRawPtr(slot));
508 break;
509 default :
510 sprintf(str, "%.14g", slotRawFloat(slot));
511 break;
513 return res;
517 int asCompileString(PyrSlot *slot, char *str)
519 switch (GetTag(slot)) {
520 case tagInt :
521 sprintf(str, "%d", slotRawInt(slot));
522 break;
523 case tagChar :
525 int c = slotRawChar(slot);
526 if (isprint(c)) {
527 sprintf(str, "$%c", c);
528 } else {
529 switch (c) {
530 case '\n' : strcpy(str, "$\\n"); break;
531 case '\r' : strcpy(str, "$\\r"); break;
532 case '\t' : strcpy(str, "$\\t"); break;
533 case '\f' : strcpy(str, "$\\f"); break;
534 case '\v' : strcpy(str, "$\\v"); break;
535 default: sprintf(str, "%d.asAscii", c);
538 break;
540 case tagSym :
541 return errFailed;
542 case tagObj :
543 return errFailed;
544 case tagNil :
545 sprintf(str, "nil");
546 break;
547 case tagFalse :
548 sprintf(str, "false");
549 break;
550 case tagTrue :
551 sprintf(str, "true");
552 break;
553 case tagPtr :
554 strcpy(str, "/*Ptr*/ nil");
555 break;
556 default :
557 sprintf(str, "%f", slotRawFloat(slot));
558 break;
560 return errNone;
564 void stringFromPyrString(PyrString *obj, char *str, int maxlength);
565 void stringFromPyrString(PyrString *obj, char *str, int maxlength)
567 if (obj->classptr == class_string) {
568 int len;
569 if (obj->size > maxlength-4) {
570 memcpy(str, obj->s, maxlength-4);
571 str[maxlength-4] = '.';
572 str[maxlength-3] = '.';
573 str[maxlength-2] = '.';
574 str[maxlength-1] = 0;
575 } else {
576 len = sc_min(maxlength-1, obj->size);
577 memcpy(str, obj->s, len);
578 str[len] = 0;
580 } else {
581 sprintf(str, "not a string");
585 void pstrncpy(unsigned char *s1, unsigned char *s2, int n);
587 void pstringFromPyrString(PyrString *obj, unsigned char *str, int maxlength)
589 static const char not_a_string[] = "not a string";
590 const char * src;
591 int len;
592 if (obj && obj->classptr == class_string) {
593 len = sc_min(maxlength-1, obj->size);
594 src = obj->s;
595 } else {
596 len = sizeof(not_a_string);
597 src = not_a_string;
599 memcpy(str+1, src, len);
600 str[0] = len;