Files
thesis-lisp/vm/vmval.c
T
2021-04-07 22:24:33 +03:00

101 lines
2.2 KiB
C

#include "vmval.h"
#include <stdlib.h>
#include <stdio.h>
static void vm_print2(uint64_t w, int cdepth);
static void vm_print_ref(struct vm_value *value, int cdepth) {
uint64_t w0;
if (!value) {
printf("nil");
return;
}
switch (value->type) {
case VT_STRING:
printf("\"%s\"", vm_cstr(&value->v_string));
break;
case VT_CONS:
if (!cdepth) {
printf("(");
}
vm_print2(value->v_cons.fat_ar, 0);
w0 = value->v_cons.fat_dr;
if (!null_q(w0)) {
printf(" ");
if (cons_q(w0)) {
vm_print2(w0, cdepth + 1);
} else {
printf(". ");
vm_print2(w0, cdepth + 1);
}
}
if (!cdepth) {
printf(")");
}
break;
case VT_FUNC:
printf("<function %zu:%zu>", value->v_func.lib_index, value->v_func.fn_index);
break;
}
}
static void vm_print2(uint64_t w, int cdepth) {
if (w & FLAG_REF) {
vm_print_ref((void *) (w << 1), cdepth);
} else {
if (w & (1ULL << 62)) {
w |= 1ULL << 63;
}
printf("%ld", (int64_t) w);
}
}
static struct vm_value *vm_value_create(enum vm_type type) {
struct vm_value *v = calloc(1, sizeof(struct vm_value));
if (!v) {
return NULL;
}
v->type = type;
v->refcount = 0;
return v;
}
void vm_value_free(struct vm_value *v) {
assert(v->refcount == 0);
free(v);
}
struct vm_value *vm_cons(uint64_t w0, uint64_t w1) {
struct vm_value *v = vm_value_create(VT_CONS);
if (!v) {
return NULL;
}
v->v_cons.fat_ar = w0;
v->v_cons.fat_dr = w1;
return v;
}
struct vm_value *vm_makestr(const char *str) {
struct vm_value *v = vm_value_create(VT_STRING);
if (!v) {
return NULL;
}
vm_string_init(&v->v_string, str);
return v;
}
struct vm_value *vm_func(size_t lib_index, size_t fn_index) {
struct vm_value *v = vm_value_create(VT_FUNC);
if (!v) {
return NULL;
}
v->v_func.lib_index = lib_index;
v->v_func.fn_index = fn_index;
return v;
}
void vm_print(uint64_t w) {
vm_print2(w, 0);
}