4-variable-simplifier/print.c
2025-06-30 09:03:33 -05:00

223 lines
4.8 KiB
C

#include <stdio.h>
#include <assert.h>
#include <debug.h>
#include <cmdln.h>
#include <expr.h>
#include "simplifications.h"
#include "print.h"
static void helper(
const struct simplifications* simps,
const struct row* row,
uint16_t truthtable,
bool print_with_color,
int depth)
{
#define LITERAL_ESCAPE "\e[38;2;200;200;100m"
#define VARIABLE_ESCAPE "\e[38;2;100;100;200m"
#define RESET_ESCAPE "\e[0m"
static const char* const operator_colors[10] = {
"\e[38;2;204;0;0m",
"\e[38;2;204;122;0m",
"\e[38;2;163;204;0m",
"\e[38;2;40;204;0m",
"\e[38;2;0;204;81m",
"\e[38;2;0;204;204m",
"\e[38;2;0;81;204m",
"\e[38;2;40;0;204m",
"\e[38;2;163;0;204m",
"\e[38;2;204;0;122m",
};
const struct expr* e = &row->data[truthtable];
switch (e->kind)
{
case ek_unreachable:
{
assert(!"NOPE");
break;
}
case ek_0:
{
printf(print_with_color ? LITERAL_ESCAPE "0" RESET_ESCAPE : "0");
break;
}
case ek_1:
{
printf(print_with_color ? LITERAL_ESCAPE "1" RESET_ESCAPE : "1");
break;
}
case ek_W:
{
printf(print_with_color ? VARIABLE_ESCAPE "w" RESET_ESCAPE : "w");
break;
}
case ek_X:
{
printf(print_with_color ? VARIABLE_ESCAPE "x" RESET_ESCAPE : "x");
break;
}
case ek_Y:
{
printf(print_with_color ? VARIABLE_ESCAPE "y" RESET_ESCAPE : "y");
break;
}
case ek_Z:
{
printf(print_with_color ? VARIABLE_ESCAPE "z" RESET_ESCAPE : "z");
break;
}
case ek_A:
{
printf(print_with_color ? VARIABLE_ESCAPE "a" RESET_ESCAPE : "a");
break;
}
case ek_not:
{
const char* start = print_with_color ? operator_colors[depth % 10] : "";
const char* end = print_with_color ? RESET_ESCAPE : "";
printf("%s(!%s", start, end);
helper(simps, row, e->left, print_with_color, depth + 1);
printf("%s)%s", start, end);
break;
}
#define BINARY_OPERATOR(kind, operatorstring) \
case kind: \
{ \
const char *start = "", *end = ""; \
\
if (print_with_color) \
{ \
start = operator_colors[depth % 10]; \
\
end = RESET_ESCAPE; \
} \
\
printf("%s(%s", start, end); \
\
helper(simps, row, e->left, print_with_color, depth + 1); \
\
printf("%s%s%s", start, operatorstring, end); \
\
helper(simps, row, e->right, print_with_color, depth + 1); \
\
printf("%s)%s", start, end); \
break; \
}
BINARY_OPERATOR(ek_or, " || ");
BINARY_OPERATOR(ek_orn, " |! ");
BINARY_OPERATOR(ek_nor, " !| ");
BINARY_OPERATOR(ek_and, " && ");
BINARY_OPERATOR(ek_andn, " &! ");
BINARY_OPERATOR(ek_nand, " !& ");
BINARY_OPERATOR(ek_xor, " != ");
BINARY_OPERATOR(ek_nxor, " == ");
BINARY_OPERATOR(ek_lt, " < ");
BINARY_OPERATOR(ek_lte, " <= ");
BINARY_OPERATOR(ek_gt, " > ");
BINARY_OPERATOR(ek_gte, " >= ");
#undef BINARY_OPERATOR
case ek_ternary:
{
const char *start = "", *end = "";
if (print_with_color)
{
start = operator_colors[depth % 10];
end = RESET_ESCAPE;
}
printf("%s(%s", start, end);
helper(simps, row, e->cond, print_with_color, depth + 1);
printf(" %s?%s ", start, end);
helper(simps, row, e->left, print_with_color, depth + 1);
printf(" %s:%s ", start, end);
helper(simps, row, e->right, print_with_color, depth + 1);
printf("%s)%s", start, end);
break;
}
case ek_assignment:
{
const char *start = "", *end = "";
if (print_with_color)
{
start = operator_colors[depth % 10];
end = RESET_ESCAPE;
}
printf("%s(a = ..., ...)%s", start, end);
break;
};
}
}
void print(
const struct cmdln_flags* flags,
const struct simplifications* simps,
const struct row* row,
uint16_t truthtable)
{
helper(simps, row, truthtable, flags->print_with_color, 0);
}