112 lines
2.4 KiB
C
112 lines
2.4 KiB
C
#include <stdio.h>
|
|
#include "tmpasm.h"
|
|
|
|
static void indent(FILE *f, int depth)
|
|
{
|
|
for(;depth > 0; depth--) fputc(' ', f);
|
|
}
|
|
|
|
static void print_arg(FILE *f, tmpasm_arg_t *a)
|
|
{
|
|
if (a == NULL) {
|
|
fprintf(f, "*NULL - broken AST*");
|
|
return;
|
|
}
|
|
if (a->next != NULL) {
|
|
/* block mode */
|
|
fprintf(f, "[~");
|
|
for(;a != NULL; a = a->next) {
|
|
if (a->is_addr)
|
|
fprintf(f, "~%s~", a->data);
|
|
else
|
|
fprintf(f, "%s", a->data);
|
|
}
|
|
fprintf(f, "~]");
|
|
}
|
|
else {
|
|
if (a->is_addr)
|
|
fprintf(f, "%s", a->data);
|
|
else
|
|
fprintf(f, "{%s}", a->data);
|
|
}
|
|
}
|
|
|
|
static void print_loc(FILE *f, tmpasm_exec_t *c)
|
|
{
|
|
if ((c->line != 0) || (c->col != 0))
|
|
fprintf(f, " [at %d:%d]\n", c->line, c->col);
|
|
else
|
|
fprintf(f, "\n");
|
|
}
|
|
|
|
static void dump(FILE *f, int depth, tmpasm_exec_t *c)
|
|
{
|
|
tmpasm_case_t *cc;
|
|
int n;
|
|
for(; c != NULL; c = c->next) {
|
|
switch(c->kw) {
|
|
case KW_NOP:
|
|
indent(f, depth);
|
|
fprintf(f, "(NOP)");
|
|
print_loc(f, c);
|
|
break;
|
|
case KW_none:
|
|
indent(f, depth);
|
|
fprintf(f, "%s", c->payload.instr.call_name);
|
|
print_loc(f, c);
|
|
for(n = 0; n < c->payload.instr.argc; n++) {
|
|
indent(f, depth+1);
|
|
fprintf(f, "arg: ");
|
|
print_arg(f, c->payload.instr.argv[n]);
|
|
fprintf(f, "\n");
|
|
}
|
|
break;
|
|
case KW_IF:
|
|
indent(f, depth);
|
|
fprintf(f, "if ");
|
|
print_arg(f, c->payload.fc_if.cond);
|
|
print_loc(f, c);
|
|
indent(f, depth);
|
|
fprintf(f, "then:\n");
|
|
dump(f, depth+1, c->payload.fc_if.code_then);
|
|
indent(f, depth);
|
|
fprintf(f, "else:\n");
|
|
dump(f, depth+1, c->payload.fc_if.code_else);
|
|
break;
|
|
case KW_FOREACH:
|
|
indent(f, depth);
|
|
fprintf(f, "foreach %s in ", c->payload.fc_foreach.loop_var);
|
|
print_arg(f, c->payload.fc_foreach.data);
|
|
print_loc(f, c);
|
|
dump(f, depth+1, c->payload.fc_foreach.code_body);
|
|
break;
|
|
case KW_SWITCH:
|
|
indent(f, depth);
|
|
fprintf(f, "switch ");
|
|
print_arg(f, c->payload.fc_switch.cond);
|
|
print_loc(f, c);
|
|
for(cc = c->payload.fc_switch.first; cc != NULL; cc = cc->next) {
|
|
indent(f, depth+1);
|
|
if (cc->data != NULL) {
|
|
fprintf(f, "case ");
|
|
print_arg(f, cc->data);
|
|
fprintf(f, "\n");
|
|
}
|
|
else
|
|
printf("default\n");
|
|
dump(f, depth+2, cc->body);
|
|
}
|
|
break;
|
|
default:
|
|
indent(f, depth);
|
|
fprintf(f, "invalid kw ");
|
|
print_loc(f, c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void tmpasm_dump(tmpasm_t *ctx, FILE *f)
|
|
{
|
|
dump(f, 0, ctx->code);
|
|
}
|