/* 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 . * Created: 2025-04-06 * Description: */ #include #include 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; }