@@ -1,28 +1,31 @@ | |||
// X macro: Define a macro named X, then include this file, then undef X. | |||
#ifdef Y | |||
Y("none", knone) | |||
Y("true", ktrue) | |||
Y("false", kfalse) | |||
#ifdef XNAME | |||
XNAME("none", knone) | |||
#endif | |||
#ifdef X | |||
X("+", l2_builtin_add) | |||
X("-", l2_builtin_sub) | |||
X("*", l2_builtin_mul) | |||
X("/", l2_builtin_div) | |||
X("==", l2_builtin_eq) | |||
X("!=", l2_builtin_neq) | |||
X("<", l2_builtin_lt) | |||
X("<=", l2_builtin_lteq) | |||
X(">", l2_builtin_gt) | |||
X(">=", l2_builtin_gteq) | |||
X("&&", l2_builtin_land) | |||
X("||", l2_builtin_lor) | |||
X("??", l2_builtin_first) | |||
X("print", l2_builtin_print) | |||
X("len", l2_builtin_len) | |||
X("if", l2_builtin_if) | |||
X("loop", l2_builtin_loop) | |||
X("while", l2_builtin_while) | |||
#ifdef XATOM | |||
XATOM("true", ktrue) | |||
XATOM("false", kfalse) | |||
#endif | |||
#ifdef XFUNCTION | |||
XFUNCTION("+", l2_builtin_add) | |||
XFUNCTION("-", l2_builtin_sub) | |||
XFUNCTION("*", l2_builtin_mul) | |||
XFUNCTION("/", l2_builtin_div) | |||
XFUNCTION("==", l2_builtin_eq) | |||
XFUNCTION("!=", l2_builtin_neq) | |||
XFUNCTION("<", l2_builtin_lt) | |||
XFUNCTION("<=", l2_builtin_lteq) | |||
XFUNCTION(">", l2_builtin_gt) | |||
XFUNCTION(">=", l2_builtin_gteq) | |||
XFUNCTION("&&", l2_builtin_land) | |||
XFUNCTION("||", l2_builtin_lor) | |||
XFUNCTION("??", l2_builtin_first) | |||
XFUNCTION("print", l2_builtin_print) | |||
XFUNCTION("len", l2_builtin_len) | |||
XFUNCTION("if", l2_builtin_if) | |||
XFUNCTION("loop", l2_builtin_loop) | |||
XFUNCTION("while", l2_builtin_while) | |||
#endif |
@@ -1,6 +1,6 @@ | |||
#include "vm.h" | |||
#define X(name, f) \ | |||
#define XFUNCTION(name, f) \ | |||
l2_word f(struct l2_vm *vm, l2_word argc, l2_word *argv); | |||
#include "../builtins.x.h" | |||
#undef X | |||
#undef XFUNCTION |
@@ -48,13 +48,16 @@ void l2_gen_init(struct l2_generator *gen, struct l2_io_writer *w) { | |||
l2_bufio_writer_init(&gen->writer, w); | |||
// Register atoms for all builtins | |||
#define Y(name, k) \ | |||
#define XNAME(name, k) \ | |||
l2_strset_put_copy(&gen->atomset, name); | |||
#define X(name, f) \ | |||
#define XATOM(name, k) \ | |||
l2_strset_put_copy(&gen->atomset, name); | |||
#define XFUNCTION(name, f) \ | |||
l2_strset_put_copy(&gen->atomset, name); | |||
#include "builtins.x.h" | |||
#undef Y | |||
#undef X | |||
#undef XNAME | |||
#undef XATOM | |||
#undef XFUNCTION | |||
} | |||
void l2_gen_flush(struct l2_generator *gen) { |
@@ -224,28 +224,32 @@ void l2_vm_init(struct l2_vm *vm, unsigned char *ops, size_t opslen) { | |||
vm->fstack[vm->fsptr].sptr = 0; | |||
vm->fsptr += 1; | |||
// None is always at 0 | |||
vm->knone = 0; | |||
vm->values[vm->knone].flags = L2_VAL_TYPE_NONE | L2_VAL_CONST; | |||
// Define a C function variable for every builtin | |||
l2_word id; | |||
l2_word key = 1; | |||
#define Y(name, k) \ | |||
if (strcmp(#k, "knone") == 0) { \ | |||
id = 0; \ | |||
l2_vm_namespace_set(&vm->values[builtins], key, id); \ | |||
} else { \ | |||
id = alloc_val(vm); \ | |||
vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \ | |||
vm->values[id].atom = key; \ | |||
} \ | |||
#define XNAME(name, k) \ | |||
l2_vm_namespace_set(&vm->values[builtins], key, vm->k); \ | |||
key += 1; | |||
#define XATOM(name, k) \ | |||
id = alloc_val(vm); \ | |||
vm->values[id].flags = L2_VAL_TYPE_ATOM | L2_VAL_CONST; \ | |||
vm->values[id].atom = key; \ | |||
vm->k = id; \ | |||
key += 1; | |||
#define X(name, f) \ | |||
#define XFUNCTION(name, f) \ | |||
id = alloc_val(vm); \ | |||
vm->values[id].flags = L2_VAL_TYPE_CFUNCTION | L2_VAL_CONST; \ | |||
vm->values[id].cfunc = f; \ | |||
l2_vm_namespace_set(&vm->values[builtins], key++, id); | |||
l2_vm_namespace_set(&vm->values[builtins], key, id); \ | |||
key += 1; | |||
#include "builtins.x.h" | |||
#undef Y | |||
#undef X | |||
#undef XNAME | |||
#undef XATOM | |||
#undef XFUNCTION | |||
vm->gc_start = id + 1; | |||
} |