This repository has been archived on 2025-11-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
alisp/tag.c
Aryadev Chavali 779c4b8305 Conses and Vectors for my tagging scheme
Unfortunately, due to how vectors are implemented, pointers to them
are unstable.  We need to box them one more time (therefore adding a
level of indirection) in order to stabilise them.  This is annoying
but currently necessary.

Even if we implemented vectors as {u64, u64, ptr} instead of {u64,
u64, bytes...}, we'd still have the same problem at access - two
levels of indirection.  I guess size and capacity checks would be one
level of indirection which is nice at least, but we're already screwed
at the point of doing lookup either way.
2025-08-19 23:21:41 +01:00

65 lines
1.3 KiB
C

/* Copyright (C) 2025 Aryadev Chavali
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the Unlicense for details.
* You may distribute and modify this code under the terms of the Unlicense,
* which you should have received a copy of along with this program. If not,
* please go to <https://unlicense.org/>.
* Created: 2025-08-19
* Description: Pointer tagging
*/
#include <assert.h>
#include <stdlib.h>
#include "./base.h"
lisp_t *tag_int(i64 i)
{
return TAG((u64)i, INT);
}
lisp_t *tag_sym(char *str)
{
return TAG((u64)str, SYM);
}
lisp_t *tag_cons(cons_t *cons)
{
return TAG((u64)cons, CONS);
}
i64 as_int(lisp_t *obj)
{
assert(IS_TAG(obj, INT));
u64 p_obj = (u64)obj;
return UNTAG(p_obj, INT) | // Delete the tag
(NTH_BYTE(p_obj, 7) & 0x80) << 56 // duplicate the MSB (preserve sign)
;
}
char *as_sym(lisp_t *obj)
{
assert(IS_TAG(obj, SYM));
return (char *)UNTAG(obj, SYM);
}
cons_t *as_cons(lisp_t *obj)
{
assert(IS_TAG(obj, CONS));
return (cons_t *)UNTAG(obj, CONS);
}
void *as_vec(lisp_t *obj)
{
assert(IS_TAG(obj, VEC));
lvec_t *vec = (lvec_t *)UNTAG(obj, VEC);
if (vec)
return vec->data;
else
return NULL;
}