95 lines
1.9 KiB
C
95 lines
1.9 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 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;
|
|
}
|