aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2025-08-21 14:54:57 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2025-08-21 14:55:54 +0100
commit0f68afd9a040256939ddd082a380bd37b0a3996b (patch)
tree2c59292ca62bfe70a09b7e7efadfcc756b0914c6
parent742f19886cce986d0d01606b07dd533fbffe2cdd (diff)
downloadalisp-0f68afd9a040256939ddd082a380bd37b0a3996b.tar.gz
alisp-0f68afd9a040256939ddd082a380bd37b0a3996b.tar.bz2
alisp-0f68afd9a040256939ddd082a380bd37b0a3996b.zip
Make nicer primitive functions for car/cdr
If it isn't a CONS, we return NIL instead of failing. This way, we can use it in our general iteration functions. Eventually the actual runtime would use this as well. The macros are mostly for internal use to do assignment etc.
-rw-r--r--alisp.h3
-rw-r--r--constructor.c16
-rw-r--r--sys.c9
3 files changed, 24 insertions, 4 deletions
diff --git a/alisp.h b/alisp.h
index c3d25c3..e9694d9 100644
--- a/alisp.h
+++ b/alisp.h
@@ -126,6 +126,9 @@ vec_t *as_vec(lisp_t *);
#define CAR(L) (as_cons(L)->car)
#define CDR(L) (as_cons(L)->cdr)
+lisp_t *car(lisp_t *);
+lisp_t *cdr(lisp_t *);
+
/// Pointer tagging scheme for lisps
typedef enum Tag
diff --git a/constructor.c b/constructor.c
index 9db0330..e0fab52 100644
--- a/constructor.c
+++ b/constructor.c
@@ -46,3 +46,19 @@ lisp_t *intern(sys_t *sys, sv_t sv)
char *str = sym_table_find(&sys->symtable, sv);
return tag_sym(str);
}
+
+lisp_t *car(lisp_t *lsp)
+{
+ if (!IS_TAG(lsp, CONS))
+ return NIL;
+ else
+ return CAR(lsp);
+}
+
+lisp_t *cdr(lisp_t *lsp)
+{
+ if (!IS_TAG(lsp, CONS))
+ return NIL;
+ else
+ return CDR(lsp);
+}
diff --git a/sys.c b/sys.c
index d3a9bb2..ac26a88 100644
--- a/sys.c
+++ b/sys.c
@@ -43,12 +43,13 @@ void sys_cleanup(sys_t *sys)
return;
// Iterate through each element of memory
- for (lisp_t *cell = sys->memory, *next = CDR(cell); cell;
- cell = next, next = CDR(cell))
+ for (lisp_t *cell = sys->memory, *next = cdr(cell); cell;
+ cell = next, next = cdr(next))
{
// Only reason allocated exists is because we had to allocate memory on the
- // heap for it. It's therefore
- lisp_t *allocated = CAR(cell);
+ // heap for it. It's therefore enough to deal with only the allocated
+ // types.
+ lisp_t *allocated = car(cell);
switch (get_tag(allocated))
{
case TAG_CONS: