picrin/lib/bool.c

192 lines
3.7 KiB
C
Raw Normal View History

2014-08-25 00:38:09 -04:00
/**
* See Copyright Notice in picrin.h
*/
#include "picrin.h"
2017-05-05 23:53:20 -04:00
#include "value.h"
2017-03-28 10:09:40 -04:00
#include "object.h"
2017-05-05 23:53:20 -04:00
#include "state.h"
bool
2016-02-21 05:19:35 -05:00
pic_eq_p(pic_state *PIC_UNUSED(pic), pic_value x, pic_value y)
{
2017-05-05 23:53:20 -04:00
return value_eq_p(&x, &y);
}
bool
2016-02-21 05:19:35 -05:00
pic_eqv_p(pic_state *PIC_UNUSED(pic), pic_value x, pic_value y)
{
2017-05-05 23:53:20 -04:00
return value_eq_p(&x, &y);
}
2017-04-26 11:17:22 -04:00
bool
pic_equal_p(pic_state *pic, pic_value x, pic_value y)
2014-08-25 00:38:09 -04:00
{
LOOP:
if (pic_eqv_p(pic, x, y)) {
2014-08-25 00:38:09 -04:00
return true;
2015-06-24 17:44:45 -04:00
}
if (pic_type(pic, x) != pic_type(pic, y)) {
2014-08-25 00:38:09 -04:00
return false;
2015-06-24 17:44:45 -04:00
}
2014-08-25 00:38:09 -04:00
switch (pic_type(pic, x)) {
case PIC_TYPE_STRING: {
2017-03-28 10:31:15 -04:00
int xlen, ylen;
const char *xstr, *ystr;
xstr = pic_str(pic, x, &xlen);
ystr = pic_str(pic, y, &ylen);
if (xlen != ylen) {
return false;
}
return strcmp(xstr, ystr) == 0;
2015-06-24 17:44:45 -04:00
}
case PIC_TYPE_BLOB: {
2016-02-19 09:22:41 -05:00
int xlen, ylen;
const unsigned char *xbuf, *ybuf;
2015-06-24 17:44:45 -04:00
2016-02-19 09:22:41 -05:00
xbuf = pic_blob(pic, x, &xlen);
ybuf = pic_blob(pic, y, &ylen);
2014-08-25 00:38:09 -04:00
2016-02-19 09:22:41 -05:00
if (xlen != ylen) {
2015-06-24 17:44:45 -04:00
return false;
}
2017-03-28 10:31:15 -04:00
return memcmp(xbuf, ybuf, xlen) == 0;
2015-06-24 17:44:45 -04:00
}
case PIC_TYPE_PAIR: {
2017-04-26 11:17:22 -04:00
if (! pic_equal_p(pic, pic_car(pic, x), pic_car(pic, y))) {
2015-06-24 17:44:45 -04:00
return false;
2014-08-25 00:38:09 -04:00
}
2015-06-24 17:44:45 -04:00
x = pic_cdr(pic, x);
y = pic_cdr(pic, y);
goto LOOP; /* tail-call optimization */
2014-08-25 00:38:09 -04:00
}
case PIC_TYPE_VECTOR: {
2016-02-19 07:56:45 -05:00
int i, xlen, ylen;
2014-08-25 00:38:09 -04:00
2016-02-19 07:56:45 -05:00
xlen = pic_vec_len(pic, x);
ylen = pic_vec_len(pic, y);
2014-08-25 00:38:09 -04:00
2016-02-19 07:56:45 -05:00
if (xlen != ylen) {
2014-08-25 00:38:09 -04:00
return false;
}
2016-02-19 07:56:45 -05:00
for (i = 0; i < xlen; ++i) {
2017-04-26 11:17:22 -04:00
if (! pic_equal_p(pic, pic_vec_ref(pic, x, i), pic_vec_ref(pic, y, i)))
2014-08-25 00:38:09 -04:00
return false;
}
return true;
}
2017-04-26 11:17:22 -04:00
case PIC_TYPE_DICT: {
int it = 0;
pic_value key, val;
if (pic_dict_size(pic, x) != pic_dict_size(pic, y)) {
return false;
}
while (pic_dict_next(pic, x, &it, &key, &val)) {
if (! pic_dict_has(pic, y, key))
return false;
if (! pic_equal_p(pic, val, pic_dict_ref(pic, y, key)))
return false;
}
return true;
}
case PIC_TYPE_RECORD: {
if (! pic_eq_p(pic, pic_record_type(pic, x), pic_record_type(pic, y))) {
return false;
}
x = pic_record_datum(pic, x);
y = pic_record_datum(pic, y);
goto LOOP;
}
case PIC_TYPE_DATA: {
2016-02-19 09:30:47 -05:00
return pic_data(pic, x) == pic_data(pic, y);
}
2014-08-25 00:38:09 -04:00
default:
return false;
}
}
static pic_value
pic_bool_eq_p(pic_state *pic)
{
pic_value x, y;
pic_get_args(pic, "oo", &x, &y);
return pic_bool_value(pic, pic_eq_p(pic, x, y));
2014-08-25 00:38:09 -04:00
}
static pic_value
pic_bool_eqv_p(pic_state *pic)
{
pic_value x, y;
pic_get_args(pic, "oo", &x, &y);
return pic_bool_value(pic, pic_eqv_p(pic, x, y));
2014-08-25 00:38:09 -04:00
}
static pic_value
pic_bool_equal_p(pic_state *pic)
{
pic_value x, y;
pic_get_args(pic, "oo", &x, &y);
return pic_bool_value(pic, pic_equal_p(pic, x, y));
2014-08-25 00:38:09 -04:00
}
static pic_value
pic_bool_not(pic_state *pic)
{
pic_value v;
pic_get_args(pic, "o", &v);
2017-03-28 10:09:40 -04:00
return pic_bool_value(pic, pic_false_p(pic, v));
2014-08-25 00:38:09 -04:00
}
static pic_value
pic_bool_boolean_p(pic_state *pic)
{
pic_value v;
pic_get_args(pic, "o", &v);
2017-03-28 10:09:40 -04:00
return pic_bool_value(pic, pic_bool_p(pic, v));
2014-08-25 00:38:09 -04:00
}
static pic_value
pic_bool_boolean_eq_p(pic_state *pic)
{
2015-08-26 06:04:27 -04:00
int argc, i;
2014-08-25 00:38:09 -04:00
pic_value *argv;
pic_get_args(pic, "*", &argc, &argv);
for (i = 0; i < argc; ++i) {
if (! (pic_true_p(pic, argv[i]) || pic_false_p(pic, argv[i]))) {
return pic_false_value(pic);
2014-08-25 00:38:09 -04:00
}
if (! pic_eq_p(pic, argv[i], argv[0])) {
return pic_false_value(pic);
2014-08-25 00:38:09 -04:00
}
}
return pic_true_value(pic);
2014-08-25 00:38:09 -04:00
}
void
pic_init_bool(pic_state *pic)
{
pic_defun(pic, "eq?", pic_bool_eq_p);
pic_defun(pic, "eqv?", pic_bool_eqv_p);
pic_defun(pic, "equal?", pic_bool_equal_p);
2015-07-01 17:17:27 -04:00
pic_defun(pic, "not", pic_bool_not);
2014-08-25 00:38:09 -04:00
pic_defun(pic, "boolean?", pic_bool_boolean_p);
pic_defun(pic, "boolean=?", pic_bool_boolean_eq_p);
}