added color support

This commit is contained in:
Alex Thannhauser 2025-06-11 14:21:41 -05:00
parent 1c433de317
commit c57232fee6
2 changed files with 366 additions and 277 deletions

193
main.c
View file

@ -37,11 +37,15 @@ bool assume_yes = false;
bool verbose = false;
bool print_with_color = false;
static void parse_args(int argc, char* const* argv)
{
bool unset_operators = true;
for (int opt; (opt = getopt(argc, argv, "pyvc:eEo:")) != -1; ) switch (opt)
print_with_color = isatty(1);
for (int opt; (opt = getopt(argc, argv, "pyvc:eEo:C:")) != -1; ) switch (opt)
{
case 'p':
print_all_and_quit = true;
@ -124,6 +128,22 @@ static void parse_args(int argc, char* const* argv)
break;
}
case 'C':
{
if (!strcmp(optarg, "yes") || !strcmp(optarg, "on"))
print_with_color = true;
else if (!strcmp(optarg, "no") || !strcmp(optarg, "off"))
print_with_color = false;
else if (!strcmp(optarg, "auto"))
print_with_color = isatty(1);
else
{
assert(!"TODO");
}
break;
}
default:
assert(!"TODO");
break;
@ -184,8 +204,25 @@ struct expr {
// truthtable -> cost
int costs[N] = {};
static void print(uint16_t truthtable)
static void print(uint16_t truthtable, 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 = &lookup[truthtable];
switch (e->kind)
@ -194,72 +231,120 @@ static void print(uint16_t truthtable)
assert(!"NOPE");
break;
case ek_0: printf("0"); break;
case ek_1: printf("1"); break;
case ek_0:
{
printf(print_with_color ? LITERAL_ESCAPE "0" RESET_ESCAPE : "0");
break;
}
case ek_W: printf("w"); break;
case ek_X: printf("x"); break;
case ek_Y: printf("y"); break;
case ek_Z: printf("z"); 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_not:
printf("(!"), print(e->left), printf(")");
break;
{
const char* start = print_with_color ? operator_colors[depth % 10] : "";
const char* end = print_with_color ? RESET_ESCAPE : "";
case ek_or:
printf("("), print(e->left), printf(" || "), print(e->right), printf(")");
break;
printf("%s(!%s", start, end);
case ek_orn:
printf("("), print(e->left), printf(" |! "), print(e->right), printf(")");
break;
print(e->left, depth + 1);
case ek_nor:
printf("("), print(e->left), printf(" !| "), print(e->right), printf(")");
printf("%s)%s", start, end);
break;
}
case ek_and:
printf("("), print(e->left), printf(" && "), print(e->right), printf(")");
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); \
\
print(e->left, depth + 1); \
\
printf("%s%s%s", start, operatorstring, end); \
\
print(e->right, depth + 1); \
\
printf("%s)%s", start, end); \
break; \
}
case ek_andn:
printf("("), print(e->left), printf(" &! "), print(e->right), printf(")");
break;
BINARY_OPERATOR(ek_or, " || ");
BINARY_OPERATOR(ek_orn, " |! ");
BINARY_OPERATOR(ek_nor, " !| ");
case ek_nand:
printf("("), print(e->left), printf(" !& "), print(e->right), printf(")");
break;
BINARY_OPERATOR(ek_and, " && ");
BINARY_OPERATOR(ek_andn, " &! ");
BINARY_OPERATOR(ek_nand, " !& ");
case ek_xor:
printf("("), print(e->left), printf(" != "), print(e->right), printf(")");
break;
BINARY_OPERATOR(ek_xor, " != ");
BINARY_OPERATOR(ek_nxor, " == ");
case ek_nxor:
printf("("), print(e->left), printf(" == "), print(e->right), printf(")");
break;
BINARY_OPERATOR(ek_lt, " < ");
BINARY_OPERATOR(ek_lte, " <= ");
BINARY_OPERATOR(ek_gt, " > ");
BINARY_OPERATOR(ek_gte, " >= ");
case ek_lt:
printf("("), print(e->left), printf(" < "), print(e->right), printf(")");
break;
case ek_lte:
printf("("), print(e->left), printf(" <= "), print(e->right), printf(")");
break;
case ek_gt:
printf("("), print(e->left), printf(" > "), print(e->right), printf(")");
break;
case ek_gte:
printf("("), print(e->left), printf(" >= "), print(e->right), printf(")");
break;
#undef BINARY_OPERATOR
case ek_ternary:
printf("("), print(e->cond), printf(" ? "),
print(e->left), printf(" : "), print(e->right), printf(")");
{
const char *start = "", *end = "";
if (print_with_color)
{
start = operator_colors[depth % 10];
end = RESET_ESCAPE;
}
printf("%s(%s", start, end);
print(e->cond, depth + 1);
printf(" %s?%s ", start, end);
print(e->left, depth + 1);
printf(" %s:%s ", start, end);
print(e->right, depth + 1);
printf("%s)%s", start, end);
break;
}
}
}
void calculate_simplifications(void)
{
@ -395,7 +480,7 @@ void calculate_simplifications(void)
printf("%i of %i (%.2f%%): [%i] ", left, N, (100.0 * left / N), cost);
print(truthtable), puts("");
print(truthtable, 0), puts("");
}
// consider NOT:
@ -1197,7 +1282,7 @@ int main(int argc, char* const* argv)
if (cost != INT_MAX)
{
printf("0b%016b: [%2i]: ", i, cost), print(i), puts("");
printf("0b%016b: [%2i]: ", i, cost), print(i, 0), puts("");
}
}
}
@ -1213,7 +1298,7 @@ int main(int argc, char* const* argv)
}
else
{
printf("%2i: ", costs[truthtable]), print(truthtable), puts("");
printf("%2i: ", costs[truthtable]), print(truthtable, 0), puts("");
}
}
else
@ -1248,7 +1333,7 @@ int main(int argc, char* const* argv)
}
else
{
printf("%2i: ", costs[truthtable]), print(truthtable), puts("");
printf("%2i: ", costs[truthtable]), print(truthtable, 0), puts("");
}
}
}

View file

@ -7,7 +7,7 @@ cc = gcc
cppflags = -D _GNU_SOURCE
cflags = -Werror -Wall -Wextra -Wstrict-prototypes
cflags = -Werror -Wall -Wextra -Wstrict-prototypes -Wfatal-errors
cflags += -O3
@ -20,3 +20,7 @@ ldflags += -lreadline
run: /tmp/4-variable-simplifier
$< $(args)
# nix --extra-experimental-features nix-command --extra-experimental-features flakes develop --command 'make'