80 lines
1.6 KiB
C
80 lines
1.6 KiB
C
#pragma once
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#include "vmstring.h"
|
|
#include "vmstate.h"
|
|
|
|
enum vm_type {
|
|
VT_CONS,
|
|
VT_STRING,
|
|
VT_FUNC,
|
|
};
|
|
|
|
struct vm_value {
|
|
enum vm_type type;
|
|
size_t refcount;
|
|
union {
|
|
struct {
|
|
uintptr_t fat_ar, fat_dr;
|
|
} v_cons;
|
|
struct {
|
|
size_t lib_index, fn_index;
|
|
} v_func;
|
|
struct vm_string v_string;
|
|
};
|
|
};
|
|
|
|
static inline int ref_q(uint64_t w) {
|
|
return (w & FLAG_REF) != 0;
|
|
}
|
|
|
|
static inline int null_q(uint64_t w) {
|
|
return w == FLAG_REF;
|
|
}
|
|
|
|
static inline struct vm_value *getref(uint64_t w) {
|
|
assert(ref_q(w));
|
|
return (struct vm_value *) (w << 1);
|
|
}
|
|
|
|
static inline int cons_q(uint64_t w) {
|
|
if (ref_q(w)) {
|
|
return null_q(w) || getref(w)->type == VT_CONS;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static inline int func_q(uint64_t w) {
|
|
return ref_q(w) && !null_q(w) && getref(w)->type == VT_FUNC;
|
|
}
|
|
|
|
static inline int pair_q(uint64_t w) {
|
|
return ref_q(w) && (!null_q(w) && getref(w)->type == VT_CONS);
|
|
}
|
|
|
|
void vm_value_ref(struct vm_value *v);
|
|
int vm_value_unref(struct vm_value *v);
|
|
|
|
static inline void vm_ref(uint64_t w) {
|
|
if (ref_q(w)) {
|
|
vm_value_ref(getref(w));
|
|
}
|
|
}
|
|
static inline int vm_unref(uint64_t w) {
|
|
if (ref_q(w)) {
|
|
return vm_value_unref(getref(w));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void vm_value_free(struct vm_value *val);
|
|
|
|
struct vm_value *vm_cons(uint64_t w0, uint64_t w1);
|
|
struct vm_value *vm_makestr(const char *str);
|
|
struct vm_value *vm_func(size_t lib_index, size_t fn_index);
|
|
|
|
void vm_print(uint64_t w);
|