Skip to content

Commit

Permalink
Replace snek_poly_equal and snek_poly_less with snek_poly_cmp
Browse files Browse the repository at this point in the history
This single function returns <0, =0, >0 depending on the relation of
the two values, saving a bunch of space compared with having two
separate functions.

snek_poly_cmp provides a global order for all snek values, permitting
comparisons of strings, list and tuples in addition to floats.

Signed-off-by: Keith Packard <keithp@keithp.com>
  • Loading branch information
keith-packard committed Mar 2, 2019
1 parent 53645d2 commit b756548
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 87 deletions.
123 changes: 62 additions & 61 deletions snek-code.c
Expand Up @@ -672,17 +672,33 @@ snek_binary(snek_poly_t a, snek_op_t op, snek_poly_t b, bool inplace)
bool found;
snek_poly_t ret = SNEK_NULL;

switch (op) {
case snek_op_eq:
return snek_bool_to_poly(snek_poly_equal(a, b, false));
case snek_op_ne:
return snek_bool_to_poly(!snek_poly_equal(a, b, false));
case snek_op_is:
return snek_bool_to_poly(snek_poly_equal(a, b, true));
case snek_op_is_not:
return snek_bool_to_poly(!snek_poly_equal(a, b, true));
default:
break;
if (op <= snek_op_is_not) {
int8_t cmp = snek_poly_cmp(a, b, op >= snek_op_is);
bool v;
switch (op) {
case snek_op_eq:
case snek_op_is:
v = cmp == 0;
break;
case snek_op_ne:
case snek_op_is_not:
v = cmp != 0;
break;
case snek_op_gt:
v = cmp > 0;
break;
case snek_op_lt:
v = cmp < 0;
break;
case snek_op_ge:
v = cmp >= 0;
break;
case snek_op_le:
default:
v = cmp <= 0;
break;
}
return snek_bool_to_poly(v);
}

snek_type_t at = snek_poly_type(a);
Expand All @@ -703,61 +719,46 @@ snek_binary(snek_poly_t a, snek_op_t op, snek_poly_t b, bool inplace)
af = snek_poly_to_float(a);
bf = snek_poly_to_float(b);
switch (op) {
case snek_op_lt:
ret = snek_bool_to_poly(af < bf);
case snek_op_plus:
af = af + bf;
break;
case snek_op_gt:
ret = snek_bool_to_poly(af > bf);
case snek_op_minus:
af = af - bf;
break;
case snek_op_le:
ret = snek_bool_to_poly(af <= bf);
case snek_op_times:
af = af * bf;
break;
case snek_op_ge:
ret = snek_bool_to_poly(af >= bf);
case snek_op_divide:
af = af / bf;
break;
case snek_op_div:
af = (float) ((int32_t) af / (int32_t) bf);
break;
case snek_op_mod:
af = (float) ((int32_t) af % (int32_t) bf);
break;
case snek_op_pow:
af = powf(af, bf);
break;
case snek_op_land:
af = (float) ((int32_t) af & (int32_t) bf);
break;
case snek_op_lor:
af = (float) ((int32_t) af | (int32_t) bf);
break;
case snek_op_lxor:
af = (float) ((int32_t) af ^ (int32_t) bf);
break;
case snek_op_lshift:
af = (float) ((int32_t) af << (int32_t) bf);
break;
case snek_op_rshift:
af = (float) ((int32_t) af >> (int32_t) bf);
break;
default:
switch (op) {
case snek_op_plus:
af = af + bf;
break;
case snek_op_minus:
af = af - bf;
break;
case snek_op_times:
af = af * bf;
break;
case snek_op_divide:
af = af / bf;
break;
case snek_op_div:
af = (float) ((int32_t) af / (int32_t) bf);
break;
case snek_op_mod:
af = (float) ((int32_t) af % (int32_t) bf);
break;
case snek_op_pow:
af = powf(af, bf);
break;
case snek_op_land:
af = (float) ((int32_t) af & (int32_t) bf);
break;
case snek_op_lor:
af = (float) ((int32_t) af | (int32_t) bf);
break;
case snek_op_lxor:
af = (float) ((int32_t) af ^ (int32_t) bf);
break;
case snek_op_lshift:
af = (float) ((int32_t) af << (int32_t) bf);
break;
case snek_op_rshift:
af = (float) ((int32_t) af >> (int32_t) bf);
break;
default:
break;
}
ret = snek_float_to_poly(af);
break;
}
ret = snek_float_to_poly(af);
} else {
switch (op) {
case snek_op_in:
Expand All @@ -767,7 +768,7 @@ snek_binary(snek_poly_t a, snek_op_t op, snek_poly_t b, bool inplace)
snek_offset_t o, step = snek_list_type(bl) == snek_list_dict ? 2 : 1;
found = false;
for (o = 0; o < bl->size; o += step) {
if (snek_poly_equal(a, snek_list_data(bl)[o], false)) {
if (snek_poly_cmp(a, snek_list_data(bl)[o], false) == 0) {
found = true;
break;
}
Expand Down
28 changes: 17 additions & 11 deletions snek-list.c
Expand Up @@ -142,7 +142,7 @@ _snek_list_ref(snek_list_t *list, snek_poly_t p, bool report_error, bool add)

if (snek_list_type(list) == snek_list_dict) {
for (o = 0; o < list->size; o += 2) {
if (snek_poly_equal(p, snek_list_data(list)[o], false)) {
if (snek_poly_cmp(p, snek_list_data(list)[o], false) == 0) {
o++;
goto done;
}
Expand Down Expand Up @@ -187,19 +187,25 @@ snek_list_get(snek_list_t *list, snek_poly_t p, bool report_error)
return SNEK_ZERO;
}

bool
snek_list_equal(snek_list_t *a, snek_list_t *b)
int8_t
snek_list_cmp(snek_list_t *a, snek_list_t *b)
{
if (snek_list_type(a) != snek_list_type(b))
return false;
if (a->size != b->size)
return false;
int8_t diff = snek_list_type(a) - snek_list_type(b);
if (diff)
return diff;
snek_poly_t *adata = snek_list_data(a);
snek_poly_t *bdata = snek_list_data(b);
for (snek_offset_t o = 0; o < a->size; o++)
if (!snek_poly_equal(adata[o], bdata[o], false))
return false;
return true;

snek_offset_t o;
for (o = 0; o < a->size; o++) {
if (o >= b->size)
return 1;

diff = snek_poly_cmp(adata[o], bdata[o], false);
if (diff)
return diff;
}
return b->size > o;
}

snek_poly_t
Expand Down
23 changes: 12 additions & 11 deletions snek-poly.c
Expand Up @@ -69,26 +69,27 @@ snek_poly_print(FILE *file, snek_poly_t poly, char format)
snek_poly_format(&buf, poly, format);
}

bool
snek_poly_equal(snek_poly_t a, snek_poly_t b, bool is)
int8_t
snek_poly_cmp(snek_poly_t a, snek_poly_t b, bool is)
{
if (a.u == b.u)
return true;
snek_type_t atype = snek_poly_type(a);
snek_type_t btype = snek_poly_type(b);
if (atype != btype)
return false;

int8_t tdiff = atype - btype;
if (tdiff)
return tdiff;
switch (atype) {
case snek_float:
return (b.f < a.f) - (a.f < b.f);
case snek_string:
return !strcmp(snek_poly_to_string(a), snek_poly_to_string(b));
return strcmp(snek_poly_to_string(a), snek_poly_to_string(b));
case snek_list:
if (!is)
return snek_list_equal(snek_poly_to_list(a), snek_poly_to_list(b));
break;
return snek_list_cmp(snek_poly_to_list(a), snek_poly_to_list(b));
/* fall through */
default:
break;
return (b.u < a.u) - (a.u < b.u);
}
return false;
}

bool
Expand Down
8 changes: 4 additions & 4 deletions snek.h
Expand Up @@ -568,8 +568,8 @@ snek_list_get(snek_list_t *list, snek_poly_t p, bool report_error);
snek_poly_t *
snek_list_data(snek_list_t *list);

bool
snek_list_equal(snek_list_t *a, snek_list_t *b);
int8_t
snek_list_cmp(snek_list_t *a, snek_list_t *b);

snek_poly_t
snek_list_imm(snek_offset_t size, snek_list_type_t type);
Expand Down Expand Up @@ -718,8 +718,8 @@ snek_poly_type(snek_poly_t v);
void
snek_poly_print(FILE *file, snek_poly_t poly, char format);

bool
snek_poly_equal(snek_poly_t a, snek_poly_t b, bool is);
int8_t
snek_poly_cmp(snek_poly_t a, snek_poly_t b, bool is);

bool
snek_poly_true(snek_poly_t a);
Expand Down

0 comments on commit b756548

Please sign in to comment.