/* * Copyright (c) 2026 Nakidai Perumenei * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * These functions are called for debugging if needed */ #include "thac.h" void walknode(struct node *x, ulong depth) { int i; for (i = 0; i < depth; ++i) fputs(" ", stderr); fprintf(stderr, "%s", nodename(x->type)); switch (x->type) { break; case NOPER: { fprintf(stderr, ": %s\n", nopername(x->noper.type)); switch (x->noper.type) { break; case OINDEX: { walknode(x->noper.l, depth + 1); walknode(x->noper.m, depth + 1); if (x->noper.r) walknode(x->noper.r, depth + 1); } break; case OASSERT: case OLEN: case OINV: case ONOT: case OPOSTDECR: case OPOSTINCR: case OPREDECR: case OPREINCR: { walknode(x->noper.m, depth + 1); } break; case OCOND: { walknode(x->noper.l, depth + 1); walknode(x->noper.m, depth + 1); walknode(x->noper.r, depth + 1); } break; default: { walknode(x->noper.l, depth + 1); walknode(x->noper.r, depth + 1); } } } break; case NNODE: { ulong i; fputc('\n', stderr); for (i = 0; i < x->nnode.len; ++i) walknode(x->nnode.params[i], depth + 1); } break; case NCOMP: { ulong i; fputc('\n', stderr); for (i = 0; i < x->ncomp.len; ++i) walknode(x->ncomp.stmts[i], depth + 1); } break; case NMOD: { ulong i; fputs(": ", stderr); for (i = 0; i < x->nmod.len; ++i) fprintf(stderr, "%s ", x->nmod.params[i]); fputc('\n', stderr); walknode(x->nmod.code, depth + 1); } break; case NVAR: { fprintf(stderr, ": %s\n", x->nvar); } break; case NNUM: { fprintf(stderr, ": %lld\n", x->nnum); } break; case NFOR: { fputc('\n', stderr); if (x->nfor.before) walknode(x->nfor.before, depth + 1); if (x->nfor.cond) walknode(x->nfor.cond, depth + 1); if (x->nfor.between) walknode(x->nfor.between, depth + 1); walknode(x->nfor.code, depth + 1); } break; case NFOREACH: { fputc('\n', stderr); walknode(x->nforeach.obj, depth + 1); walknode(x->nforeach.code, depth + 1); } break; case NCOND: { fputc('\n', stderr); walknode(x->ncond.cond, depth + 1); walknode(x->ncond.t, depth + 1); if (x->ncond.f) walknode(x->ncond.f, depth + 1); } break; case NWITH: { ulong i; fputc('\n', stderr); walknode(x->nwith.mod, depth + 1); for (i = 0; i < x->nwith.len; ++i) walknode(x->nwith.args[i], depth + 1); walknode(x->nwith.code, depth + 1); } break; default: putc('\n', stderr); } } void walkscope(struct scope *scope, ulong depth) { #define printdepth() for (j = 0; j < depth; ++j) fputs(" ", stderr) ulong i, j; printdepth(); fprintf(stderr, "scope(%lu)=%p:\n", scope->len, scope); ++depth; if (scope->parent) walkscope(scope->parent, depth); for (i = 0; i < scope->len; ++i) { printdepth(); fprintf( stderr, "%s:%s=%lld\n", scope->vars[i].name, valname(scope->vars[i].val.type), scope->vars[i].val.num ); } } void walkval(struct val *v, ulong depth) { ulong i; for (i = 0; i < depth; ++i) fputs(" ", stderr); fprintf(stderr, "%s", valname(v->type)); switch (v->type) { break; case VARR: fprintf(stderr, ": %lu\n", v->len); for (i = 0; i < v->len; ++i) walkval(&v->arr[i], depth + 1); break; case VNUM: fprintf(stderr, ": %lld\n", v->num); break; case VVAR: fprintf(stderr, ": %s\n", v->name); break; default: putc('\n', stderr); } }