2014-01-17 06:58:31 -05:00
|
|
|
/**
|
|
|
|
* See Copyright Notice in picrin.h
|
|
|
|
*/
|
|
|
|
|
2013-10-22 23:39:48 -04:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
2013-10-10 04:06:26 -04:00
|
|
|
#include "picrin.h"
|
2013-10-19 23:34:57 -04:00
|
|
|
#include "picrin/pair.h"
|
2013-10-10 04:06:26 -04:00
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_cons(pic_state *pic, pic_value car, pic_value cdr)
|
|
|
|
{
|
|
|
|
struct pic_pair *pair;
|
|
|
|
|
2013-10-13 03:55:07 -04:00
|
|
|
pair = (struct pic_pair *)pic_obj_alloc(pic, sizeof(struct pic_pair), PIC_TT_PAIR);
|
2013-10-10 04:06:26 -04:00
|
|
|
pair->car = car;
|
|
|
|
pair->cdr = cdr;
|
|
|
|
|
|
|
|
return pic_obj_value(pair);
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_car(pic_state *pic, pic_value obj)
|
|
|
|
{
|
|
|
|
struct pic_pair *pair;
|
|
|
|
|
2013-10-20 10:30:01 -04:00
|
|
|
if (! pic_pair_p(obj)) {
|
|
|
|
pic_error(pic, "pair required");
|
|
|
|
}
|
2013-11-05 00:27:59 -05:00
|
|
|
pair = pic_pair_ptr(obj);
|
2013-10-10 04:06:26 -04:00
|
|
|
|
|
|
|
return pair->car;
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_cdr(pic_state *pic, pic_value obj)
|
|
|
|
{
|
|
|
|
struct pic_pair *pair;
|
|
|
|
|
2013-10-20 10:30:01 -04:00
|
|
|
if (! pic_pair_p(obj)) {
|
|
|
|
pic_error(pic, "pair required");
|
|
|
|
}
|
2013-11-05 00:27:59 -05:00
|
|
|
pair = pic_pair_ptr(obj);
|
2013-10-10 04:06:26 -04:00
|
|
|
|
|
|
|
return pair->cdr;
|
|
|
|
}
|
2013-10-19 23:34:57 -04:00
|
|
|
|
2013-10-20 23:03:35 -04:00
|
|
|
bool
|
|
|
|
pic_list_p(pic_state *pic, pic_value obj)
|
|
|
|
{
|
|
|
|
while (pic_pair_p(obj))
|
|
|
|
obj = pic_pair_ptr(obj)->cdr;
|
|
|
|
|
|
|
|
return pic_nil_p(obj);
|
|
|
|
}
|
|
|
|
|
2013-10-22 23:39:48 -04:00
|
|
|
pic_value
|
|
|
|
pic_list(pic_state *pic, size_t c, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
pic_value v;
|
|
|
|
|
|
|
|
va_start(ap, c);
|
|
|
|
|
|
|
|
v = pic_nil_value();
|
|
|
|
while (c--) {
|
|
|
|
v = pic_cons(pic, va_arg(ap, pic_value), v);
|
|
|
|
}
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
return pic_reverse(pic, v);
|
|
|
|
}
|
|
|
|
|
2013-11-17 04:16:03 -05:00
|
|
|
pic_value
|
|
|
|
pic_list_from_array(pic_state *pic, size_t c, pic_value *vs)
|
|
|
|
{
|
|
|
|
pic_value v;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
v = pic_nil_value();
|
|
|
|
for (i = 0; i < c; ++i) {
|
|
|
|
v = pic_cons(pic, vs[i], v);
|
|
|
|
}
|
|
|
|
return pic_reverse(pic, v);
|
|
|
|
}
|
|
|
|
|
2013-10-24 08:55:07 -04:00
|
|
|
int
|
|
|
|
pic_length(pic_state *pic, pic_value obj)
|
|
|
|
{
|
|
|
|
int c = 0;
|
|
|
|
|
|
|
|
while (! pic_nil_p(obj)) {
|
|
|
|
obj = pic_cdr(pic, obj);
|
|
|
|
++c;
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2013-10-21 11:19:43 -04:00
|
|
|
pic_value
|
|
|
|
pic_reverse(pic_state *pic, pic_value list)
|
|
|
|
{
|
2013-11-21 09:32:56 -05:00
|
|
|
int ai = pic_gc_arena_preserve(pic);
|
|
|
|
pic_value v, acc;
|
2013-10-21 11:19:43 -04:00
|
|
|
|
2013-11-21 09:32:56 -05:00
|
|
|
acc = pic_nil_value();
|
2013-10-21 11:19:43 -04:00
|
|
|
for (v = list; ! pic_nil_p(v); v = pic_cdr(pic ,v)) {
|
|
|
|
acc = pic_cons(pic, pic_car(pic, v), acc);
|
2013-11-21 09:32:56 -05:00
|
|
|
|
|
|
|
pic_gc_arena_restore(pic, ai);
|
|
|
|
pic_gc_protect(pic, acc);
|
|
|
|
pic_gc_protect(pic, v);
|
2013-10-21 11:19:43 -04:00
|
|
|
}
|
|
|
|
return acc;
|
|
|
|
}
|
|
|
|
|
2014-01-22 06:57:14 -05:00
|
|
|
pic_value
|
|
|
|
pic_append(pic_state *pic, pic_value xs, pic_value ys)
|
|
|
|
{
|
|
|
|
int ai = pic_gc_arena_preserve(pic);
|
|
|
|
|
|
|
|
if (pic_nil_p(xs)) {
|
|
|
|
return ys;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
xs = pic_cons(pic, pic_car(pic, xs), pic_append(pic, pic_cdr(pic, xs), ys));
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_gc_arena_restore(pic, ai);
|
|
|
|
pic_gc_protect(pic, xs);
|
|
|
|
return xs;
|
|
|
|
}
|
|
|
|
|
2013-10-19 23:34:57 -04:00
|
|
|
pic_value
|
|
|
|
pic_assq(pic_state *pic, pic_value key, pic_value assoc)
|
|
|
|
{
|
|
|
|
pic_value cell;
|
|
|
|
|
|
|
|
enter:
|
|
|
|
|
|
|
|
if (pic_nil_p(assoc))
|
2013-12-08 02:13:45 -05:00
|
|
|
return pic_false_value();
|
2013-10-19 23:34:57 -04:00
|
|
|
|
|
|
|
cell = pic_car(pic, assoc);
|
2013-11-06 02:06:31 -05:00
|
|
|
if (pic_eq_p(key, pic_car(pic, cell)))
|
2013-12-07 09:30:21 -05:00
|
|
|
return cell;
|
|
|
|
|
|
|
|
assoc = pic_cdr(pic, assoc);
|
|
|
|
goto enter;
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_assoc(pic_state *pic, pic_value key, pic_value assoc)
|
|
|
|
{
|
|
|
|
pic_value cell;
|
|
|
|
|
|
|
|
enter:
|
|
|
|
|
|
|
|
if (pic_nil_p(assoc))
|
2013-12-08 02:13:45 -05:00
|
|
|
return pic_false_value();
|
2013-12-07 09:30:21 -05:00
|
|
|
|
|
|
|
cell = pic_car(pic, assoc);
|
|
|
|
if (pic_equal_p(pic, key, pic_car(pic, cell)))
|
2013-10-19 23:34:57 -04:00
|
|
|
return cell;
|
|
|
|
|
|
|
|
assoc = pic_cdr(pic, assoc);
|
|
|
|
goto enter;
|
|
|
|
}
|
2013-10-20 01:04:39 -04:00
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_acons(pic_state *pic, pic_value key, pic_value val, pic_value assoc)
|
|
|
|
{
|
|
|
|
return pic_cons(pic, pic_cons(pic, key, val), assoc);
|
|
|
|
}
|
2013-10-22 23:01:06 -04:00
|
|
|
|
2013-11-26 05:42:13 -05:00
|
|
|
pic_value
|
|
|
|
pic_caar(pic_state *pic, pic_value v)
|
|
|
|
{
|
|
|
|
return pic_car(pic, pic_car(pic, v));
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_cadr(pic_state *pic, pic_value v)
|
|
|
|
{
|
|
|
|
return pic_car(pic, pic_cdr(pic, v));
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_cdar(pic_state *pic, pic_value v)
|
|
|
|
{
|
|
|
|
return pic_cdr(pic, pic_car(pic, v));
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_cddr(pic_state *pic, pic_value v)
|
|
|
|
{
|
|
|
|
return pic_cdr(pic, pic_cdr(pic, v));
|
|
|
|
}
|
|
|
|
|
2014-01-22 06:57:05 -05:00
|
|
|
pic_value
|
|
|
|
pic_list_tail(pic_state *pic, pic_value list, int i)
|
|
|
|
{
|
|
|
|
while (i-- > 0) {
|
|
|
|
list = pic_cdr(pic, list);
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_list_ref(pic_state *pic, pic_value list, int i)
|
|
|
|
{
|
|
|
|
return pic_car(pic, pic_list_tail(pic, list, i));
|
|
|
|
}
|
|
|
|
|
2013-10-24 11:37:08 -04:00
|
|
|
static pic_value
|
|
|
|
pic_pair_pair_p(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v;
|
|
|
|
|
|
|
|
pic_get_args(pic, "o", &v);
|
|
|
|
|
|
|
|
return pic_bool_value(pic_pair_p(v));
|
|
|
|
}
|
|
|
|
|
2013-11-15 02:07:03 -05:00
|
|
|
static pic_value
|
|
|
|
pic_pair_car(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v;
|
|
|
|
|
|
|
|
pic_get_args(pic, "o", &v);
|
|
|
|
|
|
|
|
return pic_car(pic, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_pair_cdr(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v;
|
|
|
|
|
|
|
|
pic_get_args(pic, "o", &v);
|
|
|
|
|
|
|
|
return pic_cdr(pic, v);
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_pair_null_p(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v;
|
|
|
|
|
|
|
|
pic_get_args(pic, "o", &v);
|
|
|
|
|
|
|
|
return pic_bool_value(pic_nil_p(v));
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_pair_cons(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v,w;
|
|
|
|
|
|
|
|
pic_get_args(pic, "oo", &v, &w);
|
|
|
|
|
|
|
|
return pic_cons(pic, v, w);
|
|
|
|
}
|
|
|
|
|
2013-10-22 23:01:06 -04:00
|
|
|
static pic_value
|
|
|
|
pic_pair_set_car(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v,w;
|
|
|
|
|
|
|
|
pic_get_args(pic, "oo", &v, &w);
|
|
|
|
|
|
|
|
if (! pic_pair_p(v))
|
|
|
|
pic_error(pic, "pair expected");
|
|
|
|
|
|
|
|
pic_pair_ptr(v)->car = w;
|
2014-01-08 01:22:23 -05:00
|
|
|
return pic_none_value();
|
2013-10-22 23:01:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_pair_set_cdr(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value v,w;
|
|
|
|
|
|
|
|
pic_get_args(pic, "oo", &v, &w);
|
|
|
|
|
|
|
|
if (! pic_pair_p(v))
|
|
|
|
pic_error(pic, "pair expected");
|
|
|
|
|
|
|
|
pic_pair_ptr(v)->cdr = w;
|
2014-01-08 01:22:23 -05:00
|
|
|
return pic_none_value();
|
2013-10-22 23:01:06 -04:00
|
|
|
}
|
|
|
|
|
2014-01-22 07:00:29 -05:00
|
|
|
static pic_value
|
|
|
|
pic_pair_list_tail(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value list;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pic_get_args(pic, "oi", &list, &i);
|
|
|
|
|
|
|
|
return pic_list_tail(pic, list, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_pair_list_ref(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value list;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
pic_get_args(pic, "oi", &list, &i);
|
|
|
|
|
|
|
|
return pic_list_ref(pic, list, i);
|
|
|
|
}
|
|
|
|
|
2013-10-22 23:01:06 -04:00
|
|
|
void
|
|
|
|
pic_init_pair(pic_state *pic)
|
|
|
|
{
|
2013-10-24 11:37:08 -04:00
|
|
|
pic_defun(pic, "pair?", pic_pair_pair_p);
|
2013-11-15 02:07:03 -05:00
|
|
|
pic_defun(pic, "car", pic_pair_car);
|
|
|
|
pic_defun(pic, "cdr", pic_pair_cdr);
|
|
|
|
pic_defun(pic, "null?", pic_pair_null_p);
|
|
|
|
pic_defun(pic, "cons", pic_pair_cons);
|
2013-10-22 23:01:06 -04:00
|
|
|
pic_defun(pic, "set-car!", pic_pair_set_car);
|
|
|
|
pic_defun(pic, "set-cdr!", pic_pair_set_cdr);
|
2014-01-22 07:00:29 -05:00
|
|
|
pic_defun(pic, "list-tail", pic_pair_list_tail);
|
|
|
|
pic_defun(pic, "list-ref", pic_pair_list_ref);
|
2013-10-22 23:01:06 -04:00
|
|
|
}
|