/* See LICENSE file for copyright and license details. */ #include "common.h" #ifndef TEST int (libnormalform_literal_cmp__)(struct expression *a, struct expression *b) { int a_class, b_class; uintptr_t a_value, b_value; beginning: switch (a->type) { case LIBNORMALFORM_VARIABLE: case LIBNORMALFORM_NEGATED_VARIABLE: a_class = 0; break; case LIBNORMALFORM_TRANSFORMATION: case LIBNORMALFORM_FUNCTION: case LIBNORMALFORM_NEGATED_FUNCTION: a_class = 1; break; case LIBNORMALFORM_FOR_ALL: case LIBNORMALFORM_NEGATED_FOR_ALL: case LIBNORMALFORM_FOR_ANY: case LIBNORMALFORM_NEGATED_FOR_ANY: a_class = 2; break; case LIBNORMALFORM_FOR_ONE: case LIBNORMALFORM_NEGATED_FOR_ONE: a_class = 3; break; default: case LIBNORMALFORM_CONJUNCTION: case LIBNORMALFORM_DISJUNCTION: case LIBNORMALFORM_EXCLUSIVE_DISJUNCTION: abort(); } switch (b->type) { case LIBNORMALFORM_VARIABLE: case LIBNORMALFORM_NEGATED_VARIABLE: b_class = 0; break; case LIBNORMALFORM_TRANSFORMATION: case LIBNORMALFORM_FUNCTION: case LIBNORMALFORM_NEGATED_FUNCTION: b_class = 1; break; case LIBNORMALFORM_FOR_ALL: case LIBNORMALFORM_NEGATED_FOR_ALL: case LIBNORMALFORM_FOR_ANY: case LIBNORMALFORM_NEGATED_FOR_ANY: b_class = 2; break; case LIBNORMALFORM_FOR_ONE: case LIBNORMALFORM_NEGATED_FOR_ONE: b_class = 3; break; default: case LIBNORMALFORM_CONJUNCTION: case LIBNORMALFORM_DISJUNCTION: case LIBNORMALFORM_EXCLUSIVE_DISJUNCTION: abort(); } if (a_class != b_class) return a_class < b_class ? -2 : +2; a_value = (uintptr_t)a->user_item; b_value = (uintptr_t)b->user_item; if (a_value != b_value) return a_value < b_value ? -2 : +2; switch (a->type) { case LIBNORMALFORM_VARIABLE: return -(b->type == LIBNORMALFORM_NEGATED_VARIABLE); case LIBNORMALFORM_NEGATED_VARIABLE: return +(b->type == LIBNORMALFORM_VARIABLE); case LIBNORMALFORM_TRANSFORMATION: a = a->terms[0]; b = b->terms[0]; goto beginning; case LIBNORMALFORM_FUNCTION: return -(b->type == LIBNORMALFORM_NEGATED_FUNCTION); case LIBNORMALFORM_NEGATED_FUNCTION: return +(b->type == LIBNORMALFORM_FUNCTION); case LIBNORMALFORM_FOR_ALL: case LIBNORMALFORM_NEGATED_FOR_ALL: case LIBNORMALFORM_FOR_ANY: case LIBNORMALFORM_NEGATED_FOR_ANY: /* TODO (not) all/any */ return 0; case LIBNORMALFORM_FOR_ONE: case LIBNORMALFORM_NEGATED_FOR_ONE: /* TODO (not) one */ return 0; default: case LIBNORMALFORM_CONJUNCTION: case LIBNORMALFORM_DISJUNCTION: case LIBNORMALFORM_EXCLUSIVE_DISJUNCTION: abort(); } } #else TODO_TEST #endif