123 lines
2.7 KiB
C
123 lines
2.7 KiB
C
#include <stdio.h>
|
|
#include <gc.h>
|
|
#include <string.h>
|
|
#include "gyehoek.h"
|
|
|
|
|
|
|
|
const long scm_tc3_cons = 0;
|
|
|
|
const long scm_tc7_weak_set = 0x55;
|
|
const long scm_tc7_symbol = 0x05;
|
|
const long scm_tc7_string = 0x15;
|
|
|
|
|
|
|
|
SCM scm_newline () {
|
|
putc ('\n', stdout);
|
|
return SCM_PACK(NULL);
|
|
}
|
|
|
|
size_t scm_c_string_length (SCM str) {
|
|
return SCM_CELL_WORD (str, 1);
|
|
}
|
|
|
|
const char *scm_c_string_chars (SCM str) {
|
|
return (const char *) SCM_UNPACK_POINTER (SCM_CELL_OBJECT (str, 2));
|
|
}
|
|
|
|
static void scm_write_string (SCM x) {
|
|
const size_t len = scm_c_string_length (x);
|
|
const char *s = scm_c_string_chars (x);
|
|
/* FIXME: this is a very naïve implementation with no escaping. */
|
|
printf ("some unrelated unicode lol: %s\n", "왜 하냐??");
|
|
printf ("\"%.*s\"", (int) len, s);
|
|
}
|
|
|
|
SCM scm_write (SCM x) {
|
|
if (SCM_IMP (x)) {
|
|
printf ("%ld", SCM_UNPACK (x) >> 2);
|
|
} else if (SCM_CONSP (x)) {
|
|
printf ("(");
|
|
scm_write (scm_car (x));
|
|
printf (" . ");
|
|
scm_write (scm_cdr (x));
|
|
printf (")");
|
|
} else if (SCM_STRINGP (x)) {
|
|
scm_write_string (x);
|
|
} else {
|
|
printf ("#<heap object 0x%016lx>", SCM_UNPACK (x));
|
|
}
|
|
return SCM_PACK(NULL);
|
|
}
|
|
|
|
SCM scm_car (SCM x) {
|
|
return SCM_CELL_OBJECT (x, 0);
|
|
}
|
|
|
|
SCM scm_cdr (SCM x) {
|
|
return SCM_CELL_OBJECT (x, 1);
|
|
}
|
|
|
|
SCM scm_words (scm_t_bits word_0, uint32_t n_words) {
|
|
scm_t_bits *r = GC_malloc (n_words * sizeof (scm_t_bits));
|
|
r[0] = word_0;
|
|
return SCM_PACK (r);
|
|
}
|
|
|
|
SCM scm_from_utf8_string (const char *str, size_t len) {
|
|
SCM r = scm_words (scm_tc7_string, 3);
|
|
SCM_SET_CELL_WORD (r, 1, len);
|
|
SCM_SET_CELL_WORD (r, 2, str);
|
|
return r;
|
|
}
|
|
|
|
SCM scm_from_cstring (const char *str) {
|
|
return scm_from_utf8_string (str, strlen (str));
|
|
}
|
|
|
|
unsigned long scm_c_hash (SCM str) {
|
|
const unsigned long offset_basis = 0xcbf29ce484222325;
|
|
const unsigned long prime = 0x100000001b3;
|
|
const size_t len = scm_c_string_length (str);
|
|
const char *bytes = scm_c_string_chars (str);
|
|
unsigned long hash = offset_basis;
|
|
|
|
for (const char *c = bytes; c < bytes + len; c++) {
|
|
hash ^= *c;
|
|
hash *= prime;
|
|
}
|
|
|
|
// mask off MSB, since we use it to mark tombstones in weak-set.c.
|
|
/* hash &= 0x7fffffffffffffff; */
|
|
|
|
// shift off MSB, since we use it to mark tombstones in weak-set.c.
|
|
/* hash >>= 1; */
|
|
|
|
/* ensure hash is non-zero */
|
|
hash |= hash == 0;
|
|
|
|
return hash;
|
|
}
|
|
|
|
SCM scm_str_to_symbol (SCM str) {
|
|
|
|
}
|
|
|
|
SCM scm_from_utf8_symbol (const char *s, size_t len) {
|
|
}
|
|
|
|
SCM scm_cons (SCM car, SCM cdr) {
|
|
scm_t_bits *r = GC_malloc (2 * sizeof (scm_t_bits));
|
|
r[0] = SCM_UNPACK (car);
|
|
r[1] = SCM_UNPACK (cdr);
|
|
return SCM_PACK (r);
|
|
}
|
|
|
|
SCM scm_make_symbol (SCM name, unsigned long hash) {
|
|
SCM r = scm_words(scm_tc7_symbol, 3);
|
|
SCM_SET_CELL_WORD (r, 1, hash);
|
|
SCM_SET_CELL_OBJECT (r, 2, name);
|
|
return r;
|
|
}
|