summaryrefslogtreecommitdiffstats
path: root/gencadr.txr
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-07-21 22:14:23 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-07-21 22:14:23 -0700
commitf10ed814f895f2527b99fc6a55057617a7750ba7 (patch)
tree7e0c421f9b284f195c8e3fae239ef84463d8f0ad /gencadr.txr
parent701d5ff8c6a2d4ca6023be345faf4f085db6c689 (diff)
downloadtxr-f10ed814f895f2527b99fc6a55057617a7750ba7.tar.gz
txr-f10ed814f895f2527b99fc6a55057617a7750ba7.tar.bz2
txr-f10ed814f895f2527b99fc6a55057617a7750ba7.zip
Implementing caar, cadr, cdar and friends.
* lib.c (init): Call cadr_init. * lisplib.c (dl_table, set_dlt_entries, dlt_register): Externalize. * lisplib.h (dl_table, set_dlt_entries, dlt_register): Declared. * Makefile (OBJS): Add cadr.o. * cadr.c: New file. * cadr.h: New file. * gencadr.txr: New file. * share/txr/stdlib/cadr.tl: New file. * txr.1: Document cadr accessors.
Diffstat (limited to 'gencadr.txr')
-rw-r--r--gencadr.txr109
1 files changed, 109 insertions, 0 deletions
diff --git a/gencadr.txr b/gencadr.txr
new file mode 100644
index 00000000..f21386fd
--- /dev/null
+++ b/gencadr.txr
@@ -0,0 +1,109 @@
+@(bind ad @(append-each* ((i (range 2 5))) (rperm "ad" i)))
+@(do
+ (defun compile-ad (string arg)
+ (casequal string
+ ("" arg)
+ (t `c@[string 0]r(@(compile-ad [string 1..:] arg))`))))
+@(next "lib.c")
+@(collect)
+@{c-copyright}
+@(until)
+
+@(end)
+@(next "share/txr/stdlib/place.tl")
+@(collect)
+@{tl-copyright}
+@(until)
+
+@(end)
+@(output "cadr.c")
+@{c-copyright "\n"}
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <limits.h>
+#include <signal.h>
+#include "config.h"
+#include "lib.h"
+#include "gc.h"
+#include "signal.h"
+#include "unwind.h"
+#include "eval.h"
+#include "stream.h"
+#include "lisplib.h"
+#include "txr.h"
+#include "cadr.h"
+@ (repeat)
+
+val c@{ad}r(val cons)
+{
+ return @(compile-ad ad 'cons);
+}
+@ (end)
+
+static val cadr_register(val set_fun)
+{
+ funcall1(set_fun, nil);
+@ (repeat)
+ reg_fun(intern(lit("c@{ad}r"), user_package), func_n1(c@{ad}r));
+@ (end)
+ load(format(nil, lit("~a/cadr.tl"), stdlib_path, nao));
+ return nil;
+}
+
+static val cadr_set_entries(val dlt, val fun)
+{
+ val name[] = {
+@ (repeat)
+ lit("c@{ad}r"),
+@ (end)
+ nil
+ };
+
+ set_dlt_entries(dlt, name, fun);
+ return nil;
+}
+
+void cadr_init(void)
+{
+ dlt_register(dl_table, cadr_register, cadr_set_entries);
+}
+@(end)
+@(output "cadr.h")
+@{c-copyright "\n"}
+
+@ (repeat)
+val c@{ad}r(val);
+@ (end)
+
+void cadr_init(void);
+@(end)
+@(output "share/txr/stdlib/cadr.tl")
+@{tl-copyright "\n"}
+@ (repeat)
+
+(defplace (c@{ad}r cell) body
+ (getter setter
+ (with-gensyms (cell-sym)
+ ^(rlet ((,cell-sym (c@{ad [1..:]}r ,cell)))
+ (macrolet ((,getter () ^(c@{ad [0]}r ,',cell-sym))
+ (,setter (val) ^(sys:rplac@{ad [0]} ,',cell-sym ,val)))
+ ,body))))
+ (ssetter
+ ^(macrolet ((,ssetter (val) ^(sys:rplac@{ad [0]} (c@{ad [1..:]}r ,',cell) ,val)))
+ ,body))
+ (deleter
+ ^(macrolet ((,deleter ()
+ (with-gensyms (tmp)
+ (with-update-expander (cgetter csetter) '(c@{ad [1..:]}r ,cell) nil
+ ^(let ((,tmp (,cgetter)))
+ @(if (equal [ad 0] #\a)
+ `(prog1 (car ,tmp) (,csetter (cdr ,tmp)))`
+ `(prog1 (cdr ,tmp) (,csetter (car ,tmp)))`))))))
+ ,body)))
+@ (end)
+@(end)