summary refs log tree commit diff
path: root/debug.c
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-04-05 19:51:14 +0300
committerNakidai <nakidai@disroot.org>2026-04-05 20:01:32 +0300
commit8afa976e073c7bc29c878230eead6dddfdcc08a1 (patch)
tree044b8ddf87b9a3c8b5a229b27e84e870468fb950 /debug.c
downloadthac-5e9fb4d28f49aa4a17b38f436a63b5a7a764457b.tar.gz
thac-5e9fb4d28f49aa4a17b38f436a63b5a7a764457b.zip
Add code v0.1.0
Diffstat (limited to 'debug.c')
-rw-r--r--debug.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/debug.c b/debug.c
new file mode 100644
index 0000000..ecb4f78
--- /dev/null
+++ b/debug.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2026 Nakidai Perumenei <nakidai at disroot dot org>
+ *
+ * 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);
+	}
+}