aboutsummaryrefslogtreecommitdiff
path: root/tag.c
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2025-05-09 18:29:52 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2025-05-09 18:29:52 +0100
commitba5c0a4579ece5d53c009a14d00e683e70b982f4 (patch)
treead7e6788b8ce634172f9a5cdee0a1a9ac08c7788 /tag.c
parent576bf0f3085022e9117d78e3b4e19971c82a61d6 (diff)
downloadoats-ba5c0a4579ece5d53c009a14d00e683e70b982f4.tar.gz
oats-ba5c0a4579ece5d53c009a14d00e683e70b982f4.tar.bz2
oats-ba5c0a4579ece5d53c009a14d00e683e70b982f4.zip
Initial implementation
Diffstat (limited to 'tag.c')
-rw-r--r--tag.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/tag.c b/tag.c
new file mode 100644
index 0000000..5fc03e0
--- /dev/null
+++ b/tag.c
@@ -0,0 +1,94 @@
+/* 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 GNU General Public License Version 2 for
+ * details.
+
+ * You may distribute and modify this code under the terms of the GNU General
+ * Public License Version 2, which you should have received a copy of along with
+ * this program. If not, please go to <https://www.gnu.org/licenses/>.
+
+ * Created: 2025-04-06
+ * Description:
+ */
+
+#include <string.h>
+#include <tag.h>
+
+lisp_t *tag_int(i64 i)
+{
+ return TAG((u64)i, INT);
+}
+
+lisp_t *tag_cons(void *ptr)
+{
+ return TAG((u64)ptr, CONS);
+}
+
+lisp_t *tag_sym(void *ptr)
+{
+ return TAG((u64)ptr, SYM);
+}
+
+lisp_t *tag_ssym(const char *data, size_t size)
+{
+ assert(size <= 7);
+ u8 buffer[sizeof(u64)];
+ memset(buffer, 0, sizeof(buffer));
+ // in 8 bits we have:
+ // size - 3 bits (up to 7)
+ // tag - 5 bits
+ buffer[0] = size;
+ buffer[0] <<= SHIFT_SSYM;
+ buffer[0] |= TAG_SSYM;
+ memcpy(buffer + 1, data, size);
+ u64 word = 0;
+ memcpy(&word, buffer, sizeof(u64));
+ return (lisp_t *)word;
+}
+
+lisp_t *tag_bool(bool b)
+{
+ return TAG((u64)b, BOOL);
+}
+
+lisp_t *tag_vec(void *ptr)
+{
+ return TAG((u64)ptr, VEC);
+}
+
+lisp_t *tag_str(void *ptr)
+{
+ return TAG((u64)ptr, STR);
+}
+
+lisp_t *tag_char(u32 codepoint)
+{
+ u64 w = codepoint;
+ return TAG(w, CHAR);
+}
+
+enum Tag tag_get(lisp_t *ptr)
+{
+ static_assert(NUM_TAGS == 9);
+ if (!ptr)
+ return TAG_NIL;
+ else if (IS_TAG(ptr, INT))
+ return TAG_INT;
+ else if (IS_TAG(ptr, CHAR))
+ return TAG_CHAR;
+ else if (IS_TAG(ptr, SYM))
+ return TAG_SYM;
+ else if (IS_TAG(ptr, SSYM))
+ return TAG_SSYM;
+ else if (IS_TAG(ptr, BOOL))
+ return TAG_BOOL;
+ else if (IS_TAG(ptr, VEC))
+ return TAG_VEC;
+ else if (IS_TAG(ptr, STR))
+ return TAG_STR;
+ else if (IS_TAG(ptr, CONS))
+ return TAG_CONS;
+ return 0;
+}